feat: 打通出库作业链路
This commit is contained in:
104
tools/mcp/sqlserver-mcp-server/src/db.ts
Normal file
104
tools/mcp/sqlserver-mcp-server/src/db.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
import sql, { type config as SqlConfig, type ConnectionPool, type IResult, type Request } from "mssql";
|
||||
import type { ServerConfig } from "./config.js";
|
||||
import { quoteIdentifier, resolveDatabaseName, type SqlParam } from "./sql.js";
|
||||
|
||||
export type QueryResult = IResult<Record<string, unknown>>;
|
||||
|
||||
export class SqlServerClient {
|
||||
private readonly pools = new Map<string, Promise<ConnectionPool>>();
|
||||
|
||||
constructor(private readonly config: ServerConfig) {}
|
||||
|
||||
get allowedDatabases(): string[] {
|
||||
return this.config.allowedDatabases;
|
||||
}
|
||||
|
||||
get defaultDatabase(): string {
|
||||
return this.config.defaultDatabase;
|
||||
}
|
||||
|
||||
get readOnly(): boolean {
|
||||
return this.config.readOnly;
|
||||
}
|
||||
|
||||
get enableDdl(): boolean {
|
||||
return this.config.enableDdl;
|
||||
}
|
||||
|
||||
get maxRows(): number {
|
||||
return this.config.maxRows;
|
||||
}
|
||||
|
||||
get maxWriteRows(): number {
|
||||
return this.config.maxWriteRows;
|
||||
}
|
||||
|
||||
async query(
|
||||
databaseName: string | undefined,
|
||||
statement: string,
|
||||
params: SqlParam[] = []
|
||||
): Promise<QueryResult> {
|
||||
const pool = await this.getPool(databaseName);
|
||||
const request = pool.request();
|
||||
bindParams(request, params);
|
||||
return request.query(statement) as Promise<QueryResult>;
|
||||
}
|
||||
|
||||
async batch(databaseName: string | undefined, statement: string): Promise<QueryResult> {
|
||||
const pool = await this.getPool(databaseName);
|
||||
return pool.request().batch(statement) as Promise<QueryResult>;
|
||||
}
|
||||
|
||||
async close(): Promise<void> {
|
||||
const pools = await Promise.all([...this.pools.values()]);
|
||||
await Promise.all(pools.map((pool) => pool.close()));
|
||||
this.pools.clear();
|
||||
}
|
||||
|
||||
private async getPool(requestedDatabase: string | undefined): Promise<ConnectionPool> {
|
||||
const database = resolveDatabaseName(
|
||||
requestedDatabase,
|
||||
this.config.defaultDatabase,
|
||||
this.config.allowedDatabases
|
||||
);
|
||||
const key = database.toLowerCase();
|
||||
const existing = this.pools.get(key);
|
||||
if (existing) {
|
||||
return existing;
|
||||
}
|
||||
|
||||
const poolPromise = new sql.ConnectionPool(buildSqlConfig(this.config, database)).connect();
|
||||
this.pools.set(key, poolPromise);
|
||||
return poolPromise;
|
||||
}
|
||||
}
|
||||
|
||||
export function useDatabaseStatement(databaseName: string): string {
|
||||
return `USE ${quoteIdentifier(databaseName)};`;
|
||||
}
|
||||
|
||||
function buildSqlConfig(config: ServerConfig, database: string): SqlConfig {
|
||||
return {
|
||||
server: config.serverName,
|
||||
database,
|
||||
user: config.user,
|
||||
password: config.password,
|
||||
connectionTimeout: config.connectionTimeoutMs,
|
||||
requestTimeout: config.requestTimeoutMs,
|
||||
options: {
|
||||
encrypt: config.encrypt,
|
||||
trustServerCertificate: config.trustServerCertificate
|
||||
},
|
||||
pool: {
|
||||
max: 5,
|
||||
min: 0,
|
||||
idleTimeoutMillis: 30000
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function bindParams(request: Request, params: SqlParam[]): void {
|
||||
for (const param of params) {
|
||||
request.input(param.name, param.value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user