Skip to content

Commit 9451a4f

Browse files
committed
add TimeAxisShift; bump version
1 parent 88e8f43 commit 9451a4f

File tree

6 files changed

+63
-16
lines changed

6 files changed

+63
-16
lines changed

docs/conf.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
master_doc = 'index'
2727

2828
# The full version, including alpha/beta/rc tags
29-
release = '0.5.0'
29+
release = '0.5.1'
3030

3131

3232
# -- General configuration ---------------------------------------------------

pysirix/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pysirix.database import Database
55
from pysirix.resource import Resource
66
from pysirix.json_store import JsonStoreSync, JsonStoreAsync
7-
from pysirix.constants import Insert, DBType
7+
from pysirix.constants import Insert, DBType, TimeAxisShift
88
from pysirix.errors import SirixServerError
99
from pysirix.types import (
1010
QueryResult,
@@ -65,4 +65,5 @@ async def sirix_async(
6565
"DeleteDiff",
6666
"Metadata",
6767
"MetaNode",
68+
"TimeAxisShift",
6869
]

pysirix/constants.py

+6
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ class DBType(Enum):
2323
JSON = "application/json"
2424

2525

26+
class TimeAxisShift(Enum):
27+
oldest = -1
28+
none = 0
29+
latest = 1
30+
31+
2632
class MetadataType(Enum):
2733
"""
2834
This class defines the scope of the metadata to return using the

pysirix/json_store.py

+27-12
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
from datetime import datetime
22
from typing import Union, Dict, List, Awaitable, Optional
3+
34
from pysirix.types import Commit, Revision as RevisionType, SubtreeRevision
45
from json import dumps, loads
56

67
from abc import ABC
78

8-
from pysirix.constants import DBType, Revision
9+
from pysirix.constants import DBType, Revision, TimeAxisShift
910
from pysirix.async_client import AsyncClient
1011
from pysirix.auth import Auth
1112
from pysirix.sync_client import SyncClient
@@ -39,7 +40,7 @@ def stringify(v: Union[None, int, str, Dict, List]):
3940
query_function_include = (
4041
"declare function local:q($i, $q) {"
4142
"let $m := for $k in jn:keys($q) return if (not(empty($i=>$k))) then deep-equal($i=>$k, $q=>$k) else false()"
42-
"return empty(index-of($m, false()))"
43+
" return empty(index-of($m, false()))"
4344
"};"
4445
)
4546

@@ -178,8 +179,9 @@ def _prepare_find_all(
178179
query_dict: Dict,
179180
projection: List[str] = None,
180181
revision: Revision = None,
181-
node_key=True,
182-
hash=False,
182+
node_key: bool = True,
183+
hash: bool = False,
184+
time_axis_shift: TimeAxisShift = TimeAxisShift.none,
183185
start_result_index: Optional[int] = None,
184186
end_result_index: Optional[int] = None,
185187
):
@@ -200,6 +202,10 @@ def _prepare_find_all(
200202
f"for $i in bit:array-values(jn:doc('{self.db_name}','{self.name}',{revision})){self.root}",
201203
]
202204
query_list.append(f"where local:q($i, {stringify(query_dict)})")
205+
if time_axis_shift == TimeAxisShift.oldest:
206+
query_list.append("let $i := jn:first-existing($i)")
207+
elif time_axis_shift == TimeAxisShift.latest:
208+
query_list.append("let $i := jn:last-existing($i)")
203209
return_obj = (
204210
"return {$i,'nodeKey': sdb:nodekey($i),'hash': sdb:hash($i)}"
205211
if node_key and hash
@@ -230,8 +236,9 @@ def find_all(
230236
query_dict: Dict,
231237
projection: List[str] = None,
232238
revision: Revision = None,
233-
node_key=True,
234-
hash=False,
239+
node_key: bool = True,
240+
hash: bool = False,
241+
time_axis_shift: TimeAxisShift = TimeAxisShift.none,
235242
start_result_index: Optional[int] = None,
236243
end_result_index: Optional[int] = None,
237244
) -> List[QueryResult]:
@@ -251,6 +258,7 @@ def find_all(
251258
the nodeKey of the record.
252259
:param hash: a ``bool`` determining whether or not to return a ``hash`` field containing the hash of the record.
253260
:param revision: the revision to search, defaults to latest. May be an integer or a ``datetime`` instance
261+
:param time_axis_shift: specify fetching the most or least recent existing revision of the record
254262
:param start_result_index: index of first result to return.
255263
:param end_result_index: index of last result to return.
256264
:return: a ``list`` of :py:class:`QueryResult` records matching the query.
@@ -366,8 +374,9 @@ def find_one(
366374
query_dict: Dict,
367375
projection: List[str] = None,
368376
revision: Revision = None,
369-
node_key=True,
370-
hash=False,
377+
node_key: bool = True,
378+
hash: bool = False,
379+
time_axis_shift: TimeAxisShift = TimeAxisShift.none,
371380
) -> List[QueryResult]:
372381
"""
373382
This method is the same as :py:meth:`find_many`, except that this method will only return the first result,
@@ -378,6 +387,7 @@ def find_one(
378387
:param revision:
379388
:param node_key:
380389
:param hash:
390+
:param time_axis_shift:
381391
:return:
382392
"""
383393
return self.find_all(
@@ -386,6 +396,7 @@ def find_one(
386396
revision,
387397
node_key,
388398
hash,
399+
time_axis_shift,
389400
start_result_index=0,
390401
end_result_index=0,
391402
)
@@ -406,8 +417,9 @@ def find_all(
406417
query_dict: Dict,
407418
projection: List[str] = None,
408419
revision: Revision = None,
409-
node_key=True,
410-
hash=False,
420+
node_key: bool = True,
421+
hash: bool = False,
422+
time_axis_shift: TimeAxisShift = TimeAxisShift.none,
411423
start_result_index: Optional[int] = None,
412424
end_result_index: Optional[int] = None,
413425
) -> List[QueryResult]:
@@ -417,6 +429,7 @@ def find_all(
417429
revision,
418430
node_key,
419431
hash,
432+
time_axis_shift,
420433
start_result_index,
421434
end_result_index,
422435
)
@@ -459,8 +472,9 @@ async def find_all(
459472
query_dict: Dict,
460473
projection: List[str] = None,
461474
revision: Revision = None,
462-
node_key=True,
463-
hash=False,
475+
node_key: bool = True,
476+
hash: bool = False,
477+
time_axis_shift: TimeAxisShift = TimeAxisShift.none,
464478
start_result_index: Optional[int] = None,
465479
end_result_index: Optional[int] = None,
466480
) -> List[QueryResult]:
@@ -470,6 +484,7 @@ async def find_all(
470484
revision,
471485
node_key,
472486
hash,
487+
time_axis_shift,
473488
start_result_index,
474489
end_result_index,
475490
)

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
setuptools.setup(
77
name="pysirix",
8-
version="0.5.0",
8+
version="0.5.1",
99
author="Moshe Uminer",
1010
author_email="[email protected]",
1111
description="The SirixDB Python SDK",

tests/test_json_store.py

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
import time
12
from datetime import datetime
23

34
import httpx
45
import pysirix
5-
from pysirix import DBType
6+
from pysirix import DBType, TimeAxisShift
67

78
base_url = "http://localhost:9443"
89

@@ -148,6 +149,30 @@ def test_upsert_non_existent_field():
148149
assert store.find_one({"key": "value"}, node_key=False) == [{"key": "value"}]
149150

150151

152+
def test_shift_time_axis():
153+
store.create()
154+
store.insert_one({"id": 0})
155+
store.update_by_key(2, {"key": "value"})
156+
assert (
157+
store.find_one(
158+
{"id": 0},
159+
node_key=False,
160+
revision=2,
161+
time_axis_shift=TimeAxisShift.latest,
162+
)
163+
== [{"key": "value", "id": 0}]
164+
)
165+
assert (
166+
store.find_one(
167+
{"id": 0},
168+
node_key=False,
169+
revision=3,
170+
time_axis_shift=TimeAxisShift.oldest,
171+
)
172+
== [{"id": 0}]
173+
)
174+
175+
151176
def test_update_many():
152177
store.create()
153178
store.insert_many(

0 commit comments

Comments
 (0)