@tejasanik/postgres-mcp-server 2.1.1 → 2.2.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/README.md +163 -95
- package/dist/db-manager/index.d.ts +7 -0
- package/dist/db-manager/index.d.ts.map +1 -0
- package/dist/db-manager/index.js +7 -0
- package/dist/db-manager/index.js.map +1 -0
- package/dist/db-manager/validation.d.ts +35 -0
- package/dist/db-manager/validation.d.ts.map +1 -0
- package/dist/db-manager/validation.js +54 -0
- package/dist/db-manager/validation.js.map +1 -0
- package/dist/db-manager.d.ts +175 -5
- package/dist/db-manager.d.ts.map +1 -1
- package/dist/db-manager.js +589 -26
- package/dist/db-manager.js.map +1 -1
- package/dist/index.js +141 -11
- package/dist/index.js.map +1 -1
- package/dist/tools/analysis-tools.d.ts.map +1 -1
- package/dist/tools/analysis-tools.js +53 -49
- package/dist/tools/analysis-tools.js.map +1 -1
- package/dist/tools/schema-tools.d.ts +40 -1
- package/dist/tools/schema-tools.d.ts.map +1 -1
- package/dist/tools/schema-tools.js +174 -92
- package/dist/tools/schema-tools.js.map +1 -1
- package/dist/tools/server-tools.d.ts.map +1 -1
- package/dist/tools/server-tools.js +5 -2
- package/dist/tools/server-tools.js.map +1 -1
- package/dist/tools/sql/utils/connection-utils.d.ts +79 -0
- package/dist/tools/sql/utils/connection-utils.d.ts.map +1 -0
- package/dist/tools/sql/utils/connection-utils.js +129 -0
- package/dist/tools/sql/utils/connection-utils.js.map +1 -0
- package/dist/tools/sql/utils/constants.d.ts +55 -0
- package/dist/tools/sql/utils/constants.d.ts.map +1 -0
- package/dist/tools/sql/utils/constants.js +55 -0
- package/dist/tools/sql/utils/constants.js.map +1 -0
- package/dist/tools/sql/utils/dry-run-utils.d.ts +31 -0
- package/dist/tools/sql/utils/dry-run-utils.d.ts.map +1 -0
- package/dist/tools/sql/utils/dry-run-utils.js +173 -0
- package/dist/tools/sql/utils/dry-run-utils.js.map +1 -0
- package/dist/tools/sql/utils/file-handler.d.ts +57 -0
- package/dist/tools/sql/utils/file-handler.d.ts.map +1 -0
- package/dist/tools/sql/utils/file-handler.js +150 -0
- package/dist/tools/sql/utils/file-handler.js.map +1 -0
- package/dist/tools/sql/utils/index.d.ts +12 -0
- package/dist/tools/sql/utils/index.d.ts.map +1 -0
- package/dist/tools/sql/utils/index.js +12 -0
- package/dist/tools/sql/utils/index.js.map +1 -0
- package/dist/tools/sql/utils/result-formatter.d.ts +94 -0
- package/dist/tools/sql/utils/result-formatter.d.ts.map +1 -0
- package/dist/tools/sql/utils/result-formatter.js +154 -0
- package/dist/tools/sql/utils/result-formatter.js.map +1 -0
- package/dist/tools/sql/utils/sql-parser.d.ts +125 -0
- package/dist/tools/sql/utils/sql-parser.d.ts.map +1 -0
- package/dist/tools/sql/utils/sql-parser.js +468 -0
- package/dist/tools/sql/utils/sql-parser.js.map +1 -0
- package/dist/tools/sql-tools.d.ts +21 -0
- package/dist/tools/sql-tools.d.ts.map +1 -1
- package/dist/tools/sql-tools.js +383 -532
- package/dist/tools/sql-tools.js.map +1 -1
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/retry.d.ts +1 -1
- package/dist/utils/retry.d.ts.map +1 -1
- package/dist/utils/retry.js.map +1 -1
- package/dist/utils/validation.d.ts +45 -9
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +335 -72
- package/dist/utils/validation.js.map +1 -1
- package/package.json +9 -2
- package/dist/__tests__/analysis-tools.test.d.ts +0 -2
- package/dist/__tests__/analysis-tools.test.d.ts.map +0 -1
- package/dist/__tests__/analysis-tools.test.js +0 -294
- package/dist/__tests__/analysis-tools.test.js.map +0 -1
- package/dist/__tests__/db-manager.test.d.ts +0 -2
- package/dist/__tests__/db-manager.test.d.ts.map +0 -1
- package/dist/__tests__/db-manager.test.js +0 -410
- package/dist/__tests__/db-manager.test.js.map +0 -1
- package/dist/__tests__/mcp-server.test.d.ts +0 -13
- package/dist/__tests__/mcp-server.test.d.ts.map +0 -1
- package/dist/__tests__/mcp-server.test.js +0 -146
- package/dist/__tests__/mcp-server.test.js.map +0 -1
- package/dist/__tests__/schema-tools.test.d.ts +0 -2
- package/dist/__tests__/schema-tools.test.d.ts.map +0 -1
- package/dist/__tests__/schema-tools.test.js +0 -171
- package/dist/__tests__/schema-tools.test.js.map +0 -1
- package/dist/__tests__/server-tools.test.d.ts +0 -2
- package/dist/__tests__/server-tools.test.d.ts.map +0 -1
- package/dist/__tests__/server-tools.test.js +0 -137
- package/dist/__tests__/server-tools.test.js.map +0 -1
- package/dist/__tests__/sql-tools.test.d.ts +0 -2
- package/dist/__tests__/sql-tools.test.d.ts.map +0 -1
- package/dist/__tests__/sql-tools.test.js +0 -1912
- package/dist/__tests__/sql-tools.test.js.map +0 -1
- package/dist/__tests__/validation.test.d.ts +0 -2
- package/dist/__tests__/validation.test.d.ts.map +0 -1
- package/dist/__tests__/validation.test.js +0 -203
- package/dist/__tests__/validation.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -4,101 +4,6 @@ A Model Context Protocol (MCP) server for PostgreSQL database management and ana
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
## 🤖 Agent Experience (AX) - Claude Code Review
|
|
8
|
-
|
|
9
|
-
**Tested by:** Claude Code (Sonnet 4.5)
|
|
10
|
-
**Use Case:** Database deployment, schema exploration, and SQL migration
|
|
11
|
-
**Rating:** ⭐⭐⭐⭐⭐ (9.5/10)
|
|
12
|
-
|
|
13
|
-
### What I Loved
|
|
14
|
-
|
|
15
|
-
**1. Clear, Structured Responses**
|
|
16
|
-
Every response includes connection context (`server`, `database`, `schema`), making it crystal clear which environment I'm working in. This is essential when managing multiple databases - I never have to guess where a query ran.
|
|
17
|
-
|
|
18
|
-
**2. Excellent Error Handling**
|
|
19
|
-
When I encountered a syntax error with Liquibase's `/` delimiter, the error message showed:
|
|
20
|
-
|
|
21
|
-
- Exact line number (151)
|
|
22
|
-
- The failing statement
|
|
23
|
-
- Transaction rollback confirmation
|
|
24
|
-
|
|
25
|
-
This made troubleshooting instant. No digging through logs or guessing what failed.
|
|
26
|
-
|
|
27
|
-
**3. Server Management is Intuitive**
|
|
28
|
-
|
|
29
|
-
- `list_servers` → Shows all available servers with connection status
|
|
30
|
-
- `list_databases` → Filters databases by server name
|
|
31
|
-
- `switch_server_db` → Seamless switching with immediate confirmation
|
|
32
|
-
|
|
33
|
-
The flow is natural: discover → select → connect → execute.
|
|
34
|
-
|
|
35
|
-
**4. SQL File Deployment Made Easy**
|
|
36
|
-
The `stripPatterns` feature solved my exact problem:
|
|
37
|
-
|
|
38
|
-
```javascript
|
|
39
|
-
execute_sql_file({
|
|
40
|
-
filePath: "/path/to/liquibase.sql",
|
|
41
|
-
stripPatterns: ["/"], // Removes Liquibase delimiters
|
|
42
|
-
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Before this feature, I had to manually remove delimiters or use raw `execute_sql`. Now it's one clean call.
|
|
46
|
-
|
|
47
|
-
**5. Dry-Run Capabilities are Outstanding**
|
|
48
|
-
`dry_run_sql_file` is a game-changer:
|
|
49
|
-
|
|
50
|
-
- Executes ALL statements in a transaction
|
|
51
|
-
- Shows REAL errors with PostgreSQL error codes and constraint names
|
|
52
|
-
- Automatically skips non-rollbackable operations (VACUUM, NEXTVAL)
|
|
53
|
-
- Provides EXPLAIN plans for skipped statements
|
|
54
|
-
- Then rolls back everything
|
|
55
|
-
|
|
56
|
-
This is _way_ better than just parsing - I can catch constraint violations, trigger issues, and get exact row counts before deployment.
|
|
57
|
-
|
|
58
|
-
**6. Security by Default**
|
|
59
|
-
|
|
60
|
-
- Credentials never appear in responses
|
|
61
|
-
- Host/port intentionally hidden (only server names visible)
|
|
62
|
-
- Readonly mode available for production safety
|
|
63
|
-
- Connection context always visible
|
|
64
|
-
|
|
65
|
-
### Improvements Based on My Feedback
|
|
66
|
-
|
|
67
|
-
The developer implemented several features after I tested the MCP:
|
|
68
|
-
|
|
69
|
-
✅ **SQL File Delimiter Support** - Added `stripPatterns` for Liquibase `/`, SQL Server `GO`, etc.
|
|
70
|
-
✅ **Validate-Only Mode** - `execute_sql_file({ validateOnly: true })` previews without execution
|
|
71
|
-
✅ **Enhanced Connection Info** - `get_current_connection` now returns `user` and AI `context`
|
|
72
|
-
✅ **Comprehensive Dry-Run** - `dry_run_sql_file` provides real execution + rollback
|
|
73
|
-
✅ **Better Error Details** - PostgreSQL error codes, constraint names, hints included
|
|
74
|
-
|
|
75
|
-
### Real-World Experience
|
|
76
|
-
|
|
77
|
-
**Task:** Deploy a PostgreSQL function to two databases (dev + GraphQL-Intro-DB)
|
|
78
|
-
|
|
79
|
-
1. **Discovery**: `list_servers` showed all configured servers
|
|
80
|
-
2. **Preview**: Used `preview_sql_file` to check the file structure
|
|
81
|
-
3. **Issue**: Got syntax error from Liquibase's `/` delimiter
|
|
82
|
-
4. **Solution**: Switched to direct `execute_sql` to bypass the delimiter
|
|
83
|
-
5. **Deployment**: Successfully deployed to both databases
|
|
84
|
-
6. **Verification**: Used `get_current_connection` to confirm each deployment
|
|
85
|
-
|
|
86
|
-
Total time: ~3 minutes. The structured responses and clear errors made it feel effortless.
|
|
87
|
-
|
|
88
|
-
### Minor Suggestions for Future
|
|
89
|
-
|
|
90
|
-
1. **Batch Cross Servers Deployment** - Deploy same script to multiple servers at once
|
|
91
|
-
2. **Recent Connections** - Quick-switch to recently used databases
|
|
92
|
-
3. **Statement Progress** - Show progress for large SQL files (e.g., "Executing statement 15/100...")
|
|
93
|
-
|
|
94
|
-
### Bottom Line
|
|
95
|
-
|
|
96
|
-
This MCP is production-ready and developer-friendly. The combination of clear responses, robust error handling, and powerful features like dry-run make it an essential tool for database work. The developer clearly understands the needs of both AI agents and human operators.
|
|
97
|
-
|
|
98
|
-
**Recommended for:** Database migrations, schema exploration, multi-environment management, and production deployments.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
7
|
## Installation
|
|
103
8
|
|
|
104
9
|
```bash
|
|
@@ -395,6 +300,7 @@ Lists all database schemas in the current PostgreSQL database.
|
|
|
395
300
|
**Parameters:**
|
|
396
301
|
|
|
397
302
|
- `includeSystemSchemas` (optional): Include system schemas
|
|
303
|
+
- `server`, `database`, `schema` (optional): One-time connection override
|
|
398
304
|
|
|
399
305
|
#### `list_objects`
|
|
400
306
|
|
|
@@ -405,6 +311,7 @@ Lists database objects within a specified schema.
|
|
|
405
311
|
- `schema` (required): Schema name to list objects from
|
|
406
312
|
- `objectType` (optional): Type of objects to list (table, view, sequence, extension, all)
|
|
407
313
|
- `filter` (optional): Filter objects by name
|
|
314
|
+
- `server`, `database`, `targetSchema` (optional): One-time connection override
|
|
408
315
|
|
|
409
316
|
#### `get_object_details`
|
|
410
317
|
|
|
@@ -415,6 +322,7 @@ Provides detailed information about a database object including columns, constra
|
|
|
415
322
|
- `schema` (required): Schema name containing the object
|
|
416
323
|
- `objectName` (required): Name of the object
|
|
417
324
|
- `objectType` (optional): Type of the object
|
|
325
|
+
- `server`, `database`, `targetSchema` (optional): One-time connection override
|
|
418
326
|
|
|
419
327
|
### Query Execution
|
|
420
328
|
|
|
@@ -432,6 +340,7 @@ Executes SQL statements on the database. Supports pagination and parameterized q
|
|
|
432
340
|
- `includeSchemaHint` (optional): Include schema information (columns, primary keys, foreign keys) for tables referenced in the query.
|
|
433
341
|
- `allowMultipleStatements` (optional): Allow multiple SQL statements separated by semicolons. Returns results for each statement with line numbers.
|
|
434
342
|
- `transactionId` (optional): Execute within an active transaction. Get this from `begin_transaction`.
|
|
343
|
+
- `server`, `database`, `schema` (optional): One-time connection override. Execute on a different server/database/schema without changing the main connection. Cannot be used with `transactionId`.
|
|
435
344
|
|
|
436
345
|
**Returns:**
|
|
437
346
|
|
|
@@ -811,6 +720,70 @@ Gets the execution plan for a SQL query.
|
|
|
811
720
|
- `buffers` (optional): Include buffer usage statistics
|
|
812
721
|
- `format` (optional): Output format (text, json, yaml, xml)
|
|
813
722
|
- `hypotheticalIndexes` (optional): Simulate indexes (requires hypopg extension)
|
|
723
|
+
- `server`, `database`, `schema` (optional): One-time connection override (see below)
|
|
724
|
+
|
|
725
|
+
### Connection Override (One-Time Execution)
|
|
726
|
+
|
|
727
|
+
Most query execution tools support **one-time connection override** parameters that allow executing a query on a different server/database/schema without changing the main connection. This is useful for:
|
|
728
|
+
|
|
729
|
+
- Querying multiple databases in a single workflow
|
|
730
|
+
- Running read queries against a replica while keeping the main connection to primary
|
|
731
|
+
- Comparing schemas across different servers
|
|
732
|
+
|
|
733
|
+
**Supported tools:** `execute_sql`, `explain_query`, `list_schemas`, `list_objects`, `get_object_details`, `execute_sql_file`, `mutation_preview`, `mutation_dry_run`, `dry_run_sql_file`, `batch_execute`
|
|
734
|
+
|
|
735
|
+
**Override Parameters:**
|
|
736
|
+
|
|
737
|
+
- `server` (optional): Execute on this server instead of the current one
|
|
738
|
+
- `database` (optional): Execute on this database instead of the current one
|
|
739
|
+
- `schema` (optional): Set search_path to this schema for this execution only
|
|
740
|
+
|
|
741
|
+
**Important Notes:**
|
|
742
|
+
|
|
743
|
+
1. The main connection remains unchanged after the query completes
|
|
744
|
+
2. Connection override cannot be used with transactions (`transactionId`)
|
|
745
|
+
3. Override connections use a separate connection pool with LRU eviction
|
|
746
|
+
4. Maximum 10 cached override pools, each limited to 2 connections
|
|
747
|
+
5. Total connections across all pools limited to 50
|
|
748
|
+
|
|
749
|
+
**Examples:**
|
|
750
|
+
|
|
751
|
+
```
|
|
752
|
+
# Query another database without switching
|
|
753
|
+
execute_sql({
|
|
754
|
+
sql: "SELECT * FROM users LIMIT 10",
|
|
755
|
+
database: "analytics_db"
|
|
756
|
+
})
|
|
757
|
+
|
|
758
|
+
# Query a different server entirely
|
|
759
|
+
execute_sql({
|
|
760
|
+
sql: "SELECT COUNT(*) FROM orders",
|
|
761
|
+
server: "reporting",
|
|
762
|
+
database: "warehouse"
|
|
763
|
+
})
|
|
764
|
+
|
|
765
|
+
# List schemas on a different server
|
|
766
|
+
list_schemas({
|
|
767
|
+
server: "production",
|
|
768
|
+
database: "myapp"
|
|
769
|
+
})
|
|
770
|
+
|
|
771
|
+
# Compare table structure across environments
|
|
772
|
+
get_object_details({
|
|
773
|
+
schema: "public",
|
|
774
|
+
objectName: "users",
|
|
775
|
+
server: "staging"
|
|
776
|
+
})
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
**Connection Pool Management:**
|
|
780
|
+
|
|
781
|
+
Override connections are managed efficiently:
|
|
782
|
+
|
|
783
|
+
- Pools are cached and reused for repeated queries to the same server/database
|
|
784
|
+
- LRU eviction removes oldest pools when limit (10) is reached
|
|
785
|
+
- Connections are properly released after each query
|
|
786
|
+
- Global connection limit prevents resource exhaustion
|
|
814
787
|
|
|
815
788
|
### Performance Analysis
|
|
816
789
|
|
|
@@ -996,6 +969,101 @@ When `execute_sql_file` or multi-statement execution encounters errors, line num
|
|
|
996
969
|
- Optional: `pg_stat_statements` extension for query performance analysis
|
|
997
970
|
- Optional: `hypopg` extension for hypothetical index simulation
|
|
998
971
|
|
|
972
|
+
## 🤖 Agent Experience (AX) - Claude Code Review
|
|
973
|
+
|
|
974
|
+
**Tested by:** Claude Code (Sonnet 4.5)
|
|
975
|
+
**Use Case:** Database deployment, schema exploration, and SQL migration
|
|
976
|
+
**Rating:** ⭐⭐⭐⭐⭐ (9.5/10)
|
|
977
|
+
|
|
978
|
+
### What I Loved
|
|
979
|
+
|
|
980
|
+
**1. Clear, Structured Responses**
|
|
981
|
+
Every response includes connection context (`server`, `database`, `schema`), making it crystal clear which environment I'm working in. This is essential when managing multiple databases - I never have to guess where a query ran.
|
|
982
|
+
|
|
983
|
+
**2. Excellent Error Handling**
|
|
984
|
+
When I encountered a syntax error with Liquibase's `/` delimiter, the error message showed:
|
|
985
|
+
|
|
986
|
+
- Exact line number (151)
|
|
987
|
+
- The failing statement
|
|
988
|
+
- Transaction rollback confirmation
|
|
989
|
+
|
|
990
|
+
This made troubleshooting instant. No digging through logs or guessing what failed.
|
|
991
|
+
|
|
992
|
+
**3. Server Management is Intuitive**
|
|
993
|
+
|
|
994
|
+
- `list_servers` → Shows all available servers with connection status
|
|
995
|
+
- `list_databases` → Filters databases by server name
|
|
996
|
+
- `switch_server_db` → Seamless switching with immediate confirmation
|
|
997
|
+
|
|
998
|
+
The flow is natural: discover → select → connect → execute.
|
|
999
|
+
|
|
1000
|
+
**4. SQL File Deployment Made Easy**
|
|
1001
|
+
The `stripPatterns` feature solved my exact problem:
|
|
1002
|
+
|
|
1003
|
+
```javascript
|
|
1004
|
+
execute_sql_file({
|
|
1005
|
+
filePath: "/path/to/liquibase.sql",
|
|
1006
|
+
stripPatterns: ["/"], // Removes Liquibase delimiters
|
|
1007
|
+
});
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
Before this feature, I had to manually remove delimiters or use raw `execute_sql`. Now it's one clean call.
|
|
1011
|
+
|
|
1012
|
+
**5. Dry-Run Capabilities are Outstanding**
|
|
1013
|
+
`dry_run_sql_file` is a game-changer:
|
|
1014
|
+
|
|
1015
|
+
- Executes ALL statements in a transaction
|
|
1016
|
+
- Shows REAL errors with PostgreSQL error codes and constraint names
|
|
1017
|
+
- Automatically skips non-rollbackable operations (VACUUM, NEXTVAL)
|
|
1018
|
+
- Provides EXPLAIN plans for skipped statements
|
|
1019
|
+
- Then rolls back everything
|
|
1020
|
+
|
|
1021
|
+
This is _way_ better than just parsing - I can catch constraint violations, trigger issues, and get exact row counts before deployment.
|
|
1022
|
+
|
|
1023
|
+
**6. Security by Default**
|
|
1024
|
+
|
|
1025
|
+
- Credentials never appear in responses
|
|
1026
|
+
- Host/port intentionally hidden (only server names visible)
|
|
1027
|
+
- Readonly mode available for production safety
|
|
1028
|
+
- Connection context always visible
|
|
1029
|
+
|
|
1030
|
+
### Improvements Based on My Feedback
|
|
1031
|
+
|
|
1032
|
+
The developer implemented several features after I tested the MCP:
|
|
1033
|
+
|
|
1034
|
+
✅ **SQL File Delimiter Support** - Added `stripPatterns` for Liquibase `/`, SQL Server `GO`, etc.
|
|
1035
|
+
✅ **Validate-Only Mode** - `execute_sql_file({ validateOnly: true })` previews without execution
|
|
1036
|
+
✅ **Enhanced Connection Info** - `get_current_connection` now returns `user` and AI `context`
|
|
1037
|
+
✅ **Comprehensive Dry-Run** - `dry_run_sql_file` provides real execution + rollback
|
|
1038
|
+
✅ **Better Error Details** - PostgreSQL error codes, constraint names, hints included
|
|
1039
|
+
|
|
1040
|
+
### Real-World Experience
|
|
1041
|
+
|
|
1042
|
+
**Task:** Deploy a PostgreSQL function to two databases (dev + GraphQL-Intro-DB)
|
|
1043
|
+
|
|
1044
|
+
1. **Discovery**: `list_servers` showed all configured servers
|
|
1045
|
+
2. **Preview**: Used `preview_sql_file` to check the file structure
|
|
1046
|
+
3. **Issue**: Got syntax error from Liquibase's `/` delimiter
|
|
1047
|
+
4. **Solution**: Switched to direct `execute_sql` to bypass the delimiter
|
|
1048
|
+
5. **Deployment**: Successfully deployed to both databases
|
|
1049
|
+
6. **Verification**: Used `get_current_connection` to confirm each deployment
|
|
1050
|
+
|
|
1051
|
+
Total time: ~3 minutes. The structured responses and clear errors made it feel effortless.
|
|
1052
|
+
|
|
1053
|
+
### Minor Suggestions for Future
|
|
1054
|
+
|
|
1055
|
+
1. **Batch Cross Servers Deployment** - Deploy same script to multiple servers at once
|
|
1056
|
+
2. **Recent Connections** - Quick-switch to recently used databases
|
|
1057
|
+
3. **Statement Progress** - Show progress for large SQL files (e.g., "Executing statement 15/100...")
|
|
1058
|
+
|
|
1059
|
+
### Bottom Line
|
|
1060
|
+
|
|
1061
|
+
This MCP is production-ready and developer-friendly. The combination of clear responses, robust error handling, and powerful features like dry-run make it an essential tool for database work. The developer clearly understands the needs of both AI agents and human operators.
|
|
1062
|
+
|
|
1063
|
+
**Recommended for:** Database migrations, schema exploration, multi-environment management, and production deployments.
|
|
1064
|
+
|
|
1065
|
+
---
|
|
1066
|
+
|
|
999
1067
|
## License
|
|
1000
1068
|
|
|
1001
1069
|
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db-manager/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db-manager/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Manager Validation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Centralized validation functions for database and schema names.
|
|
5
|
+
* Prevents SQL injection and ensures PostgreSQL-compatible identifiers.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Validates a database name for PostgreSQL compatibility and SQL injection prevention.
|
|
9
|
+
*
|
|
10
|
+
* @param name - The database name to validate
|
|
11
|
+
* @throws Error if the database name is invalid
|
|
12
|
+
*/
|
|
13
|
+
export declare function validateDatabaseName(name: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Validates a schema name for PostgreSQL compatibility.
|
|
16
|
+
*
|
|
17
|
+
* @param name - The schema name to validate
|
|
18
|
+
* @throws Error if the schema name is invalid
|
|
19
|
+
*/
|
|
20
|
+
export declare function validateSchemaName(name: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Checks if a database name is valid without throwing.
|
|
23
|
+
*
|
|
24
|
+
* @param name - The database name to check
|
|
25
|
+
* @returns true if valid, false otherwise
|
|
26
|
+
*/
|
|
27
|
+
export declare function isValidDatabaseName(name: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Checks if a schema name is valid without throwing.
|
|
30
|
+
*
|
|
31
|
+
* @param name - The schema name to check
|
|
32
|
+
* @returns true if valid, false otherwise
|
|
33
|
+
*/
|
|
34
|
+
export declare function isValidSchemaName(name: string): boolean;
|
|
35
|
+
//# sourceMappingURL=validation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../src/db-manager/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAOvD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIrD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Manager Validation Utilities
|
|
3
|
+
*
|
|
4
|
+
* Centralized validation functions for database and schema names.
|
|
5
|
+
* Prevents SQL injection and ensures PostgreSQL-compatible identifiers.
|
|
6
|
+
*/
|
|
7
|
+
/** Pattern for valid database names: start with letter/underscore, alphanumeric/underscore/hyphen */
|
|
8
|
+
const DATABASE_NAME_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_-]*$/;
|
|
9
|
+
/** Pattern for SQL injection characters that must not appear in database names */
|
|
10
|
+
const SQL_INJECTION_PATTERN = /--|;|'|"|`/;
|
|
11
|
+
/** Pattern for valid schema names: start with letter/underscore, alphanumeric/underscore only */
|
|
12
|
+
const SCHEMA_NAME_PATTERN = /^[a-zA-Z_]\w*$/;
|
|
13
|
+
/**
|
|
14
|
+
* Validates a database name for PostgreSQL compatibility and SQL injection prevention.
|
|
15
|
+
*
|
|
16
|
+
* @param name - The database name to validate
|
|
17
|
+
* @throws Error if the database name is invalid
|
|
18
|
+
*/
|
|
19
|
+
export function validateDatabaseName(name) {
|
|
20
|
+
if (!DATABASE_NAME_PATTERN.test(name) || SQL_INJECTION_PATTERN.test(name)) {
|
|
21
|
+
throw new Error('Invalid database name. Allowed: letters, digits, underscores, hyphens. ' +
|
|
22
|
+
'Cannot contain SQL characters (;, --, quotes).');
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Validates a schema name for PostgreSQL compatibility.
|
|
27
|
+
*
|
|
28
|
+
* @param name - The schema name to validate
|
|
29
|
+
* @throws Error if the schema name is invalid
|
|
30
|
+
*/
|
|
31
|
+
export function validateSchemaName(name) {
|
|
32
|
+
if (!SCHEMA_NAME_PATTERN.test(name)) {
|
|
33
|
+
throw new Error('Invalid schema name. Only alphanumeric characters and underscores are allowed.');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Checks if a database name is valid without throwing.
|
|
38
|
+
*
|
|
39
|
+
* @param name - The database name to check
|
|
40
|
+
* @returns true if valid, false otherwise
|
|
41
|
+
*/
|
|
42
|
+
export function isValidDatabaseName(name) {
|
|
43
|
+
return DATABASE_NAME_PATTERN.test(name) && !SQL_INJECTION_PATTERN.test(name);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Checks if a schema name is valid without throwing.
|
|
47
|
+
*
|
|
48
|
+
* @param name - The schema name to check
|
|
49
|
+
* @returns true if valid, false otherwise
|
|
50
|
+
*/
|
|
51
|
+
export function isValidSchemaName(name) {
|
|
52
|
+
return SCHEMA_NAME_PATTERN.test(name);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/db-manager/validation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qGAAqG;AACrG,MAAM,qBAAqB,GAAG,2BAA2B,CAAC;AAE1D,kFAAkF;AAClF,MAAM,qBAAqB,GAAG,YAAY,CAAC;AAE3C,iGAAiG;AACjG,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC1E,MAAM,IAAI,KAAK,CACb,yEAAyE;YACvE,gDAAgD,CACnD,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACpG,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC"}
|
package/dist/db-manager.d.ts
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { PoolClient, QueryResult, QueryResultRow } from "pg";
|
|
2
|
-
import { ServerConfig, ServersConfig, ConnectionState, ConnectionInfo, DatabaseInfo, ConnectionContext, TransactionInfo } from "./types.js";
|
|
2
|
+
import { ServerConfig, ServersConfig, ConnectionState, ConnectionInfo, DatabaseInfo, ConnectionContext, TransactionInfo, ConnectionOverride } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Result from getClientWithOverride containing the client, release function, and resolved schema
|
|
5
|
+
*/
|
|
6
|
+
export interface OverrideClientResult {
|
|
7
|
+
client: PoolClient;
|
|
8
|
+
release: () => void;
|
|
9
|
+
server: string;
|
|
10
|
+
database: string;
|
|
11
|
+
schema: string;
|
|
12
|
+
context?: string;
|
|
13
|
+
isOverride: boolean;
|
|
14
|
+
}
|
|
3
15
|
export declare class DatabaseManager {
|
|
4
16
|
private serversConfig;
|
|
5
17
|
private connectionState;
|
|
@@ -7,7 +19,57 @@ export declare class DatabaseManager {
|
|
|
7
19
|
private readOnlyMode;
|
|
8
20
|
private queryTimeoutMs;
|
|
9
21
|
private activeTransactions;
|
|
22
|
+
private poolCache;
|
|
23
|
+
private poolCleanupInterval;
|
|
24
|
+
private transactionCleanupInterval;
|
|
25
|
+
private poolCreationPromises;
|
|
26
|
+
private totalActiveConnections;
|
|
27
|
+
private mainPoolActiveConnections;
|
|
10
28
|
constructor(readOnlyMode?: boolean, queryTimeoutMs?: number);
|
|
29
|
+
/**
|
|
30
|
+
* Starts the periodic cleanup of idle cached pools
|
|
31
|
+
*/
|
|
32
|
+
private startPoolCleanup;
|
|
33
|
+
/**
|
|
34
|
+
* Cleans up pools that have been idle for too long
|
|
35
|
+
*/
|
|
36
|
+
private cleanupIdlePools;
|
|
37
|
+
/**
|
|
38
|
+
* Starts the periodic cleanup of abandoned transactions.
|
|
39
|
+
* Transactions older than TRANSACTION_CLEANUP_TIMEOUT_MS (45 minutes) are
|
|
40
|
+
* automatically rolled back to prevent connection leaks.
|
|
41
|
+
*/
|
|
42
|
+
private startTransactionCleanup;
|
|
43
|
+
/**
|
|
44
|
+
* Cleans up transactions that have been open for too long.
|
|
45
|
+
* Rolls back and releases the client for any transaction older than
|
|
46
|
+
* TRANSACTION_CLEANUP_TIMEOUT_MS (45 minutes).
|
|
47
|
+
*
|
|
48
|
+
* @returns Array of cleaned up transaction IDs with their info
|
|
49
|
+
*/
|
|
50
|
+
private cleanupAbandonedTransactions;
|
|
51
|
+
/**
|
|
52
|
+
* Gets the age of a transaction in milliseconds.
|
|
53
|
+
*
|
|
54
|
+
* @param transactionId - The transaction ID
|
|
55
|
+
* @returns Age in milliseconds or null if transaction not found
|
|
56
|
+
*/
|
|
57
|
+
getTransactionAge(transactionId: string): number | null;
|
|
58
|
+
/**
|
|
59
|
+
* Gets the remaining time before a transaction is auto-cleaned in milliseconds.
|
|
60
|
+
*
|
|
61
|
+
* @param transactionId - The transaction ID
|
|
62
|
+
* @returns Remaining time in milliseconds or null if transaction not found
|
|
63
|
+
*/
|
|
64
|
+
getTransactionTimeRemaining(transactionId: string): number | null;
|
|
65
|
+
/**
|
|
66
|
+
* Generates a cache key for a server/database combination
|
|
67
|
+
*/
|
|
68
|
+
private getPoolCacheKey;
|
|
69
|
+
/**
|
|
70
|
+
* Evicts the least recently used pool when cache is full
|
|
71
|
+
*/
|
|
72
|
+
private evictLruPool;
|
|
11
73
|
private loadServersConfig;
|
|
12
74
|
getServersConfig(): ServersConfig;
|
|
13
75
|
getServerNames(): string[];
|
|
@@ -23,6 +85,103 @@ export declare class DatabaseManager {
|
|
|
23
85
|
listDatabases(): Promise<DatabaseInfo[]>;
|
|
24
86
|
query<T extends QueryResultRow = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
|
|
25
87
|
getClient(): Promise<PoolClient>;
|
|
88
|
+
/**
|
|
89
|
+
* Checks if we can acquire a new connection without exceeding global limits
|
|
90
|
+
*/
|
|
91
|
+
private canAcquireConnection;
|
|
92
|
+
/**
|
|
93
|
+
* Acquires a client from the main pool with proper tracking
|
|
94
|
+
*/
|
|
95
|
+
private acquireMainPoolClient;
|
|
96
|
+
/**
|
|
97
|
+
* Acquires a client from a cached pool with proper tracking
|
|
98
|
+
*/
|
|
99
|
+
private acquireCachedPoolClient;
|
|
100
|
+
/**
|
|
101
|
+
* Creates a new cached pool. This method handles concurrent creation requests
|
|
102
|
+
* by storing the creation promise so multiple callers wait for the same pool.
|
|
103
|
+
*/
|
|
104
|
+
private getOrCreateCachedPool;
|
|
105
|
+
/**
|
|
106
|
+
* Gets a client with optional connection override for one-time execution.
|
|
107
|
+
* Handles concurrent calls efficiently by:
|
|
108
|
+
* - Reusing existing pools for the same server/database
|
|
109
|
+
* - Preventing duplicate pool creation through promise caching
|
|
110
|
+
* - Tracking active connections for resource management
|
|
111
|
+
* - Enforcing global connection limits
|
|
112
|
+
*
|
|
113
|
+
* @param override - Optional connection override parameters
|
|
114
|
+
* @returns Object containing the client, release function, and resolved connection info
|
|
115
|
+
* @throws Error if no connection and no override, or if override server not found
|
|
116
|
+
*/
|
|
117
|
+
getClientWithOverride(override?: ConnectionOverride): Promise<OverrideClientResult>;
|
|
118
|
+
/**
|
|
119
|
+
* Executes a query with optional connection override.
|
|
120
|
+
* Convenience method that handles client lifecycle automatically.
|
|
121
|
+
*
|
|
122
|
+
* @param sql - SQL query to execute
|
|
123
|
+
* @param params - Query parameters
|
|
124
|
+
* @param override - Optional connection override parameters
|
|
125
|
+
* @returns Query result with connection info
|
|
126
|
+
*/
|
|
127
|
+
queryWithOverride<T extends QueryResultRow = any>(sql: string, params?: any[], override?: ConnectionOverride): Promise<QueryResult<T> & {
|
|
128
|
+
connectionInfo: {
|
|
129
|
+
server: string;
|
|
130
|
+
database: string;
|
|
131
|
+
schema: string;
|
|
132
|
+
};
|
|
133
|
+
}>;
|
|
134
|
+
/**
|
|
135
|
+
* Escapes a PostgreSQL identifier to prevent SQL injection
|
|
136
|
+
*/
|
|
137
|
+
private escapeIdentifier;
|
|
138
|
+
/**
|
|
139
|
+
* Closes all cached pools and cleans up resources
|
|
140
|
+
*/
|
|
141
|
+
closeAllCachedPools(): Promise<void>;
|
|
142
|
+
/**
|
|
143
|
+
* Gets comprehensive statistics about all connection pools (for monitoring/debugging)
|
|
144
|
+
*/
|
|
145
|
+
getConnectionStats(): {
|
|
146
|
+
totalActiveConnections: number;
|
|
147
|
+
maxTotalConnections: number;
|
|
148
|
+
mainPool: {
|
|
149
|
+
activeConnections: number;
|
|
150
|
+
maxSize: number;
|
|
151
|
+
isConnected: boolean;
|
|
152
|
+
};
|
|
153
|
+
cachedPools: {
|
|
154
|
+
count: number;
|
|
155
|
+
maxCount: number;
|
|
156
|
+
totalActiveConnections: number;
|
|
157
|
+
pools: Array<{
|
|
158
|
+
key: string;
|
|
159
|
+
serverName: string;
|
|
160
|
+
database: string;
|
|
161
|
+
activeConnections: number;
|
|
162
|
+
maxSize: number;
|
|
163
|
+
lastUsed: Date;
|
|
164
|
+
createdAt: Date;
|
|
165
|
+
idleTimeRemaining: number;
|
|
166
|
+
}>;
|
|
167
|
+
};
|
|
168
|
+
pendingPoolCreations: number;
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* @deprecated Use getConnectionStats() instead
|
|
172
|
+
* Gets statistics about cached pools (for monitoring/debugging)
|
|
173
|
+
*/
|
|
174
|
+
getCachedPoolStats(): {
|
|
175
|
+
count: number;
|
|
176
|
+
maxSize: number;
|
|
177
|
+
pools: Array<{
|
|
178
|
+
key: string;
|
|
179
|
+
serverName: string;
|
|
180
|
+
database: string;
|
|
181
|
+
lastUsed: Date;
|
|
182
|
+
createdAt: Date;
|
|
183
|
+
}>;
|
|
184
|
+
};
|
|
26
185
|
close(): Promise<void>;
|
|
27
186
|
/**
|
|
28
187
|
* Invalidates the current connection without clearing the connection state.
|
|
@@ -64,13 +223,24 @@ export declare class DatabaseManager {
|
|
|
64
223
|
*/
|
|
65
224
|
queryInTransaction<T extends QueryResultRow = any>(transactionId: string, sql: string, params?: any[]): Promise<QueryResult<T>>;
|
|
66
225
|
/**
|
|
67
|
-
* Gets information about an active transaction
|
|
226
|
+
* Gets information about an active transaction, including time remaining.
|
|
227
|
+
*
|
|
228
|
+
* @param transactionId - The transaction ID
|
|
229
|
+
* @returns Transaction info with age and time remaining, or null if not found
|
|
68
230
|
*/
|
|
69
|
-
getTransactionInfo(transactionId: string): TransactionInfo
|
|
231
|
+
getTransactionInfo(transactionId: string): (TransactionInfo & {
|
|
232
|
+
ageMs: number;
|
|
233
|
+
timeRemainingMs: number;
|
|
234
|
+
}) | null;
|
|
70
235
|
/**
|
|
71
|
-
* Lists all active transactions
|
|
236
|
+
* Lists all active transactions with age and time remaining.
|
|
237
|
+
*
|
|
238
|
+
* @returns Array of transaction info objects with age and time remaining
|
|
72
239
|
*/
|
|
73
|
-
listActiveTransactions(): TransactionInfo
|
|
240
|
+
listActiveTransactions(): Array<TransactionInfo & {
|
|
241
|
+
ageMs: number;
|
|
242
|
+
timeRemainingMs: number;
|
|
243
|
+
}>;
|
|
74
244
|
}
|
|
75
245
|
/**
|
|
76
246
|
* Gets the singleton DatabaseManager instance.
|
package/dist/db-manager.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db-manager.d.ts","sourceRoot":"","sources":["../src/db-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,IAAI,CAAC;AAEnE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,cAAc,EACd,YAAY,EACZ,iBAAiB,EACjB,eAAe,
|
|
1
|
+
{"version":3,"file":"db-manager.d.ts","sourceRoot":"","sources":["../src/db-manager.ts"],"names":[],"mappings":"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"}
|