nedb-engine 2.0.8__tar.gz → 2.0.9__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.0.8 → nedb_engine-2.0.9}/PKG-INFO +1 -1
- nedb_engine-2.0.9/client/node/README.md +192 -0
- nedb_engine-2.0.9/client/python/README.md +191 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/pyproject.toml +1 -1
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/__init__.py +1 -1
- nedb_engine-2.0.8/client/python/README.md +0 -55
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/.gitignore +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/LICENSE +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/README.md +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/autoindex.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/backends/__init__.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/backends/redis_backend.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/cascade.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/concurrent.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/crypto.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/engine.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/index.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/log.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/merkle.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/mongo.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/query.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/redis_compat.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/relations.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/resp2.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/server.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/snapshot.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/sql.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/store.py +0 -0
- {nedb_engine-2.0.8 → nedb_engine-2.0.9}/python/nedb/wrap_redis.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nedb-engine
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.9
|
|
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/Eth-Interchained/nedb
|
|
6
6
|
Project-URL: Repository, https://github.com/Eth-Interchained/nedb
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# nedb-engine-client
|
|
2
|
+
|
|
3
|
+
> TypeScript/JavaScript client for [nedbd](https://github.com/Eth-Interchained/nedb) — the NEDB server daemon.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/nedb-engine-client)
|
|
6
|
+
[](https://github.com/Eth-Interchained/nedb/blob/master/LICENSE)
|
|
7
|
+
|
|
8
|
+
Connect to any running `nedbd` instance from Node.js or the browser. No engine embedded, no native dependencies. Just fetch.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install nedb-engine-client
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Requires Node.js ≥ 18 (uses native `fetch`). Works in modern browsers too.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { NedbClient } from "nedb-engine-client";
|
|
26
|
+
|
|
27
|
+
const db = new NedbClient({ url: "http://127.0.0.1:7070", db: "mydb" });
|
|
28
|
+
|
|
29
|
+
// Write a document
|
|
30
|
+
await db.put("blocks", "618000", {
|
|
31
|
+
height: 618000,
|
|
32
|
+
hash: "000000000000000000024bead8df69990852c202db0e0097c1a12ea637d7e96d",
|
|
33
|
+
txCount: 2734,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Query with NQL
|
|
37
|
+
const rows = await db.query("FROM blocks ORDER BY height DESC LIMIT 10");
|
|
38
|
+
|
|
39
|
+
// Time-travel: what did the DB look like at seq 100?
|
|
40
|
+
const old = await db.query("FROM blocks AS OF 100 WHERE height > 600000");
|
|
41
|
+
|
|
42
|
+
// Bi-temporal: what was true on 2024-06-15?
|
|
43
|
+
const valid = await db.query('FROM policy VALID AS OF "2024-06-15"');
|
|
44
|
+
|
|
45
|
+
// BLAKE2b Merkle head — changes on every write, anchorable
|
|
46
|
+
const head = await db.head();
|
|
47
|
+
|
|
48
|
+
// Tamper-evidence check across all objects
|
|
49
|
+
const report = await db.verify();
|
|
50
|
+
console.assert(report.ok, "tamper detected!");
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## nedbd — start the server
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm install nedb-engine # or: pip install nedb-engine
|
|
59
|
+
|
|
60
|
+
# v2 DAG engine (recommended — instant cold start, tamper-evident)
|
|
61
|
+
NEDBD_DAG=1 nedbd --data ./data
|
|
62
|
+
|
|
63
|
+
# Check health
|
|
64
|
+
curl http://127.0.0.1:7070/health
|
|
65
|
+
# {"ok":true,"version":"2.0.8","service":"nedbd","encrypted":true}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## API reference
|
|
71
|
+
|
|
72
|
+
### Constructor
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
const db = new NedbClient({
|
|
76
|
+
url: "http://127.0.0.1:7070", // nedbd base URL
|
|
77
|
+
db: "mydb", // database name
|
|
78
|
+
token: "secret", // bearer auth (optional)
|
|
79
|
+
autoCreate: true, // create DB on first write
|
|
80
|
+
readTimeoutMs: 3_000, // query timeout
|
|
81
|
+
writeTimeoutMs: 30_000, // write timeout
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Writes
|
|
86
|
+
|
|
87
|
+
| Method | Description |
|
|
88
|
+
|--------|-------------|
|
|
89
|
+
| `db.put(coll, id, doc, opts?)` | Write a document |
|
|
90
|
+
| `db.delete(coll, id)` | Tombstone delete (history preserved in DAG) |
|
|
91
|
+
| `db.batch(ops)` | Batch put/del in one HTTP round-trip |
|
|
92
|
+
| `db.createIndex(coll, field)` | Create sorted index for ORDER BY |
|
|
93
|
+
|
|
94
|
+
**Put options:**
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
await db.put("claims", "c1", { fact: "..." }, {
|
|
98
|
+
causedBy: ["abc123hash"], // DAG causal provenance
|
|
99
|
+
validFrom: "2024-01-01", // bi-temporal valid window
|
|
100
|
+
validTo: "2024-12-31",
|
|
101
|
+
evidence: "sensor-42", // human-readable provenance note
|
|
102
|
+
confidence: 0.95, // confidence score 0–1
|
|
103
|
+
idem: "dedup-key", // idempotency key
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Reads
|
|
108
|
+
|
|
109
|
+
| Method | Description |
|
|
110
|
+
|--------|-------------|
|
|
111
|
+
| `db.get(coll, id)` | Fetch current version of a document |
|
|
112
|
+
| `db.query(nql)` | NQL query → array of objects |
|
|
113
|
+
| `db.queryFull(nql)` | NQL query → full response (rows + seq + head) |
|
|
114
|
+
|
|
115
|
+
### NQL — NEDB Query Language
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
FROM <collection>
|
|
119
|
+
[AS OF <seq>] transaction time (when was it written?)
|
|
120
|
+
[VALID AS OF "<date>"] valid time (when was it true in the world?)
|
|
121
|
+
[WHERE field = value [AND ...]] op: = != < <= > >=
|
|
122
|
+
[ORDER BY field [DESC]]
|
|
123
|
+
[LIMIT n]
|
|
124
|
+
[GROUP BY field COUNT|SUM|AVG|MIN|MAX]
|
|
125
|
+
[TRACE caused_by [REVERSE]] causal graph traversal
|
|
126
|
+
[SEARCH "text"] full-text search
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Integrity
|
|
130
|
+
|
|
131
|
+
| Method | Description |
|
|
132
|
+
|--------|-------------|
|
|
133
|
+
| `db.verify()` | BLAKE2b tamper-evidence check across all objects |
|
|
134
|
+
| `db.head()` | Current Merkle root — changes on every write |
|
|
135
|
+
| `db.seq()` | Current global sequence number |
|
|
136
|
+
| `db.log(limit?)` | Recent write log |
|
|
137
|
+
| `db.checkpoint()` | Explicit checkpoint (no-op on v2 DAG) |
|
|
138
|
+
|
|
139
|
+
### Server management
|
|
140
|
+
|
|
141
|
+
| Method | Description |
|
|
142
|
+
|--------|-------------|
|
|
143
|
+
| `db.health()` | Server health — version, databases, encryption |
|
|
144
|
+
| `db.ping()` | Boolean reachability check |
|
|
145
|
+
| `db.listDatabases()` | All databases on this server |
|
|
146
|
+
| `db.createDatabase()` | Create this database explicitly |
|
|
147
|
+
| `db.dropDatabase()` | Drop this database (irreversible) |
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Error handling
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { NedbClient, NedbError } from "nedb-engine-client";
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
await db.put("coll", "id", { data: "value" });
|
|
158
|
+
} catch (e) {
|
|
159
|
+
if (e instanceof NedbError) {
|
|
160
|
+
console.error(`HTTP ${e.status}: ${e.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Queries on missing collections return `[]` rather than throwing — resilient by default.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Batch writes
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
await db.batch([
|
|
173
|
+
{ op: "put", coll: "blocks", id: "618001", doc: { height: 618001 } },
|
|
174
|
+
{ op: "put", coll: "blocks", id: "618002", doc: { height: 618002 } },
|
|
175
|
+
{ op: "del", coll: "blocks", id: "617999" },
|
|
176
|
+
]);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
One HTTP request, multiple ops — best throughput for bulk ingestion.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Links
|
|
184
|
+
|
|
185
|
+
- **Engine:** [pip install nedb-engine](https://pypi.org/project/nedb-engine/) · [npm install nedb-engine](https://www.npmjs.com/package/nedb-engine)
|
|
186
|
+
- **Python client:** [pip install nedb-engine-client](https://pypi.org/project/nedb-engine-client/)
|
|
187
|
+
- **Source:** [github.com/Eth-Interchained/nedb](https://github.com/Eth-Interchained/nedb)
|
|
188
|
+
- **Studio:** [studio.interchained.org](https://studio.interchained.org)
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
© [INTERCHAINED, LLC](https://interchained.org) · GPL-3.0-or-later · Built with [Hyperagent](https://hyperagent.com/refer/J2G6TCD7)
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# nedb-engine-client
|
|
2
|
+
|
|
3
|
+
> Async Python client for [nedbd](https://github.com/Eth-Interchained/nedb) — the NEDB server daemon.
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/nedb-engine-client/)
|
|
6
|
+
[](https://pypi.org/project/nedb-engine-client/)
|
|
7
|
+
[](https://github.com/Eth-Interchained/nedb/blob/master/LICENSE)
|
|
8
|
+
|
|
9
|
+
Connect to any running `nedbd` instance — local or remote — with a clean async API. No engine code embedded, no Rust toolchain required. Just HTTP.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pip install nedb-engine-client
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Requires Python ≥ 3.8 and `httpx`.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Quick start
|
|
24
|
+
|
|
25
|
+
```python
|
|
26
|
+
import asyncio
|
|
27
|
+
from nedb_client import NedbClient
|
|
28
|
+
|
|
29
|
+
async def main():
|
|
30
|
+
async with NedbClient("http://127.0.0.1:7070", db="mydb") as db:
|
|
31
|
+
|
|
32
|
+
# Write a document
|
|
33
|
+
await db.put("blocks", "618000", {
|
|
34
|
+
"height": 618000,
|
|
35
|
+
"hash": "000000000000000000024bead8df69990852c202db0e0097c1a12ea637d7e96d",
|
|
36
|
+
"tx_count": 2734,
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
# Query with NQL
|
|
40
|
+
rows = await db.query("FROM blocks ORDER BY height DESC LIMIT 10")
|
|
41
|
+
|
|
42
|
+
# Time-travel: what did the DB look like at seq 100?
|
|
43
|
+
old = await db.query("FROM blocks AS OF 100 WHERE height > 600000")
|
|
44
|
+
|
|
45
|
+
# Bi-temporal: what was true on 2024-06-15?
|
|
46
|
+
valid = await db.query('FROM policy VALID AS OF "2024-06-15"')
|
|
47
|
+
|
|
48
|
+
# Causal trace: why was this written?
|
|
49
|
+
trace = await db.query("FROM blocks TRACE caused_by")
|
|
50
|
+
|
|
51
|
+
# BLAKE2b Merkle head — changes on every write, anchorable
|
|
52
|
+
head = await db.head()
|
|
53
|
+
print(f"head: {head}")
|
|
54
|
+
|
|
55
|
+
# Tamper-evidence check across all objects
|
|
56
|
+
report = await db.verify()
|
|
57
|
+
assert report["ok"], "tamper detected!"
|
|
58
|
+
|
|
59
|
+
asyncio.run(main())
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## nedbd — start the server
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
pip install nedb-engine
|
|
68
|
+
|
|
69
|
+
# v1 AOF engine (default)
|
|
70
|
+
nedbd --data ./data
|
|
71
|
+
|
|
72
|
+
# v2 DAG engine (recommended — instant cold start, tamper-evident)
|
|
73
|
+
NEDBD_DAG=1 nedbd --data ./data
|
|
74
|
+
|
|
75
|
+
# With AES-256-GCM encryption
|
|
76
|
+
NEDBD_DAG=1 NEDB_TMK=<32-byte-hex> nedbd --data ./data
|
|
77
|
+
|
|
78
|
+
# Check health
|
|
79
|
+
curl http://127.0.0.1:7070/health
|
|
80
|
+
# {"ok":true,"version":"2.0.8","service":"nedbd","encrypted":true}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## API reference
|
|
86
|
+
|
|
87
|
+
### Client lifecycle
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
# Async context manager (recommended)
|
|
91
|
+
async with NedbClient(url, db=name, token=token) as db:
|
|
92
|
+
...
|
|
93
|
+
|
|
94
|
+
# Manual
|
|
95
|
+
db = NedbClient(url="http://127.0.0.1:7070", db="mydb", token="secret")
|
|
96
|
+
await db.open()
|
|
97
|
+
await db.close()
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Writes
|
|
101
|
+
|
|
102
|
+
| Method | Description |
|
|
103
|
+
|--------|-------------|
|
|
104
|
+
| `await db.put(coll, id, doc, **opts)` | Write a document |
|
|
105
|
+
| `await db.delete(coll, id)` | Tombstone delete (history preserved in DAG) |
|
|
106
|
+
| `await db.batch(ops)` | Batch put/del in one HTTP round-trip |
|
|
107
|
+
| `await db.create_index(coll, field)` | Create sorted index for ORDER BY |
|
|
108
|
+
|
|
109
|
+
**Put options:**
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
await db.put("claims", "c1", {"fact": "..."},
|
|
113
|
+
caused_by=["abc123hash"], # DAG causal provenance
|
|
114
|
+
valid_from="2024-01-01", # bi-temporal valid window
|
|
115
|
+
valid_to="2024-12-31",
|
|
116
|
+
evidence="sensor-42", # human-readable provenance note
|
|
117
|
+
confidence=0.95, # confidence score 0–1
|
|
118
|
+
idem="dedup-key", # idempotency key
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Reads
|
|
123
|
+
|
|
124
|
+
| Method | Description |
|
|
125
|
+
|--------|-------------|
|
|
126
|
+
| `await db.get(coll, id)` | Fetch current version of a document |
|
|
127
|
+
| `await db.query(nql)` | NQL query → list of dicts |
|
|
128
|
+
| `await db.query_full(nql)` | NQL query → full response (rows + seq + head) |
|
|
129
|
+
|
|
130
|
+
### NQL — NEDB Query Language
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
FROM <collection>
|
|
134
|
+
[AS OF <seq>] transaction time (when was it written?)
|
|
135
|
+
[VALID AS OF "<date>"] valid time (when was it true in the world?)
|
|
136
|
+
[WHERE field = value [AND ...]] op: = != < <= > >=
|
|
137
|
+
[ORDER BY field [DESC]]
|
|
138
|
+
[LIMIT n]
|
|
139
|
+
[GROUP BY field COUNT|SUM|AVG|MIN|MAX]
|
|
140
|
+
[TRACE caused_by [REVERSE]] causal graph traversal
|
|
141
|
+
[SEARCH "text"] full-text search
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Integrity
|
|
145
|
+
|
|
146
|
+
| Method | Description |
|
|
147
|
+
|--------|-------------|
|
|
148
|
+
| `await db.verify()` | BLAKE2b tamper-evidence check across all objects |
|
|
149
|
+
| `await db.head()` | Current Merkle root — changes on every write |
|
|
150
|
+
| `await db.seq()` | Current global sequence number |
|
|
151
|
+
| `await db.log(limit)` | Recent write log |
|
|
152
|
+
| `await db.checkpoint()` | Explicit checkpoint (no-op on v2 DAG) |
|
|
153
|
+
|
|
154
|
+
### Server management
|
|
155
|
+
|
|
156
|
+
| Method | Description |
|
|
157
|
+
|--------|-------------|
|
|
158
|
+
| `await db.health()` | Server health — version, databases, encryption |
|
|
159
|
+
| `await db.ping()` | Boolean reachability check |
|
|
160
|
+
| `await db.list_databases()` | All databases on this server |
|
|
161
|
+
| `await db.create_database()` | Create this database explicitly |
|
|
162
|
+
| `await db.drop_database()` | Drop this database (irreversible) |
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Error handling
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from nedb_client import NedbClient, NedbError
|
|
170
|
+
|
|
171
|
+
async with NedbClient("http://127.0.0.1:7070", db="mydb") as db:
|
|
172
|
+
try:
|
|
173
|
+
await db.put("coll", "id", {"data": "value"})
|
|
174
|
+
except NedbError as e:
|
|
175
|
+
print(f"HTTP {e.status}: {e.message}")
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Queries on missing collections return `[]` rather than raising — resilient by default.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Links
|
|
183
|
+
|
|
184
|
+
- **Engine:** [pip install nedb-engine](https://pypi.org/project/nedb-engine/) · [npm install nedb-engine](https://www.npmjs.com/package/nedb-engine)
|
|
185
|
+
- **JS/TS client:** [npm install nedb-engine-client](https://www.npmjs.com/package/nedb-engine-client)
|
|
186
|
+
- **Source:** [github.com/Eth-Interchained/nedb](https://github.com/Eth-Interchained/nedb)
|
|
187
|
+
- **Studio:** [studio.interchained.org](https://studio.interchained.org)
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
© [INTERCHAINED, LLC](https://interchained.org) · GPL-3.0-or-later · Built with [Hyperagent](https://hyperagent.com/refer/J2G6TCD7)
|
|
@@ -10,7 +10,7 @@ build-backend = "hatchling.build"
|
|
|
10
10
|
|
|
11
11
|
[project]
|
|
12
12
|
name = "nedb-engine"
|
|
13
|
-
version = "2.0.
|
|
13
|
+
version = "2.0.9"
|
|
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"
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
# nedb-client (Python)
|
|
2
|
-
|
|
3
|
-
Async Python client for the [nedbd](https://github.com/Eth-Interchained/nedb) HTTP API.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
pip install nedb-client
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
## Quick start
|
|
10
|
-
|
|
11
|
-
```python
|
|
12
|
-
from nedb_client import NedbClient
|
|
13
|
-
|
|
14
|
-
async with NedbClient("http://127.0.0.1:7070", db="mydb") as db:
|
|
15
|
-
# Write
|
|
16
|
-
await db.put("blocks", "618000", {"height": 618000, "hash": "000abc"})
|
|
17
|
-
|
|
18
|
-
# Query (full NQL)
|
|
19
|
-
rows = await db.query("FROM blocks ORDER BY height DESC LIMIT 10")
|
|
20
|
-
|
|
21
|
-
# Causal provenance + bi-temporal
|
|
22
|
-
result = await db.put("claims", "c1", {"fact": "..."},
|
|
23
|
-
caused_by=["abc123..."],
|
|
24
|
-
valid_from="2024-01-01",
|
|
25
|
-
evidence="sensor-42")
|
|
26
|
-
|
|
27
|
-
# Merkle head (tamper-evident root)
|
|
28
|
-
head = await db.head()
|
|
29
|
-
|
|
30
|
-
# Full tamper-evidence check
|
|
31
|
-
report = await db.verify()
|
|
32
|
-
assert report["ok"]
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## API
|
|
36
|
-
|
|
37
|
-
| Method | Description |
|
|
38
|
-
|--------|-------------|
|
|
39
|
-
| `put(coll, id, doc, **meta)` | Write a document |
|
|
40
|
-
| `get(coll, id)` | Fetch current version |
|
|
41
|
-
| `delete(coll, id)` | Tombstone delete |
|
|
42
|
-
| `query(nql)` | NQL query → list of dicts |
|
|
43
|
-
| `query_full(nql)` | NQL query → full response with seq + head |
|
|
44
|
-
| `batch(ops)` | Batch put/del in one round-trip |
|
|
45
|
-
| `create_index(coll, field)` | Create sorted index |
|
|
46
|
-
| `verify()` | BLAKE2b tamper-evidence check |
|
|
47
|
-
| `head()` | Current Merkle head |
|
|
48
|
-
| `seq()` | Current sequence number |
|
|
49
|
-
| `checkpoint()` | Explicit checkpoint |
|
|
50
|
-
| `log(limit)` | Recent write log |
|
|
51
|
-
| `health()` | Server health |
|
|
52
|
-
| `ping()` | Boolean reachability check |
|
|
53
|
-
| `list_databases()` | All databases on server |
|
|
54
|
-
| `create_database()` | Create this database |
|
|
55
|
-
| `drop_database()` | Drop this database |
|
|
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
|