@libredb/studio 0.9.7 → 0.9.12
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/chunk-34YQUUCM.mjs +319 -0
- package/dist/chunk-34YQUUCM.mjs.map +1 -0
- package/dist/chunk-4LVB3K53.mjs +37 -0
- package/dist/chunk-4LVB3K53.mjs.map +1 -0
- package/dist/chunk-6DRZXXNT.mjs +100 -0
- package/dist/chunk-6DRZXXNT.mjs.map +1 -0
- package/dist/chunk-CZVV3JJB.mjs +160 -0
- package/dist/chunk-CZVV3JJB.mjs.map +1 -0
- package/dist/chunk-D4WVWWWF.js +332 -0
- package/dist/chunk-D4WVWWWF.js.map +1 -0
- package/dist/chunk-DY3KXE44.mjs +3 -0
- package/dist/chunk-DY3KXE44.mjs.map +1 -0
- package/dist/chunk-DZ2UB3C6.mjs +6679 -0
- package/dist/chunk-DZ2UB3C6.mjs.map +1 -0
- package/dist/chunk-FYSE52VB.js +242 -0
- package/dist/chunk-FYSE52VB.js.map +1 -0
- package/dist/chunk-G4WYE6TI.js +4 -0
- package/dist/chunk-G4WYE6TI.js.map +1 -0
- package/dist/chunk-JOGLIOFO.js +1310 -0
- package/dist/chunk-JOGLIOFO.js.map +1 -0
- package/dist/chunk-JZO5KRZN.js +165 -0
- package/dist/chunk-JZO5KRZN.js.map +1 -0
- package/dist/chunk-KV356UXJ.js +253 -0
- package/dist/chunk-KV356UXJ.js.map +1 -0
- package/dist/chunk-PPODO6HX.mjs +237 -0
- package/dist/chunk-PPODO6HX.mjs.map +1 -0
- package/dist/chunk-PTIRB2JO.js +258 -0
- package/dist/chunk-PTIRB2JO.js.map +1 -0
- package/dist/chunk-Q6LRDBK7.js +42 -0
- package/dist/chunk-Q6LRDBK7.js.map +1 -0
- package/dist/chunk-QJP5FZRY.mjs +255 -0
- package/dist/chunk-QJP5FZRY.mjs.map +1 -0
- package/dist/chunk-R3POCJK6.mjs +248 -0
- package/dist/chunk-R3POCJK6.mjs.map +1 -0
- package/dist/chunk-RBVDMLFV.js +6747 -0
- package/dist/chunk-RBVDMLFV.js.map +1 -0
- package/dist/chunk-RCQB4FCE.js +186 -0
- package/dist/chunk-RCQB4FCE.js.map +1 -0
- package/dist/chunk-SR5DRGBX.mjs +174 -0
- package/dist/chunk-SR5DRGBX.mjs.map +1 -0
- package/dist/chunk-VLCRUZX7.js +102 -0
- package/dist/chunk-VLCRUZX7.js.map +1 -0
- package/dist/chunk-VWVRUCQO.mjs +1289 -0
- package/dist/chunk-VWVRUCQO.mjs.map +1 -0
- package/dist/components.d.mts +273 -0
- package/dist/components.d.ts +273 -0
- package/dist/components.js +59 -0
- package/dist/components.js.map +1 -0
- package/dist/components.mjs +6 -0
- package/dist/components.mjs.map +1 -0
- package/dist/custom-BNDOYC5P.js +134 -0
- package/dist/custom-BNDOYC5P.js.map +1 -0
- package/dist/custom-S2EKFMP3.mjs +132 -0
- package/dist/custom-S2EKFMP3.mjs.map +1 -0
- package/dist/gemini-4ASHNK4H.js +81 -0
- package/dist/gemini-4ASHNK4H.js.map +1 -0
- package/dist/gemini-C5RBLQEJ.mjs +79 -0
- package/dist/gemini-C5RBLQEJ.mjs.map +1 -0
- package/dist/index.d.mts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +10 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mongodb-XMZEZA4A.mjs +748 -0
- package/dist/mongodb-XMZEZA4A.mjs.map +1 -0
- package/dist/mongodb-YQJJTLX3.js +750 -0
- package/dist/mongodb-YQJJTLX3.js.map +1 -0
- package/dist/mssql-PMOU4D36.js +916 -0
- package/dist/mssql-PMOU4D36.js.map +1 -0
- package/{src/lib/db/providers/sql/mssql.ts → dist/mssql-ZH5VP2C5.mjs} +268 -423
- package/dist/mssql-ZH5VP2C5.mjs.map +1 -0
- package/{src/lib/db/providers/sql/mysql.ts → dist/mysql-I3WJQXN2.mjs} +277 -428
- package/dist/mysql-I3WJQXN2.mjs.map +1 -0
- package/dist/mysql-Y3MSA5QY.js +833 -0
- package/dist/mysql-Y3MSA5QY.js.map +1 -0
- package/dist/ollama-26BYLVEV.mjs +115 -0
- package/dist/ollama-26BYLVEV.mjs.map +1 -0
- package/dist/ollama-HVWAGKQC.js +117 -0
- package/dist/ollama-HVWAGKQC.js.map +1 -0
- package/dist/openai-4U56KPG7.mjs +111 -0
- package/dist/openai-4U56KPG7.mjs.map +1 -0
- package/dist/openai-AK3R37BS.js +113 -0
- package/dist/openai-AK3R37BS.js.map +1 -0
- package/dist/oracle-L6VEAVXO.js +917 -0
- package/dist/oracle-L6VEAVXO.js.map +1 -0
- package/{src/lib/db/providers/sql/oracle.ts → dist/oracle-P2G7T4P4.mjs} +321 -454
- package/dist/oracle-P2G7T4P4.mjs.map +1 -0
- package/{src/lib/db/providers/sql/postgres.ts → dist/postgres-O5KOQUVP.mjs} +261 -471
- package/dist/postgres-O5KOQUVP.mjs.map +1 -0
- package/dist/postgres-RLCWNFFX.js +971 -0
- package/dist/postgres-RLCWNFFX.js.map +1 -0
- package/dist/providers.d.mts +149 -0
- package/dist/providers.d.ts +149 -0
- package/dist/providers.js +44 -0
- package/dist/providers.js.map +1 -0
- package/dist/providers.mjs +7 -0
- package/dist/providers.mjs.map +1 -0
- package/dist/redis-4WMQOVLX.mjs +435 -0
- package/dist/redis-4WMQOVLX.mjs.map +1 -0
- package/dist/redis-QVQ6YU62.js +441 -0
- package/dist/redis-QVQ6YU62.js.map +1 -0
- package/dist/sqlite-4I2P2OGQ.js +554 -0
- package/dist/sqlite-4I2P2OGQ.js.map +1 -0
- package/dist/sqlite-OA4YJX5S.mjs +531 -0
- package/dist/sqlite-OA4YJX5S.mjs.map +1 -0
- package/dist/types-BJvJfxSY.d.mts +141 -0
- package/dist/types-BJvJfxSY.d.ts +141 -0
- package/dist/types-ClAg_v5k.d.mts +343 -0
- package/dist/types-Der_X8E8.d.ts +343 -0
- package/dist/types.d.mts +2 -0
- package/dist/types.d.ts +2 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/types.mjs +3 -0
- package/dist/types.mjs.map +1 -0
- package/dist/workspace.d.mts +80 -0
- package/dist/workspace.d.ts +80 -0
- package/dist/workspace.js +4182 -0
- package/dist/workspace.js.map +1 -0
- package/dist/workspace.mjs +4155 -0
- package/dist/workspace.mjs.map +1 -0
- package/package.json +60 -5
- package/.claude/settings.local.json +0 -127
- package/.cursorrules +0 -426
- package/.devin/wiki.json +0 -143
- package/.dockerignore +0 -80
- package/.env.example +0 -159
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -49
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -29
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -57
- package/.github/workflows/ci.yml +0 -185
- package/.github/workflows/codeql.yml +0 -57
- package/.github/workflows/docker-build-push.yml +0 -118
- package/.github/workflows/helm-release.yml +0 -113
- package/CLAUDE.md +0 -265
- package/CODE_OF_CONDUCT.md +0 -124
- package/CONTRIBUTING.md +0 -154
- package/Dockerfile +0 -73
- package/SECURITY.md +0 -107
- package/artifacthub-repo.yml +0 -4
- package/bun.lock +0 -1714
- package/bunfig.toml +0 -3
- package/charts/libredb-studio/.helmignore +0 -11
- package/charts/libredb-studio/Chart.lock +0 -6
- package/charts/libredb-studio/Chart.yaml +0 -50
- package/charts/libredb-studio/README.md +0 -206
- package/charts/libredb-studio/templates/NOTES.txt +0 -59
- package/charts/libredb-studio/templates/_helpers.tpl +0 -135
- package/charts/libredb-studio/templates/configmap.yaml +0 -37
- package/charts/libredb-studio/templates/deployment.yaml +0 -184
- package/charts/libredb-studio/templates/hpa.yaml +0 -32
- package/charts/libredb-studio/templates/ingress.yaml +0 -41
- package/charts/libredb-studio/templates/networkpolicy.yaml +0 -50
- package/charts/libredb-studio/templates/pdb.yaml +0 -18
- package/charts/libredb-studio/templates/pvc.yaml +0 -23
- package/charts/libredb-studio/templates/secret.yaml +0 -30
- package/charts/libredb-studio/templates/seed-configmap.yaml +0 -11
- package/charts/libredb-studio/templates/service.yaml +0 -22
- package/charts/libredb-studio/templates/serviceaccount.yaml +0 -13
- package/charts/libredb-studio/values.schema.json +0 -246
- package/charts/libredb-studio/values.yaml +0 -286
- package/components.json +0 -22
- package/conductor/code_styleguides/typescript.md +0 -43
- package/conductor/product-guidelines.md +0 -43
- package/conductor/product.md +0 -3
- package/conductor/setup_state.json +0 -1
- package/conductor/tech-stack.md +0 -39
- package/conductor/tracks/enhance_postgres_monitoring_20251227/metadata.json +0 -8
- package/conductor/tracks/enhance_postgres_monitoring_20251227/plan.md +0 -44
- package/conductor/tracks/enhance_postgres_monitoring_20251227/spec.md +0 -31
- package/conductor/tracks.md +0 -8
- package/conductor/workflow.md +0 -333
- package/database-compose.yml +0 -55
- package/docker/postgres-init/01-extensions.sql +0 -10
- package/docker/postgres-init/02-sample-data.sql +0 -585
- package/docker/postgres.yml +0 -68
- package/docker-compose.yml +0 -38
- package/docs/AI_PLAN.md +0 -74
- package/docs/API_DOCS.md +0 -875
- package/docs/ARCHITECTURE.md +0 -218
- package/docs/DATABASE_PROVIDERS.md +0 -358
- package/docs/FEATURES.md +0 -116
- package/docs/HELM_CHART.md +0 -252
- package/docs/LOGIN_PAGE.md +0 -178
- package/docs/MONACO_EDITOR_PERFORMANCE.md +0 -315
- package/docs/OIDC_ARCH.md +0 -681
- package/docs/OIDC_SETUP.md +0 -322
- package/docs/POSTGRES_METRICS.md +0 -516
- package/docs/QUERY_OPTIMIZATION.md +0 -370
- package/docs/SEED_CONNECTIONS.md +0 -468
- package/docs/SQL_ALIAS_COMPLETION.md +0 -190
- package/docs/STORAGE_ARCHITECTURE.md +0 -565
- package/docs/STORAGE_QUICK_SETUP.md +0 -419
- package/docs/TECHNICAL_PLAN.md +0 -36
- package/docs/THEMING.md +0 -345
- package/docs/adding-a-new-database-provider.md +0 -642
- package/docs/backlogs/000-PLATFORM_DATA_SYNC_DATABASE.md +0 -360
- package/docs/backlogs/001-INLINE_DATA_EDITING.md +0 -118
- package/docs/backlogs/002-DATA_IMPORT.md +0 -215
- package/docs/backlogs/003-QUERY_TIME_MACHINE.md +0 -183
- package/docs/backlogs/004-AI_DATA_STORYTELLER.md +0 -292
- package/docs/backlogs/005-QUERY_PLAYGROUND.md +0 -352
- package/docs/backlogs/006-DATA_MASKING.md +0 -418
- package/docs/enterprise-features.md +0 -718
- package/docs/kubernetes-helm-chart-artifacthub-plan.md +0 -803
- package/docs/medium-koyeb-article-en.md +0 -215
- package/docs/plans/test-plans.md +0 -445
- package/docs/releases/RELEASE.V0.3.0.md +0 -22
- package/docs/releases/RELEASE.V0.4.0.md +0 -154
- package/docs/releases/RELEASE.V0.5.0.md +0 -252
- package/docs/releases/RELEASE_v0.5.6.md +0 -145
- package/docs/releases/RELEASE_v0.6.1.md +0 -303
- package/docs/releases/RELEASE_v0.6.7.md +0 -292
- package/docs/releases/RELEASE_v0.7.0.md +0 -332
- package/docs/releases/RELEASE_v0.8.0.md +0 -521
- package/docs/sampledb/titanic.sql +0 -1379
- package/docs/superpowers/plans/2026-03-25-seed-connections.md +0 -1362
- package/docs/superpowers/specs/2026-03-25-seed-connections-design.md +0 -590
- package/e2e/admin-dashboard.spec.ts +0 -64
- package/e2e/connection-management.spec.ts +0 -58
- package/e2e/export.spec.ts +0 -34
- package/e2e/login.spec.ts +0 -85
- package/e2e/query-execution.spec.ts +0 -35
- package/e2e/tab-management.spec.ts +0 -64
- package/eslint.config.mjs +0 -28
- package/fly.toml +0 -43
- package/next.config.ts +0 -32
- package/playwright.config.ts +0 -34
- package/postcss.config.mjs +0 -7
- package/public/favicon-32x32.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/file.svg +0 -1
- package/public/globe.svg +0 -1
- package/public/logo.svg +0 -32
- package/public/next.svg +0 -1
- package/public/screenshots/code-generator.png +0 -0
- package/public/screenshots/connection-modal.png +0 -0
- package/public/screenshots/data-profiler.png +0 -0
- package/public/screenshots/erd-diagram.png +0 -0
- package/public/screenshots/hero-editor.png +0 -0
- package/public/screenshots/nl2sql.png +0 -0
- package/public/vercel.svg +0 -1
- package/public/window.svg +0 -1
- package/render.yaml +0 -58
- package/scripts/merge-lcov.mjs +0 -239
- package/sonar-project.properties +0 -16
- package/src/app/admin/error.tsx +0 -46
- package/src/app/admin/page.tsx +0 -10
- package/src/app/api/admin/audit/route.ts +0 -52
- package/src/app/api/admin/fleet-health/route.ts +0 -81
- package/src/app/api/ai/autopilot/route.ts +0 -105
- package/src/app/api/ai/chat/route.ts +0 -132
- package/src/app/api/ai/describe-schema/route.ts +0 -52
- package/src/app/api/ai/explain/route.ts +0 -86
- package/src/app/api/ai/impact/route.ts +0 -97
- package/src/app/api/ai/index-advisor/route.ts +0 -98
- package/src/app/api/ai/nl2sql/route.ts +0 -87
- package/src/app/api/ai/query-safety/route.ts +0 -87
- package/src/app/api/auth/login/route.ts +0 -62
- package/src/app/api/auth/logout/route.ts +0 -25
- package/src/app/api/auth/me/route.ts +0 -10
- package/src/app/api/auth/oidc/callback/route.ts +0 -82
- package/src/app/api/auth/oidc/login/route.ts +0 -43
- package/src/app/api/connections/managed/route.ts +0 -35
- package/src/app/api/db/cancel/route.ts +0 -42
- package/src/app/api/db/disconnect/route.ts +0 -28
- package/src/app/api/db/health/route.ts +0 -49
- package/src/app/api/db/maintenance/route.ts +0 -72
- package/src/app/api/db/monitoring/route.ts +0 -62
- package/src/app/api/db/multi-query/route.ts +0 -116
- package/src/app/api/db/pool-stats/route.ts +0 -37
- package/src/app/api/db/profile/route.ts +0 -144
- package/src/app/api/db/provider-meta/route.ts +0 -49
- package/src/app/api/db/query/route.ts +0 -50
- package/src/app/api/db/schema/route.ts +0 -47
- package/src/app/api/db/schema-snapshot/route.ts +0 -42
- package/src/app/api/db/test-connection/route.ts +0 -55
- package/src/app/api/db/transaction/route.ts +0 -111
- package/src/app/api/storage/[collection]/route.ts +0 -67
- package/src/app/api/storage/config/route.ts +0 -17
- package/src/app/api/storage/migrate/route.ts +0 -45
- package/src/app/api/storage/route.ts +0 -32
- package/src/app/error.tsx +0 -49
- package/src/app/global-error.tsx +0 -55
- package/src/app/globals.css +0 -146
- package/src/app/icon.svg +0 -42
- package/src/app/layout.tsx +0 -34
- package/src/app/login/login-form.tsx +0 -301
- package/src/app/login/page.tsx +0 -11
- package/src/app/monitoring/page.tsx +0 -8
- package/src/app/not-found.tsx +0 -29
- package/src/app/page.tsx +0 -5
- package/src/components/AIAutopilotPanel.tsx +0 -238
- package/src/components/CodeGenerator.tsx +0 -271
- package/src/components/CommandPalette.tsx +0 -227
- package/src/components/ConnectionModal.tsx +0 -759
- package/src/components/CreateTableModal.tsx +0 -281
- package/src/components/DataCharts.tsx +0 -962
- package/src/components/DataImportModal.tsx +0 -582
- package/src/components/DataProfiler.tsx +0 -335
- package/src/components/DatabaseDocs.tsx +0 -251
- package/src/components/MaskingSettings.tsx +0 -414
- package/src/components/MobileNav.tsx +0 -50
- package/src/components/NL2SQLPanel.tsx +0 -281
- package/src/components/PivotTable.tsx +0 -257
- package/src/components/QueryEditor.tsx +0 -760
- package/src/components/QueryHistory.tsx +0 -344
- package/src/components/QuerySafetyDialog.tsx +0 -290
- package/src/components/ResultsGrid.tsx +0 -644
- package/src/components/SaveQueryModal.tsx +0 -104
- package/src/components/SavedQueries.tsx +0 -128
- package/src/components/SchemaDiagram.tsx +0 -473
- package/src/components/SchemaDiff.tsx +0 -473
- package/src/components/SnapshotTimeline.tsx +0 -116
- package/src/components/Studio.tsx +0 -639
- package/src/components/TestDataGenerator.tsx +0 -261
- package/src/components/VisualExplain.tsx +0 -820
- package/src/components/admin/AdminDashboard.tsx +0 -163
- package/src/components/admin/tabs/AuditTab.tsx +0 -531
- package/src/components/admin/tabs/MonitoringEmbed.tsx +0 -11
- package/src/components/admin/tabs/OperationsTab.tsx +0 -646
- package/src/components/admin/tabs/OverviewTab.tsx +0 -1328
- package/src/components/admin/tabs/SecurityTab.tsx +0 -284
- package/src/components/community-section.tsx +0 -92
- package/src/components/icons/db-icons.tsx +0 -84
- package/src/components/libredb-logo.tsx +0 -61
- package/src/components/monitoring/MonitoringDashboard.tsx +0 -345
- package/src/components/monitoring/tabs/MetricChart.tsx +0 -82
- package/src/components/monitoring/tabs/OverviewTab.tsx +0 -263
- package/src/components/monitoring/tabs/PerformanceTab.tsx +0 -254
- package/src/components/monitoring/tabs/PoolTab.tsx +0 -174
- package/src/components/monitoring/tabs/QueriesTab.tsx +0 -287
- package/src/components/monitoring/tabs/SessionsTab.tsx +0 -316
- package/src/components/monitoring/tabs/StorageTab.tsx +0 -335
- package/src/components/monitoring/tabs/TablesTab.tsx +0 -300
- package/src/components/results-grid/ResultCard.tsx +0 -111
- package/src/components/results-grid/RowDetailSheet.tsx +0 -178
- package/src/components/results-grid/StatsBar.tsx +0 -201
- package/src/components/results-grid/index.ts +0 -1
- package/src/components/results-grid/utils.ts +0 -23
- package/src/components/schema-explorer/ColumnList.tsx +0 -53
- package/src/components/schema-explorer/SchemaExplorer.tsx +0 -182
- package/src/components/schema-explorer/TableItem.tsx +0 -210
- package/src/components/schema-explorer/index.ts +0 -1
- package/src/components/sidebar/ConnectionItem.tsx +0 -105
- package/src/components/sidebar/ConnectionsList.tsx +0 -62
- package/src/components/sidebar/Sidebar.tsx +0 -130
- package/src/components/sidebar/index.ts +0 -2
- package/src/components/studio/BottomPanel.tsx +0 -286
- package/src/components/studio/QueryToolbar.tsx +0 -180
- package/src/components/studio/StudioDesktopHeader.tsx +0 -114
- package/src/components/studio/StudioMobileHeader.tsx +0 -340
- package/src/components/studio/StudioTabBar.tsx +0 -82
- package/src/components/studio/index.ts +0 -5
- package/src/components/ui/accordion.tsx +0 -66
- package/src/components/ui/alert-dialog.tsx +0 -157
- package/src/components/ui/alert.tsx +0 -66
- package/src/components/ui/aspect-ratio.tsx +0 -11
- package/src/components/ui/avatar.tsx +0 -53
- package/src/components/ui/badge.tsx +0 -46
- package/src/components/ui/breadcrumb.tsx +0 -109
- package/src/components/ui/button-group.tsx +0 -83
- package/src/components/ui/button.tsx +0 -60
- package/src/components/ui/calendar.tsx +0 -216
- package/src/components/ui/card.tsx +0 -92
- package/src/components/ui/carousel.tsx +0 -241
- package/src/components/ui/chart.tsx +0 -357
- package/src/components/ui/checkbox.tsx +0 -32
- package/src/components/ui/collapsible.tsx +0 -33
- package/src/components/ui/command.tsx +0 -184
- package/src/components/ui/context-menu.tsx +0 -252
- package/src/components/ui/dialog.tsx +0 -143
- package/src/components/ui/drawer.tsx +0 -135
- package/src/components/ui/dropdown-menu.tsx +0 -257
- package/src/components/ui/empty.tsx +0 -104
- package/src/components/ui/field.tsx +0 -248
- package/src/components/ui/form.tsx +0 -167
- package/src/components/ui/hover-card.tsx +0 -44
- package/src/components/ui/input-group.tsx +0 -170
- package/src/components/ui/input-otp.tsx +0 -77
- package/src/components/ui/input.tsx +0 -21
- package/src/components/ui/item.tsx +0 -193
- package/src/components/ui/kbd.tsx +0 -28
- package/src/components/ui/label.tsx +0 -24
- package/src/components/ui/menubar.tsx +0 -276
- package/src/components/ui/navigation-menu.tsx +0 -168
- package/src/components/ui/pagination.tsx +0 -127
- package/src/components/ui/popover.tsx +0 -48
- package/src/components/ui/progress.tsx +0 -31
- package/src/components/ui/radio-group.tsx +0 -45
- package/src/components/ui/resizable.tsx +0 -56
- package/src/components/ui/scroll-area.tsx +0 -58
- package/src/components/ui/select.tsx +0 -187
- package/src/components/ui/separator.tsx +0 -28
- package/src/components/ui/sheet.tsx +0 -139
- package/src/components/ui/sidebar.tsx +0 -726
- package/src/components/ui/skeleton.tsx +0 -13
- package/src/components/ui/slider.tsx +0 -63
- package/src/components/ui/sonner.tsx +0 -40
- package/src/components/ui/spinner.tsx +0 -16
- package/src/components/ui/switch.tsx +0 -31
- package/src/components/ui/table.tsx +0 -116
- package/src/components/ui/tabs.tsx +0 -66
- package/src/components/ui/textarea.tsx +0 -18
- package/src/components/ui/toggle-group.tsx +0 -83
- package/src/components/ui/toggle.tsx +0 -47
- package/src/components/ui/tooltip.tsx +0 -61
- package/src/exports/components.ts +0 -15
- package/src/exports/index.ts +0 -4
- package/src/exports/providers.ts +0 -4
- package/src/exports/types.ts +0 -26
- package/src/hooks/use-ai-chat.ts +0 -182
- package/src/hooks/use-all-connections.ts +0 -66
- package/src/hooks/use-api-call.ts +0 -71
- package/src/hooks/use-auth.ts +0 -51
- package/src/hooks/use-connection-form.ts +0 -349
- package/src/hooks/use-connection-manager.ts +0 -169
- package/src/hooks/use-connection-payload.ts +0 -15
- package/src/hooks/use-inline-editing.ts +0 -109
- package/src/hooks/use-mobile.ts +0 -20
- package/src/hooks/use-monitoring-data.ts +0 -270
- package/src/hooks/use-provider-metadata.ts +0 -62
- package/src/hooks/use-query-execution.ts +0 -478
- package/src/hooks/use-storage-sync.ts +0 -259
- package/src/hooks/use-tab-manager.ts +0 -231
- package/src/hooks/use-toast.ts +0 -20
- package/src/hooks/use-transaction-control.ts +0 -64
- package/src/lib/api/error-codes.ts +0 -30
- package/src/lib/api/errors.ts +0 -236
- package/src/lib/api/with-error-handler.ts +0 -41
- package/src/lib/audit.ts +0 -105
- package/src/lib/auth.ts +0 -87
- package/src/lib/connection-string-parser.ts +0 -172
- package/src/lib/data-masking.ts +0 -385
- package/src/lib/db/base-provider.ts +0 -325
- package/src/lib/db/errors.ts +0 -317
- package/src/lib/db/factory.ts +0 -324
- package/src/lib/db/index.ts +0 -123
- package/src/lib/db/providers/document/index.ts +0 -6
- package/src/lib/db/providers/document/mongodb.ts +0 -992
- package/src/lib/db/providers/keyvalue/redis.ts +0 -554
- package/src/lib/db/providers/sql/index.ts +0 -11
- package/src/lib/db/providers/sql/sql-base.ts +0 -174
- package/src/lib/db/providers/sql/sqlite.ts +0 -721
- package/src/lib/db/types.ts +0 -437
- package/src/lib/db/utils/pool-manager.ts +0 -287
- package/src/lib/db/utils/query-limiter.ts +0 -239
- package/src/lib/db-ui-config.ts +0 -86
- package/src/lib/editor/mongodb-completions.ts +0 -172
- package/src/lib/editor/sql-completions.ts +0 -280
- package/src/lib/llm/base-provider.ts +0 -117
- package/src/lib/llm/factory.ts +0 -102
- package/src/lib/llm/index.ts +0 -90
- package/src/lib/llm/providers/custom.ts +0 -181
- package/src/lib/llm/providers/gemini.ts +0 -126
- package/src/lib/llm/providers/ollama.ts +0 -154
- package/src/lib/llm/providers/openai.ts +0 -146
- package/src/lib/llm/types.ts +0 -173
- package/src/lib/llm/utils/config.ts +0 -187
- package/src/lib/llm/utils/retry.ts +0 -119
- package/src/lib/llm/utils/streaming.ts +0 -202
- package/src/lib/logger.ts +0 -127
- package/src/lib/monitoring-thresholds.ts +0 -44
- package/src/lib/oidc.ts +0 -262
- package/src/lib/query-generators.ts +0 -61
- package/src/lib/schema-diff/diff-engine.ts +0 -273
- package/src/lib/schema-diff/migration-generator.ts +0 -208
- package/src/lib/schema-diff/types.ts +0 -55
- package/src/lib/seed/config-loader.ts +0 -79
- package/src/lib/seed/connection-filter.ts +0 -49
- package/src/lib/seed/credential-resolver.ts +0 -62
- package/src/lib/seed/index.ts +0 -40
- package/src/lib/seed/resolve-connection.ts +0 -57
- package/src/lib/seed/types.ts +0 -69
- package/src/lib/sql/alias-extractor.ts +0 -267
- package/src/lib/sql/index.ts +0 -8
- package/src/lib/sql/statement-splitter.ts +0 -167
- package/src/lib/sql/types.ts +0 -40
- package/src/lib/ssh/tunnel.ts +0 -142
- package/src/lib/storage/factory.ts +0 -84
- package/src/lib/storage/index.ts +0 -14
- package/src/lib/storage/local-storage.ts +0 -99
- package/src/lib/storage/providers/postgres.ts +0 -225
- package/src/lib/storage/providers/sqlite.ts +0 -153
- package/src/lib/storage/storage-facade.ts +0 -272
- package/src/lib/storage/types.ts +0 -75
- package/src/lib/time-series-buffer.ts +0 -58
- package/src/lib/types.ts +0 -173
- package/src/lib/utils.ts +0 -6
- package/src/proxy.ts +0 -104
- package/src/types/db-drivers.d.ts +0 -23
- package/src/types/html2canvas.d.ts +0 -9
- package/tests/api/admin/audit.test.ts +0 -178
- package/tests/api/admin/fleet-health.test.ts +0 -183
- package/tests/api/ai/autopilot.test.ts +0 -174
- package/tests/api/ai/chat.test.ts +0 -250
- package/tests/api/ai/describe-schema.test.ts +0 -266
- package/tests/api/ai/explain.test.ts +0 -199
- package/tests/api/ai/impact.test.ts +0 -168
- package/tests/api/ai/index-advisor.test.ts +0 -171
- package/tests/api/ai/nl2sql.test.ts +0 -202
- package/tests/api/ai/query-safety.test.ts +0 -196
- package/tests/api/auth/login.test.ts +0 -170
- package/tests/api/auth/logout.test.ts +0 -140
- package/tests/api/auth/me.test.ts +0 -73
- package/tests/api/auth/oidc-callback.test.ts +0 -215
- package/tests/api/auth/oidc-login.test.ts +0 -127
- package/tests/api/db/cancel.test.ts +0 -198
- package/tests/api/db/disconnect.test.ts +0 -124
- package/tests/api/db/health.test.ts +0 -222
- package/tests/api/db/maintenance.test.ts +0 -263
- package/tests/api/db/monitoring.test.ts +0 -221
- package/tests/api/db/multi-query.test.ts +0 -316
- package/tests/api/db/pool-stats.test.ts +0 -135
- package/tests/api/db/profile.test.ts +0 -330
- package/tests/api/db/provider-meta.test.ts +0 -193
- package/tests/api/db/query.test.ts +0 -314
- package/tests/api/db/schema-snapshot.test.ts +0 -170
- package/tests/api/db/schema.test.ts +0 -191
- package/tests/api/db/test-connection.test.ts +0 -185
- package/tests/api/db/transaction.test.ts +0 -314
- package/tests/api/proxy.test.ts +0 -191
- package/tests/api/seed/managed-route.test.ts +0 -113
- package/tests/api/storage/config.test.ts +0 -42
- package/tests/api/storage/storage-routes.test.ts +0 -309
- package/tests/components/AIAutopilotPanel.test.tsx +0 -756
- package/tests/components/AdminPage.test.tsx +0 -33
- package/tests/components/CodeGenerator.test.tsx +0 -182
- package/tests/components/CommandPalette.test.tsx +0 -428
- package/tests/components/CommunitySection.test.tsx +0 -91
- package/tests/components/ConnectionModal.mobile.test.tsx +0 -284
- package/tests/components/ConnectionModal.test.tsx +0 -570
- package/tests/components/CreateTableModal.test.tsx +0 -383
- package/tests/components/DataCharts.test.tsx +0 -739
- package/tests/components/DataImportModal.test.tsx +0 -751
- package/tests/components/DataProfiler.test.tsx +0 -589
- package/tests/components/DatabaseDocs.test.tsx +0 -353
- package/tests/components/LoginPage.test.tsx +0 -163
- package/tests/components/LoginPageOIDC.test.tsx +0 -92
- package/tests/components/MaskingSettings.test.tsx +0 -498
- package/tests/components/MobileNav.test.tsx +0 -30
- package/tests/components/MonitoringPage.test.tsx +0 -32
- package/tests/components/NL2SQLPanel.test.tsx +0 -621
- package/tests/components/Page.test.tsx +0 -33
- package/tests/components/PivotTable.test.tsx +0 -350
- package/tests/components/QueryEditor.test.tsx +0 -1730
- package/tests/components/QueryHistory.test.tsx +0 -572
- package/tests/components/QuerySafetyDialog.test.tsx +0 -586
- package/tests/components/ResultsGrid.test.tsx +0 -804
- package/tests/components/RootLayout.test.tsx +0 -83
- package/tests/components/SaveQueryModal.test.tsx +0 -25
- package/tests/components/SavedQueries.test.tsx +0 -43
- package/tests/components/SchemaDiagram.test.tsx +0 -1034
- package/tests/components/SchemaDiff.test.tsx +0 -906
- package/tests/components/SnapshotTimeline.test.tsx +0 -174
- package/tests/components/Studio.test.tsx +0 -1030
- package/tests/components/TestDataGenerator.test.tsx +0 -291
- package/tests/components/VisualExplain.test.tsx +0 -704
- package/tests/components/admin/AdminDashboard.test.tsx +0 -205
- package/tests/components/admin/AuditTab.test.tsx +0 -220
- package/tests/components/admin/MonitoringEmbed.test.tsx +0 -58
- package/tests/components/admin/OperationsTab.test.tsx +0 -975
- package/tests/components/admin/OverviewTab.test.tsx +0 -254
- package/tests/components/admin/SecurityTab.test.tsx +0 -467
- package/tests/components/monitoring/MetricChart.test.tsx +0 -111
- package/tests/components/monitoring/MonitoringDashboard.test.tsx +0 -259
- package/tests/components/monitoring/OverviewTab.test.tsx +0 -78
- package/tests/components/monitoring/PerformanceTab.test.tsx +0 -87
- package/tests/components/monitoring/PoolTab.test.tsx +0 -42
- package/tests/components/monitoring/QueriesTab.test.tsx +0 -80
- package/tests/components/monitoring/SessionsTab.test.tsx +0 -154
- package/tests/components/monitoring/StorageTab.test.tsx +0 -127
- package/tests/components/monitoring/TablesTab.test.tsx +0 -153
- package/tests/components/results-grid/ResultCard.test.tsx +0 -105
- package/tests/components/results-grid/RowDetailSheet.test.tsx +0 -308
- package/tests/components/results-grid/StatsBar.test.tsx +0 -162
- package/tests/components/schema-explorer/ColumnList.test.tsx +0 -151
- package/tests/components/schema-explorer/SchemaExplorer.test.tsx +0 -461
- package/tests/components/schema-explorer/TableItem.test.tsx +0 -415
- package/tests/components/sidebar/ConnectionItem.test.tsx +0 -201
- package/tests/components/sidebar/ConnectionsList.test.tsx +0 -176
- package/tests/components/sidebar/Sidebar.test.tsx +0 -187
- package/tests/components/studio/BottomPanel.test.tsx +0 -383
- package/tests/components/studio/QueryToolbar.test.tsx +0 -321
- package/tests/components/studio/StudioDesktopHeader.test.tsx +0 -377
- package/tests/components/studio/StudioMobileHeader.test.tsx +0 -198
- package/tests/components/studio/StudioTabBar.test.tsx +0 -331
- package/tests/fixtures/connections.ts +0 -96
- package/tests/fixtures/masking-configs.ts +0 -86
- package/tests/fixtures/query-results.ts +0 -71
- package/tests/fixtures/schemas.ts +0 -64
- package/tests/fixtures/seed-connections/invalid-config.yaml +0 -7
- package/tests/fixtures/seed-connections/minimal-config.yaml +0 -8
- package/tests/fixtures/seed-connections/mixed-credentials.yaml +0 -23
- package/tests/fixtures/seed-connections/multi-role-config.yaml +0 -30
- package/tests/fixtures/seed-connections/valid-config.json +0 -15
- package/tests/fixtures/seed-connections/valid-config.yaml +0 -51
- package/tests/helpers/mock-fetch.ts +0 -59
- package/tests/helpers/mock-monaco.ts +0 -112
- package/tests/helpers/mock-navigation.ts +0 -28
- package/tests/helpers/mock-next.ts +0 -80
- package/tests/helpers/mock-provider.ts +0 -133
- package/tests/helpers/mock-sonner.ts +0 -29
- package/tests/helpers/render-with-providers.tsx +0 -19
- package/tests/hooks/use-ai-chat.test.ts +0 -600
- package/tests/hooks/use-auth.test.ts +0 -371
- package/tests/hooks/use-connection-form.test.ts +0 -743
- package/tests/hooks/use-connection-manager.test.ts +0 -466
- package/tests/hooks/use-inline-editing.test.ts +0 -321
- package/tests/hooks/use-mobile.test.ts +0 -177
- package/tests/hooks/use-monitoring-data.test.ts +0 -819
- package/tests/hooks/use-provider-metadata.test.ts +0 -228
- package/tests/hooks/use-query-execution.test.ts +0 -1212
- package/tests/hooks/use-tab-manager.test.ts +0 -756
- package/tests/hooks/use-toast.test.ts +0 -74
- package/tests/hooks/use-transaction-control.test.ts +0 -211
- package/tests/integration/db/mongodb-provider.test.ts +0 -698
- package/tests/integration/db/mssql-provider.test.ts +0 -840
- package/tests/integration/db/mysql-provider.test.ts +0 -872
- package/tests/integration/db/oracle-provider.test.ts +0 -843
- package/tests/integration/db/postgres-provider.test.ts +0 -1382
- package/tests/integration/db/redis-provider.test.ts +0 -526
- package/tests/integration/db/sqlite-provider.test.ts +0 -480
- package/tests/integration/seed/seed-pipeline.test.ts +0 -102
- package/tests/isolated/factory-singleton.test.ts +0 -150
- package/tests/isolated/use-storage-sync.test.ts +0 -389
- package/tests/run-components.sh +0 -196
- package/tests/setup-dom.ts +0 -58
- package/tests/setup.ts +0 -40
- package/tests/unit/api-errors.test.ts +0 -210
- package/tests/unit/code-generator-functions.test.ts +0 -271
- package/tests/unit/components/column-list.test.tsx +0 -190
- package/tests/unit/components/data-import-modal.test.tsx +0 -441
- package/tests/unit/components/studio-mobile-header.test.tsx +0 -327
- package/tests/unit/data-charts-functions.test.ts +0 -496
- package/tests/unit/data-import-functions.test.ts +0 -320
- package/tests/unit/data-import-utils.test.ts +0 -125
- package/tests/unit/db/base-provider.test.ts +0 -517
- package/tests/unit/db/errors.test.ts +0 -403
- package/tests/unit/db/factory.test.ts +0 -436
- package/tests/unit/db/pool-manager.test.ts +0 -440
- package/tests/unit/db/query-limiter.test.ts +0 -387
- package/tests/unit/db/sql-base.test.ts +0 -438
- package/tests/unit/lib/api/error-codes.test.ts +0 -39
- package/tests/unit/lib/audit.test.ts +0 -326
- package/tests/unit/lib/auth.test.ts +0 -146
- package/tests/unit/lib/connection-string-parser.test.ts +0 -424
- package/tests/unit/lib/data-masking.test.ts +0 -583
- package/tests/unit/lib/db-icons.test.tsx +0 -41
- package/tests/unit/lib/monitoring-thresholds.test.ts +0 -133
- package/tests/unit/lib/oidc.test.ts +0 -509
- package/tests/unit/lib/query-generators.test.ts +0 -127
- package/tests/unit/lib/storage/factory.test.ts +0 -71
- package/tests/unit/lib/storage/local-storage.test.ts +0 -114
- package/tests/unit/lib/storage/providers/postgres.test.ts +0 -312
- package/tests/unit/lib/storage/providers/sqlite.test.ts +0 -232
- package/tests/unit/lib/storage/storage-facade-extended.test.ts +0 -331
- package/tests/unit/lib/storage/storage-facade.test.ts +0 -184
- package/tests/unit/lib/storage.test.ts +0 -317
- package/tests/unit/lib/time-series-buffer.test.ts +0 -212
- package/tests/unit/lib/utils.test.ts +0 -24
- package/tests/unit/llm/base-provider.test.ts +0 -238
- package/tests/unit/llm/config.test.ts +0 -262
- package/tests/unit/llm/custom-provider.test.ts +0 -281
- package/tests/unit/llm/gemini-provider.test.ts +0 -248
- package/tests/unit/llm/llm-factory.test.ts +0 -155
- package/tests/unit/llm/ollama-provider.test.ts +0 -288
- package/tests/unit/llm/openai-provider.test.ts +0 -324
- package/tests/unit/llm/retry.test.ts +0 -180
- package/tests/unit/llm/streaming.test.ts +0 -355
- package/tests/unit/logger.test.ts +0 -198
- package/tests/unit/mongodb-completions.test.ts +0 -516
- package/tests/unit/pivot-table-functions.test.ts +0 -76
- package/tests/unit/query-cancelled-error.test.ts +0 -81
- package/tests/unit/schema-diff/diff-engine.test.ts +0 -367
- package/tests/unit/schema-diff/migration-generator.test.ts +0 -513
- package/tests/unit/seed/config-loader.test.ts +0 -73
- package/tests/unit/seed/connection-filter.test.ts +0 -91
- package/tests/unit/seed/credential-resolver.test.ts +0 -85
- package/tests/unit/seed/index.test.ts +0 -72
- package/tests/unit/seed/resolve-connection.test.ts +0 -74
- package/tests/unit/seed/types.test.ts +0 -129
- package/tests/unit/sql/alias-extractor.test.ts +0 -444
- package/tests/unit/sql/statement-splitter.test.ts +0 -348
- package/tests/unit/sql-completions.test.ts +0 -463
- package/tests/unit/ssh-tunnel.test.ts +0 -465
- package/tsconfig.json +0 -42
|
@@ -0,0 +1,971 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkKV356UXJ_js = require('./chunk-KV356UXJ.js');
|
|
4
|
+
var chunkPTIRB2JO_js = require('./chunk-PTIRB2JO.js');
|
|
5
|
+
var chunkJZO5KRZN_js = require('./chunk-JZO5KRZN.js');
|
|
6
|
+
var chunkQ6LRDBK7_js = require('./chunk-Q6LRDBK7.js');
|
|
7
|
+
var pg = require('pg');
|
|
8
|
+
|
|
9
|
+
var _PostgresProvider = class _PostgresProvider extends chunkKV356UXJ_js.SQLBaseProvider {
|
|
10
|
+
// 5 minutes
|
|
11
|
+
constructor(config, options = {}) {
|
|
12
|
+
super(config, options);
|
|
13
|
+
this.pool = null;
|
|
14
|
+
// Transaction support: dedicated client held outside pool
|
|
15
|
+
this.txClient = null;
|
|
16
|
+
this.txActive = false;
|
|
17
|
+
this.txTimeout = null;
|
|
18
|
+
// ============================================================================
|
|
19
|
+
// Query Execution
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Track running query PIDs for cancellation
|
|
22
|
+
this.runningQueryPids = /* @__PURE__ */ new Map();
|
|
23
|
+
this.validate();
|
|
24
|
+
}
|
|
25
|
+
// ============================================================================
|
|
26
|
+
// Provider Metadata
|
|
27
|
+
// ============================================================================
|
|
28
|
+
getCapabilities() {
|
|
29
|
+
return chunkQ6LRDBK7_js.__spreadProps(chunkQ6LRDBK7_js.__spreadValues({}, super.getCapabilities()), {
|
|
30
|
+
defaultPort: 5432,
|
|
31
|
+
supportsExplain: true,
|
|
32
|
+
supportsConnectionString: true,
|
|
33
|
+
maintenanceOperations: ["vacuum", "analyze", "reindex", "kill"]
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// ============================================================================
|
|
37
|
+
// Validation
|
|
38
|
+
// ============================================================================
|
|
39
|
+
validate() {
|
|
40
|
+
super.validate();
|
|
41
|
+
if (!this.config.connectionString) {
|
|
42
|
+
if (!this.config.host) {
|
|
43
|
+
throw new chunkJZO5KRZN_js.DatabaseConfigError("Host is required for PostgreSQL", "postgres");
|
|
44
|
+
}
|
|
45
|
+
if (!this.config.database) {
|
|
46
|
+
throw new chunkJZO5KRZN_js.DatabaseConfigError("Database name is required for PostgreSQL", "postgres");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
// ============================================================================
|
|
51
|
+
// Connection Management
|
|
52
|
+
// ============================================================================
|
|
53
|
+
async connect() {
|
|
54
|
+
if (this.pool) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const poolConfig = this.buildPoolConfig();
|
|
59
|
+
this.pool = new pg.Pool(poolConfig);
|
|
60
|
+
const client = await this.pool.connect();
|
|
61
|
+
client.release();
|
|
62
|
+
this.setConnected(true);
|
|
63
|
+
} catch (error) {
|
|
64
|
+
this.setError(error instanceof Error ? error : new Error(String(error)));
|
|
65
|
+
throw new chunkJZO5KRZN_js.ConnectionError(
|
|
66
|
+
`Failed to connect to PostgreSQL: ${error instanceof Error ? error.message : error}`,
|
|
67
|
+
"postgres",
|
|
68
|
+
this.config.host,
|
|
69
|
+
this.config.port
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async disconnect() {
|
|
74
|
+
if (this.pool) {
|
|
75
|
+
await this.pool.end();
|
|
76
|
+
this.pool = null;
|
|
77
|
+
this.setConnected(false);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
buildPoolConfig() {
|
|
81
|
+
var _a;
|
|
82
|
+
const sslConfig = this.buildSSLConfig();
|
|
83
|
+
const baseConfig = {
|
|
84
|
+
min: this.poolConfig.min,
|
|
85
|
+
max: this.poolConfig.max,
|
|
86
|
+
idleTimeoutMillis: this.poolConfig.idleTimeout,
|
|
87
|
+
connectionTimeoutMillis: this.poolConfig.acquireTimeout,
|
|
88
|
+
statement_timeout: this.queryTimeout,
|
|
89
|
+
ssl: sslConfig
|
|
90
|
+
};
|
|
91
|
+
if (this.config.connectionString) {
|
|
92
|
+
return chunkQ6LRDBK7_js.__spreadProps(chunkQ6LRDBK7_js.__spreadValues({}, baseConfig), {
|
|
93
|
+
connectionString: this.config.connectionString
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return chunkQ6LRDBK7_js.__spreadProps(chunkQ6LRDBK7_js.__spreadValues({}, baseConfig), {
|
|
97
|
+
host: this.config.host,
|
|
98
|
+
port: (_a = this.config.port) != null ? _a : 5432,
|
|
99
|
+
user: this.config.user,
|
|
100
|
+
password: this.config.password,
|
|
101
|
+
database: this.config.database
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
buildSSLConfig() {
|
|
105
|
+
const connSSL = this.config.ssl;
|
|
106
|
+
if (connSSL) {
|
|
107
|
+
if (connSSL.mode === "disable") return false;
|
|
108
|
+
const ssl = {
|
|
109
|
+
rejectUnauthorized: connSSL.mode === "verify-ca" || connSSL.mode === "verify-full"
|
|
110
|
+
};
|
|
111
|
+
if (connSSL.caCert) ssl.ca = connSSL.caCert;
|
|
112
|
+
if (connSSL.clientCert) ssl.cert = connSSL.clientCert;
|
|
113
|
+
if (connSSL.clientKey) ssl.key = connSSL.clientKey;
|
|
114
|
+
return ssl;
|
|
115
|
+
}
|
|
116
|
+
if (this.shouldEnableSSL()) {
|
|
117
|
+
return { rejectUnauthorized: false };
|
|
118
|
+
}
|
|
119
|
+
if (this.options.ssl === false) return false;
|
|
120
|
+
return void 0;
|
|
121
|
+
}
|
|
122
|
+
async query(sql, params, queryId) {
|
|
123
|
+
this.ensureConnected();
|
|
124
|
+
return this.trackQuery(async () => {
|
|
125
|
+
var _a, _b, _c;
|
|
126
|
+
const { result, executionTime } = await this.measureExecution(async () => {
|
|
127
|
+
try {
|
|
128
|
+
const client = await this.pool.connect();
|
|
129
|
+
try {
|
|
130
|
+
if (queryId) {
|
|
131
|
+
const pidRes = await client.query("SELECT pg_backend_pid() as pid");
|
|
132
|
+
this.runningQueryPids.set(queryId, pidRes.rows[0].pid);
|
|
133
|
+
}
|
|
134
|
+
const res = await client.query(sql, params);
|
|
135
|
+
return res;
|
|
136
|
+
} finally {
|
|
137
|
+
if (queryId) this.runningQueryPids.delete(queryId);
|
|
138
|
+
client.release();
|
|
139
|
+
}
|
|
140
|
+
} catch (error) {
|
|
141
|
+
if (queryId) this.runningQueryPids.delete(queryId);
|
|
142
|
+
throw chunkJZO5KRZN_js.mapDatabaseError(error, "postgres", sql);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
return {
|
|
146
|
+
rows: result.rows,
|
|
147
|
+
fields: (_b = (_a = result.fields) == null ? void 0 : _a.map((f) => f.name)) != null ? _b : [],
|
|
148
|
+
rowCount: (_c = result.rowCount) != null ? _c : 0,
|
|
149
|
+
executionTime
|
|
150
|
+
};
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async cancelQuery(queryId) {
|
|
154
|
+
var _a;
|
|
155
|
+
const pid = this.runningQueryPids.get(queryId);
|
|
156
|
+
if (!pid) return false;
|
|
157
|
+
try {
|
|
158
|
+
const client = await this.pool.connect();
|
|
159
|
+
try {
|
|
160
|
+
const res = await client.query("SELECT pg_cancel_backend($1) as cancelled", [pid]);
|
|
161
|
+
return ((_a = res.rows[0]) == null ? void 0 : _a.cancelled) === true;
|
|
162
|
+
} finally {
|
|
163
|
+
client.release();
|
|
164
|
+
}
|
|
165
|
+
} catch (error) {
|
|
166
|
+
console.error("[Postgres] Failed to cancel query:", error);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// Transaction Support
|
|
172
|
+
// ============================================================================
|
|
173
|
+
clearTxTimeout() {
|
|
174
|
+
if (this.txTimeout) {
|
|
175
|
+
clearTimeout(this.txTimeout);
|
|
176
|
+
this.txTimeout = null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Force-expire an active transaction (auto-rollback).
|
|
181
|
+
* Called by the timeout timer, but also available for testing.
|
|
182
|
+
*/
|
|
183
|
+
async expireTransaction() {
|
|
184
|
+
if (this.txActive && this.txClient) {
|
|
185
|
+
console.warn("[Postgres] Transaction timed out, auto-rolling back");
|
|
186
|
+
try {
|
|
187
|
+
await this.txClient.query("ROLLBACK");
|
|
188
|
+
} catch (e) {
|
|
189
|
+
} finally {
|
|
190
|
+
this.txClient.release();
|
|
191
|
+
this.txClient = null;
|
|
192
|
+
this.txActive = false;
|
|
193
|
+
this.clearTxTimeout();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async beginTransaction() {
|
|
198
|
+
this.ensureConnected();
|
|
199
|
+
if (this.txActive) throw new chunkJZO5KRZN_js.QueryError("Transaction already active", "postgres");
|
|
200
|
+
this.txClient = await this.pool.connect();
|
|
201
|
+
await this.txClient.query("BEGIN");
|
|
202
|
+
this.txActive = true;
|
|
203
|
+
this.txTimeout = setTimeout(() => {
|
|
204
|
+
this.expireTransaction();
|
|
205
|
+
}, _PostgresProvider.TX_TIMEOUT_MS);
|
|
206
|
+
}
|
|
207
|
+
async commitTransaction() {
|
|
208
|
+
if (!this.txClient || !this.txActive) throw new chunkJZO5KRZN_js.QueryError("No active transaction", "postgres");
|
|
209
|
+
this.clearTxTimeout();
|
|
210
|
+
try {
|
|
211
|
+
await this.txClient.query("COMMIT");
|
|
212
|
+
} finally {
|
|
213
|
+
this.txClient.release();
|
|
214
|
+
this.txClient = null;
|
|
215
|
+
this.txActive = false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async rollbackTransaction() {
|
|
219
|
+
if (!this.txClient || !this.txActive) throw new chunkJZO5KRZN_js.QueryError("No active transaction", "postgres");
|
|
220
|
+
this.clearTxTimeout();
|
|
221
|
+
try {
|
|
222
|
+
await this.txClient.query("ROLLBACK");
|
|
223
|
+
} finally {
|
|
224
|
+
this.txClient.release();
|
|
225
|
+
this.txClient = null;
|
|
226
|
+
this.txActive = false;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
isInTransaction() {
|
|
230
|
+
return this.txActive;
|
|
231
|
+
}
|
|
232
|
+
async queryInTransaction(sql, params) {
|
|
233
|
+
if (!this.txClient || !this.txActive) throw new chunkJZO5KRZN_js.QueryError("No active transaction", "postgres");
|
|
234
|
+
return this.trackQuery(async () => {
|
|
235
|
+
var _a, _b, _c;
|
|
236
|
+
const { result, executionTime } = await this.measureExecution(async () => {
|
|
237
|
+
try {
|
|
238
|
+
return await this.txClient.query(sql, params);
|
|
239
|
+
} catch (error) {
|
|
240
|
+
throw chunkJZO5KRZN_js.mapDatabaseError(error, "postgres", sql);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
return {
|
|
244
|
+
rows: result.rows,
|
|
245
|
+
fields: (_b = (_a = result.fields) == null ? void 0 : _a.map((f) => f.name)) != null ? _b : [],
|
|
246
|
+
rowCount: (_c = result.rowCount) != null ? _c : 0,
|
|
247
|
+
executionTime
|
|
248
|
+
};
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
// ============================================================================
|
|
252
|
+
// Schema Operations
|
|
253
|
+
// ============================================================================
|
|
254
|
+
async getSchema() {
|
|
255
|
+
this.ensureConnected();
|
|
256
|
+
const client = await this.pool.connect();
|
|
257
|
+
try {
|
|
258
|
+
const result = await client.query(`
|
|
259
|
+
WITH tables_info AS (
|
|
260
|
+
SELECT
|
|
261
|
+
t.table_schema,
|
|
262
|
+
t.table_name,
|
|
263
|
+
COALESCE(c.reltuples::bigint, 0) as row_count,
|
|
264
|
+
COALESCE(pg_total_relation_size(c.oid), 0) as total_size
|
|
265
|
+
FROM information_schema.tables t
|
|
266
|
+
LEFT JOIN pg_class c ON c.oid = (quote_ident(t.table_schema) || '.' || quote_ident(t.table_name))::regclass
|
|
267
|
+
WHERE t.table_schema NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
|
|
268
|
+
AND t.table_type = 'BASE TABLE'
|
|
269
|
+
),
|
|
270
|
+
columns_info AS (
|
|
271
|
+
SELECT
|
|
272
|
+
c.table_schema,
|
|
273
|
+
c.table_name,
|
|
274
|
+
json_agg(
|
|
275
|
+
json_build_object(
|
|
276
|
+
'name', c.column_name,
|
|
277
|
+
'type', c.data_type,
|
|
278
|
+
'nullable', c.is_nullable = 'YES',
|
|
279
|
+
'defaultValue', c.column_default
|
|
280
|
+
) ORDER BY c.ordinal_position
|
|
281
|
+
) FILTER (WHERE c.ordinal_position <= 100) as columns
|
|
282
|
+
FROM information_schema.columns c
|
|
283
|
+
WHERE c.table_schema NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
|
|
284
|
+
GROUP BY c.table_schema, c.table_name
|
|
285
|
+
),
|
|
286
|
+
pk_info AS (
|
|
287
|
+
SELECT
|
|
288
|
+
tc.table_schema,
|
|
289
|
+
tc.table_name,
|
|
290
|
+
array_agg(kcu.column_name) as pk_columns
|
|
291
|
+
FROM information_schema.table_constraints tc
|
|
292
|
+
JOIN information_schema.key_column_usage kcu
|
|
293
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
294
|
+
AND tc.table_schema = kcu.table_schema
|
|
295
|
+
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
296
|
+
GROUP BY tc.table_schema, tc.table_name
|
|
297
|
+
),
|
|
298
|
+
fk_info AS (
|
|
299
|
+
SELECT
|
|
300
|
+
tc.table_schema,
|
|
301
|
+
tc.table_name,
|
|
302
|
+
json_agg(
|
|
303
|
+
json_build_object(
|
|
304
|
+
'columnName', kcu.column_name,
|
|
305
|
+
'referencedSchema', ccu.table_schema,
|
|
306
|
+
'referencedTable', ccu.table_name,
|
|
307
|
+
'referencedColumn', ccu.column_name
|
|
308
|
+
)
|
|
309
|
+
) as foreign_keys
|
|
310
|
+
FROM information_schema.table_constraints tc
|
|
311
|
+
JOIN information_schema.key_column_usage kcu
|
|
312
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
313
|
+
AND tc.table_schema = kcu.table_schema
|
|
314
|
+
JOIN information_schema.constraint_column_usage ccu
|
|
315
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
316
|
+
AND ccu.table_schema = tc.table_schema
|
|
317
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
318
|
+
GROUP BY tc.table_schema, tc.table_name
|
|
319
|
+
),
|
|
320
|
+
index_info AS (
|
|
321
|
+
SELECT
|
|
322
|
+
n.nspname as table_schema,
|
|
323
|
+
t.relname as table_name,
|
|
324
|
+
json_agg(
|
|
325
|
+
json_build_object(
|
|
326
|
+
'name', i.relname,
|
|
327
|
+
'columns', (
|
|
328
|
+
SELECT array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum))
|
|
329
|
+
FROM pg_attribute a
|
|
330
|
+
WHERE a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
|
|
331
|
+
),
|
|
332
|
+
'unique', ix.indisunique
|
|
333
|
+
)
|
|
334
|
+
) as indexes
|
|
335
|
+
FROM pg_index ix
|
|
336
|
+
JOIN pg_class t ON t.oid = ix.indrelid
|
|
337
|
+
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
338
|
+
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
339
|
+
WHERE n.nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')
|
|
340
|
+
GROUP BY n.nspname, t.relname
|
|
341
|
+
)
|
|
342
|
+
SELECT
|
|
343
|
+
ti.table_schema,
|
|
344
|
+
ti.table_name,
|
|
345
|
+
ti.row_count,
|
|
346
|
+
ti.total_size,
|
|
347
|
+
COALESCE(ci.columns, '[]'::json) as columns,
|
|
348
|
+
COALESCE(pk.pk_columns, ARRAY[]::text[]) as pk_columns,
|
|
349
|
+
COALESCE(fk.foreign_keys, '[]'::json) as foreign_keys,
|
|
350
|
+
COALESCE(ii.indexes, '[]'::json) as indexes
|
|
351
|
+
FROM tables_info ti
|
|
352
|
+
LEFT JOIN columns_info ci ON ci.table_schema = ti.table_schema AND ci.table_name = ti.table_name
|
|
353
|
+
LEFT JOIN pk_info pk ON pk.table_schema = ti.table_schema AND pk.table_name = ti.table_name
|
|
354
|
+
LEFT JOIN fk_info fk ON fk.table_schema = ti.table_schema AND fk.table_name = ti.table_name
|
|
355
|
+
LEFT JOIN index_info ii ON ii.table_schema = ti.table_schema AND ii.table_name = ti.table_name
|
|
356
|
+
ORDER BY ti.table_schema, ti.table_name ASC;
|
|
357
|
+
`);
|
|
358
|
+
return result.rows.map((row) => {
|
|
359
|
+
const schemaName = row.table_schema;
|
|
360
|
+
const tableName = row.table_name;
|
|
361
|
+
const displayName = schemaName === "public" ? tableName : `${schemaName}.${tableName}`;
|
|
362
|
+
const rowCount = Math.max(0, parseInt(row.row_count || "0"));
|
|
363
|
+
const sizeBytes = parseInt(row.total_size || "0");
|
|
364
|
+
const pkColumns = row.pk_columns || [];
|
|
365
|
+
const columns = (row.columns || []).map((col) => {
|
|
366
|
+
var _a;
|
|
367
|
+
return {
|
|
368
|
+
name: col.name,
|
|
369
|
+
type: col.type,
|
|
370
|
+
nullable: col.nullable,
|
|
371
|
+
isPrimary: pkColumns.includes(col.name),
|
|
372
|
+
defaultValue: (_a = col.defaultValue) != null ? _a : void 0
|
|
373
|
+
};
|
|
374
|
+
});
|
|
375
|
+
const indexes = (row.indexes || []).map((idx) => ({
|
|
376
|
+
name: idx.name,
|
|
377
|
+
columns: Array.isArray(idx.columns) ? idx.columns : [],
|
|
378
|
+
unique: idx.unique
|
|
379
|
+
}));
|
|
380
|
+
const foreignKeys = (row.foreign_keys || []).map((fk) => ({
|
|
381
|
+
columnName: fk.columnName,
|
|
382
|
+
referencedTable: fk.referencedSchema === "public" ? fk.referencedTable : `${fk.referencedSchema}.${fk.referencedTable}`,
|
|
383
|
+
referencedColumn: fk.referencedColumn
|
|
384
|
+
}));
|
|
385
|
+
return {
|
|
386
|
+
name: displayName,
|
|
387
|
+
rowCount,
|
|
388
|
+
size: chunkPTIRB2JO_js.formatBytes(sizeBytes),
|
|
389
|
+
columns,
|
|
390
|
+
indexes,
|
|
391
|
+
foreignKeys
|
|
392
|
+
};
|
|
393
|
+
});
|
|
394
|
+
} finally {
|
|
395
|
+
client.release();
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
// ============================================================================
|
|
399
|
+
// Health & Monitoring
|
|
400
|
+
// ============================================================================
|
|
401
|
+
async getHealth() {
|
|
402
|
+
this.ensureConnected();
|
|
403
|
+
const client = await this.pool.connect();
|
|
404
|
+
try {
|
|
405
|
+
const connRes = await client.query("SELECT count(*) FROM pg_stat_activity");
|
|
406
|
+
const sizeRes = await client.query("SELECT pg_size_pretty(pg_database_size($1))", [
|
|
407
|
+
this.config.database
|
|
408
|
+
]);
|
|
409
|
+
const cacheRes = await client.query(`
|
|
410
|
+
SELECT
|
|
411
|
+
sum(heap_blks_read) as heap_read,
|
|
412
|
+
sum(heap_blks_hit) as heap_hit,
|
|
413
|
+
COALESCE(
|
|
414
|
+
ROUND((sum(heap_blks_hit) * 100.0 / NULLIF(sum(heap_blks_hit) + sum(heap_blks_read), 0)), 1),
|
|
415
|
+
100
|
|
416
|
+
) as ratio
|
|
417
|
+
FROM pg_statio_user_tables;
|
|
418
|
+
`);
|
|
419
|
+
let slowQueries = [];
|
|
420
|
+
try {
|
|
421
|
+
const slowRes = await client.query(`
|
|
422
|
+
SELECT
|
|
423
|
+
LEFT(query, 100) as query,
|
|
424
|
+
calls,
|
|
425
|
+
ROUND((mean_exec_time)::numeric, 2)::text || 'ms' as avgTime
|
|
426
|
+
FROM pg_stat_statements
|
|
427
|
+
WHERE calls > 0
|
|
428
|
+
ORDER BY total_exec_time DESC
|
|
429
|
+
LIMIT 5;
|
|
430
|
+
`);
|
|
431
|
+
slowQueries = slowRes.rows.map((r) => ({
|
|
432
|
+
query: r.query,
|
|
433
|
+
calls: r.calls,
|
|
434
|
+
avgTime: r.avgtime
|
|
435
|
+
}));
|
|
436
|
+
} catch (e) {
|
|
437
|
+
slowQueries = [
|
|
438
|
+
{ query: "pg_stat_statements extension not enabled", calls: 0, avgTime: "N/A" }
|
|
439
|
+
];
|
|
440
|
+
}
|
|
441
|
+
const sessionsRes = await client.query(`
|
|
442
|
+
SELECT
|
|
443
|
+
pid,
|
|
444
|
+
usename as user,
|
|
445
|
+
datname as database,
|
|
446
|
+
COALESCE(state, 'unknown') as state,
|
|
447
|
+
LEFT(COALESCE(query, ''), 100) as query,
|
|
448
|
+
CASE
|
|
449
|
+
WHEN xact_start IS NOT NULL THEN
|
|
450
|
+
EXTRACT(EPOCH FROM (NOW() - xact_start))::text || 's'
|
|
451
|
+
ELSE 'N/A'
|
|
452
|
+
END as duration
|
|
453
|
+
FROM pg_stat_activity
|
|
454
|
+
WHERE datname = $1
|
|
455
|
+
AND pid != pg_backend_pid()
|
|
456
|
+
ORDER BY xact_start DESC NULLS LAST
|
|
457
|
+
LIMIT 10;
|
|
458
|
+
`, [this.config.database]);
|
|
459
|
+
const activeSessions = sessionsRes.rows.map((r) => ({
|
|
460
|
+
pid: r.pid,
|
|
461
|
+
user: r.user || "unknown",
|
|
462
|
+
database: r.database || "",
|
|
463
|
+
state: r.state,
|
|
464
|
+
query: r.query || "",
|
|
465
|
+
duration: r.duration
|
|
466
|
+
}));
|
|
467
|
+
return {
|
|
468
|
+
activeConnections: parseInt(connRes.rows[0].count),
|
|
469
|
+
databaseSize: sizeRes.rows[0].pg_size_pretty,
|
|
470
|
+
cacheHitRatio: `${cacheRes.rows[0].ratio}%`,
|
|
471
|
+
slowQueries,
|
|
472
|
+
activeSessions
|
|
473
|
+
};
|
|
474
|
+
} finally {
|
|
475
|
+
client.release();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
// ============================================================================
|
|
479
|
+
// Maintenance Operations
|
|
480
|
+
// ============================================================================
|
|
481
|
+
async runMaintenance(type, target) {
|
|
482
|
+
this.ensureConnected();
|
|
483
|
+
const { result, executionTime } = await this.measureExecution(async () => {
|
|
484
|
+
const client = await this.pool.connect();
|
|
485
|
+
try {
|
|
486
|
+
let sql = "";
|
|
487
|
+
switch (type) {
|
|
488
|
+
case "vacuum":
|
|
489
|
+
sql = target ? `VACUUM ANALYZE public.${this.escapeIdentifier(target)}` : "VACUUM ANALYZE";
|
|
490
|
+
break;
|
|
491
|
+
case "analyze":
|
|
492
|
+
sql = target ? `ANALYZE public.${this.escapeIdentifier(target)}` : "ANALYZE";
|
|
493
|
+
break;
|
|
494
|
+
case "reindex":
|
|
495
|
+
sql = target ? `REINDEX TABLE public.${this.escapeIdentifier(target)}` : `REINDEX DATABASE ${this.escapeIdentifier(this.config.database || "")}`;
|
|
496
|
+
break;
|
|
497
|
+
case "kill":
|
|
498
|
+
if (!target) {
|
|
499
|
+
throw new chunkJZO5KRZN_js.QueryError("Target PID is required for kill operation", "postgres");
|
|
500
|
+
}
|
|
501
|
+
const pid = parseInt(target, 10);
|
|
502
|
+
if (isNaN(pid)) {
|
|
503
|
+
throw new chunkJZO5KRZN_js.QueryError("Invalid PID for kill operation", "postgres");
|
|
504
|
+
}
|
|
505
|
+
sql = `SELECT pg_terminate_backend(${pid})`;
|
|
506
|
+
break;
|
|
507
|
+
default:
|
|
508
|
+
throw new chunkJZO5KRZN_js.QueryError(`Unsupported maintenance type: ${type}`, "postgres");
|
|
509
|
+
}
|
|
510
|
+
await client.query(sql);
|
|
511
|
+
return { success: true };
|
|
512
|
+
} finally {
|
|
513
|
+
client.release();
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
return {
|
|
517
|
+
success: result.success,
|
|
518
|
+
executionTime,
|
|
519
|
+
message: `${type.toUpperCase()} completed successfully`
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
// ============================================================================
|
|
523
|
+
// Pool Statistics
|
|
524
|
+
// ============================================================================
|
|
525
|
+
getPoolStats() {
|
|
526
|
+
if (!this.pool) {
|
|
527
|
+
return { total: 0, idle: 0, active: 0, waiting: 0 };
|
|
528
|
+
}
|
|
529
|
+
return {
|
|
530
|
+
total: this.pool.totalCount,
|
|
531
|
+
idle: this.pool.idleCount,
|
|
532
|
+
active: this.pool.totalCount - this.pool.idleCount,
|
|
533
|
+
waiting: this.pool.waitingCount
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
// ============================================================================
|
|
537
|
+
// Extended Monitoring Methods
|
|
538
|
+
// ============================================================================
|
|
539
|
+
/**
|
|
540
|
+
* Get database overview metrics
|
|
541
|
+
*/
|
|
542
|
+
async getOverview() {
|
|
543
|
+
var _a;
|
|
544
|
+
this.ensureConnected();
|
|
545
|
+
const client = await this.pool.connect();
|
|
546
|
+
try {
|
|
547
|
+
const infoRes = await client.query(`
|
|
548
|
+
SELECT
|
|
549
|
+
version() as version,
|
|
550
|
+
pg_postmaster_start_time() as start_time,
|
|
551
|
+
EXTRACT(EPOCH FROM (now() - pg_postmaster_start_time()))::bigint as uptime_seconds
|
|
552
|
+
`);
|
|
553
|
+
const connRes = await client.query(`
|
|
554
|
+
SELECT
|
|
555
|
+
count(*) as active_connections,
|
|
556
|
+
(SELECT setting::int FROM pg_settings WHERE name = 'max_connections') as max_connections
|
|
557
|
+
FROM pg_stat_activity
|
|
558
|
+
WHERE datname = $1
|
|
559
|
+
`, [this.config.database]);
|
|
560
|
+
const sizeRes = await client.query(`
|
|
561
|
+
SELECT
|
|
562
|
+
pg_size_pretty(pg_database_size($1)) as database_size,
|
|
563
|
+
pg_database_size($1) as database_size_bytes
|
|
564
|
+
`, [this.config.database]);
|
|
565
|
+
const countRes = await client.query(`
|
|
566
|
+
SELECT
|
|
567
|
+
(SELECT count(*) FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')) as table_count,
|
|
568
|
+
(SELECT count(*) FROM pg_indexes WHERE schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')) as index_count
|
|
569
|
+
`);
|
|
570
|
+
const uptimeSeconds = parseInt(infoRes.rows[0].uptime_seconds || "0");
|
|
571
|
+
const days = Math.floor(uptimeSeconds / 86400);
|
|
572
|
+
const hours = Math.floor(uptimeSeconds % 86400 / 3600);
|
|
573
|
+
const minutes = Math.floor(uptimeSeconds % 3600 / 60);
|
|
574
|
+
const uptime = days > 0 ? `${days}d ${hours}h ${minutes}m` : hours > 0 ? `${hours}h ${minutes}m` : `${minutes}m`;
|
|
575
|
+
return {
|
|
576
|
+
version: ((_a = infoRes.rows[0].version) == null ? void 0 : _a.split(",")[0]) || "PostgreSQL",
|
|
577
|
+
uptime,
|
|
578
|
+
startTime: infoRes.rows[0].start_time ? new Date(infoRes.rows[0].start_time) : void 0,
|
|
579
|
+
activeConnections: parseInt(connRes.rows[0].active_connections || "0"),
|
|
580
|
+
maxConnections: parseInt(connRes.rows[0].max_connections || "100"),
|
|
581
|
+
databaseSize: sizeRes.rows[0].database_size || "0 bytes",
|
|
582
|
+
databaseSizeBytes: parseInt(sizeRes.rows[0].database_size_bytes || "0"),
|
|
583
|
+
tableCount: parseInt(countRes.rows[0].table_count || "0"),
|
|
584
|
+
indexCount: parseInt(countRes.rows[0].index_count || "0")
|
|
585
|
+
};
|
|
586
|
+
} finally {
|
|
587
|
+
client.release();
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Get performance metrics
|
|
592
|
+
*/
|
|
593
|
+
async getPerformanceMetrics() {
|
|
594
|
+
this.ensureConnected();
|
|
595
|
+
const client = await this.pool.connect();
|
|
596
|
+
try {
|
|
597
|
+
const cacheRes = await client.query(`
|
|
598
|
+
SELECT
|
|
599
|
+
COALESCE(
|
|
600
|
+
ROUND(sum(heap_blks_hit) * 100.0 / NULLIF(sum(heap_blks_hit) + sum(heap_blks_read), 0), 2),
|
|
601
|
+
100
|
|
602
|
+
) as cache_hit_ratio
|
|
603
|
+
FROM pg_statio_user_tables
|
|
604
|
+
`);
|
|
605
|
+
const txRes = await client.query(`
|
|
606
|
+
SELECT
|
|
607
|
+
xact_commit,
|
|
608
|
+
xact_rollback,
|
|
609
|
+
deadlocks,
|
|
610
|
+
blks_read,
|
|
611
|
+
blks_hit
|
|
612
|
+
FROM pg_stat_database
|
|
613
|
+
WHERE datname = $1
|
|
614
|
+
`, [this.config.database]);
|
|
615
|
+
let checkpointWriteTime = "0";
|
|
616
|
+
try {
|
|
617
|
+
const checkpointRes = await client.query(`
|
|
618
|
+
SELECT
|
|
619
|
+
checkpoint_write_time,
|
|
620
|
+
checkpoint_sync_time
|
|
621
|
+
FROM pg_stat_bgwriter
|
|
622
|
+
`);
|
|
623
|
+
const checkpointRow = checkpointRes.rows[0] || {};
|
|
624
|
+
const writeTime = parseFloat(checkpointRow.checkpoint_write_time || "0");
|
|
625
|
+
const syncTime = parseFloat(checkpointRow.checkpoint_sync_time || "0");
|
|
626
|
+
checkpointWriteTime = `${((writeTime + syncTime) / 1e3).toFixed(1)}s`;
|
|
627
|
+
} catch (e) {
|
|
628
|
+
checkpointWriteTime = "N/A";
|
|
629
|
+
}
|
|
630
|
+
const txRow = txRes.rows[0] || {};
|
|
631
|
+
const blksHit = parseInt(txRow.blks_hit || "0");
|
|
632
|
+
const blksRead = parseInt(txRow.blks_read || "0");
|
|
633
|
+
const bufferPoolUsage = blksHit + blksRead > 0 ? Math.round(blksHit / (blksHit + blksRead) * 100) : 100;
|
|
634
|
+
return {
|
|
635
|
+
cacheHitRatio: parseFloat(cacheRes.rows[0].cache_hit_ratio || "100"),
|
|
636
|
+
transactionsPerSecond: void 0,
|
|
637
|
+
// Would need time-based sampling
|
|
638
|
+
queriesPerSecond: void 0,
|
|
639
|
+
// Would need time-based sampling
|
|
640
|
+
bufferPoolUsage,
|
|
641
|
+
deadlocks: parseInt(txRow.deadlocks || "0"),
|
|
642
|
+
checkpointWriteTime
|
|
643
|
+
};
|
|
644
|
+
} finally {
|
|
645
|
+
client.release();
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
/**
|
|
649
|
+
* Get slow query statistics from pg_stat_statements
|
|
650
|
+
*/
|
|
651
|
+
async getSlowQueries(options) {
|
|
652
|
+
var _a;
|
|
653
|
+
this.ensureConnected();
|
|
654
|
+
const limit = (_a = options == null ? void 0 : options.limit) != null ? _a : 10;
|
|
655
|
+
const client = await this.pool.connect();
|
|
656
|
+
try {
|
|
657
|
+
try {
|
|
658
|
+
const res = await client.query(`
|
|
659
|
+
SELECT
|
|
660
|
+
queryid::text as query_id,
|
|
661
|
+
LEFT(query, 500) as query,
|
|
662
|
+
calls,
|
|
663
|
+
ROUND(total_exec_time::numeric, 2) as total_time,
|
|
664
|
+
ROUND(mean_exec_time::numeric, 2) as avg_time,
|
|
665
|
+
ROUND(min_exec_time::numeric, 2) as min_time,
|
|
666
|
+
ROUND(max_exec_time::numeric, 2) as max_time,
|
|
667
|
+
rows,
|
|
668
|
+
shared_blks_hit,
|
|
669
|
+
shared_blks_read
|
|
670
|
+
FROM pg_stat_statements
|
|
671
|
+
WHERE calls > 0
|
|
672
|
+
AND dbid = (SELECT oid FROM pg_database WHERE datname = $1)
|
|
673
|
+
ORDER BY total_exec_time DESC
|
|
674
|
+
LIMIT $2
|
|
675
|
+
`, [this.config.database, limit]);
|
|
676
|
+
return res.rows.map((r) => ({
|
|
677
|
+
queryId: r.query_id,
|
|
678
|
+
query: r.query || "",
|
|
679
|
+
calls: parseInt(r.calls || "0"),
|
|
680
|
+
totalTime: parseFloat(r.total_time || "0"),
|
|
681
|
+
avgTime: parseFloat(r.avg_time || "0"),
|
|
682
|
+
minTime: parseFloat(r.min_time || "0"),
|
|
683
|
+
maxTime: parseFloat(r.max_time || "0"),
|
|
684
|
+
rows: parseInt(r.rows || "0"),
|
|
685
|
+
sharedBlksHit: parseInt(r.shared_blks_hit || "0"),
|
|
686
|
+
sharedBlksRead: parseInt(r.shared_blks_read || "0")
|
|
687
|
+
}));
|
|
688
|
+
} catch (e) {
|
|
689
|
+
const fallbackRes = await client.query(`
|
|
690
|
+
SELECT
|
|
691
|
+
pid::text as query_id,
|
|
692
|
+
LEFT(COALESCE(query, ''), 500) as query,
|
|
693
|
+
1 as calls,
|
|
694
|
+
COALESCE(EXTRACT(EPOCH FROM (now() - query_start)) * 1000, 0) as total_time,
|
|
695
|
+
COALESCE(EXTRACT(EPOCH FROM (now() - query_start)) * 1000, 0) as avg_time,
|
|
696
|
+
0 as rows
|
|
697
|
+
FROM pg_stat_activity
|
|
698
|
+
WHERE datname = $1
|
|
699
|
+
AND pid != pg_backend_pid()
|
|
700
|
+
AND state = 'active'
|
|
701
|
+
AND query IS NOT NULL
|
|
702
|
+
AND query != ''
|
|
703
|
+
AND query NOT LIKE '%pg_stat_activity%'
|
|
704
|
+
ORDER BY query_start ASC NULLS LAST
|
|
705
|
+
LIMIT $2
|
|
706
|
+
`, [this.config.database, limit]);
|
|
707
|
+
return fallbackRes.rows.map((r) => ({
|
|
708
|
+
queryId: r.query_id,
|
|
709
|
+
query: r.query || "",
|
|
710
|
+
calls: parseInt(r.calls || "1"),
|
|
711
|
+
totalTime: parseFloat(r.total_time || "0"),
|
|
712
|
+
avgTime: parseFloat(r.avg_time || "0"),
|
|
713
|
+
minTime: void 0,
|
|
714
|
+
maxTime: void 0,
|
|
715
|
+
rows: parseInt(r.rows || "0"),
|
|
716
|
+
sharedBlksHit: void 0,
|
|
717
|
+
sharedBlksRead: void 0
|
|
718
|
+
}));
|
|
719
|
+
}
|
|
720
|
+
} finally {
|
|
721
|
+
client.release();
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
/**
|
|
725
|
+
* Get active sessions with detailed information
|
|
726
|
+
*/
|
|
727
|
+
async getActiveSessions(options) {
|
|
728
|
+
var _a;
|
|
729
|
+
this.ensureConnected();
|
|
730
|
+
const limit = (_a = options == null ? void 0 : options.limit) != null ? _a : 50;
|
|
731
|
+
const client = await this.pool.connect();
|
|
732
|
+
try {
|
|
733
|
+
const res = await client.query(`
|
|
734
|
+
SELECT
|
|
735
|
+
pid,
|
|
736
|
+
usename as user,
|
|
737
|
+
datname as database,
|
|
738
|
+
application_name,
|
|
739
|
+
client_addr::text,
|
|
740
|
+
COALESCE(state, 'unknown') as state,
|
|
741
|
+
LEFT(COALESCE(query, ''), 500) as query,
|
|
742
|
+
query_start,
|
|
743
|
+
wait_event_type,
|
|
744
|
+
wait_event,
|
|
745
|
+
CASE
|
|
746
|
+
WHEN state = 'active' THEN
|
|
747
|
+
EXTRACT(EPOCH FROM (now() - query_start))::text || 's'
|
|
748
|
+
WHEN xact_start IS NOT NULL THEN
|
|
749
|
+
EXTRACT(EPOCH FROM (now() - xact_start))::text || 's'
|
|
750
|
+
ELSE 'N/A'
|
|
751
|
+
END as duration,
|
|
752
|
+
CASE
|
|
753
|
+
WHEN state = 'active' THEN
|
|
754
|
+
EXTRACT(EPOCH FROM (now() - query_start)) * 1000
|
|
755
|
+
WHEN xact_start IS NOT NULL THEN
|
|
756
|
+
EXTRACT(EPOCH FROM (now() - xact_start)) * 1000
|
|
757
|
+
ELSE 0
|
|
758
|
+
END as duration_ms
|
|
759
|
+
FROM pg_stat_activity
|
|
760
|
+
WHERE datname = $1
|
|
761
|
+
AND pid != pg_backend_pid()
|
|
762
|
+
ORDER BY
|
|
763
|
+
CASE state WHEN 'active' THEN 0 ELSE 1 END,
|
|
764
|
+
query_start DESC NULLS LAST
|
|
765
|
+
LIMIT $2
|
|
766
|
+
`, [this.config.database, limit]);
|
|
767
|
+
return res.rows.map((r) => ({
|
|
768
|
+
pid: r.pid,
|
|
769
|
+
user: r.user || "unknown",
|
|
770
|
+
database: r.database || "",
|
|
771
|
+
applicationName: r.application_name || void 0,
|
|
772
|
+
clientAddr: r.client_addr || void 0,
|
|
773
|
+
state: r.state,
|
|
774
|
+
query: r.query || "",
|
|
775
|
+
queryStart: r.query_start ? new Date(r.query_start) : void 0,
|
|
776
|
+
duration: r.duration,
|
|
777
|
+
durationMs: parseFloat(r.duration_ms || "0"),
|
|
778
|
+
waitEventType: r.wait_event_type || void 0,
|
|
779
|
+
waitEvent: r.wait_event || void 0,
|
|
780
|
+
blocked: false
|
|
781
|
+
// Could be enhanced with pg_locks query
|
|
782
|
+
}));
|
|
783
|
+
} finally {
|
|
784
|
+
client.release();
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
/**
|
|
788
|
+
* Get table statistics
|
|
789
|
+
*/
|
|
790
|
+
async getTableStats(options) {
|
|
791
|
+
this.ensureConnected();
|
|
792
|
+
const schema = options == null ? void 0 : options.schema;
|
|
793
|
+
const client = await this.pool.connect();
|
|
794
|
+
try {
|
|
795
|
+
const whereClause = schema ? `WHERE schemaname = $1` : `WHERE schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')`;
|
|
796
|
+
const params = schema ? [schema] : [];
|
|
797
|
+
const res = await client.query(`
|
|
798
|
+
SELECT
|
|
799
|
+
schemaname as schema_name,
|
|
800
|
+
relname as table_name,
|
|
801
|
+
n_live_tup as live_row_count,
|
|
802
|
+
n_dead_tup as dead_row_count,
|
|
803
|
+
n_live_tup + n_dead_tup as row_count,
|
|
804
|
+
pg_size_pretty(pg_table_size(schemaname || '.' || relname)) as table_size,
|
|
805
|
+
pg_table_size(schemaname || '.' || relname) as table_size_bytes,
|
|
806
|
+
pg_size_pretty(pg_indexes_size(schemaname || '.' || relname)) as index_size,
|
|
807
|
+
pg_indexes_size(schemaname || '.' || relname) as index_size_bytes,
|
|
808
|
+
pg_size_pretty(pg_total_relation_size(schemaname || '.' || relname)) as total_size,
|
|
809
|
+
pg_total_relation_size(schemaname || '.' || relname) as total_size_bytes,
|
|
810
|
+
last_vacuum,
|
|
811
|
+
last_autovacuum,
|
|
812
|
+
last_analyze,
|
|
813
|
+
last_autoanalyze,
|
|
814
|
+
CASE
|
|
815
|
+
WHEN n_live_tup > 0 THEN
|
|
816
|
+
ROUND(n_dead_tup * 100.0 / (n_live_tup + n_dead_tup), 2)
|
|
817
|
+
ELSE 0
|
|
818
|
+
END as bloat_ratio
|
|
819
|
+
FROM pg_stat_user_tables
|
|
820
|
+
${whereClause}
|
|
821
|
+
ORDER BY pg_total_relation_size(schemaname || '.' || relname) DESC
|
|
822
|
+
`, params);
|
|
823
|
+
return res.rows.map((r) => ({
|
|
824
|
+
schemaName: r.schema_name,
|
|
825
|
+
tableName: r.table_name,
|
|
826
|
+
rowCount: parseInt(r.row_count || "0"),
|
|
827
|
+
liveRowCount: parseInt(r.live_row_count || "0"),
|
|
828
|
+
deadRowCount: parseInt(r.dead_row_count || "0"),
|
|
829
|
+
tableSize: r.table_size || "0 bytes",
|
|
830
|
+
tableSizeBytes: parseInt(r.table_size_bytes || "0"),
|
|
831
|
+
indexSize: r.index_size || "0 bytes",
|
|
832
|
+
indexSizeBytes: parseInt(r.index_size_bytes || "0"),
|
|
833
|
+
totalSize: r.total_size || "0 bytes",
|
|
834
|
+
totalSizeBytes: parseInt(r.total_size_bytes || "0"),
|
|
835
|
+
lastVacuum: r.last_vacuum || r.last_autovacuum ? new Date(r.last_vacuum || r.last_autovacuum) : void 0,
|
|
836
|
+
lastAnalyze: r.last_analyze || r.last_autoanalyze ? new Date(r.last_analyze || r.last_autoanalyze) : void 0,
|
|
837
|
+
bloatRatio: parseFloat(r.bloat_ratio || "0")
|
|
838
|
+
}));
|
|
839
|
+
} finally {
|
|
840
|
+
client.release();
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* Get index statistics
|
|
845
|
+
*/
|
|
846
|
+
async getIndexStats(options) {
|
|
847
|
+
this.ensureConnected();
|
|
848
|
+
const schema = options == null ? void 0 : options.schema;
|
|
849
|
+
const client = await this.pool.connect();
|
|
850
|
+
try {
|
|
851
|
+
const whereClause = schema ? `WHERE s.schemaname = $1` : `WHERE s.schemaname NOT IN ('pg_catalog', 'information_schema', 'pg_toast')`;
|
|
852
|
+
const params = schema ? [schema] : [];
|
|
853
|
+
const res = await client.query(`
|
|
854
|
+
SELECT
|
|
855
|
+
s.schemaname as schema_name,
|
|
856
|
+
s.relname as table_name,
|
|
857
|
+
s.indexrelname as index_name,
|
|
858
|
+
am.amname as index_type,
|
|
859
|
+
pg_size_pretty(pg_relation_size(s.indexrelid)) as index_size,
|
|
860
|
+
pg_relation_size(s.indexrelid) as index_size_bytes,
|
|
861
|
+
s.idx_scan as scans,
|
|
862
|
+
s.idx_tup_read as tuples_read,
|
|
863
|
+
s.idx_tup_fetch as tuples_fetched,
|
|
864
|
+
ix.indisunique as is_unique,
|
|
865
|
+
ix.indisprimary as is_primary,
|
|
866
|
+
array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) as columns,
|
|
867
|
+
CASE
|
|
868
|
+
WHEN (SELECT seq_scan + idx_scan FROM pg_stat_user_tables t WHERE t.relid = s.relid) > 0
|
|
869
|
+
THEN ROUND(
|
|
870
|
+
s.idx_scan * 100.0 /
|
|
871
|
+
(SELECT seq_scan + idx_scan FROM pg_stat_user_tables t WHERE t.relid = s.relid),
|
|
872
|
+
2
|
|
873
|
+
)
|
|
874
|
+
ELSE 0
|
|
875
|
+
END as usage_ratio
|
|
876
|
+
FROM pg_stat_user_indexes s
|
|
877
|
+
JOIN pg_index ix ON ix.indexrelid = s.indexrelid
|
|
878
|
+
JOIN pg_class i ON i.oid = s.indexrelid
|
|
879
|
+
JOIN pg_am am ON am.oid = i.relam
|
|
880
|
+
JOIN pg_attribute a ON a.attrelid = s.relid AND a.attnum = ANY(ix.indkey)
|
|
881
|
+
${whereClause}
|
|
882
|
+
GROUP BY s.schemaname, s.relname, s.indexrelname, am.amname,
|
|
883
|
+
s.indexrelid, s.idx_scan, s.idx_tup_read, s.idx_tup_fetch,
|
|
884
|
+
ix.indisunique, ix.indisprimary, s.relid
|
|
885
|
+
ORDER BY s.idx_scan DESC
|
|
886
|
+
`, params);
|
|
887
|
+
return res.rows.map((r) => ({
|
|
888
|
+
schemaName: r.schema_name,
|
|
889
|
+
tableName: r.table_name,
|
|
890
|
+
indexName: r.index_name,
|
|
891
|
+
indexType: r.index_type,
|
|
892
|
+
columns: Array.isArray(r.columns) ? r.columns : [],
|
|
893
|
+
isUnique: r.is_unique || false,
|
|
894
|
+
isPrimary: r.is_primary || false,
|
|
895
|
+
indexSize: r.index_size || "0 bytes",
|
|
896
|
+
indexSizeBytes: parseInt(r.index_size_bytes || "0"),
|
|
897
|
+
scans: parseInt(r.scans || "0"),
|
|
898
|
+
usageRatio: parseFloat(r.usage_ratio || "0")
|
|
899
|
+
}));
|
|
900
|
+
} finally {
|
|
901
|
+
client.release();
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
/**
|
|
905
|
+
* Get storage statistics including tablespaces and WAL
|
|
906
|
+
*/
|
|
907
|
+
async getStorageStats() {
|
|
908
|
+
this.ensureConnected();
|
|
909
|
+
const client = await this.pool.connect();
|
|
910
|
+
try {
|
|
911
|
+
const results = [];
|
|
912
|
+
const tsRes = await client.query(`
|
|
913
|
+
SELECT
|
|
914
|
+
spcname as name,
|
|
915
|
+
pg_tablespace_location(oid) as location,
|
|
916
|
+
pg_size_pretty(pg_tablespace_size(oid)) as size,
|
|
917
|
+
pg_tablespace_size(oid) as size_bytes,
|
|
918
|
+
spcname = 'pg_default' as is_default
|
|
919
|
+
FROM pg_tablespace
|
|
920
|
+
WHERE spcname NOT LIKE 'pg_global'
|
|
921
|
+
`);
|
|
922
|
+
for (const row of tsRes.rows) {
|
|
923
|
+
results.push({
|
|
924
|
+
name: row.name,
|
|
925
|
+
location: row.location || "default",
|
|
926
|
+
size: row.size || "0 bytes",
|
|
927
|
+
sizeBytes: parseInt(row.size_bytes || "0"),
|
|
928
|
+
usagePercent: void 0
|
|
929
|
+
// Would need disk space info
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
try {
|
|
933
|
+
const walRes = await client.query(`
|
|
934
|
+
SELECT
|
|
935
|
+
pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(), '0/0')) as wal_size,
|
|
936
|
+
pg_wal_lsn_diff(pg_current_wal_lsn(), '0/0') as wal_size_bytes
|
|
937
|
+
`);
|
|
938
|
+
if (walRes.rows.length > 0) {
|
|
939
|
+
results.push({
|
|
940
|
+
name: "WAL",
|
|
941
|
+
location: "pg_wal",
|
|
942
|
+
size: walRes.rows[0].wal_size || "0 bytes",
|
|
943
|
+
sizeBytes: parseInt(walRes.rows[0].wal_size_bytes || "0"),
|
|
944
|
+
walSize: walRes.rows[0].wal_size || "0 bytes",
|
|
945
|
+
walSizeBytes: parseInt(walRes.rows[0].wal_size_bytes || "0")
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
} catch (e) {
|
|
949
|
+
}
|
|
950
|
+
return results;
|
|
951
|
+
} finally {
|
|
952
|
+
client.release();
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
async getPgStatActivity() {
|
|
956
|
+
this.ensureConnected();
|
|
957
|
+
const client = await this.pool.connect();
|
|
958
|
+
try {
|
|
959
|
+
const res = await client.query("SELECT * FROM pg_stat_activity");
|
|
960
|
+
return res.rows;
|
|
961
|
+
} finally {
|
|
962
|
+
client.release();
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
};
|
|
966
|
+
_PostgresProvider.TX_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
967
|
+
var PostgresProvider = _PostgresProvider;
|
|
968
|
+
|
|
969
|
+
exports.PostgresProvider = PostgresProvider;
|
|
970
|
+
//# sourceMappingURL=postgres-RLCWNFFX.js.map
|
|
971
|
+
//# sourceMappingURL=postgres-RLCWNFFX.js.map
|