@lucidcms/sqlite-adapter
Version:
The official SQLite adapter for Lucid CMS
180 lines (174 loc) • 5.95 kB
JavaScript
import { DatabaseAdapter } from "@lucidcms/core";
import { ParseJSONResultsPlugin, SqliteDialect, sql } from "kysely";
import { jsonArrayFrom } from "kysely/helpers/sqlite";
//#region src/utils/format-default-value.ts
const formatDefaultValue = (type, defaultValue) => {
if (defaultValue === null) return null;
if (defaultValue === "''") return "";
if (type === "json" && defaultValue.startsWith("'") && defaultValue.endsWith("'")) try {
return JSON.parse(defaultValue.slice(1, -1));
} catch {
return null;
}
if (defaultValue.startsWith("'") && defaultValue.endsWith("'")) return defaultValue.slice(1, -1);
if (/^-?\d+(\.\d+)?$/.test(defaultValue)) return type === "integer" || type === "bigint" ? Number.parseInt(defaultValue, 10) : Number.parseFloat(defaultValue);
return defaultValue;
};
var format_default_value_default = formatDefaultValue;
//#endregion
//#region src/utils/format-on-delete.ts
const formatOnDelete = (value) => {
return value?.toLowerCase() ?? "no action";
};
var format_on_delete_default = formatOnDelete;
//#endregion
//#region src/utils/format-on-update.ts
const formatOnUpdate = (value) => {
return value?.toLowerCase() ?? "no action";
};
var format_on_update_default = formatOnUpdate;
//#endregion
//#region src/utils/format-type.ts
const formatType = (type) => {
return type.toLowerCase();
};
var format_type_default = formatType;
//#endregion
//#region src/index.ts
var SQLiteAdapter = class extends DatabaseAdapter {
constructor(config) {
super({
adapter: "sqlite",
dialect: new SqliteDialect(config),
plugins: [new ParseJSONResultsPlugin()]
});
}
async initialise() {
await sql`PRAGMA journal_mode = WAL`.execute(this.client);
await sql`PRAGMA foreign_keys = ON`.execute(this.client);
await sql`PRAGMA synchronous = NORMAL`.execute(this.client);
await sql`PRAGMA cache_size = -2000`.execute(this.client);
await sql`PRAGMA temp_store = MEMORY`.execute(this.client);
}
get jsonArrayFrom() {
return jsonArrayFrom;
}
get config() {
return {
support: {
alterColumn: false,
multipleAlterTables: false,
boolean: false,
autoIncrement: true
},
dataTypes: {
primary: "integer",
integer: "integer",
boolean: "integer",
json: "json",
text: "text",
timestamp: "timestamp",
char: "text",
varchar: "text"
},
defaults: {
timestamp: { now: "CURRENT_TIMESTAMP" },
boolean: {
true: 1,
false: 0
}
},
fuzzOperator: "like"
};
}
async inferSchema(tx) {
const res = await sql`
WITH RECURSIVE
tables AS (
SELECT name as table_name
FROM sqlite_master
WHERE type='table'
AND name LIKE 'lucid_%'
AND name NOT LIKE 'sqlite_%'
),
table_info AS (
SELECT
tables.table_name,
p.*
FROM tables
CROSS JOIN pragma_table_info(tables.table_name) as p
),
foreign_keys AS (
SELECT
tables.table_name,
fk.'from' as column_name,
fk.'table' as referenced_table,
fk.'to' as referenced_column,
fk.'on_update' as on_update,
fk.'on_delete' as on_delete
FROM tables
CROSS JOIN pragma_foreign_key_list(tables.table_name) as fk
),
unique_constraints AS (
SELECT
tables.table_name,
idx.name as index_name,
idx.'unique' as is_unique,
info.name as column_name
FROM tables
CROSS JOIN pragma_index_list(tables.table_name) as idx
CROSS JOIN pragma_index_info(idx.name) as info
WHERE idx.'unique' = 1
)
SELECT
t.*,
fk.referenced_table as fk_table,
fk.referenced_column as fk_column,
fk.on_update as fk_on_update,
fk.on_delete as fk_on_delete,
CASE WHEN uc.column_name IS NOT NULL THEN 1 ELSE 0 END as is_unique
FROM table_info t
LEFT JOIN foreign_keys fk ON
t.table_name = fk.table_name AND
t.name = fk.column_name
LEFT JOIN unique_constraints uc ON
t.table_name = uc.table_name AND
t.name = uc.column_name
`.execute(tx ?? this.client);
const tableMap = /* @__PURE__ */ new Map();
for (const row of res.rows) {
let table = tableMap.get(row.table_name);
if (!table) {
table = {
name: row.table_name,
columns: []
};
tableMap.set(row.table_name, table);
}
table.columns.push({
name: row.name,
type: format_type_default(row.type),
nullable: !row.notnull,
default: format_default_value_default(format_type_default(row.type), row.dflt_value),
primary: Boolean(row.pk),
unique: Boolean(row.is_unique),
foreignKey: row.fk_table && row.fk_column ? {
table: row.fk_table,
column: row.fk_column,
onUpdate: format_on_update_default(row.fk_on_update),
onDelete: format_on_delete_default(row.fk_on_delete)
} : void 0
});
}
return Array.from(tableMap.values());
}
formatDefaultValue(type, value) {
if (type === "timestamp" && typeof value === "string") return sql.raw(value);
if (typeof value === "object" && value !== null) return JSON.stringify(value);
return value;
}
};
var src_default = SQLiteAdapter;
//#endregion
export { src_default as default };
//# sourceMappingURL=index.js.map