diff --git a/example/__main__.py b/example/__main__.py index 66d3ddd..726f42c 100644 --- a/example/__main__.py +++ b/example/__main__.py @@ -1,17 +1,16 @@ from cmd import Cmd import objectbox -import datetime +from datetime import datetime, timezone from example.model import * # objectbox expects date timestamp in milliseconds since UNIX epoch def now_ms() -> int: - seconds: float = datetime.datetime.utcnow().timestamp() - return round(seconds * 1000) + return datetime.now(timezone.utc) -def format_date(timestamp_ms: int) -> str: - return "" if timestamp_ms == 0 else str(datetime.datetime.fromtimestamp(timestamp_ms / 1000)) +def format_date(timestamp_ms: datetime) -> str: + return "" if timestamp_ms == 0 else str(timestamp_ms) class TasklistCmd(Cmd): diff --git a/example/model.py b/example/model.py index 88c7142..3ac14c3 100644 --- a/example/model.py +++ b/example/model.py @@ -1,3 +1,4 @@ +from datetime import datetime from objectbox.model import * @@ -6,9 +7,8 @@ class Task: id = Id(id=1, uid=1001) text = Property(str, id=2, uid=1002) - # TODO property type DATE - date_created = Property(int, id=3, uid=1003) - date_finished = Property(int, id=4, uid=1004) + date_created = Property(datetime, type=PropertyType.dateNano, id=3, uid=1003) + date_finished = Property(datetime, id=4, uid=1004) def get_objectbox_model(): diff --git a/objectbox/__init__.py b/objectbox/__init__.py index b08cfed..584be96 100644 --- a/objectbox/__init__.py +++ b/objectbox/__init__.py @@ -31,7 +31,7 @@ ] # Python binding version -version = Version(0, 4, 0) +version = Version(0, 5, 0) def version_info(): diff --git a/objectbox/c.py b/objectbox/c.py index 339b530..33aef62 100644 --- a/objectbox/c.py +++ b/objectbox/c.py @@ -394,6 +394,7 @@ def c_voidp_as_bytes(voidp, size): OBXPropertyType_String = 9 OBXPropertyType_Date = 10 OBXPropertyType_Relation = 11 +OBXPropertyType_DateNano = 12 OBXPropertyType_ByteVector = 23 OBXPropertyType_StringVector = 30 diff --git a/objectbox/model/entity.py b/objectbox/model/entity.py index 2f83e59..dc33a54 100644 --- a/objectbox/model/entity.py +++ b/objectbox/model/entity.py @@ -13,6 +13,7 @@ # limitations under the License. +from datetime import datetime import flatbuffers from objectbox.c import * from objectbox.model.properties import Property @@ -78,8 +79,10 @@ def fill_properties(self): def get_value(self, object, prop: Property): # in case value is not overwritten on the object, it's the Property object itself (= as defined in the Class) val = getattr(object, prop._name) - if val == prop: - return prop._py_type() # default (empty) value for the given type + if hasattr(val, "timestamp"): # handle datetimes first + return int(val.timestamp()) + elif val == prop: + return prop._py_type() if not hasattr(prop._py_type, "timestamp") else 0 # default (empty) value for the given type return val def get_object_id(self, object) -> int: @@ -143,6 +146,9 @@ def unmarshal(self, data: bytes): # slice the vector as a requested type val = prop._py_type(table.Bytes[start:start+size]) + elif prop._ob_type == OBXPropertyType_Date or prop._ob_type == OBXPropertyType_DateNano: + table_val = table.Get(prop._fb_type, o + table.Pos) + val = datetime.fromtimestamp(table_val) if table_val != 0 else 0 # default timestamp else: val = table.Get(prop._fb_type, o + table.Pos) diff --git a/objectbox/model/properties.py b/objectbox/model/properties.py index 08810f2..3b0c9a9 100644 --- a/objectbox/model/properties.py +++ b/objectbox/model/properties.py @@ -12,6 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from datetime import datetime from enum import IntEnum from objectbox.c import * @@ -28,7 +29,8 @@ class PropertyType(IntEnum): float = OBXPropertyType_Float double = OBXPropertyType_Double string = OBXPropertyType_String - # date = OBXPropertyType_Date + date = OBXPropertyType_Date + dateNano = OBXPropertyType_DateNano # relation = OBXPropertyType_Relation byteVector = OBXPropertyType_ByteVector # stringVector = OBXPropertyType_StringVector @@ -44,7 +46,8 @@ class PropertyType(IntEnum): PropertyType.float: flatbuffers.number_types.Float32Flags, PropertyType.double: flatbuffers.number_types.Float64Flags, PropertyType.string: flatbuffers.number_types.UOffsetTFlags, - # PropertyType.date: flatbuffers.number_types.Int64Flags, + PropertyType.date: flatbuffers.number_types.Int64Flags, + PropertyType.dateNano: flatbuffers.number_types.Float64Flags, # PropertyType.relation: flatbuffers.number_types.Int64Flags, PropertyType.byteVector: flatbuffers.number_types.UOffsetTFlags, # PropertyType.stringVector: flatbuffers.number_types.UOffsetTFlags, @@ -81,6 +84,8 @@ def __determine_ob_type(self) -> OBXPropertyType: return OBXPropertyType_Double elif ts == bool: return OBXPropertyType_Bool + elif ts == datetime: + return OBXPropertyType_Date else: raise Exception("unknown property type %s" % ts)