spindb 0.37.2 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/bin.js +9 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/commands/attach.js +102 -0
- package/dist/cli/commands/attach.js.map +1 -0
- package/dist/cli/commands/backup.js +197 -0
- package/dist/cli/commands/backup.js.map +1 -0
- package/dist/cli/commands/backups.js +190 -0
- package/dist/cli/commands/backups.js.map +1 -0
- package/dist/cli/commands/clone.js +119 -0
- package/dist/cli/commands/clone.js.map +1 -0
- package/dist/cli/commands/config.js +276 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/connect.js +559 -0
- package/dist/cli/commands/connect.js.map +1 -0
- package/dist/cli/commands/create.js +952 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/databases.js +485 -0
- package/dist/cli/commands/databases.js.map +1 -0
- package/dist/cli/commands/delete.js +106 -0
- package/dist/cli/commands/delete.js.map +1 -0
- package/dist/cli/commands/deps.js +238 -0
- package/dist/cli/commands/deps.js.map +1 -0
- package/dist/cli/commands/detach.js +81 -0
- package/dist/cli/commands/detach.js.map +1 -0
- package/dist/cli/commands/doctor.js +567 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/duckdb.js +207 -0
- package/dist/cli/commands/duckdb.js.map +1 -0
- package/dist/cli/commands/edit.js +524 -0
- package/dist/cli/commands/edit.js.map +1 -0
- package/dist/cli/commands/engines.js +1414 -0
- package/dist/cli/commands/engines.js.map +1 -0
- package/dist/cli/commands/export.js +383 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/info.js +270 -0
- package/dist/cli/commands/info.js.map +1 -0
- package/dist/cli/commands/list.js +215 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/logs.js +81 -0
- package/dist/cli/commands/logs.js.map +1 -0
- package/dist/cli/commands/menu/backup-handlers.js +1202 -0
- package/dist/cli/commands/menu/backup-handlers.js.map +1 -0
- package/dist/cli/commands/menu/container-handlers.js +1788 -0
- package/dist/cli/commands/menu/container-handlers.js.map +1 -0
- package/dist/cli/commands/menu/engine-handlers.js +235 -0
- package/dist/cli/commands/menu/engine-handlers.js.map +1 -0
- package/dist/cli/commands/menu/index.js +266 -0
- package/dist/cli/commands/menu/index.js.map +1 -0
- package/dist/cli/commands/menu/settings-handlers.js +320 -0
- package/dist/cli/commands/menu/settings-handlers.js.map +1 -0
- package/dist/cli/commands/menu/shared.js +13 -0
- package/dist/cli/commands/menu/shared.js.map +1 -0
- package/dist/cli/commands/menu/shell-handlers.js +1573 -0
- package/dist/cli/commands/menu/shell-handlers.js.map +1 -0
- package/dist/cli/commands/menu/sql-handlers.js +185 -0
- package/dist/cli/commands/menu/sql-handlers.js.map +1 -0
- package/dist/cli/commands/menu/update-handlers.js +322 -0
- package/dist/cli/commands/menu/update-handlers.js.map +1 -0
- package/dist/cli/commands/menu/validators.js +9 -0
- package/dist/cli/commands/menu/validators.js.map +1 -0
- package/dist/cli/commands/ports.js +166 -0
- package/dist/cli/commands/ports.js.map +1 -0
- package/dist/cli/commands/pull.js +166 -0
- package/dist/cli/commands/pull.js.map +1 -0
- package/dist/cli/commands/query.js +180 -0
- package/dist/cli/commands/query.js.map +1 -0
- package/dist/cli/commands/restore.js +428 -0
- package/dist/cli/commands/restore.js.map +1 -0
- package/dist/cli/commands/run.js +115 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/self-update.js +99 -0
- package/dist/cli/commands/self-update.js.map +1 -0
- package/dist/cli/commands/sqlite.js +207 -0
- package/dist/cli/commands/sqlite.js.map +1 -0
- package/dist/cli/commands/start.js +196 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/stop.js +182 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/url.js +88 -0
- package/dist/cli/commands/url.js.map +1 -0
- package/dist/cli/commands/users.js +189 -0
- package/dist/cli/commands/users.js.map +1 -0
- package/dist/cli/commands/version.js +52 -0
- package/dist/cli/commands/version.js.map +1 -0
- package/dist/cli/commands/which.js +258 -0
- package/dist/cli/commands/which.js.map +1 -0
- package/dist/cli/constants.js +212 -0
- package/dist/cli/constants.js.map +1 -0
- package/dist/cli/helpers.js +1120 -0
- package/dist/cli/helpers.js.map +1 -0
- package/dist/cli/index.js +146 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/ui/prompts.js +1002 -0
- package/dist/cli/ui/prompts.js.map +1 -0
- package/dist/cli/ui/spinner.js +74 -0
- package/dist/cli/ui/spinner.js.map +1 -0
- package/dist/cli/ui/theme.js +99 -0
- package/dist/cli/ui/theme.js.map +1 -0
- package/dist/cli/utils/file-follower.js +79 -0
- package/dist/cli/utils/file-follower.js.map +1 -0
- package/dist/config/backup-formats.js +363 -0
- package/dist/config/backup-formats.js.map +1 -0
- package/dist/config/defaults.js +25 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/config/engine-defaults.js +303 -0
- package/dist/config/engine-defaults.js.map +1 -0
- package/dist/config/engines-registry.js +103 -0
- package/dist/config/engines-registry.js.map +1 -0
- package/dist/config/os-dependencies.js +767 -0
- package/dist/config/os-dependencies.js.map +1 -0
- package/dist/config/paths.js +156 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/version.js +3 -0
- package/dist/config/version.js.map +1 -0
- package/dist/core/backup-restore.js +219 -0
- package/dist/core/backup-restore.js.map +1 -0
- package/dist/core/base-binary-manager.js +403 -0
- package/dist/core/base-binary-manager.js.map +1 -0
- package/dist/core/base-document-binary-manager.js +364 -0
- package/dist/core/base-document-binary-manager.js.map +1 -0
- package/dist/core/base-embedded-binary-manager.js +364 -0
- package/dist/core/base-embedded-binary-manager.js.map +1 -0
- package/dist/core/base-server-binary-manager.js +368 -0
- package/dist/core/base-server-binary-manager.js.map +1 -0
- package/dist/core/config-manager.js +495 -0
- package/dist/core/config-manager.js.map +1 -0
- package/dist/core/container-manager.js +609 -0
- package/dist/core/container-manager.js.map +1 -0
- package/dist/core/credential-generator.js +67 -0
- package/dist/core/credential-generator.js.map +1 -0
- package/dist/core/credential-manager.js +211 -0
- package/dist/core/credential-manager.js.map +1 -0
- package/dist/core/dblab-utils.js +105 -0
- package/dist/core/dblab-utils.js.map +1 -0
- package/dist/core/dependency-manager.js +359 -0
- package/dist/core/dependency-manager.js.map +1 -0
- package/dist/core/docker-exporter.js +1077 -0
- package/dist/core/docker-exporter.js.map +1 -0
- package/dist/core/error-handler.js +295 -0
- package/dist/core/error-handler.js.map +1 -0
- package/dist/core/fs-error-utils.js +74 -0
- package/dist/core/fs-error-utils.js.map +1 -0
- package/dist/core/homebrew-version-manager.js +280 -0
- package/dist/core/homebrew-version-manager.js.map +1 -0
- package/dist/core/hostdb-client.js +252 -0
- package/dist/core/hostdb-client.js.map +1 -0
- package/dist/core/hostdb-metadata.js +243 -0
- package/dist/core/hostdb-metadata.js.map +1 -0
- package/dist/core/hostdb-releases-factory.js +161 -0
- package/dist/core/hostdb-releases-factory.js.map +1 -0
- package/dist/core/library-env.js +88 -0
- package/dist/core/library-env.js.map +1 -0
- package/dist/core/pgweb-utils.js +53 -0
- package/dist/core/pgweb-utils.js.map +1 -0
- package/dist/core/platform-service.js +632 -0
- package/dist/core/platform-service.js.map +1 -0
- package/dist/core/port-manager.js +136 -0
- package/dist/core/port-manager.js.map +1 -0
- package/dist/core/process-manager.js +445 -0
- package/dist/core/process-manager.js.map +1 -0
- package/dist/core/pull-manager.js +418 -0
- package/dist/core/pull-manager.js.map +1 -0
- package/dist/core/query-parser.js +449 -0
- package/dist/core/query-parser.js.map +1 -0
- package/dist/core/spawn-utils.js +90 -0
- package/dist/core/spawn-utils.js.map +1 -0
- package/dist/core/start-with-retry.js +90 -0
- package/dist/core/start-with-retry.js.map +1 -0
- package/dist/core/test-cleanup.js +85 -0
- package/dist/core/test-cleanup.js.map +1 -0
- package/dist/core/tls-generator.js +84 -0
- package/dist/core/tls-generator.js.map +1 -0
- package/dist/core/transaction-manager.js +139 -0
- package/dist/core/transaction-manager.js.map +1 -0
- package/dist/core/update-manager.js +241 -0
- package/dist/core/update-manager.js.map +1 -0
- package/dist/core/version-migration.js +260 -0
- package/dist/core/version-migration.js.map +1 -0
- package/dist/core/version-utils.js +91 -0
- package/dist/core/version-utils.js.map +1 -0
- package/dist/engines/base-engine.js +179 -0
- package/dist/engines/base-engine.js.map +1 -0
- package/dist/engines/clickhouse/backup.js +289 -0
- package/dist/engines/clickhouse/backup.js.map +1 -0
- package/dist/engines/clickhouse/binary-manager.js +145 -0
- package/dist/engines/clickhouse/binary-manager.js.map +1 -0
- package/dist/engines/clickhouse/binary-urls.js +100 -0
- package/dist/engines/clickhouse/binary-urls.js.map +1 -0
- package/dist/engines/clickhouse/cli-utils.js +143 -0
- package/dist/engines/clickhouse/cli-utils.js.map +1 -0
- package/dist/engines/clickhouse/hostdb-releases.js +24 -0
- package/dist/engines/clickhouse/hostdb-releases.js.map +1 -0
- package/dist/engines/clickhouse/index.js +1077 -0
- package/dist/engines/clickhouse/index.js.map +1 -0
- package/dist/engines/clickhouse/restore.js +335 -0
- package/dist/engines/clickhouse/restore.js.map +1 -0
- package/dist/engines/clickhouse/version-maps.js +83 -0
- package/dist/engines/clickhouse/version-maps.js.map +1 -0
- package/dist/engines/clickhouse/version-validator.js +133 -0
- package/dist/engines/clickhouse/version-validator.js.map +1 -0
- package/dist/engines/cockroachdb/backup.js +261 -0
- package/dist/engines/cockroachdb/backup.js.map +1 -0
- package/dist/engines/cockroachdb/binary-manager.js +33 -0
- package/dist/engines/cockroachdb/binary-manager.js.map +1 -0
- package/dist/engines/cockroachdb/binary-urls.js +33 -0
- package/dist/engines/cockroachdb/binary-urls.js.map +1 -0
- package/dist/engines/cockroachdb/cli-utils.js +338 -0
- package/dist/engines/cockroachdb/cli-utils.js.map +1 -0
- package/dist/engines/cockroachdb/hostdb-releases.js +21 -0
- package/dist/engines/cockroachdb/hostdb-releases.js.map +1 -0
- package/dist/engines/cockroachdb/index.js +1016 -0
- package/dist/engines/cockroachdb/index.js.map +1 -0
- package/dist/engines/cockroachdb/restore.js +323 -0
- package/dist/engines/cockroachdb/restore.js.map +1 -0
- package/dist/engines/cockroachdb/version-maps.js +37 -0
- package/dist/engines/cockroachdb/version-maps.js.map +1 -0
- package/dist/engines/couchdb/api-client.js +64 -0
- package/dist/engines/couchdb/api-client.js.map +1 -0
- package/dist/engines/couchdb/backup.js +90 -0
- package/dist/engines/couchdb/backup.js.map +1 -0
- package/dist/engines/couchdb/binary-manager.js +62 -0
- package/dist/engines/couchdb/binary-manager.js.map +1 -0
- package/dist/engines/couchdb/binary-urls.js +92 -0
- package/dist/engines/couchdb/binary-urls.js.map +1 -0
- package/dist/engines/couchdb/hostdb-releases.js +21 -0
- package/dist/engines/couchdb/hostdb-releases.js.map +1 -0
- package/dist/engines/couchdb/index.js +1043 -0
- package/dist/engines/couchdb/index.js.map +1 -0
- package/dist/engines/couchdb/restore.js +198 -0
- package/dist/engines/couchdb/restore.js.map +1 -0
- package/dist/engines/couchdb/version-maps.js +67 -0
- package/dist/engines/couchdb/version-maps.js.map +1 -0
- package/dist/engines/couchdb/version-validator.js +88 -0
- package/dist/engines/couchdb/version-validator.js.map +1 -0
- package/dist/engines/duckdb/binary-manager.js +33 -0
- package/dist/engines/duckdb/binary-manager.js.map +1 -0
- package/{engines/duckdb/binary-urls.ts → dist/engines/duckdb/binary-urls.js} +11 -16
- package/dist/engines/duckdb/binary-urls.js.map +1 -0
- package/dist/engines/duckdb/hostdb-releases.js +21 -0
- package/dist/engines/duckdb/hostdb-releases.js.map +1 -0
- package/dist/engines/duckdb/index.js +594 -0
- package/dist/engines/duckdb/index.js.map +1 -0
- package/dist/engines/duckdb/registry.js +265 -0
- package/dist/engines/duckdb/registry.js.map +1 -0
- package/dist/engines/duckdb/scanner.js +12 -0
- package/dist/engines/duckdb/scanner.js.map +1 -0
- package/dist/engines/duckdb/version-maps.js +67 -0
- package/dist/engines/duckdb/version-maps.js.map +1 -0
- package/dist/engines/duckdb/version-validator.js +62 -0
- package/dist/engines/duckdb/version-validator.js.map +1 -0
- package/dist/engines/ferretdb/backup.js +170 -0
- package/dist/engines/ferretdb/backup.js.map +1 -0
- package/dist/engines/ferretdb/binary-manager.js +765 -0
- package/dist/engines/ferretdb/binary-manager.js.map +1 -0
- package/dist/engines/ferretdb/binary-urls.js +135 -0
- package/dist/engines/ferretdb/binary-urls.js.map +1 -0
- package/dist/engines/ferretdb/index.js +1517 -0
- package/dist/engines/ferretdb/index.js.map +1 -0
- package/dist/engines/ferretdb/restore.js +310 -0
- package/dist/engines/ferretdb/restore.js.map +1 -0
- package/{engines/ferretdb/version-maps.ts → dist/engines/ferretdb/version-maps.js} +62 -79
- package/dist/engines/ferretdb/version-maps.js.map +1 -0
- package/dist/engines/file-based-utils.js +184 -0
- package/dist/engines/file-based-utils.js.map +1 -0
- package/dist/engines/index.js +124 -0
- package/dist/engines/index.js.map +1 -0
- package/dist/engines/influxdb/api-client.js +54 -0
- package/dist/engines/influxdb/api-client.js.map +1 -0
- package/dist/engines/influxdb/backup.js +119 -0
- package/dist/engines/influxdb/backup.js.map +1 -0
- package/dist/engines/influxdb/binary-manager.js +87 -0
- package/dist/engines/influxdb/binary-manager.js.map +1 -0
- package/dist/engines/influxdb/binary-urls.js +56 -0
- package/dist/engines/influxdb/binary-urls.js.map +1 -0
- package/dist/engines/influxdb/hostdb-releases.js +21 -0
- package/dist/engines/influxdb/hostdb-releases.js.map +1 -0
- package/dist/engines/influxdb/index.js +962 -0
- package/dist/engines/influxdb/index.js.map +1 -0
- package/dist/engines/influxdb/restore.js +329 -0
- package/dist/engines/influxdb/restore.js.map +1 -0
- package/dist/engines/influxdb/version-maps.js +64 -0
- package/dist/engines/influxdb/version-maps.js.map +1 -0
- package/dist/engines/influxdb/version-validator.js +109 -0
- package/dist/engines/influxdb/version-validator.js.map +1 -0
- package/dist/engines/mariadb/backup.js +178 -0
- package/dist/engines/mariadb/backup.js.map +1 -0
- package/dist/engines/mariadb/binary-manager.js +33 -0
- package/dist/engines/mariadb/binary-manager.js.map +1 -0
- package/{engines/mariadb/binary-urls.ts → dist/engines/mariadb/binary-urls.js} +38 -55
- package/dist/engines/mariadb/binary-urls.js.map +1 -0
- package/dist/engines/mariadb/hostdb-releases.js +21 -0
- package/dist/engines/mariadb/hostdb-releases.js.map +1 -0
- package/dist/engines/mariadb/index.js +1011 -0
- package/dist/engines/mariadb/index.js.map +1 -0
- package/dist/engines/mariadb/restore.js +322 -0
- package/dist/engines/mariadb/restore.js.map +1 -0
- package/dist/engines/mariadb/version-maps.js +63 -0
- package/dist/engines/mariadb/version-maps.js.map +1 -0
- package/dist/engines/mariadb/version-validator.js +143 -0
- package/dist/engines/mariadb/version-validator.js.map +1 -0
- package/dist/engines/meilisearch/api-client.js +50 -0
- package/dist/engines/meilisearch/api-client.js.map +1 -0
- package/dist/engines/meilisearch/backup.js +167 -0
- package/dist/engines/meilisearch/backup.js.map +1 -0
- package/dist/engines/meilisearch/binary-manager.js +31 -0
- package/dist/engines/meilisearch/binary-manager.js.map +1 -0
- package/dist/engines/meilisearch/binary-urls.js +56 -0
- package/dist/engines/meilisearch/binary-urls.js.map +1 -0
- package/dist/engines/meilisearch/hostdb-releases.js +21 -0
- package/dist/engines/meilisearch/hostdb-releases.js.map +1 -0
- package/dist/engines/meilisearch/index.js +992 -0
- package/dist/engines/meilisearch/index.js.map +1 -0
- package/dist/engines/meilisearch/restore.js +167 -0
- package/dist/engines/meilisearch/restore.js.map +1 -0
- package/dist/engines/meilisearch/version-maps.js +67 -0
- package/dist/engines/meilisearch/version-maps.js.map +1 -0
- package/dist/engines/meilisearch/version-validator.js +109 -0
- package/dist/engines/meilisearch/version-validator.js.map +1 -0
- package/dist/engines/mongodb/backup.js +109 -0
- package/dist/engines/mongodb/backup.js.map +1 -0
- package/dist/engines/mongodb/binary-manager.js +36 -0
- package/dist/engines/mongodb/binary-manager.js.map +1 -0
- package/dist/engines/mongodb/binary-urls.js +46 -0
- package/dist/engines/mongodb/binary-urls.js.map +1 -0
- package/dist/engines/mongodb/cli-utils.js +131 -0
- package/dist/engines/mongodb/cli-utils.js.map +1 -0
- package/dist/engines/mongodb/hostdb-releases.js +77 -0
- package/dist/engines/mongodb/hostdb-releases.js.map +1 -0
- package/dist/engines/mongodb/index.js +873 -0
- package/dist/engines/mongodb/index.js.map +1 -0
- package/dist/engines/mongodb/restore.js +276 -0
- package/dist/engines/mongodb/restore.js.map +1 -0
- package/dist/engines/mongodb/version-maps.js +79 -0
- package/dist/engines/mongodb/version-maps.js.map +1 -0
- package/dist/engines/mongodb/version-validator.js +133 -0
- package/dist/engines/mongodb/version-validator.js.map +1 -0
- package/dist/engines/mysql/backup.js +210 -0
- package/dist/engines/mysql/backup.js.map +1 -0
- package/dist/engines/mysql/binary-detection.js +325 -0
- package/dist/engines/mysql/binary-detection.js.map +1 -0
- package/dist/engines/mysql/binary-manager.js +30 -0
- package/dist/engines/mysql/binary-manager.js.map +1 -0
- package/dist/engines/mysql/binary-urls.js +87 -0
- package/dist/engines/mysql/binary-urls.js.map +1 -0
- package/{engines/mysql/hostdb-releases.ts → dist/engines/mysql/hostdb-releases.js} +20 -23
- package/dist/engines/mysql/hostdb-releases.js.map +1 -0
- package/dist/engines/mysql/index.js +1066 -0
- package/dist/engines/mysql/index.js.map +1 -0
- package/dist/engines/mysql/restore.js +361 -0
- package/dist/engines/mysql/restore.js.map +1 -0
- package/dist/engines/mysql/version-maps.js +79 -0
- package/dist/engines/mysql/version-maps.js.map +1 -0
- package/dist/engines/mysql/version-validator.js +266 -0
- package/dist/engines/mysql/version-validator.js.map +1 -0
- package/dist/engines/postgresql/backup.js +118 -0
- package/dist/engines/postgresql/backup.js.map +1 -0
- package/dist/engines/postgresql/binary-manager.js +85 -0
- package/dist/engines/postgresql/binary-manager.js.map +1 -0
- package/dist/engines/postgresql/binary-urls.js +80 -0
- package/dist/engines/postgresql/binary-urls.js.map +1 -0
- package/dist/engines/postgresql/hostdb-releases.js +21 -0
- package/dist/engines/postgresql/hostdb-releases.js.map +1 -0
- package/dist/engines/postgresql/index.js +852 -0
- package/dist/engines/postgresql/index.js.map +1 -0
- package/dist/engines/postgresql/remote-version.js +109 -0
- package/dist/engines/postgresql/remote-version.js.map +1 -0
- package/dist/engines/postgresql/restore.js +254 -0
- package/dist/engines/postgresql/restore.js.map +1 -0
- package/dist/engines/postgresql/version-maps.js +73 -0
- package/dist/engines/postgresql/version-maps.js.map +1 -0
- package/dist/engines/postgresql/version-validator.js +286 -0
- package/dist/engines/postgresql/version-validator.js.map +1 -0
- package/dist/engines/qdrant/api-client.js +50 -0
- package/dist/engines/qdrant/api-client.js.map +1 -0
- package/dist/engines/qdrant/backup.js +115 -0
- package/dist/engines/qdrant/backup.js.map +1 -0
- package/dist/engines/qdrant/binary-manager.js +31 -0
- package/dist/engines/qdrant/binary-manager.js.map +1 -0
- package/dist/engines/qdrant/binary-urls.js +92 -0
- package/dist/engines/qdrant/binary-urls.js.map +1 -0
- package/dist/engines/qdrant/cli-utils.js +39 -0
- package/dist/engines/qdrant/cli-utils.js.map +1 -0
- package/dist/engines/qdrant/hostdb-releases.js +21 -0
- package/dist/engines/qdrant/hostdb-releases.js.map +1 -0
- package/dist/engines/qdrant/index.js +1002 -0
- package/dist/engines/qdrant/index.js.map +1 -0
- package/dist/engines/qdrant/restore.js +154 -0
- package/dist/engines/qdrant/restore.js.map +1 -0
- package/dist/engines/qdrant/version-maps.js +67 -0
- package/dist/engines/qdrant/version-maps.js.map +1 -0
- package/dist/engines/qdrant/version-validator.js +109 -0
- package/dist/engines/qdrant/version-validator.js.map +1 -0
- package/dist/engines/questdb/backup.js +191 -0
- package/dist/engines/questdb/backup.js.map +1 -0
- package/dist/engines/questdb/binary-manager.js +247 -0
- package/dist/engines/questdb/binary-manager.js.map +1 -0
- package/dist/engines/questdb/binary-urls.js +27 -0
- package/dist/engines/questdb/binary-urls.js.map +1 -0
- package/dist/engines/questdb/hostdb-releases.js +21 -0
- package/dist/engines/questdb/hostdb-releases.js.map +1 -0
- package/dist/engines/questdb/index.js +814 -0
- package/dist/engines/questdb/index.js.map +1 -0
- package/dist/engines/questdb/restore.js +202 -0
- package/dist/engines/questdb/restore.js.map +1 -0
- package/dist/engines/questdb/version-maps.js +33 -0
- package/dist/engines/questdb/version-maps.js.map +1 -0
- package/dist/engines/questdb/version-validator.js +99 -0
- package/dist/engines/questdb/version-validator.js.map +1 -0
- package/dist/engines/redis/backup.js +292 -0
- package/dist/engines/redis/backup.js.map +1 -0
- package/dist/engines/redis/binary-manager.js +32 -0
- package/dist/engines/redis/binary-manager.js.map +1 -0
- package/dist/engines/redis/binary-urls.js +96 -0
- package/dist/engines/redis/binary-urls.js.map +1 -0
- package/dist/engines/redis/cli-utils.js +38 -0
- package/dist/engines/redis/cli-utils.js.map +1 -0
- package/dist/engines/redis/hostdb-releases.js +21 -0
- package/dist/engines/redis/hostdb-releases.js.map +1 -0
- package/dist/engines/redis/index.js +1263 -0
- package/dist/engines/redis/index.js.map +1 -0
- package/dist/engines/redis/restore.js +338 -0
- package/dist/engines/redis/restore.js.map +1 -0
- package/dist/engines/redis/version-maps.js +70 -0
- package/dist/engines/redis/version-maps.js.map +1 -0
- package/dist/engines/redis/version-validator.js +109 -0
- package/dist/engines/redis/version-validator.js.map +1 -0
- package/dist/engines/sqlite/binary-manager.js +39 -0
- package/dist/engines/sqlite/binary-manager.js.map +1 -0
- package/{engines/sqlite/binary-urls.ts → dist/engines/sqlite/binary-urls.js} +11 -16
- package/dist/engines/sqlite/binary-urls.js.map +1 -0
- package/dist/engines/sqlite/hostdb-releases.js +21 -0
- package/dist/engines/sqlite/hostdb-releases.js.map +1 -0
- package/dist/engines/sqlite/index.js +493 -0
- package/dist/engines/sqlite/index.js.map +1 -0
- package/dist/engines/sqlite/registry.js +163 -0
- package/dist/engines/sqlite/registry.js.map +1 -0
- package/dist/engines/sqlite/scanner.js +12 -0
- package/dist/engines/sqlite/scanner.js.map +1 -0
- package/dist/engines/sqlite/version-maps.js +57 -0
- package/dist/engines/sqlite/version-maps.js.map +1 -0
- package/dist/engines/surrealdb/backup.js +97 -0
- package/dist/engines/surrealdb/backup.js.map +1 -0
- package/dist/engines/surrealdb/binary-manager.js +33 -0
- package/dist/engines/surrealdb/binary-manager.js.map +1 -0
- package/dist/engines/surrealdb/binary-urls.js +33 -0
- package/dist/engines/surrealdb/binary-urls.js.map +1 -0
- package/dist/engines/surrealdb/cli-utils.js +147 -0
- package/dist/engines/surrealdb/cli-utils.js.map +1 -0
- package/dist/engines/surrealdb/hostdb-releases.js +21 -0
- package/dist/engines/surrealdb/hostdb-releases.js.map +1 -0
- package/dist/engines/surrealdb/index.js +1022 -0
- package/dist/engines/surrealdb/index.js.map +1 -0
- package/dist/engines/surrealdb/restore.js +224 -0
- package/dist/engines/surrealdb/restore.js.map +1 -0
- package/dist/engines/surrealdb/version-maps.js +36 -0
- package/dist/engines/surrealdb/version-maps.js.map +1 -0
- package/dist/engines/tigerbeetle/backup.js +36 -0
- package/dist/engines/tigerbeetle/backup.js.map +1 -0
- package/dist/engines/tigerbeetle/binary-manager.js +72 -0
- package/dist/engines/tigerbeetle/binary-manager.js.map +1 -0
- package/dist/engines/tigerbeetle/binary-urls.js +49 -0
- package/dist/engines/tigerbeetle/binary-urls.js.map +1 -0
- package/dist/engines/tigerbeetle/hostdb-releases.js +21 -0
- package/dist/engines/tigerbeetle/hostdb-releases.js.map +1 -0
- package/dist/engines/tigerbeetle/index.js +559 -0
- package/dist/engines/tigerbeetle/index.js.map +1 -0
- package/dist/engines/tigerbeetle/restore.js +91 -0
- package/dist/engines/tigerbeetle/restore.js.map +1 -0
- package/{engines/tigerbeetle/version-maps.ts → dist/engines/tigerbeetle/version-maps.js} +22 -31
- package/dist/engines/tigerbeetle/version-maps.js.map +1 -0
- package/dist/engines/tigerbeetle/version-validator.js +108 -0
- package/dist/engines/tigerbeetle/version-validator.js.map +1 -0
- package/dist/engines/typedb/backup.js +129 -0
- package/dist/engines/typedb/backup.js.map +1 -0
- package/dist/engines/typedb/binary-manager.js +151 -0
- package/dist/engines/typedb/binary-manager.js.map +1 -0
- package/dist/engines/typedb/binary-urls.js +33 -0
- package/dist/engines/typedb/binary-urls.js.map +1 -0
- package/dist/engines/typedb/cli-utils.js +163 -0
- package/dist/engines/typedb/cli-utils.js.map +1 -0
- package/dist/engines/typedb/hostdb-releases.js +21 -0
- package/dist/engines/typedb/hostdb-releases.js.map +1 -0
- package/dist/engines/typedb/index.js +1003 -0
- package/dist/engines/typedb/index.js.map +1 -0
- package/dist/engines/typedb/restore.js +279 -0
- package/dist/engines/typedb/restore.js.map +1 -0
- package/dist/engines/typedb/version-maps.js +40 -0
- package/dist/engines/typedb/version-maps.js.map +1 -0
- package/dist/engines/typedb/version-validator.js +103 -0
- package/dist/engines/typedb/version-validator.js.map +1 -0
- package/dist/engines/valkey/backup.js +292 -0
- package/dist/engines/valkey/backup.js.map +1 -0
- package/dist/engines/valkey/binary-manager.js +33 -0
- package/dist/engines/valkey/binary-manager.js.map +1 -0
- package/dist/engines/valkey/binary-urls.js +98 -0
- package/dist/engines/valkey/binary-urls.js.map +1 -0
- package/dist/engines/valkey/cli-utils.js +38 -0
- package/dist/engines/valkey/cli-utils.js.map +1 -0
- package/dist/engines/valkey/hostdb-releases.js +21 -0
- package/dist/engines/valkey/hostdb-releases.js.map +1 -0
- package/dist/engines/valkey/index.js +1257 -0
- package/dist/engines/valkey/index.js.map +1 -0
- package/dist/engines/valkey/restore.js +340 -0
- package/dist/engines/valkey/restore.js.map +1 -0
- package/dist/engines/valkey/version-maps.js +70 -0
- package/dist/engines/valkey/version-maps.js.map +1 -0
- package/dist/engines/valkey/version-validator.js +112 -0
- package/dist/engines/valkey/version-validator.js.map +1 -0
- package/dist/engines/weaviate/api-client.js +50 -0
- package/dist/engines/weaviate/api-client.js.map +1 -0
- package/dist/engines/weaviate/backup.js +95 -0
- package/dist/engines/weaviate/backup.js.map +1 -0
- package/dist/engines/weaviate/binary-manager.js +58 -0
- package/dist/engines/weaviate/binary-manager.js.map +1 -0
- package/dist/engines/weaviate/binary-urls.js +92 -0
- package/dist/engines/weaviate/binary-urls.js.map +1 -0
- package/dist/engines/weaviate/cli-utils.js +39 -0
- package/dist/engines/weaviate/cli-utils.js.map +1 -0
- package/dist/engines/weaviate/hostdb-releases.js +21 -0
- package/dist/engines/weaviate/hostdb-releases.js.map +1 -0
- package/dist/engines/weaviate/index.js +871 -0
- package/dist/engines/weaviate/index.js.map +1 -0
- package/dist/engines/weaviate/restore.js +185 -0
- package/dist/engines/weaviate/restore.js.map +1 -0
- package/dist/engines/weaviate/version-maps.js +67 -0
- package/dist/engines/weaviate/version-maps.js.map +1 -0
- package/dist/engines/weaviate/version-validator.js +109 -0
- package/dist/engines/weaviate/version-validator.js.map +1 -0
- package/dist/types/index.js +102 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +12 -9
- package/bin/cli.js +0 -68
- package/cli/bin.ts +0 -10
- package/cli/commands/attach.ts +0 -139
- package/cli/commands/backup.ts +0 -290
- package/cli/commands/backups.ts +0 -247
- package/cli/commands/clone.ts +0 -159
- package/cli/commands/config.ts +0 -367
- package/cli/commands/connect.ts +0 -684
- package/cli/commands/create.ts +0 -1201
- package/cli/commands/databases.ts +0 -630
- package/cli/commands/delete.ts +0 -133
- package/cli/commands/deps.ts +0 -342
- package/cli/commands/detach.ts +0 -107
- package/cli/commands/doctor.ts +0 -689
- package/cli/commands/duckdb.ts +0 -273
- package/cli/commands/edit.ts +0 -683
- package/cli/commands/engines.ts +0 -1914
- package/cli/commands/export.ts +0 -544
- package/cli/commands/info.ts +0 -340
- package/cli/commands/list.ts +0 -284
- package/cli/commands/logs.ts +0 -102
- package/cli/commands/menu/backup-handlers.ts +0 -1571
- package/cli/commands/menu/container-handlers.ts +0 -2288
- package/cli/commands/menu/engine-handlers.ts +0 -355
- package/cli/commands/menu/index.ts +0 -342
- package/cli/commands/menu/settings-handlers.ts +0 -365
- package/cli/commands/menu/shared.ts +0 -23
- package/cli/commands/menu/shell-handlers.ts +0 -1811
- package/cli/commands/menu/sql-handlers.ts +0 -231
- package/cli/commands/menu/update-handlers.ts +0 -378
- package/cli/commands/menu/validators.ts +0 -8
- package/cli/commands/ports.ts +0 -211
- package/cli/commands/pull.ts +0 -223
- package/cli/commands/query.ts +0 -241
- package/cli/commands/restore.ts +0 -587
- package/cli/commands/run.ts +0 -178
- package/cli/commands/self-update.ts +0 -121
- package/cli/commands/sqlite.ts +0 -273
- package/cli/commands/start.ts +0 -218
- package/cli/commands/stop.ts +0 -241
- package/cli/commands/url.ts +0 -104
- package/cli/commands/users.ts +0 -264
- package/cli/commands/version.ts +0 -55
- package/cli/commands/which.ts +0 -290
- package/cli/constants.ts +0 -233
- package/cli/helpers.ts +0 -1593
- package/cli/index.ts +0 -162
- package/cli/ui/prompts.ts +0 -1525
- package/cli/ui/spinner.ts +0 -88
- package/cli/ui/theme.ts +0 -128
- package/cli/utils/file-follower.ts +0 -93
- package/config/backup-formats.ts +0 -446
- package/config/defaults.ts +0 -56
- package/config/engine-defaults.ts +0 -336
- package/config/engines-registry.ts +0 -150
- package/config/engines.schema.json +0 -135
- package/config/os-dependencies.ts +0 -888
- package/config/paths.ts +0 -200
- package/core/backup-restore.ts +0 -330
- package/core/base-binary-manager.ts +0 -562
- package/core/base-document-binary-manager.ts +0 -523
- package/core/base-embedded-binary-manager.ts +0 -547
- package/core/base-server-binary-manager.ts +0 -523
- package/core/config-manager.ts +0 -652
- package/core/container-manager.ts +0 -787
- package/core/credential-generator.ts +0 -93
- package/core/credential-manager.ts +0 -259
- package/core/dblab-utils.ts +0 -113
- package/core/dependency-manager.ts +0 -512
- package/core/docker-exporter.ts +0 -1345
- package/core/error-handler.ts +0 -419
- package/core/fs-error-utils.ts +0 -82
- package/core/homebrew-version-manager.ts +0 -352
- package/core/hostdb-client.ts +0 -344
- package/core/hostdb-metadata.ts +0 -350
- package/core/hostdb-releases-factory.ts +0 -237
- package/core/library-env.ts +0 -118
- package/core/pgweb-utils.ts +0 -62
- package/core/platform-service.ts +0 -829
- package/core/port-manager.ts +0 -165
- package/core/process-manager.ts +0 -576
- package/core/pull-manager.ts +0 -511
- package/core/query-parser.ts +0 -514
- package/core/spawn-utils.ts +0 -122
- package/core/start-with-retry.ts +0 -130
- package/core/test-cleanup.ts +0 -108
- package/core/tls-generator.ts +0 -116
- package/core/transaction-manager.ts +0 -158
- package/core/update-manager.ts +0 -308
- package/core/version-migration.ts +0 -346
- package/core/version-utils.ts +0 -104
- package/engines/base-engine.ts +0 -340
- package/engines/clickhouse/README.md +0 -231
- package/engines/clickhouse/backup.ts +0 -398
- package/engines/clickhouse/binary-manager.ts +0 -201
- package/engines/clickhouse/binary-urls.ts +0 -125
- package/engines/clickhouse/cli-utils.ts +0 -176
- package/engines/clickhouse/hostdb-releases.ts +0 -30
- package/engines/clickhouse/index.ts +0 -1345
- package/engines/clickhouse/restore.ts +0 -466
- package/engines/clickhouse/version-maps.ts +0 -95
- package/engines/clickhouse/version-validator.ts +0 -154
- package/engines/cockroachdb/README.md +0 -170
- package/engines/cockroachdb/backup.ts +0 -376
- package/engines/cockroachdb/binary-manager.ts +0 -45
- package/engines/cockroachdb/binary-urls.ts +0 -40
- package/engines/cockroachdb/cli-utils.ts +0 -384
- package/engines/cockroachdb/hostdb-releases.ts +0 -26
- package/engines/cockroachdb/index.ts +0 -1276
- package/engines/cockroachdb/restore.ts +0 -455
- package/engines/cockroachdb/version-maps.ts +0 -42
- package/engines/couchdb/README.md +0 -257
- package/engines/couchdb/api-client.ts +0 -81
- package/engines/couchdb/backup.ts +0 -137
- package/engines/couchdb/binary-manager.ts +0 -86
- package/engines/couchdb/binary-urls.ts +0 -115
- package/engines/couchdb/hostdb-releases.ts +0 -23
- package/engines/couchdb/index.ts +0 -1429
- package/engines/couchdb/restore.ts +0 -290
- package/engines/couchdb/version-maps.ts +0 -78
- package/engines/couchdb/version-validator.ts +0 -111
- package/engines/duckdb/README.md +0 -154
- package/engines/duckdb/binary-manager.ts +0 -45
- package/engines/duckdb/hostdb-releases.ts +0 -23
- package/engines/duckdb/index.ts +0 -749
- package/engines/duckdb/registry.ts +0 -303
- package/engines/duckdb/scanner.ts +0 -22
- package/engines/duckdb/version-maps.ts +0 -78
- package/engines/duckdb/version-validator.ts +0 -78
- package/engines/ferretdb/README.md +0 -262
- package/engines/ferretdb/backup.ts +0 -173
- package/engines/ferretdb/binary-manager.ts +0 -1095
- package/engines/ferretdb/binary-urls.ts +0 -183
- package/engines/ferretdb/index.ts +0 -1907
- package/engines/ferretdb/restore.ts +0 -357
- package/engines/file-based-utils.ts +0 -262
- package/engines/index.ts +0 -131
- package/engines/influxdb/README.md +0 -180
- package/engines/influxdb/api-client.ts +0 -64
- package/engines/influxdb/backup.ts +0 -160
- package/engines/influxdb/binary-manager.ts +0 -110
- package/engines/influxdb/binary-urls.ts +0 -69
- package/engines/influxdb/hostdb-releases.ts +0 -23
- package/engines/influxdb/index.ts +0 -1272
- package/engines/influxdb/restore.ts +0 -417
- package/engines/influxdb/version-maps.ts +0 -75
- package/engines/influxdb/version-validator.ts +0 -128
- package/engines/mariadb/README.md +0 -141
- package/engines/mariadb/backup.ts +0 -233
- package/engines/mariadb/binary-manager.ts +0 -45
- package/engines/mariadb/hostdb-releases.ts +0 -23
- package/engines/mariadb/index.ts +0 -1300
- package/engines/mariadb/restore.ts +0 -447
- package/engines/mariadb/version-maps.ts +0 -72
- package/engines/mariadb/version-validator.ts +0 -181
- package/engines/meilisearch/README.md +0 -255
- package/engines/meilisearch/api-client.ts +0 -61
- package/engines/meilisearch/backup.ts +0 -233
- package/engines/meilisearch/binary-manager.ts +0 -43
- package/engines/meilisearch/binary-urls.ts +0 -69
- package/engines/meilisearch/hostdb-releases.ts +0 -26
- package/engines/meilisearch/index.ts +0 -1292
- package/engines/meilisearch/restore.ts +0 -219
- package/engines/meilisearch/version-maps.ts +0 -78
- package/engines/meilisearch/version-validator.ts +0 -128
- package/engines/mongodb/README.md +0 -162
- package/engines/mongodb/backup.ts +0 -127
- package/engines/mongodb/binary-manager.ts +0 -48
- package/engines/mongodb/binary-urls.ts +0 -63
- package/engines/mongodb/cli-utils.ts +0 -171
- package/engines/mongodb/hostdb-releases.ts +0 -91
- package/engines/mongodb/index.ts +0 -1118
- package/engines/mongodb/restore.ts +0 -361
- package/engines/mongodb/version-maps.ts +0 -91
- package/engines/mongodb/version-validator.ts +0 -160
- package/engines/mysql/README.md +0 -142
- package/engines/mysql/backup.ts +0 -270
- package/engines/mysql/binary-detection.ts +0 -408
- package/engines/mysql/binary-manager.ts +0 -42
- package/engines/mysql/binary-urls.ts +0 -104
- package/engines/mysql/index.ts +0 -1361
- package/engines/mysql/restore.ts +0 -500
- package/engines/mysql/version-maps.ts +0 -91
- package/engines/mysql/version-validator.ts +0 -369
- package/engines/postgresql/README.md +0 -158
- package/engines/postgresql/backup.ts +0 -151
- package/engines/postgresql/binary-manager.ts +0 -114
- package/engines/postgresql/binary-urls.ts +0 -99
- package/engines/postgresql/hostdb-releases.ts +0 -26
- package/engines/postgresql/index.ts +0 -1143
- package/engines/postgresql/remote-version.ts +0 -161
- package/engines/postgresql/restore.ts +0 -342
- package/engines/postgresql/version-maps.ts +0 -83
- package/engines/postgresql/version-validator.ts +0 -413
- package/engines/qdrant/README.md +0 -222
- package/engines/qdrant/api-client.ts +0 -61
- package/engines/qdrant/backup.ts +0 -165
- package/engines/qdrant/binary-manager.ts +0 -43
- package/engines/qdrant/binary-urls.ts +0 -115
- package/engines/qdrant/cli-utils.ts +0 -43
- package/engines/qdrant/hostdb-releases.ts +0 -23
- package/engines/qdrant/index.ts +0 -1312
- package/engines/qdrant/restore.ts +0 -203
- package/engines/qdrant/version-maps.ts +0 -78
- package/engines/qdrant/version-validator.ts +0 -128
- package/engines/questdb/README.md +0 -334
- package/engines/questdb/backup.ts +0 -220
- package/engines/questdb/binary-manager.ts +0 -310
- package/engines/questdb/binary-urls.ts +0 -34
- package/engines/questdb/hostdb-releases.ts +0 -23
- package/engines/questdb/index.ts +0 -1023
- package/engines/questdb/restore.ts +0 -260
- package/engines/questdb/version-maps.ts +0 -37
- package/engines/questdb/version-validator.ts +0 -121
- package/engines/redis/README.md +0 -173
- package/engines/redis/backup.ts +0 -389
- package/engines/redis/binary-manager.ts +0 -44
- package/engines/redis/binary-urls.ts +0 -117
- package/engines/redis/cli-utils.ts +0 -42
- package/engines/redis/hostdb-releases.ts +0 -23
- package/engines/redis/index.ts +0 -1583
- package/engines/redis/restore.ts +0 -443
- package/engines/redis/version-maps.ts +0 -81
- package/engines/redis/version-validator.ts +0 -131
- package/engines/sqlite/README.md +0 -162
- package/engines/sqlite/binary-manager.ts +0 -52
- package/engines/sqlite/hostdb-releases.ts +0 -23
- package/engines/sqlite/index.ts +0 -641
- package/engines/sqlite/registry.ts +0 -198
- package/engines/sqlite/scanner.ts +0 -22
- package/engines/sqlite/version-maps.ts +0 -64
- package/engines/surrealdb/README.md +0 -218
- package/engines/surrealdb/backup.ts +0 -131
- package/engines/surrealdb/binary-manager.ts +0 -45
- package/engines/surrealdb/binary-urls.ts +0 -40
- package/engines/surrealdb/cli-utils.ts +0 -173
- package/engines/surrealdb/hostdb-releases.ts +0 -23
- package/engines/surrealdb/index.ts +0 -1246
- package/engines/surrealdb/restore.ts +0 -302
- package/engines/surrealdb/version-maps.ts +0 -41
- package/engines/tigerbeetle/README.md +0 -61
- package/engines/tigerbeetle/backup.ts +0 -49
- package/engines/tigerbeetle/binary-manager.ts +0 -95
- package/engines/tigerbeetle/binary-urls.ts +0 -62
- package/engines/tigerbeetle/hostdb-releases.ts +0 -26
- package/engines/tigerbeetle/index.ts +0 -746
- package/engines/tigerbeetle/restore.ts +0 -130
- package/engines/tigerbeetle/version-validator.ts +0 -126
- package/engines/typedb/backup.ts +0 -167
- package/engines/typedb/binary-manager.ts +0 -200
- package/engines/typedb/binary-urls.ts +0 -40
- package/engines/typedb/cli-utils.ts +0 -210
- package/engines/typedb/hostdb-releases.ts +0 -23
- package/engines/typedb/index.ts +0 -1275
- package/engines/typedb/restore.ts +0 -377
- package/engines/typedb/version-maps.ts +0 -48
- package/engines/typedb/version-validator.ts +0 -127
- package/engines/valkey/README.md +0 -219
- package/engines/valkey/backup.ts +0 -389
- package/engines/valkey/binary-manager.ts +0 -45
- package/engines/valkey/binary-urls.ts +0 -122
- package/engines/valkey/cli-utils.ts +0 -42
- package/engines/valkey/hostdb-releases.ts +0 -23
- package/engines/valkey/index.ts +0 -1585
- package/engines/valkey/restore.ts +0 -446
- package/engines/valkey/version-maps.ts +0 -81
- package/engines/valkey/version-validator.ts +0 -131
- package/engines/weaviate/README.md +0 -302
- package/engines/weaviate/api-client.ts +0 -61
- package/engines/weaviate/backup.ts +0 -145
- package/engines/weaviate/binary-manager.ts +0 -80
- package/engines/weaviate/binary-urls.ts +0 -115
- package/engines/weaviate/cli-utils.ts +0 -43
- package/engines/weaviate/hostdb-releases.ts +0 -23
- package/engines/weaviate/index.ts +0 -1139
- package/engines/weaviate/restore.ts +0 -235
- package/engines/weaviate/version-maps.ts +0 -78
- package/engines/weaviate/version-validator.ts +0 -128
- package/types/index.ts +0 -624
- /package/{config → dist/config}/engines.json +0 -0
package/engines/duckdb/index.ts
DELETED
|
@@ -1,749 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DuckDB Engine
|
|
3
|
-
*
|
|
4
|
-
* DuckDB is a file-based embedded OLAP database with no server process.
|
|
5
|
-
* Key differences from PostgreSQL/MySQL:
|
|
6
|
-
* - No start/stop operations (file-based)
|
|
7
|
-
* - No port management
|
|
8
|
-
* - Database files stored in user project directories (not ~/.spindb/)
|
|
9
|
-
* - Uses a registry to track file paths
|
|
10
|
-
*
|
|
11
|
-
* Binary sourcing:
|
|
12
|
-
* - Downloads duckdb CLI from hostdb
|
|
13
|
-
*/
|
|
14
|
-
|
|
15
|
-
import { spawn, execFile } from 'child_process'
|
|
16
|
-
import { promisify } from 'util'
|
|
17
|
-
import { existsSync, statSync, createWriteStream, createReadStream } from 'fs'
|
|
18
|
-
import { copyFile, unlink, mkdir, open, writeFile } from 'fs/promises'
|
|
19
|
-
import { resolve, dirname, join } from 'path'
|
|
20
|
-
import { tmpdir } from 'os'
|
|
21
|
-
import { BaseEngine } from '../base-engine'
|
|
22
|
-
import { duckdbRegistry } from './registry'
|
|
23
|
-
import { configManager } from '../../core/config-manager'
|
|
24
|
-
import { platformService } from '../../core/platform-service'
|
|
25
|
-
import { paths } from '../../config/paths'
|
|
26
|
-
import { duckdbBinaryManager } from './binary-manager'
|
|
27
|
-
import { getBinaryUrl } from './binary-urls'
|
|
28
|
-
import { SUPPORTED_MAJOR_VERSIONS, normalizeVersion } from './version-maps'
|
|
29
|
-
import { fetchAvailableVersions } from './hostdb-releases'
|
|
30
|
-
import { logDebug } from '../../core/error-handler'
|
|
31
|
-
import {
|
|
32
|
-
type Platform,
|
|
33
|
-
type Arch,
|
|
34
|
-
type ContainerConfig,
|
|
35
|
-
type ProgressCallback,
|
|
36
|
-
type BackupFormat,
|
|
37
|
-
type BackupOptions,
|
|
38
|
-
type BackupResult,
|
|
39
|
-
type RestoreResult,
|
|
40
|
-
type DumpResult,
|
|
41
|
-
type StatusResult,
|
|
42
|
-
type QueryResult,
|
|
43
|
-
type QueryOptions,
|
|
44
|
-
} from '../../types'
|
|
45
|
-
import { parseCSVToQueryResult } from '../../core/query-parser'
|
|
46
|
-
|
|
47
|
-
const execFileAsync = promisify(execFile)
|
|
48
|
-
|
|
49
|
-
export class DuckDBEngine extends BaseEngine {
|
|
50
|
-
name = 'duckdb'
|
|
51
|
-
displayName = 'DuckDB'
|
|
52
|
-
defaultPort = 0 // File-based, no port
|
|
53
|
-
supportedVersions = SUPPORTED_MAJOR_VERSIONS
|
|
54
|
-
|
|
55
|
-
// Get the download URL for DuckDB binaries from hostdb
|
|
56
|
-
getBinaryUrl(version: string, platform: Platform, arch: Arch): string {
|
|
57
|
-
return getBinaryUrl(version, platform, arch)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async verifyBinary(): Promise<boolean> {
|
|
61
|
-
return this.isBinaryInstalled('1')
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async isBinaryInstalled(version: string): Promise<boolean> {
|
|
65
|
-
const { platform, arch } = platformService.getPlatformInfo()
|
|
66
|
-
return duckdbBinaryManager.isInstalled(version, platform, arch)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Ensure DuckDB binaries are downloaded from hostdb and register tools
|
|
70
|
-
async ensureBinaries(
|
|
71
|
-
version: string,
|
|
72
|
-
onProgress?: ProgressCallback,
|
|
73
|
-
): Promise<string> {
|
|
74
|
-
const { platform, arch } = platformService.getPlatformInfo()
|
|
75
|
-
|
|
76
|
-
// Download from hostdb
|
|
77
|
-
const binPath = await duckdbBinaryManager.ensureInstalled(
|
|
78
|
-
version,
|
|
79
|
-
platform,
|
|
80
|
-
arch,
|
|
81
|
-
onProgress,
|
|
82
|
-
)
|
|
83
|
-
|
|
84
|
-
// Register all DuckDB tools in config
|
|
85
|
-
const ext = platformService.getExecutableExtension()
|
|
86
|
-
const tools = ['duckdb'] as const
|
|
87
|
-
|
|
88
|
-
for (const tool of tools) {
|
|
89
|
-
const toolPath = join(binPath, 'bin', `${tool}${ext}`)
|
|
90
|
-
if (existsSync(toolPath)) {
|
|
91
|
-
await configManager.setBinaryPath(tool, toolPath, 'bundled')
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return binPath
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Get path to duckdb binary - checks downloaded binary first
|
|
99
|
-
override async getDuckDBPath(version?: string): Promise<string | null> {
|
|
100
|
-
// Check config manager first (cached path from downloaded binaries)
|
|
101
|
-
const configPath = await configManager.getBinaryPath('duckdb')
|
|
102
|
-
if (configPath && existsSync(configPath)) {
|
|
103
|
-
return configPath
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// If version provided, check downloaded binary path directly
|
|
107
|
-
if (version) {
|
|
108
|
-
const { platform, arch } = platformService.getPlatformInfo()
|
|
109
|
-
const fullVersion = normalizeVersion(version)
|
|
110
|
-
const binPath = paths.getBinaryPath({
|
|
111
|
-
engine: 'duckdb',
|
|
112
|
-
version: fullVersion,
|
|
113
|
-
platform,
|
|
114
|
-
arch,
|
|
115
|
-
})
|
|
116
|
-
const ext = platformService.getExecutableExtension()
|
|
117
|
-
const duckdbPath = join(binPath, 'bin', `duckdb${ext}`)
|
|
118
|
-
if (existsSync(duckdbPath)) {
|
|
119
|
-
return duckdbPath
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// Not found - require download
|
|
124
|
-
return null
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async initDataDir(
|
|
128
|
-
containerName: string,
|
|
129
|
-
_version: string,
|
|
130
|
-
options: Record<string, unknown> = {},
|
|
131
|
-
): Promise<string> {
|
|
132
|
-
// Determine file path - default to CWD
|
|
133
|
-
const pathOption = options.path as string | undefined
|
|
134
|
-
const filePath = pathOption || `./${containerName}.duckdb`
|
|
135
|
-
const absolutePath = resolve(filePath)
|
|
136
|
-
|
|
137
|
-
// Ensure parent directory exists
|
|
138
|
-
const dir = dirname(absolutePath)
|
|
139
|
-
if (!existsSync(dir)) {
|
|
140
|
-
await mkdir(dir, { recursive: true })
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Check if file already exists
|
|
144
|
-
if (existsSync(absolutePath)) {
|
|
145
|
-
throw new Error(`File already exists: ${absolutePath}`)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Check if this path is already registered
|
|
149
|
-
if (await duckdbRegistry.isPathRegistered(absolutePath)) {
|
|
150
|
-
throw new Error(`Path is already registered: ${absolutePath}`)
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Create empty database by running a simple query
|
|
154
|
-
const duckdb = await this.requireDuckDBPath()
|
|
155
|
-
|
|
156
|
-
await execFileAsync(duckdb, [absolutePath, '-c', 'SELECT 1'])
|
|
157
|
-
|
|
158
|
-
// Register in the DuckDB registry
|
|
159
|
-
await duckdbRegistry.add({
|
|
160
|
-
name: containerName,
|
|
161
|
-
filePath: absolutePath,
|
|
162
|
-
created: new Date().toISOString(),
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
return absolutePath
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
// Start is a no-op for DuckDB (file-based, no server).
|
|
169
|
-
async start(
|
|
170
|
-
container: ContainerConfig,
|
|
171
|
-
_onProgress?: ProgressCallback,
|
|
172
|
-
): Promise<{ port: number; connectionString: string }> {
|
|
173
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
174
|
-
if (!entry) {
|
|
175
|
-
throw new Error(
|
|
176
|
-
`DuckDB container "${container.name}" not found in registry`,
|
|
177
|
-
)
|
|
178
|
-
}
|
|
179
|
-
if (!existsSync(entry.filePath)) {
|
|
180
|
-
throw new Error(`DuckDB database file not found: ${entry.filePath}`)
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return {
|
|
184
|
-
port: 0,
|
|
185
|
-
connectionString: this.getConnectionString(container),
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Stop is a no-op for DuckDB (file-based, no server).
|
|
190
|
-
async stop(_container: ContainerConfig): Promise<void> {}
|
|
191
|
-
|
|
192
|
-
async status(container: ContainerConfig): Promise<StatusResult> {
|
|
193
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
194
|
-
if (!entry) {
|
|
195
|
-
return {
|
|
196
|
-
running: false,
|
|
197
|
-
message: 'Not registered in DuckDB registry',
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
if (!existsSync(entry.filePath)) {
|
|
201
|
-
return {
|
|
202
|
-
running: false,
|
|
203
|
-
message: `File not found: ${entry.filePath}`,
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return {
|
|
207
|
-
running: true,
|
|
208
|
-
message: 'Database file exists',
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
getConnectionString(container: ContainerConfig, _database?: string): string {
|
|
213
|
-
// container.database stores the file path for DuckDB
|
|
214
|
-
const filePath = container.database
|
|
215
|
-
return `duckdb:///${filePath}`
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
// Opens an interactive duckdb shell.
|
|
219
|
-
async connect(container: ContainerConfig, _database?: string): Promise<void> {
|
|
220
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
221
|
-
if (!entry) {
|
|
222
|
-
throw new Error(
|
|
223
|
-
`DuckDB container "${container.name}" not found in registry`,
|
|
224
|
-
)
|
|
225
|
-
}
|
|
226
|
-
if (!existsSync(entry.filePath)) {
|
|
227
|
-
throw new Error(`DuckDB database file not found: ${entry.filePath}`)
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const cmd = await this.requireDuckDBPath()
|
|
231
|
-
|
|
232
|
-
return new Promise((resolve, reject) => {
|
|
233
|
-
const proc = spawn(cmd, [entry.filePath], { stdio: 'inherit' })
|
|
234
|
-
|
|
235
|
-
proc.on('error', (err: NodeJS.ErrnoException) => {
|
|
236
|
-
reject(err)
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
proc.on('close', () => resolve())
|
|
240
|
-
})
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// In DuckDB, the file IS the database.
|
|
244
|
-
async createDatabase(
|
|
245
|
-
_container: ContainerConfig,
|
|
246
|
-
_database: string,
|
|
247
|
-
): Promise<void> {}
|
|
248
|
-
|
|
249
|
-
async dropDatabase(
|
|
250
|
-
container: ContainerConfig,
|
|
251
|
-
_database: string,
|
|
252
|
-
): Promise<void> {
|
|
253
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
254
|
-
if (entry && existsSync(entry.filePath)) {
|
|
255
|
-
await unlink(entry.filePath)
|
|
256
|
-
}
|
|
257
|
-
await duckdbRegistry.remove(container.name)
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
async getDatabaseSize(container: ContainerConfig): Promise<number | null> {
|
|
261
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
262
|
-
if (!entry || !existsSync(entry.filePath)) {
|
|
263
|
-
return null
|
|
264
|
-
}
|
|
265
|
-
const stats = statSync(entry.filePath)
|
|
266
|
-
return stats.size
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
async detectBackupFormat(filePath: string): Promise<BackupFormat> {
|
|
270
|
-
if (filePath.endsWith('.sql')) {
|
|
271
|
-
return {
|
|
272
|
-
format: 'sql',
|
|
273
|
-
description: 'DuckDB SQL dump',
|
|
274
|
-
restoreCommand: 'duckdb <db> < <file>',
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return {
|
|
278
|
-
format: 'duckdb',
|
|
279
|
-
description: 'DuckDB database file (binary copy)',
|
|
280
|
-
restoreCommand: 'cp <file> <db>',
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
async backup(
|
|
285
|
-
container: ContainerConfig,
|
|
286
|
-
outputPath: string,
|
|
287
|
-
options: BackupOptions,
|
|
288
|
-
): Promise<BackupResult> {
|
|
289
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
290
|
-
if (!entry || !existsSync(entry.filePath)) {
|
|
291
|
-
throw new Error('DuckDB database file not found')
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
if (options.format === 'sql') {
|
|
295
|
-
// Use EXPORT DATABASE for SQL format
|
|
296
|
-
const duckdb = await this.requireDuckDBPath()
|
|
297
|
-
|
|
298
|
-
// DuckDB exports to a directory, so we need to handle this differently
|
|
299
|
-
// For SQL format, we'll use a query to dump schema and data
|
|
300
|
-
await this.dumpToFile(duckdb, entry.filePath, outputPath)
|
|
301
|
-
} else {
|
|
302
|
-
// Binary copy for 'binary' format
|
|
303
|
-
await copyFile(entry.filePath, outputPath)
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
const stats = statSync(outputPath)
|
|
307
|
-
return {
|
|
308
|
-
path: outputPath,
|
|
309
|
-
format: options.format ?? 'binary',
|
|
310
|
-
size: stats.size,
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
async restore(
|
|
315
|
-
container: ContainerConfig,
|
|
316
|
-
backupPath: string,
|
|
317
|
-
_options?: Record<string, unknown>,
|
|
318
|
-
): Promise<RestoreResult> {
|
|
319
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
320
|
-
if (!entry) {
|
|
321
|
-
throw new Error(`Container "${container.name}" not registered`)
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
const format = await this.detectBackupFormat(backupPath)
|
|
325
|
-
|
|
326
|
-
if (format.format === 'sql') {
|
|
327
|
-
// Restore SQL dump
|
|
328
|
-
const duckdb = await this.requireDuckDBPath()
|
|
329
|
-
|
|
330
|
-
// Pipe file to duckdb stdin (avoids shell injection)
|
|
331
|
-
await this.runSqlFile(duckdb, entry.filePath, backupPath)
|
|
332
|
-
return { format: 'sql' }
|
|
333
|
-
} else {
|
|
334
|
-
// Binary file copy
|
|
335
|
-
await copyFile(backupPath, entry.filePath)
|
|
336
|
-
return { format: 'duckdb' }
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
async dumpFromConnectionString(
|
|
341
|
-
connectionString: string,
|
|
342
|
-
outputPath: string,
|
|
343
|
-
): Promise<DumpResult> {
|
|
344
|
-
let filePath = connectionString
|
|
345
|
-
let tempFile: string | null = null
|
|
346
|
-
|
|
347
|
-
// Handle HTTP/HTTPS URLs - download to temp file
|
|
348
|
-
if (filePath.startsWith('http://') || filePath.startsWith('https://')) {
|
|
349
|
-
tempFile = join(tmpdir(), `spindb-download-${Date.now()}.duckdb`)
|
|
350
|
-
await this.downloadFile(filePath, tempFile)
|
|
351
|
-
|
|
352
|
-
// Validate it's a valid DuckDB database
|
|
353
|
-
if (!(await this.isValidDuckDBFile(tempFile))) {
|
|
354
|
-
await unlink(tempFile)
|
|
355
|
-
throw new Error('Downloaded file is not a valid DuckDB database')
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
filePath = tempFile
|
|
359
|
-
}
|
|
360
|
-
// Handle duckdb:// URLs (strip prefix for local file)
|
|
361
|
-
else if (filePath.startsWith('duckdb:///')) {
|
|
362
|
-
filePath = filePath.slice('duckdb:///'.length)
|
|
363
|
-
} else if (filePath.startsWith('duckdb://')) {
|
|
364
|
-
filePath = filePath.slice('duckdb://'.length)
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Verify local file exists
|
|
368
|
-
if (!existsSync(filePath)) {
|
|
369
|
-
throw new Error(`DuckDB database file not found: ${filePath}`)
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
const duckdb = await this.requireDuckDBPath()
|
|
373
|
-
|
|
374
|
-
try {
|
|
375
|
-
// Dump to file (avoids shell injection)
|
|
376
|
-
await this.dumpToFile(duckdb, filePath, outputPath)
|
|
377
|
-
|
|
378
|
-
return { filePath: outputPath }
|
|
379
|
-
} finally {
|
|
380
|
-
// Clean up temp file if we downloaded it (even on error)
|
|
381
|
-
if (tempFile && existsSync(tempFile)) {
|
|
382
|
-
await unlink(tempFile)
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
/**
|
|
388
|
-
* Dumps a DuckDB database to a SQL file.
|
|
389
|
-
*
|
|
390
|
-
* Uses a two-step approach:
|
|
391
|
-
* 1. Get schema (CREATE TABLE statements)
|
|
392
|
-
* 2. For each table, output INSERT statements
|
|
393
|
-
*
|
|
394
|
-
* Uses spawn to avoid shell injection.
|
|
395
|
-
*/
|
|
396
|
-
private async dumpToFile(
|
|
397
|
-
duckdbPath: string,
|
|
398
|
-
dbPath: string,
|
|
399
|
-
outputPath: string,
|
|
400
|
-
): Promise<void> {
|
|
401
|
-
// Step 1: Get list of tables
|
|
402
|
-
const tablesResult = await execFileAsync(duckdbPath, [
|
|
403
|
-
dbPath,
|
|
404
|
-
'-csv',
|
|
405
|
-
'-noheader',
|
|
406
|
-
'-c',
|
|
407
|
-
"SELECT table_name FROM information_schema.tables WHERE table_schema = 'main' AND table_type = 'BASE TABLE'",
|
|
408
|
-
])
|
|
409
|
-
const tables = tablesResult.stdout
|
|
410
|
-
.trim()
|
|
411
|
-
.split('\n')
|
|
412
|
-
.filter((t) => t.length > 0)
|
|
413
|
-
|
|
414
|
-
// Step 2: Build dump script - schema first, then data for each table
|
|
415
|
-
const dumpCommands = [
|
|
416
|
-
'.schema', // Output CREATE TABLE statements
|
|
417
|
-
]
|
|
418
|
-
|
|
419
|
-
for (const table of tables) {
|
|
420
|
-
// Quote table name and escape embedded double quotes
|
|
421
|
-
const escapedTable = table.replace(/"/g, '""')
|
|
422
|
-
// Set insert mode with table name for each table
|
|
423
|
-
dumpCommands.push(`.mode insert ${escapedTable}`)
|
|
424
|
-
dumpCommands.push(`SELECT * FROM "${escapedTable}";`)
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
const dumpScript = dumpCommands.join('\n')
|
|
428
|
-
|
|
429
|
-
// Step 3: Execute dump script and write to file
|
|
430
|
-
return new Promise((resolve, reject) => {
|
|
431
|
-
const output = createWriteStream(outputPath)
|
|
432
|
-
const proc = spawn(duckdbPath, [dbPath])
|
|
433
|
-
let rejected = false
|
|
434
|
-
|
|
435
|
-
const rejectOnce = (err: Error) => {
|
|
436
|
-
if (!rejected) {
|
|
437
|
-
rejected = true
|
|
438
|
-
output.close()
|
|
439
|
-
reject(err)
|
|
440
|
-
}
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// Pipe stdout to output file and handle errors
|
|
444
|
-
proc.stdout.pipe(output)
|
|
445
|
-
proc.stdout.on('error', (err) => {
|
|
446
|
-
rejectOnce(new Error(`stdout error: ${err.message}`))
|
|
447
|
-
})
|
|
448
|
-
output.on('error', (err) => {
|
|
449
|
-
rejectOnce(new Error(`output file error: ${err.message}`))
|
|
450
|
-
})
|
|
451
|
-
|
|
452
|
-
// Handle stdin errors (e.g., EPIPE if child exits early)
|
|
453
|
-
proc.stdin.on('error', (err) => {
|
|
454
|
-
rejectOnce(new Error(`stdin error: ${err.message}`))
|
|
455
|
-
})
|
|
456
|
-
|
|
457
|
-
proc.stderr.on('data', (data: Buffer) => {
|
|
458
|
-
// Log stderr but don't fail (warnings are common)
|
|
459
|
-
logDebug('duckdb dump stderr', { message: data.toString() })
|
|
460
|
-
})
|
|
461
|
-
|
|
462
|
-
proc.on('error', (err) => {
|
|
463
|
-
rejectOnce(err)
|
|
464
|
-
})
|
|
465
|
-
|
|
466
|
-
proc.on('close', (code) => {
|
|
467
|
-
output.close()
|
|
468
|
-
if (!rejected) {
|
|
469
|
-
if (code === 0) {
|
|
470
|
-
resolve()
|
|
471
|
-
} else {
|
|
472
|
-
reject(new Error(`duckdb dump failed with exit code ${code}`))
|
|
473
|
-
}
|
|
474
|
-
}
|
|
475
|
-
})
|
|
476
|
-
|
|
477
|
-
// Write the dump script to stdin with backpressure handling
|
|
478
|
-
const writeOk = proc.stdin.write(dumpScript)
|
|
479
|
-
if (writeOk) {
|
|
480
|
-
proc.stdin.end()
|
|
481
|
-
} else {
|
|
482
|
-
// Handle backpressure: wait for drain before ending
|
|
483
|
-
proc.stdin.once('drain', () => {
|
|
484
|
-
proc.stdin.end()
|
|
485
|
-
})
|
|
486
|
-
}
|
|
487
|
-
})
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// Streams a SQL file to a DuckDB database via stdin
|
|
491
|
-
private async runSqlFile(
|
|
492
|
-
duckdbPath: string,
|
|
493
|
-
dbPath: string,
|
|
494
|
-
sqlFilePath: string,
|
|
495
|
-
): Promise<void> {
|
|
496
|
-
return new Promise((resolve, reject) => {
|
|
497
|
-
// Use 'ignore' for stdout since we don't need output and leaving it
|
|
498
|
-
// unconsumed could fill the buffer and cause a deadlock
|
|
499
|
-
const proc = spawn(duckdbPath, [dbPath], {
|
|
500
|
-
stdio: ['pipe', 'ignore', 'pipe'],
|
|
501
|
-
})
|
|
502
|
-
|
|
503
|
-
let stderrData = ''
|
|
504
|
-
let rejected = false
|
|
505
|
-
|
|
506
|
-
const rejectOnce = (err: Error) => {
|
|
507
|
-
if (!rejected) {
|
|
508
|
-
rejected = true
|
|
509
|
-
reject(err)
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
// Handle stdin errors (e.g., EPIPE if child exits early)
|
|
514
|
-
proc.stdin.on('error', (err) => {
|
|
515
|
-
rejectOnce(new Error(`stdin error: ${err.message}`))
|
|
516
|
-
})
|
|
517
|
-
|
|
518
|
-
proc.stderr.on('data', (data: Buffer) => {
|
|
519
|
-
stderrData += data.toString()
|
|
520
|
-
})
|
|
521
|
-
|
|
522
|
-
proc.on('error', (err) => {
|
|
523
|
-
rejectOnce(err)
|
|
524
|
-
})
|
|
525
|
-
|
|
526
|
-
proc.on('close', (code) => {
|
|
527
|
-
if (!rejected) {
|
|
528
|
-
if (code === 0) {
|
|
529
|
-
resolve()
|
|
530
|
-
} else {
|
|
531
|
-
reject(
|
|
532
|
-
new Error(
|
|
533
|
-
`duckdb failed with exit code ${code}${stderrData ? `: ${stderrData}` : ''}`,
|
|
534
|
-
),
|
|
535
|
-
)
|
|
536
|
-
}
|
|
537
|
-
}
|
|
538
|
-
})
|
|
539
|
-
|
|
540
|
-
// Stream SQL file to duckdb stdin
|
|
541
|
-
const fileStream = createReadStream(sqlFilePath, { encoding: 'utf-8' })
|
|
542
|
-
|
|
543
|
-
fileStream.on('error', (error) => {
|
|
544
|
-
rejectOnce(new Error(`Failed to read SQL file: ${error.message}`))
|
|
545
|
-
fileStream.destroy()
|
|
546
|
-
proc.stdin.end()
|
|
547
|
-
})
|
|
548
|
-
|
|
549
|
-
fileStream.pipe(proc.stdin)
|
|
550
|
-
})
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
private async downloadFile(url: string, destPath: string): Promise<void> {
|
|
554
|
-
const controller = new AbortController()
|
|
555
|
-
const timeoutMs = 5 * 60 * 1000 // 5 minutes
|
|
556
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs)
|
|
557
|
-
|
|
558
|
-
try {
|
|
559
|
-
const response = await fetch(url, { signal: controller.signal })
|
|
560
|
-
if (!response.ok) {
|
|
561
|
-
if (response.status === 404) {
|
|
562
|
-
throw new Error(
|
|
563
|
-
`File not found (404) at ${url}. ` +
|
|
564
|
-
`This version may have been removed from hostdb. ` +
|
|
565
|
-
`Try a different version or check https://registry.layerbase.host`,
|
|
566
|
-
)
|
|
567
|
-
}
|
|
568
|
-
throw new Error(
|
|
569
|
-
`Failed to download: ${response.status} ${response.statusText}`,
|
|
570
|
-
)
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
const buffer = await response.arrayBuffer()
|
|
574
|
-
await writeFile(destPath, Buffer.from(buffer))
|
|
575
|
-
} catch (error) {
|
|
576
|
-
if (error instanceof Error && error.name === 'AbortError') {
|
|
577
|
-
throw new Error('Download timed out after 5 minutes')
|
|
578
|
-
}
|
|
579
|
-
throw error
|
|
580
|
-
} finally {
|
|
581
|
-
clearTimeout(timeout)
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
/**
|
|
586
|
-
* Validates that a file is a DuckDB database.
|
|
587
|
-
*
|
|
588
|
-
* DuckDB files have a specific binary header. We check:
|
|
589
|
-
* 1. File is not empty and has minimum size (DuckDB files are at least 4KB)
|
|
590
|
-
* 2. First bytes are not ASCII text (rules out SQL files)
|
|
591
|
-
* 3. Try to execute a simple query to verify it's a valid database
|
|
592
|
-
*/
|
|
593
|
-
private async isValidDuckDBFile(filePath: string): Promise<boolean> {
|
|
594
|
-
try {
|
|
595
|
-
// Check minimum file size (DuckDB databases are at least a few KB)
|
|
596
|
-
const stats = statSync(filePath)
|
|
597
|
-
if (stats.size < 4096) {
|
|
598
|
-
return false
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
// Read first 16 bytes to check for text content
|
|
602
|
-
const buffer = Buffer.alloc(16)
|
|
603
|
-
const fd = await open(filePath, 'r')
|
|
604
|
-
await fd.read(buffer, 0, 16, 0)
|
|
605
|
-
await fd.close()
|
|
606
|
-
|
|
607
|
-
// Check if file starts with common SQL text patterns (not a binary DuckDB file)
|
|
608
|
-
const header = buffer.toString('utf8', 0, 16).toLowerCase()
|
|
609
|
-
const textPatterns = [
|
|
610
|
-
'create',
|
|
611
|
-
'insert',
|
|
612
|
-
'select',
|
|
613
|
-
'drop',
|
|
614
|
-
'--',
|
|
615
|
-
'/*',
|
|
616
|
-
'pragma',
|
|
617
|
-
]
|
|
618
|
-
for (const pattern of textPatterns) {
|
|
619
|
-
if (header.startsWith(pattern)) {
|
|
620
|
-
return false // This is a SQL text file, not a DuckDB binary
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
// Final validation: try to open with DuckDB and run a simple query
|
|
625
|
-
const duckdb = await this.getDuckDBPath()
|
|
626
|
-
if (duckdb) {
|
|
627
|
-
try {
|
|
628
|
-
await execFileAsync(duckdb, [filePath, '-c', 'SELECT 1'], {
|
|
629
|
-
timeout: 5000,
|
|
630
|
-
})
|
|
631
|
-
return true
|
|
632
|
-
} catch {
|
|
633
|
-
return false
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// If we can't run DuckDB, fall back to binary header check
|
|
638
|
-
// DuckDB files should have non-printable bytes in the header
|
|
639
|
-
const hasNonPrintable = buffer.some((b) => b !== 0 && (b < 32 || b > 126))
|
|
640
|
-
return hasNonPrintable
|
|
641
|
-
} catch {
|
|
642
|
-
return false
|
|
643
|
-
}
|
|
644
|
-
}
|
|
645
|
-
|
|
646
|
-
async runScript(
|
|
647
|
-
container: ContainerConfig,
|
|
648
|
-
options: { file?: string; sql?: string; database?: string },
|
|
649
|
-
): Promise<void> {
|
|
650
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
651
|
-
if (!entry || !existsSync(entry.filePath)) {
|
|
652
|
-
throw new Error('DuckDB database file not found')
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
const duckdb = await this.requireDuckDBPath()
|
|
656
|
-
|
|
657
|
-
if (options.file) {
|
|
658
|
-
// Run SQL file - pipe file to stdin (avoids shell injection)
|
|
659
|
-
await this.runSqlFile(duckdb, entry.filePath, options.file)
|
|
660
|
-
} else if (options.sql) {
|
|
661
|
-
// Run inline SQL - pass as argument, output to stdout
|
|
662
|
-
const { stdout, stderr } = await execFileAsync(duckdb, [
|
|
663
|
-
entry.filePath,
|
|
664
|
-
'-c',
|
|
665
|
-
options.sql,
|
|
666
|
-
])
|
|
667
|
-
if (stdout) process.stdout.write(stdout)
|
|
668
|
-
if (stderr) process.stderr.write(stderr)
|
|
669
|
-
} else {
|
|
670
|
-
throw new Error('Either file or sql option must be provided')
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
|
|
674
|
-
async fetchAvailableVersions(): Promise<Record<string, string[]>> {
|
|
675
|
-
return fetchAvailableVersions()
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
// Helper to get duckdb path or throw a helpful error
|
|
679
|
-
private async requireDuckDBPath(): Promise<string> {
|
|
680
|
-
const duckdb = await this.getDuckDBPath()
|
|
681
|
-
if (!duckdb) {
|
|
682
|
-
throw new Error(
|
|
683
|
-
'duckdb not found. Ensure DuckDB binaries are downloaded:\n' +
|
|
684
|
-
' spindb engines download duckdb',
|
|
685
|
-
)
|
|
686
|
-
}
|
|
687
|
-
return duckdb
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
async executeQuery(
|
|
691
|
-
container: ContainerConfig,
|
|
692
|
-
query: string,
|
|
693
|
-
_options?: QueryOptions,
|
|
694
|
-
): Promise<QueryResult> {
|
|
695
|
-
const entry = await duckdbRegistry.get(container.name)
|
|
696
|
-
if (!entry || !existsSync(entry.filePath)) {
|
|
697
|
-
throw new Error('DuckDB database file not found')
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
const duckdb = await this.requireDuckDBPath()
|
|
701
|
-
|
|
702
|
-
// Use spawn instead of execFileAsync to stream results
|
|
703
|
-
return new Promise((resolve, reject) => {
|
|
704
|
-
const proc = spawn(duckdb, [
|
|
705
|
-
'-csv',
|
|
706
|
-
'-header',
|
|
707
|
-
entry.filePath,
|
|
708
|
-
'-c',
|
|
709
|
-
query,
|
|
710
|
-
])
|
|
711
|
-
|
|
712
|
-
let stdout = ''
|
|
713
|
-
let stderr = ''
|
|
714
|
-
|
|
715
|
-
proc.stdout?.on('data', (data: Buffer) => {
|
|
716
|
-
stdout += data.toString()
|
|
717
|
-
})
|
|
718
|
-
proc.stderr?.on('data', (data: Buffer) => {
|
|
719
|
-
stderr += data.toString()
|
|
720
|
-
})
|
|
721
|
-
|
|
722
|
-
proc.on('error', reject)
|
|
723
|
-
|
|
724
|
-
proc.on('close', (code) => {
|
|
725
|
-
if (code !== 0) {
|
|
726
|
-
reject(new Error(stderr || `duckdb exited with code ${code}`))
|
|
727
|
-
return
|
|
728
|
-
}
|
|
729
|
-
// Log stderr as debug info if present (warnings, etc.) but don't throw
|
|
730
|
-
if (stderr) {
|
|
731
|
-
logDebug(`DuckDB stderr: ${stderr}`)
|
|
732
|
-
}
|
|
733
|
-
resolve(parseCSVToQueryResult(stdout))
|
|
734
|
-
})
|
|
735
|
-
})
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
/**
|
|
739
|
-
* List databases for DuckDB.
|
|
740
|
-
* DuckDB is file-based with one database per file.
|
|
741
|
-
* Returns the configured database (file path) as a single-item array.
|
|
742
|
-
*/
|
|
743
|
-
async listDatabases(container: ContainerConfig): Promise<string[]> {
|
|
744
|
-
// DuckDB is file-based, one database per file
|
|
745
|
-
return [container.database]
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
|
|
749
|
-
export const duckdbEngine = new DuckDBEngine()
|