MCPcopy Index your code
hub / github.com/bytebase/dbhub / executeSQL

Method executeSQL

src/connectors/sqlite/index.ts:451–592  ·  view source on GitHub ↗
(sql: string, options: ExecuteOptions, parameters?: any[])

Source from the content-addressed store, hash-verified

449
450
451 async executeSQL(sql: string, options: ExecuteOptions, parameters?: any[]): Promise<SQLResult> {
452 if (!this.db) {
453 throw new Error("Not connected to SQLite database");
454 }
455
456 // Engine-level read-only backstop: PRAGMA query_only=ON makes SQLite reject any
457 // write (including header-writing pragmas like `PRAGMA user_version=N` and
458 // `wal_checkpoint(...)`) regardless of what the keyword classifier allowed. The
459 // body below runs synchronously (node:sqlite is sync), so no other executeSQL
460 // call can interleave between toggling the flag on and restoring it.
461 if (options.readonly) {
462 this.db.exec("PRAGMA query_only = ON");
463 }
464
465 try {
466 // Check if this is a multi-statement query
467 const statements = splitSQLStatements(sql, "sqlite");
468
469 if (statements.length === 1) {
470 // Single statement - determine if it returns data
471 let processedStatement = statements[0];
472 const trimmedStatement = statements[0].toLowerCase().trim();
473 const isReadStatement = trimmedStatement.startsWith('select') ||
474 trimmedStatement.startsWith('with') ||
475 trimmedStatement.startsWith('explain') ||
476 trimmedStatement.startsWith('analyze') ||
477 (trimmedStatement.startsWith('pragma') &&
478 (trimmedStatement.includes('table_info') ||
479 trimmedStatement.includes('index_info') ||
480 trimmedStatement.includes('index_list') ||
481 trimmedStatement.includes('foreign_key_list')));
482
483 // Apply maxRows limit to SELECT queries if specified (not PRAGMA/ANALYZE)
484 if (options.maxRows) {
485 processedStatement = SQLRowLimiter.applyMaxRows(processedStatement, options.maxRows);
486 }
487
488 if (isReadStatement) {
489 // Pass parameters if provided
490 if (parameters && parameters.length > 0) {
491 try {
492 const rows = this.prepare(processedStatement).all(...parameters);
493 return { rows, rowCount: rows.length };
494 } catch (error) {
495 console.error(`[SQLite executeSQL] ERROR: ${(error as Error).message}`);
496 console.error(`[SQLite executeSQL] SQL: ${processedStatement}`);
497 console.error(`[SQLite executeSQL] Parameters: ${JSON.stringify(parameters)}`);
498 throw error;
499 }
500 } else {
501 const rows = this.prepare(processedStatement).all();
502 return { rows, rowCount: rows.length };
503 }
504 } else {
505 // Use run() for statements that don't return data
506 let result;
507 if (parameters && parameters.length > 0) {
508 try {

Callers

nothing calls this directly

Calls 3

prepareMethod · 0.95
splitSQLStatementsFunction · 0.85
applyMaxRowsMethod · 0.80

Tested by

no test coverage detected