Skip to content

Commit d72ffcc

Browse files
authored
Added Compact datetime type (#134)
1 parent be3838a commit d72ffcc

File tree

7 files changed

+75
-6
lines changed

7 files changed

+75
-6
lines changed

pyproject.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "surrealdb"
3-
version = "0.4.1"
3+
version = "0.4.3"
44
description = "The official SurrealDB library for Python."
55
readme = "README.md"
66
authors = ["SurrealDB"]
@@ -34,4 +34,3 @@ ruff = "^0.8.0"
3434
black = "^24.10.0"
3535
mypy = "^1.13.0"
3636
types-requests = "^2.32.0.20241016"
37-

requirements.txt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
cbor2==5.6.5
2+
certifi==2024.12.14
3+
charset-normalizer==3.4.0
24
docker==7.1.0
3-
Requests==2.32.3
5+
idna==3.10
6+
mypy==1.13.0
7+
mypy-extensions==1.0.0
8+
pytz==2024.2
9+
requests==2.32.3
10+
semantic-version==2.10.0
411
setuptools>=70.0.0
5-
setuptools_rust==1.6.0
12+
setuptools-rust==1.6.0
13+
tomli==2.2.1
14+
types-pytz==2024.2.0.20241003
15+
types-requests==2.32.0.20241016
16+
typing_extensions==4.12.2
17+
urllib3==2.2.3
618
websockets==14.1

surrealdb/data/cbor.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import cbor2
22

33
from surrealdb.data.types import constants
4+
from surrealdb.data.types.datetime import DateTimeCompact
45
from surrealdb.data.types.duration import Duration
56
from surrealdb.data.types.future import Future
67
from surrealdb.data.types.geometry import (
@@ -64,7 +65,12 @@ def default_encoder(encoder, obj):
6465
tagged = cbor2.CBORTag(constants.TAG_BOUND_EXCLUDED, obj.value)
6566

6667
elif isinstance(obj, Duration):
67-
tagged = cbor2.CBORTag(constants.TAG_DURATION, obj.getSecondsAndNano())
68+
tagged = cbor2.CBORTag(constants.TAG_DURATION, obj.get_seconds_and_nano())
69+
70+
elif isinstance(obj, DateTimeCompact):
71+
tagged = cbor2.CBORTag(
72+
constants.TAG_DATETIME_COMPACT, obj.get_seconds_and_nano()
73+
)
6874

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

124+
elif tag.tag == constants.TAG_DATETIME_COMPACT:
125+
return DateTimeCompact.parse(tag.value[0], tag.value[1])
126+
118127
else:
119128
raise SurrealDbDecodeError("no decoder for tag", tag.tag)
120129

surrealdb/data/types/datetime.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import pytz # type: ignore
2+
3+
from dataclasses import dataclass
4+
from datetime import datetime
5+
from math import floor
6+
from typing import Tuple
7+
8+
9+
@dataclass
10+
class DateTimeCompact:
11+
timestamp: int = 0 # nanoseconds
12+
13+
@staticmethod
14+
def parse(seconds: int, nanoseconds: int):
15+
return DateTimeCompact(nanoseconds + (seconds * pow(10, 9)))
16+
17+
def get_seconds_and_nano(self) -> Tuple[int, int]:
18+
sec = floor(self.timestamp / pow(10, 9))
19+
nsec = self.timestamp - (sec * pow(10, 9))
20+
21+
return sec, nsec
22+
23+
def get_date_time(self, fmt: str = "%Y-%m-%dT%H:%M:%S.%fZ"):
24+
return datetime.fromtimestamp(self.timestamp / pow(10, 9), pytz.UTC).strftime(
25+
fmt
26+
)

surrealdb/data/types/duration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Duration:
1111
def parse(seconds: int, nanoseconds: int):
1212
return Duration(nanoseconds + (seconds * pow(10, 9)))
1313

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

tests/unit/cbor_types/__init__.py

Whitespace-only changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
from unittest import TestCase
2+
3+
from surrealdb.data.types.datetime import DateTimeCompact
4+
from surrealdb.data.cbor import encode, decode
5+
6+
7+
class TestCBOR(TestCase):
8+
def setUp(self):
9+
pass
10+
11+
def tearDown(self):
12+
pass
13+
14+
def test_datetime(self):
15+
compact_date_time_array = [1733994058, 83988472] # December 12, 2024 9:00:58.083 AM
16+
17+
compact_date_time = DateTimeCompact.parse(compact_date_time_array[0], compact_date_time_array[1])
18+
encoded = encode(compact_date_time)
19+
decoded = decode(encoded)
20+
21+
self.assertEqual(decoded.get_date_time(), '2024-12-12T09:00:58.083988Z')
22+
23+

0 commit comments

Comments
 (0)