agnostic-query
Version:
Type-safe fluent builder for portable query schemas. Runtime-agnostic, database-agnostic — the same QuerySchema drives Drizzle, Kysely, db0, or raw SQL.
69 lines (68 loc) • 2.53 kB
JavaScript
import { isComparisonWhere } from "../core/where.js";
import { fieldToStr } from "../sql/sqlite.js";
import { and, asc, desc, eq, gt, gte, inArray, like, lt, lte, not, or, sql } from "drizzle-orm";
//#region src/drizzle/sqlite.ts
const opMap = {
"=": eq,
">": gt,
">=": gte,
"<": lt,
"<=": lte,
like
};
const _toDrizzleWhere = (table, where) => {
if (!where) return void 0;
if (where.op === "not") {
const sub = _toDrizzleWhere(table, where.condition);
return sub ? not(sub) : void 0;
}
if (where.op === "and" || where.op === "or") {
const conditions = where.conditions.map((c) => _toDrizzleWhere(table, c)).filter((c) => !!c);
if (conditions.length === 0) return;
return where.op === "and" ? and(...conditions) : or(...conditions);
}
if (!isComparisonWhere(where)) return;
const [rootKey, ...segments] = where.field;
const column = table[rootKey];
if (!column) {
console.warn(`Field ${rootKey} does not exist on table`);
return;
}
const target = segments.length === 0 ? column : sql.raw(fieldToStr(where.field));
if (where.op === "in") return inArray(target, where.values);
if (where.op === "is null") return sql`${target} IS NULL`;
if (where.op === "ilike") return sql`LOWER(${target}) LIKE LOWER(${where.value})`;
if (where.op === "@>" || where.op === "<@" || where.op === "&&") {
console.warn(`Operator ${where.op} not supported for SQLite adapter`);
return;
}
const opFn = opMap[where.op];
if (!opFn) {
console.warn(`Operator ${where.op} not supported for SQLite adapter`);
return;
}
return opFn(target, where.value);
};
const toDrizzleWhere = (table, where, extra) => {
const wc = _toDrizzleWhere(table, where);
if (!extra) return wc;
if (!wc) return extra;
return and(extra, wc);
};
const toDrizzleOrderBy = (table, orderBy) => {
if (!orderBy) return [];
return orderBy.map((c) => {
const col = table[c.field[0]];
return (c.direction === "desc" ? desc : asc)(col);
});
};
const toDrizzle = (db, table, querySchema) => {
if (!querySchema) return db.select().from(table);
const query = db.select().from(table).where(toDrizzleWhere(table, querySchema.where)).orderBy(...toDrizzleOrderBy(table, querySchema.orderBy));
if (querySchema.limit && querySchema.offset) return query.limit(querySchema.limit).offset(querySchema.offset);
if (querySchema.limit) return query.limit(querySchema.limit);
if (querySchema.offset) return query.offset(querySchema.offset);
return query;
};
//#endregion
export { toDrizzle as default, toDrizzle, toDrizzleOrderBy, toDrizzleWhere };