@tejasanik/postgres-mcp-server 1.0.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/LICENSE +21 -0
- package/README.md +237 -0
- package/dist/db-manager.d.ts +25 -0
- package/dist/db-manager.d.ts.map +1 -0
- package/dist/db-manager.js +148 -0
- package/dist/db-manager.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +358 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/analysis-tools.d.ts +24 -0
- package/dist/tools/analysis-tools.d.ts.map +1 -0
- package/dist/tools/analysis-tools.js +449 -0
- package/dist/tools/analysis-tools.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +21 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/schema-tools.d.ts +22 -0
- package/dist/tools/schema-tools.d.ts.map +1 -0
- package/dist/tools/schema-tools.js +189 -0
- package/dist/tools/schema-tools.js.map +1 -0
- package/dist/tools/server-tools.d.ts +28 -0
- package/dist/tools/server-tools.d.ts.map +1 -0
- package/dist/tools/server-tools.js +71 -0
- package/dist/tools/server-tools.js.map +1 -0
- package/dist/tools/sql-tools.d.ts +17 -0
- package/dist/tools/sql-tools.d.ts.map +1 -0
- package/dist/tools/sql-tools.js +134 -0
- package/dist/tools/sql-tools.js.map +1 -0
- package/dist/types.d.ts +83 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Sanikommu Teja
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# PostgreSQL MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server for PostgreSQL database management and analysis. This server provides comprehensive tools for exploring database schemas, executing queries, analyzing performance, and monitoring database health.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g postgres-mcp-server
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or run directly with npx:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx postgres-mcp-server
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
### Environment Variables
|
|
20
|
+
|
|
21
|
+
Set the `POSTGRES_SERVERS` environment variable with a JSON object containing your server configurations:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
export POSTGRES_SERVERS='{
|
|
25
|
+
"dev": {
|
|
26
|
+
"host": "pgbouncer-server-devdb.elb.us-east-1.amazonaws.com",
|
|
27
|
+
"port": "5432",
|
|
28
|
+
"username": "your_username",
|
|
29
|
+
"password": "your_password"
|
|
30
|
+
},
|
|
31
|
+
"staging": {
|
|
32
|
+
"host": "pgbouncer-server-stagingdb.elb.us-east-1.amazonaws.com",
|
|
33
|
+
"port": "5432",
|
|
34
|
+
"username": "your_username",
|
|
35
|
+
"password": "your_password"
|
|
36
|
+
},
|
|
37
|
+
"production": {
|
|
38
|
+
"host": "pgbouncer-server-proddb.elb.us-east-1.amazonaws.com",
|
|
39
|
+
"port": "5432",
|
|
40
|
+
"username": "your_username",
|
|
41
|
+
"password": "your_password"
|
|
42
|
+
}
|
|
43
|
+
}'
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Claude Desktop Configuration
|
|
47
|
+
|
|
48
|
+
Add the server to your Claude Desktop MCP configuration (`claude_desktop_config.json`):
|
|
49
|
+
|
|
50
|
+
```json
|
|
51
|
+
{
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"postgres": {
|
|
54
|
+
"command": "npx",
|
|
55
|
+
"args": ["postgres-mcp-server"],
|
|
56
|
+
"env": {
|
|
57
|
+
"POSTGRES_SERVERS": "{\"dev\":{\"host\":\"your-host.com\",\"port\":\"5432\",\"username\":\"user\",\"password\":\"pass\"}}"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Available Tools
|
|
65
|
+
|
|
66
|
+
### Server & Database Management
|
|
67
|
+
|
|
68
|
+
#### `list_servers_and_dbs`
|
|
69
|
+
|
|
70
|
+
Lists all configured PostgreSQL servers and their databases.
|
|
71
|
+
|
|
72
|
+
**Parameters:**
|
|
73
|
+
|
|
74
|
+
- `filter` (optional): Filter servers and databases by name
|
|
75
|
+
- `includeSystemDbs` (optional): Include system databases (template0, template1)
|
|
76
|
+
- `fetchDatabases` (optional): Fetch list of databases from connected server
|
|
77
|
+
|
|
78
|
+
#### `switch_server_db`
|
|
79
|
+
|
|
80
|
+
Switch to a different PostgreSQL server and optionally a specific database.
|
|
81
|
+
|
|
82
|
+
**Parameters:**
|
|
83
|
+
|
|
84
|
+
- `server` (required): Name of the server to connect to
|
|
85
|
+
- `database` (optional): Name of the database to connect to
|
|
86
|
+
|
|
87
|
+
### Schema & Object Exploration
|
|
88
|
+
|
|
89
|
+
#### `list_schemas`
|
|
90
|
+
|
|
91
|
+
Lists all database schemas in the current PostgreSQL database.
|
|
92
|
+
|
|
93
|
+
**Parameters:**
|
|
94
|
+
|
|
95
|
+
- `includeSystemSchemas` (optional): Include system schemas
|
|
96
|
+
|
|
97
|
+
#### `list_objects`
|
|
98
|
+
|
|
99
|
+
Lists database objects within a specified schema.
|
|
100
|
+
|
|
101
|
+
**Parameters:**
|
|
102
|
+
|
|
103
|
+
- `schema` (required): Schema name to list objects from
|
|
104
|
+
- `objectType` (optional): Type of objects to list (table, view, sequence, extension, all)
|
|
105
|
+
- `filter` (optional): Filter objects by name
|
|
106
|
+
|
|
107
|
+
#### `get_object_details`
|
|
108
|
+
|
|
109
|
+
Provides detailed information about a database object including columns, constraints, indexes, size, and row count.
|
|
110
|
+
|
|
111
|
+
**Parameters:**
|
|
112
|
+
|
|
113
|
+
- `schema` (required): Schema name containing the object
|
|
114
|
+
- `objectName` (required): Name of the object
|
|
115
|
+
- `objectType` (optional): Type of the object
|
|
116
|
+
|
|
117
|
+
### Query Execution
|
|
118
|
+
|
|
119
|
+
#### `execute_sql`
|
|
120
|
+
|
|
121
|
+
Executes SQL statements on the database. Read-only mode prevents write operations.
|
|
122
|
+
|
|
123
|
+
**Parameters:**
|
|
124
|
+
|
|
125
|
+
- `sql` (required): SQL statement to execute
|
|
126
|
+
- `maxRows` (optional): Maximum rows to return directly (default: 1000)
|
|
127
|
+
|
|
128
|
+
**Note:** Large outputs are automatically written to a temp file, and the file path is returned. This prevents token wastage when dealing with large result sets.
|
|
129
|
+
|
|
130
|
+
#### `explain_query`
|
|
131
|
+
|
|
132
|
+
Gets the execution plan for a SQL query.
|
|
133
|
+
|
|
134
|
+
**Parameters:**
|
|
135
|
+
|
|
136
|
+
- `sql` (required): SQL query to explain
|
|
137
|
+
- `analyze` (optional): Execute query to get real timing
|
|
138
|
+
- `buffers` (optional): Include buffer usage statistics
|
|
139
|
+
- `format` (optional): Output format (text, json, yaml, xml)
|
|
140
|
+
- `hypotheticalIndexes` (optional): Simulate indexes (requires hypopg extension)
|
|
141
|
+
|
|
142
|
+
### Performance Analysis
|
|
143
|
+
|
|
144
|
+
#### `get_top_queries`
|
|
145
|
+
|
|
146
|
+
Reports the slowest SQL queries based on execution time.
|
|
147
|
+
|
|
148
|
+
**Parameters:**
|
|
149
|
+
|
|
150
|
+
- `limit` (optional): Number of queries to return (default: 10)
|
|
151
|
+
- `orderBy` (optional): Order by total_time, mean_time, or calls
|
|
152
|
+
- `minCalls` (optional): Minimum number of calls to include
|
|
153
|
+
|
|
154
|
+
**Requires:** `pg_stat_statements` extension
|
|
155
|
+
|
|
156
|
+
#### `analyze_workload_indexes`
|
|
157
|
+
|
|
158
|
+
Analyzes database workload and recommends optimal indexes.
|
|
159
|
+
|
|
160
|
+
**Parameters:**
|
|
161
|
+
|
|
162
|
+
- `topQueriesCount` (optional): Number of top queries to analyze
|
|
163
|
+
- `includeHypothetical` (optional): Include hypothetical index analysis
|
|
164
|
+
|
|
165
|
+
#### `analyze_query_indexes`
|
|
166
|
+
|
|
167
|
+
Analyzes specific SQL queries and recommends indexes.
|
|
168
|
+
|
|
169
|
+
**Parameters:**
|
|
170
|
+
|
|
171
|
+
- `queries` (required): Array of SQL queries to analyze (max 10)
|
|
172
|
+
|
|
173
|
+
### Health Monitoring
|
|
174
|
+
|
|
175
|
+
#### `analyze_db_health`
|
|
176
|
+
|
|
177
|
+
Performs comprehensive database health checks including:
|
|
178
|
+
|
|
179
|
+
- **Buffer Cache Hit Rate**: Checks cache efficiency
|
|
180
|
+
- **Connection Health**: Monitors connection usage
|
|
181
|
+
- **Invalid Indexes**: Detects broken indexes
|
|
182
|
+
- **Unused Indexes**: Identifies indexes that aren't being used
|
|
183
|
+
- **Duplicate Indexes**: Finds redundant indexes
|
|
184
|
+
- **Vacuum Health**: Monitors dead tuple ratios
|
|
185
|
+
- **Sequence Limits**: Warns about sequences approaching limits
|
|
186
|
+
- **Constraint Validation**: Checks for unvalidated constraints
|
|
187
|
+
|
|
188
|
+
## Usage Examples
|
|
189
|
+
|
|
190
|
+
### Connect to a Server and List Databases
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
1. Use list_servers_and_dbs to see available servers
|
|
194
|
+
2. Use switch_server_db with server="dev" to connect
|
|
195
|
+
3. Use list_servers_and_dbs with fetchDatabases=true to see databases
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Explore Database Schema
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
1. Use list_schemas to see all schemas
|
|
202
|
+
2. Use list_objects with schema="public" to see tables
|
|
203
|
+
3. Use get_object_details with schema="public", objectName="users" to see table structure
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Analyze Query Performance
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
1. Use explain_query with your SQL to see the execution plan
|
|
210
|
+
2. Use get_top_queries to find slow queries
|
|
211
|
+
3. Use analyze_query_indexes to get index recommendations
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Health Check
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
1. Use analyze_db_health to run all health checks
|
|
218
|
+
2. Review warnings and critical issues
|
|
219
|
+
3. Take action on recommendations
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Security
|
|
223
|
+
|
|
224
|
+
- By default, the server runs in **read-only mode**, preventing any write operations (INSERT, UPDATE, DELETE, DROP, etc.)
|
|
225
|
+
- Credentials are managed via environment variables
|
|
226
|
+
- No credentials are logged or exposed through the MCP interface
|
|
227
|
+
|
|
228
|
+
## Requirements
|
|
229
|
+
|
|
230
|
+
- Node.js 18.0.0 or higher
|
|
231
|
+
- PostgreSQL 11 or higher
|
|
232
|
+
- Optional: `pg_stat_statements` extension for query performance analysis
|
|
233
|
+
- Optional: `hypopg` extension for hypothetical index simulation
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
MIT
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { PoolClient, QueryResult, QueryResultRow } from 'pg';
|
|
2
|
+
import { ServerConfig, ServersConfig, ConnectionState, DatabaseInfo } from './types.js';
|
|
3
|
+
export declare class DatabaseManager {
|
|
4
|
+
private serversConfig;
|
|
5
|
+
private connectionState;
|
|
6
|
+
private currentPool;
|
|
7
|
+
private readOnlyMode;
|
|
8
|
+
constructor(readOnlyMode?: boolean);
|
|
9
|
+
private loadServersConfig;
|
|
10
|
+
getServersConfig(): ServersConfig;
|
|
11
|
+
getServerNames(): string[];
|
|
12
|
+
getServerConfig(serverName: string): ServerConfig | null;
|
|
13
|
+
getCurrentState(): ConnectionState;
|
|
14
|
+
isConnected(): boolean;
|
|
15
|
+
switchServer(serverName: string, database?: string): Promise<void>;
|
|
16
|
+
switchDatabase(database: string): Promise<void>;
|
|
17
|
+
listDatabases(): Promise<DatabaseInfo[]>;
|
|
18
|
+
query<T extends QueryResultRow = any>(sql: string, params?: any[]): Promise<QueryResult<T>>;
|
|
19
|
+
getClient(): Promise<PoolClient>;
|
|
20
|
+
close(): Promise<void>;
|
|
21
|
+
isReadOnly(): boolean;
|
|
22
|
+
setReadOnlyMode(readOnly: boolean): void;
|
|
23
|
+
}
|
|
24
|
+
export declare function getDbManager(readOnlyMode?: boolean): DatabaseManager;
|
|
25
|
+
//# sourceMappingURL=db-manager.d.ts.map
|
|
@@ -0,0 +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;AACnE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,YAAY,EACb,MAAM,YAAY,CAAC;AAKpB,qBAAa,eAAe;IAC1B,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,YAAY,CAAU;gBAElB,YAAY,GAAE,OAAc;IASxC,OAAO,CAAC,iBAAiB;IAelB,gBAAgB,IAAI,aAAa;IAIjC,cAAc,IAAI,MAAM,EAAE;IAI1B,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIxD,eAAe,IAAI,eAAe;IAIlC,WAAW,IAAI,OAAO;IAIhB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqClE,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/C,aAAa,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;IAcxC,KAAK,CAAC,CAAC,SAAS,cAAc,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAoB3F,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IAOhC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B,UAAU,IAAI,OAAO;IAIrB,eAAe,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI;CAGhD;AAKD,wBAAgB,YAAY,CAAC,YAAY,GAAE,OAAc,GAAG,eAAe,CAK1E"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseManager = void 0;
|
|
4
|
+
exports.getDbManager = getDbManager;
|
|
5
|
+
const pg_1 = require("pg");
|
|
6
|
+
const DEFAULT_PORT = '5432';
|
|
7
|
+
const DEFAULT_DATABASE = 'postgres';
|
|
8
|
+
class DatabaseManager {
|
|
9
|
+
serversConfig;
|
|
10
|
+
connectionState;
|
|
11
|
+
currentPool = null;
|
|
12
|
+
readOnlyMode;
|
|
13
|
+
constructor(readOnlyMode = true) {
|
|
14
|
+
this.serversConfig = this.loadServersConfig();
|
|
15
|
+
this.connectionState = {
|
|
16
|
+
currentServer: null,
|
|
17
|
+
currentDatabase: null
|
|
18
|
+
};
|
|
19
|
+
this.readOnlyMode = readOnlyMode;
|
|
20
|
+
}
|
|
21
|
+
loadServersConfig() {
|
|
22
|
+
const configEnv = process.env.POSTGRES_SERVERS;
|
|
23
|
+
if (!configEnv) {
|
|
24
|
+
console.error('Warning: POSTGRES_SERVERS environment variable not set. Using empty config.');
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return JSON.parse(configEnv);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error('Error parsing POSTGRES_SERVERS:', error);
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
getServersConfig() {
|
|
36
|
+
return this.serversConfig;
|
|
37
|
+
}
|
|
38
|
+
getServerNames() {
|
|
39
|
+
return Object.keys(this.serversConfig);
|
|
40
|
+
}
|
|
41
|
+
getServerConfig(serverName) {
|
|
42
|
+
return this.serversConfig[serverName] || null;
|
|
43
|
+
}
|
|
44
|
+
getCurrentState() {
|
|
45
|
+
return { ...this.connectionState };
|
|
46
|
+
}
|
|
47
|
+
isConnected() {
|
|
48
|
+
return this.currentPool !== null;
|
|
49
|
+
}
|
|
50
|
+
async switchServer(serverName, database) {
|
|
51
|
+
const serverConfig = this.getServerConfig(serverName);
|
|
52
|
+
if (!serverConfig) {
|
|
53
|
+
throw new Error(`Server '${serverName}' not found in configuration`);
|
|
54
|
+
}
|
|
55
|
+
// Close existing pool if any
|
|
56
|
+
if (this.currentPool) {
|
|
57
|
+
await this.currentPool.end();
|
|
58
|
+
}
|
|
59
|
+
const dbName = database || DEFAULT_DATABASE;
|
|
60
|
+
this.currentPool = new pg_1.Pool({
|
|
61
|
+
host: serverConfig.host,
|
|
62
|
+
port: parseInt(serverConfig.port || DEFAULT_PORT, 10),
|
|
63
|
+
user: serverConfig.username,
|
|
64
|
+
password: serverConfig.password,
|
|
65
|
+
database: dbName,
|
|
66
|
+
max: 10,
|
|
67
|
+
idleTimeoutMillis: 30000,
|
|
68
|
+
connectionTimeoutMillis: 10000
|
|
69
|
+
});
|
|
70
|
+
// Test connection
|
|
71
|
+
try {
|
|
72
|
+
const client = await this.currentPool.connect();
|
|
73
|
+
client.release();
|
|
74
|
+
this.connectionState.currentServer = serverName;
|
|
75
|
+
this.connectionState.currentDatabase = dbName;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
await this.currentPool.end();
|
|
79
|
+
this.currentPool = null;
|
|
80
|
+
throw new Error(`Failed to connect to server '${serverName}': ${error}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async switchDatabase(database) {
|
|
84
|
+
if (!this.connectionState.currentServer) {
|
|
85
|
+
throw new Error('No server selected. Please switch to a server first.');
|
|
86
|
+
}
|
|
87
|
+
await this.switchServer(this.connectionState.currentServer, database);
|
|
88
|
+
}
|
|
89
|
+
async listDatabases() {
|
|
90
|
+
const result = await this.query(`
|
|
91
|
+
SELECT
|
|
92
|
+
datname as name,
|
|
93
|
+
pg_catalog.pg_get_userbyid(datdba) as owner,
|
|
94
|
+
pg_catalog.pg_encoding_to_char(encoding) as encoding,
|
|
95
|
+
pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(datname)) as size
|
|
96
|
+
FROM pg_catalog.pg_database
|
|
97
|
+
WHERE datistemplate = false
|
|
98
|
+
ORDER BY datname
|
|
99
|
+
`);
|
|
100
|
+
return result.rows;
|
|
101
|
+
}
|
|
102
|
+
async query(sql, params) {
|
|
103
|
+
if (!this.currentPool) {
|
|
104
|
+
throw new Error('No database connection. Please switch to a server and database first.');
|
|
105
|
+
}
|
|
106
|
+
// Check for read-only mode violations
|
|
107
|
+
if (this.readOnlyMode) {
|
|
108
|
+
const upperSql = sql.trim().toUpperCase();
|
|
109
|
+
const writeOperations = ['INSERT', 'UPDATE', 'DELETE', 'DROP', 'CREATE', 'ALTER', 'TRUNCATE', 'GRANT', 'REVOKE'];
|
|
110
|
+
for (const op of writeOperations) {
|
|
111
|
+
if (upperSql.startsWith(op)) {
|
|
112
|
+
throw new Error(`Write operation '${op}' is not allowed in read-only mode`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return this.currentPool.query(sql, params);
|
|
117
|
+
}
|
|
118
|
+
async getClient() {
|
|
119
|
+
if (!this.currentPool) {
|
|
120
|
+
throw new Error('No database connection. Please switch to a server and database first.');
|
|
121
|
+
}
|
|
122
|
+
return this.currentPool.connect();
|
|
123
|
+
}
|
|
124
|
+
async close() {
|
|
125
|
+
if (this.currentPool) {
|
|
126
|
+
await this.currentPool.end();
|
|
127
|
+
this.currentPool = null;
|
|
128
|
+
this.connectionState.currentServer = null;
|
|
129
|
+
this.connectionState.currentDatabase = null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
isReadOnly() {
|
|
133
|
+
return this.readOnlyMode;
|
|
134
|
+
}
|
|
135
|
+
setReadOnlyMode(readOnly) {
|
|
136
|
+
this.readOnlyMode = readOnly;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.DatabaseManager = DatabaseManager;
|
|
140
|
+
// Singleton instance
|
|
141
|
+
let dbManager = null;
|
|
142
|
+
function getDbManager(readOnlyMode = true) {
|
|
143
|
+
if (!dbManager) {
|
|
144
|
+
dbManager = new DatabaseManager(readOnlyMode);
|
|
145
|
+
}
|
|
146
|
+
return dbManager;
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=db-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-manager.js","sourceRoot":"","sources":["../src/db-manager.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|