nedb-engine 2.1.0__tar.gz → 2.2.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.
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/PKG-INFO +1 -1
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/pyproject.toml +1 -1
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/__init__.py +1 -1
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/wrap_redis.py +64 -17
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/.gitignore +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/LICENSE +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/README.md +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/client/node/README.md +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/client/python/README.md +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/autoindex.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/backends/__init__.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/backends/redis_backend.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/cascade.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/concurrent.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/crypto.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/engine.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/index.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/log.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/merkle.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/mongo.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/query.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/redis_compat.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/relations.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/resp2.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/server.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/snapshot.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/sql.py +0 -0
- {nedb_engine-2.1.0 → nedb_engine-2.2.0}/python/nedb/store.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nedb-engine
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: NEDB — a versioned, self-compressing, time-traveling embedded database (replay-protected, idempotent, relational, searchable) with durable AOF persistence and a server daemon (nedbd).
|
|
5
5
|
Project-URL: Homepage, https://github.com/aiassistsecure/nedb
|
|
6
6
|
Project-URL: Repository, https://github.com/aiassistsecure/nedb
|
|
@@ -10,7 +10,7 @@ build-backend = "hatchling.build"
|
|
|
10
10
|
|
|
11
11
|
[project]
|
|
12
12
|
name = "nedb-engine"
|
|
13
|
-
version = "2.
|
|
13
|
+
version = "2.2.0"
|
|
14
14
|
description = "NEDB — a versioned, self-compressing, time-traveling embedded database (replay-protected, idempotent, relational, searchable) with durable AOF persistence and a server daemon (nedbd)."
|
|
15
15
|
readme = "README.md"
|
|
16
16
|
requires-python = ">=3.8"
|
|
@@ -151,12 +151,31 @@ class NedBdProxy:
|
|
|
151
151
|
self._req("DELETE", f"/v1/databases/{self._name}/rows/{coll}/{id}")
|
|
152
152
|
|
|
153
153
|
def link(self, frm: str, rel: str, to: str, **_kw) -> None:
|
|
154
|
-
|
|
154
|
+
# v1 nedbd has POST /link; v2 DAG stores relations as NQL-queryable docs
|
|
155
|
+
# in a __links__ collection — compatible with TRAVERSE queries.
|
|
156
|
+
try:
|
|
157
|
+
self._req("POST", self._db("/link"), {"frm": frm, "rel": rel, "to": to})
|
|
158
|
+
except RuntimeError as e:
|
|
159
|
+
if "404" in str(e) or "not found" in str(e).lower():
|
|
160
|
+
# v2 DAG: store as a document so NQL can traverse it
|
|
161
|
+
self._req("POST", self._db("/put"), {
|
|
162
|
+
"coll": "__links__",
|
|
163
|
+
"id": f"{frm}|{rel}|{to}",
|
|
164
|
+
"doc": {"_from": frm, "_rel": rel, "_to": to},
|
|
165
|
+
})
|
|
166
|
+
else:
|
|
167
|
+
raise
|
|
155
168
|
|
|
156
169
|
def unlink(self, frm: str, rel: str, to: str, **_kw) -> None:
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
170
|
+
try:
|
|
171
|
+
self._req("DELETE", f"/v1/databases/{self._name}/links/{frm}/{rel}/{to}")
|
|
172
|
+
except RuntimeError:
|
|
173
|
+
# v2 fallback: tombstone the __links__ doc
|
|
174
|
+
try:
|
|
175
|
+
self._req("DELETE",
|
|
176
|
+
f"/v1/databases/{self._name}/rows/__links__/{frm}|{rel}|{to}")
|
|
177
|
+
except RuntimeError:
|
|
178
|
+
pass
|
|
160
179
|
|
|
161
180
|
def neighbors(self, frm: str, rel: str, as_of: Optional[int] = None) -> List[str]:
|
|
162
181
|
frm_coll, frm_id = (frm.split(":", 1) + [""])[:2]
|
|
@@ -423,9 +442,28 @@ class NEDBSurface:
|
|
|
423
442
|
return total
|
|
424
443
|
|
|
425
444
|
def _backfill_one(self, mapping: CollectionMapping, batch_size: int) -> int:
|
|
426
|
-
"""Import all keys matching one mapping from Redis into NEDB.
|
|
427
|
-
|
|
428
|
-
|
|
445
|
+
"""Import all keys matching one mapping from Redis into NEDB.
|
|
446
|
+
|
|
447
|
+
In nedbd mode uses /batch for high throughput (v2 DAG: ~4000 ops/s).
|
|
448
|
+
In-process mode falls back to individual puts.
|
|
449
|
+
"""
|
|
450
|
+
count = 0
|
|
451
|
+
cursor = 0
|
|
452
|
+
pending: List[dict] = []
|
|
453
|
+
|
|
454
|
+
def _flush() -> int:
|
|
455
|
+
if not pending or not self._nedbd_mode:
|
|
456
|
+
return 0
|
|
457
|
+
proxy: NedBdProxy = self._db # type: ignore[assignment]
|
|
458
|
+
try:
|
|
459
|
+
r = proxy._req("POST", proxy._db("/batch"), {"ops": list(pending)})
|
|
460
|
+
n = r.get("count", len(pending))
|
|
461
|
+
pending.clear()
|
|
462
|
+
return n
|
|
463
|
+
except Exception:
|
|
464
|
+
pending.clear()
|
|
465
|
+
return 0
|
|
466
|
+
|
|
429
467
|
while True:
|
|
430
468
|
cursor, keys = self._r.scan(cursor, match=mapping.pattern,
|
|
431
469
|
count=batch_size)
|
|
@@ -441,16 +479,24 @@ class NEDBSurface:
|
|
|
441
479
|
continue
|
|
442
480
|
doc = mapping.parse_value(raw_val)
|
|
443
481
|
doc.setdefault("_source", "backfill")
|
|
444
|
-
self.
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
482
|
+
if self._nedbd_mode:
|
|
483
|
+
pending.append({"op": "put", "coll": mapping.collection,
|
|
484
|
+
"id": doc_id, "doc": doc})
|
|
485
|
+
if len(pending) >= 500:
|
|
486
|
+
count += _flush()
|
|
487
|
+
else:
|
|
488
|
+
self._db.put(mapping.collection, doc_id, doc,
|
|
489
|
+
client="__backfill__",
|
|
490
|
+
evidence="backfill",
|
|
491
|
+
confidence=1.0)
|
|
492
|
+
self._persist_last_op()
|
|
493
|
+
count += 1
|
|
450
494
|
except Exception:
|
|
451
495
|
pass # skip unreadable keys
|
|
452
496
|
if cursor == 0:
|
|
453
497
|
break
|
|
498
|
+
|
|
499
|
+
count += _flush() # flush remainder
|
|
454
500
|
return count
|
|
455
501
|
|
|
456
502
|
# ── Write shadowing ───────────────────────────────────────────────────────
|
|
@@ -641,10 +687,11 @@ def wrap_redis(r: Any, db_name: str = "default",
|
|
|
641
687
|
Args:
|
|
642
688
|
r: An existing ``redis.Redis`` (or compatible) connection.
|
|
643
689
|
db_name: Logical database name. NEDB uses ``nedb:{db_name}:*``.
|
|
644
|
-
nedbd_url: Optional URL of a running nedbd server
|
|
645
|
-
``"http://localhost:
|
|
646
|
-
|
|
647
|
-
|
|
690
|
+
nedbd_url: Optional URL of a running nedbd server.
|
|
691
|
+
v1 AOF: ``"http://localhost:7070"`` (nedbd, no flag)
|
|
692
|
+
v2 DAG: ``"http://localhost:7070"`` (nedbd --dag)
|
|
693
|
+
When set, all r.nedb.* calls go to nedbd over HTTP.
|
|
694
|
+
v2 DAG backfill uses /batch for ~4000 ops/s throughput.
|
|
648
695
|
nedbd_token: Optional bearer token for nedbd authentication
|
|
649
696
|
(set via ``NEDBD_TOKEN`` env on the server).
|
|
650
697
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|