Coverage for target/native-coverage/profiles/8cb89e7529e5488ca16399c0daa3ee58/project/.venv/lib/python3.13/site-packages/rdflib_turbo/store.py: 100%

36 statements  

« prev     ^ index     » next       coverage.py v7.16.2, created at 2026-10-20 21:00 +0000

1"""Transactional Oxigraph storage owned by the shared native extension.""" 

2 

3from contextlib import contextmanager 

4from os import fspath 

5 

6from ._native import NativeStore 

7from ._operations import GraphOperations 

8 

9 

10class InferenceOperations(GraphOperations): 

11 """Shared inference entry point for a store and its active transaction.""" 

12 

13 def infer(self, *, inference="owlrl", destination=None): 

14 """Expand the graph union; write new facts to destination (default graph if omitted). 

15 

16 Execution errors abort the entire transaction, including preceding writes. 

17 Existing statements retain their original contexts. 

18 """ 

19 self._native.infer(inference, destination) 

20 return self 

21 

22 

23class Transaction(InferenceOperations): 

24 """A scoped view of a store, including this transaction's uncommitted changes. 

25 

26 The enclosing context commits on success and aborts on any exception. A failed 

27 native operation aborts the transaction even if its exception is caught. 

28 Handles cannot be reused after the context exits. No base dataset is copied. 

29 """ 

30 

31 def __init__(self, native): 

32 self._native = native 

33 

34 def update(self, source): 

35 """Execute SPARQL Update inside the current transaction.""" 

36 self._native.update(source) 

37 return self 

38 

39 

40class Store(InferenceOperations): 

41 """An in-memory Oxigraph store, or a persistent RocksDB store at path. 

42 

43 This storage API supports queries, atomic mutations and direct inference. 

44 SHACL remains separate until its direct store adapter lands. 

45 """ 

46 

47 def __init__(self, path=None): 

48 self._native = NativeStore(None if path is None else fspath(path)) 

49 

50 def close(self): 

51 """Release the store; an active transaction must finish first.""" 

52 self._native.close() 

53 

54 def __enter__(self): 

55 self._native.ensure_open() 

56 return self 

57 

58 def __exit__(self, exc_type, exc_value, traceback): 

59 self.close() 

60 

61 def update(self, source): 

62 """Commit a SPARQL Update atomically, or abort it on error.""" 

63 self._native.update(source) 

64 return self 

65 

66 @contextmanager 

67 def transaction(self): 

68 """Commit on normal scope exit; abort on any exception or native failure. 

69 

70 Queries on the transaction see its own writes. Queries on the store see 

71 committed state. A second writer on this handle fails immediately. 

72 Oxigraph buffers the transaction delta in memory, not the base dataset. 

73 """ 

74 native = self._native.transaction() 

75 try: 

76 yield Transaction(native) 

77 except BaseException: 

78 native.rollback() 

79 raise 

80 else: 

81 native.commit()