idb-engine 0.1.0__py3-none-win_amd64.whl

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.
idb/__init__.py ADDED
@@ -0,0 +1,322 @@
1
+ """idb — Python bindings for the idb embedded database (ctypes → idb_engine)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ctypes
6
+ import json
7
+ import os
8
+ import platform
9
+ from ctypes import c_char_p, c_uint32, c_void_p
10
+ from typing import Any, Optional
11
+
12
+ EXPECTED_API_VERSION = 2
13
+
14
+
15
+ class IdbError(RuntimeError):
16
+ """Raised when an IQL/FFI call returns ``{"error": ...}`` and check=True."""
17
+
18
+
19
+ def _default_library_name() -> str:
20
+ system = platform.system().lower()
21
+ if "windows" in system:
22
+ return "idb_engine.dll"
23
+ if "darwin" in system:
24
+ return "libidb_engine.dylib"
25
+ return "libidb_engine.so"
26
+
27
+
28
+ def _plat_dir() -> str:
29
+ system = platform.system().lower()
30
+ machine = platform.machine().lower()
31
+ if "windows" in system:
32
+ return "win_amd64" if machine in ("amd64", "x86_64") else f"win_{machine}"
33
+ if "darwin" in system:
34
+ return "macosx_arm64" if machine in ("arm64", "aarch64") else "macosx_x86_64"
35
+ return "manylinux_x86_64" if machine in ("x86_64", "amd64") else f"manylinux_{machine}"
36
+
37
+
38
+ def _candidate_library_paths(explicit: str | None) -> list[str]:
39
+ name = _default_library_name()
40
+ here = os.path.dirname(os.path.abspath(__file__))
41
+ pkg_root = here
42
+ repo_root = os.path.dirname(here)
43
+ if os.path.basename(here) == "idb" and os.path.basename(repo_root) == "python":
44
+ repo_root = os.path.dirname(repo_root)
45
+ pkg_root = here
46
+ out: list[str] = []
47
+ if explicit:
48
+ out.append(explicit)
49
+ env = os.environ.get("IDB_LIBRARY_PATH")
50
+ if env:
51
+ out.append(env)
52
+ out.append(os.path.join(pkg_root, "_bin", _plat_dir(), name))
53
+ out.append(os.path.join(repo_root, "idb", "_bin", _plat_dir(), name))
54
+ out.append(os.path.join(repo_root, "target", "release", name))
55
+ out.append(os.path.join(here, "..", "target", "release", name))
56
+ out.append(os.path.join(repo_root, "target", "debug", name))
57
+ out.append(os.path.join(here, "..", "target", "debug", name))
58
+ seen: set[str] = set()
59
+ uniq: list[str] = []
60
+ for p in out:
61
+ ap = os.path.normpath(os.path.abspath(p))
62
+ if ap not in seen:
63
+ seen.add(ap)
64
+ uniq.append(ap)
65
+ return uniq
66
+
67
+
68
+ def _bind(lib: ctypes.CDLL) -> None:
69
+ lib.idb_open.restype = c_void_p
70
+ lib.idb_open.argtypes = [c_char_p]
71
+ if hasattr(lib, "idb_open_with_key"):
72
+ lib.idb_open_with_key.restype = c_void_p
73
+ lib.idb_open_with_key.argtypes = [c_char_p, c_char_p]
74
+ lib.idb_connect.restype = c_void_p
75
+ lib.idb_connect.argtypes = [c_void_p]
76
+ lib.idb_disconnect.argtypes = [c_void_p]
77
+ # IMPORTANT: string results must be c_void_p so we can idb_free_str the real pointer.
78
+ # c_char_p would auto-convert and make free_str corrupt the heap.
79
+ for name in (
80
+ "idb_run",
81
+ "idb_conn_run",
82
+ "idb_run_with_params",
83
+ "idb_begin",
84
+ "idb_commit",
85
+ "idb_abort",
86
+ "idb_conn_begin",
87
+ "idb_conn_commit",
88
+ "idb_conn_abort",
89
+ "idb_checkpoint",
90
+ "idb_gc",
91
+ "idb_vacuum",
92
+ "idb_schema_info",
93
+ ):
94
+ if hasattr(lib, name):
95
+ getattr(lib, name).restype = c_void_p
96
+ lib.idb_run.argtypes = [c_void_p, c_char_p]
97
+ lib.idb_conn_run.argtypes = [c_void_p, c_char_p]
98
+ lib.idb_run_with_params.argtypes = [c_void_p, c_char_p, c_char_p]
99
+ if hasattr(lib, "idb_conn_run_with_params"):
100
+ lib.idb_conn_run_with_params.restype = c_void_p
101
+ lib.idb_conn_run_with_params.argtypes = [c_void_p, c_char_p, c_char_p]
102
+ for name in (
103
+ "idb_begin",
104
+ "idb_commit",
105
+ "idb_abort",
106
+ "idb_conn_begin",
107
+ "idb_conn_commit",
108
+ "idb_conn_abort",
109
+ "idb_checkpoint",
110
+ "idb_gc",
111
+ "idb_vacuum",
112
+ "idb_schema_info",
113
+ ):
114
+ getattr(lib, name).argtypes = [c_void_p]
115
+ if hasattr(lib, "idb_vacuum_full"):
116
+ lib.idb_vacuum_full.restype = c_void_p
117
+ lib.idb_vacuum_full.argtypes = [c_void_p]
118
+ if hasattr(lib, "idb_backup"):
119
+ lib.idb_backup.restype = c_void_p
120
+ lib.idb_backup.argtypes = [c_void_p, c_char_p]
121
+ lib.idb_close.argtypes = [c_void_p]
122
+ lib.idb_free_str.argtypes = [c_void_p]
123
+ if hasattr(lib, "idb_api_version"):
124
+ lib.idb_api_version.restype = c_uint32
125
+ lib.idb_api_version.argtypes = []
126
+ if hasattr(lib, "idb_format_version"):
127
+ lib.idb_format_version.restype = c_uint32
128
+ lib.idb_format_version.argtypes = []
129
+
130
+
131
+ def _load_lib(library_path: str | None = None) -> ctypes.CDLL:
132
+ last_err: OSError | None = None
133
+ lib: ctypes.CDLL | None = None
134
+ for path in _candidate_library_paths(library_path):
135
+ if not os.path.isfile(path):
136
+ continue
137
+ try:
138
+ lib = ctypes.CDLL(path)
139
+ break
140
+ except OSError as e:
141
+ last_err = e
142
+ continue
143
+ if lib is None:
144
+ tried = "\n ".join(_candidate_library_paths(library_path))
145
+ raise RuntimeError(
146
+ "failed to load idb_engine shared library.\n"
147
+ "Install a platform wheel (pip install idb-engine) or build natives:\n"
148
+ " powershell -File scripts/build-release.ps1\n"
149
+ " # or: scripts/build-release.sh\n"
150
+ f"Tried:\n {tried}"
151
+ ) from last_err
152
+ _bind(lib)
153
+ if hasattr(lib, "idb_api_version"):
154
+ ver = int(lib.idb_api_version())
155
+ if ver < EXPECTED_API_VERSION:
156
+ raise RuntimeError(
157
+ f"idb_engine API {ver} < required {EXPECTED_API_VERSION}; rebuild the shared library"
158
+ )
159
+ return lib
160
+
161
+
162
+ def _raise_if_error(results: list[Any], check: bool) -> list[Any]:
163
+ if not check:
164
+ return results
165
+ for item in results:
166
+ if isinstance(item, dict) and "error" in item:
167
+ raise IdbError(str(item["error"]))
168
+ return results
169
+
170
+
171
+ class IdbConnection:
172
+ """Отдельная session (явные begin/commit не пересекаются с другими)."""
173
+
174
+ def __init__(self, lib: ctypes.CDLL, handle: int, check: bool = True):
175
+ self._lib = lib
176
+ self._conn = handle
177
+ self.check = check
178
+
179
+ def run(self, script: str) -> list[Any]:
180
+ raw = self._lib.idb_conn_run(self._conn, script.encode("utf-8"))
181
+ return _raise_if_error(self._decode(raw), self.check)
182
+
183
+ def run_with_params(self, script: str, params: dict) -> list[Any]:
184
+ if not hasattr(self._lib, "idb_conn_run_with_params"):
185
+ raise RuntimeError("idb_conn_run_with_params unavailable")
186
+ raw = self._lib.idb_conn_run_with_params(
187
+ self._conn,
188
+ script.encode("utf-8"),
189
+ json.dumps(params).encode("utf-8"),
190
+ )
191
+ return _raise_if_error(self._decode(raw), self.check)
192
+
193
+ def begin(self) -> list[Any]:
194
+ return _raise_if_error(self._decode(self._lib.idb_conn_begin(self._conn)), self.check)
195
+
196
+ def commit(self) -> list[Any]:
197
+ return _raise_if_error(self._decode(self._lib.idb_conn_commit(self._conn)), self.check)
198
+
199
+ def abort(self) -> list[Any]:
200
+ return _raise_if_error(self._decode(self._lib.idb_conn_abort(self._conn)), self.check)
201
+
202
+ def _decode(self, raw) -> list[Any]:
203
+ if not raw:
204
+ return []
205
+ try:
206
+ text = ctypes.string_at(raw).decode("utf-8")
207
+ return json.loads(text)
208
+ finally:
209
+ self._lib.idb_free_str(raw)
210
+
211
+ def close(self) -> None:
212
+ if self._conn:
213
+ self._lib.idb_disconnect(self._conn)
214
+ self._conn = None
215
+
216
+ def __enter__(self):
217
+ return self
218
+
219
+ def __exit__(self, *args):
220
+ self.close()
221
+
222
+
223
+ class Idb:
224
+ def __init__(
225
+ self,
226
+ db_path: str,
227
+ library_path: str | None = None,
228
+ key: str | None = None,
229
+ check: bool = True,
230
+ ):
231
+ self._lib = _load_lib(library_path)
232
+ self.check = check
233
+ key = key or os.environ.get("IDB_KEY")
234
+ if key:
235
+ if not hasattr(self._lib, "idb_open_with_key"):
236
+ raise RuntimeError("idb_open_with_key unavailable")
237
+ self._db = self._lib.idb_open_with_key(
238
+ db_path.encode("utf-8"), key.encode("utf-8")
239
+ )
240
+ else:
241
+ self._db = self._lib.idb_open(db_path.encode("utf-8"))
242
+ if not self._db:
243
+ raise RuntimeError(f"failed to open database: {db_path}")
244
+
245
+ def connect(self) -> IdbConnection:
246
+ handle = self._lib.idb_connect(self._db)
247
+ if not handle:
248
+ raise RuntimeError("idb_connect failed")
249
+ return IdbConnection(self._lib, handle, check=self.check)
250
+
251
+ def run(self, script: str) -> list[Any]:
252
+ raw = self._lib.idb_run(self._db, script.encode("utf-8"))
253
+ return _raise_if_error(self._decode_json(raw), self.check)
254
+
255
+ def run_with_params(self, script: str, params: dict) -> list[Any]:
256
+ raw = self._lib.idb_run_with_params(
257
+ self._db,
258
+ script.encode("utf-8"),
259
+ json.dumps(params).encode("utf-8"),
260
+ )
261
+ return _raise_if_error(self._decode_json(raw), self.check)
262
+
263
+ def begin(self) -> list[Any]:
264
+ return _raise_if_error(self._decode_json(self._lib.idb_begin(self._db)), self.check)
265
+
266
+ def commit(self) -> list[Any]:
267
+ return _raise_if_error(self._decode_json(self._lib.idb_commit(self._db)), self.check)
268
+
269
+ def abort(self) -> list[Any]:
270
+ return _raise_if_error(self._decode_json(self._lib.idb_abort(self._db)), self.check)
271
+
272
+ def checkpoint(self) -> list[Any]:
273
+ return _raise_if_error(self._decode_json(self._lib.idb_checkpoint(self._db)), self.check)
274
+
275
+ def gc(self) -> list[Any]:
276
+ return _raise_if_error(self._decode_json(self._lib.idb_gc(self._db)), self.check)
277
+
278
+ def vacuum(self) -> list[Any]:
279
+ return _raise_if_error(self._decode_json(self._lib.idb_vacuum(self._db)), self.check)
280
+
281
+ def vacuum_full(self) -> list[Any]:
282
+ if not hasattr(self._lib, "idb_vacuum_full"):
283
+ raise RuntimeError("idb_vacuum_full unavailable")
284
+ return _raise_if_error(
285
+ self._decode_json(self._lib.idb_vacuum_full(self._db)), self.check
286
+ )
287
+
288
+ def backup(self, dest: str) -> list[Any]:
289
+ if not hasattr(self._lib, "idb_backup"):
290
+ raise RuntimeError("idb_backup unavailable")
291
+ return _raise_if_error(
292
+ self._decode_json(self._lib.idb_backup(self._db, dest.encode("utf-8"))),
293
+ self.check,
294
+ )
295
+
296
+ def schema_info(self) -> list[Any]:
297
+ return _raise_if_error(
298
+ self._decode_json(self._lib.idb_schema_info(self._db)), self.check
299
+ )
300
+
301
+ def _decode_json(self, raw) -> list[Any]:
302
+ if not raw:
303
+ return []
304
+ try:
305
+ text = ctypes.string_at(raw).decode("utf-8")
306
+ return json.loads(text)
307
+ finally:
308
+ self._lib.idb_free_str(raw)
309
+
310
+ def close(self) -> None:
311
+ if self._db:
312
+ self._lib.idb_close(self._db)
313
+ self._db = None
314
+
315
+ def __enter__(self):
316
+ return self
317
+
318
+ def __exit__(self, exc_type, exc, tb):
319
+ self.close()
320
+
321
+
322
+ __all__ = ["Idb", "IdbConnection", "IdbError", "EXPECTED_API_VERSION"]
Binary file
Binary file
idb/py.typed ADDED
File without changes
@@ -0,0 +1,97 @@
1
+ Metadata-Version: 2.4
2
+ Name: idb-engine
3
+ Version: 0.1.0
4
+ Summary: Embedded multi-model database (binary package; source is proprietary)
5
+ Author: IDB
6
+ Project-URL: Homepage, https://github.com/tretakovpavel681-design/IDB-realese
7
+ Project-URL: Releases, https://github.com/tretakovpavel681-design/IDB-realese/releases
8
+ Keywords: database,embedded,iql,ffi
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Topic :: Database
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Dynamic: license-file
17
+
18
+ # IDB
19
+
20
+ Встраиваемая multi-model база данных. **Бесплатна для использования.**
21
+ Распространяется как готовые программы и пакеты (**без исходного кода**).
22
+
23
+ ## Скачать
24
+
25
+ | Что | Откуда |
26
+ |-----|--------|
27
+ | CLI (`idb.exe` / `idb`) | [GitHub Releases](https://github.com/tretakovpavel681-design/IDB/releases) |
28
+ | Python | `pip install idb-engine` (когда пакет опубликован) или `.whl` из Releases |
29
+ | Node.js | `npm install idb-engine` (когда пакет опубликован) или `.tgz` из Releases |
30
+
31
+ Сборка из исходников **не предлагается** — исходный код закрыт.
32
+
33
+ ## Быстрый старт (CLI)
34
+
35
+ 1. Скачайте `idb` / `idb.exe` для вашей ОС из Releases.
36
+ 2. Запустите:
37
+
38
+ ```text
39
+ idb demo.idb
40
+ ```
41
+
42
+ Если файла нет — создаётся новый `demo.idb` (как у SQLite: один файл БД рядом с программой).
43
+
44
+ ```text
45
+ idb --json demo.idb script.iql
46
+ idb --key <64-hex-символа> secure.idb
47
+ ```
48
+
49
+ Команды shell: `.exit` `.help` `.schemas` `.vacuum` `.checkpoint` `.backup` `.gc`
50
+
51
+ ## Python
52
+
53
+ ```bash
54
+ pip install idb-engine
55
+ ```
56
+
57
+ ```python
58
+ from idb import Idb
59
+
60
+ with Idb("demo.idb") as db:
61
+ db.run("create schema Item index by id")
62
+ db.run("insert Item =\n id = 1\n name = Ada")
63
+ print(db.run("select Item =\n name"))
64
+ ```
65
+
66
+ Шифрование страниц: `Idb("sec.idb", key="…64 hex…")` или переменная `IDB_KEY`.
67
+
68
+ ## Node.js
69
+
70
+ ```bash
71
+ npm install idb-engine koffi
72
+ ```
73
+
74
+ ```js
75
+ const { Idb } = require("idb-engine");
76
+ const db = new Idb("demo.idb");
77
+ db.run("create schema Item index by id");
78
+ console.log(db.run("select Item =\n id"));
79
+ db.close();
80
+ ```
81
+
82
+ ## Возможности
83
+
84
+ - файл `.idb` + WAL / MVCC / vacuum / backup
85
+ - язык запросов IQL (CRUD, фильтры, joins, EXISTS, FTS, EXPLAIN)
86
+ - индексы B+Tree, covering, HashJoin
87
+ - опциональное шифрование страниц
88
+ - FFI для встраивания (C / Python / JS) — см. бинарный SDK в Releases
89
+
90
+ ## Лицензия
91
+
92
+ Бесплатное использование бинарников. Исходный код **не** открыт.
93
+ См. файл [LICENSE](LICENSE).
94
+
95
+ ## Поддержка
96
+
97
+ Issues / обсуждения — в репозитории Releases или указанном канале поддержки правообладателя.
@@ -0,0 +1,9 @@
1
+ idb/__init__.py,sha256=GqJE2hCggulVzggn8G1zomMxjBND6tBWK4Ulv0Se1WQ,11440
2
+ idb/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ idb/_bin/win_amd64/idb.exe,sha256=_-aJEzeF-cIkXrvsLSgk-7Y_3mdN0VIWPampWaN9b-U,1679872
4
+ idb/_bin/win_amd64/idb_engine.dll,sha256=n-_My7INa3a6DBQCKrSJHtClX29b52Tm5FtLozHmVjA,1678848
5
+ idb_engine-0.1.0.dist-info/licenses/LICENSE,sha256=-cwne5e-ovijZLbKmWwMZPJsU1u0yXBiUe2yR7VJD6A,2411
6
+ idb_engine-0.1.0.dist-info/METADATA,sha256=2Y2uMoX9OWGYQNGpnENcb0-S0SPTiC1-BP-AYsCJoWQ,3321
7
+ idb_engine-0.1.0.dist-info/WHEEL,sha256=3I5VVWZdsFlU417aCS2bMRuerS8wsfvBq99MyatBV3A,97
8
+ idb_engine-0.1.0.dist-info/top_level.txt,sha256=w7UowfB_EDA-_Ui_mVJPjF7QrDIig_z0vmq5ZAGw3oY,4
9
+ idb_engine-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-win_amd64
5
+
@@ -0,0 +1,55 @@
1
+ IDB Freeware License (Binary Distribution)
2
+ Version 1.0
3
+
4
+ Copyright (c) 2026 IDB authors. All rights reserved.
5
+
6
+ SUMMARY
7
+ IDB is provided free of charge as compiled binaries and language
8
+ packages (CLI, shared libraries, pip/npm wheels). Source code is
9
+ proprietary and is not licensed for public use or redistribution.
10
+
11
+ 1. GRANT OF LICENSE
12
+ Subject to this License, you may install and use the IDB software
13
+ (the "Software"), free of charge, for any purpose, including
14
+ personal and commercial use, on any number of machines.
15
+
16
+ 2. WHAT YOU MAY DO
17
+ - Use the Software as an embedded or standalone database.
18
+ - Redistribute unmodified official binary packages (CLI installers,
19
+ platform wheels, npm tarballs) obtained from the copyright holder
20
+ or authorized release channels, provided this License accompanies
21
+ them and you do not charge a separate fee solely for the Software
22
+ itself (hosting/bandwidth costs are fine).
23
+
24
+ 3. WHAT YOU MAY NOT DO
25
+ - Copy, publish, share, or redistribute the Software source code.
26
+ - Create derivative works from the source code.
27
+ - Reverse engineer, decompile, or disassemble the Software except
28
+ to the limited extent that applicable law expressly prohibits
29
+ such restriction.
30
+ - Remove or alter copyright, attribution, or license notices.
31
+ - Use the name "IDB" or related marks to imply endorsement of
32
+ your product without prior written permission.
33
+
34
+ 4. NO SOURCE CODE LICENSE
35
+ This License does not grant any rights to the Software source code,
36
+ build scripts beyond what is needed to consume official packages,
37
+ tests, or internal documentation. Access to source (if any) is
38
+ under a separate written agreement only.
39
+
40
+ 5. UPDATES
41
+ Updates may be provided at the copyright holder's discretion and
42
+ are governed by this License unless accompanied by different terms.
43
+
44
+ 6. NO WARRANTY
45
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
48
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
49
+ BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY ARISING FROM
50
+ USE OF THE SOFTWARE.
51
+
52
+ 7. TERMINATION
53
+ This License terminates automatically if you breach it. Upon
54
+ termination you must stop using and destroy copies of the Software
55
+ obtained under this License, except as required by law.
@@ -0,0 +1 @@
1
+ idb