MCPcopy Create free account
hub / github.com/QodeXcli/QodeX / execute

Method execute

src/tools/database/db-tools.ts:219–290  ·  view source on GitHub ↗
(args: z.infer<typeof DbQueryArgs>, _ctx: ToolContext)

Source from the content-addressed store, hash-verified

217 argsSchema = DbQueryArgs;
218
219 async execute(args: z.infer<typeof DbQueryArgs>, _ctx: ToolContext): Promise<ToolResult> {
220 if (!args.allow_write && !READ_ONLY_PREFIXES.test(args.sql)) {
221 return {
222 content: `[DB_QUERY_REFUSED] Only read statements (SELECT/EXPLAIN/SHOW/DESCRIBE/PRAGMA/WITH) are allowed by default. Detected non-read prefix in: ${args.sql.slice(0, 80)}…\n\nPass allow_write=true if intentional. Note: changes to a remote DB cannot be /restored by QodeX.`,
223 isError: true,
224 };
225 }
226
227 const parsed = parseConn(args.connection_string);
228 if (!parsed) return { content: `[DB_QUERY_ERROR] Bad connection_string`, isError: true };
229 const g = await getConnection(parsed);
230 if (g.kind === 'error') return { content: `[DB_QUERY_ERROR] ${g.message}`, isError: true };
231 const { conn } = g;
232 const maxRows = args.max_rows ?? 200;
233
234 try {
235 let rows: any[] = [];
236 let affectedRows: number | undefined;
237
238 if (parsed.dialect === 'mysql') {
239 const [r] = await conn.execute(args.sql, args.params ?? []);
240 if (Array.isArray(r)) rows = r as any[];
241 else affectedRows = (r as any).affectedRows;
242 } else if (parsed.dialect === 'postgres') {
243 const r = await conn.query(args.sql, args.params ?? []);
244 rows = r.rows ?? [];
245 affectedRows = r.rowCount ?? undefined;
246 } else {
247 const stmt = conn.prepare(args.sql);
248 if (stmt.reader) {
249 rows = stmt.all(...(args.params ?? []));
250 } else {
251 const info = stmt.run(...(args.params ?? []));
252 affectedRows = info.changes;
253 }
254 }
255
256 const out: string[] = [];
257 out.push(`# DB Query result`);
258 out.push(`SQL: ${args.sql.slice(0, 200)}${args.sql.length > 200 ? '…' : ''}`);
259 if (affectedRows !== undefined) {
260 out.push(`Affected rows: ${affectedRows}`);
261 }
262 if (rows.length > 0) {
263 const total = rows.length;
264 const shown = rows.slice(0, maxRows);
265 const cols = Object.keys(shown[0]!);
266 // Pretty-print as a markdown table
267 out.push('');
268 out.push(`Rows: ${total}${total > maxRows ? ` (showing first ${maxRows})` : ''}`);
269 out.push('');
270 out.push('| ' + cols.join(' | ') + ' |');
271 out.push('|' + cols.map(() => '---').join('|') + '|');
272 for (const r of shown) {
273 out.push('| ' + cols.map(c => {
274 const v = (r as any)[c];
275 if (v === null) return 'NULL';
276 const s = typeof v === 'object' ? JSON.stringify(v) : String(v);

Callers

nothing calls this directly

Calls 6

parseConnFunction · 0.85
getConnectionFunction · 0.85
closeConnectionFunction · 0.85
executeMethod · 0.65
runMethod · 0.65
pushMethod · 0.45

Tested by

no test coverage detected