philipgreat's picture
Deploy traceable order management playground
aa89cb5 verified
Raw History Blame Contribute Delete
2.77 kB
import { debugSQL } from '../src/sql/core';
import { Values } from '../src/core/value';
import { SQLiteDriver } from '../src/sql/sqlite';
describe('debugSQL', () => {
test('renders positional SQL that can be copied into SQLite or MySQL', () => {
expect(debugSQL(
"SELECT * FROM school WHERE name = ? AND active = ? AND phone IS ? AND note = '?'",
["O'Brien School", true, null],
)).toBe(
"SELECT * FROM school WHERE name = 'O''Brien School' AND active = TRUE AND phone IS NULL AND note = '?'",
);
});
test('renders numbered placeholders repeatedly and ignores SQL string literals', () => {
expect(debugSQL("SELECT $2, $1, $1, '$2'", ["O'Brien", 7]))
.toBe("SELECT 7, 'O''Brien', 'O''Brien', '$2'");
expect(debugSQL('SELECT @p2, @p1', ['first', 'second']))
.toBe("SELECT 'second', 'first'");
});
test('preserves comments and renders SQLite temporal storage literals', () => {
expect(debugSQL(
"-- line ? $1\nSELECT '?', \"identifier?\", ?, ? /* block ? */",
[Values.Date('2024-02-29'), Values.Timestamp(1787110200123)],
)).toBe(
"-- line ? $1\nSELECT '?', \"identifier?\", '2024-02-29', 1787110200123 /* block ? */",
);
});
test('temporal debug SQL matches prepared SQLite storage', async () => {
const driver = new SQLiteDriver(':memory:');
try {
await driver.query('CREATE TABLE temporal_fixture(id INTEGER, d TEXT, t INTEGER)');
await driver.query(
'INSERT INTO temporal_fixture VALUES (?, ?, ?) /* ignored ? */',
[1, '2024-02-29', -123],
);
const literal = debugSQL(
'/* teaql source=temporal ? */ INSERT INTO temporal_fixture VALUES (?, ?, ?)',
[Values.I64(2), Values.Date('2024-02-29'), Values.Timestamp(-123)],
);
await driver.query(literal);
const result = await driver.query(
'SELECT d, t, typeof(d) AS dt, typeof(t) AS tt FROM temporal_fixture ORDER BY id',
);
expect(result.rows).toEqual([
{ d: '2024-02-29', t: -123, dt: 'text', tt: 'integer' },
{ d: '2024-02-29', t: -123, dt: 'text', tt: 'integer' },
]);
} finally {
await driver.close();
}
});
test('renders PostgreSQL and MySQL typed temporal literals', () => {
const values = [Values.Date('2024-02-29'), Values.Timestamp(-315521754322)];
expect(debugSQL(
'-- ignored $1\nSELECT $1, $2 /* ignored $2 */', values, 'postgresql',
)).toBe(
"-- ignored $1\nSELECT DATE '2024-02-29', TIMESTAMPTZ '1960-01-02T03:04:05.678Z' /* ignored $2 */",
);
expect(debugSQL('SELECT ?, ? /* ignored ? */', values, 'mysql')).toBe(
"SELECT CAST('2024-02-29' AS DATE), CAST('1960-01-02 03:04:05.678' AS DATETIME(3)) /* ignored ? */",
);
});
});