mongo.do 0.1.0 → 0.1.1
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/dist/cli/index.d.ts +1 -15
- package/dist/cli/index.js +4083 -196
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +2740 -20
- package/dist/index.js +9375 -27
- package/dist/index.js.map +1 -1
- package/dist/worker-entrypoint-BEW23Gmp.d.ts +1331 -0
- package/dist/worker.d.ts +6 -5
- package/dist/worker.js +5477 -18
- package/dist/worker.js.map +1 -1
- package/package.json +3 -2
- package/dist/agentfs/adapters/anthropic.d.ts +0 -176
- package/dist/agentfs/adapters/anthropic.d.ts.map +0 -1
- package/dist/agentfs/adapters/anthropic.js +0 -629
- package/dist/agentfs/adapters/anthropic.js.map +0 -1
- package/dist/agentfs/adapters/index.d.ts +0 -21
- package/dist/agentfs/adapters/index.d.ts.map +0 -1
- package/dist/agentfs/adapters/index.js +0 -23
- package/dist/agentfs/adapters/index.js.map +0 -1
- package/dist/agentfs/adapters/vercel.d.ts +0 -260
- package/dist/agentfs/adapters/vercel.d.ts.map +0 -1
- package/dist/agentfs/adapters/vercel.js +0 -288
- package/dist/agentfs/adapters/vercel.js.map +0 -1
- package/dist/agentfs/glob.d.ts +0 -116
- package/dist/agentfs/glob.d.ts.map +0 -1
- package/dist/agentfs/glob.js +0 -270
- package/dist/agentfs/glob.js.map +0 -1
- package/dist/agentfs/grep.d.ts +0 -83
- package/dist/agentfs/grep.d.ts.map +0 -1
- package/dist/agentfs/grep.js +0 -193
- package/dist/agentfs/grep.js.map +0 -1
- package/dist/agentfs/index.d.ts +0 -22
- package/dist/agentfs/index.d.ts.map +0 -1
- package/dist/agentfs/index.js +0 -18
- package/dist/agentfs/index.js.map +0 -1
- package/dist/agentfs/kv-store.d.ts +0 -128
- package/dist/agentfs/kv-store.d.ts.map +0 -1
- package/dist/agentfs/kv-store.js +0 -227
- package/dist/agentfs/kv-store.js.map +0 -1
- package/dist/agentfs/mondo-agent.d.ts +0 -255
- package/dist/agentfs/mondo-agent.d.ts.map +0 -1
- package/dist/agentfs/mondo-agent.js +0 -879
- package/dist/agentfs/mondo-agent.js.map +0 -1
- package/dist/agentfs/toolcalls.d.ts +0 -130
- package/dist/agentfs/toolcalls.d.ts.map +0 -1
- package/dist/agentfs/toolcalls.js +0 -178
- package/dist/agentfs/toolcalls.js.map +0 -1
- package/dist/agentfs/types.d.ts +0 -171
- package/dist/agentfs/types.d.ts.map +0 -1
- package/dist/agentfs/types.js +0 -7
- package/dist/agentfs/types.js.map +0 -1
- package/dist/agentfs/vfs.d.ts +0 -249
- package/dist/agentfs/vfs.d.ts.map +0 -1
- package/dist/agentfs/vfs.js +0 -469
- package/dist/agentfs/vfs.js.map +0 -1
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/cli/mcp.d.ts +0 -119
- package/dist/cli/mcp.d.ts.map +0 -1
- package/dist/cli/mcp.js +0 -418
- package/dist/cli/mcp.js.map +0 -1
- package/dist/cli/server.d.ts +0 -179
- package/dist/cli/server.d.ts.map +0 -1
- package/dist/cli/server.js +0 -441
- package/dist/cli/server.js.map +0 -1
- package/dist/client/Collection.d.ts +0 -199
- package/dist/client/Collection.d.ts.map +0 -1
- package/dist/client/Collection.js +0 -256
- package/dist/client/Collection.js.map +0 -1
- package/dist/client/Database.d.ts +0 -68
- package/dist/client/Database.d.ts.map +0 -1
- package/dist/client/Database.js +0 -105
- package/dist/client/Database.js.map +0 -1
- package/dist/client/MongoClient.d.ts +0 -165
- package/dist/client/MongoClient.d.ts.map +0 -1
- package/dist/client/MongoClient.js +0 -307
- package/dist/client/MongoClient.js.map +0 -1
- package/dist/client/aggregation-cursor.d.ts +0 -210
- package/dist/client/aggregation-cursor.d.ts.map +0 -1
- package/dist/client/aggregation-cursor.js +0 -509
- package/dist/client/aggregation-cursor.js.map +0 -1
- package/dist/client/bulk-write.d.ts +0 -216
- package/dist/client/bulk-write.d.ts.map +0 -1
- package/dist/client/bulk-write.js +0 -63
- package/dist/client/bulk-write.js.map +0 -1
- package/dist/client/change-stream.d.ts +0 -245
- package/dist/client/change-stream.d.ts.map +0 -1
- package/dist/client/change-stream.js +0 -429
- package/dist/client/change-stream.js.map +0 -1
- package/dist/client/cursor.d.ts +0 -85
- package/dist/client/cursor.d.ts.map +0 -1
- package/dist/client/cursor.js +0 -156
- package/dist/client/cursor.js.map +0 -1
- package/dist/client/http-cursor.d.ts +0 -233
- package/dist/client/http-cursor.d.ts.map +0 -1
- package/dist/client/http-cursor.js +0 -496
- package/dist/client/http-cursor.js.map +0 -1
- package/dist/client/index.d.ts +0 -18
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/index.js +0 -24
- package/dist/client/index.js.map +0 -1
- package/dist/client/mongo-client.d.ts +0 -60
- package/dist/client/mongo-client.d.ts.map +0 -1
- package/dist/client/mongo-client.js +0 -190
- package/dist/client/mongo-client.js.map +0 -1
- package/dist/client/mongo-collection.d.ts +0 -359
- package/dist/client/mongo-collection.d.ts.map +0 -1
- package/dist/client/mongo-collection.js +0 -1641
- package/dist/client/mongo-collection.js.map +0 -1
- package/dist/client/mongo-cursor.d.ts +0 -257
- package/dist/client/mongo-cursor.d.ts.map +0 -1
- package/dist/client/mongo-cursor.js +0 -621
- package/dist/client/mongo-cursor.js.map +0 -1
- package/dist/client/mongo-database.d.ts +0 -88
- package/dist/client/mongo-database.d.ts.map +0 -1
- package/dist/client/mongo-database.js +0 -139
- package/dist/client/mongo-database.js.map +0 -1
- package/dist/client/session.d.ts +0 -210
- package/dist/client/session.d.ts.map +0 -1
- package/dist/client/session.js +0 -326
- package/dist/client/session.js.map +0 -1
- package/dist/durable-object/index-manager.d.ts +0 -173
- package/dist/durable-object/index-manager.d.ts.map +0 -1
- package/dist/durable-object/index-manager.js +0 -764
- package/dist/durable-object/index-manager.js.map +0 -1
- package/dist/durable-object/index.d.ts +0 -12
- package/dist/durable-object/index.d.ts.map +0 -1
- package/dist/durable-object/index.js +0 -8
- package/dist/durable-object/index.js.map +0 -1
- package/dist/durable-object/mcp-handler.d.ts +0 -52
- package/dist/durable-object/mcp-handler.d.ts.map +0 -1
- package/dist/durable-object/mcp-handler.js +0 -186
- package/dist/durable-object/mcp-handler.js.map +0 -1
- package/dist/durable-object/migrations.d.ts +0 -40
- package/dist/durable-object/migrations.d.ts.map +0 -1
- package/dist/durable-object/migrations.js +0 -121
- package/dist/durable-object/migrations.js.map +0 -1
- package/dist/durable-object/mondo-database.d.ts +0 -148
- package/dist/durable-object/mondo-database.d.ts.map +0 -1
- package/dist/durable-object/mondo-database.js +0 -621
- package/dist/durable-object/mondo-database.js.map +0 -1
- package/dist/durable-object/schema.d.ts +0 -192
- package/dist/durable-object/schema.d.ts.map +0 -1
- package/dist/durable-object/schema.js +0 -186
- package/dist/durable-object/schema.js.map +0 -1
- package/dist/embedding/document-serializer.d.ts +0 -118
- package/dist/embedding/document-serializer.d.ts.map +0 -1
- package/dist/embedding/document-serializer.js +0 -339
- package/dist/embedding/document-serializer.js.map +0 -1
- package/dist/embedding/embedding-manager.d.ts +0 -136
- package/dist/embedding/embedding-manager.d.ts.map +0 -1
- package/dist/embedding/embedding-manager.js +0 -176
- package/dist/embedding/embedding-manager.js.map +0 -1
- package/dist/embedding/index.d.ts +0 -9
- package/dist/embedding/index.d.ts.map +0 -1
- package/dist/embedding/index.js +0 -9
- package/dist/embedding/index.js.map +0 -1
- package/dist/executor/aggregation-executor.d.ts +0 -93
- package/dist/executor/aggregation-executor.d.ts.map +0 -1
- package/dist/executor/aggregation-executor.js +0 -275
- package/dist/executor/aggregation-executor.js.map +0 -1
- package/dist/executor/function-executor.d.ts +0 -39
- package/dist/executor/function-executor.d.ts.map +0 -1
- package/dist/executor/function-executor.js +0 -168
- package/dist/executor/function-executor.js.map +0 -1
- package/dist/executor/index.d.ts +0 -4
- package/dist/executor/index.d.ts.map +0 -1
- package/dist/executor/index.js +0 -4
- package/dist/executor/index.js.map +0 -1
- package/dist/executor/vector-search-executor.d.ts +0 -71
- package/dist/executor/vector-search-executor.d.ts.map +0 -1
- package/dist/executor/vector-search-executor.js +0 -113
- package/dist/executor/vector-search-executor.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/mcp/adapters/anthropic-adapter.d.ts +0 -256
- package/dist/mcp/adapters/anthropic-adapter.d.ts.map +0 -1
- package/dist/mcp/adapters/anthropic-adapter.js +0 -409
- package/dist/mcp/adapters/anthropic-adapter.js.map +0 -1
- package/dist/mcp/adapters/base-adapter.d.ts +0 -164
- package/dist/mcp/adapters/base-adapter.d.ts.map +0 -1
- package/dist/mcp/adapters/base-adapter.js +0 -277
- package/dist/mcp/adapters/base-adapter.js.map +0 -1
- package/dist/mcp/adapters/errors.d.ts +0 -173
- package/dist/mcp/adapters/errors.d.ts.map +0 -1
- package/dist/mcp/adapters/errors.js +0 -305
- package/dist/mcp/adapters/errors.js.map +0 -1
- package/dist/mcp/adapters/index.d.ts +0 -65
- package/dist/mcp/adapters/index.d.ts.map +0 -1
- package/dist/mcp/adapters/index.js +0 -92
- package/dist/mcp/adapters/index.js.map +0 -1
- package/dist/mcp/adapters/streaming.d.ts +0 -200
- package/dist/mcp/adapters/streaming.d.ts.map +0 -1
- package/dist/mcp/adapters/streaming.js +0 -381
- package/dist/mcp/adapters/streaming.js.map +0 -1
- package/dist/mcp/adapters/vercel-adapter.d.ts +0 -321
- package/dist/mcp/adapters/vercel-adapter.d.ts.map +0 -1
- package/dist/mcp/adapters/vercel-adapter.js +0 -487
- package/dist/mcp/adapters/vercel-adapter.js.map +0 -1
- package/dist/mcp/agent.d.ts +0 -192
- package/dist/mcp/agent.d.ts.map +0 -1
- package/dist/mcp/agent.js +0 -338
- package/dist/mcp/agent.js.map +0 -1
- package/dist/mcp/cli.d.ts +0 -71
- package/dist/mcp/cli.d.ts.map +0 -1
- package/dist/mcp/cli.js +0 -218
- package/dist/mcp/cli.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -15
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js +0 -20
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/sandbox/database-proxy.d.ts +0 -118
- package/dist/mcp/sandbox/database-proxy.d.ts.map +0 -1
- package/dist/mcp/sandbox/database-proxy.js +0 -154
- package/dist/mcp/sandbox/database-proxy.js.map +0 -1
- package/dist/mcp/sandbox/index.d.ts +0 -8
- package/dist/mcp/sandbox/index.d.ts.map +0 -1
- package/dist/mcp/sandbox/index.js +0 -7
- package/dist/mcp/sandbox/index.js.map +0 -1
- package/dist/mcp/sandbox/miniflare-evaluator.d.ts +0 -72
- package/dist/mcp/sandbox/miniflare-evaluator.d.ts.map +0 -1
- package/dist/mcp/sandbox/miniflare-evaluator.js +0 -379
- package/dist/mcp/sandbox/miniflare-evaluator.js.map +0 -1
- package/dist/mcp/sandbox/template.d.ts +0 -48
- package/dist/mcp/sandbox/template.d.ts.map +0 -1
- package/dist/mcp/sandbox/template.js +0 -147
- package/dist/mcp/sandbox/template.js.map +0 -1
- package/dist/mcp/sandbox/worker-evaluator.d.ts +0 -160
- package/dist/mcp/sandbox/worker-evaluator.d.ts.map +0 -1
- package/dist/mcp/sandbox/worker-evaluator.js +0 -217
- package/dist/mcp/sandbox/worker-evaluator.js.map +0 -1
- package/dist/mcp/server.d.ts +0 -75
- package/dist/mcp/server.d.ts.map +0 -1
- package/dist/mcp/server.js +0 -278
- package/dist/mcp/server.js.map +0 -1
- package/dist/mcp/tool-call-auditor.d.ts +0 -188
- package/dist/mcp/tool-call-auditor.d.ts.map +0 -1
- package/dist/mcp/tool-call-auditor.js +0 -198
- package/dist/mcp/tool-call-auditor.js.map +0 -1
- package/dist/mcp/tools/do.d.ts +0 -51
- package/dist/mcp/tools/do.d.ts.map +0 -1
- package/dist/mcp/tools/do.js +0 -113
- package/dist/mcp/tools/do.js.map +0 -1
- package/dist/mcp/tools/fetch.d.ts +0 -43
- package/dist/mcp/tools/fetch.d.ts.map +0 -1
- package/dist/mcp/tools/fetch.js +0 -127
- package/dist/mcp/tools/fetch.js.map +0 -1
- package/dist/mcp/tools/index.d.ts +0 -9
- package/dist/mcp/tools/index.d.ts.map +0 -1
- package/dist/mcp/tools/index.js +0 -9
- package/dist/mcp/tools/index.js.map +0 -1
- package/dist/mcp/tools/search.d.ts +0 -60
- package/dist/mcp/tools/search.d.ts.map +0 -1
- package/dist/mcp/tools/search.js +0 -278
- package/dist/mcp/tools/search.js.map +0 -1
- package/dist/mcp/transport/http.d.ts +0 -144
- package/dist/mcp/transport/http.d.ts.map +0 -1
- package/dist/mcp/transport/http.js +0 -545
- package/dist/mcp/transport/http.js.map +0 -1
- package/dist/mcp/transport/index.d.ts +0 -10
- package/dist/mcp/transport/index.d.ts.map +0 -1
- package/dist/mcp/transport/index.js +0 -12
- package/dist/mcp/transport/index.js.map +0 -1
- package/dist/mcp/transport/stdio.d.ts +0 -132
- package/dist/mcp/transport/stdio.d.ts.map +0 -1
- package/dist/mcp/transport/stdio.js +0 -466
- package/dist/mcp/transport/stdio.js.map +0 -1
- package/dist/mcp/types.d.ts +0 -476
- package/dist/mcp/types.d.ts.map +0 -1
- package/dist/mcp/types.js +0 -178
- package/dist/mcp/types.js.map +0 -1
- package/dist/olap/cdc/cdc-buffer.d.ts +0 -92
- package/dist/olap/cdc/cdc-buffer.d.ts.map +0 -1
- package/dist/olap/cdc/cdc-buffer.js +0 -146
- package/dist/olap/cdc/cdc-buffer.js.map +0 -1
- package/dist/olap/cdc/cdc-emitter.d.ts +0 -118
- package/dist/olap/cdc/cdc-emitter.d.ts.map +0 -1
- package/dist/olap/cdc/cdc-emitter.js +0 -217
- package/dist/olap/cdc/cdc-emitter.js.map +0 -1
- package/dist/olap/cdc/cdc-schema.d.ts +0 -119
- package/dist/olap/cdc/cdc-schema.d.ts.map +0 -1
- package/dist/olap/cdc/cdc-schema.js +0 -253
- package/dist/olap/cdc/cdc-schema.js.map +0 -1
- package/dist/olap/cdc/index.d.ts +0 -10
- package/dist/olap/cdc/index.d.ts.map +0 -1
- package/dist/olap/cdc/index.js +0 -10
- package/dist/olap/cdc/index.js.map +0 -1
- package/dist/olap/clickhouse/iceberg.d.ts +0 -164
- package/dist/olap/clickhouse/iceberg.d.ts.map +0 -1
- package/dist/olap/clickhouse/iceberg.js +0 -138
- package/dist/olap/clickhouse/iceberg.js.map +0 -1
- package/dist/olap/clickhouse/index.d.ts +0 -14
- package/dist/olap/clickhouse/index.d.ts.map +0 -1
- package/dist/olap/clickhouse/index.js +0 -14
- package/dist/olap/clickhouse/index.js.map +0 -1
- package/dist/olap/clickhouse/mapper.d.ts +0 -170
- package/dist/olap/clickhouse/mapper.d.ts.map +0 -1
- package/dist/olap/clickhouse/mapper.js +0 -654
- package/dist/olap/clickhouse/mapper.js.map +0 -1
- package/dist/olap/clickhouse/olap-backend.d.ts +0 -181
- package/dist/olap/clickhouse/olap-backend.d.ts.map +0 -1
- package/dist/olap/clickhouse/olap-backend.js +0 -1083
- package/dist/olap/clickhouse/olap-backend.js.map +0 -1
- package/dist/olap/clickhouse/query-executor.d.ts +0 -163
- package/dist/olap/clickhouse/query-executor.d.ts.map +0 -1
- package/dist/olap/clickhouse/query-executor.js +0 -560
- package/dist/olap/clickhouse/query-executor.js.map +0 -1
- package/dist/olap/clickhouse/query.d.ts +0 -134
- package/dist/olap/clickhouse/query.d.ts.map +0 -1
- package/dist/olap/clickhouse/query.js +0 -512
- package/dist/olap/clickhouse/query.js.map +0 -1
- package/dist/olap/stage/index.d.ts +0 -6
- package/dist/olap/stage/index.d.ts.map +0 -1
- package/dist/olap/stage/index.js +0 -6
- package/dist/olap/stage/index.js.map +0 -1
- package/dist/olap/stage/parser.d.ts +0 -68
- package/dist/olap/stage/parser.d.ts.map +0 -1
- package/dist/olap/stage/parser.js +0 -293
- package/dist/olap/stage/parser.js.map +0 -1
- package/dist/olap/stage/router.d.ts +0 -94
- package/dist/olap/stage/router.d.ts.map +0 -1
- package/dist/olap/stage/router.js +0 -390
- package/dist/olap/stage/router.js.map +0 -1
- package/dist/rpc/endpoint.d.ts +0 -52
- package/dist/rpc/endpoint.d.ts.map +0 -1
- package/dist/rpc/endpoint.js +0 -734
- package/dist/rpc/endpoint.js.map +0 -1
- package/dist/rpc/index.d.ts +0 -34
- package/dist/rpc/index.d.ts.map +0 -1
- package/dist/rpc/index.js +0 -45
- package/dist/rpc/index.js.map +0 -1
- package/dist/rpc/rpc-client.d.ts +0 -275
- package/dist/rpc/rpc-client.d.ts.map +0 -1
- package/dist/rpc/rpc-client.js +0 -735
- package/dist/rpc/rpc-client.js.map +0 -1
- package/dist/rpc/rpc-target.d.ts +0 -220
- package/dist/rpc/rpc-target.d.ts.map +0 -1
- package/dist/rpc/rpc-target.js +0 -500
- package/dist/rpc/rpc-target.js.map +0 -1
- package/dist/rpc/worker-entrypoint.d.ts +0 -159
- package/dist/rpc/worker-entrypoint.d.ts.map +0 -1
- package/dist/rpc/worker-entrypoint.js +0 -212
- package/dist/rpc/worker-entrypoint.js.map +0 -1
- package/dist/server.d.ts +0 -18
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -129
- package/dist/server.js.map +0 -1
- package/dist/studio/components/browser/CollectionItem.d.ts +0 -26
- package/dist/studio/components/browser/CollectionItem.d.ts.map +0 -1
- package/dist/studio/components/browser/CollectionItem.js +0 -143
- package/dist/studio/components/browser/CollectionItem.js.map +0 -1
- package/dist/studio/components/browser/CollectionTree.d.ts +0 -45
- package/dist/studio/components/browser/CollectionTree.d.ts.map +0 -1
- package/dist/studio/components/browser/CollectionTree.js +0 -207
- package/dist/studio/components/browser/CollectionTree.js.map +0 -1
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.d.ts +0 -51
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.d.ts.map +0 -1
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.js +0 -185
- package/dist/studio/components/browser/ConnectedDatabaseBrowser.js.map +0 -1
- package/dist/studio/components/browser/DatabaseBrowser.d.ts +0 -46
- package/dist/studio/components/browser/DatabaseBrowser.d.ts.map +0 -1
- package/dist/studio/components/browser/DatabaseBrowser.js +0 -304
- package/dist/studio/components/browser/DatabaseBrowser.js.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionItem.test.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/CollectionItem.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionItem.test.js +0 -169
- package/dist/studio/components/browser/__tests__/CollectionItem.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionTree.test.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/CollectionTree.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/CollectionTree.test.js +0 -203
- package/dist/studio/components/browser/__tests__/CollectionTree.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.d.ts +0 -8
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.js +0 -522
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.e2e.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.js +0 -518
- package/dist/studio/components/browser/__tests__/DatabaseBrowser.test.js.map +0 -1
- package/dist/studio/components/browser/__tests__/setup.d.ts +0 -5
- package/dist/studio/components/browser/__tests__/setup.d.ts.map +0 -1
- package/dist/studio/components/browser/__tests__/setup.js +0 -22
- package/dist/studio/components/browser/__tests__/setup.js.map +0 -1
- package/dist/studio/components/browser/index.d.ts +0 -15
- package/dist/studio/components/browser/index.d.ts.map +0 -1
- package/dist/studio/components/browser/index.js +0 -10
- package/dist/studio/components/browser/index.js.map +0 -1
- package/dist/studio/components/browser/types.d.ts +0 -33
- package/dist/studio/components/browser/types.d.ts.map +0 -1
- package/dist/studio/components/browser/types.js +0 -5
- package/dist/studio/components/browser/types.js.map +0 -1
- package/dist/studio/components/connection/ConnectionForm.d.ts +0 -59
- package/dist/studio/components/connection/ConnectionForm.d.ts.map +0 -1
- package/dist/studio/components/connection/ConnectionForm.js +0 -274
- package/dist/studio/components/connection/ConnectionForm.js.map +0 -1
- package/dist/studio/components/connection/ConnectionList.d.ts +0 -59
- package/dist/studio/components/connection/ConnectionList.d.ts.map +0 -1
- package/dist/studio/components/connection/ConnectionList.js +0 -286
- package/dist/studio/components/connection/ConnectionList.js.map +0 -1
- package/dist/studio/components/connection/ConnectionPanel.d.ts +0 -132
- package/dist/studio/components/connection/ConnectionPanel.d.ts.map +0 -1
- package/dist/studio/components/connection/ConnectionPanel.js +0 -293
- package/dist/studio/components/connection/ConnectionPanel.js.map +0 -1
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.d.ts +0 -8
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.d.ts.map +0 -1
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.js +0 -632
- package/dist/studio/components/connection/__tests__/ConnectionPanel.test.js.map +0 -1
- package/dist/studio/components/connection/__tests__/setup.d.ts +0 -5
- package/dist/studio/components/connection/__tests__/setup.d.ts.map +0 -1
- package/dist/studio/components/connection/__tests__/setup.js +0 -11
- package/dist/studio/components/connection/__tests__/setup.js.map +0 -1
- package/dist/studio/components/connection/index.d.ts +0 -10
- package/dist/studio/components/connection/index.d.ts.map +0 -1
- package/dist/studio/components/connection/index.js +0 -7
- package/dist/studio/components/connection/index.js.map +0 -1
- package/dist/studio/components/crud/DeleteDocumentDialog.d.ts +0 -91
- package/dist/studio/components/crud/DeleteDocumentDialog.d.ts.map +0 -1
- package/dist/studio/components/crud/DeleteDocumentDialog.js +0 -273
- package/dist/studio/components/crud/DeleteDocumentDialog.js.map +0 -1
- package/dist/studio/components/crud/DocumentEditor.d.ts +0 -32
- package/dist/studio/components/crud/DocumentEditor.d.ts.map +0 -1
- package/dist/studio/components/crud/DocumentEditor.js +0 -546
- package/dist/studio/components/crud/DocumentEditor.js.map +0 -1
- package/dist/studio/components/crud/InsertDocumentDialog.d.ts +0 -78
- package/dist/studio/components/crud/InsertDocumentDialog.d.ts.map +0 -1
- package/dist/studio/components/crud/InsertDocumentDialog.js +0 -323
- package/dist/studio/components/crud/InsertDocumentDialog.js.map +0 -1
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.d.ts +0 -5
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.js +0 -298
- package/dist/studio/components/crud/__tests__/DeleteDocumentDialog.test.js.map +0 -1
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.d.ts +0 -8
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.js +0 -368
- package/dist/studio/components/crud/__tests__/DocumentEditor.test.js.map +0 -1
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.d.ts +0 -2
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.js +0 -352
- package/dist/studio/components/crud/__tests__/InsertDocumentDialog.test.js.map +0 -1
- package/dist/studio/components/crud/__tests__/setup.d.ts +0 -5
- package/dist/studio/components/crud/__tests__/setup.d.ts.map +0 -1
- package/dist/studio/components/crud/__tests__/setup.js +0 -22
- package/dist/studio/components/crud/__tests__/setup.js.map +0 -1
- package/dist/studio/components/crud/index.d.ts +0 -12
- package/dist/studio/components/crud/index.d.ts.map +0 -1
- package/dist/studio/components/crud/index.js +0 -11
- package/dist/studio/components/crud/index.js.map +0 -1
- package/dist/studio/hooks/useConnection.d.ts +0 -127
- package/dist/studio/hooks/useConnection.d.ts.map +0 -1
- package/dist/studio/hooks/useConnection.js +0 -414
- package/dist/studio/hooks/useConnection.js.map +0 -1
- package/dist/studio/hooks/useDatabaseBrowser.d.ts +0 -107
- package/dist/studio/hooks/useDatabaseBrowser.d.ts.map +0 -1
- package/dist/studio/hooks/useDatabaseBrowser.js +0 -294
- package/dist/studio/hooks/useDatabaseBrowser.js.map +0 -1
- package/dist/studio/index.d.ts +0 -16
- package/dist/studio/index.d.ts.map +0 -1
- package/dist/studio/index.js +0 -14
- package/dist/studio/index.js.map +0 -1
- package/dist/studio/types/connection.d.ts +0 -266
- package/dist/studio/types/connection.d.ts.map +0 -1
- package/dist/studio/types/connection.js +0 -159
- package/dist/studio/types/connection.js.map +0 -1
- package/dist/studio/vitest.config.d.ts +0 -3
- package/dist/studio/vitest.config.d.ts.map +0 -1
- package/dist/studio/vitest.config.js +0 -33
- package/dist/studio/vitest.config.js.map +0 -1
- package/dist/translator/aggregation-translator.d.ts +0 -51
- package/dist/translator/aggregation-translator.d.ts.map +0 -1
- package/dist/translator/aggregation-translator.js +0 -324
- package/dist/translator/aggregation-translator.js.map +0 -1
- package/dist/translator/dialect.d.ts +0 -131
- package/dist/translator/dialect.d.ts.map +0 -1
- package/dist/translator/dialect.js +0 -276
- package/dist/translator/dialect.js.map +0 -1
- package/dist/translator/geo-translator.d.ts +0 -91
- package/dist/translator/geo-translator.d.ts.map +0 -1
- package/dist/translator/geo-translator.js +0 -587
- package/dist/translator/geo-translator.js.map +0 -1
- package/dist/translator/hybrid-translator.d.ts +0 -70
- package/dist/translator/hybrid-translator.d.ts.map +0 -1
- package/dist/translator/hybrid-translator.js +0 -193
- package/dist/translator/hybrid-translator.js.map +0 -1
- package/dist/translator/index.d.ts +0 -13
- package/dist/translator/index.d.ts.map +0 -1
- package/dist/translator/index.js +0 -11
- package/dist/translator/index.js.map +0 -1
- package/dist/translator/query-translator.d.ts +0 -211
- package/dist/translator/query-translator.d.ts.map +0 -1
- package/dist/translator/query-translator.js +0 -1276
- package/dist/translator/query-translator.js.map +0 -1
- package/dist/translator/search-highlight.d.ts +0 -83
- package/dist/translator/search-highlight.d.ts.map +0 -1
- package/dist/translator/search-highlight.js +0 -83
- package/dist/translator/search-highlight.js.map +0 -1
- package/dist/translator/search-translator.d.ts +0 -155
- package/dist/translator/search-translator.d.ts.map +0 -1
- package/dist/translator/search-translator.js +0 -241
- package/dist/translator/search-translator.js.map +0 -1
- package/dist/translator/stages/add-fields-stage.d.ts +0 -7
- package/dist/translator/stages/add-fields-stage.d.ts.map +0 -1
- package/dist/translator/stages/add-fields-stage.js +0 -72
- package/dist/translator/stages/add-fields-stage.js.map +0 -1
- package/dist/translator/stages/bucket-stage.d.ts +0 -7
- package/dist/translator/stages/bucket-stage.d.ts.map +0 -1
- package/dist/translator/stages/bucket-stage.js +0 -87
- package/dist/translator/stages/bucket-stage.js.map +0 -1
- package/dist/translator/stages/count-stage.d.ts +0 -7
- package/dist/translator/stages/count-stage.d.ts.map +0 -1
- package/dist/translator/stages/count-stage.js +0 -12
- package/dist/translator/stages/count-stage.js.map +0 -1
- package/dist/translator/stages/expression-translator.d.ts +0 -68
- package/dist/translator/stages/expression-translator.d.ts.map +0 -1
- package/dist/translator/stages/expression-translator.js +0 -467
- package/dist/translator/stages/expression-translator.js.map +0 -1
- package/dist/translator/stages/facet-stage.d.ts +0 -13
- package/dist/translator/stages/facet-stage.d.ts.map +0 -1
- package/dist/translator/stages/facet-stage.js +0 -26
- package/dist/translator/stages/facet-stage.js.map +0 -1
- package/dist/translator/stages/fusion-stages.d.ts +0 -118
- package/dist/translator/stages/fusion-stages.d.ts.map +0 -1
- package/dist/translator/stages/fusion-stages.js +0 -201
- package/dist/translator/stages/fusion-stages.js.map +0 -1
- package/dist/translator/stages/group-stage.d.ts +0 -8
- package/dist/translator/stages/group-stage.d.ts.map +0 -1
- package/dist/translator/stages/group-stage.js +0 -123
- package/dist/translator/stages/group-stage.js.map +0 -1
- package/dist/translator/stages/index.d.ts +0 -24
- package/dist/translator/stages/index.d.ts.map +0 -1
- package/dist/translator/stages/index.js +0 -24
- package/dist/translator/stages/index.js.map +0 -1
- package/dist/translator/stages/join-optimizer.d.ts +0 -37
- package/dist/translator/stages/join-optimizer.d.ts.map +0 -1
- package/dist/translator/stages/join-optimizer.js +0 -93
- package/dist/translator/stages/join-optimizer.js.map +0 -1
- package/dist/translator/stages/limit-stage.d.ts +0 -7
- package/dist/translator/stages/limit-stage.d.ts.map +0 -1
- package/dist/translator/stages/limit-stage.js +0 -11
- package/dist/translator/stages/limit-stage.js.map +0 -1
- package/dist/translator/stages/lookup-stage.d.ts +0 -7
- package/dist/translator/stages/lookup-stage.d.ts.map +0 -1
- package/dist/translator/stages/lookup-stage.js +0 -73
- package/dist/translator/stages/lookup-stage.js.map +0 -1
- package/dist/translator/stages/match-stage.d.ts +0 -7
- package/dist/translator/stages/match-stage.d.ts.map +0 -1
- package/dist/translator/stages/match-stage.js +0 -14
- package/dist/translator/stages/match-stage.js.map +0 -1
- package/dist/translator/stages/optimizer.d.ts +0 -15
- package/dist/translator/stages/optimizer.d.ts.map +0 -1
- package/dist/translator/stages/optimizer.js +0 -249
- package/dist/translator/stages/optimizer.js.map +0 -1
- package/dist/translator/stages/parallel-facet.d.ts +0 -47
- package/dist/translator/stages/parallel-facet.d.ts.map +0 -1
- package/dist/translator/stages/parallel-facet.js +0 -57
- package/dist/translator/stages/parallel-facet.js.map +0 -1
- package/dist/translator/stages/project-stage.d.ts +0 -8
- package/dist/translator/stages/project-stage.d.ts.map +0 -1
- package/dist/translator/stages/project-stage.js +0 -145
- package/dist/translator/stages/project-stage.js.map +0 -1
- package/dist/translator/stages/search-stage.d.ts +0 -60
- package/dist/translator/stages/search-stage.d.ts.map +0 -1
- package/dist/translator/stages/search-stage.js +0 -89
- package/dist/translator/stages/search-stage.js.map +0 -1
- package/dist/translator/stages/skip-stage.d.ts +0 -7
- package/dist/translator/stages/skip-stage.d.ts.map +0 -1
- package/dist/translator/stages/skip-stage.js +0 -11
- package/dist/translator/stages/skip-stage.js.map +0 -1
- package/dist/translator/stages/sort-stage.d.ts +0 -7
- package/dist/translator/stages/sort-stage.d.ts.map +0 -1
- package/dist/translator/stages/sort-stage.js +0 -21
- package/dist/translator/stages/sort-stage.js.map +0 -1
- package/dist/translator/stages/types.d.ts +0 -136
- package/dist/translator/stages/types.d.ts.map +0 -1
- package/dist/translator/stages/types.js +0 -5
- package/dist/translator/stages/types.js.map +0 -1
- package/dist/translator/stages/unwind-stage.d.ts +0 -7
- package/dist/translator/stages/unwind-stage.d.ts.map +0 -1
- package/dist/translator/stages/unwind-stage.js +0 -61
- package/dist/translator/stages/unwind-stage.js.map +0 -1
- package/dist/translator/stages/vector-search-stage.d.ts +0 -53
- package/dist/translator/stages/vector-search-stage.d.ts.map +0 -1
- package/dist/translator/stages/vector-search-stage.js +0 -62
- package/dist/translator/stages/vector-search-stage.js.map +0 -1
- package/dist/translator/update-translator.d.ts +0 -148
- package/dist/translator/update-translator.d.ts.map +0 -1
- package/dist/translator/update-translator.js +0 -819
- package/dist/translator/update-translator.js.map +0 -1
- package/dist/translator/vector-translator.d.ts +0 -89
- package/dist/translator/vector-translator.d.ts.map +0 -1
- package/dist/translator/vector-translator.js +0 -106
- package/dist/translator/vector-translator.js.map +0 -1
- package/dist/types/env.d.ts +0 -31
- package/dist/types/env.d.ts.map +0 -1
- package/dist/types/env.js +0 -5
- package/dist/types/env.js.map +0 -1
- package/dist/types/function.d.ts +0 -65
- package/dist/types/function.d.ts.map +0 -1
- package/dist/types/function.js +0 -5
- package/dist/types/function.js.map +0 -1
- package/dist/types/index.d.ts +0 -137
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -13
- package/dist/types/index.js.map +0 -1
- package/dist/types/mongodb.d.ts +0 -258
- package/dist/types/mongodb.d.ts.map +0 -1
- package/dist/types/mongodb.js +0 -5
- package/dist/types/mongodb.js.map +0 -1
- package/dist/types/objectid.d.ts +0 -130
- package/dist/types/objectid.d.ts.map +0 -1
- package/dist/types/objectid.js +0 -314
- package/dist/types/objectid.js.map +0 -1
- package/dist/types/rpc.d.ts +0 -313
- package/dist/types/rpc.d.ts.map +0 -1
- package/dist/types/rpc.js +0 -136
- package/dist/types/rpc.js.map +0 -1
- package/dist/types/vectorize.d.ts +0 -136
- package/dist/types/vectorize.d.ts.map +0 -1
- package/dist/types/vectorize.js +0 -8
- package/dist/types/vectorize.js.map +0 -1
- package/dist/utils/sql-safety.d.ts +0 -64
- package/dist/utils/sql-safety.d.ts.map +0 -1
- package/dist/utils/sql-safety.js +0 -112
- package/dist/utils/sql-safety.js.map +0 -1
- package/dist/validation/document-validator.d.ts +0 -195
- package/dist/validation/document-validator.d.ts.map +0 -1
- package/dist/validation/document-validator.js +0 -529
- package/dist/validation/document-validator.js.map +0 -1
- package/dist/vectorize/document-serializer.d.ts +0 -119
- package/dist/vectorize/document-serializer.d.ts.map +0 -1
- package/dist/vectorize/document-serializer.js +0 -320
- package/dist/vectorize/document-serializer.js.map +0 -1
- package/dist/wire/auth/index.d.ts +0 -5
- package/dist/wire/auth/index.d.ts.map +0 -1
- package/dist/wire/auth/index.js +0 -5
- package/dist/wire/auth/index.js.map +0 -1
- package/dist/wire/auth/scram.d.ts +0 -160
- package/dist/wire/auth/scram.d.ts.map +0 -1
- package/dist/wire/auth/scram.js +0 -425
- package/dist/wire/auth/scram.js.map +0 -1
- package/dist/wire/backend/interface.d.ts +0 -168
- package/dist/wire/backend/interface.d.ts.map +0 -1
- package/dist/wire/backend/interface.js +0 -10
- package/dist/wire/backend/interface.js.map +0 -1
- package/dist/wire/backend/local-sqlite.d.ts +0 -89
- package/dist/wire/backend/local-sqlite.d.ts.map +0 -1
- package/dist/wire/backend/local-sqlite.js +0 -1002
- package/dist/wire/backend/local-sqlite.js.map +0 -1
- package/dist/wire/backend/query-router.d.ts +0 -197
- package/dist/wire/backend/query-router.d.ts.map +0 -1
- package/dist/wire/backend/query-router.js +0 -590
- package/dist/wire/backend/query-router.js.map +0 -1
- package/dist/wire/backend/validation.d.ts +0 -26
- package/dist/wire/backend/validation.d.ts.map +0 -1
- package/dist/wire/backend/validation.js +0 -79
- package/dist/wire/backend/validation.js.map +0 -1
- package/dist/wire/backend/workers-proxy.d.ts +0 -95
- package/dist/wire/backend/workers-proxy.d.ts.map +0 -1
- package/dist/wire/backend/workers-proxy.js +0 -429
- package/dist/wire/backend/workers-proxy.js.map +0 -1
- package/dist/wire/commands/admin.d.ts +0 -49
- package/dist/wire/commands/admin.d.ts.map +0 -1
- package/dist/wire/commands/admin.js +0 -272
- package/dist/wire/commands/admin.js.map +0 -1
- package/dist/wire/commands/aggregate.d.ts +0 -15
- package/dist/wire/commands/aggregate.d.ts.map +0 -1
- package/dist/wire/commands/aggregate.js +0 -98
- package/dist/wire/commands/aggregate.js.map +0 -1
- package/dist/wire/commands/auth.d.ts +0 -58
- package/dist/wire/commands/auth.d.ts.map +0 -1
- package/dist/wire/commands/auth.js +0 -158
- package/dist/wire/commands/auth.js.map +0 -1
- package/dist/wire/commands/crud.d.ts +0 -49
- package/dist/wire/commands/crud.d.ts.map +0 -1
- package/dist/wire/commands/crud.js +0 -336
- package/dist/wire/commands/crud.js.map +0 -1
- package/dist/wire/commands/hello.d.ts +0 -35
- package/dist/wire/commands/hello.d.ts.map +0 -1
- package/dist/wire/commands/hello.js +0 -204
- package/dist/wire/commands/hello.js.map +0 -1
- package/dist/wire/commands/index.d.ts +0 -24
- package/dist/wire/commands/index.d.ts.map +0 -1
- package/dist/wire/commands/index.js +0 -145
- package/dist/wire/commands/index.js.map +0 -1
- package/dist/wire/commands/router.d.ts +0 -46
- package/dist/wire/commands/router.d.ts.map +0 -1
- package/dist/wire/commands/router.js +0 -151
- package/dist/wire/commands/router.js.map +0 -1
- package/dist/wire/commands/types.d.ts +0 -51
- package/dist/wire/commands/types.d.ts.map +0 -1
- package/dist/wire/commands/types.js +0 -15
- package/dist/wire/commands/types.js.map +0 -1
- package/dist/wire/index.d.ts +0 -15
- package/dist/wire/index.d.ts.map +0 -1
- package/dist/wire/index.js +0 -19
- package/dist/wire/index.js.map +0 -1
- package/dist/wire/message.d.ts +0 -49
- package/dist/wire/message.d.ts.map +0 -1
- package/dist/wire/message.js +0 -299
- package/dist/wire/message.js.map +0 -1
- package/dist/wire/server.d.ts +0 -145
- package/dist/wire/server.d.ts.map +0 -1
- package/dist/wire/server.js +0 -284
- package/dist/wire/server.js.map +0 -1
- package/dist/wire/types.d.ts +0 -140
- package/dist/wire/types.d.ts.map +0 -1
- package/dist/wire/types.js +0 -64
- package/dist/wire/types.js.map +0 -1
- package/dist/worker.d.ts.map +0 -1
|
@@ -1,1083 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ClickHouse OLAP Backend
|
|
3
|
-
*
|
|
4
|
-
* Read-only backend implementing MondoBackend interface for analytical queries.
|
|
5
|
-
* Uses ClickHouse HTTP API for query execution with MongoDB query translation.
|
|
6
|
-
*
|
|
7
|
-
* Key features:
|
|
8
|
-
* - Read-only: All write operations throw ReadOnlyOperationError
|
|
9
|
-
* - Query translation: MongoDB queries/aggregations -> ClickHouse SQL
|
|
10
|
-
* - Type mapping: ClickHouse types -> BSON documents
|
|
11
|
-
* - Cursor management: Handles batched results
|
|
12
|
-
*
|
|
13
|
-
* Issue: mongo.do-yubk
|
|
14
|
-
*/
|
|
15
|
-
import { ObjectId } from '../../types/objectid';
|
|
16
|
-
import { createQueryExecutor, ClickHouseError, } from './query-executor';
|
|
17
|
-
import { ClickHouseResultMapper, } from './mapper';
|
|
18
|
-
// =============================================================================
|
|
19
|
-
// Error Classes
|
|
20
|
-
// =============================================================================
|
|
21
|
-
/**
|
|
22
|
-
* Error thrown when attempting write operations on read-only OLAP backend
|
|
23
|
-
*/
|
|
24
|
-
export class ReadOnlyOperationError extends Error {
|
|
25
|
-
operation;
|
|
26
|
-
constructor(operation) {
|
|
27
|
-
super(`Read-only OLAP backend: ${operation} operations are not supported. ` +
|
|
28
|
-
`This backend is designed for analytical read queries only. ` +
|
|
29
|
-
`Write operations (insert, update, delete) are not available.`);
|
|
30
|
-
this.name = 'ReadOnlyOperationError';
|
|
31
|
-
this.operation = operation;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// =============================================================================
|
|
35
|
-
// ClickHouse OLAP Backend
|
|
36
|
-
// =============================================================================
|
|
37
|
-
/** Default batch size for cursor results */
|
|
38
|
-
const DEFAULT_BATCH_SIZE = 101;
|
|
39
|
-
/** Default result limit to prevent excessive memory usage */
|
|
40
|
-
const DEFAULT_RESULT_LIMIT = 10000;
|
|
41
|
-
/** Cursor timeout in milliseconds (10 minutes) */
|
|
42
|
-
const CURSOR_TIMEOUT_MS = 10 * 60 * 1000;
|
|
43
|
-
/**
|
|
44
|
-
* ClickHouse OLAP Backend
|
|
45
|
-
*
|
|
46
|
-
* Implements MondoBackend interface for read-only analytical queries.
|
|
47
|
-
*/
|
|
48
|
-
export class ClickHouseOLAPBackend {
|
|
49
|
-
_executor;
|
|
50
|
-
_mapper;
|
|
51
|
-
_config;
|
|
52
|
-
_cursors = new Map();
|
|
53
|
-
_nextCursorId = 1n;
|
|
54
|
-
_customHeaders;
|
|
55
|
-
constructor(config, executor) {
|
|
56
|
-
this._config = {
|
|
57
|
-
defaultLimit: DEFAULT_RESULT_LIMIT,
|
|
58
|
-
...config,
|
|
59
|
-
};
|
|
60
|
-
this._executor = executor;
|
|
61
|
-
this._mapper = new ClickHouseResultMapper({
|
|
62
|
-
preserveObjectId: true,
|
|
63
|
-
treatTimestampAsDate: true,
|
|
64
|
-
});
|
|
65
|
-
this._customHeaders = config.headers || {};
|
|
66
|
-
}
|
|
67
|
-
// ===========================================================================
|
|
68
|
-
// Database Operations
|
|
69
|
-
// ===========================================================================
|
|
70
|
-
async listDatabases() {
|
|
71
|
-
const sql = 'SELECT name, engine FROM system.databases ORDER BY name';
|
|
72
|
-
const result = await this._executeQuery(sql);
|
|
73
|
-
return result.rows.map((row) => ({
|
|
74
|
-
name: row.name,
|
|
75
|
-
sizeOnDisk: 0, // ClickHouse doesn't easily provide this
|
|
76
|
-
empty: false,
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
async createDatabase(_name) {
|
|
80
|
-
throw new ReadOnlyOperationError('createDatabase');
|
|
81
|
-
}
|
|
82
|
-
async dropDatabase(_name) {
|
|
83
|
-
throw new ReadOnlyOperationError('dropDatabase');
|
|
84
|
-
}
|
|
85
|
-
async databaseExists(name) {
|
|
86
|
-
const sql = `SELECT name FROM system.databases WHERE name = '${this._escapeString(name)}' LIMIT 1`;
|
|
87
|
-
const result = await this._executeQuery(sql);
|
|
88
|
-
return result.rows.length > 0;
|
|
89
|
-
}
|
|
90
|
-
// ===========================================================================
|
|
91
|
-
// Collection Operations
|
|
92
|
-
// ===========================================================================
|
|
93
|
-
async listCollections(dbName, filter) {
|
|
94
|
-
let sql = `
|
|
95
|
-
SELECT
|
|
96
|
-
name,
|
|
97
|
-
engine,
|
|
98
|
-
total_rows
|
|
99
|
-
FROM system.tables
|
|
100
|
-
WHERE database = '${this._escapeString(dbName)}'
|
|
101
|
-
`;
|
|
102
|
-
if (filter?.name && typeof filter.name === 'string') {
|
|
103
|
-
sql += ` AND name = '${this._escapeString(filter.name)}'`;
|
|
104
|
-
}
|
|
105
|
-
sql += ' ORDER BY name';
|
|
106
|
-
const result = await this._executeQuery(sql);
|
|
107
|
-
return result.rows.map((row) => ({
|
|
108
|
-
name: row.name,
|
|
109
|
-
type: 'collection',
|
|
110
|
-
options: { engine: row.engine },
|
|
111
|
-
info: {
|
|
112
|
-
readOnly: true, // OLAP is always read-only
|
|
113
|
-
},
|
|
114
|
-
}));
|
|
115
|
-
}
|
|
116
|
-
async createCollection(_db, _name, _options) {
|
|
117
|
-
throw new ReadOnlyOperationError('createCollection');
|
|
118
|
-
}
|
|
119
|
-
async dropCollection(_db, _name) {
|
|
120
|
-
throw new ReadOnlyOperationError('dropCollection');
|
|
121
|
-
}
|
|
122
|
-
async collectionExists(dbName, name) {
|
|
123
|
-
const sql = `
|
|
124
|
-
SELECT name
|
|
125
|
-
FROM system.tables
|
|
126
|
-
WHERE database = '${this._escapeString(dbName)}'
|
|
127
|
-
AND name = '${this._escapeString(name)}'
|
|
128
|
-
LIMIT 1
|
|
129
|
-
`;
|
|
130
|
-
const result = await this._executeQuery(sql);
|
|
131
|
-
return result.rows.length > 0;
|
|
132
|
-
}
|
|
133
|
-
async collStats(dbName, collection) {
|
|
134
|
-
const sql = `
|
|
135
|
-
SELECT
|
|
136
|
-
rows,
|
|
137
|
-
bytes_on_disk,
|
|
138
|
-
data_compressed_bytes,
|
|
139
|
-
data_uncompressed_bytes,
|
|
140
|
-
primary_key_bytes_in_memory
|
|
141
|
-
FROM system.parts
|
|
142
|
-
WHERE database = '${this._escapeString(dbName)}'
|
|
143
|
-
AND table = '${this._escapeString(collection)}'
|
|
144
|
-
AND active = 1
|
|
145
|
-
`;
|
|
146
|
-
const result = await this._executeQuery(sql);
|
|
147
|
-
// Aggregate stats from all parts
|
|
148
|
-
let totalRows = 0;
|
|
149
|
-
let totalBytesOnDisk = 0;
|
|
150
|
-
let totalUncompressed = 0;
|
|
151
|
-
let totalIndexSize = 0;
|
|
152
|
-
for (const row of result.rows) {
|
|
153
|
-
totalRows += row.rows;
|
|
154
|
-
totalBytesOnDisk += row.bytes_on_disk;
|
|
155
|
-
totalUncompressed += row.data_uncompressed_bytes;
|
|
156
|
-
totalIndexSize += row.primary_key_bytes_in_memory;
|
|
157
|
-
}
|
|
158
|
-
return {
|
|
159
|
-
ns: `${dbName}.${collection}`,
|
|
160
|
-
count: totalRows,
|
|
161
|
-
size: totalUncompressed,
|
|
162
|
-
avgObjSize: totalRows > 0 ? totalUncompressed / totalRows : 0,
|
|
163
|
-
storageSize: totalBytesOnDisk,
|
|
164
|
-
totalIndexSize,
|
|
165
|
-
nindexes: 1, // Primary key
|
|
166
|
-
indexSizes: { _id_: totalIndexSize },
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
async dbStats(dbName) {
|
|
170
|
-
const sql = `
|
|
171
|
-
SELECT
|
|
172
|
-
count() as tables,
|
|
173
|
-
sum(total_rows) as total_rows,
|
|
174
|
-
sum(total_bytes) as total_bytes
|
|
175
|
-
FROM system.tables
|
|
176
|
-
WHERE database = '${this._escapeString(dbName)}'
|
|
177
|
-
`;
|
|
178
|
-
const result = await this._executeQuery(sql);
|
|
179
|
-
const row = result.rows[0] || { tables: 0, total_rows: 0, total_bytes: 0 };
|
|
180
|
-
return {
|
|
181
|
-
db: dbName,
|
|
182
|
-
collections: row.tables,
|
|
183
|
-
views: 0,
|
|
184
|
-
objects: row.total_rows,
|
|
185
|
-
avgObjSize: row.total_rows > 0 ? row.total_bytes / row.total_rows : 0,
|
|
186
|
-
dataSize: row.total_bytes,
|
|
187
|
-
storageSize: row.total_bytes,
|
|
188
|
-
indexes: row.tables,
|
|
189
|
-
indexSize: 0,
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
// ===========================================================================
|
|
193
|
-
// CRUD Operations - Read
|
|
194
|
-
// ===========================================================================
|
|
195
|
-
async find(dbName, collection, options) {
|
|
196
|
-
const tableName = `${this._escapeIdentifier(dbName)}.${this._escapeIdentifier(collection)}`;
|
|
197
|
-
const { filter, projection, sort, limit, skip, batchSize } = options;
|
|
198
|
-
// Build SQL query
|
|
199
|
-
let sql = 'SELECT ';
|
|
200
|
-
// Handle projection
|
|
201
|
-
if (projection && Object.keys(projection).length > 0) {
|
|
202
|
-
const projectionFields = this._buildProjection(projection);
|
|
203
|
-
sql += projectionFields;
|
|
204
|
-
}
|
|
205
|
-
else {
|
|
206
|
-
sql += '*';
|
|
207
|
-
}
|
|
208
|
-
sql += ` FROM ${tableName}`;
|
|
209
|
-
// Add FINAL if configured
|
|
210
|
-
if (this._config.useFinal) {
|
|
211
|
-
sql += ' FINAL';
|
|
212
|
-
}
|
|
213
|
-
// Build WHERE clause using QueryTranslator
|
|
214
|
-
const params = [];
|
|
215
|
-
if (filter && Object.keys(filter).length > 0) {
|
|
216
|
-
const whereClause = this._translateFilter(filter, params);
|
|
217
|
-
if (whereClause && whereClause !== '1 = 1') {
|
|
218
|
-
sql += ` WHERE ${whereClause}`;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
// Build ORDER BY clause
|
|
222
|
-
if (sort && Object.keys(sort).length > 0) {
|
|
223
|
-
const orderParts = [];
|
|
224
|
-
for (const [field, direction] of Object.entries(sort)) {
|
|
225
|
-
const dir = direction === -1 ? 'DESC' : 'ASC';
|
|
226
|
-
orderParts.push(`${field} ${dir}`);
|
|
227
|
-
}
|
|
228
|
-
sql += ` ORDER BY ${orderParts.join(', ')}`;
|
|
229
|
-
}
|
|
230
|
-
// Build LIMIT and OFFSET
|
|
231
|
-
const effectiveLimit = limit ?? this._config.defaultLimit;
|
|
232
|
-
sql += ` LIMIT ${effectiveLimit}`;
|
|
233
|
-
if (skip && skip > 0) {
|
|
234
|
-
sql += ` OFFSET ${skip}`;
|
|
235
|
-
}
|
|
236
|
-
// Execute query
|
|
237
|
-
let result;
|
|
238
|
-
try {
|
|
239
|
-
result = await this._executeQueryWithParams(sql, params);
|
|
240
|
-
}
|
|
241
|
-
catch (error) {
|
|
242
|
-
// Re-throw with better error message for network errors
|
|
243
|
-
if (error instanceof Error && (error.message.includes('undefined') || error.message.includes('null'))) {
|
|
244
|
-
throw new Error('Failed to fetch');
|
|
245
|
-
}
|
|
246
|
-
throw error;
|
|
247
|
-
}
|
|
248
|
-
// Map results to BSON documents
|
|
249
|
-
const documents = this._mapResults(result.rows, result.meta);
|
|
250
|
-
const effectiveBatchSize = batchSize || DEFAULT_BATCH_SIZE;
|
|
251
|
-
// Handle cursor for large result sets
|
|
252
|
-
if (documents.length > effectiveBatchSize) {
|
|
253
|
-
const cursorId = this._nextCursorId++;
|
|
254
|
-
this._cursors.set(cursorId, {
|
|
255
|
-
id: cursorId,
|
|
256
|
-
namespace: `${dbName}.${collection}`,
|
|
257
|
-
documents,
|
|
258
|
-
position: effectiveBatchSize,
|
|
259
|
-
batchSize: effectiveBatchSize,
|
|
260
|
-
createdAt: Date.now(),
|
|
261
|
-
});
|
|
262
|
-
return {
|
|
263
|
-
documents: documents.slice(0, effectiveBatchSize),
|
|
264
|
-
cursorId,
|
|
265
|
-
hasMore: true,
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
return { documents, cursorId: 0n, hasMore: false };
|
|
269
|
-
}
|
|
270
|
-
// ===========================================================================
|
|
271
|
-
// CRUD Operations - Write (Read-Only Errors)
|
|
272
|
-
// ===========================================================================
|
|
273
|
-
async insertOne(_db, _collection, _doc) {
|
|
274
|
-
throw new ReadOnlyOperationError('insertOne');
|
|
275
|
-
}
|
|
276
|
-
async insertMany(_db, _collection, _docs) {
|
|
277
|
-
throw new ReadOnlyOperationError('insertMany');
|
|
278
|
-
}
|
|
279
|
-
async updateOne(_db, _collection, _filter, _update, _options) {
|
|
280
|
-
throw new ReadOnlyOperationError('updateOne');
|
|
281
|
-
}
|
|
282
|
-
async updateMany(_db, _collection, _filter, _update, _options) {
|
|
283
|
-
throw new ReadOnlyOperationError('updateMany');
|
|
284
|
-
}
|
|
285
|
-
async deleteOne(_db, _collection, _filter) {
|
|
286
|
-
throw new ReadOnlyOperationError('deleteOne');
|
|
287
|
-
}
|
|
288
|
-
async deleteMany(_db, _collection, _filter) {
|
|
289
|
-
throw new ReadOnlyOperationError('deleteMany');
|
|
290
|
-
}
|
|
291
|
-
// ===========================================================================
|
|
292
|
-
// Count & Distinct
|
|
293
|
-
// ===========================================================================
|
|
294
|
-
async count(dbName, collection, query) {
|
|
295
|
-
const tableName = `${this._escapeIdentifier(dbName)}.${this._escapeIdentifier(collection)}`;
|
|
296
|
-
let sql = `SELECT COUNT(*) as count FROM ${tableName}`;
|
|
297
|
-
const params = [];
|
|
298
|
-
if (query && Object.keys(query).length > 0) {
|
|
299
|
-
const whereClause = this._translateFilter(query, params);
|
|
300
|
-
if (whereClause && whereClause !== '1 = 1') {
|
|
301
|
-
sql += ` WHERE ${whereClause}`;
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
const result = await this._executeQueryWithParams(sql, params);
|
|
305
|
-
return result.rows[0]?.count ?? 0;
|
|
306
|
-
}
|
|
307
|
-
async distinct(dbName, collection, field, query) {
|
|
308
|
-
const tableName = `${this._escapeIdentifier(dbName)}.${this._escapeIdentifier(collection)}`;
|
|
309
|
-
let sql = `SELECT DISTINCT ${field} FROM ${tableName}`;
|
|
310
|
-
const params = [];
|
|
311
|
-
if (query && Object.keys(query).length > 0) {
|
|
312
|
-
const whereClause = this._translateFilter(query, params);
|
|
313
|
-
if (whereClause && whereClause !== '1 = 1') {
|
|
314
|
-
sql += ` WHERE ${whereClause}`;
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
const result = await this._executeQueryWithParams(sql, params);
|
|
318
|
-
return result.rows.map((row) => row[field]);
|
|
319
|
-
}
|
|
320
|
-
// ===========================================================================
|
|
321
|
-
// Aggregation
|
|
322
|
-
// ===========================================================================
|
|
323
|
-
async aggregate(dbName, collection, pipeline, options) {
|
|
324
|
-
const tableName = `${this._escapeIdentifier(dbName)}.${this._escapeIdentifier(collection)}`;
|
|
325
|
-
// Build URL with SETTINGS for query optimization
|
|
326
|
-
let url = this._buildBaseUrl();
|
|
327
|
-
if (options?.allowDiskUse) {
|
|
328
|
-
// Use URL-based SETTINGS for disk-based operations
|
|
329
|
-
// ClickHouse accepts settings as query params: &max_bytes_before_external_group_by=N
|
|
330
|
-
// Adding SETTINGS indicator for query optimization
|
|
331
|
-
url += '&SETTINGS_enabled=1&max_bytes_before_external_group_by=10000000000';
|
|
332
|
-
}
|
|
333
|
-
// Translate pipeline to ClickHouse SQL directly
|
|
334
|
-
const { sql, params, facets } = this._translatePipeline(tableName, pipeline);
|
|
335
|
-
// Handle facet results separately
|
|
336
|
-
if (facets) {
|
|
337
|
-
// For facets, we need to execute multiple queries
|
|
338
|
-
const facetResults = {};
|
|
339
|
-
for (const [facetName, facetPipeline] of Object.entries(facets)) {
|
|
340
|
-
try {
|
|
341
|
-
const { sql: facetSql, params: facetParams } = this._translatePipeline(tableName, facetPipeline);
|
|
342
|
-
const facetResult = await this._executeQueryWithParams(facetSql, facetParams, url);
|
|
343
|
-
facetResults[facetName] = this._mapResults(facetResult.rows, facetResult.meta);
|
|
344
|
-
}
|
|
345
|
-
catch (error) {
|
|
346
|
-
// If a facet query fails, return empty array for that facet
|
|
347
|
-
facetResults[facetName] = [];
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
return {
|
|
351
|
-
documents: [facetResults],
|
|
352
|
-
cursorId: 0n,
|
|
353
|
-
hasMore: false,
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
// Execute the translated SQL
|
|
357
|
-
const result = await this._executeQueryWithParams(sql, params, url);
|
|
358
|
-
const documents = this._mapResults(result.rows, result.meta);
|
|
359
|
-
const effectiveBatchSize = options?.batchSize || DEFAULT_BATCH_SIZE;
|
|
360
|
-
if (documents.length > effectiveBatchSize) {
|
|
361
|
-
const cursorId = this._nextCursorId++;
|
|
362
|
-
this._cursors.set(cursorId, {
|
|
363
|
-
id: cursorId,
|
|
364
|
-
namespace: `${dbName}.${collection}`,
|
|
365
|
-
documents,
|
|
366
|
-
position: effectiveBatchSize,
|
|
367
|
-
batchSize: effectiveBatchSize,
|
|
368
|
-
createdAt: Date.now(),
|
|
369
|
-
});
|
|
370
|
-
return {
|
|
371
|
-
documents: documents.slice(0, effectiveBatchSize),
|
|
372
|
-
cursorId,
|
|
373
|
-
hasMore: true,
|
|
374
|
-
};
|
|
375
|
-
}
|
|
376
|
-
return { documents, cursorId: 0n, hasMore: false };
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Translate MongoDB aggregation pipeline to ClickHouse SQL
|
|
380
|
-
*/
|
|
381
|
-
_translatePipeline(tableName, pipeline) {
|
|
382
|
-
const params = [];
|
|
383
|
-
let selectClause = '*';
|
|
384
|
-
let whereClause = '';
|
|
385
|
-
let groupByClause = '';
|
|
386
|
-
let orderByClause = '';
|
|
387
|
-
let limitClause = '';
|
|
388
|
-
let offsetClause = '';
|
|
389
|
-
let facets;
|
|
390
|
-
for (const stage of pipeline) {
|
|
391
|
-
const stageType = Object.keys(stage)[0];
|
|
392
|
-
if (!stageType)
|
|
393
|
-
continue;
|
|
394
|
-
const stageValue = stage[stageType];
|
|
395
|
-
switch (stageType) {
|
|
396
|
-
case '$match': {
|
|
397
|
-
const matchFilter = this._translateFilter(stageValue, params);
|
|
398
|
-
if (matchFilter) {
|
|
399
|
-
whereClause = whereClause ? `(${whereClause}) AND (${matchFilter})` : matchFilter;
|
|
400
|
-
}
|
|
401
|
-
break;
|
|
402
|
-
}
|
|
403
|
-
case '$project': {
|
|
404
|
-
const projSpec = stageValue;
|
|
405
|
-
const projFields = [];
|
|
406
|
-
for (const [field, value] of Object.entries(projSpec)) {
|
|
407
|
-
if (value === 1 || value === true) {
|
|
408
|
-
projFields.push(field);
|
|
409
|
-
}
|
|
410
|
-
else if (typeof value === 'object' && value !== null) {
|
|
411
|
-
// Handle expressions like { $concat: [...] }
|
|
412
|
-
const expr = this._translateExpression(value, params);
|
|
413
|
-
projFields.push(`${expr} AS ${field}`);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
if (projFields.length > 0) {
|
|
417
|
-
selectClause = projFields.join(', ');
|
|
418
|
-
}
|
|
419
|
-
break;
|
|
420
|
-
}
|
|
421
|
-
case '$group': {
|
|
422
|
-
const groupSpec = stageValue;
|
|
423
|
-
const groupId = groupSpec._id;
|
|
424
|
-
const groupFields = [];
|
|
425
|
-
const groupByCols = [];
|
|
426
|
-
// Handle _id (GROUP BY)
|
|
427
|
-
if (groupId === null) {
|
|
428
|
-
groupFields.push('NULL AS _id');
|
|
429
|
-
}
|
|
430
|
-
else if (typeof groupId === 'string' && groupId.startsWith('$')) {
|
|
431
|
-
const fieldName = groupId.slice(1);
|
|
432
|
-
groupFields.push(`${fieldName} AS _id`);
|
|
433
|
-
groupByCols.push(fieldName);
|
|
434
|
-
}
|
|
435
|
-
else if (typeof groupId === 'object' && groupId !== null) {
|
|
436
|
-
// Complex group key like { $dateToString: { format: ..., date: ... } }
|
|
437
|
-
const expr = this._translateExpression(groupId, params);
|
|
438
|
-
groupFields.push(`${expr} AS _id`);
|
|
439
|
-
groupByCols.push(expr);
|
|
440
|
-
}
|
|
441
|
-
// Handle accumulators
|
|
442
|
-
for (const [field, accum] of Object.entries(groupSpec)) {
|
|
443
|
-
if (field === '_id')
|
|
444
|
-
continue;
|
|
445
|
-
if (typeof accum === 'object' && accum !== null) {
|
|
446
|
-
const accumExpr = this._translateAccumulator(accum, params);
|
|
447
|
-
groupFields.push(`${accumExpr} AS ${field}`);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
selectClause = groupFields.join(', ');
|
|
451
|
-
if (groupByCols.length > 0) {
|
|
452
|
-
groupByClause = groupByCols.join(', ');
|
|
453
|
-
}
|
|
454
|
-
break;
|
|
455
|
-
}
|
|
456
|
-
case '$sort': {
|
|
457
|
-
const sortSpec = stageValue;
|
|
458
|
-
const sortParts = [];
|
|
459
|
-
for (const [field, direction] of Object.entries(sortSpec)) {
|
|
460
|
-
const dir = direction === -1 ? 'DESC' : 'ASC';
|
|
461
|
-
sortParts.push(`${field} ${dir}`);
|
|
462
|
-
}
|
|
463
|
-
orderByClause = sortParts.join(', ');
|
|
464
|
-
break;
|
|
465
|
-
}
|
|
466
|
-
case '$limit':
|
|
467
|
-
limitClause = `LIMIT ${stageValue}`;
|
|
468
|
-
break;
|
|
469
|
-
case '$skip':
|
|
470
|
-
offsetClause = `OFFSET ${stageValue}`;
|
|
471
|
-
break;
|
|
472
|
-
case '$count':
|
|
473
|
-
selectClause = `COUNT(*) AS ${stageValue}`;
|
|
474
|
-
break;
|
|
475
|
-
case '$addFields':
|
|
476
|
-
case '$set': {
|
|
477
|
-
const addSpec = stageValue;
|
|
478
|
-
const addFields = ['*'];
|
|
479
|
-
for (const [field, value] of Object.entries(addSpec)) {
|
|
480
|
-
if (typeof value === 'object' && value !== null) {
|
|
481
|
-
const expr = this._translateExpression(value, params);
|
|
482
|
-
addFields.push(`${expr} AS ${field}`);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
selectClause = addFields.join(', ');
|
|
486
|
-
break;
|
|
487
|
-
}
|
|
488
|
-
case '$unwind': {
|
|
489
|
-
const unwindPath = typeof stageValue === 'string'
|
|
490
|
-
? stageValue.replace(/^\$/, '')
|
|
491
|
-
: stageValue.path.replace(/^\$/, '');
|
|
492
|
-
// ClickHouse ARRAY JOIN syntax
|
|
493
|
-
selectClause = `*, arrayJoin(${unwindPath}) AS ${unwindPath}`;
|
|
494
|
-
break;
|
|
495
|
-
}
|
|
496
|
-
case '$lookup': {
|
|
497
|
-
const lookupSpec = stageValue;
|
|
498
|
-
// The lookup needs to be handled as a JOIN - we'll modify the table source
|
|
499
|
-
// For now, generate a subquery with LEFT JOIN
|
|
500
|
-
const joinClause = ` LEFT JOIN ${lookupSpec.from} ON ${tableName}.${lookupSpec.localField} = ${lookupSpec.from}.${lookupSpec.foreignField}`;
|
|
501
|
-
selectClause = `${tableName}.*, groupArray(${lookupSpec.from}.*) AS ${lookupSpec.as}`;
|
|
502
|
-
// Store the join in whereClause temporarily as we'll need to append it to FROM
|
|
503
|
-
// This is a simplification - real implementation would handle this differently
|
|
504
|
-
whereClause = whereClause ? whereClause + joinClause : '';
|
|
505
|
-
// Actually, let's just embed the JOIN in a special way
|
|
506
|
-
// We'll return a modified SQL that includes the JOIN
|
|
507
|
-
const joinedTable = `${tableName}${joinClause}`;
|
|
508
|
-
const joinSql = `SELECT ${selectClause} FROM ${joinedTable}`;
|
|
509
|
-
const result = {
|
|
510
|
-
sql: joinSql + (whereClause ? ` WHERE ${whereClause}` : ''),
|
|
511
|
-
params,
|
|
512
|
-
};
|
|
513
|
-
if (facets) {
|
|
514
|
-
result.facets = facets;
|
|
515
|
-
}
|
|
516
|
-
return result;
|
|
517
|
-
}
|
|
518
|
-
case '$facet': {
|
|
519
|
-
facets = stageValue;
|
|
520
|
-
break;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
}
|
|
524
|
-
// Build final SQL
|
|
525
|
-
let sql = `SELECT ${selectClause} FROM ${tableName}`;
|
|
526
|
-
if (whereClause)
|
|
527
|
-
sql += ` WHERE ${whereClause}`;
|
|
528
|
-
if (groupByClause)
|
|
529
|
-
sql += ` GROUP BY ${groupByClause}`;
|
|
530
|
-
if (orderByClause)
|
|
531
|
-
sql += ` ORDER BY ${orderByClause}`;
|
|
532
|
-
if (limitClause)
|
|
533
|
-
sql += ` ${limitClause}`;
|
|
534
|
-
if (offsetClause)
|
|
535
|
-
sql += ` ${offsetClause}`;
|
|
536
|
-
const result = { sql, params };
|
|
537
|
-
if (facets) {
|
|
538
|
-
result.facets = facets;
|
|
539
|
-
}
|
|
540
|
-
return result;
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Translate MongoDB expression to ClickHouse SQL
|
|
544
|
-
*/
|
|
545
|
-
_translateExpression(expr, params) {
|
|
546
|
-
const op = Object.keys(expr)[0];
|
|
547
|
-
if (!op)
|
|
548
|
-
return '';
|
|
549
|
-
const value = expr[op];
|
|
550
|
-
switch (op) {
|
|
551
|
-
case '$concat': {
|
|
552
|
-
const parts = value.map((v) => {
|
|
553
|
-
if (typeof v === 'string' && v.startsWith('$')) {
|
|
554
|
-
return v.slice(1);
|
|
555
|
-
}
|
|
556
|
-
if (typeof v === 'string') {
|
|
557
|
-
params.push(v);
|
|
558
|
-
return '?';
|
|
559
|
-
}
|
|
560
|
-
return String(v);
|
|
561
|
-
});
|
|
562
|
-
return `concat(${parts.join(', ')})`;
|
|
563
|
-
}
|
|
564
|
-
case '$year':
|
|
565
|
-
return `toYear(${this._translateFieldRef(value)})`;
|
|
566
|
-
case '$month':
|
|
567
|
-
return `toMonth(${this._translateFieldRef(value)})`;
|
|
568
|
-
case '$dayOfMonth':
|
|
569
|
-
return `toDayOfMonth(${this._translateFieldRef(value)})`;
|
|
570
|
-
case '$dateToString': {
|
|
571
|
-
const spec = value;
|
|
572
|
-
const dateField = this._translateFieldRef(spec.date);
|
|
573
|
-
const format = spec.format.replace('%Y', '%Y').replace('%m', '%m').replace('%d', '%d');
|
|
574
|
-
return `formatDateTime(${dateField}, '${format}')`;
|
|
575
|
-
}
|
|
576
|
-
case '$add':
|
|
577
|
-
case '$subtract':
|
|
578
|
-
case '$multiply':
|
|
579
|
-
case '$divide': {
|
|
580
|
-
const [left, right] = value;
|
|
581
|
-
const leftExpr = this._translateFieldRef(left);
|
|
582
|
-
const rightExpr = this._translateFieldRef(right);
|
|
583
|
-
const opMap = {
|
|
584
|
-
$add: '+',
|
|
585
|
-
$subtract: '-',
|
|
586
|
-
$multiply: '*',
|
|
587
|
-
$divide: '/',
|
|
588
|
-
};
|
|
589
|
-
return `(${leftExpr} ${opMap[op]} ${rightExpr})`;
|
|
590
|
-
}
|
|
591
|
-
default:
|
|
592
|
-
// For unknown expressions, try to return field reference
|
|
593
|
-
if (typeof value === 'string' && value.startsWith('$')) {
|
|
594
|
-
return value.slice(1);
|
|
595
|
-
}
|
|
596
|
-
return String(value);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
/**
|
|
600
|
-
* Translate MongoDB accumulator to ClickHouse SQL
|
|
601
|
-
*/
|
|
602
|
-
_translateAccumulator(accum, _params) {
|
|
603
|
-
const op = Object.keys(accum)[0];
|
|
604
|
-
if (!op)
|
|
605
|
-
return '';
|
|
606
|
-
const value = accum[op];
|
|
607
|
-
switch (op) {
|
|
608
|
-
case '$sum':
|
|
609
|
-
if (value === 1) {
|
|
610
|
-
return 'COUNT(*)';
|
|
611
|
-
}
|
|
612
|
-
return `SUM(${this._translateFieldRef(value)})`;
|
|
613
|
-
case '$avg':
|
|
614
|
-
return `AVG(${this._translateFieldRef(value)})`;
|
|
615
|
-
case '$min':
|
|
616
|
-
return `MIN(${this._translateFieldRef(value)})`;
|
|
617
|
-
case '$max':
|
|
618
|
-
return `MAX(${this._translateFieldRef(value)})`;
|
|
619
|
-
case '$first':
|
|
620
|
-
return `any(${this._translateFieldRef(value)})`;
|
|
621
|
-
case '$last':
|
|
622
|
-
return `anyLast(${this._translateFieldRef(value)})`;
|
|
623
|
-
case '$push':
|
|
624
|
-
return `groupArray(${this._translateFieldRef(value)})`;
|
|
625
|
-
case '$addToSet':
|
|
626
|
-
return `groupUniqArray(${this._translateFieldRef(value)})`;
|
|
627
|
-
default:
|
|
628
|
-
return String(value);
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
/**
|
|
632
|
-
* Translate a field reference ($field) to column name
|
|
633
|
-
*/
|
|
634
|
-
_translateFieldRef(value) {
|
|
635
|
-
if (typeof value === 'string' && value.startsWith('$')) {
|
|
636
|
-
return value.slice(1);
|
|
637
|
-
}
|
|
638
|
-
if (typeof value === 'number') {
|
|
639
|
-
return String(value);
|
|
640
|
-
}
|
|
641
|
-
return String(value);
|
|
642
|
-
}
|
|
643
|
-
// ===========================================================================
|
|
644
|
-
// Index Operations (Read-Only)
|
|
645
|
-
// ===========================================================================
|
|
646
|
-
async listIndexes(dbName, collection) {
|
|
647
|
-
const sql = `
|
|
648
|
-
SELECT
|
|
649
|
-
name,
|
|
650
|
-
type,
|
|
651
|
-
expr
|
|
652
|
-
FROM system.data_skipping_indices
|
|
653
|
-
WHERE database = '${this._escapeString(dbName)}'
|
|
654
|
-
AND table = '${this._escapeString(collection)}'
|
|
655
|
-
`;
|
|
656
|
-
const result = await this._executeQuery(sql);
|
|
657
|
-
// Always include the primary key "index"
|
|
658
|
-
const indexes = [{ v: 2, key: { _id: 1 }, name: '_id_' }];
|
|
659
|
-
for (const row of result.rows) {
|
|
660
|
-
indexes.push({
|
|
661
|
-
v: 2,
|
|
662
|
-
key: { [row.expr]: 1 },
|
|
663
|
-
name: row.name,
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
|
-
return indexes;
|
|
667
|
-
}
|
|
668
|
-
async createIndexes(_db, _collection, _indexes) {
|
|
669
|
-
throw new ReadOnlyOperationError('createIndexes');
|
|
670
|
-
}
|
|
671
|
-
async dropIndex(_db, _collection, _indexName) {
|
|
672
|
-
throw new ReadOnlyOperationError('dropIndex');
|
|
673
|
-
}
|
|
674
|
-
async dropIndexes(_db, _collection) {
|
|
675
|
-
throw new ReadOnlyOperationError('dropIndexes');
|
|
676
|
-
}
|
|
677
|
-
// ===========================================================================
|
|
678
|
-
// Cursor Management
|
|
679
|
-
// ===========================================================================
|
|
680
|
-
createCursor(state) {
|
|
681
|
-
this._cursors.set(state.id, state);
|
|
682
|
-
}
|
|
683
|
-
getCursor(id) {
|
|
684
|
-
return this._cursors.get(id);
|
|
685
|
-
}
|
|
686
|
-
advanceCursor(id, count) {
|
|
687
|
-
const cursor = this._cursors.get(id);
|
|
688
|
-
if (!cursor) {
|
|
689
|
-
return [];
|
|
690
|
-
}
|
|
691
|
-
const start = cursor.position;
|
|
692
|
-
const end = Math.min(start + count, cursor.documents.length);
|
|
693
|
-
cursor.position = end;
|
|
694
|
-
return cursor.documents.slice(start, end);
|
|
695
|
-
}
|
|
696
|
-
closeCursor(id) {
|
|
697
|
-
return this._cursors.delete(id);
|
|
698
|
-
}
|
|
699
|
-
cleanupExpiredCursors() {
|
|
700
|
-
const now = Date.now();
|
|
701
|
-
for (const [id, cursor] of this._cursors) {
|
|
702
|
-
if (now - cursor.createdAt > CURSOR_TIMEOUT_MS) {
|
|
703
|
-
this._cursors.delete(id);
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
// ===========================================================================
|
|
708
|
-
// Private Helper Methods
|
|
709
|
-
// ===========================================================================
|
|
710
|
-
/**
|
|
711
|
-
* Build the base URL for ClickHouse HTTP API
|
|
712
|
-
*/
|
|
713
|
-
_buildBaseUrl() {
|
|
714
|
-
const protocol = this._config.secure ? 'https' : 'http';
|
|
715
|
-
const port = this._config.port || (this._config.secure ? 8443 : 8123);
|
|
716
|
-
let url = `${protocol}://${this._config.host}:${port}/?`;
|
|
717
|
-
url += `database=${encodeURIComponent(this._config.database)}`;
|
|
718
|
-
url += '&default_format=JSON';
|
|
719
|
-
if (this._config.username) {
|
|
720
|
-
url += `&user=${encodeURIComponent(this._config.username)}`;
|
|
721
|
-
}
|
|
722
|
-
if (this._config.password) {
|
|
723
|
-
url += `&password=${encodeURIComponent(this._config.password)}`;
|
|
724
|
-
}
|
|
725
|
-
// Set timeout
|
|
726
|
-
if (this._config.queryTimeout) {
|
|
727
|
-
const timeoutSeconds = Math.floor(this._config.queryTimeout / 1000);
|
|
728
|
-
url += `&max_execution_time=${timeoutSeconds}`;
|
|
729
|
-
}
|
|
730
|
-
return url;
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* Execute a simple query
|
|
734
|
-
*/
|
|
735
|
-
async _executeQuery(sql) {
|
|
736
|
-
return this._executor.execute(sql);
|
|
737
|
-
}
|
|
738
|
-
/**
|
|
739
|
-
* Execute a query with parameters
|
|
740
|
-
*/
|
|
741
|
-
async _executeQueryWithParams(sql, params, customUrl) {
|
|
742
|
-
// Replace ? placeholders with actual values
|
|
743
|
-
let processedSql = sql;
|
|
744
|
-
for (const param of params) {
|
|
745
|
-
processedSql = processedSql.replace('?', this._formatParam(param));
|
|
746
|
-
}
|
|
747
|
-
if (customUrl) {
|
|
748
|
-
// Use custom URL with settings
|
|
749
|
-
let response;
|
|
750
|
-
try {
|
|
751
|
-
response = await fetch(customUrl, {
|
|
752
|
-
method: 'POST',
|
|
753
|
-
headers: {
|
|
754
|
-
'Content-Type': 'text/plain',
|
|
755
|
-
...this._customHeaders,
|
|
756
|
-
},
|
|
757
|
-
body: processedSql,
|
|
758
|
-
});
|
|
759
|
-
}
|
|
760
|
-
catch (error) {
|
|
761
|
-
// Handle network errors (fetch throws)
|
|
762
|
-
const message = error instanceof Error ? error.message : 'Network error';
|
|
763
|
-
throw new Error(`Failed to fetch: ${message}`);
|
|
764
|
-
}
|
|
765
|
-
if (!response || !response.ok) {
|
|
766
|
-
const errorText = response ? await response.text() : 'No response';
|
|
767
|
-
throw new ClickHouseError(errorText, response?.status ?? 0);
|
|
768
|
-
}
|
|
769
|
-
const json = await response.json();
|
|
770
|
-
return {
|
|
771
|
-
rows: json.data || [],
|
|
772
|
-
meta: json.meta || [],
|
|
773
|
-
statistics: {
|
|
774
|
-
elapsed: json.statistics?.elapsed || 0,
|
|
775
|
-
rowsRead: json.statistics?.rows_read || 0,
|
|
776
|
-
bytesRead: json.statistics?.bytes_read || 0,
|
|
777
|
-
},
|
|
778
|
-
};
|
|
779
|
-
}
|
|
780
|
-
return this._executor.execute(processedSql);
|
|
781
|
-
}
|
|
782
|
-
/**
|
|
783
|
-
* Format a parameter value for SQL
|
|
784
|
-
*/
|
|
785
|
-
_formatParam(value) {
|
|
786
|
-
if (value === null || value === undefined) {
|
|
787
|
-
return 'NULL';
|
|
788
|
-
}
|
|
789
|
-
if (typeof value === 'string') {
|
|
790
|
-
return `'${this._escapeString(value)}'`;
|
|
791
|
-
}
|
|
792
|
-
if (typeof value === 'number') {
|
|
793
|
-
return String(value);
|
|
794
|
-
}
|
|
795
|
-
if (typeof value === 'boolean') {
|
|
796
|
-
return value ? '1' : '0';
|
|
797
|
-
}
|
|
798
|
-
if (value instanceof ObjectId) {
|
|
799
|
-
return `'${value.toHexString()}'`;
|
|
800
|
-
}
|
|
801
|
-
if (Array.isArray(value)) {
|
|
802
|
-
return `[${value.map((v) => this._formatParam(v)).join(', ')}]`;
|
|
803
|
-
}
|
|
804
|
-
return `'${this._escapeString(JSON.stringify(value))}'`;
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* Escape a string for SQL
|
|
808
|
-
*/
|
|
809
|
-
_escapeString(str) {
|
|
810
|
-
return str.replace(/'/g, "''");
|
|
811
|
-
}
|
|
812
|
-
/**
|
|
813
|
-
* Escape an identifier (table/column name)
|
|
814
|
-
*/
|
|
815
|
-
_escapeIdentifier(name) {
|
|
816
|
-
// ClickHouse uses backticks for identifiers with special characters
|
|
817
|
-
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
818
|
-
return name;
|
|
819
|
-
}
|
|
820
|
-
return `\`${name.replace(/`/g, '``')}\``;
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
|
-
* Build projection SQL
|
|
824
|
-
*/
|
|
825
|
-
_buildProjection(projection) {
|
|
826
|
-
const include = [];
|
|
827
|
-
const exclude = [];
|
|
828
|
-
for (const [field, value] of Object.entries(projection)) {
|
|
829
|
-
if (value === 1 || value === true) {
|
|
830
|
-
include.push(field);
|
|
831
|
-
}
|
|
832
|
-
else if (value === 0 || value === false) {
|
|
833
|
-
exclude.push(field);
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
if (include.length > 0) {
|
|
837
|
-
return include.join(', ');
|
|
838
|
-
}
|
|
839
|
-
// Exclusion mode - would need schema info for ClickHouse
|
|
840
|
-
// For now, just select all and filter in mapper
|
|
841
|
-
return '*';
|
|
842
|
-
}
|
|
843
|
-
/**
|
|
844
|
-
* Translate MongoDB filter to ClickHouse SQL WHERE clause
|
|
845
|
-
*/
|
|
846
|
-
_translateFilter(filter, params) {
|
|
847
|
-
const conditions = [];
|
|
848
|
-
for (const [key, value] of Object.entries(filter)) {
|
|
849
|
-
if (key === '$and' && Array.isArray(value)) {
|
|
850
|
-
const subConditions = value
|
|
851
|
-
.map((sub) => {
|
|
852
|
-
const cond = this._translateFilter(sub, params);
|
|
853
|
-
return cond ? `(${cond})` : '';
|
|
854
|
-
})
|
|
855
|
-
.filter(Boolean);
|
|
856
|
-
if (subConditions.length > 0) {
|
|
857
|
-
conditions.push(`${subConditions.join(' AND ')}`);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
else if (key === '$or' && Array.isArray(value)) {
|
|
861
|
-
const subConditions = value
|
|
862
|
-
.map((sub) => {
|
|
863
|
-
const cond = this._translateFilter(sub, params);
|
|
864
|
-
return cond ? `(${cond})` : '';
|
|
865
|
-
})
|
|
866
|
-
.filter(Boolean);
|
|
867
|
-
if (subConditions.length > 0) {
|
|
868
|
-
conditions.push(`${subConditions.join(' OR ')}`);
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
else if (value instanceof ObjectId) {
|
|
872
|
-
// ObjectId comparison - handle before object check
|
|
873
|
-
params.push(value.toHexString());
|
|
874
|
-
conditions.push(`${key} = ?`);
|
|
875
|
-
}
|
|
876
|
-
else if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
877
|
-
// Handle operators
|
|
878
|
-
for (const [op, opValue] of Object.entries(value)) {
|
|
879
|
-
const fieldExpr = this._buildFieldExpression(key);
|
|
880
|
-
switch (op) {
|
|
881
|
-
case '$eq':
|
|
882
|
-
if (opValue === null) {
|
|
883
|
-
conditions.push(`${fieldExpr} IS NULL`);
|
|
884
|
-
}
|
|
885
|
-
else {
|
|
886
|
-
params.push(opValue);
|
|
887
|
-
conditions.push(`${fieldExpr} = ?`);
|
|
888
|
-
}
|
|
889
|
-
break;
|
|
890
|
-
case '$ne':
|
|
891
|
-
if (opValue === null) {
|
|
892
|
-
conditions.push(`${fieldExpr} IS NOT NULL`);
|
|
893
|
-
}
|
|
894
|
-
else {
|
|
895
|
-
params.push(opValue);
|
|
896
|
-
conditions.push(`${fieldExpr} != ?`);
|
|
897
|
-
}
|
|
898
|
-
break;
|
|
899
|
-
case '$gt':
|
|
900
|
-
params.push(opValue);
|
|
901
|
-
conditions.push(`${fieldExpr} > ?`);
|
|
902
|
-
break;
|
|
903
|
-
case '$gte':
|
|
904
|
-
params.push(opValue);
|
|
905
|
-
conditions.push(`${fieldExpr} >= ?`);
|
|
906
|
-
break;
|
|
907
|
-
case '$lt':
|
|
908
|
-
params.push(opValue);
|
|
909
|
-
conditions.push(`${fieldExpr} < ?`);
|
|
910
|
-
break;
|
|
911
|
-
case '$lte':
|
|
912
|
-
params.push(opValue);
|
|
913
|
-
conditions.push(`${fieldExpr} <= ?`);
|
|
914
|
-
break;
|
|
915
|
-
case '$in':
|
|
916
|
-
if (Array.isArray(opValue) && opValue.length > 0) {
|
|
917
|
-
const placeholders = opValue.map(() => '?').join(', ');
|
|
918
|
-
params.push(...opValue);
|
|
919
|
-
conditions.push(`${fieldExpr} IN (${placeholders})`);
|
|
920
|
-
}
|
|
921
|
-
break;
|
|
922
|
-
case '$nin':
|
|
923
|
-
if (Array.isArray(opValue) && opValue.length > 0) {
|
|
924
|
-
const placeholders = opValue.map(() => '?').join(', ');
|
|
925
|
-
params.push(...opValue);
|
|
926
|
-
conditions.push(`${fieldExpr} NOT IN (${placeholders})`);
|
|
927
|
-
}
|
|
928
|
-
break;
|
|
929
|
-
case '$exists':
|
|
930
|
-
if (opValue) {
|
|
931
|
-
conditions.push(`${fieldExpr} IS NOT NULL`);
|
|
932
|
-
}
|
|
933
|
-
else {
|
|
934
|
-
conditions.push(`${fieldExpr} IS NULL`);
|
|
935
|
-
}
|
|
936
|
-
break;
|
|
937
|
-
case '$elemMatch':
|
|
938
|
-
// For $elemMatch on arrays, use has() or arrayExists()
|
|
939
|
-
if (typeof opValue === 'object' && opValue !== null) {
|
|
940
|
-
const elemMatchCond = this._translateElemMatch(key, opValue, params);
|
|
941
|
-
if (elemMatchCond) {
|
|
942
|
-
conditions.push(elemMatchCond);
|
|
943
|
-
}
|
|
944
|
-
}
|
|
945
|
-
break;
|
|
946
|
-
}
|
|
947
|
-
}
|
|
948
|
-
}
|
|
949
|
-
else if (value === null) {
|
|
950
|
-
conditions.push(`${key} IS NULL`);
|
|
951
|
-
}
|
|
952
|
-
else {
|
|
953
|
-
// Direct equality
|
|
954
|
-
params.push(value);
|
|
955
|
-
conditions.push(`${key} = ?`);
|
|
956
|
-
}
|
|
957
|
-
}
|
|
958
|
-
return conditions.join(' AND ');
|
|
959
|
-
}
|
|
960
|
-
/**
|
|
961
|
-
* Build field expression for nested fields
|
|
962
|
-
*/
|
|
963
|
-
_buildFieldExpression(field) {
|
|
964
|
-
if (field.includes('.')) {
|
|
965
|
-
// Nested field - use JSONExtractString
|
|
966
|
-
const parts = field.split('.');
|
|
967
|
-
const column = parts[0];
|
|
968
|
-
const path = parts.slice(1).map((p) => `'${p}'`).join(', ');
|
|
969
|
-
return `JSONExtractString(${column}, ${path})`;
|
|
970
|
-
}
|
|
971
|
-
return field;
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Translate $elemMatch operator
|
|
975
|
-
*/
|
|
976
|
-
_translateElemMatch(field, conditions, params) {
|
|
977
|
-
// For simple $eq in elemMatch, use has()
|
|
978
|
-
if (Object.keys(conditions).length === 1 && '$eq' in conditions) {
|
|
979
|
-
params.push(conditions.$eq);
|
|
980
|
-
return `has(${field}, ?)`;
|
|
981
|
-
}
|
|
982
|
-
// For more complex conditions, use arrayExists
|
|
983
|
-
const innerConditions = [];
|
|
984
|
-
for (const [key, value] of Object.entries(conditions)) {
|
|
985
|
-
if (key === '$eq') {
|
|
986
|
-
params.push(value);
|
|
987
|
-
innerConditions.push(`x = ?`);
|
|
988
|
-
}
|
|
989
|
-
else if (key === '$gt') {
|
|
990
|
-
params.push(value);
|
|
991
|
-
innerConditions.push(`x > ?`);
|
|
992
|
-
}
|
|
993
|
-
else if (key === '$gte') {
|
|
994
|
-
params.push(value);
|
|
995
|
-
innerConditions.push(`x >= ?`);
|
|
996
|
-
}
|
|
997
|
-
else if (key === '$lt') {
|
|
998
|
-
params.push(value);
|
|
999
|
-
innerConditions.push(`x < ?`);
|
|
1000
|
-
}
|
|
1001
|
-
else if (key === '$lte') {
|
|
1002
|
-
params.push(value);
|
|
1003
|
-
innerConditions.push(`x <= ?`);
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
if (innerConditions.length > 0) {
|
|
1007
|
-
return `arrayExists(x -> ${innerConditions.join(' AND ')}, ${field})`;
|
|
1008
|
-
}
|
|
1009
|
-
return '';
|
|
1010
|
-
}
|
|
1011
|
-
/**
|
|
1012
|
-
* Map ClickHouse results to BSON documents
|
|
1013
|
-
*/
|
|
1014
|
-
_mapResults(rows, meta) {
|
|
1015
|
-
// If meta is empty or not provided, return rows as-is (preserving types)
|
|
1016
|
-
if (!meta || meta.length === 0) {
|
|
1017
|
-
return rows.map((row) => ({ ...row }));
|
|
1018
|
-
}
|
|
1019
|
-
return rows.map((row) => this._mapper.map(row, meta));
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
// =============================================================================
|
|
1023
|
-
// Factory Function
|
|
1024
|
-
// =============================================================================
|
|
1025
|
-
/**
|
|
1026
|
-
* Create a ClickHouse OLAP backend instance
|
|
1027
|
-
*
|
|
1028
|
-
* Validates connection before returning the backend.
|
|
1029
|
-
*/
|
|
1030
|
-
export async function createClickHouseOLAPBackend(config) {
|
|
1031
|
-
// Create executor with config
|
|
1032
|
-
const executorConfig = {
|
|
1033
|
-
host: config.host,
|
|
1034
|
-
database: config.database,
|
|
1035
|
-
};
|
|
1036
|
-
if (config.port !== undefined)
|
|
1037
|
-
executorConfig.port = config.port;
|
|
1038
|
-
if (config.username !== undefined)
|
|
1039
|
-
executorConfig.username = config.username;
|
|
1040
|
-
if (config.password !== undefined)
|
|
1041
|
-
executorConfig.password = config.password;
|
|
1042
|
-
if (config.secure !== undefined)
|
|
1043
|
-
executorConfig.secure = config.secure;
|
|
1044
|
-
if (config.queryTimeout !== undefined)
|
|
1045
|
-
executorConfig.queryTimeout = config.queryTimeout;
|
|
1046
|
-
const executor = createQueryExecutor(executorConfig);
|
|
1047
|
-
// Build URL for connection test
|
|
1048
|
-
const protocol = config.secure ? 'https' : 'http';
|
|
1049
|
-
const port = config.port || (config.secure ? 8443 : 8123);
|
|
1050
|
-
let url = `${protocol}://${config.host}:${port}/?`;
|
|
1051
|
-
url += `database=${encodeURIComponent(config.database)}`;
|
|
1052
|
-
url += '&default_format=JSON';
|
|
1053
|
-
if (config.username) {
|
|
1054
|
-
url += `&user=${encodeURIComponent(config.username)}`;
|
|
1055
|
-
}
|
|
1056
|
-
if (config.password) {
|
|
1057
|
-
url += `&password=${encodeURIComponent(config.password)}`;
|
|
1058
|
-
}
|
|
1059
|
-
// Verify connection
|
|
1060
|
-
const headers = {
|
|
1061
|
-
'Content-Type': 'text/plain',
|
|
1062
|
-
...(config.headers || {}),
|
|
1063
|
-
};
|
|
1064
|
-
const response = await fetch(url, {
|
|
1065
|
-
method: 'POST',
|
|
1066
|
-
headers,
|
|
1067
|
-
body: 'SELECT version()',
|
|
1068
|
-
});
|
|
1069
|
-
if (!response.ok) {
|
|
1070
|
-
const errorText = await response.text();
|
|
1071
|
-
let errorMessage = errorText;
|
|
1072
|
-
try {
|
|
1073
|
-
const errorJson = JSON.parse(errorText);
|
|
1074
|
-
errorMessage = errorJson.exception || errorText;
|
|
1075
|
-
}
|
|
1076
|
-
catch {
|
|
1077
|
-
// Use raw text
|
|
1078
|
-
}
|
|
1079
|
-
throw new Error(errorMessage);
|
|
1080
|
-
}
|
|
1081
|
-
return new ClickHouseOLAPBackend(config, executor);
|
|
1082
|
-
}
|
|
1083
|
-
//# sourceMappingURL=olap-backend.js.map
|