Skip to content

Commit

Permalink
Added Compact datetime type (#134)
Browse files Browse the repository at this point in the history
  • Loading branch information
remade authored Dec 20, 2024
1 parent be3838a commit d72ffcc
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 6 deletions.
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "surrealdb"
version = "0.4.1"
version = "0.4.3"
description = "The official SurrealDB library for Python."
readme = "README.md"
authors = ["SurrealDB"]
Expand Down Expand Up @@ -34,4 +34,3 @@ ruff = "^0.8.0"
black = "^24.10.0"
mypy = "^1.13.0"
types-requests = "^2.32.0.20241016"

16 changes: 14 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
cbor2==5.6.5
certifi==2024.12.14
charset-normalizer==3.4.0
docker==7.1.0
Requests==2.32.3
idna==3.10
mypy==1.13.0
mypy-extensions==1.0.0
pytz==2024.2
requests==2.32.3
semantic-version==2.10.0
setuptools>=70.0.0
setuptools_rust==1.6.0
setuptools-rust==1.6.0
tomli==2.2.1
types-pytz==2024.2.0.20241003
types-requests==2.32.0.20241016
typing_extensions==4.12.2
urllib3==2.2.3
websockets==14.1
11 changes: 10 additions & 1 deletion surrealdb/data/cbor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import cbor2

from surrealdb.data.types import constants
from surrealdb.data.types.datetime import DateTimeCompact
from surrealdb.data.types.duration import Duration
from surrealdb.data.types.future import Future
from surrealdb.data.types.geometry import (
Expand Down Expand Up @@ -64,7 +65,12 @@ def default_encoder(encoder, obj):
tagged = cbor2.CBORTag(constants.TAG_BOUND_EXCLUDED, obj.value)

elif isinstance(obj, Duration):
tagged = cbor2.CBORTag(constants.TAG_DURATION, obj.getSecondsAndNano())
tagged = cbor2.CBORTag(constants.TAG_DURATION, obj.get_seconds_and_nano())

elif isinstance(obj, DateTimeCompact):
tagged = cbor2.CBORTag(
constants.TAG_DATETIME_COMPACT, obj.get_seconds_and_nano()
)

else:
raise SurrealDbEncodeError("no encoder for type ", type(obj))
Expand Down Expand Up @@ -115,6 +121,9 @@ def tag_decoder(decoder, tag, shareable_index=None):
elif tag.tag == constants.TAG_DURATION:
return Duration.parse(tag.value[0], tag.value[1])

elif tag.tag == constants.TAG_DATETIME_COMPACT:
return DateTimeCompact.parse(tag.value[0], tag.value[1])

else:
raise SurrealDbDecodeError("no decoder for tag", tag.tag)

Expand Down
26 changes: 26 additions & 0 deletions surrealdb/data/types/datetime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import pytz # type: ignore

from dataclasses import dataclass
from datetime import datetime
from math import floor
from typing import Tuple


@dataclass
class DateTimeCompact:
timestamp: int = 0 # nanoseconds

@staticmethod
def parse(seconds: int, nanoseconds: int):
return DateTimeCompact(nanoseconds + (seconds * pow(10, 9)))

def get_seconds_and_nano(self) -> Tuple[int, int]:
sec = floor(self.timestamp / pow(10, 9))
nsec = self.timestamp - (sec * pow(10, 9))

return sec, nsec

def get_date_time(self, fmt: str = "%Y-%m-%dT%H:%M:%S.%fZ"):
return datetime.fromtimestamp(self.timestamp / pow(10, 9), pytz.UTC).strftime(
fmt
)
2 changes: 1 addition & 1 deletion surrealdb/data/types/duration.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Duration:
def parse(seconds: int, nanoseconds: int):
return Duration(nanoseconds + (seconds * pow(10, 9)))

def getSecondsAndNano(self) -> Tuple[int, int]:
def get_seconds_and_nano(self) -> Tuple[int, int]:
sec = floor(self.elapsed / pow(10, 9))
nsec = self.elapsed - (sec * pow(10, 9))

Expand Down
Empty file.
23 changes: 23 additions & 0 deletions tests/unit/cbor_types/test_datetime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from unittest import TestCase

from surrealdb.data.types.datetime import DateTimeCompact
from surrealdb.data.cbor import encode, decode


class TestCBOR(TestCase):
def setUp(self):
pass

def tearDown(self):
pass

def test_datetime(self):
compact_date_time_array = [1733994058, 83988472] # December 12, 2024 9:00:58.083 AM

compact_date_time = DateTimeCompact.parse(compact_date_time_array[0], compact_date_time_array[1])
encoded = encode(compact_date_time)
decoded = decode(encoded)

self.assertEqual(decoded.get_date_time(), '2024-12-12T09:00:58.083988Z')


0 comments on commit d72ffcc

Please sign in to comment.