db-mcp 2.0.0 → 3.0.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/README.md +96 -91
- package/dist/.tsbuildinfo +1 -0
- package/dist/adapters/database-adapter.d.ts +173 -0
- package/dist/adapters/database-adapter.d.ts.map +1 -0
- package/dist/adapters/query-validation.d.ts +20 -0
- package/dist/adapters/query-validation.d.ts.map +1 -0
- package/dist/adapters/registration/index.d.ts +4 -0
- package/dist/adapters/registration/index.d.ts.map +1 -0
- package/dist/adapters/registration/prompts.d.ts +7 -0
- package/dist/adapters/registration/prompts.d.ts.map +1 -0
- package/dist/adapters/registration/resources.d.ts +7 -0
- package/dist/adapters/registration/resources.d.ts.map +1 -0
- package/dist/adapters/registration/tools.d.ts +9 -0
- package/dist/adapters/registration/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite/index.d.ts +9 -0
- package/dist/adapters/sqlite/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/json-utils.d.ts +100 -0
- package/dist/adapters/sqlite/json-utils.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/analysis.d.ts +23 -0
- package/dist/adapters/sqlite/prompts/analysis.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/index.d.ts +16 -0
- package/dist/adapters/sqlite/prompts/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/query.d.ts +19 -0
- package/dist/adapters/sqlite/prompts/query.d.ts.map +1 -0
- package/dist/adapters/sqlite/prompts/schema.d.ts +20 -0
- package/dist/adapters/sqlite/prompts/schema.d.ts.map +1 -0
- package/dist/adapters/sqlite/query-executor.d.ts +38 -0
- package/dist/adapters/sqlite/query-executor.d.ts.map +1 -0
- package/dist/adapters/sqlite/resources.d.ts +13 -0
- package/dist/adapters/sqlite/resources.d.ts.map +1 -0
- package/dist/adapters/sqlite/schema-manager.d.ts +69 -0
- package/dist/adapters/sqlite/schema-manager.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/admin.d.ts +459 -0
- package/dist/adapters/sqlite/schemas/admin.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/codemode.d.ts +30 -0
- package/dist/adapters/sqlite/schemas/codemode.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/common.d.ts +9 -0
- package/dist/adapters/sqlite/schemas/common.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/core.d.ts +530 -0
- package/dist/adapters/sqlite/schemas/core.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/error-mixin.d.ts +10 -0
- package/dist/adapters/sqlite/schemas/error-mixin.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/fts.d.ts +106 -0
- package/dist/adapters/sqlite/schemas/fts.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/geo.d.ts +135 -0
- package/dist/adapters/sqlite/schemas/geo.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/index.d.ts +23 -0
- package/dist/adapters/sqlite/schemas/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/introspection.d.ts +583 -0
- package/dist/adapters/sqlite/schemas/introspection.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/json.d.ts +849 -0
- package/dist/adapters/sqlite/schemas/json.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/migration.d.ts +220 -0
- package/dist/adapters/sqlite/schemas/migration.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/native.d.ts +235 -0
- package/dist/adapters/sqlite/schemas/native.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/server.d.ts +13 -0
- package/dist/adapters/sqlite/schemas/server.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/spatialite.d.ts +114 -0
- package/dist/adapters/sqlite/schemas/spatialite.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/stats.d.ts +780 -0
- package/dist/adapters/sqlite/schemas/stats.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/text.d.ts +570 -0
- package/dist/adapters/sqlite/schemas/text.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/vector.d.ts +252 -0
- package/dist/adapters/sqlite/schemas/vector.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/virtual.d.ts +257 -0
- package/dist/adapters/sqlite/schemas/virtual.d.ts.map +1 -0
- package/dist/adapters/sqlite/schemas/where.d.ts +20 -0
- package/dist/adapters/sqlite/schemas/where.d.ts.map +1 -0
- package/dist/adapters/sqlite/sqlite-adapter/lifecycle.d.ts +13 -0
- package/dist/adapters/sqlite/sqlite-adapter/lifecycle.d.ts.map +1 -0
- package/dist/adapters/sqlite/sqlite-adapter/schema.d.ts +7 -0
- package/dist/adapters/sqlite/sqlite-adapter/schema.d.ts.map +1 -0
- package/dist/adapters/sqlite/sqlite-adapter.d.ts +138 -0
- package/dist/adapters/sqlite/sqlite-adapter.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/analyze.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/analyze.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/create.d.ts +11 -0
- package/dist/adapters/sqlite/tools/admin/backup/create.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/dump.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/dump.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/index.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/integrity.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/integrity.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/optimize.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/optimize.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/backup/restore.d.ts +7 -0
- package/dist/adapters/sqlite/tools/admin/backup/restore.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/helpers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/admin/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/admin/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/pragma.d.ts +37 -0
- package/dist/adapters/sqlite/tools/admin/pragma.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/reindex.d.ts +10 -0
- package/dist/adapters/sqlite/tools/admin/reindex.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/verify.d.ts +13 -0
- package/dist/adapters/sqlite/tools/admin/verify.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/admin/wal.d.ts +10 -0
- package/dist/adapters/sqlite/tools/admin/wal.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/codemode.d.ts +22 -0
- package/dist/adapters/sqlite/tools/codemode.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/column-validation.d.ts +26 -0
- package/dist/adapters/sqlite/tools/column-validation.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/alter-table.d.ts +11 -0
- package/dist/adapters/sqlite/tools/core/alter-table.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/constraints.d.ts +10 -0
- package/dist/adapters/sqlite/tools/core/constraints.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/convenience-helpers.d.ts +20 -0
- package/dist/adapters/sqlite/tools/core/convenience-helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/convenience-schemas.d.ts +20 -0
- package/dist/adapters/sqlite/tools/core/convenience-schemas.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/convenience.d.ts +29 -0
- package/dist/adapters/sqlite/tools/core/convenience.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/datetime.d.ts +11 -0
- package/dist/adapters/sqlite/tools/core/datetime.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/index.d.ts +14 -0
- package/dist/adapters/sqlite/tools/core/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/indexes.d.ts +20 -0
- package/dist/adapters/sqlite/tools/core/indexes.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/queries.d.ts +16 -0
- package/dist/adapters/sqlite/tools/core/queries.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/tables.d.ts +37 -0
- package/dist/adapters/sqlite/tools/core/tables.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/core/triggers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/core/triggers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/fts.d.ts +13 -0
- package/dist/adapters/sqlite/tools/fts.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/geo.d.ts +14 -0
- package/dist/adapters/sqlite/tools/geo.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/index.d.ts +33 -0
- package/dist/adapters/sqlite/tools/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/constraints.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/constraints.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/diff.d.ts +11 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/diff.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/risks.d.ts +9 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/risks.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/snapshot.d.ts +40 -0
- package/dist/adapters/sqlite/tools/introspection/analysis/snapshot.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/index.d.ts +9 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/indexes.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/indexes.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/query-plan.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/query-plan.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/storage.d.ts +10 -0
- package/dist/adapters/sqlite/tools/introspection/diagnostics/storage.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/graph/helpers.d.ts +44 -0
- package/dist/adapters/sqlite/tools/introspection/graph/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/graph/index.d.ts +9 -0
- package/dist/adapters/sqlite/tools/introspection/graph/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/graph/tools.d.ts +12 -0
- package/dist/adapters/sqlite/tools/introspection/graph/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/introspection/index.d.ts +17 -0
- package/dist/adapters/sqlite/tools/introspection/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/helpers.d.ts +21 -0
- package/dist/adapters/sqlite/tools/json-helpers/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/index.d.ts +17 -0
- package/dist/adapters/sqlite/tools/json-helpers/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/read.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-helpers/read.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-helpers/write.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-helpers/write.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/crud.d.ts +39 -0
- package/dist/adapters/sqlite/tools/json-operations/crud.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/diff.d.ts +11 -0
- package/dist/adapters/sqlite/tools/json-operations/diff.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/helpers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/json-operations/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/json-operations/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/query.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-operations/query.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/security.d.ts +19 -0
- package/dist/adapters/sqlite/tools/json-operations/security.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/json-operations/transform.d.ts +24 -0
- package/dist/adapters/sqlite/tools/json-operations/transform.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/helpers.d.ts +34 -0
- package/dist/adapters/sqlite/tools/migration/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/index.d.ts +15 -0
- package/dist/adapters/sqlite/tools/migration/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/apply.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/apply.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/history.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/history.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/index.d.ts +7 -0
- package/dist/adapters/sqlite/tools/migration/tracking/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/init.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/init.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/record.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/record.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/rollback.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/rollback.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/migration/tracking/status.d.ts +4 -0
- package/dist/adapters/sqlite/tools/migration/tracking/status.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/advanced.d.ts +28 -0
- package/dist/adapters/sqlite/tools/stats/advanced.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/anomaly-detection.d.ts +22 -0
- package/dist/adapters/sqlite/tools/stats/anomaly-detection.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/basic.d.ts +32 -0
- package/dist/adapters/sqlite/tools/stats/basic.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/helpers.d.ts +27 -0
- package/dist/adapters/sqlite/tools/stats/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/index.d.ts +12 -0
- package/dist/adapters/sqlite/tools/stats/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/hypothesis.d.ts +7 -0
- package/dist/adapters/sqlite/tools/stats/inference/hypothesis.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/index.d.ts +4 -0
- package/dist/adapters/sqlite/tools/stats/inference/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/outlier.d.ts +7 -0
- package/dist/adapters/sqlite/tools/stats/inference/outlier.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/inference/regression.d.ts +7 -0
- package/dist/adapters/sqlite/tools/stats/inference/regression.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/math-helpers.d.ts +17 -0
- package/dist/adapters/sqlite/tools/stats/math-helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/stats/schema-risks.d.ts +15 -0
- package/dist/adapters/sqlite/tools/stats/schema-risks.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/formatting.d.ts +48 -0
- package/dist/adapters/sqlite/tools/text/formatting.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/helpers.d.ts +22 -0
- package/dist/adapters/sqlite/tools/text/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/text/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/regex.d.ts +21 -0
- package/dist/adapters/sqlite/tools/text/regex.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/search.d.ts +17 -0
- package/dist/adapters/sqlite/tools/text/search.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/sentiment.d.ts +13 -0
- package/dist/adapters/sqlite/tools/text/sentiment.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/text/validate.d.ts +11 -0
- package/dist/adapters/sqlite/tools/text/validate.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/helpers.d.ts +11 -0
- package/dist/adapters/sqlite/tools/vector/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/index.d.ts +14 -0
- package/dist/adapters/sqlite/tools/vector/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/metadata.d.ts +28 -0
- package/dist/adapters/sqlite/tools/vector/metadata.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/search.d.ts +16 -0
- package/dist/adapters/sqlite/tools/vector/search.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/storage.d.ts +24 -0
- package/dist/adapters/sqlite/tools/vector/storage.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/vector/tools.d.ts +9 -0
- package/dist/adapters/sqlite/tools/vector/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/analysis.d.ts +24 -0
- package/dist/adapters/sqlite/tools/virtual/analysis.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/extensions.d.ts +13 -0
- package/dist/adapters/sqlite/tools/virtual/extensions.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/helpers.d.ts +18 -0
- package/dist/adapters/sqlite/tools/virtual/helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/index.d.ts +10 -0
- package/dist/adapters/sqlite/tools/virtual/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/views.d.ts +21 -0
- package/dist/adapters/sqlite/tools/virtual/views.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/analyze-csv.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/analyze-csv.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/csv.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/csv.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/drop.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/drop.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/index.d.ts +6 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/index.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/info.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/info.d.ts.map +1 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/list.d.ts +4 -0
- package/dist/adapters/sqlite/tools/virtual/vtable/list.d.ts.map +1 -0
- package/dist/adapters/sqlite/types.d.ts +89 -0
- package/dist/adapters/sqlite/types.d.ts.map +1 -0
- package/dist/adapters/sqlite-helpers.d.ts +51 -0
- package/dist/adapters/sqlite-helpers.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/extensions.d.ts +17 -0
- package/dist/adapters/sqlite-native/extensions.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/index.d.ts +11 -0
- package/dist/adapters/sqlite-native/index.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/native-query-executor.d.ts +24 -0
- package/dist/adapters/sqlite-native/native-query-executor.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/native-sqlite-adapter.d.ts +160 -0
- package/dist/adapters/sqlite-native/native-sqlite-adapter.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/registration/index.d.ts +12 -0
- package/dist/adapters/sqlite-native/registration/index.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/analysis.d.ts +23 -0
- package/dist/adapters/sqlite-native/tools/spatialite/analysis.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/index.d.ts +15 -0
- package/dist/adapters/sqlite-native/tools/spatialite/index.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/loader.d.ts +22 -0
- package/dist/adapters/sqlite-native/tools/spatialite/loader.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/schemas.d.ts +78 -0
- package/dist/adapters/sqlite-native/tools/spatialite/schemas.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/spatialite/tools.d.ts +30 -0
- package/dist/adapters/sqlite-native/tools/spatialite/tools.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/transactions.d.ts +12 -0
- package/dist/adapters/sqlite-native/tools/transactions.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/tools/window.d.ts +7 -0
- package/dist/adapters/sqlite-native/tools/window.d.ts.map +1 -0
- package/dist/adapters/sqlite-native/transaction-methods.d.ts +36 -0
- package/dist/adapters/sqlite-native/transaction-methods.d.ts.map +1 -0
- package/dist/audit/backup-manager.d.ts +90 -0
- package/dist/audit/backup-manager.d.ts.map +1 -0
- package/dist/audit/index.d.ts +11 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/interceptor.d.ts +54 -0
- package/dist/audit/interceptor.d.ts.map +1 -0
- package/dist/audit/logger.d.ts +62 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/types.d.ts +112 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/auth/auth-context.d.ts +28 -0
- package/dist/auth/auth-context.d.ts.map +1 -0
- package/dist/auth/authorization-server-discovery.d.ts +90 -0
- package/dist/auth/authorization-server-discovery.d.ts.map +1 -0
- package/dist/auth/errors.d.ts +74 -0
- package/dist/auth/errors.d.ts.map +1 -0
- package/dist/auth/middleware/core.d.ts +22 -0
- package/dist/auth/middleware/core.d.ts.map +1 -0
- package/dist/auth/middleware/express-auth.d.ts +13 -0
- package/dist/auth/middleware/express-auth.d.ts.map +1 -0
- package/dist/auth/middleware/express-scopes.d.ts +6 -0
- package/dist/auth/middleware/express-scopes.d.ts.map +1 -0
- package/dist/auth/middleware/extraction.d.ts +2 -0
- package/dist/auth/middleware/extraction.d.ts.map +1 -0
- package/dist/auth/middleware/index.d.ts +5 -0
- package/dist/auth/middleware/index.d.ts.map +1 -0
- package/dist/auth/oauth-resource-server.d.ts +74 -0
- package/dist/auth/oauth-resource-server.d.ts.map +1 -0
- package/dist/auth/scope-map.d.ts +24 -0
- package/dist/auth/scope-map.d.ts.map +1 -0
- package/dist/auth/scopes/constants.d.ts +40 -0
- package/dist/auth/scopes/constants.d.ts.map +1 -0
- package/dist/auth/scopes/display.d.ts +5 -0
- package/dist/auth/scopes/display.d.ts.map +1 -0
- package/dist/auth/scopes/enforcement.d.ts +27 -0
- package/dist/auth/scopes/enforcement.d.ts.map +1 -0
- package/dist/auth/scopes/index.d.ts +6 -0
- package/dist/auth/scopes/index.d.ts.map +1 -0
- package/dist/auth/scopes/mapping.d.ts +39 -0
- package/dist/auth/scopes/mapping.d.ts.map +1 -0
- package/dist/auth/scopes/validation.d.ts +27 -0
- package/dist/auth/scopes/validation.d.ts.map +1 -0
- package/dist/auth/token-validator.d.ts +63 -0
- package/dist/auth/token-validator.d.ts.map +1 -0
- package/dist/auth/transport-agnostic.d.ts +11 -0
- package/dist/auth/transport-agnostic.d.ts.map +1 -0
- package/dist/auth/types.d.ts +257 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/{chunk-WBER5YY4.js → chunk-37G4DLL6.js} +1010 -409
- package/dist/chunk-E5IESRTK.js +489 -0
- package/dist/{chunk-645ZEFLA.js → chunk-L552U3QS.js} +887 -309
- package/dist/{chunk-5Y42NPBP.js → chunk-NV34JSQM.js} +4656 -1829
- package/dist/{chunk-Z7C2TM4L.js → chunk-W5WQVNVX.js} +169 -57
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +47 -26
- package/dist/codemode/api-constants.d.ts +40 -0
- package/dist/codemode/api-constants.d.ts.map +1 -0
- package/dist/codemode/api.d.ts +70 -0
- package/dist/codemode/api.d.ts.map +1 -0
- package/dist/codemode/auto-return.d.ts +25 -0
- package/dist/codemode/auto-return.d.ts.map +1 -0
- package/dist/codemode/index.d.ts +12 -0
- package/dist/codemode/index.d.ts.map +1 -0
- package/dist/codemode/sandbox-factory.d.ts +72 -0
- package/dist/codemode/sandbox-factory.d.ts.map +1 -0
- package/dist/codemode/sandbox.d.ts +54 -0
- package/dist/codemode/sandbox.d.ts.map +1 -0
- package/dist/codemode/security.d.ts +45 -0
- package/dist/codemode/security.d.ts.map +1 -0
- package/dist/codemode/types.d.ts +167 -0
- package/dist/codemode/types.d.ts.map +1 -0
- package/dist/constants/server-instructions.d.ts +22 -0
- package/dist/constants/server-instructions.d.ts.map +1 -0
- package/dist/filtering/tool-constants.d.ts +45 -0
- package/dist/filtering/tool-constants.d.ts.map +1 -0
- package/dist/filtering/tool-filter.d.ts +82 -0
- package/dist/filtering/tool-filter.d.ts.map +1 -0
- package/dist/{http-6KF4ULDI.js → http-HWTUVFIA.js} +498 -391
- package/dist/index.d.ts +9 -1065
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -6
- package/dist/server/mcp-server.d.ts +66 -0
- package/dist/server/mcp-server.d.ts.map +1 -0
- package/dist/server/registration/audit-tools.d.ts +13 -0
- package/dist/server/registration/audit-tools.d.ts.map +1 -0
- package/dist/server/registration/built-in-tools.d.ts +8 -0
- package/dist/server/registration/built-in-tools.d.ts.map +1 -0
- package/dist/server/registration/help-resources.d.ts +7 -0
- package/dist/server/registration/help-resources.d.ts.map +1 -0
- package/dist/server/registration/index.d.ts +4 -0
- package/dist/server/registration/index.d.ts.map +1 -0
- package/dist/{sqlite-U5KSYQXK.js → sqlite-TB56Z7G3.js} +61 -17
- package/dist/{sqlite-native-JXMCFQBA.js → sqlite-native-IF75BB3O.js} +459 -254
- package/dist/transports/http/index.d.ts +8 -0
- package/dist/transports/http/index.d.ts.map +1 -0
- package/dist/transports/http/middleware.d.ts +25 -0
- package/dist/transports/http/middleware.d.ts.map +1 -0
- package/dist/transports/http/oauth.d.ts +24 -0
- package/dist/transports/http/oauth.d.ts.map +1 -0
- package/dist/transports/http/session.d.ts +2 -0
- package/dist/transports/http/session.d.ts.map +1 -0
- package/dist/transports/http/sessions/index.d.ts +4 -0
- package/dist/transports/http/sessions/index.d.ts.map +1 -0
- package/dist/transports/http/sessions/legacy-sse.d.ts +6 -0
- package/dist/transports/http/sessions/legacy-sse.d.ts.map +1 -0
- package/dist/transports/http/sessions/mutex.d.ts +6 -0
- package/dist/transports/http/sessions/mutex.d.ts.map +1 -0
- package/dist/transports/http/sessions/stateful.d.ts +12 -0
- package/dist/transports/http/sessions/stateful.d.ts.map +1 -0
- package/dist/transports/http/sessions/stateless.d.ts +6 -0
- package/dist/transports/http/sessions/stateless.d.ts.map +1 -0
- package/dist/transports/http/transport.d.ts +65 -0
- package/dist/transports/http/transport.d.ts.map +1 -0
- package/dist/transports/http/type-adapters.d.ts +20 -0
- package/dist/transports/http/type-adapters.d.ts.map +1 -0
- package/dist/transports/http/types.d.ts +120 -0
- package/dist/transports/http/types.d.ts.map +1 -0
- package/dist/types/adapter.d.ts +138 -0
- package/dist/types/adapter.d.ts.map +1 -0
- package/dist/types/auth.d.ts +79 -0
- package/dist/types/auth.d.ts.map +1 -0
- package/dist/types/database.d.ts +100 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/filtering.d.ts +41 -0
- package/dist/types/filtering.d.ts.map +1 -0
- package/dist/types/index.d.ts +13 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/server.d.ts +48 -0
- package/dist/types/server.d.ts.map +1 -0
- package/dist/utils/annotations.d.ts +62 -0
- package/dist/utils/annotations.d.ts.map +1 -0
- package/dist/utils/errors/base.d.ts +33 -0
- package/dist/utils/errors/base.d.ts.map +1 -0
- package/dist/utils/errors/categories.d.ts +41 -0
- package/dist/utils/errors/categories.d.ts.map +1 -0
- package/dist/utils/errors/classes.d.ts +124 -0
- package/dist/utils/errors/classes.d.ts.map +1 -0
- package/dist/utils/errors/error-response-fields.d.ts +24 -0
- package/dist/utils/errors/error-response-fields.d.ts.map +1 -0
- package/dist/utils/errors/format.d.ts +74 -0
- package/dist/utils/errors/format.d.ts.map +1 -0
- package/dist/utils/errors/index.d.ts +11 -0
- package/dist/utils/errors/index.d.ts.map +1 -0
- package/dist/utils/errors/suggestions.d.ts +16 -0
- package/dist/utils/errors/suggestions.d.ts.map +1 -0
- package/dist/utils/icons.d.ts +19 -0
- package/dist/utils/icons.d.ts.map +1 -0
- package/dist/utils/identifiers.d.ts +121 -0
- package/dist/utils/identifiers.d.ts.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/insights-manager.d.ts +39 -0
- package/dist/utils/insights-manager.d.ts.map +1 -0
- package/dist/utils/logger/error-codes.d.ts +48 -0
- package/dist/utils/logger/error-codes.d.ts.map +1 -0
- package/dist/utils/logger/index.d.ts +22 -0
- package/dist/utils/logger/index.d.ts.map +1 -0
- package/dist/utils/logger/logger.d.ts +94 -0
- package/dist/utils/logger/logger.d.ts.map +1 -0
- package/dist/utils/logger/module-logger.d.ts +28 -0
- package/dist/utils/logger/module-logger.d.ts.map +1 -0
- package/dist/utils/logger/types.d.ts +36 -0
- package/dist/utils/logger/types.d.ts.map +1 -0
- package/dist/utils/progress-utils.d.ts +54 -0
- package/dist/utils/progress-utils.d.ts.map +1 -0
- package/dist/utils/redaction.d.ts +4 -0
- package/dist/utils/redaction.d.ts.map +1 -0
- package/dist/utils/resource-annotations.d.ts +36 -0
- package/dist/utils/resource-annotations.d.ts.map +1 -0
- package/dist/utils/validate-json-path.d.ts +43 -0
- package/dist/utils/validate-json-path.d.ts.map +1 -0
- package/dist/utils/validate-path.d.ts +37 -0
- package/dist/utils/validate-path.d.ts.map +1 -0
- package/dist/utils/where-clause.d.ts +42 -0
- package/dist/utils/where-clause.d.ts.map +1 -0
- package/dist/version.d.ts +10 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +26 -13
- package/.gitattributes +0 -2
- package/.gitleaks.toml +0 -9
- package/.trivyignore +0 -8
- package/dist/chunk-OKOVZ5QE.js +0 -28
- package/dist/chunk-SFJQCNG7.js +0 -131
- package/dist/chunk-VIDSICEL.js +0 -85
- package/dist/chunk-X3MUUOWM.js +0 -152
- package/dist/worker-script.d.ts +0 -2
- package/dist/worker-script.js +0 -150
- package/logs/.gitkeep +0 -1
- package/mcp-config-example.json +0 -83
- package/playwright.config.ts +0 -101
- package/scripts/generate-server-instructions.ts +0 -111
- package/scripts/update-badges.ts +0 -99
- package/server.json +0 -54
- package/test-server/README.md +0 -115
- package/test-server/code-map.md +0 -421
- package/test-server/fixtures/sample.csv +0 -6
- package/test-server/reset-database.ps1 +0 -415
- package/test-server/sample.csv +0 -11
- package/test-server/scripts/README.md +0 -27
- package/test-server/scripts/test-help-resources.mjs +0 -245
- package/test-server/scripts/test-prompts.mjs +0 -251
- package/test-server/scripts/test-tool-annotations.mjs +0 -162
- package/test-server/test-advanced/README.md +0 -70
- package/test-server/test-advanced/test-codemode-advanced-admin.md +0 -174
- package/test-server/test-advanced/test-codemode-advanced-core.md +0 -193
- package/test-server/test-advanced/test-codemode-advanced-geo.md +0 -157
- package/test-server/test-advanced/test-codemode-advanced-introspection.md +0 -171
- package/test-server/test-advanced/test-codemode-advanced-json.md +0 -169
- package/test-server/test-advanced/test-codemode-advanced-migration.md +0 -160
- package/test-server/test-advanced/test-codemode-advanced-stats.md +0 -185
- package/test-server/test-advanced/test-codemode-advanced-text.md +0 -183
- package/test-server/test-advanced/test-codemode-advanced-transactions.md +0 -136
- package/test-server/test-advanced/test-codemode-advanced-vector.md +0 -141
- package/test-server/test-codemode/README.md +0 -121
- package/test-server/test-codemode/test-codemode-admin.md +0 -223
- package/test-server/test-codemode/test-codemode-core.md +0 -286
- package/test-server/test-codemode/test-codemode-geo.md +0 -177
- package/test-server/test-codemode/test-codemode-introspection.md +0 -190
- package/test-server/test-codemode/test-codemode-json.md +0 -237
- package/test-server/test-codemode/test-codemode-migration.md +0 -278
- package/test-server/test-codemode/test-codemode-sandbox.md +0 -413
- package/test-server/test-codemode/test-codemode-stats.md +0 -232
- package/test-server/test-codemode/test-codemode-text.md +0 -237
- package/test-server/test-codemode/test-codemode-transactions.md +0 -236
- package/test-server/test-codemode/test-codemode-vector.md +0 -244
- package/test-server/test-codemode/test-codemode-wasm-degradation.md +0 -394
- package/test-server/test-database.sql +0 -424
- package/test-server/test-preflight.md +0 -53
- package/test-server/test-prompts.md +0 -354
- package/test-server/test-resources.md +0 -272
- package/test-server/test-tool-groups/README.md +0 -100
- package/test-server/test-tool-groups/test-admin-core.md +0 -165
- package/test-server/test-tool-groups/test-admin-extensions.md +0 -133
- package/test-server/test-tool-groups/test-core-data.md +0 -262
- package/test-server/test-tool-groups/test-core-schema.md +0 -240
- package/test-server/test-tool-groups/test-geo-haversine.md +0 -130
- package/test-server/test-tool-groups/test-geo-spatialite.md +0 -110
- package/test-server/test-tool-groups/test-introspection-diagnostics.md +0 -123
- package/test-server/test-tool-groups/test-introspection-schema.md +0 -133
- package/test-server/test-tool-groups/test-json-read.md +0 -219
- package/test-server/test-tool-groups/test-json-write.md +0 -157
- package/test-server/test-tool-groups/test-migration.md +0 -193
- package/test-server/test-tool-groups/test-stats-advanced.md +0 -118
- package/test-server/test-tool-groups/test-stats-basic.md +0 -156
- package/test-server/test-tool-groups/test-text-advanced.md +0 -169
- package/test-server/test-tool-groups/test-text-basic.md +0 -177
- package/test-server/test-tool-groups/test-transactions.md +0 -179
- package/test-server/test-tool-groups/test-vector-read.md +0 -130
- package/test-server/test-tool-groups/test-vector-write.md +0 -115
- package/test-server/tool-reference.md +0 -257
- package/tsconfig.build.json +0 -6
- package/tsconfig.test.json +0 -9
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { DatabaseAdapter } from './chunk-
|
|
3
|
-
import { write, readOnly, VERSION, admin, getToolGroupIcon, idempotent } from './chunk-
|
|
4
|
-
import './chunk-
|
|
5
|
-
import { formatHandlerError, ValidationError, ConfigurationError, ConnectionError, ResourceNotFoundError, ExtensionNotAvailableError } from './chunk-X3MUUOWM.js';
|
|
6
|
-
import { logger, ERROR_CODES, DbMcpError } from './chunk-645ZEFLA.js';
|
|
1
|
+
import { RowRecordSchema, WhereConditionSchema, sanitizeIdentifier, buildWhereClause, resolveAliases, autoEnableWal, detectAndSetJsonbSupport, SchemaManager, applyCommonPragmas, isDDL, getResourceDefinitions, getPromptDefinitions, validateIdentifier, normalizeSqliteParams, translateSqliteError, getCoreTools, getJsonOperationTools, getJsonHelperTools, getTextTools, getStatsTools, getVirtualTools, getVectorTools, getGeoTools, getAdminTools, getIntrospectionTools, getMigrationTools, getCodeModeTools, validateTableExists, FtsHeadlineSchema } from './chunk-NV34JSQM.js';
|
|
2
|
+
import { DatabaseAdapter } from './chunk-W5WQVNVX.js';
|
|
3
|
+
import { ErrorResponseFields, write, readOnly, VERSION, admin, writeFs, getToolGroupIcon, idempotent } from './chunk-E5IESRTK.js';
|
|
4
|
+
import { logger, formatHandlerError, ValidationError, ConfigurationError, ERROR_CODES, ConnectionError, DbMcpError, ResourceNotFoundError, ExtensionNotAvailableError } from './chunk-L552U3QS.js';
|
|
7
5
|
import Database from 'better-sqlite3';
|
|
8
6
|
import { z } from 'zod';
|
|
9
|
-
import
|
|
10
|
-
import fs from 'fs';
|
|
7
|
+
import { createRequire } from 'module';
|
|
11
8
|
import { fileURLToPath } from 'url';
|
|
9
|
+
import path2 from 'path';
|
|
10
|
+
import fs from 'fs';
|
|
12
11
|
|
|
13
12
|
var FtsCreateOutputSchema = z.object({
|
|
14
13
|
success: z.boolean(),
|
|
@@ -58,11 +57,15 @@ var FtsSearchSchema = z.object({
|
|
|
58
57
|
table: z.string().describe("FTS table name"),
|
|
59
58
|
query: z.string().describe("Full-text search query"),
|
|
60
59
|
columns: z.array(z.string()).optional().describe("Specific columns to search"),
|
|
61
|
-
limit: z.preprocess(
|
|
62
|
-
(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
limit: z.preprocess((val) => {
|
|
61
|
+
if (typeof val === "string") {
|
|
62
|
+
const parsed = Number(val);
|
|
63
|
+
return isNaN(parsed) ? val : parsed;
|
|
64
|
+
}
|
|
65
|
+
return val;
|
|
66
|
+
}, z.number().optional().default(100)),
|
|
67
|
+
highlight: z.boolean().optional().default(false).describe("Include highlighted snippets"),
|
|
68
|
+
includeRowData: z.boolean().optional().default(true).describe("Include full row data in results")
|
|
66
69
|
});
|
|
67
70
|
var FtsRebuildSchema = z.object({
|
|
68
71
|
table: z.string().describe("FTS table name to rebuild")
|
|
@@ -73,7 +76,8 @@ var FtsMatchInfoSchema = z.object({
|
|
|
73
76
|
format: z.preprocess(
|
|
74
77
|
coerceEnumValues(["bm25", "rank"]),
|
|
75
78
|
z.enum(["bm25", "rank"]).optional().default("bm25")
|
|
76
|
-
)
|
|
79
|
+
),
|
|
80
|
+
includeRowData: z.boolean().optional().default(true).describe("Include full row data in results")
|
|
77
81
|
});
|
|
78
82
|
|
|
79
83
|
// src/adapters/sqlite/tools/fts.ts
|
|
@@ -181,7 +185,7 @@ async function createSyncTriggers(adapter, ftsTable, contentTable, columns) {
|
|
|
181
185
|
INSERT INTO "${ftsTable}"(rowid, ${colList}) VALUES (NEW.rowid, ${newColList});
|
|
182
186
|
END;
|
|
183
187
|
`;
|
|
184
|
-
await adapter.
|
|
188
|
+
await adapter.rawQuery(insertTrigger, void 0);
|
|
185
189
|
triggersCreated.push(insertTriggerName);
|
|
186
190
|
const deleteTriggerName = `${ftsTable}_ad`;
|
|
187
191
|
const deleteTrigger = `
|
|
@@ -189,7 +193,7 @@ async function createSyncTriggers(adapter, ftsTable, contentTable, columns) {
|
|
|
189
193
|
INSERT INTO "${ftsTable}"("${ftsTable}", rowid, ${colList}) VALUES('delete', OLD.rowid, ${oldColList});
|
|
190
194
|
END;
|
|
191
195
|
`;
|
|
192
|
-
await adapter.
|
|
196
|
+
await adapter.rawQuery(deleteTrigger, void 0);
|
|
193
197
|
triggersCreated.push(deleteTriggerName);
|
|
194
198
|
const updateTriggerName = `${ftsTable}_au`;
|
|
195
199
|
const updateTrigger = `
|
|
@@ -198,7 +202,7 @@ async function createSyncTriggers(adapter, ftsTable, contentTable, columns) {
|
|
|
198
202
|
INSERT INTO "${ftsTable}"(rowid, ${colList}) VALUES (NEW.rowid, ${newColList});
|
|
199
203
|
END;
|
|
200
204
|
`;
|
|
201
|
-
await adapter.
|
|
205
|
+
await adapter.rawQuery(updateTrigger, void 0);
|
|
202
206
|
triggersCreated.push(updateTriggerName);
|
|
203
207
|
return triggersCreated;
|
|
204
208
|
}
|
|
@@ -214,18 +218,19 @@ function createFtsSearchTool(adapter) {
|
|
|
214
218
|
handler: async (params, _context) => {
|
|
215
219
|
try {
|
|
216
220
|
const input = FtsSearchSchema.parse(params);
|
|
221
|
+
const queryParams = [];
|
|
217
222
|
if (!isFts5Available(adapter)) {
|
|
218
223
|
return buildFts5SearchUnavailableError();
|
|
219
224
|
}
|
|
220
225
|
sanitizeIdentifier(input.table);
|
|
221
226
|
await validateTableExists(adapter, input.table);
|
|
222
|
-
let selectClause = "*";
|
|
227
|
+
let selectClause = input.includeRowData ? "*" : "rowid";
|
|
223
228
|
if (input.highlight) {
|
|
224
|
-
selectClause
|
|
229
|
+
selectClause += `, highlight("${input.table}", 0, '<b>', '</b>') as snippet`;
|
|
225
230
|
}
|
|
226
231
|
if (input.query === "*" || input.query.trim() === "") {
|
|
227
232
|
const sql2 = `SELECT ${selectClause}, NULL as rank FROM "${input.table}" ORDER BY rowid LIMIT ${input.limit}`;
|
|
228
|
-
const result2 = await adapter.executeReadQuery(sql2);
|
|
233
|
+
const result2 = await adapter.executeReadQuery(sql2, queryParams);
|
|
229
234
|
return {
|
|
230
235
|
success: true,
|
|
231
236
|
rowCount: result2.rows?.length ?? 0,
|
|
@@ -242,7 +247,7 @@ function createFtsSearchTool(adapter) {
|
|
|
242
247
|
matchExpr = `"${input.table}" MATCH '${colFilter}'`;
|
|
243
248
|
}
|
|
244
249
|
const sql = `SELECT ${selectClause}, rank FROM "${input.table}" WHERE ${matchExpr} ORDER BY rank LIMIT ${input.limit}`;
|
|
245
|
-
const result = await adapter.executeReadQuery(sql);
|
|
250
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
246
251
|
return {
|
|
247
252
|
success: true,
|
|
248
253
|
rowCount: result.rows?.length ?? 0,
|
|
@@ -304,6 +309,7 @@ function createFtsMatchInfoTool(adapter) {
|
|
|
304
309
|
handler: async (params, _context) => {
|
|
305
310
|
try {
|
|
306
311
|
const input = FtsMatchInfoSchema.parse(params);
|
|
312
|
+
const queryParams = [];
|
|
307
313
|
if (!isFts5Available(adapter)) {
|
|
308
314
|
return buildFts5SearchUnavailableError();
|
|
309
315
|
}
|
|
@@ -316,8 +322,9 @@ function createFtsMatchInfoTool(adapter) {
|
|
|
316
322
|
} else {
|
|
317
323
|
rankExpr = "rank";
|
|
318
324
|
}
|
|
319
|
-
const
|
|
320
|
-
const
|
|
325
|
+
const selectCols = input.includeRowData ? "*" : "rowid";
|
|
326
|
+
const sql = `SELECT ${selectCols}, ${rankExpr} as score FROM "${input.table}" WHERE "${input.table}" MATCH '${queryEscaped}' ORDER BY score`;
|
|
327
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
321
328
|
return {
|
|
322
329
|
success: true,
|
|
323
330
|
rowCount: result.rows?.length ?? 0,
|
|
@@ -344,6 +351,7 @@ function createFtsHeadlineTool(adapter) {
|
|
|
344
351
|
handler: async (params, _context) => {
|
|
345
352
|
try {
|
|
346
353
|
const input = FtsHeadlineSchema.parse(params);
|
|
354
|
+
const queryParams = [];
|
|
347
355
|
if (!isFts5Available(adapter)) {
|
|
348
356
|
return buildFts5SearchUnavailableError();
|
|
349
357
|
}
|
|
@@ -353,7 +361,8 @@ function createFtsHeadlineTool(adapter) {
|
|
|
353
361
|
let columnIndex = 0;
|
|
354
362
|
if (input.column) {
|
|
355
363
|
const colResult = await adapter.executeReadQuery(
|
|
356
|
-
`PRAGMA table_info("${input.table}")
|
|
364
|
+
`PRAGMA table_info("${input.table}")`,
|
|
365
|
+
queryParams
|
|
357
366
|
);
|
|
358
367
|
const colRows = colResult.rows ?? [];
|
|
359
368
|
const found = colRows.findIndex(
|
|
@@ -369,7 +378,7 @@ function createFtsHeadlineTool(adapter) {
|
|
|
369
378
|
const snippetExpr = `snippet("${input.table}", ${String(columnIndex)}, '${startSel}', '${stopSel}', '...', ${String(input.snippetWords)})`;
|
|
370
379
|
if (input.query === "*" || input.query.trim() === "") {
|
|
371
380
|
const sql2 = `SELECT *, NULL as headline, NULL as snippet, NULL as rank FROM "${input.table}" ORDER BY rowid LIMIT ${String(input.limit)}`;
|
|
372
|
-
const result2 = await adapter.executeReadQuery(sql2);
|
|
381
|
+
const result2 = await adapter.executeReadQuery(sql2, queryParams);
|
|
373
382
|
return {
|
|
374
383
|
success: true,
|
|
375
384
|
rowCount: result2.rows?.length ?? 0,
|
|
@@ -377,7 +386,7 @@ function createFtsHeadlineTool(adapter) {
|
|
|
377
386
|
};
|
|
378
387
|
}
|
|
379
388
|
const sql = `SELECT ${highlightExpr} as headline, ${snippetExpr} as snippet, rank FROM "${input.table}" WHERE "${input.table}" MATCH '${queryEscaped}' ORDER BY rank LIMIT ${String(input.limit)}`;
|
|
380
|
-
const result = await adapter.executeReadQuery(sql);
|
|
389
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
381
390
|
return {
|
|
382
391
|
success: true,
|
|
383
392
|
rowCount: result.rows?.length ?? 0,
|
|
@@ -549,17 +558,9 @@ var SpatialiteImportOutputSchema = z.object({
|
|
|
549
558
|
}).extend(ErrorResponseFields.shape);
|
|
550
559
|
|
|
551
560
|
// src/adapters/sqlite-native/tools/transactions.ts
|
|
552
|
-
var VALID_MODES = ["deferred", "immediate", "exclusive"];
|
|
553
561
|
var BeginTransactionSchema = z.object({
|
|
554
|
-
mode: z.
|
|
555
|
-
|
|
556
|
-
if (typeof val !== "string") return void 0;
|
|
557
|
-
const normalized = val.toLowerCase();
|
|
558
|
-
return VALID_MODES.includes(normalized) ? normalized : void 0;
|
|
559
|
-
},
|
|
560
|
-
z.enum(["deferred", "immediate", "exclusive"]).optional().default("deferred").describe(
|
|
561
|
-
"Transaction mode: deferred waits for first write, immediate acquires lock immediately, exclusive blocks all access"
|
|
562
|
-
)
|
|
562
|
+
mode: z.enum(["deferred", "immediate", "exclusive"]).optional().default("deferred").describe(
|
|
563
|
+
"Transaction mode: deferred waits for first write, immediate acquires lock immediately, exclusive blocks all access"
|
|
563
564
|
)
|
|
564
565
|
});
|
|
565
566
|
var SavepointSchema = z.object({
|
|
@@ -784,6 +785,7 @@ function createExecuteInTransactionTool(adapter) {
|
|
|
784
785
|
annotations: write("Execute in Transaction"),
|
|
785
786
|
requiredScopes: ["write"],
|
|
786
787
|
handler: async (params, _context) => {
|
|
788
|
+
const queryParams = [];
|
|
787
789
|
let input;
|
|
788
790
|
try {
|
|
789
791
|
input = ExecuteInTransactionSchema.parse(params);
|
|
@@ -813,18 +815,29 @@ function createExecuteInTransactionTool(adapter) {
|
|
|
813
815
|
try {
|
|
814
816
|
const isSelect = statement.trim().toUpperCase().startsWith("SELECT");
|
|
815
817
|
if (isSelect) {
|
|
816
|
-
const result = await adapter.executeReadQuery(
|
|
818
|
+
const result = await adapter.executeReadQuery(
|
|
819
|
+
statement,
|
|
820
|
+
queryParams
|
|
821
|
+
);
|
|
817
822
|
const rowCount = result.rows?.length ?? 0;
|
|
818
823
|
const statementResult = {
|
|
819
824
|
statement: statement.substring(0, 100) + (statement.length > 100 ? "..." : ""),
|
|
820
825
|
rowCount
|
|
821
826
|
};
|
|
822
827
|
if (result.rows) {
|
|
823
|
-
|
|
828
|
+
if (result.rows.length > 50) {
|
|
829
|
+
statementResult.rows = result.rows.slice(0, 50);
|
|
830
|
+
statementResult.error = "Result truncated to 50 rows. Use sqlite_read_query with LIMIT for larger datasets.";
|
|
831
|
+
} else {
|
|
832
|
+
statementResult.rows = result.rows;
|
|
833
|
+
}
|
|
824
834
|
}
|
|
825
835
|
results.push(statementResult);
|
|
826
836
|
} else {
|
|
827
|
-
const result = await adapter.executeWriteQuery(
|
|
837
|
+
const result = await adapter.executeWriteQuery(
|
|
838
|
+
statement,
|
|
839
|
+
queryParams
|
|
840
|
+
);
|
|
828
841
|
results.push({
|
|
829
842
|
statement: statement.substring(0, 100) + (statement.length > 100 ? "..." : ""),
|
|
830
843
|
rowsAffected: result.rowsAffected ?? 0
|
|
@@ -888,8 +901,9 @@ function createExecuteInTransactionTool(adapter) {
|
|
|
888
901
|
}
|
|
889
902
|
var coerceNumber = (val) => {
|
|
890
903
|
if (typeof val === "string") {
|
|
904
|
+
if (val.trim() === "") return void 0;
|
|
891
905
|
const num = Number(val);
|
|
892
|
-
return isNaN(num) ?
|
|
906
|
+
return isNaN(num) ? val : num;
|
|
893
907
|
}
|
|
894
908
|
return val;
|
|
895
909
|
};
|
|
@@ -900,7 +914,7 @@ var RowNumberSchema = z.object({
|
|
|
900
914
|
orderBy: z.string().describe("Column(s) to order by"),
|
|
901
915
|
partitionBy: z.string().optional().describe("Column(s) to partition by"),
|
|
902
916
|
selectColumns: z.array(z.string()).optional().describe("Columns to include in result"),
|
|
903
|
-
|
|
917
|
+
conditions: z.array(WhereConditionSchema).optional().describe("Optional WHERE clause conditions"),
|
|
904
918
|
limit: z.preprocess(
|
|
905
919
|
coerceNumber,
|
|
906
920
|
z.number().optional().default(20).describe("Maximum rows to return")
|
|
@@ -915,7 +929,7 @@ var RankSchema = z.object({
|
|
|
915
929
|
coerceEnumValues2(["rank", "dense_rank", "percent_rank"]),
|
|
916
930
|
z.enum(["rank", "dense_rank", "percent_rank"]).optional().default("rank").describe("Rank function type")
|
|
917
931
|
),
|
|
918
|
-
|
|
932
|
+
conditions: z.array(WhereConditionSchema).optional().describe("Optional WHERE clause conditions"),
|
|
919
933
|
limit: z.preprocess(
|
|
920
934
|
coerceNumber,
|
|
921
935
|
z.number().optional().default(20).describe("Maximum rows to return")
|
|
@@ -933,7 +947,7 @@ var LagLeadSchema = z.object({
|
|
|
933
947
|
defaultValue: z.string().optional().describe("Default value if no row exists"),
|
|
934
948
|
partitionBy: z.string().optional().describe("Column(s) to partition by"),
|
|
935
949
|
selectColumns: z.array(z.string()).optional().describe("Columns to include in result"),
|
|
936
|
-
|
|
950
|
+
conditions: z.array(WhereConditionSchema).optional().describe("Optional WHERE clause conditions"),
|
|
937
951
|
limit: z.preprocess(
|
|
938
952
|
coerceNumber,
|
|
939
953
|
z.number().optional().default(20).describe("Maximum rows to return")
|
|
@@ -945,7 +959,7 @@ var RunningTotalSchema = z.object({
|
|
|
945
959
|
orderBy: z.string().describe("Column(s) to order by"),
|
|
946
960
|
partitionBy: z.string().optional().describe("Reset running total for each partition"),
|
|
947
961
|
selectColumns: z.array(z.string()).optional().describe("Columns to include in result"),
|
|
948
|
-
|
|
962
|
+
conditions: z.array(WhereConditionSchema).optional().describe("Optional WHERE clause conditions"),
|
|
949
963
|
limit: z.preprocess(
|
|
950
964
|
coerceNumber,
|
|
951
965
|
z.number().optional().default(20).describe("Maximum rows to return")
|
|
@@ -957,11 +971,11 @@ var MovingAverageSchema = z.object({
|
|
|
957
971
|
orderBy: z.string().describe("Column(s) to order by"),
|
|
958
972
|
windowSize: z.preprocess(
|
|
959
973
|
coerceNumber,
|
|
960
|
-
z.number().
|
|
974
|
+
z.number().describe("Number of rows in the moving window")
|
|
961
975
|
),
|
|
962
976
|
partitionBy: z.string().optional().describe("Column(s) to partition by"),
|
|
963
977
|
selectColumns: z.array(z.string()).optional().describe("Columns to include in result"),
|
|
964
|
-
|
|
978
|
+
conditions: z.array(WhereConditionSchema).optional().describe("Optional WHERE clause conditions"),
|
|
965
979
|
limit: z.preprocess(
|
|
966
980
|
coerceNumber,
|
|
967
981
|
z.number().optional().default(20).describe("Maximum rows to return")
|
|
@@ -972,24 +986,18 @@ var NtileSchema = z.object({
|
|
|
972
986
|
orderBy: z.string().describe("Column(s) to order by"),
|
|
973
987
|
buckets: z.preprocess(
|
|
974
988
|
coerceNumber,
|
|
975
|
-
z.number().
|
|
989
|
+
z.number().describe("Number of buckets (e.g., 4 for quartiles)")
|
|
976
990
|
),
|
|
977
991
|
partitionBy: z.string().optional().describe("Column(s) to partition by"),
|
|
978
992
|
selectColumns: z.array(z.string()).optional().describe("Columns to include in result"),
|
|
979
|
-
|
|
993
|
+
conditions: z.array(WhereConditionSchema).optional().describe("Optional WHERE clause conditions"),
|
|
980
994
|
limit: z.preprocess(
|
|
981
995
|
coerceNumber,
|
|
982
996
|
z.number().optional().default(20).describe("Maximum rows to return")
|
|
983
997
|
)
|
|
984
998
|
});
|
|
985
999
|
async function validateTableExists2(adapter, table) {
|
|
986
|
-
|
|
987
|
-
throw new DbMcpError(
|
|
988
|
-
"Invalid table name",
|
|
989
|
-
"NATIVE_WINDOW_INVALID_TABLE",
|
|
990
|
-
"validation" /* VALIDATION */
|
|
991
|
-
);
|
|
992
|
-
}
|
|
1000
|
+
validateIdentifier(table);
|
|
993
1001
|
const result = await adapter.executeReadQuery(
|
|
994
1002
|
`SELECT 1 FROM sqlite_master WHERE type IN ('table', 'view') AND name='${table}'`
|
|
995
1003
|
);
|
|
@@ -1006,13 +1014,7 @@ async function validateTableExists2(adapter, table) {
|
|
|
1006
1014
|
}
|
|
1007
1015
|
}
|
|
1008
1016
|
async function validateColumnInTable(adapter, table, column) {
|
|
1009
|
-
|
|
1010
|
-
throw new DbMcpError(
|
|
1011
|
-
"Invalid column name",
|
|
1012
|
-
"NATIVE_WINDOW_INVALID_COLUMN",
|
|
1013
|
-
"validation" /* VALIDATION */
|
|
1014
|
-
);
|
|
1015
|
-
}
|
|
1017
|
+
validateIdentifier(column);
|
|
1016
1018
|
const tableInfo = await adapter.executeReadQuery(
|
|
1017
1019
|
`SELECT name FROM pragma_table_info('${table}') WHERE name='${column}'`
|
|
1018
1020
|
);
|
|
@@ -1035,19 +1037,31 @@ async function validateOrderByColumns(adapter, table, orderBy) {
|
|
|
1035
1037
|
const firstToken = tokens[0];
|
|
1036
1038
|
if (!firstToken) continue;
|
|
1037
1039
|
const colName = firstToken.replace(/^"|"$/g, "");
|
|
1038
|
-
if (/[
|
|
1040
|
+
if (/[;()+*/]/.test(colName)) {
|
|
1041
|
+
throw new DbMcpError(
|
|
1042
|
+
`Invalid ORDER BY expression: '${colName}' contains disallowed characters. Only column names with optional ASC/DESC are permitted.`,
|
|
1043
|
+
"NATIVE_WINDOW_INVALID_ORDERBY",
|
|
1044
|
+
"validation" /* VALIDATION */
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1039
1047
|
if (/^(ASC|DESC)$/i.test(colName)) continue;
|
|
1048
|
+
if (colName.includes(".")) {
|
|
1049
|
+
for (const segment of colName.split(".")) {
|
|
1050
|
+
validateIdentifier(segment);
|
|
1051
|
+
}
|
|
1052
|
+
continue;
|
|
1053
|
+
}
|
|
1040
1054
|
await validateColumnInTable(adapter, table, colName);
|
|
1041
1055
|
}
|
|
1042
1056
|
}
|
|
1043
1057
|
async function resolveSelectColumns(adapter, table, selectColumns, rankCol) {
|
|
1044
1058
|
if (selectColumns && selectColumns.length > 0) {
|
|
1045
1059
|
return {
|
|
1046
|
-
columnList: selectColumns.map((c) =>
|
|
1060
|
+
columnList: selectColumns.map((c) => sanitizeIdentifier(c)).join(", ")
|
|
1047
1061
|
};
|
|
1048
1062
|
}
|
|
1049
1063
|
const tableInfo = await adapter.executeReadQuery(
|
|
1050
|
-
`PRAGMA table_info(
|
|
1064
|
+
`PRAGMA table_info('${table}')`
|
|
1051
1065
|
);
|
|
1052
1066
|
const TEXT_TYPES = /* @__PURE__ */ new Set([
|
|
1053
1067
|
"text",
|
|
@@ -1095,14 +1109,57 @@ async function resolveSelectColumns(adapter, table, selectColumns, rankCol) {
|
|
|
1095
1109
|
included.push(colName);
|
|
1096
1110
|
}
|
|
1097
1111
|
}
|
|
1112
|
+
if (included.length > 10) {
|
|
1113
|
+
throw new ValidationError(
|
|
1114
|
+
`Table '${table}' has too many columns (${included.length} remaining after text filtering). You must explicitly provide 'selectColumns' to prevent context window bloat.`,
|
|
1115
|
+
"INVALID_INPUT"
|
|
1116
|
+
);
|
|
1117
|
+
}
|
|
1098
1118
|
if (excluded.length > 0 && included.length > 0) {
|
|
1099
1119
|
return {
|
|
1100
|
-
columnList: included.map((c) =>
|
|
1120
|
+
columnList: included.map((c) => sanitizeIdentifier(c)).join(", "),
|
|
1101
1121
|
hint: `Excluded ${excluded.length} long-content column(s) (${excluded.join(", ")}) to reduce payload. Use selectColumns to override.`
|
|
1102
1122
|
};
|
|
1103
1123
|
}
|
|
1104
1124
|
return { columnList: "*" };
|
|
1105
1125
|
}
|
|
1126
|
+
function sanitizePartitionBy(partitionBy) {
|
|
1127
|
+
const columns = partitionBy.split(",").map((c) => c.trim()).filter(Boolean);
|
|
1128
|
+
for (const col of columns) {
|
|
1129
|
+
validateIdentifier(col);
|
|
1130
|
+
}
|
|
1131
|
+
return columns.map((c) => sanitizeIdentifier(c)).join(", ");
|
|
1132
|
+
}
|
|
1133
|
+
function sanitizeOrderByExpr(orderBy) {
|
|
1134
|
+
const parts = orderBy.split(",");
|
|
1135
|
+
const sanitized = [];
|
|
1136
|
+
for (const part of parts) {
|
|
1137
|
+
const tokens = part.trim().split(/\s+/);
|
|
1138
|
+
const colToken = tokens[0];
|
|
1139
|
+
if (!colToken) continue;
|
|
1140
|
+
const colName = colToken.replace(/^"|"$/g, "");
|
|
1141
|
+
validateIdentifier(colName);
|
|
1142
|
+
const direction = tokens[1];
|
|
1143
|
+
if (direction && /^(ASC|DESC)$/i.test(direction)) {
|
|
1144
|
+
sanitized.push(
|
|
1145
|
+
`${sanitizeIdentifier(colName)} ${direction.toUpperCase()}`
|
|
1146
|
+
);
|
|
1147
|
+
} else {
|
|
1148
|
+
sanitized.push(sanitizeIdentifier(colName));
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
return sanitized.join(", ");
|
|
1152
|
+
}
|
|
1153
|
+
function validateDefaultValue(value) {
|
|
1154
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) return;
|
|
1155
|
+
if (/^'[^']*'$/.test(value)) return;
|
|
1156
|
+
if (/^NULL$/i.test(value)) return;
|
|
1157
|
+
throw new DbMcpError(
|
|
1158
|
+
`Invalid default value: '${value}'. Only numeric literals, single-quoted strings, or NULL are permitted.`,
|
|
1159
|
+
"NATIVE_WINDOW_INVALID_DEFAULT",
|
|
1160
|
+
"validation" /* VALIDATION */
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1106
1163
|
function getWindowTools(adapter) {
|
|
1107
1164
|
return [
|
|
1108
1165
|
createRowNumberTool(adapter),
|
|
@@ -1123,6 +1180,7 @@ function createRowNumberTool(adapter) {
|
|
|
1123
1180
|
annotations: readOnly("Window Row Number"),
|
|
1124
1181
|
requiredScopes: ["read"],
|
|
1125
1182
|
handler: async (params, _context) => {
|
|
1183
|
+
const queryParams = [];
|
|
1126
1184
|
try {
|
|
1127
1185
|
const input = RowNumberSchema.parse(params);
|
|
1128
1186
|
await validateTableExists2(adapter, input.table);
|
|
@@ -1132,18 +1190,24 @@ function createRowNumberTool(adapter) {
|
|
|
1132
1190
|
input.table,
|
|
1133
1191
|
input.selectColumns
|
|
1134
1192
|
);
|
|
1135
|
-
const partition = input.partitionBy ? `PARTITION BY ${input.partitionBy}` : "";
|
|
1193
|
+
const partition = input.partitionBy ? `PARTITION BY ${sanitizePartitionBy(input.partitionBy)}` : "";
|
|
1194
|
+
const orderByExpr = sanitizeOrderByExpr(input.orderBy);
|
|
1136
1195
|
let sql = `
|
|
1137
1196
|
SELECT ${columns},
|
|
1138
|
-
ROW_NUMBER() OVER (${partition} ORDER BY ${
|
|
1139
|
-
FROM
|
|
1197
|
+
ROW_NUMBER() OVER (${partition} ORDER BY ${orderByExpr}) as row_number
|
|
1198
|
+
FROM ${sanitizeIdentifier(input.table)}
|
|
1140
1199
|
`;
|
|
1141
|
-
if (input.
|
|
1142
|
-
|
|
1143
|
-
|
|
1200
|
+
if (input.conditions) {
|
|
1201
|
+
const { sql: whereSql, params: whereParams } = buildWhereClause(
|
|
1202
|
+
input.conditions
|
|
1203
|
+
);
|
|
1204
|
+
if (whereSql !== "") {
|
|
1205
|
+
sql += ` WHERE ${whereSql}`;
|
|
1206
|
+
queryParams.push(...whereParams);
|
|
1207
|
+
}
|
|
1144
1208
|
}
|
|
1145
1209
|
sql += ` LIMIT ${input.limit}`;
|
|
1146
|
-
const result = await adapter.executeReadQuery(sql);
|
|
1210
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
1147
1211
|
const response = {
|
|
1148
1212
|
success: true,
|
|
1149
1213
|
rowCount: result.rows?.length ?? 0,
|
|
@@ -1169,6 +1233,7 @@ function createRankTool(adapter) {
|
|
|
1169
1233
|
handler: async (params, _context) => {
|
|
1170
1234
|
try {
|
|
1171
1235
|
const input = RankSchema.parse(params);
|
|
1236
|
+
const queryParams = [];
|
|
1172
1237
|
await validateTableExists2(adapter, input.table);
|
|
1173
1238
|
await validateOrderByColumns(adapter, input.table, input.orderBy);
|
|
1174
1239
|
const { columnList: columns, hint } = await resolveSelectColumns(
|
|
@@ -1176,19 +1241,25 @@ function createRankTool(adapter) {
|
|
|
1176
1241
|
input.table,
|
|
1177
1242
|
input.selectColumns
|
|
1178
1243
|
);
|
|
1179
|
-
const partition = input.partitionBy ? `PARTITION BY ${input.partitionBy}` : "";
|
|
1244
|
+
const partition = input.partitionBy ? `PARTITION BY ${sanitizePartitionBy(input.partitionBy)}` : "";
|
|
1180
1245
|
const rankFunc = input.rankType.toUpperCase();
|
|
1246
|
+
const orderByExpr = sanitizeOrderByExpr(input.orderBy);
|
|
1181
1247
|
let sql = `
|
|
1182
1248
|
SELECT ${columns},
|
|
1183
|
-
${rankFunc}() OVER (${partition} ORDER BY ${
|
|
1184
|
-
FROM
|
|
1249
|
+
${rankFunc}() OVER (${partition} ORDER BY ${orderByExpr}) as ${input.rankType}
|
|
1250
|
+
FROM ${sanitizeIdentifier(input.table)}
|
|
1185
1251
|
`;
|
|
1186
|
-
if (input.
|
|
1187
|
-
|
|
1188
|
-
|
|
1252
|
+
if (input.conditions) {
|
|
1253
|
+
const { sql: whereSql, params: whereParams } = buildWhereClause(
|
|
1254
|
+
input.conditions
|
|
1255
|
+
);
|
|
1256
|
+
if (whereSql !== "") {
|
|
1257
|
+
sql += ` WHERE ${whereSql}`;
|
|
1258
|
+
queryParams.push(...whereParams);
|
|
1259
|
+
}
|
|
1189
1260
|
}
|
|
1190
1261
|
sql += ` LIMIT ${input.limit}`;
|
|
1191
|
-
const result = await adapter.executeReadQuery(sql);
|
|
1262
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
1192
1263
|
const response = {
|
|
1193
1264
|
success: true,
|
|
1194
1265
|
rankType: input.rankType,
|
|
@@ -1214,7 +1285,10 @@ function createLagLeadTool(adapter) {
|
|
|
1214
1285
|
requiredScopes: ["read"],
|
|
1215
1286
|
handler: async (params, _context) => {
|
|
1216
1287
|
try {
|
|
1217
|
-
const input = LagLeadSchema.parse(
|
|
1288
|
+
const input = LagLeadSchema.parse(
|
|
1289
|
+
resolveAliases(params, { valueColumn: "column" })
|
|
1290
|
+
);
|
|
1291
|
+
const queryParams = [];
|
|
1218
1292
|
const normalizedDirection = input.direction.toLowerCase();
|
|
1219
1293
|
if (!VALID_DIRECTIONS.includes(
|
|
1220
1294
|
normalizedDirection
|
|
@@ -1236,20 +1310,30 @@ function createLagLeadTool(adapter) {
|
|
|
1236
1310
|
input.selectColumns,
|
|
1237
1311
|
input.column
|
|
1238
1312
|
);
|
|
1239
|
-
const partition = input.partitionBy ? `PARTITION BY ${input.partitionBy}` : "";
|
|
1313
|
+
const partition = input.partitionBy ? `PARTITION BY ${sanitizePartitionBy(input.partitionBy)}` : "";
|
|
1240
1314
|
const func = normalizedDirection.toUpperCase();
|
|
1241
|
-
|
|
1315
|
+
let defaultVal = "";
|
|
1316
|
+
if (input.defaultValue !== void 0) {
|
|
1317
|
+
validateDefaultValue(input.defaultValue);
|
|
1318
|
+
defaultVal = `, ${input.defaultValue}`;
|
|
1319
|
+
}
|
|
1320
|
+
const orderByExpr = sanitizeOrderByExpr(input.orderBy);
|
|
1242
1321
|
let sql = `
|
|
1243
1322
|
SELECT ${columns},
|
|
1244
|
-
${func}(
|
|
1245
|
-
FROM
|
|
1323
|
+
${func}(${sanitizeIdentifier(input.column)}, ${input.offset}${defaultVal}) OVER (${partition} ORDER BY ${orderByExpr}) as ${normalizedDirection}_value
|
|
1324
|
+
FROM ${sanitizeIdentifier(input.table)}
|
|
1246
1325
|
`;
|
|
1247
|
-
if (input.
|
|
1248
|
-
|
|
1249
|
-
|
|
1326
|
+
if (input.conditions) {
|
|
1327
|
+
const { sql: whereSql, params: whereParams } = buildWhereClause(
|
|
1328
|
+
input.conditions
|
|
1329
|
+
);
|
|
1330
|
+
if (whereSql !== "") {
|
|
1331
|
+
sql += ` WHERE ${whereSql}`;
|
|
1332
|
+
queryParams.push(...whereParams);
|
|
1333
|
+
}
|
|
1250
1334
|
}
|
|
1251
1335
|
sql += ` LIMIT ${input.limit}`;
|
|
1252
|
-
const result = await adapter.executeReadQuery(sql);
|
|
1336
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
1253
1337
|
const response = {
|
|
1254
1338
|
success: true,
|
|
1255
1339
|
direction: normalizedDirection,
|
|
@@ -1275,6 +1359,7 @@ function createRunningTotalTool(adapter) {
|
|
|
1275
1359
|
annotations: readOnly("Window Running Total"),
|
|
1276
1360
|
requiredScopes: ["read"],
|
|
1277
1361
|
handler: async (params, _context) => {
|
|
1362
|
+
const queryParams = [];
|
|
1278
1363
|
try {
|
|
1279
1364
|
const input = RunningTotalSchema.parse(
|
|
1280
1365
|
resolveAliases(params, { valueColumn: "column" })
|
|
@@ -1288,18 +1373,24 @@ function createRunningTotalTool(adapter) {
|
|
|
1288
1373
|
input.selectColumns,
|
|
1289
1374
|
input.column
|
|
1290
1375
|
);
|
|
1291
|
-
const partition = input.partitionBy ? `PARTITION BY ${input.partitionBy}` : "";
|
|
1376
|
+
const partition = input.partitionBy ? `PARTITION BY ${sanitizePartitionBy(input.partitionBy)}` : "";
|
|
1377
|
+
const orderByExpr = sanitizeOrderByExpr(input.orderBy);
|
|
1292
1378
|
let sql = `
|
|
1293
1379
|
SELECT ${columns},
|
|
1294
|
-
SUM(
|
|
1295
|
-
FROM
|
|
1380
|
+
SUM(${sanitizeIdentifier(input.column)}) OVER (${partition} ORDER BY ${orderByExpr} ROWS UNBOUNDED PRECEDING) as running_total
|
|
1381
|
+
FROM ${sanitizeIdentifier(input.table)}
|
|
1296
1382
|
`;
|
|
1297
|
-
if (input.
|
|
1298
|
-
|
|
1299
|
-
|
|
1383
|
+
if (input.conditions) {
|
|
1384
|
+
const { sql: whereSql, params: whereParams } = buildWhereClause(
|
|
1385
|
+
input.conditions
|
|
1386
|
+
);
|
|
1387
|
+
if (whereSql !== "") {
|
|
1388
|
+
sql += ` WHERE ${whereSql}`;
|
|
1389
|
+
queryParams.push(...whereParams);
|
|
1390
|
+
}
|
|
1300
1391
|
}
|
|
1301
1392
|
sql += ` LIMIT ${input.limit}`;
|
|
1302
|
-
const result = await adapter.executeReadQuery(sql);
|
|
1393
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
1303
1394
|
const response = {
|
|
1304
1395
|
success: true,
|
|
1305
1396
|
valueColumn: input.column,
|
|
@@ -1324,19 +1415,11 @@ function createMovingAverageTool(adapter) {
|
|
|
1324
1415
|
annotations: readOnly("Window Moving Average"),
|
|
1325
1416
|
requiredScopes: ["read"],
|
|
1326
1417
|
handler: async (params, _context) => {
|
|
1418
|
+
const queryParams = [];
|
|
1327
1419
|
try {
|
|
1328
1420
|
const input = MovingAverageSchema.parse(
|
|
1329
1421
|
resolveAliases(params, { valueColumn: "column" })
|
|
1330
1422
|
);
|
|
1331
|
-
if (input.windowSize === void 0) {
|
|
1332
|
-
return {
|
|
1333
|
-
success: false,
|
|
1334
|
-
error: "'windowSize' is required",
|
|
1335
|
-
code: "VALIDATION_ERROR",
|
|
1336
|
-
category: "validation",
|
|
1337
|
-
recoverable: false
|
|
1338
|
-
};
|
|
1339
|
-
}
|
|
1340
1423
|
await validateTableExists2(adapter, input.table);
|
|
1341
1424
|
await validateColumnInTable(adapter, input.table, input.column);
|
|
1342
1425
|
await validateOrderByColumns(adapter, input.table, input.orderBy);
|
|
@@ -1346,19 +1429,25 @@ function createMovingAverageTool(adapter) {
|
|
|
1346
1429
|
input.selectColumns,
|
|
1347
1430
|
input.column
|
|
1348
1431
|
);
|
|
1349
|
-
const partition = input.partitionBy ? `PARTITION BY ${input.partitionBy}` : "";
|
|
1432
|
+
const partition = input.partitionBy ? `PARTITION BY ${sanitizePartitionBy(input.partitionBy)}` : "";
|
|
1350
1433
|
const preceding = input.windowSize - 1;
|
|
1434
|
+
const orderByExpr = sanitizeOrderByExpr(input.orderBy);
|
|
1351
1435
|
let sql = `
|
|
1352
1436
|
SELECT ${columns},
|
|
1353
|
-
AVG(
|
|
1354
|
-
FROM
|
|
1437
|
+
AVG(${sanitizeIdentifier(input.column)}) OVER (${partition} ORDER BY ${orderByExpr} ROWS BETWEEN ${preceding} PRECEDING AND CURRENT ROW) as moving_avg
|
|
1438
|
+
FROM ${sanitizeIdentifier(input.table)}
|
|
1355
1439
|
`;
|
|
1356
|
-
if (input.
|
|
1357
|
-
|
|
1358
|
-
|
|
1440
|
+
if (input.conditions) {
|
|
1441
|
+
const { sql: whereSql, params: whereParams } = buildWhereClause(
|
|
1442
|
+
input.conditions
|
|
1443
|
+
);
|
|
1444
|
+
if (whereSql !== "") {
|
|
1445
|
+
sql += ` WHERE ${whereSql}`;
|
|
1446
|
+
queryParams.push(...whereParams);
|
|
1447
|
+
}
|
|
1359
1448
|
}
|
|
1360
1449
|
sql += ` LIMIT ${input.limit}`;
|
|
1361
|
-
const result = await adapter.executeReadQuery(sql);
|
|
1450
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
1362
1451
|
const response = {
|
|
1363
1452
|
success: true,
|
|
1364
1453
|
valueColumn: input.column,
|
|
@@ -1386,15 +1475,7 @@ function createNtileTool(adapter) {
|
|
|
1386
1475
|
handler: async (params, _context) => {
|
|
1387
1476
|
try {
|
|
1388
1477
|
const input = NtileSchema.parse(params);
|
|
1389
|
-
|
|
1390
|
-
return {
|
|
1391
|
-
success: false,
|
|
1392
|
-
error: "'buckets' is required",
|
|
1393
|
-
code: "VALIDATION_ERROR",
|
|
1394
|
-
category: "validation",
|
|
1395
|
-
recoverable: false
|
|
1396
|
-
};
|
|
1397
|
-
}
|
|
1478
|
+
const queryParams = [];
|
|
1398
1479
|
await validateTableExists2(adapter, input.table);
|
|
1399
1480
|
await validateOrderByColumns(adapter, input.table, input.orderBy);
|
|
1400
1481
|
const { columnList: columns, hint } = await resolveSelectColumns(
|
|
@@ -1402,18 +1483,24 @@ function createNtileTool(adapter) {
|
|
|
1402
1483
|
input.table,
|
|
1403
1484
|
input.selectColumns
|
|
1404
1485
|
);
|
|
1405
|
-
const partition = input.partitionBy ? `PARTITION BY ${input.partitionBy}` : "";
|
|
1486
|
+
const partition = input.partitionBy ? `PARTITION BY ${sanitizePartitionBy(input.partitionBy)}` : "";
|
|
1487
|
+
const orderByExpr = sanitizeOrderByExpr(input.orderBy);
|
|
1406
1488
|
let sql = `
|
|
1407
1489
|
SELECT ${columns},
|
|
1408
|
-
NTILE(${input.buckets}) OVER (${partition} ORDER BY ${
|
|
1409
|
-
FROM
|
|
1490
|
+
NTILE(${input.buckets}) OVER (${partition} ORDER BY ${orderByExpr}) as ntile
|
|
1491
|
+
FROM ${sanitizeIdentifier(input.table)}
|
|
1410
1492
|
`;
|
|
1411
|
-
if (input.
|
|
1412
|
-
|
|
1413
|
-
|
|
1493
|
+
if (input.conditions) {
|
|
1494
|
+
const { sql: whereSql, params: whereParams } = buildWhereClause(
|
|
1495
|
+
input.conditions
|
|
1496
|
+
);
|
|
1497
|
+
if (whereSql !== "") {
|
|
1498
|
+
sql += ` WHERE ${whereSql}`;
|
|
1499
|
+
queryParams.push(...whereParams);
|
|
1500
|
+
}
|
|
1414
1501
|
}
|
|
1415
1502
|
sql += ` LIMIT ${input.limit}`;
|
|
1416
|
-
const result = await adapter.executeReadQuery(sql);
|
|
1503
|
+
const result = await adapter.executeReadQuery(sql, queryParams);
|
|
1417
1504
|
const response = {
|
|
1418
1505
|
success: true,
|
|
1419
1506
|
buckets: input.buckets,
|
|
@@ -1428,7 +1515,14 @@ function createNtileTool(adapter) {
|
|
|
1428
1515
|
}
|
|
1429
1516
|
};
|
|
1430
1517
|
}
|
|
1431
|
-
var coerceNumber2 = (val) =>
|
|
1518
|
+
var coerceNumber2 = (val) => {
|
|
1519
|
+
if (typeof val === "string") {
|
|
1520
|
+
if (val.trim() === "") return void 0;
|
|
1521
|
+
const num = Number(val);
|
|
1522
|
+
return isNaN(num) ? val : num;
|
|
1523
|
+
}
|
|
1524
|
+
return val;
|
|
1525
|
+
};
|
|
1432
1526
|
var coerceBoolean = (val) => typeof val === "string" ? val === "true" ? true : val === "false" ? false : void 0 : val;
|
|
1433
1527
|
function createEnumCoercer(validValues) {
|
|
1434
1528
|
return (val) => typeof val === "string" && validValues.includes(val) ? val : typeof val === "string" ? void 0 : val;
|
|
@@ -1459,9 +1553,20 @@ var VALID_OPERATIONS = [
|
|
|
1459
1553
|
"envelope",
|
|
1460
1554
|
"simplify"
|
|
1461
1555
|
];
|
|
1556
|
+
var VALID_COLUMN_TYPES = [
|
|
1557
|
+
"TEXT",
|
|
1558
|
+
"INTEGER",
|
|
1559
|
+
"REAL",
|
|
1560
|
+
"BLOB",
|
|
1561
|
+
"NUMERIC",
|
|
1562
|
+
"VARCHAR",
|
|
1563
|
+
"BOOLEAN",
|
|
1564
|
+
"DATE",
|
|
1565
|
+
"DATETIME",
|
|
1566
|
+
"TIMESTAMP"
|
|
1567
|
+
];
|
|
1462
1568
|
var coerceGeometryType = createEnumCoercer(VALID_GEOMETRY_TYPES);
|
|
1463
1569
|
var LoadSpatialiteSchema = z.object({
|
|
1464
|
-
extensionPath: z.string().optional().describe("Custom path to mod_spatialite extension"),
|
|
1465
1570
|
forceReload: z.preprocess(
|
|
1466
1571
|
coerceBoolean,
|
|
1467
1572
|
z.boolean().optional().default(false).describe("Force reload if already loaded")
|
|
@@ -1489,7 +1594,7 @@ var CreateSpatialTableSchema = z.object({
|
|
|
1489
1594
|
additionalColumns: z.array(
|
|
1490
1595
|
z.object({
|
|
1491
1596
|
name: z.string(),
|
|
1492
|
-
type: z.
|
|
1597
|
+
type: z.enum(VALID_COLUMN_TYPES).optional().default("TEXT")
|
|
1493
1598
|
})
|
|
1494
1599
|
).optional().default([]).describe("Additional non-spatial columns")
|
|
1495
1600
|
});
|
|
@@ -1559,8 +1664,9 @@ var SpatialImportSchema = z.object({
|
|
|
1559
1664
|
),
|
|
1560
1665
|
additionalData: z.record(z.string(), z.unknown()).optional().describe("Additional column values")
|
|
1561
1666
|
});
|
|
1562
|
-
|
|
1563
|
-
|
|
1667
|
+
var require2 = createRequire(import.meta.url);
|
|
1668
|
+
var __filename$1 = fileURLToPath(import.meta.url);
|
|
1669
|
+
var __dirname$1 = path2.dirname(__filename$1);
|
|
1564
1670
|
var SPATIALITE_PATHS = [
|
|
1565
1671
|
process.env["SPATIALITE_PATH"],
|
|
1566
1672
|
"mod_spatialite",
|
|
@@ -1571,20 +1677,27 @@ var SPATIALITE_PATHS = [
|
|
|
1571
1677
|
"/usr/local/lib/mod_spatialite.dylib"
|
|
1572
1678
|
].filter((p) => Boolean(p));
|
|
1573
1679
|
var loadedDatabases = /* @__PURE__ */ new WeakSet();
|
|
1574
|
-
function tryLoadSpatialite(adapter
|
|
1680
|
+
function tryLoadSpatialite(adapter) {
|
|
1575
1681
|
const db = adapter.getDatabase();
|
|
1576
1682
|
if (db === null) {
|
|
1577
1683
|
return { success: false, error: "Database not connected" };
|
|
1578
1684
|
}
|
|
1579
|
-
const paths =
|
|
1580
|
-
const chosenPathForEnv =
|
|
1685
|
+
const paths = SPATIALITE_PATHS;
|
|
1686
|
+
const chosenPathForEnv = process.env["SPATIALITE_PATH"];
|
|
1687
|
+
let dllCookie = null;
|
|
1688
|
+
let win32Dll = null;
|
|
1581
1689
|
if (process.platform === "win32" && chosenPathForEnv) {
|
|
1582
1690
|
const looksLikeFsPath = chosenPathForEnv.includes("/") || chosenPathForEnv.includes("\\");
|
|
1583
1691
|
if (looksLikeFsPath) {
|
|
1584
1692
|
const extensionDir = chosenPathForEnv.replace(/[/\\][^/\\]+$/, "");
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1693
|
+
try {
|
|
1694
|
+
const addonPath = path2.resolve(
|
|
1695
|
+
__dirname$1,
|
|
1696
|
+
"../../../../../build/Release/win32_dll.node"
|
|
1697
|
+
);
|
|
1698
|
+
win32Dll = require2(addonPath);
|
|
1699
|
+
dllCookie = win32Dll.addDllDirectory(extensionDir);
|
|
1700
|
+
} catch {
|
|
1588
1701
|
}
|
|
1589
1702
|
}
|
|
1590
1703
|
}
|
|
@@ -1593,10 +1706,16 @@ function tryLoadSpatialite(adapter, customPath) {
|
|
|
1593
1706
|
db.loadExtension(candidatePath);
|
|
1594
1707
|
db.exec("SELECT InitSpatialMetaData(1)");
|
|
1595
1708
|
loadedDatabases.add(db);
|
|
1709
|
+
if (win32Dll !== null && dllCookie !== null) {
|
|
1710
|
+
win32Dll.removeDllDirectory(dllCookie);
|
|
1711
|
+
}
|
|
1596
1712
|
return { success: true, path: candidatePath };
|
|
1597
1713
|
} catch {
|
|
1598
1714
|
}
|
|
1599
1715
|
}
|
|
1716
|
+
if (win32Dll !== null && dllCookie !== null) {
|
|
1717
|
+
win32Dll.removeDllDirectory(dllCookie);
|
|
1718
|
+
}
|
|
1600
1719
|
return {
|
|
1601
1720
|
success: false,
|
|
1602
1721
|
error: "SpatiaLite extension not found. Install mod_spatialite and set SPATIALITE_PATH environment variable."
|
|
@@ -1646,7 +1765,7 @@ function createLoadSpatialiteTool(adapter) {
|
|
|
1646
1765
|
alreadyLoaded: true
|
|
1647
1766
|
});
|
|
1648
1767
|
}
|
|
1649
|
-
const result = tryLoadSpatialite(adapter
|
|
1768
|
+
const result = tryLoadSpatialite(adapter);
|
|
1650
1769
|
if (result.success) {
|
|
1651
1770
|
return Promise.resolve({
|
|
1652
1771
|
success: true,
|
|
@@ -1681,7 +1800,9 @@ function createSpatialTableTool(adapter) {
|
|
|
1681
1800
|
try {
|
|
1682
1801
|
const input = CreateSpatialTableSchema.parse(params);
|
|
1683
1802
|
ensureSpatialite(adapter);
|
|
1684
|
-
|
|
1803
|
+
try {
|
|
1804
|
+
validateIdentifier(input.tableName);
|
|
1805
|
+
} catch {
|
|
1685
1806
|
return {
|
|
1686
1807
|
success: false,
|
|
1687
1808
|
error: `Invalid table name: '${input.tableName}'`,
|
|
@@ -1690,8 +1811,20 @@ function createSpatialTableTool(adapter) {
|
|
|
1690
1811
|
recoverable: false
|
|
1691
1812
|
};
|
|
1692
1813
|
}
|
|
1814
|
+
try {
|
|
1815
|
+
validateIdentifier(input.geometryColumn);
|
|
1816
|
+
} catch {
|
|
1817
|
+
return {
|
|
1818
|
+
success: false,
|
|
1819
|
+
error: `Invalid geometry column name: '${input.geometryColumn}'`,
|
|
1820
|
+
code: "VALIDATION_ERROR",
|
|
1821
|
+
category: "validation",
|
|
1822
|
+
recoverable: false
|
|
1823
|
+
};
|
|
1824
|
+
}
|
|
1693
1825
|
const existsCheck = await adapter.executeReadQuery(
|
|
1694
|
-
`SELECT name FROM sqlite_master WHERE type='table' AND name
|
|
1826
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
|
1827
|
+
[input.tableName]
|
|
1695
1828
|
);
|
|
1696
1829
|
const alreadyExists = existsCheck.rows != null && existsCheck.rows.length > 0;
|
|
1697
1830
|
if (alreadyExists) {
|
|
@@ -1704,7 +1837,9 @@ function createSpatialTableTool(adapter) {
|
|
|
1704
1837
|
}
|
|
1705
1838
|
const columns = ["id INTEGER PRIMARY KEY AUTOINCREMENT"];
|
|
1706
1839
|
for (const col of input.additionalColumns) {
|
|
1707
|
-
|
|
1840
|
+
try {
|
|
1841
|
+
validateIdentifier(col.name);
|
|
1842
|
+
} catch {
|
|
1708
1843
|
return {
|
|
1709
1844
|
success: false,
|
|
1710
1845
|
error: `Invalid column name: '${col.name}'`,
|
|
@@ -1713,10 +1848,10 @@ function createSpatialTableTool(adapter) {
|
|
|
1713
1848
|
recoverable: false
|
|
1714
1849
|
};
|
|
1715
1850
|
}
|
|
1716
|
-
columns.push(
|
|
1851
|
+
columns.push(`${sanitizeIdentifier(col.name)} ${col.type}`);
|
|
1717
1852
|
}
|
|
1718
1853
|
await adapter.executeWriteQuery(
|
|
1719
|
-
`CREATE TABLE
|
|
1854
|
+
`CREATE TABLE ${sanitizeIdentifier(input.tableName)} (${columns.join(", ")})`
|
|
1720
1855
|
);
|
|
1721
1856
|
const addResult = await adapter.executeReadQuery(
|
|
1722
1857
|
`SELECT AddGeometryColumn('${input.tableName}', '${input.geometryColumn}', ${input.srid}, '${input.geometryType}', 'XY')`
|
|
@@ -1795,7 +1930,9 @@ function createSpatialIndexTool(adapter) {
|
|
|
1795
1930
|
try {
|
|
1796
1931
|
const input = SpatialIndexSchema.parse(params);
|
|
1797
1932
|
ensureSpatialite(adapter);
|
|
1798
|
-
|
|
1933
|
+
try {
|
|
1934
|
+
validateIdentifier(input.tableName);
|
|
1935
|
+
} catch {
|
|
1799
1936
|
return {
|
|
1800
1937
|
success: false,
|
|
1801
1938
|
error: `Invalid table name: '${input.tableName}'`,
|
|
@@ -1813,8 +1950,20 @@ function createSpatialIndexTool(adapter) {
|
|
|
1813
1950
|
recoverable: false
|
|
1814
1951
|
};
|
|
1815
1952
|
}
|
|
1953
|
+
try {
|
|
1954
|
+
validateIdentifier(input.geometryColumn);
|
|
1955
|
+
} catch {
|
|
1956
|
+
return {
|
|
1957
|
+
success: false,
|
|
1958
|
+
error: `Invalid geometry column name: '${input.geometryColumn}'`,
|
|
1959
|
+
code: "VALIDATION_ERROR",
|
|
1960
|
+
category: "validation",
|
|
1961
|
+
recoverable: false
|
|
1962
|
+
};
|
|
1963
|
+
}
|
|
1816
1964
|
const tableCheck = await adapter.executeReadQuery(
|
|
1817
|
-
`SELECT name FROM sqlite_master WHERE type='table' AND name
|
|
1965
|
+
`SELECT name FROM sqlite_master WHERE type='table' AND name=?`,
|
|
1966
|
+
[input.tableName]
|
|
1818
1967
|
);
|
|
1819
1968
|
if (!tableCheck.rows || tableCheck.rows.length === 0) {
|
|
1820
1969
|
return {
|
|
@@ -1956,6 +2105,7 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
1956
2105
|
requiredScopes: ["read"],
|
|
1957
2106
|
annotations: readOnly("SpatiaLite Analyze"),
|
|
1958
2107
|
handler: async (params, _context) => {
|
|
2108
|
+
const queryParams = [];
|
|
1959
2109
|
try {
|
|
1960
2110
|
const input = SpatialAnalysisSchema.parse(params);
|
|
1961
2111
|
ensureSpatialite(adapter);
|
|
@@ -1970,7 +2120,9 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
1970
2120
|
recoverable: false
|
|
1971
2121
|
};
|
|
1972
2122
|
}
|
|
1973
|
-
|
|
2123
|
+
try {
|
|
2124
|
+
validateIdentifier(input.sourceTable);
|
|
2125
|
+
} catch {
|
|
1974
2126
|
return {
|
|
1975
2127
|
success: false,
|
|
1976
2128
|
error: `Invalid source table name: '${input.sourceTable}'`,
|
|
@@ -1979,10 +2131,25 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
1979
2131
|
recoverable: false
|
|
1980
2132
|
};
|
|
1981
2133
|
}
|
|
1982
|
-
if (input.targetTable
|
|
2134
|
+
if (input.targetTable) {
|
|
2135
|
+
try {
|
|
2136
|
+
validateIdentifier(input.targetTable);
|
|
2137
|
+
} catch {
|
|
2138
|
+
return {
|
|
2139
|
+
success: false,
|
|
2140
|
+
error: `Invalid target table name: '${input.targetTable}'`,
|
|
2141
|
+
code: "VALIDATION_ERROR",
|
|
2142
|
+
category: "validation",
|
|
2143
|
+
recoverable: false
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
}
|
|
2147
|
+
try {
|
|
2148
|
+
validateIdentifier(input.geometryColumn);
|
|
2149
|
+
} catch {
|
|
1983
2150
|
return {
|
|
1984
2151
|
success: false,
|
|
1985
|
-
error: `Invalid
|
|
2152
|
+
error: `Invalid geometry column name: '${input.geometryColumn}'`,
|
|
1986
2153
|
code: "VALIDATION_ERROR",
|
|
1987
2154
|
category: "validation",
|
|
1988
2155
|
recoverable: false
|
|
@@ -1990,15 +2157,18 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
1990
2157
|
}
|
|
1991
2158
|
let query;
|
|
1992
2159
|
switch (input.analysisType) {
|
|
1993
|
-
case "spatial_extent":
|
|
2160
|
+
case "spatial_extent": {
|
|
2161
|
+
const geomCol = sanitizeIdentifier(input.geometryColumn);
|
|
2162
|
+
const srcTable = sanitizeIdentifier(input.sourceTable);
|
|
1994
2163
|
query = `SELECT
|
|
1995
|
-
MbrMinX(Extent(
|
|
1996
|
-
MbrMinY(Extent(
|
|
1997
|
-
MbrMaxX(Extent(
|
|
1998
|
-
MbrMaxY(Extent(
|
|
2164
|
+
MbrMinX(Extent(${geomCol})) as min_x,
|
|
2165
|
+
MbrMinY(Extent(${geomCol})) as min_y,
|
|
2166
|
+
MbrMaxX(Extent(${geomCol})) as max_x,
|
|
2167
|
+
MbrMaxY(Extent(${geomCol})) as max_y,
|
|
1999
2168
|
COUNT(*) as feature_count
|
|
2000
|
-
FROM
|
|
2169
|
+
FROM ${srcTable}`;
|
|
2001
2170
|
break;
|
|
2171
|
+
}
|
|
2002
2172
|
case "nearest_neighbor": {
|
|
2003
2173
|
if (!input.targetTable) {
|
|
2004
2174
|
return {
|
|
@@ -2009,13 +2179,16 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
2009
2179
|
recoverable: false
|
|
2010
2180
|
};
|
|
2011
2181
|
}
|
|
2182
|
+
const geomCol = sanitizeIdentifier(input.geometryColumn);
|
|
2183
|
+
const srcTable = sanitizeIdentifier(input.sourceTable);
|
|
2184
|
+
const tgtTable = sanitizeIdentifier(input.targetTable);
|
|
2012
2185
|
const sameTable = input.sourceTable === input.targetTable;
|
|
2013
2186
|
const selfFilter = sameTable && input.excludeSelf ? "WHERE s.id != t.id" : "";
|
|
2014
|
-
const geomColumns = input.includeGeometry ? `, AsText(s
|
|
2187
|
+
const geomColumns = input.includeGeometry ? `, AsText(s.${geomCol}) as source_geom, AsText(t.${geomCol}) as target_geom` : "";
|
|
2015
2188
|
query = `SELECT
|
|
2016
2189
|
s.id as source_id, t.id as target_id,
|
|
2017
|
-
ST_Distance(s
|
|
2018
|
-
FROM
|
|
2190
|
+
ST_Distance(s.${geomCol}, t.${geomCol}) as distance${geomColumns}
|
|
2191
|
+
FROM ${srcTable} s, ${tgtTable} t
|
|
2019
2192
|
${selfFilter}
|
|
2020
2193
|
ORDER BY distance LIMIT ${input.limit}`;
|
|
2021
2194
|
break;
|
|
@@ -2030,11 +2203,14 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
2030
2203
|
recoverable: false
|
|
2031
2204
|
};
|
|
2032
2205
|
}
|
|
2033
|
-
const
|
|
2206
|
+
const geomCol = sanitizeIdentifier(input.geometryColumn);
|
|
2207
|
+
const srcTable = sanitizeIdentifier(input.sourceTable);
|
|
2208
|
+
const tgtTable = sanitizeIdentifier(input.targetTable);
|
|
2209
|
+
const geomCols = input.includeGeometry ? `, AsText(s.${geomCol}) as source_geom, AsText(t.${geomCol}) as target_geom` : "";
|
|
2034
2210
|
query = `SELECT
|
|
2035
2211
|
s.id as source_id, t.id as target_id${geomCols}
|
|
2036
|
-
FROM
|
|
2037
|
-
WHERE ST_Within(s
|
|
2212
|
+
FROM ${srcTable} s, ${tgtTable} t
|
|
2213
|
+
WHERE ST_Within(s.${geomCol}, t.${geomCol})
|
|
2038
2214
|
LIMIT ${input.limit}`;
|
|
2039
2215
|
break;
|
|
2040
2216
|
}
|
|
@@ -2042,9 +2218,12 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
2042
2218
|
const dmTarget = input.targetTable ?? input.sourceTable;
|
|
2043
2219
|
const dmSameTable = dmTarget === input.sourceTable;
|
|
2044
2220
|
const dmFilter = dmSameTable ? "WHERE a.id < b.id" : "";
|
|
2221
|
+
const geomCol = sanitizeIdentifier(input.geometryColumn);
|
|
2222
|
+
const srcTable = sanitizeIdentifier(input.sourceTable);
|
|
2223
|
+
const dmTgtTable = sanitizeIdentifier(dmTarget);
|
|
2045
2224
|
query = `SELECT a.id as id1, b.id as id2,
|
|
2046
|
-
ST_Distance(a
|
|
2047
|
-
FROM
|
|
2225
|
+
ST_Distance(a.${geomCol}, b.${geomCol}) as distance
|
|
2226
|
+
FROM ${srcTable} a, ${dmTgtTable} b
|
|
2048
2227
|
${dmFilter}
|
|
2049
2228
|
ORDER BY distance LIMIT ${input.limit}`;
|
|
2050
2229
|
break;
|
|
@@ -2052,7 +2231,7 @@ function createSpatialAnalysisTool(adapter) {
|
|
|
2052
2231
|
default:
|
|
2053
2232
|
query = "SELECT 1";
|
|
2054
2233
|
}
|
|
2055
|
-
const result = await adapter.executeReadQuery(query);
|
|
2234
|
+
const result = await adapter.executeReadQuery(query, queryParams);
|
|
2056
2235
|
return {
|
|
2057
2236
|
success: true,
|
|
2058
2237
|
analysisType: input.analysisType,
|
|
@@ -2075,6 +2254,7 @@ function createGeometryTransformTool(adapter) {
|
|
|
2075
2254
|
requiredScopes: ["read"],
|
|
2076
2255
|
annotations: readOnly("SpatiaLite Transform"),
|
|
2077
2256
|
handler: async (params, _context) => {
|
|
2257
|
+
const queryParams = [];
|
|
2078
2258
|
try {
|
|
2079
2259
|
const input = GeometryTransformSchema.parse(params);
|
|
2080
2260
|
ensureSpatialite(adapter);
|
|
@@ -2090,71 +2270,69 @@ function createGeometryTransformTool(adapter) {
|
|
|
2090
2270
|
let query;
|
|
2091
2271
|
switch (input.operation) {
|
|
2092
2272
|
case "buffer": {
|
|
2093
|
-
const bufferGeom = `Buffer(GeomFromText(
|
|
2273
|
+
const bufferGeom = `Buffer(GeomFromText(?, CAST(? AS INTEGER)), ?)`;
|
|
2094
2274
|
const defaultTolerance = Math.max(1e-4, input.distance * 0.01);
|
|
2095
2275
|
const tolerance = input.simplifyTolerance ?? defaultTolerance;
|
|
2096
|
-
const finalGeom = tolerance > 0 ? `Simplify(${bufferGeom}, ${tolerance})` : bufferGeom;
|
|
2276
|
+
const finalGeom = tolerance > 0 ? `Simplify(${bufferGeom}, ${String(tolerance)})` : bufferGeom;
|
|
2097
2277
|
query = `SELECT AsText(${finalGeom}) as result`;
|
|
2278
|
+
queryParams.push(input.geometry1, input.srid, input.distance);
|
|
2098
2279
|
break;
|
|
2099
2280
|
}
|
|
2100
|
-
case "intersection":
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
}
|
|
2110
|
-
query = `SELECT AsText(Intersection(
|
|
2111
|
-
GeomFromText('${input.geometry1}', ${input.srid}),
|
|
2112
|
-
GeomFromText('${input.geometry2}', ${input.srid})
|
|
2113
|
-
)) as result`;
|
|
2281
|
+
case "intersection": {
|
|
2282
|
+
const intersectionGeom = `Intersection(GeomFromText(?, CAST(? AS INTEGER)), GeomFromText(?, CAST(? AS INTEGER)))`;
|
|
2283
|
+
query = `SELECT AsText(${intersectionGeom}) as result`;
|
|
2284
|
+
queryParams.push(
|
|
2285
|
+
input.geometry1,
|
|
2286
|
+
input.srid,
|
|
2287
|
+
input.geometry2,
|
|
2288
|
+
input.srid
|
|
2289
|
+
);
|
|
2114
2290
|
break;
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
query = `SELECT AsText(GUnion(
|
|
2126
|
-
GeomFromText('${input.geometry1}', ${input.srid}),
|
|
2127
|
-
GeomFromText('${input.geometry2}', ${input.srid})
|
|
2128
|
-
)) as result`;
|
|
2291
|
+
}
|
|
2292
|
+
case "union": {
|
|
2293
|
+
const unionGeom = `GUnion(GeomFromText(?, CAST(? AS INTEGER)), GeomFromText(?, CAST(? AS INTEGER)))`;
|
|
2294
|
+
query = `SELECT AsText(${unionGeom}) as result`;
|
|
2295
|
+
queryParams.push(
|
|
2296
|
+
input.geometry1,
|
|
2297
|
+
input.srid,
|
|
2298
|
+
input.geometry2,
|
|
2299
|
+
input.srid
|
|
2300
|
+
);
|
|
2129
2301
|
break;
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
query = `SELECT AsText(Difference(
|
|
2141
|
-
GeomFromText('${input.geometry1}', ${input.srid}),
|
|
2142
|
-
GeomFromText('${input.geometry2}', ${input.srid})
|
|
2143
|
-
)) as result`;
|
|
2302
|
+
}
|
|
2303
|
+
case "difference": {
|
|
2304
|
+
const differenceGeom = `Difference(GeomFromText(?, CAST(? AS INTEGER)), GeomFromText(?, CAST(? AS INTEGER)))`;
|
|
2305
|
+
query = `SELECT AsText(${differenceGeom}) as result`;
|
|
2306
|
+
queryParams.push(
|
|
2307
|
+
input.geometry1,
|
|
2308
|
+
input.srid,
|
|
2309
|
+
input.geometry2,
|
|
2310
|
+
input.srid
|
|
2311
|
+
);
|
|
2144
2312
|
break;
|
|
2145
|
-
|
|
2146
|
-
|
|
2313
|
+
}
|
|
2314
|
+
case "centroid": {
|
|
2315
|
+
const centroidGeom = `Centroid(GeomFromText(?, CAST(? AS INTEGER)))`;
|
|
2316
|
+
query = `SELECT AsText(${centroidGeom}) as result`;
|
|
2317
|
+
queryParams.push(input.geometry1, input.srid);
|
|
2147
2318
|
break;
|
|
2148
|
-
|
|
2149
|
-
|
|
2319
|
+
}
|
|
2320
|
+
case "envelope": {
|
|
2321
|
+
const envelopeGeom = `Envelope(GeomFromText(?, CAST(? AS INTEGER)))`;
|
|
2322
|
+
query = `SELECT AsText(${envelopeGeom}) as result`;
|
|
2323
|
+
queryParams.push(input.geometry1, input.srid);
|
|
2150
2324
|
break;
|
|
2151
|
-
|
|
2152
|
-
|
|
2325
|
+
}
|
|
2326
|
+
case "simplify": {
|
|
2327
|
+
const simplifyGeom = `Simplify(GeomFromText(?, CAST(? AS INTEGER)), ?)`;
|
|
2328
|
+
query = `SELECT AsText(${simplifyGeom}) as result`;
|
|
2329
|
+
queryParams.push(input.geometry1, input.srid, input.distance);
|
|
2153
2330
|
break;
|
|
2331
|
+
}
|
|
2154
2332
|
default:
|
|
2155
2333
|
query = "SELECT 1";
|
|
2156
2334
|
}
|
|
2157
|
-
const result = await adapter.executeReadQuery(query);
|
|
2335
|
+
const result = await adapter.executeReadQuery(query, queryParams);
|
|
2158
2336
|
const wktResult = result.rows?.[0]?.["result"];
|
|
2159
2337
|
if (wktResult === null || wktResult === void 0) {
|
|
2160
2338
|
return {
|
|
@@ -2184,7 +2362,7 @@ function createSpatialImportTool(adapter) {
|
|
|
2184
2362
|
inputSchema: SpatialImportSchema,
|
|
2185
2363
|
outputSchema: SpatialiteImportOutputSchema,
|
|
2186
2364
|
requiredScopes: ["write"],
|
|
2187
|
-
annotations:
|
|
2365
|
+
annotations: writeFs("SpatiaLite Import"),
|
|
2188
2366
|
handler: async (params, _context) => {
|
|
2189
2367
|
try {
|
|
2190
2368
|
const input = SpatialImportSchema.parse(params);
|
|
@@ -2198,7 +2376,9 @@ function createSpatialImportTool(adapter) {
|
|
|
2198
2376
|
recoverable: false
|
|
2199
2377
|
};
|
|
2200
2378
|
}
|
|
2201
|
-
|
|
2379
|
+
try {
|
|
2380
|
+
validateIdentifier(input.tableName);
|
|
2381
|
+
} catch {
|
|
2202
2382
|
return {
|
|
2203
2383
|
success: false,
|
|
2204
2384
|
error: `Invalid table name: '${input.tableName}'`,
|
|
@@ -2212,10 +2392,11 @@ function createSpatialImportTool(adapter) {
|
|
|
2212
2392
|
try {
|
|
2213
2393
|
JSON.parse(input.data);
|
|
2214
2394
|
const geojsonCheck = await adapter.executeReadQuery(
|
|
2215
|
-
`SELECT GeomFromGeoJSON(
|
|
2395
|
+
`SELECT ST_IsValid(GeomFromGeoJSON(?)) as valid`,
|
|
2396
|
+
[input.data]
|
|
2216
2397
|
);
|
|
2217
|
-
const
|
|
2218
|
-
if (
|
|
2398
|
+
const isValid2 = geojsonCheck.rows?.[0]?.["valid"];
|
|
2399
|
+
if (isValid2 !== 1) {
|
|
2219
2400
|
return {
|
|
2220
2401
|
success: false,
|
|
2221
2402
|
error: `Invalid GeoJSON geometry: could not be parsed by SpatiaLite (must be a valid Geometry object)`,
|
|
@@ -2225,9 +2406,8 @@ function createSpatialImportTool(adapter) {
|
|
|
2225
2406
|
};
|
|
2226
2407
|
}
|
|
2227
2408
|
const columns2 = ["geom"];
|
|
2228
|
-
const
|
|
2229
|
-
|
|
2230
|
-
];
|
|
2409
|
+
const placeholders2 = [`SetSRID(GeomFromGeoJSON(?), ?)`];
|
|
2410
|
+
const insertParams2 = [input.data, input.srid];
|
|
2231
2411
|
if (input.additionalData) {
|
|
2232
2412
|
for (const [key, value] of Object.entries(input.additionalData)) {
|
|
2233
2413
|
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
|
|
@@ -2239,14 +2419,16 @@ function createSpatialImportTool(adapter) {
|
|
|
2239
2419
|
recoverable: false
|
|
2240
2420
|
};
|
|
2241
2421
|
}
|
|
2242
|
-
columns2.push(
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
);
|
|
2422
|
+
columns2.push(sanitizeIdentifier(key));
|
|
2423
|
+
placeholders2.push("?");
|
|
2424
|
+
insertParams2.push(value);
|
|
2246
2425
|
}
|
|
2247
2426
|
}
|
|
2248
|
-
const sql2 = `INSERT INTO
|
|
2249
|
-
const insertResult2 = await adapter.executeWriteQuery(
|
|
2427
|
+
const sql2 = `INSERT INTO ${sanitizeIdentifier(input.tableName)} (${columns2.join(", ")}) VALUES (${placeholders2.join(", ")})`;
|
|
2428
|
+
const insertResult2 = await adapter.executeWriteQuery(
|
|
2429
|
+
sql2,
|
|
2430
|
+
insertParams2
|
|
2431
|
+
);
|
|
2250
2432
|
return {
|
|
2251
2433
|
success: true,
|
|
2252
2434
|
message: "GeoJSON geometry imported",
|
|
@@ -2265,10 +2447,11 @@ function createSpatialImportTool(adapter) {
|
|
|
2265
2447
|
wkt = input.data;
|
|
2266
2448
|
}
|
|
2267
2449
|
const wktCheck = await adapter.executeReadQuery(
|
|
2268
|
-
`SELECT GeomFromText(
|
|
2450
|
+
`SELECT ST_IsValid(GeomFromText(?, CAST(? AS INTEGER))) as valid`,
|
|
2451
|
+
[wkt, input.srid]
|
|
2269
2452
|
);
|
|
2270
|
-
const
|
|
2271
|
-
if (
|
|
2453
|
+
const isValid = wktCheck.rows?.[0]?.["valid"];
|
|
2454
|
+
if (isValid !== 1) {
|
|
2272
2455
|
return {
|
|
2273
2456
|
success: false,
|
|
2274
2457
|
error: `Invalid WKT geometry: '${wkt}' could not be parsed`,
|
|
@@ -2278,7 +2461,8 @@ function createSpatialImportTool(adapter) {
|
|
|
2278
2461
|
};
|
|
2279
2462
|
}
|
|
2280
2463
|
const columns = ["geom"];
|
|
2281
|
-
const
|
|
2464
|
+
const placeholders = [`GeomFromText(?, CAST(? AS INTEGER))`];
|
|
2465
|
+
const insertParams = [wkt, input.srid];
|
|
2282
2466
|
if (input.additionalData) {
|
|
2283
2467
|
for (const [key, value] of Object.entries(input.additionalData)) {
|
|
2284
2468
|
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) {
|
|
@@ -2290,14 +2474,13 @@ function createSpatialImportTool(adapter) {
|
|
|
2290
2474
|
recoverable: false
|
|
2291
2475
|
};
|
|
2292
2476
|
}
|
|
2293
|
-
columns.push(
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
);
|
|
2477
|
+
columns.push(sanitizeIdentifier(key));
|
|
2478
|
+
placeholders.push("?");
|
|
2479
|
+
insertParams.push(value);
|
|
2297
2480
|
}
|
|
2298
2481
|
}
|
|
2299
|
-
const sql = `INSERT INTO
|
|
2300
|
-
const insertResult = await adapter.executeWriteQuery(sql);
|
|
2482
|
+
const sql = `INSERT INTO ${sanitizeIdentifier(input.tableName)} (${columns.join(", ")}) VALUES (${placeholders.join(", ")})`;
|
|
2483
|
+
const insertResult = await adapter.executeWriteQuery(sql, insertParams);
|
|
2301
2484
|
return {
|
|
2302
2485
|
success: true,
|
|
2303
2486
|
message: "WKT geometry imported",
|
|
@@ -2358,16 +2541,16 @@ function getNativeToolDefinitions(adapter) {
|
|
|
2358
2541
|
function findProjectRoot(startDir) {
|
|
2359
2542
|
let dir = startDir;
|
|
2360
2543
|
for (let i = 0; i < 10; i++) {
|
|
2361
|
-
if (fs.existsSync(
|
|
2362
|
-
const parent =
|
|
2544
|
+
if (fs.existsSync(path2.join(dir, "package.json"))) return dir;
|
|
2545
|
+
const parent = path2.dirname(dir);
|
|
2363
2546
|
if (parent === dir) break;
|
|
2364
2547
|
dir = parent;
|
|
2365
2548
|
}
|
|
2366
2549
|
return startDir;
|
|
2367
2550
|
}
|
|
2368
2551
|
var __moduleFilename = fileURLToPath(import.meta.url);
|
|
2369
|
-
var PROJECT_ROOT = findProjectRoot(
|
|
2370
|
-
var EXTENSIONS_DIR =
|
|
2552
|
+
var PROJECT_ROOT = findProjectRoot(path2.dirname(__moduleFilename));
|
|
2553
|
+
var EXTENSIONS_DIR = path2.join(PROJECT_ROOT, "extensions");
|
|
2371
2554
|
function tryLoadExtension(db, name, envVar, candidates, log2) {
|
|
2372
2555
|
for (const extPath of candidates) {
|
|
2373
2556
|
try {
|
|
@@ -2387,12 +2570,12 @@ function loadSpatialite(db, log2) {
|
|
|
2387
2570
|
const spatialitePaths = [
|
|
2388
2571
|
process.env["SPATIALITE_PATH"],
|
|
2389
2572
|
// Absolute paths to local extensions
|
|
2390
|
-
|
|
2573
|
+
path2.join(
|
|
2391
2574
|
EXTENSIONS_DIR,
|
|
2392
2575
|
"mod_spatialite-5.1.0-win-amd64",
|
|
2393
2576
|
"mod_spatialite"
|
|
2394
2577
|
),
|
|
2395
|
-
|
|
2578
|
+
path2.join(
|
|
2396
2579
|
EXTENSIONS_DIR,
|
|
2397
2580
|
"mod_spatialite-5.1.0-win-amd64",
|
|
2398
2581
|
"mod_spatialite.dll"
|
|
@@ -2406,7 +2589,7 @@ function loadSpatialite(db, log2) {
|
|
|
2406
2589
|
].filter((p) => Boolean(p));
|
|
2407
2590
|
const envSpatialitePath = process.env["SPATIALITE_PATH"];
|
|
2408
2591
|
if (envSpatialitePath && process.platform === "win32") {
|
|
2409
|
-
const spatialiteExtDir =
|
|
2592
|
+
const spatialiteExtDir = path2.dirname(envSpatialitePath);
|
|
2410
2593
|
const currentPath = process.env["PATH"] ?? "";
|
|
2411
2594
|
if (!currentPath.includes(spatialiteExtDir)) {
|
|
2412
2595
|
process.env["PATH"] = spatialiteExtDir + ";" + currentPath;
|
|
@@ -2418,8 +2601,8 @@ function loadCsvExtension(db, log2) {
|
|
|
2418
2601
|
const csvPaths = [
|
|
2419
2602
|
process.env["CSV_EXTENSION_PATH"],
|
|
2420
2603
|
// sqlite-xsv extension with absolute paths
|
|
2421
|
-
|
|
2422
|
-
|
|
2604
|
+
path2.join(EXTENSIONS_DIR, "xsv0.dll"),
|
|
2605
|
+
path2.join(EXTENSIONS_DIR, "xsv0"),
|
|
2423
2606
|
// System paths
|
|
2424
2607
|
"xsv0",
|
|
2425
2608
|
"xsv0.dll",
|
|
@@ -2532,8 +2715,8 @@ var NativeSqliteAdapter = class extends DatabaseAdapter {
|
|
|
2532
2715
|
*/
|
|
2533
2716
|
getConfiguredPath() {
|
|
2534
2717
|
const config = this.config;
|
|
2535
|
-
const
|
|
2536
|
-
return
|
|
2718
|
+
const path3 = config?.filePath ?? config?.connectionString ?? ":memory:";
|
|
2719
|
+
return path3;
|
|
2537
2720
|
}
|
|
2538
2721
|
db = null;
|
|
2539
2722
|
schemaManager = null;
|
|
@@ -2675,6 +2858,7 @@ var NativeSqliteAdapter = class extends DatabaseAdapter {
|
|
|
2675
2858
|
*/
|
|
2676
2859
|
executeReadQuery(sql, params) {
|
|
2677
2860
|
this.ensureConnected();
|
|
2861
|
+
this.validateQuery(sql, true);
|
|
2678
2862
|
return nativeExecuteRead(this.ensureDb(), sql, params, log);
|
|
2679
2863
|
}
|
|
2680
2864
|
/**
|
|
@@ -2682,6 +2866,7 @@ var NativeSqliteAdapter = class extends DatabaseAdapter {
|
|
|
2682
2866
|
*/
|
|
2683
2867
|
executeWriteQuery(sql, params) {
|
|
2684
2868
|
this.ensureConnected();
|
|
2869
|
+
this.validateQuery(sql, false);
|
|
2685
2870
|
const result = nativeExecuteWrite(this.ensureDb(), sql, params, log);
|
|
2686
2871
|
if (isDDL(sql)) {
|
|
2687
2872
|
this.clearSchemaCache();
|
|
@@ -2693,11 +2878,26 @@ var NativeSqliteAdapter = class extends DatabaseAdapter {
|
|
|
2693
2878
|
*/
|
|
2694
2879
|
executeQuery(sql, params) {
|
|
2695
2880
|
const trimmed = sql.trim().toUpperCase();
|
|
2696
|
-
if (trimmed.startsWith("
|
|
2881
|
+
if (trimmed.startsWith("PRAGMA")) {
|
|
2882
|
+
if (sql.includes("=") || sql.includes("(")) {
|
|
2883
|
+
return this.executeWriteQuery(sql, params);
|
|
2884
|
+
}
|
|
2885
|
+
return this.executeReadQuery(sql, params);
|
|
2886
|
+
}
|
|
2887
|
+
if (trimmed.startsWith("SELECT") || trimmed.startsWith("EXPLAIN")) {
|
|
2697
2888
|
return this.executeReadQuery(sql, params);
|
|
2698
2889
|
}
|
|
2699
2890
|
return this.executeWriteQuery(sql, params);
|
|
2700
2891
|
}
|
|
2892
|
+
/**
|
|
2893
|
+
* Execute a SQL script containing multiple statements
|
|
2894
|
+
*/
|
|
2895
|
+
executeScript(sql) {
|
|
2896
|
+
this.ensureConnected();
|
|
2897
|
+
this.ensureDb().exec(sql);
|
|
2898
|
+
this.clearSchemaCache();
|
|
2899
|
+
return Promise.resolve();
|
|
2900
|
+
}
|
|
2701
2901
|
/**
|
|
2702
2902
|
* Get schema information (cached via SchemaManager)
|
|
2703
2903
|
*/
|
|
@@ -2855,7 +3055,8 @@ var NativeSqliteAdapter = class extends DatabaseAdapter {
|
|
|
2855
3055
|
"admin",
|
|
2856
3056
|
"geo",
|
|
2857
3057
|
"introspection",
|
|
2858
|
-
"migration"
|
|
3058
|
+
"migration",
|
|
3059
|
+
"transactions"
|
|
2859
3060
|
];
|
|
2860
3061
|
}
|
|
2861
3062
|
/**
|
|
@@ -2914,7 +3115,11 @@ var NativeSqliteAdapter = class extends DatabaseAdapter {
|
|
|
2914
3115
|
* Execute raw SQL and return results (for tools)
|
|
2915
3116
|
*/
|
|
2916
3117
|
rawQuery(sql, params) {
|
|
2917
|
-
|
|
3118
|
+
const trimmed = sql.trim().toUpperCase();
|
|
3119
|
+
if (trimmed.startsWith("SELECT") || trimmed.startsWith("EXPLAIN") || trimmed.startsWith("PRAGMA") && !sql.includes("=") && !sql.includes("(")) {
|
|
3120
|
+
return nativeExecuteRead(this.ensureDb(), sql, params, log);
|
|
3121
|
+
}
|
|
3122
|
+
return nativeExecuteWrite(this.ensureDb(), sql, params, log);
|
|
2918
3123
|
}
|
|
2919
3124
|
/**
|
|
2920
3125
|
* Begin a transaction
|