axiodb 19.1.1 → 20.3.2
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.
- package/README.md +86 -9
- package/cli/VERSION +1 -1
- package/cli/cmd/auth_management.go +68 -0
- package/cli/cmd/document.go +33 -0
- package/cli/cmd/health.go +19 -0
- package/cli/cmd/transaction.go +191 -0
- package/cli/cmd/version.go +1 -1
- package/cli/pkg/commands/document.go +19 -0
- package/cli/pkg/commands/health.go +18 -0
- package/cli/pkg/commands/transaction.go +84 -0
- package/cli/pkg/httpclient/client.go +76 -0
- package/lib/Helper/Console.helper.js.map +1 -1
- package/lib/Helper/Converter.helper.d.ts +1 -1
- package/lib/Helper/Converter.helper.js +0 -1
- package/lib/Helper/Converter.helper.js.map +1 -1
- package/lib/Helper/DocumentLoader.helper.js +2 -1
- package/lib/Helper/DocumentLoader.helper.js.map +1 -1
- package/lib/Helper/Logger.helper.d.ts +5 -0
- package/lib/Helper/Logger.helper.js +45 -0
- package/lib/Helper/Logger.helper.js.map +1 -0
- package/lib/Helper/PathSanitizer.helper.js.map +1 -1
- package/lib/Helper/SortedIndexValues.helper.js.map +1 -1
- package/lib/Helper/UniqueGenerator.helper.js.map +1 -1
- package/lib/Helper/response.helper.d.ts +2 -2
- package/lib/Helper/response.helper.js +6 -3
- package/lib/Helper/response.helper.js.map +1 -1
- package/lib/Memory/memory.operation.d.ts +9 -4
- package/lib/Memory/memory.operation.js +3 -3
- package/lib/Memory/memory.operation.js.map +1 -1
- package/lib/Services/Aggregation/Aggregation.Operation.d.ts +1 -1
- package/lib/Services/Aggregation/Aggregation.Operation.js +0 -1
- package/lib/Services/Aggregation/Aggregation.Operation.js.map +1 -1
- package/lib/Services/Aggregation/OperatorRegistry.js.map +1 -1
- package/lib/Services/Aggregation/operators/accumulatorOperators.d.ts +12 -12
- package/lib/Services/Aggregation/operators/accumulatorOperators.js +2 -3
- package/lib/Services/Aggregation/operators/accumulatorOperators.js.map +1 -1
- package/lib/Services/Aggregation/operators/expressionOperators.d.ts +3 -3
- package/lib/Services/Aggregation/operators/expressionOperators.js +111 -108
- package/lib/Services/Aggregation/operators/expressionOperators.js.map +1 -1
- package/lib/Services/Aggregation/operators/stageOperators.d.ts +20 -37
- package/lib/Services/Aggregation/operators/stageOperators.js +11 -11
- package/lib/Services/Aggregation/operators/stageOperators.js.map +1 -1
- package/lib/Services/Auth/AuthEvents.service.js.map +1 -1
- package/lib/Services/Auth/AuthSeeder.service.js +2 -2
- package/lib/Services/Auth/AuthSeeder.service.js.map +1 -1
- package/lib/Services/Auth/AuthService.service.js +5 -8
- package/lib/Services/Auth/AuthService.service.js.map +1 -1
- package/lib/Services/Auth/ConfigDatabase.service.js.map +1 -1
- package/lib/Services/Auth/CookieCodec.helper.js.map +1 -1
- package/lib/Services/Auth/LoginRateLimiter.service.js.map +1 -1
- package/lib/Services/Auth/PasswordHasher.helper.js.map +1 -1
- package/lib/Services/Auth/PermissionChecker.helper.js.map +1 -1
- package/lib/Services/Auth/SessionStore.service.js.map +1 -1
- package/lib/Services/CRUD Operation/Create.operation.js +0 -1
- package/lib/Services/CRUD Operation/Create.operation.js.map +1 -1
- package/lib/Services/CRUD Operation/Delete.operation.d.ts +2 -2
- package/lib/Services/CRUD Operation/Delete.operation.js +2 -3
- package/lib/Services/CRUD Operation/Delete.operation.js.map +1 -1
- package/lib/Services/CRUD Operation/Reader.operation.d.ts +11 -3
- package/lib/Services/CRUD Operation/Reader.operation.js +76 -40
- package/lib/Services/CRUD Operation/Reader.operation.js.map +1 -1
- package/lib/Services/CRUD Operation/Update.operation.d.ts +4 -4
- package/lib/Services/CRUD Operation/Update.operation.js +2 -2
- package/lib/Services/CRUD Operation/Update.operation.js.map +1 -1
- package/lib/Services/Collection/collection.operation.d.ts +10 -3
- package/lib/Services/Collection/collection.operation.js +32 -7
- package/lib/Services/Collection/collection.operation.js.map +1 -1
- package/lib/Services/Database/database.operation.js +13 -9
- package/lib/Services/Database/database.operation.js.map +1 -1
- package/lib/Services/Index/Index.service.d.ts +1 -1
- package/lib/Services/Index/Index.service.js +1 -1
- package/lib/Services/Index/Index.service.js.map +1 -1
- package/lib/Services/Index/IndexCache.service.js +4 -5
- package/lib/Services/Index/IndexCache.service.js.map +1 -1
- package/lib/Services/Index/ReadIndex.service.d.ts +4 -4
- package/lib/Services/Index/ReadIndex.service.js +10 -9
- package/lib/Services/Index/ReadIndex.service.js.map +1 -1
- package/lib/Services/Indexation.operation.d.ts +1 -1
- package/lib/Services/Indexation.operation.js +7 -6
- package/lib/Services/Indexation.operation.js.map +1 -1
- package/lib/Services/Transaction/LockManager.service.js +3 -4
- package/lib/Services/Transaction/LockManager.service.js.map +1 -1
- package/lib/Services/Transaction/Session.service.js +9 -7
- package/lib/Services/Transaction/Session.service.js.map +1 -1
- package/lib/Services/Transaction/Transaction.service.d.ts +4 -2
- package/lib/Services/Transaction/Transaction.service.js +7 -2
- package/lib/Services/Transaction/Transaction.service.js.map +1 -1
- package/lib/Services/Transaction/TransactionIndexManager.service.d.ts +1 -1
- package/lib/Services/Transaction/TransactionIndexManager.service.js +11 -6
- package/lib/Services/Transaction/TransactionIndexManager.service.js.map +1 -1
- package/lib/Services/Transaction/TransactionRegistry.service.js.map +1 -1
- package/lib/Services/Transaction/WriteAheadLog.service.js +0 -1
- package/lib/Services/Transaction/WriteAheadLog.service.js.map +1 -1
- package/lib/client/AggregationProxy.js.map +1 -1
- package/lib/client/AxioDBCloud.client.d.ts +15 -2
- package/lib/client/AxioDBCloud.client.js +24 -2
- package/lib/client/AxioDBCloud.client.js.map +1 -1
- package/lib/client/CollectionProxy.d.ts +8 -0
- package/lib/client/CollectionProxy.js +26 -0
- package/lib/client/CollectionProxy.js.map +1 -1
- package/lib/client/DatabaseProxy.js.map +1 -1
- package/lib/client/DeleteOperationProxy.js.map +1 -1
- package/lib/client/PooledConnection.d.ts +1 -1
- package/lib/client/PooledConnection.js +6 -3
- package/lib/client/PooledConnection.js.map +1 -1
- package/lib/client/ReaderProxy.d.ts +3 -1
- package/lib/client/ReaderProxy.js +7 -0
- package/lib/client/ReaderProxy.js.map +1 -1
- package/lib/client/TransactionProxy.d.ts +37 -0
- package/lib/client/TransactionProxy.js +101 -0
- package/lib/client/TransactionProxy.js.map +1 -0
- package/lib/client/UpdateOperationProxy.js.map +1 -1
- package/lib/client/types/client.types.js.map +1 -1
- package/lib/config/DB.js.map +1 -1
- package/lib/config/Interfaces/Helper/response.helper.interface.d.ts +2 -2
- package/lib/config/Interfaces/Helper/response.helper.interface.js +0 -1
- package/lib/config/Interfaces/Helper/response.helper.interface.js.map +1 -1
- package/lib/config/Interfaces/Operation/aggregation.interface.d.ts +4 -4
- package/lib/config/Interfaces/Operation/aggregation.interface.js +0 -1
- package/lib/config/Interfaces/Operation/aggregation.interface.js.map +1 -1
- package/lib/config/Interfaces/Operation/database.operation.interface.d.ts +4 -1
- package/lib/config/Interfaces/Operation/database.operation.interface.js +0 -1
- package/lib/config/Interfaces/Operation/database.operation.interface.js.map +1 -1
- package/lib/config/Interfaces/Transaction/transaction.interface.d.ts +3 -3
- package/lib/config/Interfaces/shared.types.d.ts +36 -0
- package/lib/config/Interfaces/shared.types.js +7 -0
- package/lib/config/Interfaces/shared.types.js.map +1 -0
- package/lib/config/Keys/Keys.js.map +1 -1
- package/lib/config/Keys/Permissions.js.map +1 -1
- package/lib/config/Keys/StatusCode.js.map +1 -1
- package/lib/engine/Filesystem/FileManager.js +3 -4
- package/lib/engine/Filesystem/FileManager.js.map +1 -1
- package/lib/engine/Filesystem/FolderManager.js +11 -11
- package/lib/engine/Filesystem/FolderManager.js.map +1 -1
- package/lib/engine/cli/worker_process.js.map +1 -1
- package/lib/engine/node/WorkerForDataLoad.engine.js +7 -6
- package/lib/engine/node/WorkerForDataLoad.engine.js.map +1 -1
- package/lib/engine/node/WorkerForSearch.engine.js +0 -1
- package/lib/engine/node/WorkerForSearch.engine.js.map +1 -1
- package/lib/server/config/PortFreeChecker.js +0 -1
- package/lib/server/config/PortFreeChecker.js.map +1 -1
- package/lib/server/config/keys.js +0 -1
- package/lib/server/config/keys.js.map +1 -1
- package/lib/server/config/server.js +2 -2
- package/lib/server/config/server.js.map +1 -1
- package/lib/server/controller/Auth/Auth.controller.js.map +1 -1
- package/lib/server/controller/Auth/RoleManagement.controller.js.map +1 -1
- package/lib/server/controller/Auth/UserManagement.controller.js.map +1 -1
- package/lib/server/controller/Collections/Collection.controller.js +9 -7
- package/lib/server/controller/Collections/Collection.controller.js.map +1 -1
- package/lib/server/controller/Database/Databse.controller.js +12 -13
- package/lib/server/controller/Database/Databse.controller.js.map +1 -1
- package/lib/server/controller/Index/Index.controller.js +4 -3
- package/lib/server/controller/Index/Index.controller.js.map +1 -1
- package/lib/server/controller/Operation/CRUD.controller.d.ts +1 -0
- package/lib/server/controller/Operation/CRUD.controller.js +42 -18
- package/lib/server/controller/Operation/CRUD.controller.js.map +1 -1
- package/lib/server/controller/Stats.controller.js +21 -15
- package/lib/server/controller/Stats.controller.js.map +1 -1
- package/lib/server/helper/databaseImport.helper.js.map +1 -1
- package/lib/server/helper/documentCounterInFolder.helper.js.map +1 -1
- package/lib/server/helper/responseBuilder.helper.d.ts +2 -2
- package/lib/server/helper/responseBuilder.helper.js.map +1 -1
- package/lib/server/middleware/auth.middleware.js.map +1 -1
- package/lib/server/middleware/permission.middleware.js.map +1 -1
- package/lib/server/router/Router.js +8 -7
- package/lib/server/router/Router.js.map +1 -1
- package/lib/server/router/Routers/Auth.routes.js.map +1 -1
- package/lib/server/router/Routers/Collection.routes.js +3 -3
- package/lib/server/router/Routers/Collection.routes.js.map +1 -1
- package/lib/server/router/Routers/DB.routes.js +1 -1
- package/lib/server/router/Routers/DB.routes.js.map +1 -1
- package/lib/server/router/Routers/Index.routes.js.map +1 -1
- package/lib/server/router/Routers/Operation.routes.js +25 -10
- package/lib/server/router/Routers/Operation.routes.js.map +1 -1
- package/lib/server/router/Routers/RoleManagement.routes.js.map +1 -1
- package/lib/server/router/Routers/UserManagement.routes.js.map +1 -1
- package/lib/tcp/config/keys.d.ts +32 -32
- package/lib/tcp/config/keys.js.map +1 -1
- package/lib/tcp/config/permissions.d.ts +1 -4
- package/lib/tcp/config/permissions.js +8 -4
- package/lib/tcp/config/permissions.js.map +1 -1
- package/lib/tcp/config/protocol.d.ts +3 -3
- package/lib/tcp/config/protocol.js +31 -9
- package/lib/tcp/config/protocol.js.map +1 -1
- package/lib/tcp/config/server.js +17 -12
- package/lib/tcp/config/server.js.map +1 -1
- package/lib/tcp/connection/ConnectionManager.js.map +1 -1
- package/lib/tcp/connection/ConnectionRateLimiter.js.map +1 -1
- package/lib/tcp/connection/RequestContext.d.ts +2 -2
- package/lib/tcp/connection/RequestContext.js.map +1 -1
- package/lib/tcp/connection/TransactionManager.d.ts +26 -0
- package/lib/tcp/connection/TransactionManager.js +114 -0
- package/lib/tcp/connection/TransactionManager.js.map +1 -0
- package/lib/tcp/handler/CommandHandler.d.ts +3 -0
- package/lib/tcp/handler/CommandHandler.js +32 -8
- package/lib/tcp/handler/CommandHandler.js.map +1 -1
- package/lib/tcp/handler/handlers/Auth.handler.d.ts +4 -2
- package/lib/tcp/handler/handlers/Auth.handler.js.map +1 -1
- package/lib/tcp/handler/handlers/Collection.handler.d.ts +7 -5
- package/lib/tcp/handler/handlers/Collection.handler.js +1 -3
- package/lib/tcp/handler/handlers/Collection.handler.js.map +1 -1
- package/lib/tcp/handler/handlers/DB.handler.d.ts +6 -4
- package/lib/tcp/handler/handlers/DB.handler.js +1 -2
- package/lib/tcp/handler/handlers/DB.handler.js.map +1 -1
- package/lib/tcp/handler/handlers/Operation.handler.d.ts +19 -57
- package/lib/tcp/handler/handlers/Operation.handler.js +138 -167
- package/lib/tcp/handler/handlers/Operation.handler.js.map +1 -1
- package/lib/tcp/handler/handlers/Transaction.handler.d.ts +18 -0
- package/lib/tcp/handler/handlers/Transaction.handler.js +199 -0
- package/lib/tcp/handler/handlers/Transaction.handler.js.map +1 -0
- package/lib/tcp/types/command.types.d.ts +6 -1
- package/lib/tcp/types/command.types.js +11 -1
- package/lib/tcp/types/command.types.js.map +1 -1
- package/lib/tcp/types/protocol.types.d.ts +10 -7
- package/lib/tcp/types/protocol.types.js.map +1 -1
- package/lib/utility/BufferLoaderWithWorker.utils.js +6 -5
- package/lib/utility/BufferLoaderWithWorker.utils.js.map +1 -1
- package/lib/utility/Searcher.utils.d.ts +3 -7
- package/lib/utility/Searcher.utils.js +49 -49
- package/lib/utility/Searcher.utils.js.map +1 -1
- package/lib/utility/SortData.utils.d.ts +3 -2
- package/lib/utility/SortData.utils.js +3 -19
- package/lib/utility/SortData.utils.js.map +1 -1
- package/lib/utility/ZipUnzip.utils.d.ts +2 -2
- package/lib/utility/ZipUnzip.utils.js +2 -2
- package/lib/utility/ZipUnzip.utils.js.map +1 -1
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
# AxioDB:
|
|
1
|
+
# AxioDB: SQLite Alternative for JavaScript
|
|
2
2
|
|
|
3
3
|
[](https://badge.fury.io/js/axiodb)
|
|
4
|
+
[](https://www.npmjs.com/package/axiodb)
|
|
4
5
|
[](https://www.npmjs.com/package/axiodb)
|
|
5
6
|
[](https://www.npmjs.com/package/axiodb)
|
|
6
7
|
[](https://www.npmjs.com/package/axiodb)
|
|
7
8
|
[](https://www.npmjs.com/package/axiodb)
|
|
9
|
+
[](https://www.npmjs.com/package/axiodb)
|
|
10
|
+
[](https://www.jsdelivr.com/package/npm/axiodb)
|
|
11
|
+
[](https://www.npmjs.com/package/axiodb)
|
|
8
12
|
[](https://opensource.org/licenses/MIT)
|
|
9
13
|
|
|
10
14
|
[](https://github.com/nexoral/AxioDB/actions/workflows/Push.yml)
|
|
11
15
|
[](https://github.com/nexoral/AxioDB/actions/workflows/github-code-scanning/codeql)
|
|
12
16
|
[](https://socket.dev/npm/package/axiodb)
|
|
17
|
+
[](https://github.com/nexoral/AxioDB)
|
|
13
18
|
|
|
14
19
|
[](https://nodejs.org)
|
|
15
20
|
[](https://github.com/nexoral/AxioDB/actions/workflows/Push.yml)
|
|
16
|
-
[](https://www.typescriptlang.org/)
|
|
17
22
|
[](https://www.npmjs.com/package/axiodb)
|
|
18
23
|
|
|
19
24
|
👉 **[Official Documentation](https://axiodb.in/)**: Access full guides, examples, and API references.
|
|
@@ -156,6 +161,8 @@ const db = new AxioDB({
|
|
|
156
161
|
|
|
157
162
|
### Querying
|
|
158
163
|
- **Chainable Query API:** `.query()`, `.Sort()`, `.Limit()`, `.Skip()`, `.setCount()`, `.setProject()`, `.exec()` / `.findOne()`
|
|
164
|
+
- **Index Hints:** `.hint('fieldName')` to force a specific index on any query for predictable performance
|
|
165
|
+
- **Batch Read:** `.findByIds(['id1', 'id2'])` to retrieve multiple documents by ID in a single call
|
|
159
166
|
- **MongoDB-style Query Operators:** `$gt`, `$gte`, `$lt`, `$lte`, `$ne`, `$in`, `$nin`, `$exists`, `$regex`, `$or`, `$and`
|
|
160
167
|
- **Aggregation Pipelines:** 60+ MongoDB-compatible stages (`$match`, `$group`, `$sort`, `$project`, `$limit`, `$skip`, `$unwind`, `$addFields`, `$lookup`, `$facet`, `$bucket`, `$count`, `$sample`, ...) with full expression evaluator, cross-collection `$lookup` joins, and custom operator registration via `OperatorRegistry`
|
|
161
168
|
- **Bulk Operations:** high-performance `insertMany`, `UpdateMany`, `deleteMany`
|
|
@@ -170,14 +177,23 @@ const db = new AxioDB({
|
|
|
170
177
|
### Transactions
|
|
171
178
|
- **ACID-compliant, single-collection transactions** with savepoints, rollback, and Write-Ahead Logging (WAL) for crash recovery
|
|
172
179
|
- **Session Management:** scoped transactions with timeout support
|
|
180
|
+
- **TCP Transactions:** BEGIN/COMMIT/ROLLBACK over TCP with savepoints, connection-pinned client proxy, and auto-rollback on disconnect
|
|
173
181
|
|
|
174
182
|
```javascript
|
|
183
|
+
// Local transaction
|
|
175
184
|
const session = collection.startSession();
|
|
176
185
|
await session.withTransaction(async (tx) => {
|
|
177
186
|
await tx.insert({ name: 'Alice', balance: 1000 });
|
|
178
|
-
|
|
187
|
+
// Updates are flat merges; AxioDB does not implement MongoDB's $inc operator.
|
|
188
|
+
await tx.update({ name: 'Bob' }, { balance: 900 });
|
|
179
189
|
// Auto-commits on success, auto-rolls-back on error
|
|
180
190
|
});
|
|
191
|
+
|
|
192
|
+
// TCP transaction
|
|
193
|
+
const tx = await client.db('mydb').collection('users').beginTransaction();
|
|
194
|
+
await tx.insert({ name: 'Alice', balance: 1000 });
|
|
195
|
+
await tx.update({ name: 'Bob' }, { balance: 900 });
|
|
196
|
+
await tx.commit(); // or await tx.rollback();
|
|
181
197
|
```
|
|
182
198
|
|
|
183
199
|
### Caching
|
|
@@ -211,7 +227,7 @@ await session.withTransaction(async (tx) => {
|
|
|
211
227
|
- **🔄 Zero Code Changes:** same `createDB`/`createCollection`/`insert`/`query` API as embedded AxioDB
|
|
212
228
|
- **⚡ Fast Binary Protocol:** length-prefixed JSON framing, with automatic reconnection
|
|
213
229
|
- **🔐 Optional Authentication:** shared RBAC with the GUI, per-IP rate limiting (see [Advanced](#advanced-tcp-authentication) below)
|
|
214
|
-
- **📦
|
|
230
|
+
- **📦 32 Commands:** full CRUD, aggregation, indexing, and transactions over the wire
|
|
215
231
|
- **🔁 Auto-Reconnect:** exponential backoff, up to 10 retry attempts
|
|
216
232
|
- **💓 Heartbeat Monitoring:** `PING`/`PONG` every 30 seconds
|
|
217
233
|
- **🆔 Request Correlation:** UUID-based request/response matching
|
|
@@ -371,12 +387,17 @@ irm https://raw.githubusercontent.com/nexoral/AxioDB/main/cli/Scripts/install.ps
|
|
|
371
387
|
|
|
372
388
|
### Usage
|
|
373
389
|
|
|
390
|
+
> **Activation notice:** Data commands (`db`/`collection`/`document`/`index`/`transaction`/`ping`/`health`/`connect`) require the server started with `TCP: true` (`AXIODB_TCP=true`, port 27019). Management commands (`user`/`role`/`user change-password`/`export`/`import`) require `GUI: true`/`HTTP: true` (`AXIODB_GUI=true`, port 27018). TCP is data-plane only — no management over TCP by design.
|
|
391
|
+
|
|
374
392
|
**Single commands:**
|
|
375
393
|
```bash
|
|
376
394
|
axiodb -c axiodb://127.0.0.1:27019 ping
|
|
377
395
|
axiodb -c axiodb://127.0.0.1:27019 db list
|
|
378
396
|
axiodb -c axiodb://127.0.0.1:27019 document insert '{"name":"Alice"}' --db mydb --collection users
|
|
379
397
|
axiodb -c axiodb://127.0.0.1:27019 document query '{}' --db mydb --collection users
|
|
398
|
+
axiodb -c axiodb://127.0.0.1:27019 document query '{}' --hint email --db mydb --collection users
|
|
399
|
+
axiodb -c axiodb://127.0.0.1:27019 health
|
|
400
|
+
axiodb -c axiodb://127.0.0.1:27019 transaction begin --db mydb --collection users
|
|
380
401
|
```
|
|
381
402
|
|
|
382
403
|
**Interactive REPL (MongoDB shell style):**
|
|
@@ -412,9 +433,36 @@ axiodb import ./backups/mydb.tar.gz --http-host localhost --http-port 27018 -u a
|
|
|
412
433
|
# Tab completes .tar.gz file paths
|
|
413
434
|
```
|
|
414
435
|
|
|
436
|
+
**User and role administration (via HTTP API):**
|
|
437
|
+
```bash
|
|
438
|
+
axiodb user list --http-host localhost --http-port 27018 -u admin -p secret
|
|
439
|
+
axiodb user create analyst analyst123 View --http-host localhost --http-port 27018 -u admin -p secret
|
|
440
|
+
axiodb user change-password oldPass newPass --http-host localhost --http-port 27018 -u analyst -p analyst123
|
|
441
|
+
axiodb role list --http-host localhost --http-port 27018 -u admin -p secret
|
|
442
|
+
axiodb role create Auditor document:view,document:query --http-host localhost --http-port 27018 -u admin -p secret
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
**Transactions (via TCP, full lifecycle):**
|
|
446
|
+
```bash
|
|
447
|
+
# File-based batch (auto-commit/rollback)
|
|
448
|
+
axiodb transaction run operations.json --db mydb --collection users
|
|
449
|
+
# Manual control
|
|
450
|
+
axiodb transaction begin --db mydb --collection users # → transactionId
|
|
451
|
+
axiodb transaction savepoint <txnId> sp1
|
|
452
|
+
axiodb transaction rollback-to <txnId> sp1
|
|
453
|
+
axiodb transaction release <txnId> sp1
|
|
454
|
+
axiodb transaction commit <txnId>
|
|
455
|
+
axiodb transaction rollback <txnId>
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
Management commands use the authenticated HTTP API; they do not add management commands to the
|
|
459
|
+
TCP client protocol, which remains focused on database, collection, document, index, aggregation,
|
|
460
|
+
count, and transaction operations.
|
|
461
|
+
|
|
415
462
|
### Features
|
|
416
463
|
|
|
417
|
-
- **
|
|
464
|
+
- **TCP data operations:** database, collection, document CRUD, aggregation, indexing, counts, and transactions
|
|
465
|
+
- **CLI transactions and diagnostics:** run a transaction operation file, use query index hints, find documents by IDs, and check TCP health
|
|
418
466
|
- **Interactive REPL:** MongoDB shell syntax (`use`, `show dbs`, `db.coll.find()`)
|
|
419
467
|
- **Export & Import:** backup/restore databases via HTTP API, tab-completes file paths
|
|
420
468
|
- **TLS support:** `--tls`, `--tls-cert`, `--tls-skip-verify`
|
|
@@ -645,7 +693,7 @@ volumes:
|
|
|
645
693
|
## 🤖 MCP Server — AI Agent Integration
|
|
646
694
|
|
|
647
695
|
Spin up the same Docker container with `AXIODB_MCP=true` and let Claude (or any MCP-compatible
|
|
648
|
-
AI agent) talk to your AxioDB instance directly —
|
|
696
|
+
AI agent) talk to your AxioDB instance directly — 43 tools covering databases, collections,
|
|
649
697
|
documents, aggregation, indexes, dashboard stats, and user/role management, all gated by the
|
|
650
698
|
same RBAC as the web GUI. It runs in the same process as your existing container; nothing new
|
|
651
699
|
to install, no second database instance.
|
|
@@ -804,17 +852,21 @@ const electronics = await products
|
|
|
804
852
|
|
|
805
853
|
- `createDB(dbName: string): Promise<Database>`
|
|
806
854
|
- `deleteDatabase(dbName: string): Promise<SuccessInterface | ErrorInterface>`
|
|
855
|
+
- `isDatabaseExists(dbName: string): Promise<boolean>`
|
|
856
|
+
- `getInstanceInfo(): Promise<SuccessInterface | undefined>`
|
|
807
857
|
|
|
808
858
|
### Database
|
|
809
859
|
|
|
810
860
|
- `createCollection(name: string): Promise<Collection>`
|
|
811
861
|
- `deleteCollection(name: string): Promise<SuccessInterface | ErrorInterface>`
|
|
862
|
+
- `isCollectionExists(name: string): Promise<boolean>`
|
|
812
863
|
- `getCollectionInfo(): Promise<SuccessInterface>`
|
|
813
864
|
|
|
814
865
|
### Collection
|
|
815
866
|
|
|
816
867
|
- `insert(document: object): Promise<SuccessInterface | ErrorInterface>`
|
|
817
|
-
- `insertMany(documents: object[]): Promise<SuccessInterface | ErrorInterface>`
|
|
868
|
+
- `insertMany(documents: object | object[]): Promise<SuccessInterface | ErrorInterface>`
|
|
869
|
+
- `totalDocuments(): Promise<SuccessInterface | ErrorInterface>`
|
|
818
870
|
- `query(query: object): Reader`
|
|
819
871
|
- `update(query: object): Updater`
|
|
820
872
|
- `delete(query: object): Deleter`
|
|
@@ -828,6 +880,8 @@ const electronics = await products
|
|
|
828
880
|
|
|
829
881
|
`update(query)` and `delete(query)` on their own don't change anything — they return a chainable object. Call one of the methods below to actually apply the change:
|
|
830
882
|
|
|
883
|
+
Updates are flat shallow merges. AxioDB does not implement MongoDB update operators such as `$inc`, `$set`, or `$push`; keys beginning with `$` are stored as ordinary field names.
|
|
884
|
+
|
|
831
885
|
- `updater.UpdateOne(data: object): Promise<SuccessInterface | ErrorInterface>` — applies `data` to the first document matching `query`
|
|
832
886
|
- `updater.UpdateMany(data: object): Promise<SuccessInterface | ErrorInterface>` — applies `data` to every document matching `query`
|
|
833
887
|
- `deleter.deleteOne(): Promise<SuccessInterface | ErrorInterface>` — deletes the first document matching `query`
|
|
@@ -860,7 +914,7 @@ await collection.delete({ status: 'inactive' }).deleteMany();
|
|
|
860
914
|
### Transaction (Session)
|
|
861
915
|
|
|
862
916
|
- `startSession(options?: { timeout?: number }): Session`
|
|
863
|
-
- `session.withTransaction(callback:
|
|
917
|
+
- `session.withTransaction(callback: (transaction: Transaction) => Promise<void>): Promise<SuccessInterface | ErrorInterface>`
|
|
864
918
|
- `session.startTransaction(): Transaction`
|
|
865
919
|
- `transaction.insert(document: object): Transaction`
|
|
866
920
|
- `transaction.update(query: object, update: object): Transaction`
|
|
@@ -868,7 +922,30 @@ await collection.delete({ status: 'inactive' }).deleteMany();
|
|
|
868
922
|
- `transaction.savepoint(name: string): Transaction`
|
|
869
923
|
- `transaction.rollbackToSavepoint(name: string): Transaction`
|
|
870
924
|
- `transaction.commit(): Promise<SuccessInterface>`
|
|
871
|
-
- `transaction.rollback(): Promise<
|
|
925
|
+
- `transaction.rollback(): Promise<SuccessInterface | ErrorInterface>`
|
|
926
|
+
|
|
927
|
+
### MCP transactions (Docker image)
|
|
928
|
+
|
|
929
|
+
The Docker-only MCP server exposes authenticated, single-collection ACID transactions with
|
|
930
|
+
insert, update, delete, savepoint, commit, and rollback tools. Begin with
|
|
931
|
+
`axiodb_begin_transaction`, then pass its `transactionId` to the other transaction tools.
|
|
932
|
+
|
|
933
|
+
### TCP Transaction Proxy
|
|
934
|
+
|
|
935
|
+
- `collection.beginTransaction(): Promise<TransactionProxy>`
|
|
936
|
+
- `transactionProxy.insert(data: object): Promise<unknown>`
|
|
937
|
+
- `transactionProxy.insertMany(documents: object[]): Promise<unknown>`
|
|
938
|
+
- `transactionProxy.query(query: object, options?): Promise<unknown>`
|
|
939
|
+
- `transactionProxy.findByIds(ids: string[]): Promise<unknown>`
|
|
940
|
+
- `transactionProxy.updateById(documentId: string, updateData: object): Promise<unknown>`
|
|
941
|
+
- `transactionProxy.updateByQuery(query: object, updateData: object, updateOne?: boolean): Promise<unknown>`
|
|
942
|
+
- `transactionProxy.deleteById(documentId: string): Promise<unknown>`
|
|
943
|
+
- `transactionProxy.deleteByQuery(query: object, deleteOne?: boolean): Promise<unknown>`
|
|
944
|
+
- `transactionProxy.savepoint(name: string): Promise<unknown>`
|
|
945
|
+
- `transactionProxy.rollbackToSavepoint(name: string): Promise<unknown>`
|
|
946
|
+
- `transactionProxy.releaseSavepoint(name: string): Promise<unknown>`
|
|
947
|
+
- `transactionProxy.commit(): Promise<unknown>`
|
|
948
|
+
- `transactionProxy.rollback(): Promise<unknown>`
|
|
872
949
|
|
|
873
950
|
---
|
|
874
951
|
|
package/cli/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
20.3.2
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
package cmd
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
"strings"
|
|
6
|
+
|
|
7
|
+
"github.com/nexoral/axiodb-cli/internal/config"
|
|
8
|
+
"github.com/nexoral/axiodb-cli/pkg/httpclient"
|
|
9
|
+
"github.com/spf13/cobra"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
var userCmd = &cobra.Command{Use: "user", Short: "Manage HTTP API users"}
|
|
13
|
+
var roleCmd = &cobra.Command{Use: "role", Short: "Manage HTTP API roles"}
|
|
14
|
+
|
|
15
|
+
func httpClientFor(cmd *cobra.Command) (*config.Config, *httpclient.HTTPClient, error) {
|
|
16
|
+
cfg, err := config.FromFlags(cmd)
|
|
17
|
+
if err != nil { return nil, nil, err }
|
|
18
|
+
if cfg.Username == "" || cfg.Password == "" { return nil, nil, fmt.Errorf("--username and --password are required for HTTP administration") }
|
|
19
|
+
client := cfg.NewHTTPClient()
|
|
20
|
+
if err := client.Login(cfg.Username, cfg.Password); err != nil { return nil, nil, err }
|
|
21
|
+
return cfg, client, nil
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
var userListCmd = &cobra.Command{Use: "list", Short: "List users", RunE: func(cmd *cobra.Command, args []string) error {
|
|
25
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.ListUsers(); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
26
|
+
}}
|
|
27
|
+
|
|
28
|
+
var userCreateCmd = &cobra.Command{Use: "create <username> <password> <role>", Short: "Create a user", Args: cobra.ExactArgs(3), RunE: func(cmd *cobra.Command, args []string) error {
|
|
29
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.CreateUser(args[0], args[1], args[2]); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
30
|
+
}}
|
|
31
|
+
|
|
32
|
+
var userRoleCmd = &cobra.Command{Use: "set-role <username> <role>", Short: "Change a user's role", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error {
|
|
33
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.UpdateUserRole(args[0], args[1]); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
34
|
+
}}
|
|
35
|
+
|
|
36
|
+
var userResetCmd = &cobra.Command{Use: "reset-password <username> <password>", Short: "Reset a user's password", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error {
|
|
37
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.ResetUserPassword(args[0], args[1]); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
38
|
+
}}
|
|
39
|
+
|
|
40
|
+
var userDeleteCmd = &cobra.Command{Use: "delete <username>", Short: "Delete a user", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error {
|
|
41
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.DeleteUser(args[0]); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
42
|
+
}}
|
|
43
|
+
|
|
44
|
+
var userChangePasswordCmd = &cobra.Command{Use: "change-password <currentPassword> <newPassword>", Short: "Change own password (self-service)", Long: "Change your own password. Requires HTTP API (port 27018) to be enabled on the server (GUI/HTTP). Uses PATCH /api/auth/change-password.", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error {
|
|
45
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.ChangeOwnPassword(args[0], args[1]); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
46
|
+
}}
|
|
47
|
+
|
|
48
|
+
var roleListCmd = &cobra.Command{Use: "list", Short: "List roles", RunE: func(cmd *cobra.Command, args []string) error {
|
|
49
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.ListRoles(); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
50
|
+
}}
|
|
51
|
+
|
|
52
|
+
var roleCreateCmd = &cobra.Command{Use: "create <name> <permission,...>", Short: "Create a role", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error {
|
|
53
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; permissions := strings.Split(args[1], ","); result, err := client.CreateRole(args[0], permissions); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
54
|
+
}}
|
|
55
|
+
|
|
56
|
+
var roleDeleteCmd = &cobra.Command{Use: "delete <name>", Short: "Delete a role", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error {
|
|
57
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.DeleteRole(args[0]); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
58
|
+
}}
|
|
59
|
+
|
|
60
|
+
var rolePermissionsCmd = &cobra.Command{Use: "permissions", Short: "List available permissions", RunE: func(cmd *cobra.Command, args []string) error {
|
|
61
|
+
cfg, client, err := httpClientFor(cmd); if err != nil { return err }; result, err := client.ListPermissions(); if err != nil { return err }; return printOutput(cfg.Output, result)
|
|
62
|
+
}}
|
|
63
|
+
|
|
64
|
+
func init() {
|
|
65
|
+
userCmd.AddCommand(userListCmd, userCreateCmd, userRoleCmd, userResetCmd, userDeleteCmd, userChangePasswordCmd)
|
|
66
|
+
roleCmd.AddCommand(roleListCmd, roleCreateCmd, roleDeleteCmd, rolePermissionsCmd)
|
|
67
|
+
rootCmd.AddCommand(userCmd, roleCmd)
|
|
68
|
+
}
|
package/cli/cmd/document.go
CHANGED
|
@@ -101,11 +101,13 @@ var documentQueryCmd = &cobra.Command{
|
|
|
101
101
|
skip, _ := cmd.Flags().GetInt("skip")
|
|
102
102
|
sortStr, _ := cmd.Flags().GetString("sort")
|
|
103
103
|
findOne, _ := cmd.Flags().GetBool("find-one")
|
|
104
|
+
hint, _ := cmd.Flags().GetString("hint")
|
|
104
105
|
|
|
105
106
|
opts := commands.QueryOptions{
|
|
106
107
|
Limit: limit,
|
|
107
108
|
Skip: skip,
|
|
108
109
|
FindOne: findOne,
|
|
110
|
+
Hint: hint,
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
if len(args) > 0 {
|
|
@@ -138,6 +140,35 @@ var documentQueryCmd = &cobra.Command{
|
|
|
138
140
|
},
|
|
139
141
|
}
|
|
140
142
|
|
|
143
|
+
var documentFindByIDsCmd = &cobra.Command{
|
|
144
|
+
Use: "find-by-ids <ids-json>",
|
|
145
|
+
Short: "Find multiple documents by ID",
|
|
146
|
+
Args: cobra.ExactArgs(1),
|
|
147
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
148
|
+
cfg, err := config.FromFlags(cmd)
|
|
149
|
+
if err != nil {
|
|
150
|
+
return err
|
|
151
|
+
}
|
|
152
|
+
if cfg.DB == "" || cfg.Collection == "" {
|
|
153
|
+
return fmt.Errorf("--db and --collection flags are required")
|
|
154
|
+
}
|
|
155
|
+
var ids []string
|
|
156
|
+
if err := json.Unmarshal([]byte(args[0]), &ids); err != nil || len(ids) == 0 {
|
|
157
|
+
return fmt.Errorf("ids must be a non-empty JSON array of strings")
|
|
158
|
+
}
|
|
159
|
+
client, err := cfg.ConnectAndAuth()
|
|
160
|
+
if err != nil {
|
|
161
|
+
return err
|
|
162
|
+
}
|
|
163
|
+
defer client.Disconnect()
|
|
164
|
+
resp, err := commands.FindDocumentsByIDs(client, cfg.DB, cfg.Collection, ids)
|
|
165
|
+
if err != nil {
|
|
166
|
+
return err
|
|
167
|
+
}
|
|
168
|
+
return printOutput(cfg.Output, resp)
|
|
169
|
+
},
|
|
170
|
+
}
|
|
171
|
+
|
|
141
172
|
var documentGetCmd = &cobra.Command{
|
|
142
173
|
Use: "get <id>",
|
|
143
174
|
Short: "Get a document by ID",
|
|
@@ -358,6 +389,7 @@ func init() {
|
|
|
358
389
|
documentQueryCmd.Flags().Int("skip", 0, "Skip results")
|
|
359
390
|
documentQueryCmd.Flags().String("sort", "", "Sort JSON (e.g., '{\"name\":1}')")
|
|
360
391
|
documentQueryCmd.Flags().Bool("find-one", false, "Find single document")
|
|
392
|
+
documentQueryCmd.Flags().String("hint", "", "Index field name to use")
|
|
361
393
|
|
|
362
394
|
documentUpdateByQueryCmd.Flags().Bool("many", false, "Update multiple documents")
|
|
363
395
|
documentDeleteByQueryCmd.Flags().Bool("many", false, "Delete multiple documents")
|
|
@@ -366,6 +398,7 @@ func init() {
|
|
|
366
398
|
documentCmd.AddCommand(documentInsertManyCmd)
|
|
367
399
|
documentCmd.AddCommand(documentQueryCmd)
|
|
368
400
|
documentCmd.AddCommand(documentGetCmd)
|
|
401
|
+
documentCmd.AddCommand(documentFindByIDsCmd)
|
|
369
402
|
documentCmd.AddCommand(documentUpdateCmd)
|
|
370
403
|
documentCmd.AddCommand(documentUpdateByQueryCmd)
|
|
371
404
|
documentCmd.AddCommand(documentDeleteCmd)
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
package cmd
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"github.com/nexoral/axiodb-cli/internal/config"
|
|
5
|
+
"github.com/nexoral/axiodb-cli/pkg/commands"
|
|
6
|
+
"github.com/spf13/cobra"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
var healthCmd = &cobra.Command{
|
|
10
|
+
Use: "health", Short: "Check AxioDB service health",
|
|
11
|
+
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
12
|
+
cfg, err := config.FromFlags(cmd); if err != nil { return err }
|
|
13
|
+
client, err := cfg.ConnectAndAuth(); if err != nil { return err }; defer client.Disconnect()
|
|
14
|
+
response, err := commands.Health(client); if err != nil { return err }
|
|
15
|
+
return printOutput(cfg.Output, response)
|
|
16
|
+
},
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
func init() { rootCmd.AddCommand(healthCmd) }
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
package cmd
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"encoding/json"
|
|
5
|
+
"fmt"
|
|
6
|
+
"os"
|
|
7
|
+
|
|
8
|
+
"github.com/nexoral/axiodb-cli/internal/config"
|
|
9
|
+
"github.com/nexoral/axiodb-cli/pkg/commands"
|
|
10
|
+
"github.com/spf13/cobra"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
var transactionCmd = &cobra.Command{
|
|
14
|
+
Use: "transaction",
|
|
15
|
+
Short: "Run ACID transaction operations",
|
|
16
|
+
Long: "ACID transactions over TCP (port 27019). Requires TCP server enabled (AXIODB_TCP=true). Use 'transaction run' for file-based batch, or begin/commit/rollback/savepoint for manual control.",
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
var transactionRunCmd = &cobra.Command{
|
|
20
|
+
Use: "run <operations-json-file>",
|
|
21
|
+
Short: "Run a transaction from a JSON operation list",
|
|
22
|
+
Long: "Run a full transaction from a JSON file. Requires TCP (AXIODB_TCP=true) and --db/--collection. Auto-commits on success, auto-rollbacks on failure.",
|
|
23
|
+
Args: cobra.ExactArgs(1),
|
|
24
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
25
|
+
cfg, err := config.FromFlags(cmd)
|
|
26
|
+
if err != nil {
|
|
27
|
+
return err
|
|
28
|
+
}
|
|
29
|
+
if cfg.DB == "" || cfg.Collection == "" {
|
|
30
|
+
return fmt.Errorf("--db and --collection flags are required")
|
|
31
|
+
}
|
|
32
|
+
content, err := os.ReadFile(args[0])
|
|
33
|
+
if err != nil {
|
|
34
|
+
return fmt.Errorf("read transaction file: %w", err)
|
|
35
|
+
}
|
|
36
|
+
var steps []commands.TransactionStep
|
|
37
|
+
if err := json.Unmarshal(content, &steps); err != nil {
|
|
38
|
+
return fmt.Errorf("invalid transaction JSON: %w", err)
|
|
39
|
+
}
|
|
40
|
+
client, err := cfg.ConnectAndAuth()
|
|
41
|
+
if err != nil {
|
|
42
|
+
return err
|
|
43
|
+
}
|
|
44
|
+
defer client.Disconnect()
|
|
45
|
+
response, err := commands.RunTransaction(client, cfg.DB, cfg.Collection, steps)
|
|
46
|
+
if err != nil {
|
|
47
|
+
return err
|
|
48
|
+
}
|
|
49
|
+
return printOutput(cfg.Output, response)
|
|
50
|
+
},
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
var transactionBeginCmd = &cobra.Command{
|
|
54
|
+
Use: "begin",
|
|
55
|
+
Short: "Begin a transaction (returns transactionId)",
|
|
56
|
+
Long: "Begin a transaction on --db/--collection. Requires TCP. Returns transactionId for subsequent commit/rollback/savepoint calls.",
|
|
57
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
58
|
+
cfg, err := config.FromFlags(cmd)
|
|
59
|
+
if err != nil {
|
|
60
|
+
return err
|
|
61
|
+
}
|
|
62
|
+
if cfg.DB == "" || cfg.Collection == "" {
|
|
63
|
+
return fmt.Errorf("--db and --collection flags are required")
|
|
64
|
+
}
|
|
65
|
+
client, err := cfg.ConnectAndAuth()
|
|
66
|
+
if err != nil {
|
|
67
|
+
return err
|
|
68
|
+
}
|
|
69
|
+
defer client.Disconnect()
|
|
70
|
+
resp, err := commands.BeginTransaction(client, cfg.DB, cfg.Collection)
|
|
71
|
+
if err != nil {
|
|
72
|
+
return err
|
|
73
|
+
}
|
|
74
|
+
return printOutput(cfg.Output, resp)
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var transactionCommitCmd = &cobra.Command{
|
|
79
|
+
Use: "commit <transactionId>",
|
|
80
|
+
Short: "Commit a transaction",
|
|
81
|
+
Args: cobra.ExactArgs(1),
|
|
82
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
83
|
+
cfg, err := config.FromFlags(cmd)
|
|
84
|
+
if err != nil {
|
|
85
|
+
return err
|
|
86
|
+
}
|
|
87
|
+
client, err := cfg.ConnectAndAuth()
|
|
88
|
+
if err != nil {
|
|
89
|
+
return err
|
|
90
|
+
}
|
|
91
|
+
defer client.Disconnect()
|
|
92
|
+
resp, err := commands.CommitTransaction(client, args[0])
|
|
93
|
+
if err != nil {
|
|
94
|
+
return err
|
|
95
|
+
}
|
|
96
|
+
return printOutput(cfg.Output, resp)
|
|
97
|
+
},
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
var transactionRollbackCmd = &cobra.Command{
|
|
101
|
+
Use: "rollback <transactionId>",
|
|
102
|
+
Short: "Rollback a transaction",
|
|
103
|
+
Args: cobra.ExactArgs(1),
|
|
104
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
105
|
+
cfg, err := config.FromFlags(cmd)
|
|
106
|
+
if err != nil {
|
|
107
|
+
return err
|
|
108
|
+
}
|
|
109
|
+
client, err := cfg.ConnectAndAuth()
|
|
110
|
+
if err != nil {
|
|
111
|
+
return err
|
|
112
|
+
}
|
|
113
|
+
defer client.Disconnect()
|
|
114
|
+
resp, err := commands.RollbackTransaction(client, args[0])
|
|
115
|
+
if err != nil {
|
|
116
|
+
return err
|
|
117
|
+
}
|
|
118
|
+
return printOutput(cfg.Output, resp)
|
|
119
|
+
},
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var transactionSavepointCmd = &cobra.Command{
|
|
123
|
+
Use: "savepoint <transactionId> <name>",
|
|
124
|
+
Short: "Create a savepoint",
|
|
125
|
+
Args: cobra.ExactArgs(2),
|
|
126
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
127
|
+
cfg, err := config.FromFlags(cmd)
|
|
128
|
+
if err != nil {
|
|
129
|
+
return err
|
|
130
|
+
}
|
|
131
|
+
client, err := cfg.ConnectAndAuth()
|
|
132
|
+
if err != nil {
|
|
133
|
+
return err
|
|
134
|
+
}
|
|
135
|
+
defer client.Disconnect()
|
|
136
|
+
resp, err := commands.Savepoint(client, args[0], args[1])
|
|
137
|
+
if err != nil {
|
|
138
|
+
return err
|
|
139
|
+
}
|
|
140
|
+
return printOutput(cfg.Output, resp)
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
var transactionRollbackToCmd = &cobra.Command{
|
|
145
|
+
Use: "rollback-to <transactionId> <name>",
|
|
146
|
+
Short: "Rollback to a savepoint",
|
|
147
|
+
Args: cobra.ExactArgs(2),
|
|
148
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
149
|
+
cfg, err := config.FromFlags(cmd)
|
|
150
|
+
if err != nil {
|
|
151
|
+
return err
|
|
152
|
+
}
|
|
153
|
+
client, err := cfg.ConnectAndAuth()
|
|
154
|
+
if err != nil {
|
|
155
|
+
return err
|
|
156
|
+
}
|
|
157
|
+
defer client.Disconnect()
|
|
158
|
+
resp, err := commands.RollbackToSavepoint(client, args[0], args[1])
|
|
159
|
+
if err != nil {
|
|
160
|
+
return err
|
|
161
|
+
}
|
|
162
|
+
return printOutput(cfg.Output, resp)
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
var transactionReleaseCmd = &cobra.Command{
|
|
167
|
+
Use: "release <transactionId> <name>",
|
|
168
|
+
Short: "Release a savepoint",
|
|
169
|
+
Args: cobra.ExactArgs(2),
|
|
170
|
+
RunE: func(cmd *cobra.Command, args []string) error {
|
|
171
|
+
cfg, err := config.FromFlags(cmd)
|
|
172
|
+
if err != nil {
|
|
173
|
+
return err
|
|
174
|
+
}
|
|
175
|
+
client, err := cfg.ConnectAndAuth()
|
|
176
|
+
if err != nil {
|
|
177
|
+
return err
|
|
178
|
+
}
|
|
179
|
+
defer client.Disconnect()
|
|
180
|
+
resp, err := commands.ReleaseSavepoint(client, args[0], args[1])
|
|
181
|
+
if err != nil {
|
|
182
|
+
return err
|
|
183
|
+
}
|
|
184
|
+
return printOutput(cfg.Output, resp)
|
|
185
|
+
},
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
func init() {
|
|
189
|
+
transactionCmd.AddCommand(transactionRunCmd, transactionBeginCmd, transactionCommitCmd, transactionRollbackCmd, transactionSavepointCmd, transactionRollbackToCmd, transactionReleaseCmd)
|
|
190
|
+
rootCmd.AddCommand(transactionCmd)
|
|
191
|
+
}
|
package/cli/cmd/version.go
CHANGED
|
@@ -42,6 +42,7 @@ type QueryOptions struct {
|
|
|
42
42
|
Skip int
|
|
43
43
|
Sort interface{}
|
|
44
44
|
FindOne bool
|
|
45
|
+
Hint string
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
func QueryDocuments(client *protocol.Client, dbName, collectionName string, opts QueryOptions) (*protocol.Response, error) {
|
|
@@ -64,6 +65,9 @@ func QueryDocuments(client *protocol.Client, dbName, collectionName string, opts
|
|
|
64
65
|
if opts.FindOne {
|
|
65
66
|
params["findOne"] = true
|
|
66
67
|
}
|
|
68
|
+
if opts.Hint != "" {
|
|
69
|
+
params["hint"] = opts.Hint
|
|
70
|
+
}
|
|
67
71
|
|
|
68
72
|
resp, err := client.Send("QUERY_DOCUMENTS", params)
|
|
69
73
|
if err != nil {
|
|
@@ -90,6 +94,21 @@ func QueryByID(client *protocol.Client, dbName, collectionName, id string) (*pro
|
|
|
90
94
|
return resp, nil
|
|
91
95
|
}
|
|
92
96
|
|
|
97
|
+
func FindDocumentsByIDs(client *protocol.Client, dbName, collectionName string, ids interface{}) (*protocol.Response, error) {
|
|
98
|
+
resp, err := client.Send("FIND_BY_IDS", map[string]interface{}{
|
|
99
|
+
"dbName": dbName,
|
|
100
|
+
"collectionName": collectionName,
|
|
101
|
+
"ids": ids,
|
|
102
|
+
})
|
|
103
|
+
if err != nil {
|
|
104
|
+
return nil, fmt.Errorf("find documents by ids: %w", err)
|
|
105
|
+
}
|
|
106
|
+
if resp.StatusCode >= 400 {
|
|
107
|
+
return nil, fmt.Errorf("find documents by ids failed: %s", resp.Error)
|
|
108
|
+
}
|
|
109
|
+
return resp, nil
|
|
110
|
+
}
|
|
111
|
+
|
|
93
112
|
func UpdateDocumentByID(client *protocol.Client, dbName, collectionName, id string, updateData interface{}) (*protocol.Response, error) {
|
|
94
113
|
resp, err := client.Send("UPDATE_DOCUMENT_BY_ID", map[string]interface{}{
|
|
95
114
|
"dbName": dbName,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
package commands
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"fmt"
|
|
5
|
+
|
|
6
|
+
"github.com/nexoral/axiodb-cli/pkg/protocol"
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
func Health(client *protocol.Client) (*protocol.Response, error) {
|
|
10
|
+
resp, err := client.Send("HEALTH", nil)
|
|
11
|
+
if err != nil {
|
|
12
|
+
return nil, fmt.Errorf("get health: %w", err)
|
|
13
|
+
}
|
|
14
|
+
if resp.StatusCode >= 400 {
|
|
15
|
+
return nil, fmt.Errorf("get health failed: %s", resp.Error)
|
|
16
|
+
}
|
|
17
|
+
return resp, nil
|
|
18
|
+
}
|