(sql: string, ...params: ReadonlyArray<unknown>)
| 37 | } |
| 38 | |
| 39 | exec(sql: string, ...params: ReadonlyArray<unknown>) { |
| 40 | this.statements.push(sql) |
| 41 | const statement = normalizeSql(sql) |
| 42 | if (/^(BEGIN|COMMIT|ROLLBACK|SAVEPOINT)\b/i.test(statement)) { |
| 43 | throw new Error(`Unsupported transaction SQL: ${statement}`) |
| 44 | } |
| 45 | |
| 46 | if (/^CREATE TABLE\b/i.test(statement)) { |
| 47 | const match = /^CREATE TABLE(?: IF NOT EXISTS)?\s+("[^"]+"|\w+)\s*\((.*)\)$/i.exec(statement) |
| 48 | if (match !== null) { |
| 49 | const table = unquote(match[1]) |
| 50 | if (!this.tables.has(table)) { |
| 51 | this.tables.set(table, []) |
| 52 | this.columns.set( |
| 53 | table, |
| 54 | match[2].split(",").map((part) => unquote(part.trim().split(/\s+/)[0])).filter((column) => |
| 55 | column.length > 0 && column.toUpperCase() !== "PRIMARY" |
| 56 | ) |
| 57 | ) |
| 58 | } |
| 59 | } |
| 60 | return new FakeCursor([]) |
| 61 | } |
| 62 | |
| 63 | if (/^INSERT INTO\b/i.test(statement)) { |
| 64 | const match = /^INSERT INTO\s+("[^"]+"|\w+)\s*\(([^)]+)\)\s+VALUES\s+(.+)$/i.exec(statement) |
| 65 | if (match !== null) { |
| 66 | const table = unquote(match[1]) |
| 67 | const columns = match[2].split(",").map((column) => unquote(column.trim())) |
| 68 | const rows = this.tables.get(table) ?? [] |
| 69 | const tableColumns = this.columns.get(table) ?? [...columns] |
| 70 | if (!this.tables.has(table)) { |
| 71 | this.tables.set(table, rows) |
| 72 | this.columns.set(table, tableColumns) |
| 73 | } |
| 74 | let paramIndex = 0 |
| 75 | for (const group of valueGroups(match[3])) { |
| 76 | const values = group.split(",").map((value) => parseValue(value.trim(), params, () => paramIndex++)) |
| 77 | const row: Record<string, unknown> = {} |
| 78 | if (tableColumns.includes("id") && !columns.includes("id")) { |
| 79 | row.id = rows.length + 1 |
| 80 | } |
| 81 | for (let i = 0; i < columns.length; i++) { |
| 82 | row[columns[i]] = values[i] |
| 83 | } |
| 84 | if (tableColumns.includes("created_at") && row.created_at === undefined) { |
| 85 | row.created_at = "current_timestamp" |
| 86 | } |
| 87 | rows.push(row) |
| 88 | } |
| 89 | } |
| 90 | return new FakeCursor([]) |
| 91 | } |
| 92 | |
| 93 | if (/^SELECT\b/i.test(statement)) { |
| 94 | const match = |
| 95 | /^SELECT\s+(.+)\s+FROM\s+("[^"]+"|\w+)(?:\s+WHERE\s+("[^"]+"|\w+)\s*=\s*(\?|('[^']*')|\d+))?(?:\s+ORDER BY\s+("[^"]+"|\w+)\s+DESC)?$/i |
| 96 | .exec(statement) |
no test coverage detected