@negusdev/dbask 0.0.0-stage → 0.1.8
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/CHANGELOG.md +40 -0
- package/LICENSE +15 -0
- package/README.md +422 -2
- package/dist/ai/factory.d.ts +4 -0
- package/dist/ai/factory.d.ts.map +1 -0
- package/dist/ai/factory.js +55 -0
- package/dist/ai/factory.js.map +1 -0
- package/dist/ai/provider.d.ts +13 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +2 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/ai/sdk-provider.d.ts +13 -0
- package/dist/ai/sdk-provider.d.ts.map +1 -0
- package/dist/ai/sdk-provider.js +36 -0
- package/dist/ai/sdk-provider.js.map +1 -0
- package/dist/cli-args.d.ts +26 -0
- package/dist/cli-args.d.ts.map +1 -0
- package/dist/cli-args.js +72 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-observer.d.ts +23 -0
- package/dist/cli-observer.d.ts.map +1 -0
- package/dist/cli-observer.js +224 -0
- package/dist/cli-observer.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +127 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +247 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/validate.d.ts +31 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +205 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/config/config.d.ts +42 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +94 -0
- package/dist/config/config.js.map +1 -0
- package/dist/context/db-context.d.ts +12 -0
- package/dist/context/db-context.d.ts.map +1 -0
- package/dist/context/db-context.js +29 -0
- package/dist/context/db-context.js.map +1 -0
- package/dist/core/agent/agent.d.ts +57 -0
- package/dist/core/agent/agent.d.ts.map +1 -0
- package/dist/core/agent/agent.js +518 -0
- package/dist/core/agent/agent.js.map +1 -0
- package/dist/core/agent/index.d.ts +4 -0
- package/dist/core/agent/index.d.ts.map +1 -0
- package/dist/core/agent/index.js +2 -0
- package/dist/core/agent/index.js.map +1 -0
- package/dist/core/agent/observability.d.ts +19 -0
- package/dist/core/agent/observability.d.ts.map +1 -0
- package/dist/core/agent/observability.js +4 -0
- package/dist/core/agent/observability.js.map +1 -0
- package/dist/core/agent/query-plan.d.ts +68 -0
- package/dist/core/agent/query-plan.d.ts.map +1 -0
- package/dist/core/agent/query-plan.js +282 -0
- package/dist/core/agent/query-plan.js.map +1 -0
- package/dist/core/tools/describe-table.d.ts +6 -0
- package/dist/core/tools/describe-table.d.ts.map +1 -0
- package/dist/core/tools/describe-table.js +25 -0
- package/dist/core/tools/describe-table.js.map +1 -0
- package/dist/core/tools/describe-tables.d.ts +6 -0
- package/dist/core/tools/describe-tables.d.ts.map +1 -0
- package/dist/core/tools/describe-tables.js +22 -0
- package/dist/core/tools/describe-tables.js.map +1 -0
- package/dist/core/tools/execute-query.d.ts +6 -0
- package/dist/core/tools/execute-query.d.ts.map +1 -0
- package/dist/core/tools/execute-query.js +31 -0
- package/dist/core/tools/execute-query.js.map +1 -0
- package/dist/core/tools/explain-query.d.ts +10 -0
- package/dist/core/tools/explain-query.d.ts.map +1 -0
- package/dist/core/tools/explain-query.js +34 -0
- package/dist/core/tools/explain-query.js.map +1 -0
- package/dist/core/tools/get-relationships.d.ts +6 -0
- package/dist/core/tools/get-relationships.d.ts.map +1 -0
- package/dist/core/tools/get-relationships.js +23 -0
- package/dist/core/tools/get-relationships.js.map +1 -0
- package/dist/core/tools/index.d.ts +9 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +8 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/list-tables.d.ts +3 -0
- package/dist/core/tools/list-tables.d.ts.map +1 -0
- package/dist/core/tools/list-tables.js +18 -0
- package/dist/core/tools/list-tables.js.map +1 -0
- package/dist/core/tools/registry.d.ts +11 -0
- package/dist/core/tools/registry.d.ts.map +1 -0
- package/dist/core/tools/registry.js +48 -0
- package/dist/core/tools/registry.js.map +1 -0
- package/dist/core/types/index.d.ts +102 -0
- package/dist/core/types/index.d.ts.map +1 -0
- package/dist/core/types/index.js +6 -0
- package/dist/core/types/index.js.map +1 -0
- package/dist/database/adapter.d.ts +3 -0
- package/dist/database/adapter.d.ts.map +1 -0
- package/dist/database/adapter.js +2 -0
- package/dist/database/adapter.js.map +1 -0
- package/dist/database/factory.d.ts +16 -0
- package/dist/database/factory.d.ts.map +1 -0
- package/dist/database/factory.js +27 -0
- package/dist/database/factory.js.map +1 -0
- package/dist/database/index.d.ts +8 -0
- package/dist/database/index.d.ts.map +1 -0
- package/dist/database/index.js +4 -0
- package/dist/database/index.js.map +1 -0
- package/dist/database/mysql/adapter.d.ts +26 -0
- package/dist/database/mysql/adapter.d.ts.map +1 -0
- package/dist/database/mysql/adapter.js +131 -0
- package/dist/database/mysql/adapter.js.map +1 -0
- package/dist/database/postgres/adapter.d.ts +60 -0
- package/dist/database/postgres/adapter.d.ts.map +1 -0
- package/dist/database/postgres/adapter.js +307 -0
- package/dist/database/postgres/adapter.js.map +1 -0
- package/dist/database/result-limits.d.ts +17 -0
- package/dist/database/result-limits.d.ts.map +1 -0
- package/dist/database/result-limits.js +26 -0
- package/dist/database/result-limits.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/safety/limits.d.ts +7 -0
- package/dist/safety/limits.d.ts.map +1 -0
- package/dist/safety/limits.js +15 -0
- package/dist/safety/limits.js.map +1 -0
- package/dist/safety/policy.d.ts +8 -0
- package/dist/safety/policy.d.ts.map +1 -0
- package/dist/safety/policy.js +11 -0
- package/dist/safety/policy.js.map +1 -0
- package/dist/safety/sql-tokenizer.d.ts +49 -0
- package/dist/safety/sql-tokenizer.d.ts.map +1 -0
- package/dist/safety/sql-tokenizer.js +240 -0
- package/dist/safety/sql-tokenizer.js.map +1 -0
- package/dist/safety/sql-validator.d.ts +34 -0
- package/dist/safety/sql-validator.d.ts.map +1 -0
- package/dist/safety/sql-validator.js +270 -0
- package/dist/safety/sql-validator.js.map +1 -0
- package/dist/schema/cache.d.ts +24 -0
- package/dist/schema/cache.d.ts.map +1 -0
- package/dist/schema/cache.js +57 -0
- package/dist/schema/cache.js.map +1 -0
- package/dist/ui/markdown.d.ts +8 -0
- package/dist/ui/markdown.d.ts.map +1 -0
- package/dist/ui/markdown.js +205 -0
- package/dist/ui/markdown.js.map +1 -0
- package/dist/ui/spinner.d.ts +32 -0
- package/dist/ui/spinner.d.ts.map +1 -0
- package/dist/ui/spinner.js +74 -0
- package/dist/ui/spinner.js.map +1 -0
- package/dist/ui/sql-highlight.d.ts +4 -0
- package/dist/ui/sql-highlight.d.ts.map +1 -0
- package/dist/ui/sql-highlight.js +28 -0
- package/dist/ui/sql-highlight.js.map +1 -0
- package/dist/ui/style.d.ts +38 -0
- package/dist/ui/style.d.ts.map +1 -0
- package/dist/ui/style.js +69 -0
- package/dist/ui/style.js.map +1 -0
- package/package.json +91 -4
- package/sql-ai.example.md +32 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-tables.d.ts","sourceRoot":"","sources":["../../../src/core/tools/list-tables.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEpE,wBAAsB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC,CAgB7E"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export async function listTables(context) {
|
|
2
|
+
try {
|
|
3
|
+
const tables = context.schemaCache
|
|
4
|
+
? await context.schemaCache.listTables(context.database)
|
|
5
|
+
: await context.database.listTables();
|
|
6
|
+
return {
|
|
7
|
+
success: true,
|
|
8
|
+
data: tables,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
return {
|
|
13
|
+
success: false,
|
|
14
|
+
error: error instanceof Error ? error.message : 'Failed to list database tables.',
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=list-tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-tables.js","sourceRoot":"","sources":["../../../src/core/tools/list-tables.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAAoB;IACnD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW;YAChC,CAAC,CAAC,MAAM,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC;YACxD,CAAC,CAAC,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;QAExC,OAAO;YACL,OAAO,EAAE,IAAI;YACb,IAAI,EAAE,MAAM;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,iCAAiC;SAClF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SqlToolResult, ToolContext } from '../types/index.js';
|
|
2
|
+
export type ToolName = 'list_tables' | 'describe_table' | 'describe_tables' | 'get_relationships' | 'execute_query' | 'explain_query';
|
|
3
|
+
export interface RegisteredTool {
|
|
4
|
+
name: ToolName;
|
|
5
|
+
description: string;
|
|
6
|
+
execute: (input: unknown, context: ToolContext) => Promise<SqlToolResult>;
|
|
7
|
+
}
|
|
8
|
+
export declare function getTool(name: ToolName): RegisteredTool;
|
|
9
|
+
export declare function getTools(): RegisteredTool[];
|
|
10
|
+
export declare function executeTool(name: ToolName, input: unknown, context: ToolContext): Promise<SqlToolResult>;
|
|
11
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/core/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAQpE,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,eAAe,GACf,eAAe,CAAC;AAEpB,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;CAC3E;AAmCD,wBAAgB,OAAO,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAEtD;AAED,wBAAgB,QAAQ,IAAI,cAAc,EAAE,CAE3C;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,QAAQ,EACd,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,aAAa,CAAC,CAExB"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { describeTable } from './describe-table.js';
|
|
2
|
+
import { describeTables } from './describe-tables.js';
|
|
3
|
+
import { executeQuery } from './execute-query.js';
|
|
4
|
+
import { explainQuery } from './explain-query.js';
|
|
5
|
+
import { getRelationships } from './get-relationships.js';
|
|
6
|
+
import { listTables } from './list-tables.js';
|
|
7
|
+
const tools = {
|
|
8
|
+
list_tables: {
|
|
9
|
+
name: 'list_tables',
|
|
10
|
+
description: 'List the tables available in the connected database.',
|
|
11
|
+
execute: (_input, context) => listTables(context),
|
|
12
|
+
},
|
|
13
|
+
describe_table: {
|
|
14
|
+
name: 'describe_table',
|
|
15
|
+
description: 'Inspect the columns and basic schema information for a database table.',
|
|
16
|
+
execute: (input, context) => describeTable(input, context),
|
|
17
|
+
},
|
|
18
|
+
describe_tables: {
|
|
19
|
+
name: 'describe_tables',
|
|
20
|
+
description: 'Inspect columns and basic schema information for multiple database tables at once. Use this when several tables are relevant.',
|
|
21
|
+
execute: (input, context) => describeTables(input, context),
|
|
22
|
+
},
|
|
23
|
+
get_relationships: {
|
|
24
|
+
name: 'get_relationships',
|
|
25
|
+
description: 'List foreign-key relationships in the connected database, optionally for one table.',
|
|
26
|
+
execute: (input, context) => getRelationships((input ?? {}), context),
|
|
27
|
+
},
|
|
28
|
+
execute_query: {
|
|
29
|
+
name: 'execute_query',
|
|
30
|
+
description: 'Execute a validated read-only SQL query against the connected database.',
|
|
31
|
+
execute: (input, context) => executeQuery(input, context),
|
|
32
|
+
},
|
|
33
|
+
explain_query: {
|
|
34
|
+
name: 'explain_query',
|
|
35
|
+
description: 'Return the database execution plan for a validated SELECT or WITH query.',
|
|
36
|
+
execute: (input, context) => explainQuery(input, context),
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export function getTool(name) {
|
|
40
|
+
return tools[name];
|
|
41
|
+
}
|
|
42
|
+
export function getTools() {
|
|
43
|
+
return Object.values(tools);
|
|
44
|
+
}
|
|
45
|
+
export async function executeTool(name, input, context) {
|
|
46
|
+
return getTool(name).execute(input, context);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/core/tools/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAA2B,MAAM,qBAAqB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAA4B,MAAM,sBAAsB,CAAC;AAChF,OAAO,EAAE,YAAY,EAA0B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAA0B,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAA8B,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAgB9C,MAAM,KAAK,GAAqC;IAC9C,WAAW,EAAE;QACX,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,sDAAsD;QACnE,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;KAClD;IACD,cAAc,EAAE;QACd,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,wEAAwE;QACrF,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,aAAa,CAAC,KAA2B,EAAE,OAAO,CAAC;KACjF;IACD,eAAe,EAAE;QACf,IAAI,EAAE,iBAAiB;QACvB,WAAW,EAAE,+HAA+H;QAC5I,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,KAA4B,EAAE,OAAO,CAAC;KACnF;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,qFAAqF;QAClG,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,CAAC,KAAK,IAAI,EAAE,CAA0B,EAAE,OAAO,CAAC;KAC/F;IACD,aAAa,EAAE;QACb,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,yEAAyE;QACtF,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,KAA0B,EAAE,OAAO,CAAC;KAC/E;IACD,aAAa,EAAE;QACb,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,0EAA0E;QACvF,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,YAAY,CAAC,KAA0B,EAAE,OAAO,CAAC;KAC/E;CACF,CAAC;AAEF,MAAM,UAAU,OAAO,CAAC,IAAc;IACpC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAc,EACd,KAAc,EACd,OAAoB;IAEpB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared domain types. These types deliberately do not depend on a provider,
|
|
3
|
+
* database driver, CLI framework, or HTTP framework.
|
|
4
|
+
*/
|
|
5
|
+
export type SqlDialect = 'mysql' | 'postgres' | 'sqlite';
|
|
6
|
+
export interface ModelRequest {
|
|
7
|
+
system?: string;
|
|
8
|
+
prompt: string;
|
|
9
|
+
tools?: unknown;
|
|
10
|
+
temperature?: number;
|
|
11
|
+
maxSteps?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface ModelResponse {
|
|
14
|
+
text: string;
|
|
15
|
+
raw?: unknown;
|
|
16
|
+
steps?: number;
|
|
17
|
+
toolCalls?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface ModelProvider {
|
|
20
|
+
readonly name: string;
|
|
21
|
+
generate(request: ModelRequest): Promise<ModelResponse>;
|
|
22
|
+
}
|
|
23
|
+
export interface TableInfo {
|
|
24
|
+
name: string;
|
|
25
|
+
schema?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ColumnInfo {
|
|
28
|
+
name: string;
|
|
29
|
+
dataType: string;
|
|
30
|
+
nullable: boolean;
|
|
31
|
+
defaultValue?: unknown;
|
|
32
|
+
isPrimaryKey: boolean;
|
|
33
|
+
isAutoIncrement: boolean;
|
|
34
|
+
}
|
|
35
|
+
export interface TableSchema {
|
|
36
|
+
table: TableInfo;
|
|
37
|
+
columns: ColumnInfo[];
|
|
38
|
+
}
|
|
39
|
+
export interface RelationshipInfo {
|
|
40
|
+
table: string;
|
|
41
|
+
column: string;
|
|
42
|
+
referencedTable: string;
|
|
43
|
+
referencedColumn: string;
|
|
44
|
+
constraintName?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface QueryResult {
|
|
47
|
+
rows: Record<string, unknown>[];
|
|
48
|
+
rowCount: number;
|
|
49
|
+
executionTimeMs: number;
|
|
50
|
+
/**
|
|
51
|
+
* True when more rows were available than were returned, because the row or
|
|
52
|
+
* result-size limit was reached. Answers computed from a truncated result
|
|
53
|
+
* (counts, sums, "all of ...") are incomplete.
|
|
54
|
+
*/
|
|
55
|
+
truncated?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/** TLS behavior for database connections. Mirrors libpq's sslmode names. */
|
|
58
|
+
export type DatabaseSslMode = 'disable' | 'require' | 'verify-full';
|
|
59
|
+
export interface QueryPlan {
|
|
60
|
+
sql: string;
|
|
61
|
+
plan: unknown;
|
|
62
|
+
}
|
|
63
|
+
export interface DatabaseAdapter {
|
|
64
|
+
readonly dialect: SqlDialect;
|
|
65
|
+
listTables(): Promise<TableInfo[]>;
|
|
66
|
+
describeTable(table: string): Promise<TableSchema>;
|
|
67
|
+
getRelationships(table?: string): Promise<RelationshipInfo[]>;
|
|
68
|
+
executeQuery(sql: string, options?: QueryExecutionOptions): Promise<QueryResult>;
|
|
69
|
+
explainQuery(sql: string): Promise<QueryPlan>;
|
|
70
|
+
close?(): Promise<void>;
|
|
71
|
+
}
|
|
72
|
+
export interface QueryExecutionOptions {
|
|
73
|
+
maxRows?: number;
|
|
74
|
+
timeoutMs?: number;
|
|
75
|
+
maxResultBytes?: number;
|
|
76
|
+
}
|
|
77
|
+
export interface SqlSafetyPolicy {
|
|
78
|
+
readOnly: boolean;
|
|
79
|
+
maxRows: number;
|
|
80
|
+
queryTimeoutMs: number;
|
|
81
|
+
maxResultBytes: number;
|
|
82
|
+
}
|
|
83
|
+
export interface ToolContext {
|
|
84
|
+
database: DatabaseAdapter;
|
|
85
|
+
safety: SqlSafetyPolicy;
|
|
86
|
+
schemaCache?: import('../../schema/cache.js').SchemaCache;
|
|
87
|
+
}
|
|
88
|
+
export interface DatabaseContext {
|
|
89
|
+
content?: string;
|
|
90
|
+
source?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface SqlToolResult {
|
|
93
|
+
success: boolean;
|
|
94
|
+
data?: unknown;
|
|
95
|
+
error?: string;
|
|
96
|
+
/**
|
|
97
|
+
* True when the database adapter was actually called.
|
|
98
|
+
* False when SQL was rejected before database execution.
|
|
99
|
+
*/
|
|
100
|
+
executionAttempted?: boolean;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/types/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/types/index.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/database/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,YAAY,EAAE,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/database/adapter.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DatabaseAdapter, DatabaseSslMode } from '../core/types/index.js';
|
|
2
|
+
export interface DatabaseConnectionConfig {
|
|
3
|
+
driver: 'mysql' | 'postgres' | 'sqlite';
|
|
4
|
+
host: string;
|
|
5
|
+
port: number;
|
|
6
|
+
name: string;
|
|
7
|
+
user: string;
|
|
8
|
+
password: string;
|
|
9
|
+
ssl?: DatabaseSslMode;
|
|
10
|
+
}
|
|
11
|
+
/** Drivers that have an adapter. */
|
|
12
|
+
export declare const SUPPORTED_DRIVERS: readonly ['mysql', 'postgres'];
|
|
13
|
+
export declare function isSupportedDriver(driver: string): boolean;
|
|
14
|
+
/** Creates the adapter for `config.driver`. Throws for drivers without one. */
|
|
15
|
+
export declare function createDatabaseAdapter(config: DatabaseConnectionConfig): DatabaseAdapter;
|
|
16
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/database/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAI/E,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,QAAQ,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAED,oCAAoC;AACpC,eAAO,MAAM,iBAAiB,YAAI,OAAO,EAAE,UAAU,CAAU,CAAC;AAEhE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,+EAA+E;AAC/E,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,wBAAwB,GAAG,eAAe,CAoBvF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { MySqlAdapter } from './mysql/adapter.js';
|
|
2
|
+
import { PostgresAdapter } from './postgres/adapter.js';
|
|
3
|
+
/** Drivers that have an adapter. */
|
|
4
|
+
export const SUPPORTED_DRIVERS = ['mysql', 'postgres'];
|
|
5
|
+
export function isSupportedDriver(driver) {
|
|
6
|
+
return SUPPORTED_DRIVERS.includes(driver);
|
|
7
|
+
}
|
|
8
|
+
/** Creates the adapter for `config.driver`. Throws for drivers without one. */
|
|
9
|
+
export function createDatabaseAdapter(config) {
|
|
10
|
+
const connection = {
|
|
11
|
+
host: config.host,
|
|
12
|
+
port: config.port,
|
|
13
|
+
database: config.name,
|
|
14
|
+
user: config.user,
|
|
15
|
+
password: config.password,
|
|
16
|
+
ssl: config.ssl,
|
|
17
|
+
};
|
|
18
|
+
switch (config.driver) {
|
|
19
|
+
case 'mysql':
|
|
20
|
+
return new MySqlAdapter(connection);
|
|
21
|
+
case 'postgres':
|
|
22
|
+
return new PostgresAdapter(connection);
|
|
23
|
+
default:
|
|
24
|
+
throw new Error(`Database driver "${config.driver}" is not implemented yet. Supported: ${SUPPORTED_DRIVERS.join(', ')}.`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/database/factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAYxD,oCAAoC;AACpC,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,UAAU,CAAU,CAAC;AAEhE,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,OAAQ,iBAAuC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACnE,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,qBAAqB,CAAC,MAAgC;IACpE,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,IAAI;QACrB,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,EAAE,MAAM,CAAC,GAAG;KAChB,CAAC;IAEF,QAAQ,MAAM,CAAC,MAAM,EAAE,CAAC;QACtB,KAAK,OAAO;YACV,OAAO,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC;QACtC,KAAK,UAAU;YACb,OAAO,IAAI,eAAe,CAAC,UAAU,CAAC,CAAC;QACzC;YACE,MAAM,IAAI,KAAK,CACb,oBAAoB,MAAM,CAAC,MAAM,wCAAwC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CACzG,CAAC;IACN,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { DatabaseAdapter } from './adapter.js';
|
|
2
|
+
export { MySqlAdapter } from './mysql/adapter.js';
|
|
3
|
+
export type { MySqlAdapterConfig } from './mysql/adapter.js';
|
|
4
|
+
export { PostgresAdapter } from './postgres/adapter.js';
|
|
5
|
+
export type { PostgresAdapterConfig } from './postgres/adapter.js';
|
|
6
|
+
export { createDatabaseAdapter, isSupportedDriver, SUPPORTED_DRIVERS } from './factory.js';
|
|
7
|
+
export type { DatabaseConnectionConfig } from './factory.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,YAAY,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC3F,YAAY,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DatabaseAdapter, DatabaseSslMode, QueryExecutionOptions, QueryPlan, QueryResult, RelationshipInfo, TableInfo, TableSchema } from '../../core/types/index.js';
|
|
2
|
+
export interface MySqlAdapterConfig {
|
|
3
|
+
host: string;
|
|
4
|
+
port: number;
|
|
5
|
+
database: string;
|
|
6
|
+
user: string;
|
|
7
|
+
password: string;
|
|
8
|
+
connectionLimit?: number;
|
|
9
|
+
/**
|
|
10
|
+
* TLS mode. `require` encrypts without verifying the server certificate;
|
|
11
|
+
* `verify-full` also verifies it. Defaults to `disable`.
|
|
12
|
+
*/
|
|
13
|
+
ssl?: DatabaseSslMode;
|
|
14
|
+
}
|
|
15
|
+
export declare class MySqlAdapter implements DatabaseAdapter {
|
|
16
|
+
readonly dialect: 'mysql';
|
|
17
|
+
private readonly pool;
|
|
18
|
+
constructor(config: MySqlAdapterConfig);
|
|
19
|
+
listTables(): Promise<TableInfo[]>;
|
|
20
|
+
describeTable(table: string): Promise<TableSchema>;
|
|
21
|
+
getRelationships(table?: string): Promise<RelationshipInfo[]>;
|
|
22
|
+
executeQuery(sql: string, options?: QueryExecutionOptions): Promise<QueryResult>;
|
|
23
|
+
explainQuery(sql: string): Promise<QueryPlan>;
|
|
24
|
+
close(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/database/mysql/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,WAAW,EACZ,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAED,qBAAa,YAAa,YAAW,eAAe;IAClD,QAAQ,CAAC,OAAO,EAAG,OAAO,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAO;IAE5B,YAAY,MAAM,EAAE,kBAAkB,EAoBrC;IAEK,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAYvC;IAEK,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAmCvD;IAEK,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAmClE;IAEK,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,WAAW,CAAC,CAwBzF;IAEK,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAUlD;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;CACF"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import mysql from 'mysql2/promise';
|
|
2
|
+
import { limitRows } from '../result-limits.js';
|
|
3
|
+
export class MySqlAdapter {
|
|
4
|
+
dialect = 'mysql';
|
|
5
|
+
pool;
|
|
6
|
+
constructor(config) {
|
|
7
|
+
const options = {
|
|
8
|
+
host: config.host,
|
|
9
|
+
port: config.port,
|
|
10
|
+
database: config.database,
|
|
11
|
+
user: config.user,
|
|
12
|
+
password: config.password,
|
|
13
|
+
connectionLimit: config.connectionLimit ?? 5,
|
|
14
|
+
waitForConnections: true,
|
|
15
|
+
enableKeepAlive: true,
|
|
16
|
+
dateStrings: true,
|
|
17
|
+
};
|
|
18
|
+
if (config.ssl === 'require') {
|
|
19
|
+
options.ssl = { rejectUnauthorized: false };
|
|
20
|
+
}
|
|
21
|
+
else if (config.ssl === 'verify-full') {
|
|
22
|
+
options.ssl = { rejectUnauthorized: true };
|
|
23
|
+
}
|
|
24
|
+
this.pool = mysql.createPool(options);
|
|
25
|
+
}
|
|
26
|
+
async listTables() {
|
|
27
|
+
const [rows] = await this.pool.query(`
|
|
28
|
+
SELECT TABLE_NAME AS table_name
|
|
29
|
+
FROM information_schema.TABLES
|
|
30
|
+
WHERE TABLE_SCHEMA = DATABASE()
|
|
31
|
+
AND TABLE_TYPE = 'BASE TABLE'
|
|
32
|
+
ORDER BY TABLE_NAME ASC
|
|
33
|
+
`);
|
|
34
|
+
return rows.map((row) => ({ name: String(row.table_name) }));
|
|
35
|
+
}
|
|
36
|
+
async describeTable(table) {
|
|
37
|
+
const [rows] = await this.pool.execute(`
|
|
38
|
+
SELECT
|
|
39
|
+
COLUMN_NAME AS column_name,
|
|
40
|
+
DATA_TYPE AS data_type,
|
|
41
|
+
IS_NULLABLE AS is_nullable,
|
|
42
|
+
COLUMN_DEFAULT AS column_default,
|
|
43
|
+
COLUMN_KEY AS column_key,
|
|
44
|
+
EXTRA AS extra
|
|
45
|
+
FROM information_schema.COLUMNS
|
|
46
|
+
WHERE TABLE_SCHEMA = DATABASE()
|
|
47
|
+
AND TABLE_NAME = ?
|
|
48
|
+
ORDER BY ORDINAL_POSITION ASC
|
|
49
|
+
`, [table]);
|
|
50
|
+
if (rows.length === 0) {
|
|
51
|
+
throw new Error(`Table "${table}" was not found in the current database.`);
|
|
52
|
+
}
|
|
53
|
+
const columns = rows.map((row) => ({
|
|
54
|
+
name: String(row.column_name),
|
|
55
|
+
dataType: String(row.data_type),
|
|
56
|
+
nullable: row.is_nullable === 'YES',
|
|
57
|
+
defaultValue: row.column_default,
|
|
58
|
+
isPrimaryKey: row.column_key === 'PRI',
|
|
59
|
+
isAutoIncrement: String(row.extra ?? '').toLowerCase().includes('auto_increment'),
|
|
60
|
+
}));
|
|
61
|
+
return {
|
|
62
|
+
table: { name: table },
|
|
63
|
+
columns,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
async getRelationships(table) {
|
|
67
|
+
const conditions = [
|
|
68
|
+
'TABLE_SCHEMA = DATABASE()',
|
|
69
|
+
'REFERENCED_TABLE_SCHEMA = DATABASE()',
|
|
70
|
+
];
|
|
71
|
+
const params = [];
|
|
72
|
+
if (table) {
|
|
73
|
+
conditions.push('TABLE_NAME = ?');
|
|
74
|
+
params.push(table);
|
|
75
|
+
}
|
|
76
|
+
const [rows] = await this.pool.execute(`
|
|
77
|
+
SELECT
|
|
78
|
+
TABLE_NAME AS table_name,
|
|
79
|
+
COLUMN_NAME AS column_name,
|
|
80
|
+
REFERENCED_TABLE_NAME AS referenced_table,
|
|
81
|
+
REFERENCED_COLUMN_NAME AS referenced_column,
|
|
82
|
+
CONSTRAINT_NAME AS constraint_name
|
|
83
|
+
FROM information_schema.KEY_COLUMN_USAGE
|
|
84
|
+
WHERE ${conditions.join(' AND ')}
|
|
85
|
+
AND REFERENCED_TABLE_NAME IS NOT NULL
|
|
86
|
+
ORDER BY TABLE_NAME ASC, COLUMN_NAME ASC
|
|
87
|
+
`, params);
|
|
88
|
+
return rows.map((row) => ({
|
|
89
|
+
table: String(row.table_name),
|
|
90
|
+
column: String(row.column_name),
|
|
91
|
+
referencedTable: String(row.referenced_table),
|
|
92
|
+
referencedColumn: String(row.referenced_column),
|
|
93
|
+
constraintName: String(row.constraint_name),
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
async executeQuery(sql, options = {}) {
|
|
97
|
+
const maxRows = options.maxRows ?? 500;
|
|
98
|
+
const timeoutMs = options.timeoutMs ?? 10_000;
|
|
99
|
+
const maxResultBytes = options.maxResultBytes ?? 1_048_576;
|
|
100
|
+
const startedAt = performance.now();
|
|
101
|
+
// mysql2 supports a client-side timeout for text queries.
|
|
102
|
+
const [rawRows] = await this.pool.query({
|
|
103
|
+
sql,
|
|
104
|
+
timeout: timeoutMs,
|
|
105
|
+
});
|
|
106
|
+
const fetched = Array.isArray(rawRows)
|
|
107
|
+
? rawRows.map((row) => ({ ...row }))
|
|
108
|
+
: [];
|
|
109
|
+
const { rows, truncated } = limitRows(fetched, maxRows, maxResultBytes);
|
|
110
|
+
return {
|
|
111
|
+
rows,
|
|
112
|
+
rowCount: rows.length,
|
|
113
|
+
executionTimeMs: Math.round(performance.now() - startedAt),
|
|
114
|
+
truncated,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async explainQuery(sql) {
|
|
118
|
+
const [rows] = await this.pool.query({
|
|
119
|
+
sql: `EXPLAIN ${sql}`,
|
|
120
|
+
timeout: 10_000,
|
|
121
|
+
});
|
|
122
|
+
return {
|
|
123
|
+
sql,
|
|
124
|
+
plan: rows,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async close() {
|
|
128
|
+
await this.pool.end();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/database/mysql/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { DatabaseAdapter, DatabaseSslMode, QueryExecutionOptions, QueryPlan, QueryResult, RelationshipInfo, TableInfo, TableSchema } from '../../core/types/index.js';
|
|
2
|
+
export interface PostgresAdapterConfig {
|
|
3
|
+
host: string;
|
|
4
|
+
port: number;
|
|
5
|
+
database: string;
|
|
6
|
+
user: string;
|
|
7
|
+
password: string;
|
|
8
|
+
connectionLimit?: number;
|
|
9
|
+
/**
|
|
10
|
+
* TLS mode. `require` encrypts without verifying the server certificate
|
|
11
|
+
* (like libpq's sslmode=require); `verify-full` also verifies the
|
|
12
|
+
* certificate chain and host name. Use NODE_EXTRA_CA_CERTS to trust a
|
|
13
|
+
* private CA. Defaults to `disable`.
|
|
14
|
+
*/
|
|
15
|
+
ssl?: DatabaseSslMode;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* PostgreSQL adapter.
|
|
19
|
+
*
|
|
20
|
+
* Safety properties, independent of the SQL validator:
|
|
21
|
+
* - Every statement runs inside `BEGIN READ ONLY`, so the server refuses
|
|
22
|
+
* writes even if the connected role is allowed to make them. The
|
|
23
|
+
* transaction is always rolled back.
|
|
24
|
+
* - `statement_timeout` is set per transaction, so slow queries are cancelled
|
|
25
|
+
* by the server rather than abandoned by the client.
|
|
26
|
+
* - Queries use the extended protocol (via a cursor), so the server itself
|
|
27
|
+
* rejects multiple statements in one request.
|
|
28
|
+
* - Rows are fetched through the cursor, so at most `maxRows + 1` rows are
|
|
29
|
+
* ever transferred, however large the result is.
|
|
30
|
+
* - `standard_conforming_strings` is pinned to `on`, which the validator's
|
|
31
|
+
* tokenizer assumes.
|
|
32
|
+
*
|
|
33
|
+
* A dedicated read-only database role is still recommended.
|
|
34
|
+
*/
|
|
35
|
+
export declare class PostgresAdapter implements DatabaseAdapter {
|
|
36
|
+
readonly dialect: 'postgres';
|
|
37
|
+
private readonly pool;
|
|
38
|
+
constructor(config: PostgresAdapterConfig);
|
|
39
|
+
listTables(): Promise<TableInfo[]>;
|
|
40
|
+
describeTable(table: string): Promise<TableSchema>;
|
|
41
|
+
getRelationships(table?: string): Promise<RelationshipInfo[]>;
|
|
42
|
+
executeQuery(sql: string, options?: QueryExecutionOptions): Promise<QueryResult>;
|
|
43
|
+
explainQuery(sql: string): Promise<QueryPlan>;
|
|
44
|
+
close(): Promise<void>;
|
|
45
|
+
/** Runs a fixed catalog query with bind parameters. */
|
|
46
|
+
private run;
|
|
47
|
+
/**
|
|
48
|
+
* Resolves a name from the model ("users", "Sales.orders", "\"Order Items\"")
|
|
49
|
+
* to a table. Unqualified names resolve the way SQL would (search_path);
|
|
50
|
+
* an exact-case match wins over a lower-case one.
|
|
51
|
+
*/
|
|
52
|
+
private resolveTable;
|
|
53
|
+
/**
|
|
54
|
+
* Runs `work` inside a READ ONLY transaction with a server-side statement
|
|
55
|
+
* timeout. The transaction is always rolled back. A connection that saw an
|
|
56
|
+
* error is discarded rather than returned to the pool.
|
|
57
|
+
*/
|
|
58
|
+
private withReadOnlyTransaction;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/database/postgres/adapter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,SAAS,EACT,WAAW,EACX,gBAAgB,EAChB,SAAS,EACT,WAAW,EACZ,MAAM,2BAA2B,CAAC;AAGnC,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAqED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACrD,QAAQ,CAAC,OAAO,EAAG,UAAU,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAU;IAE/B,YAAY,MAAM,EAAE,qBAAqB,EA0BxC;IAEK,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBvC;IAEK,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA2CvD;IAEK,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAkDlE;IAEK,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,WAAW,CAAC,CAuBzF;IAEK,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAelD;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAE3B;IAED,uDAAuD;YACzC,GAAG;IAOjB;;;;OAIG;YACW,YAAY;IAgD1B;;;;OAIG;YACW,uBAAuB;CA8BtC"}
|