sqlite-prepare
Version:
A type-safe SQL query builder for Cloudflare D1
157 lines (156 loc) • 6.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.build = build;
const parseValue_1 = require("./parseValue");
/**
* Builds a SQL query with parameterized values
*
* @param strings - SQL query string with placeholders or template strings array
* @param values - Values to interpolate into the query
* @returns A SQLQuery object with the query string and parameters
*
* @example
* // Using a template literal
* const userId = 123;
* const query = build`SELECT * FROM users WHERE id = ${userId}`;
*
* @example
* // Using an array for IN clause
* const roleIds = [1, 2, 3];
* const query = build`SELECT * FROM users WHERE role_id IN ${roleIds}`;
*
* @example
* // Using a raw SQL fragment
* const query = build`SELECT * FROM users WHERE ${raw('created_at > NOW()')}`;
*
* @example
* // Using a subquery
* const subquery = build`SELECT id FROM active_users`;
* const query = build`SELECT * FROM users WHERE id IN ${subquery}`;
*
* @example
* // Using insert
* const query = build`${insert(into('users'), { name: 'John', age: 30 })}`;
*/
function build(strings, ...values) {
let query;
let params = [];
// Handle regular string with question marks
if (typeof strings === 'string') {
query = strings;
params = values.map(parseValue_1.parseValue).flatMap(v => {
if (typeof v === 'object' && v !== null) {
// Handle special SQL types (subquery, fragment, raw)
if ('__subquery' in v || '__fragment' in v || '__raw' in v) {
return v.params || [];
}
}
return [v];
});
}
else {
// Handle template literals case
query = '';
for (let i = 0; i < strings.length; i++) {
query += strings[i];
if (i < values.length) {
const value = values[i];
// Check for various formats
if (Array.isArray(value)) {
// Handle arrays for IN clauses
if (value.length === 0) {
// Empty IN clause is usually a logical error, but can be handled
query += '(NULL)';
}
else {
query += '(' + value.map(() => '?').join(', ') + ')';
params.push(...value.map(parseValue_1.parseValue).flatMap(v => {
if (typeof v === 'object' && v !== null) {
// Handle special SQL types (subquery, fragment, raw)
if ('__subquery' in v || '__fragment' in v || '__raw' in v) {
return v.params || [];
}
}
return [v];
}));
}
}
else if (value && typeof value === 'object') {
// Handle special SQL types
if ('__raw' in value && value.__raw === true) {
// Raw SQL
query += value.query;
if (value.params) {
params.push(...value.params);
}
}
else if ('__fragment' in value && value.__fragment === true) {
// Fragment SQL
query += value.query;
params.push(...value.params);
}
else if ('__insert' in value && value.__insert === true) {
// Handle insert queries
const columns = Object.keys(value.values);
const placeholders = columns.map(col => {
const val = value.values[col];
if (typeof val === 'object' && val !== null) {
// Handle special SQL types in column values
if ('__raw' in val || '__fragment' in val) {
return val.query;
}
else if ('__subquery' in val) {
return `(${val.query})`;
}
}
return '?';
}).join(', ');
query += `INSERT INTO ${value.table} (${columns.join(', ')}) VALUES (${placeholders})`;
params.push(...columns.map(col => {
const val = value.values[col];
if (typeof val === 'object' && val !== null) {
// Handle special SQL types (subquery, fragment, raw)
if ('__subquery' in val || '__fragment' in val || '__raw' in val) {
return val.params || [];
}
}
return val;
}).flat());
}
else if ('query' in value && 'params' in value) {
// Handle nested SQLQuery objects (subqueries)
query += '(' + value.query + ')';
params.push(...value.params);
}
else {
// Regular object - use parseValue
const parsed = (0, parseValue_1.parseValue)(value);
if (typeof parsed === 'object' && parsed !== null) {
// Handle special SQL types
if ('__raw' in parsed || '__fragment' in parsed || '__subquery' in parsed) {
query += parsed.query;
if (parsed.params) {
params.push(...parsed.params);
}
}
else {
query += '?';
params.push(parsed);
}
}
else {
query += '?';
params.push(parsed);
}
}
}
else {
// Regular value
query += '?';
params.push((0, parseValue_1.parseValue)(value));
}
}
}
}
return { query, params };
}