zyxdb 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- zyxdb-0.1.0/PKG-INFO +143 -0
- zyxdb-0.1.0/README.md +119 -0
- zyxdb-0.1.0/meson.build +222 -0
- zyxdb-0.1.0/pyproject.toml +32 -0
- zyxdb-0.1.0/src/zyxdb/__init__.py +23 -0
- zyxdb-0.1.0/src/zyxdb/_core.cpp +390 -0
- zyxdb-0.1.0/src/zyxdb/database.py +134 -0
- zyxdb-0.1.0/src/zyxdb/py.typed +0 -0
- zyxdb-0.1.0/src/zyxdb/result.py +151 -0
- zyxdb-0.1.0/src/zyxdb/transaction.py +61 -0
- zyxdb-0.1.0/src/zyxdb/types.py +49 -0
- zyxdb-0.1.0/tests/conftest.py +39 -0
- zyxdb-0.1.0/tests/test_basic.py +149 -0
- zyxdb-0.1.0/tests/test_result.py +142 -0
- zyxdb-0.1.0/tests/test_transactions.py +82 -0
- zyxdb-0.1.0/tests/test_types.py +171 -0
- zyxdb-0.1.0/undef_python_tokens.h +42 -0
zyxdb-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: zyxdb
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python bindings for ZYX graph database engine
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Classifier: Development Status :: 3 - Alpha
|
|
7
|
+
Classifier: Intended Audience :: Developers
|
|
8
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: C++
|
|
16
|
+
Classifier: Topic :: Database
|
|
17
|
+
Classifier: Topic :: Database :: Database Engines/Servers
|
|
18
|
+
Project-URL: Homepage, https://github.com/nexepic/zyx
|
|
19
|
+
Project-URL: Repository, https://github.com/nexepic/zyx
|
|
20
|
+
Requires-Python: >=3.9
|
|
21
|
+
Provides-Extra: test
|
|
22
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# zyxdb
|
|
26
|
+
|
|
27
|
+
Python bindings for [ZYX](https://github.com/nicklauslititz/zyx), a high-performance embeddable graph database engine with Cypher query support.
|
|
28
|
+
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
pip install zyxdb
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Build from source
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
cd bindings/python
|
|
39
|
+
pip install -e ".[test]"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Quick Start
|
|
43
|
+
|
|
44
|
+
```python
|
|
45
|
+
import zyxdb
|
|
46
|
+
|
|
47
|
+
# Open a database (creates if not exists)
|
|
48
|
+
db = zyxdb.Database("/tmp/mydb")
|
|
49
|
+
|
|
50
|
+
# Create nodes with Cypher
|
|
51
|
+
db.execute("CREATE (n:Person {name: $name, age: $age})", name="Alice", age=30)
|
|
52
|
+
|
|
53
|
+
# Query with iteration
|
|
54
|
+
for row in db.execute("MATCH (n:Person) RETURN n.name AS name, n.age AS age"):
|
|
55
|
+
print(row["name"], row["age"])
|
|
56
|
+
|
|
57
|
+
# Batch insert
|
|
58
|
+
db.create_nodes("Person", [
|
|
59
|
+
{"name": "Bob", "age": 25},
|
|
60
|
+
{"name": "Carol", "age": 35},
|
|
61
|
+
])
|
|
62
|
+
|
|
63
|
+
# Transactions with context manager
|
|
64
|
+
with db.begin_transaction() as tx:
|
|
65
|
+
tx.execute("CREATE (n:Movie {title: 'Matrix'})")
|
|
66
|
+
tx.execute(
|
|
67
|
+
"MATCH (a:Person {name: 'Alice'}), (m:Movie {title: 'Matrix'}) "
|
|
68
|
+
"CREATE (a)-[:WATCHED]->(m)"
|
|
69
|
+
)
|
|
70
|
+
tx.commit()
|
|
71
|
+
|
|
72
|
+
# Read-only transaction
|
|
73
|
+
with db.begin_read_only_transaction() as tx:
|
|
74
|
+
for row in tx.execute("MATCH (n) RETURN count(n) AS cnt"):
|
|
75
|
+
print(row["cnt"])
|
|
76
|
+
|
|
77
|
+
# Direct node/edge creation by ID (high performance)
|
|
78
|
+
id1 = db.create_node_ret_id("Person", {"name": "Dave"})
|
|
79
|
+
id2 = db.create_node_ret_id("Person", {"name": "Eve"})
|
|
80
|
+
db.create_edge_by_id(id1, id2, "KNOWS", {"since": 2024})
|
|
81
|
+
|
|
82
|
+
# Shortest path
|
|
83
|
+
path = db.get_shortest_path(id1, id2)
|
|
84
|
+
|
|
85
|
+
db.close()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Context Manager
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
with zyxdb.Database("/tmp/mydb") as db:
|
|
92
|
+
db.execute("CREATE (n:Test {x: 1})")
|
|
93
|
+
# Auto-closes on exit
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Supported Value Types
|
|
97
|
+
|
|
98
|
+
| Python | ZYX |
|
|
99
|
+
|--------|-----|
|
|
100
|
+
| `None` | null |
|
|
101
|
+
| `bool` | bool |
|
|
102
|
+
| `int` | int64 |
|
|
103
|
+
| `float` | double |
|
|
104
|
+
| `str` | string |
|
|
105
|
+
| `list[float]` | vector (embeddings) |
|
|
106
|
+
| `list[str]` | string list |
|
|
107
|
+
| `list` (mixed) | heterogeneous list |
|
|
108
|
+
| `dict` | map |
|
|
109
|
+
|
|
110
|
+
## API Reference
|
|
111
|
+
|
|
112
|
+
### `Database(path, *, open=True)`
|
|
113
|
+
|
|
114
|
+
- `execute(cypher, **params)` — Execute Cypher query with keyword parameters
|
|
115
|
+
- `begin_transaction()` — Start a read-write transaction
|
|
116
|
+
- `begin_read_only_transaction()` — Start a read-only transaction
|
|
117
|
+
- `create_node(label, props)` — Create a node (label can be `str` or `list[str]`)
|
|
118
|
+
- `create_node_ret_id(label, props)` — Create a node, return its ID
|
|
119
|
+
- `create_nodes(label, props_list)` — Batch create nodes
|
|
120
|
+
- `create_edge_by_id(src_id, dst_id, type, props)` — Create edge between known IDs
|
|
121
|
+
- `get_shortest_path(start_id, end_id, max_depth=15)` — Find shortest path
|
|
122
|
+
- `save()` — Flush to disk
|
|
123
|
+
- `close()` — Close the database
|
|
124
|
+
|
|
125
|
+
### `Transaction`
|
|
126
|
+
|
|
127
|
+
- `execute(cypher, **params)` — Execute within transaction
|
|
128
|
+
- `commit()` — Commit changes
|
|
129
|
+
- `rollback()` — Roll back changes
|
|
130
|
+
- `is_active` — Whether transaction is still active
|
|
131
|
+
- `is_read_only` — Whether read-only
|
|
132
|
+
|
|
133
|
+
### `Result`
|
|
134
|
+
|
|
135
|
+
- Iterable: `for row in result` yields `dict[str, Any]`
|
|
136
|
+
- `column_names` — List of column names
|
|
137
|
+
- `duration` — Query execution time (ms)
|
|
138
|
+
- `is_success` — Whether query succeeded
|
|
139
|
+
- `error` — Error message or `None`
|
|
140
|
+
|
|
141
|
+
## License
|
|
142
|
+
|
|
143
|
+
Apache License 2.0
|
zyxdb-0.1.0/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# zyxdb
|
|
2
|
+
|
|
3
|
+
Python bindings for [ZYX](https://github.com/nicklauslititz/zyx), a high-performance embeddable graph database engine with Cypher query support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install zyxdb
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Build from source
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
cd bindings/python
|
|
15
|
+
pip install -e ".[test]"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
import zyxdb
|
|
22
|
+
|
|
23
|
+
# Open a database (creates if not exists)
|
|
24
|
+
db = zyxdb.Database("/tmp/mydb")
|
|
25
|
+
|
|
26
|
+
# Create nodes with Cypher
|
|
27
|
+
db.execute("CREATE (n:Person {name: $name, age: $age})", name="Alice", age=30)
|
|
28
|
+
|
|
29
|
+
# Query with iteration
|
|
30
|
+
for row in db.execute("MATCH (n:Person) RETURN n.name AS name, n.age AS age"):
|
|
31
|
+
print(row["name"], row["age"])
|
|
32
|
+
|
|
33
|
+
# Batch insert
|
|
34
|
+
db.create_nodes("Person", [
|
|
35
|
+
{"name": "Bob", "age": 25},
|
|
36
|
+
{"name": "Carol", "age": 35},
|
|
37
|
+
])
|
|
38
|
+
|
|
39
|
+
# Transactions with context manager
|
|
40
|
+
with db.begin_transaction() as tx:
|
|
41
|
+
tx.execute("CREATE (n:Movie {title: 'Matrix'})")
|
|
42
|
+
tx.execute(
|
|
43
|
+
"MATCH (a:Person {name: 'Alice'}), (m:Movie {title: 'Matrix'}) "
|
|
44
|
+
"CREATE (a)-[:WATCHED]->(m)"
|
|
45
|
+
)
|
|
46
|
+
tx.commit()
|
|
47
|
+
|
|
48
|
+
# Read-only transaction
|
|
49
|
+
with db.begin_read_only_transaction() as tx:
|
|
50
|
+
for row in tx.execute("MATCH (n) RETURN count(n) AS cnt"):
|
|
51
|
+
print(row["cnt"])
|
|
52
|
+
|
|
53
|
+
# Direct node/edge creation by ID (high performance)
|
|
54
|
+
id1 = db.create_node_ret_id("Person", {"name": "Dave"})
|
|
55
|
+
id2 = db.create_node_ret_id("Person", {"name": "Eve"})
|
|
56
|
+
db.create_edge_by_id(id1, id2, "KNOWS", {"since": 2024})
|
|
57
|
+
|
|
58
|
+
# Shortest path
|
|
59
|
+
path = db.get_shortest_path(id1, id2)
|
|
60
|
+
|
|
61
|
+
db.close()
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Context Manager
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
with zyxdb.Database("/tmp/mydb") as db:
|
|
68
|
+
db.execute("CREATE (n:Test {x: 1})")
|
|
69
|
+
# Auto-closes on exit
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Supported Value Types
|
|
73
|
+
|
|
74
|
+
| Python | ZYX |
|
|
75
|
+
|--------|-----|
|
|
76
|
+
| `None` | null |
|
|
77
|
+
| `bool` | bool |
|
|
78
|
+
| `int` | int64 |
|
|
79
|
+
| `float` | double |
|
|
80
|
+
| `str` | string |
|
|
81
|
+
| `list[float]` | vector (embeddings) |
|
|
82
|
+
| `list[str]` | string list |
|
|
83
|
+
| `list` (mixed) | heterogeneous list |
|
|
84
|
+
| `dict` | map |
|
|
85
|
+
|
|
86
|
+
## API Reference
|
|
87
|
+
|
|
88
|
+
### `Database(path, *, open=True)`
|
|
89
|
+
|
|
90
|
+
- `execute(cypher, **params)` — Execute Cypher query with keyword parameters
|
|
91
|
+
- `begin_transaction()` — Start a read-write transaction
|
|
92
|
+
- `begin_read_only_transaction()` — Start a read-only transaction
|
|
93
|
+
- `create_node(label, props)` — Create a node (label can be `str` or `list[str]`)
|
|
94
|
+
- `create_node_ret_id(label, props)` — Create a node, return its ID
|
|
95
|
+
- `create_nodes(label, props_list)` — Batch create nodes
|
|
96
|
+
- `create_edge_by_id(src_id, dst_id, type, props)` — Create edge between known IDs
|
|
97
|
+
- `get_shortest_path(start_id, end_id, max_depth=15)` — Find shortest path
|
|
98
|
+
- `save()` — Flush to disk
|
|
99
|
+
- `close()` — Close the database
|
|
100
|
+
|
|
101
|
+
### `Transaction`
|
|
102
|
+
|
|
103
|
+
- `execute(cypher, **params)` — Execute within transaction
|
|
104
|
+
- `commit()` — Commit changes
|
|
105
|
+
- `rollback()` — Roll back changes
|
|
106
|
+
- `is_active` — Whether transaction is still active
|
|
107
|
+
- `is_read_only` — Whether read-only
|
|
108
|
+
|
|
109
|
+
### `Result`
|
|
110
|
+
|
|
111
|
+
- Iterable: `for row in result` yields `dict[str, Any]`
|
|
112
|
+
- `column_names` — List of column names
|
|
113
|
+
- `duration` — Query execution time (ms)
|
|
114
|
+
- `is_success` — Whether query succeeded
|
|
115
|
+
- `error` — Error message or `None`
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
Apache License 2.0
|
zyxdb-0.1.0/meson.build
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
project('zyxdb', 'cpp',
|
|
2
|
+
version : run_command(
|
|
3
|
+
'python3', '-c',
|
|
4
|
+
'import re, pathlib; print(re.search(r"version\\s*:\\s*\'([^\']+)\'", pathlib.Path("' + meson.current_source_dir() / '..' / '..' / 'meson.build' + '").read_text()).group(1))',
|
|
5
|
+
check : true).stdout().strip(),
|
|
6
|
+
default_options : [
|
|
7
|
+
'cpp_std=c++20',
|
|
8
|
+
'warning_level=3',
|
|
9
|
+
'werror=false',
|
|
10
|
+
'buildtype=release',
|
|
11
|
+
'default_library=static',
|
|
12
|
+
])
|
|
13
|
+
|
|
14
|
+
# Resolve the root of the main ZYX project (two levels up from bindings/python)
|
|
15
|
+
zyx_root = meson.current_source_dir() / '..' / '..'
|
|
16
|
+
|
|
17
|
+
cxx = meson.get_compiler('cpp')
|
|
18
|
+
|
|
19
|
+
# Windows macro conflict guards
|
|
20
|
+
if host_machine.system() == 'windows'
|
|
21
|
+
add_project_arguments('-DNOMINMAX', '-DNOGDI', language : 'cpp')
|
|
22
|
+
endif
|
|
23
|
+
|
|
24
|
+
# ==============================================================================
|
|
25
|
+
# Dependencies (same as root meson.build)
|
|
26
|
+
# ==============================================================================
|
|
27
|
+
zlib_dep = dependency('zlib')
|
|
28
|
+
boost_dep = dependency('boost', modules : ['filesystem', 'system'])
|
|
29
|
+
cli11_dep = dependency('CLI11')
|
|
30
|
+
|
|
31
|
+
antlr4_dep = dependency('antlr4-cppruntime', required : false)
|
|
32
|
+
if not antlr4_dep.found()
|
|
33
|
+
antlr4_dep = dependency('antlr4-runtime', method : 'cmake',
|
|
34
|
+
modules : ['antlr4_static'], required : true)
|
|
35
|
+
endif
|
|
36
|
+
|
|
37
|
+
# ==============================================================================
|
|
38
|
+
# ANTLR4 generated parser sources + implementation
|
|
39
|
+
# ==============================================================================
|
|
40
|
+
parser_dir = zyx_root / 'src' / 'query' / 'parser' / 'cypher' / 'generated'
|
|
41
|
+
parser_impl_dir = zyx_root / 'src' / 'query' / 'parser' / 'cypher'
|
|
42
|
+
|
|
43
|
+
_py = import('python').find_installation()
|
|
44
|
+
|
|
45
|
+
# Generated parser files
|
|
46
|
+
_find_parser = run_command(_py, '-c', '''
|
|
47
|
+
import os, sys
|
|
48
|
+
d = sys.argv[1]
|
|
49
|
+
source_dir = sys.argv[2]
|
|
50
|
+
for f in sorted(os.listdir(d)):
|
|
51
|
+
if f.endswith(".cpp"):
|
|
52
|
+
print(os.path.relpath(os.path.join(d, f), source_dir))
|
|
53
|
+
''', parser_dir, meson.current_source_dir(), check : true)
|
|
54
|
+
_parser_files = _find_parser.stdout().strip().split('\n')
|
|
55
|
+
parser_src = []
|
|
56
|
+
foreach f : _parser_files
|
|
57
|
+
if f != ''
|
|
58
|
+
parser_src += files(f)
|
|
59
|
+
endif
|
|
60
|
+
endforeach
|
|
61
|
+
|
|
62
|
+
# Parser implementation files (CypherParserImpl, helpers, clauses, etc.)
|
|
63
|
+
_find_parser_impl = run_command(_py, '-c', '''
|
|
64
|
+
import os, sys
|
|
65
|
+
base_dir = sys.argv[1]
|
|
66
|
+
source_dir = sys.argv[2]
|
|
67
|
+
seen = set()
|
|
68
|
+
for line in sys.argv[3].splitlines():
|
|
69
|
+
if line.strip():
|
|
70
|
+
seen.add(os.path.normpath(line.strip()))
|
|
71
|
+
for root, dirs, files_list in os.walk(base_dir):
|
|
72
|
+
for f in sorted(files_list):
|
|
73
|
+
if f.endswith(".cpp"):
|
|
74
|
+
rel = os.path.relpath(os.path.join(root, f), source_dir)
|
|
75
|
+
if os.path.normpath(rel) not in seen:
|
|
76
|
+
print(rel)
|
|
77
|
+
''', parser_impl_dir, meson.current_source_dir(), '\n'.join(_parser_files), check : true)
|
|
78
|
+
_parser_impl_files = _find_parser_impl.stdout().strip().split('\n')
|
|
79
|
+
foreach f : _parser_impl_files
|
|
80
|
+
if f != ''
|
|
81
|
+
parser_src += files(f)
|
|
82
|
+
endif
|
|
83
|
+
endforeach
|
|
84
|
+
|
|
85
|
+
cypher_inc = include_directories(
|
|
86
|
+
'../../src/query/parser/cypher/generated',
|
|
87
|
+
'../../src/query/parser/cypher',
|
|
88
|
+
'../../src/query/parser/cypher/helpers/internal',
|
|
89
|
+
'../../src/query/parser/cypher/helpers/public',
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
cypher_dep = declare_dependency(
|
|
93
|
+
sources : parser_src,
|
|
94
|
+
include_directories : cypher_inc,
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# ==============================================================================
|
|
98
|
+
# inputxx library (required by core/cli)
|
|
99
|
+
# ==============================================================================
|
|
100
|
+
inputxx_src_dir = zyx_root / 'lib' / 'inputxx' / 'src'
|
|
101
|
+
_find_inputxx = run_command(_py, '-c', '''
|
|
102
|
+
import os, sys
|
|
103
|
+
base_dir = sys.argv[1]
|
|
104
|
+
for root, dirs, files in os.walk(base_dir):
|
|
105
|
+
for f in sorted(files):
|
|
106
|
+
if f.endswith(".cpp"):
|
|
107
|
+
print(os.path.relpath(os.path.join(root, f), base_dir))
|
|
108
|
+
''', inputxx_src_dir, check : true)
|
|
109
|
+
inputxx_src = []
|
|
110
|
+
foreach f : _find_inputxx.stdout().strip().split('\n')
|
|
111
|
+
if f != ''
|
|
112
|
+
inputxx_src += files(zyx_root / 'lib' / 'inputxx' / 'src' / f)
|
|
113
|
+
endif
|
|
114
|
+
endforeach
|
|
115
|
+
inputxx_inc = include_directories('../../lib/inputxx/include')
|
|
116
|
+
inputxx_lib = static_library('inputxx',
|
|
117
|
+
sources : inputxx_src,
|
|
118
|
+
include_directories : inputxx_inc,
|
|
119
|
+
install : false,
|
|
120
|
+
)
|
|
121
|
+
inputxx_dep = declare_dependency(
|
|
122
|
+
include_directories : inputxx_inc,
|
|
123
|
+
link_with : inputxx_lib,
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# ==============================================================================
|
|
127
|
+
# Core library sources (same discovery as src/meson.build)
|
|
128
|
+
# ==============================================================================
|
|
129
|
+
src_dir = zyx_root / 'src'
|
|
130
|
+
_find_src = run_command(_py, '-c', '''
|
|
131
|
+
import os, sys
|
|
132
|
+
base_dir = sys.argv[1]
|
|
133
|
+
source_dir = sys.argv[2]
|
|
134
|
+
exclude = ["query/parser", "cli"]
|
|
135
|
+
for root, dirs, files_list in os.walk(base_dir):
|
|
136
|
+
rel_root = os.path.relpath(root, base_dir)
|
|
137
|
+
skip = False
|
|
138
|
+
for ex in exclude:
|
|
139
|
+
if rel_root == ex or rel_root.startswith(ex + os.sep):
|
|
140
|
+
skip = True
|
|
141
|
+
break
|
|
142
|
+
if skip:
|
|
143
|
+
continue
|
|
144
|
+
for f in sorted(files_list):
|
|
145
|
+
if f.endswith(".cpp"):
|
|
146
|
+
print(os.path.relpath(os.path.join(root, f), source_dir))
|
|
147
|
+
''', src_dir, meson.current_source_dir(), check : true)
|
|
148
|
+
_src_files = _find_src.stdout().strip().split('\n')
|
|
149
|
+
db_src = []
|
|
150
|
+
foreach f : _src_files
|
|
151
|
+
if f != ''
|
|
152
|
+
db_src += files(f)
|
|
153
|
+
endif
|
|
154
|
+
endforeach
|
|
155
|
+
|
|
156
|
+
inc_dirs = include_directories(
|
|
157
|
+
'../../include',
|
|
158
|
+
'../../src',
|
|
159
|
+
'../..',
|
|
160
|
+
'../../src/query/parser/cypher',
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
# Generate ProjectConfig.hpp from template
|
|
164
|
+
project_config = configuration_data()
|
|
165
|
+
project_config.set('PROJECT_NAME', 'zyx')
|
|
166
|
+
project_config.set('PROJECT_DISPLAY', 'ZYX')
|
|
167
|
+
project_config.set('PROJECT_VERSION', meson.project_version())
|
|
168
|
+
configure_file(
|
|
169
|
+
input: zyx_root / 'include' / 'graph' / 'core' / 'ProjectConfig.hpp.in',
|
|
170
|
+
output: 'ProjectConfig.hpp',
|
|
171
|
+
configuration: project_config,
|
|
172
|
+
install: false,
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Python's Token.h defines macros (SEMI, COMMA, etc.) that conflict with
|
|
176
|
+
# ANTLR4 parser method names. Force-include an undef header to neutralize them.
|
|
177
|
+
_undef_header = meson.current_source_dir() / 'undef_python_tokens.h'
|
|
178
|
+
if cxx.get_argument_syntax() == 'msvc'
|
|
179
|
+
_force_include = ['/FI' + _undef_header]
|
|
180
|
+
else
|
|
181
|
+
_force_include = ['-include', _undef_header]
|
|
182
|
+
endif
|
|
183
|
+
|
|
184
|
+
db_lib = static_library('zyx_core',
|
|
185
|
+
sources : db_src,
|
|
186
|
+
include_directories : inc_dirs,
|
|
187
|
+
dependencies : [zlib_dep, boost_dep, cli11_dep, antlr4_dep, cypher_dep, inputxx_dep],
|
|
188
|
+
cpp_args : ['-DCOVERAGE_SKIP_ZLIB_ERRORS'] + _force_include,
|
|
189
|
+
install : false,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
db_dep = declare_dependency(
|
|
193
|
+
include_directories : [inc_dirs, cypher_inc],
|
|
194
|
+
link_with : db_lib,
|
|
195
|
+
dependencies : [zlib_dep, boost_dep, cli11_dep, antlr4_dep, inputxx_dep],
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# ==============================================================================
|
|
199
|
+
# Python extension module
|
|
200
|
+
# ==============================================================================
|
|
201
|
+
py = import('python').find_installation(pure: false)
|
|
202
|
+
|
|
203
|
+
pybind11_dep = dependency('pybind11', required: true)
|
|
204
|
+
|
|
205
|
+
zyxdb_core = py.extension_module(
|
|
206
|
+
'_core',
|
|
207
|
+
sources: ['src/zyxdb/_core.cpp'],
|
|
208
|
+
dependencies: [pybind11_dep, db_dep],
|
|
209
|
+
include_directories: inc_dirs,
|
|
210
|
+
install: true,
|
|
211
|
+
subdir: 'zyxdb',
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
py.install_sources(
|
|
215
|
+
'src/zyxdb/__init__.py',
|
|
216
|
+
'src/zyxdb/database.py',
|
|
217
|
+
'src/zyxdb/result.py',
|
|
218
|
+
'src/zyxdb/transaction.py',
|
|
219
|
+
'src/zyxdb/types.py',
|
|
220
|
+
'src/zyxdb/py.typed',
|
|
221
|
+
subdir: 'zyxdb',
|
|
222
|
+
)
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["meson-python>=0.16.0", "pybind11>=2.13"]
|
|
3
|
+
build-backend = "mesonpy"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "zyxdb"
|
|
7
|
+
description = "Python bindings for ZYX graph database engine"
|
|
8
|
+
dynamic = ["version"]
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "Apache-2.0"}
|
|
11
|
+
requires-python = ">=3.9"
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 3 - Alpha",
|
|
14
|
+
"Intended Audience :: Developers",
|
|
15
|
+
"License :: OSI Approved :: Apache Software License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3.9",
|
|
18
|
+
"Programming Language :: Python :: 3.10",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: C++",
|
|
23
|
+
"Topic :: Database",
|
|
24
|
+
"Topic :: Database :: Database Engines/Servers",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
test = ["pytest>=7.0"]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/nexepic/zyx"
|
|
32
|
+
Repository = "https://github.com/nexepic/zyx"
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""zyxdb — Python bindings for ZYX graph database engine."""
|
|
2
|
+
|
|
3
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
4
|
+
|
|
5
|
+
from zyxdb._core import DatabaseError
|
|
6
|
+
from zyxdb.database import Database
|
|
7
|
+
from zyxdb.result import Record, Result
|
|
8
|
+
from zyxdb.transaction import Transaction
|
|
9
|
+
from zyxdb.types import Edge, Node
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
__version__ = version("zyxdb")
|
|
13
|
+
except PackageNotFoundError:
|
|
14
|
+
__version__ = "0.0.0-dev"
|
|
15
|
+
__all__ = [
|
|
16
|
+
"Database",
|
|
17
|
+
"DatabaseError",
|
|
18
|
+
"Edge",
|
|
19
|
+
"Node",
|
|
20
|
+
"Record",
|
|
21
|
+
"Result",
|
|
22
|
+
"Transaction",
|
|
23
|
+
]
|