First stable version

This commit is contained in:
Benjamin Toby 2026-03-08 07:50:38 +01:00
parent 7bbd179fa4
commit 3a4ba2ca6f
44 changed files with 1098 additions and 791 deletions

View File

@ -1,22 +1,37 @@
import { Command } from "commander"; "use strict";
import init from "../functions/init"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import path from "path"; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
import grabDBDir from "../utils/grab-db-dir"; return new (P || (P = Promise))(function (resolve, reject) {
import fs from "fs"; function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
import grabDBBackupFileName from "../utils/grab-db-backup-file-name"; function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
import chalk from "chalk"; function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
import trimBackups from "../utils/trim-backups"; step((generator = generator.apply(thisArg, _arguments || [])).next());
export default function () {
return new Command("backup")
.description("Backup Database")
.action(async (opts) => {
console.log(`Backing up database ...`);
const { config } = await init();
const { backup_dir, db_file_path } = grabDBDir({ config });
const new_db_file_name = grabDBBackupFileName({ config });
fs.cpSync(db_file_path, path.join(backup_dir, new_db_file_name));
trimBackups({ config });
console.log(`${chalk.bold(chalk.green(`DB Backup Success!`))}`);
process.exit();
}); });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const commander_1 = require("commander");
const init_1 = __importDefault(require("../functions/init"));
const path_1 = __importDefault(require("path"));
const grab_db_dir_1 = __importDefault(require("../utils/grab-db-dir"));
const fs_1 = __importDefault(require("fs"));
const grab_db_backup_file_name_1 = __importDefault(require("../utils/grab-db-backup-file-name"));
const chalk_1 = __importDefault(require("chalk"));
const trim_backups_1 = __importDefault(require("../utils/trim-backups"));
function default_1() {
return new commander_1.Command("backup")
.description("Backup Database")
.action((opts) => __awaiter(this, void 0, void 0, function* () {
console.log(`Backing up database ...`);
const { config } = yield (0, init_1.default)();
const { backup_dir, db_file_path } = (0, grab_db_dir_1.default)({ config });
const new_db_file_name = (0, grab_db_backup_file_name_1.default)({ config });
fs_1.default.cpSync(db_file_path, path_1.default.join(backup_dir, new_db_file_name));
(0, trim_backups_1.default)({ config });
console.log(`${chalk_1.default.bold(chalk_1.default.green(`DB Backup Success!`))}`);
process.exit();
}));
} }

View File

@ -1,31 +1,36 @@
#!/usr/bin/env bun #!/usr/bin/env bun
import { program } from "commander"; "use strict";
import schema from "./schema"; var __importDefault = (this && this.__importDefault) || function (mod) {
import typedef from "./typedef"; return (mod && mod.__esModule) ? mod : { "default": mod };
import backup from "./backup"; };
import restore from "./restore"; Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = require("commander");
const schema_1 = __importDefault(require("./schema"));
const typedef_1 = __importDefault(require("./typedef"));
const backup_1 = __importDefault(require("./backup"));
const restore_1 = __importDefault(require("./restore"));
/** /**
* # Describe Program * # Describe Program
*/ */
program commander_1.program
.name(`bun-sqlite`) .name(`bun-sqlite`)
.description(`SQLite manager for Bun`) .description(`SQLite manager for Bun`)
.version(`1.0.0`); .version(`1.0.0`);
/** /**
* # Declare Commands * # Declare Commands
*/ */
program.addCommand(schema()); commander_1.program.addCommand((0, schema_1.default)());
program.addCommand(typedef()); commander_1.program.addCommand((0, typedef_1.default)());
program.addCommand(backup()); commander_1.program.addCommand((0, backup_1.default)());
program.addCommand(restore()); commander_1.program.addCommand((0, restore_1.default)());
/** /**
* # Handle Unavailable Commands * # Handle Unavailable Commands
*/ */
program.on("command:*", () => { commander_1.program.on("command:*", () => {
console.error("Invalid command: %s\nSee --help for a list of available commands.", program.args.join(" ")); console.error("Invalid command: %s\nSee --help for a list of available commands.", commander_1.program.args.join(" "));
process.exit(1); process.exit(1);
}); });
/** /**
* # Parse Arguments * # Parse Arguments
*/ */
program.parse(Bun.argv); commander_1.program.parse(process.argv);

View File

@ -1,29 +1,44 @@
import { Command } from "commander"; "use strict";
import init from "../functions/init"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import grabDBDir from "../utils/grab-db-dir"; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
import fs from "fs"; return new (P || (P = Promise))(function (resolve, reject) {
import chalk from "chalk"; function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
import grabSortedBackups from "../utils/grab-sorted-backups"; function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
import { select } from "@inquirer/prompts"; function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
import grabBackupData from "../utils/grab-backup-data"; step((generator = generator.apply(thisArg, _arguments || [])).next());
import path from "path"; });
export default function () { };
return new Command("restore") var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const commander_1 = require("commander");
const init_1 = __importDefault(require("../functions/init"));
const grab_db_dir_1 = __importDefault(require("../utils/grab-db-dir"));
const fs_1 = __importDefault(require("fs"));
const chalk_1 = __importDefault(require("chalk"));
const grab_sorted_backups_1 = __importDefault(require("../utils/grab-sorted-backups"));
const prompts_1 = require("@inquirer/prompts");
const grab_backup_data_1 = __importDefault(require("../utils/grab-backup-data"));
const path_1 = __importDefault(require("path"));
function default_1() {
return new commander_1.Command("restore")
.description("Restore Database") .description("Restore Database")
.action(async (opts) => { .action((opts) => __awaiter(this, void 0, void 0, function* () {
console.log(`Restoring up database ...`); console.log(`Restoring up database ...`);
const { config } = await init(); const { config } = yield (0, init_1.default)();
const { backup_dir, db_file_path } = grabDBDir({ config }); const { backup_dir, db_file_path } = (0, grab_db_dir_1.default)({ config });
const backups = grabSortedBackups({ config }); const backups = (0, grab_sorted_backups_1.default)({ config });
if (!backups?.[0]) { if (!(backups === null || backups === void 0 ? void 0 : backups[0])) {
console.error(`No Backups to restore. Use the \`backup\` command to create a backup`); console.error(`No Backups to restore. Use the \`backup\` command to create a backup`);
process.exit(1); process.exit(1);
} }
try { try {
const selected_backup = await select({ const selected_backup = yield (0, prompts_1.select)({
message: "Select a backup:", message: "Select a backup:",
choices: backups.map((b, i) => { choices: backups.map((b, i) => {
const { backup_date } = grabBackupData({ const { backup_date } = (0, grab_backup_data_1.default)({
backup_name: b, backup_name: b,
}); });
return { return {
@ -32,13 +47,13 @@ export default function () {
}; };
}), }),
}); });
fs.cpSync(path.join(backup_dir, selected_backup), db_file_path); fs_1.default.cpSync(path_1.default.join(backup_dir, selected_backup), db_file_path);
console.log(`${chalk.bold(chalk.green(`DB Restore Success!`))}`); console.log(`${chalk_1.default.bold(chalk_1.default.green(`DB Restore Success!`))}`);
process.exit(); process.exit();
} }
catch (error) { catch (error) {
console.error(`Backup Restore ERROR => ${error.message}`); console.error(`Backup Restore ERROR => ${error.message}`);
process.exit(); process.exit();
} }
}); }));
} }

View File

@ -1,38 +1,52 @@
import { Command } from "commander"; "use strict";
import { SQLiteSchemaManager } from "../lib/sqlite/db-schema-manager"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import init from "../functions/init"; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
import grabDirNames from "../data/grab-dir-names"; return new (P || (P = Promise))(function (resolve, reject) {
import path from "path"; function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
import dbSchemaToTypeDef from "../lib/sqlite/schema-to-typedef"; function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
import _ from "lodash"; function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema"; step((generator = generator.apply(thisArg, _arguments || [])).next());
import chalk from "chalk"; });
export default function () { };
return new Command("schema") var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const commander_1 = require("commander");
const db_schema_manager_1 = require("../lib/sqlite/db-schema-manager");
const init_1 = __importDefault(require("../functions/init"));
const grab_dir_names_1 = __importDefault(require("../data/grab-dir-names"));
const path_1 = __importDefault(require("path"));
const schema_to_typedef_1 = __importDefault(require("../lib/sqlite/schema-to-typedef"));
const append_default_fields_to_db_schema_1 = __importDefault(require("../utils/append-default-fields-to-db-schema"));
const chalk_1 = __importDefault(require("chalk"));
function default_1() {
return new commander_1.Command("schema")
.description("Build DB From Schema") .description("Build DB From Schema")
.option("-v, --vector", "Recreate Vector Tables. This will drop and rebuild all vector tables") .option("-v, --vector", "Recreate Vector Tables. This will drop and rebuild all vector tables")
.option("-t, --typedef", "Generate typescript type definitions") .option("-t, --typedef", "Generate typescript type definitions")
.action(async (opts) => { .action((opts) => __awaiter(this, void 0, void 0, function* () {
console.log(`Starting process ...`); console.log(`Starting process ...`);
const { config, dbSchema } = await init(); const { config, dbSchema } = yield (0, init_1.default)();
const { ROOT_DIR } = grabDirNames(); const { ROOT_DIR } = (0, grab_dir_names_1.default)();
const isVector = Boolean(opts.vector || opts.v); const isVector = Boolean(opts.vector || opts.v);
const isTypeDef = Boolean(opts.typedef || opts.t); const isTypeDef = Boolean(opts.typedef || opts.t);
const finaldbSchema = appendDefaultFieldsToDbSchema({ dbSchema }); const finaldbSchema = (0, append_default_fields_to_db_schema_1.default)({ dbSchema });
const manager = new SQLiteSchemaManager({ const manager = new db_schema_manager_1.SQLiteSchemaManager({
schema: finaldbSchema, schema: finaldbSchema,
recreate_vector_table: isVector, recreate_vector_table: isVector,
}); });
await manager.syncSchema(); yield manager.syncSchema();
manager.close(); manager.close();
if (isTypeDef && config.typedef_file_path) { if (isTypeDef && config.typedef_file_path) {
const out_file = path.resolve(ROOT_DIR, config.typedef_file_path); const out_file = path_1.default.resolve(ROOT_DIR, config.typedef_file_path);
dbSchemaToTypeDef({ (0, schema_to_typedef_1.default)({
dbSchema: finaldbSchema, dbSchema: finaldbSchema,
dst_file: out_file, dst_file: out_file,
}); });
} }
console.log(`${chalk.bold(chalk.green(`DB Schema setup success!`))}`); console.log(`${chalk_1.default.bold(chalk_1.default.green(`DB Schema setup success!`))}`);
process.exit(); process.exit();
}); }));
} }

View File

@ -1,21 +1,36 @@
import { Command } from "commander"; "use strict";
import init from "../functions/init"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import dbSchemaToTypeDef from "../lib/sqlite/schema-to-typedef"; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
import path from "path"; return new (P || (P = Promise))(function (resolve, reject) {
import grabDirNames from "../data/grab-dir-names"; function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema"; function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
import chalk from "chalk"; function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
export default function () { step((generator = generator.apply(thisArg, _arguments || [])).next());
return new Command("typedef") });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const commander_1 = require("commander");
const init_1 = __importDefault(require("../functions/init"));
const schema_to_typedef_1 = __importDefault(require("../lib/sqlite/schema-to-typedef"));
const path_1 = __importDefault(require("path"));
const grab_dir_names_1 = __importDefault(require("../data/grab-dir-names"));
const append_default_fields_to_db_schema_1 = __importDefault(require("../utils/append-default-fields-to-db-schema"));
const chalk_1 = __importDefault(require("chalk"));
function default_1() {
return new commander_1.Command("typedef")
.description("Build DB From Schema") .description("Build DB From Schema")
.action(async (opts) => { .action((opts) => __awaiter(this, void 0, void 0, function* () {
console.log(`Creating Type Definition From DB Schema ...`); console.log(`Creating Type Definition From DB Schema ...`);
const { config, dbSchema } = await init(); const { config, dbSchema } = yield (0, init_1.default)();
const { ROOT_DIR } = grabDirNames(); const { ROOT_DIR } = (0, grab_dir_names_1.default)();
const finaldbSchema = appendDefaultFieldsToDbSchema({ dbSchema }); const finaldbSchema = (0, append_default_fields_to_db_schema_1.default)({ dbSchema });
if (config.typedef_file_path) { if (config.typedef_file_path) {
const out_file = path.resolve(ROOT_DIR, config.typedef_file_path); const out_file = path_1.default.resolve(ROOT_DIR, config.typedef_file_path);
dbSchemaToTypeDef({ (0, schema_to_typedef_1.default)({
dbSchema: finaldbSchema, dbSchema: finaldbSchema,
dst_file: out_file, dst_file: out_file,
}); });
@ -24,7 +39,7 @@ export default function () {
console.error(``); console.error(``);
process.exit(1); process.exit(1);
} }
console.log(`${chalk.bold(chalk.green(`Typedef gen success!`))}`); console.log(`${chalk_1.default.bold(chalk_1.default.green(`Typedef gen success!`))}`);
process.exit(); process.exit();
}); }));
} }

View File

@ -1,4 +1,7 @@
export const AppData = { "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AppData = void 0;
exports.AppData = {
ConfigFileName: "bun-sqlite.config.ts", ConfigFileName: "bun-sqlite.config.ts",
MaxBackups: 10, MaxBackups: 10,
DefaultBackupDirName: ".backups", DefaultBackupDirName: ".backups",

View File

@ -1,5 +1,7 @@
import path from "path"; "use strict";
export default function grabDirNames() { Object.defineProperty(exports, "__esModule", { value: true });
exports.default = grabDirNames;
function grabDirNames() {
const ROOT_DIR = process.cwd(); const ROOT_DIR = process.cwd();
return { return {
ROOT_DIR, ROOT_DIR,

View File

@ -1,2 +1,2 @@
import type { BunSQLiteConfigReturn } from "../types"; import type { BunSQLiteConfigReturn } from "../types";
export default function init(): Promise<BunSQLiteConfigReturn>; export default function init(): BunSQLiteConfigReturn;

View File

@ -1,18 +1,24 @@
import path from "path"; "use strict";
import fs from "fs"; var __importDefault = (this && this.__importDefault) || function (mod) {
import { AppData } from "../data/app-data"; return (mod && mod.__esModule) ? mod : { "default": mod };
import grabDirNames from "../data/grab-dir-names"; };
export default async function init() { Object.defineProperty(exports, "__esModule", { value: true });
exports.default = init;
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const app_data_1 = require("../data/app-data");
const grab_dir_names_1 = __importDefault(require("../data/grab-dir-names"));
function init() {
try { try {
const { ROOT_DIR } = grabDirNames(); const { ROOT_DIR } = (0, grab_dir_names_1.default)();
const { ConfigFileName } = AppData; const { ConfigFileName } = app_data_1.AppData;
const ConfigFilePath = path.join(ROOT_DIR, ConfigFileName); const ConfigFilePath = path_1.default.join(ROOT_DIR, ConfigFileName);
if (!fs.existsSync(ConfigFilePath)) { if (!fs_1.default.existsSync(ConfigFilePath)) {
console.log("ConfigFilePath", ConfigFilePath); console.log("ConfigFilePath", ConfigFilePath);
console.error(`Please create a \`${ConfigFileName}\` file at the root of your project.`); console.error(`Please create a \`${ConfigFileName}\` file at the root of your project.`);
process.exit(1); process.exit(1);
} }
const ConfigImport = await import(ConfigFilePath); const ConfigImport = require(ConfigFilePath);
const Config = ConfigImport["default"]; const Config = ConfigImport["default"];
if (!Config.db_name) { if (!Config.db_name) {
console.error(`\`db_name\` is required in your config`); console.error(`\`db_name\` is required in your config`);
@ -24,18 +30,18 @@ export default async function init() {
} }
let db_dir = ROOT_DIR; let db_dir = ROOT_DIR;
if (Config.db_dir) { if (Config.db_dir) {
db_dir = path.resolve(ROOT_DIR, Config.db_dir); db_dir = path_1.default.resolve(ROOT_DIR, Config.db_dir);
if (!fs.existsSync(Config.db_dir)) { if (!fs_1.default.existsSync(Config.db_dir)) {
fs.mkdirSync(Config.db_dir, { recursive: true }); fs_1.default.mkdirSync(Config.db_dir, { recursive: true });
} }
} }
const DBSchemaFilePath = path.join(db_dir, Config.db_schema_file_name); const DBSchemaFilePath = path_1.default.join(db_dir, Config.db_schema_file_name);
const DbSchemaImport = await import(DBSchemaFilePath); const DbSchemaImport = require(DBSchemaFilePath);
const DbSchema = DbSchemaImport["default"]; const DbSchema = DbSchemaImport["default"];
const backup_dir = Config.db_backup_dir || AppData["DefaultBackupDirName"]; const backup_dir = Config.db_backup_dir || app_data_1.AppData["DefaultBackupDirName"];
const BackupDir = path.resolve(db_dir, backup_dir); const BackupDir = path_1.default.resolve(db_dir, backup_dir);
if (!fs.existsSync(BackupDir)) { if (!fs_1.default.existsSync(BackupDir)) {
fs.mkdirSync(BackupDir, { recursive: true }); fs_1.default.mkdirSync(BackupDir, { recursive: true });
} }
return { config: Config, dbSchema: DbSchema }; return { config: Config, dbSchema: DbSchema };
} }

4
dist/index.d.ts vendored
View File

@ -3,11 +3,11 @@ import DbInsert from "./lib/sqlite/db-insert";
import DbSelect from "./lib/sqlite/db-select"; import DbSelect from "./lib/sqlite/db-select";
import DbSQL from "./lib/sqlite/db-sql"; import DbSQL from "./lib/sqlite/db-sql";
import DbUpdate from "./lib/sqlite/db-update"; import DbUpdate from "./lib/sqlite/db-update";
declare const BunSQLite: { declare const NodeSQLite: {
readonly select: typeof DbSelect; readonly select: typeof DbSelect;
readonly insert: typeof DbInsert; readonly insert: typeof DbInsert;
readonly update: typeof DbUpdate; readonly update: typeof DbUpdate;
readonly delete: typeof DbDelete; readonly delete: typeof DbDelete;
readonly sql: typeof DbSQL; readonly sql: typeof DbSQL;
}; };
export default BunSQLite; export default NodeSQLite;

29
dist/index.js vendored
View File

@ -1,13 +1,18 @@
import DbDelete from "./lib/sqlite/db-delete"; "use strict";
import DbInsert from "./lib/sqlite/db-insert"; var __importDefault = (this && this.__importDefault) || function (mod) {
import DbSelect from "./lib/sqlite/db-select"; return (mod && mod.__esModule) ? mod : { "default": mod };
import DbSQL from "./lib/sqlite/db-sql";
import DbUpdate from "./lib/sqlite/db-update";
const BunSQLite = {
select: DbSelect,
insert: DbInsert,
update: DbUpdate,
delete: DbDelete,
sql: DbSQL,
}; };
export default BunSQLite; Object.defineProperty(exports, "__esModule", { value: true });
const db_delete_1 = __importDefault(require("./lib/sqlite/db-delete"));
const db_insert_1 = __importDefault(require("./lib/sqlite/db-insert"));
const db_select_1 = __importDefault(require("./lib/sqlite/db-select"));
const db_sql_1 = __importDefault(require("./lib/sqlite/db-sql"));
const db_update_1 = __importDefault(require("./lib/sqlite/db-update"));
const NodeSQLite = {
select: db_select_1.default,
insert: db_insert_1.default,
update: db_update_1.default,
delete: db_delete_1.default,
sql: db_sql_1.default,
};
exports.default = NodeSQLite;

View File

@ -1,49 +1,67 @@
import DbClient from "."; "use strict";
import _ from "lodash"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import sqlGenerator from "../../utils/sql-generator"; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
export default async function DbDelete({ table, query, targetId, }) { return new (P || (P = Promise))(function (resolve, reject) {
try { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
let finalQuery = query || {}; function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
if (targetId) { function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
finalQuery = _.merge(finalQuery, { step((generator = generator.apply(thisArg, _arguments || [])).next());
query: { });
id: { };
value: String(targetId), var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = DbDelete;
const _1 = __importDefault(require("."));
const lodash_1 = __importDefault(require("lodash"));
const sql_generator_1 = __importDefault(require("../../utils/sql-generator"));
function DbDelete(_a) {
return __awaiter(this, arguments, void 0, function* ({ table, query, targetId, }) {
var _b;
try {
let finalQuery = query || {};
if (targetId) {
finalQuery = lodash_1.default.merge(finalQuery, {
query: {
id: {
value: String(targetId),
},
}, },
}, });
}
const sqlQueryObj = (0, sql_generator_1.default)({
tableName: table,
genObject: finalQuery,
}); });
const whereClause = (_b = sqlQueryObj.string.match(/WHERE .*/)) === null || _b === void 0 ? void 0 : _b[0];
if (whereClause) {
let sql = `DELETE FROM ${table} ${whereClause}`;
const res = _1.default.prepare(sql).run(...sqlQueryObj.values);
return {
success: Boolean(res.changes),
postInsertReturn: {
affectedRows: res.changes,
insertId: Number(res.lastInsertRowid),
},
debug: {
sql,
values: sqlQueryObj.values,
},
};
}
else {
return {
success: false,
msg: `No WHERE clause`,
};
}
} }
const sqlQueryObj = sqlGenerator({ catch (error) {
tableName: table,
genObject: finalQuery,
});
const whereClause = sqlQueryObj.string.match(/WHERE .*/)?.[0];
if (whereClause) {
let sql = `DELETE FROM ${table} ${whereClause}`;
const res = DbClient.run(sql, sqlQueryObj.values);
return {
success: Boolean(res.changes),
postInsertReturn: {
affectedRows: res.changes,
insertId: Number(res.lastInsertRowid),
},
debug: {
sql,
values: sqlQueryObj.values,
},
};
}
else {
return { return {
success: false, success: false,
msg: `No WHERE clause`, error: error.message,
}; };
} }
} });
catch (error) {
return {
success: false,
error: error.message,
};
}
} }

View File

@ -1,4 +1,7 @@
export default function generateTypeDefinition({ paradigm, table, query, typeDefName, allValuesOptional, addExport, dbName, }) { "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = generateTypeDefinition;
function generateTypeDefinition({ paradigm, table, query, typeDefName, allValuesOptional, addExport, dbName, }) {
let typeDefinition = ``; let typeDefinition = ``;
let tdName = ``; let tdName = ``;
try { try {
@ -9,21 +12,25 @@ export default function generateTypeDefinition({ paradigm, table, query, typeDef
: `BUN_SQLITE_${query.single}_${query.single_table}`.toUpperCase(); : `BUN_SQLITE_${query.single}_${query.single_table}`.toUpperCase();
const fields = table.fields; const fields = table.fields;
function typeMap(schemaType) { function typeMap(schemaType) {
var _a, _b, _c;
if (schemaType.options && schemaType.options.length > 0) { if (schemaType.options && schemaType.options.length > 0) {
return schemaType.options return schemaType.options
.map((opt) => schemaType.dataType?.match(/int/i) || .map((opt) => {
typeof opt == "number" var _a;
? `${opt}` return ((_a = schemaType.dataType) === null || _a === void 0 ? void 0 : _a.match(/int/i)) ||
: `"${opt}"`) typeof opt == "number"
? `${opt}`
: `"${opt}"`;
})
.join(" | "); .join(" | ");
} }
if (schemaType.dataType?.match(/int|double|decimal/i)) { if ((_a = schemaType.dataType) === null || _a === void 0 ? void 0 : _a.match(/int|double|decimal/i)) {
return "number"; return "number";
} }
if (schemaType.dataType?.match(/text|varchar|timestamp/i)) { if ((_b = schemaType.dataType) === null || _b === void 0 ? void 0 : _b.match(/text|varchar|timestamp/i)) {
return "string"; return "string";
} }
if (schemaType.dataType?.match(/boolean/i)) { if ((_c = schemaType.dataType) === null || _c === void 0 ? void 0 : _c.match(/boolean/i)) {
return "0 | 1"; return "0 | 1";
} }
return "string"; return "string";
@ -46,10 +53,10 @@ export default function generateTypeDefinition({ paradigm, table, query, typeDef
}); });
typesArrayTypeScript.push(`}`); typesArrayTypeScript.push(`}`);
typesArrayJavascript.push(` */`); typesArrayJavascript.push(` */`);
if (paradigm?.match(/javascript/i)) { if (paradigm === null || paradigm === void 0 ? void 0 : paradigm.match(/javascript/i)) {
typeDefinition = typesArrayJavascript.join("\n"); typeDefinition = typesArrayJavascript.join("\n");
} }
if (paradigm?.match(/typescript/i)) { if (paradigm === null || paradigm === void 0 ? void 0 : paradigm.match(/typescript/i)) {
typeDefinition = typesArrayTypeScript.join("\n"); typeDefinition = typesArrayTypeScript.join("\n");
} }
} }

View File

@ -1,32 +1,45 @@
import DbClient from "."; "use strict";
import sqlInsertGenerator from "../../utils/sql-insert-generator"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
export default async function DbInsert({ table, data }) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
try { return new (P || (P = Promise))(function (resolve, reject) {
const finalData = data.map((d) => ({ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
...d, function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
created_at: Date.now(), function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
updated_at: Date.now(), step((generator = generator.apply(thisArg, _arguments || [])).next());
})); });
const sqlObj = sqlInsertGenerator({ };
tableName: table, var __importDefault = (this && this.__importDefault) || function (mod) {
data: finalData, return (mod && mod.__esModule) ? mod : { "default": mod };
}); };
const res = DbClient.run(sqlObj?.query || "", sqlObj?.values || []); Object.defineProperty(exports, "__esModule", { value: true });
return { exports.default = DbInsert;
success: Boolean(Number(res.lastInsertRowid)), const _1 = __importDefault(require("."));
postInsertReturn: { const sql_insert_generator_1 = __importDefault(require("../../utils/sql-insert-generator"));
affectedRows: res.changes, function DbInsert(_a) {
insertId: Number(res.lastInsertRowid), return __awaiter(this, arguments, void 0, function* ({ table, data }) {
}, try {
debug: { const finalData = data.map((d) => (Object.assign(Object.assign({}, d), { created_at: Date.now(), updated_at: Date.now() })));
sqlObj, const sqlObj = (0, sql_insert_generator_1.default)({
}, tableName: table,
}; data: finalData,
} });
catch (error) { const res = _1.default.prepare((sqlObj === null || sqlObj === void 0 ? void 0 : sqlObj.query) || "").run(...((sqlObj === null || sqlObj === void 0 ? void 0 : sqlObj.values) || []));
return { return {
success: false, success: Boolean(Number(res.lastInsertRowid)),
error: error.message, postInsertReturn: {
}; affectedRows: res.changes,
} insertId: Number(res.lastInsertRowid),
},
debug: {
sqlObj,
},
};
}
catch (error) {
return {
success: false,
error: error.message,
};
}
});
} }

View File

@ -1,23 +1,33 @@
#!/usr/bin/env bun #!/usr/bin/env bun
import { Database } from "bun:sqlite"; "use strict";
import _ from "lodash"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import DbClient from "."; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SQLiteSchemaManager = void 0;
const lodash_1 = __importDefault(require("lodash"));
const _1 = __importDefault(require("."));
// Schema Manager Class // Schema Manager Class
class SQLiteSchemaManager { class SQLiteSchemaManager {
db;
db_manager_table_name;
recreate_vector_table;
db_schema;
constructor({ schema, recreate_vector_table = false, }) { constructor({ schema, recreate_vector_table = false, }) {
this.db = DbClient; this.db = _1.default;
this.db_manager_table_name = "__db_schema_manager__"; this.db_manager_table_name = "__db_schema_manager__";
this.db.run("PRAGMA foreign_keys = ON;"); this.db.exec("PRAGMA foreign_keys = ON;");
this.recreate_vector_table = recreate_vector_table; this.recreate_vector_table = recreate_vector_table;
this.createDbManagerTable(); this.createDbManagerTable();
this.db_schema = schema; this.db_schema = schema;
} }
createDbManagerTable() { createDbManagerTable() {
this.db.run(` this.db.exec(`
CREATE TABLE IF NOT EXISTS ${this.db_manager_table_name} ( CREATE TABLE IF NOT EXISTS ${this.db_manager_table_name} (
table_name TEXT NOT NULL, table_name TEXT NOT NULL,
created_at INTEGER NOT NULL, created_at INTEGER NOT NULL,
@ -26,214 +36,234 @@ class SQLiteSchemaManager {
`); `);
} }
insertDbManagerTable(tableName) { insertDbManagerTable(tableName) {
this.db.run(`INSERT INTO ${this.db_manager_table_name} (table_name,created_at,updated_at) VALUES (?, ?, ?)`, [tableName, Date.now(), Date.now()]); this.db
.prepare(`INSERT INTO ${this.db_manager_table_name} (table_name,created_at,updated_at) VALUES (?, ?, ?)`)
.run(...[tableName, Date.now(), Date.now()]);
} }
removeDbManagerTable(tableName) { removeDbManagerTable(tableName) {
this.db.run(`DELETE FROM ${this.db_manager_table_name} WHERE table_name = ?`, [tableName]); this.db
.prepare(`DELETE FROM ${this.db_manager_table_name} WHERE table_name = ?`)
.run(...[tableName]);
} }
/** /**
* Main synchronization method * Main synchronization method
*/ */
async syncSchema() { syncSchema() {
console.log("Starting schema synchronization..."); return __awaiter(this, void 0, void 0, function* () {
const existingTables = this.getExistingTables(); console.log("Starting schema synchronization...");
const schemaTables = this.db_schema.tables.map((t) => t.tableName); const existingTables = this.getExistingTables();
// 2. Create or update tables const schemaTables = this.db_schema.tables.map((t) => t.tableName);
for (const table of this.db_schema.tables) { // 2. Create or update tables
await this.syncTable(table, existingTables); for (const table of this.db_schema.tables) {
} yield this.syncTable(table, existingTables);
// 1. Drop tables that no longer exist in schema }
await this.dropRemovedTables(existingTables, schemaTables); // 1. Drop tables that no longer exist in schema
console.log("Schema synchronization complete!"); yield this.dropRemovedTables(existingTables, schemaTables);
console.log("Schema synchronization complete!");
});
} }
/** /**
* Get list of existing tables in the database * Get list of existing tables in the database
*/ */
getExistingTables() { getExistingTables() {
let sql = `SELECT table_name FROM ${this.db_manager_table_name}`; let sql = `SELECT table_name FROM ${this.db_manager_table_name}`;
const query = this.db.query(sql); const query = this.db.prepare(sql);
const results = query.all(); const results = query.all();
return results.map((r) => r.table_name); return results.map((r) => r.table_name);
} }
/** /**
* Drop tables that are no longer in the schema * Drop tables that are no longer in the schema
*/ */
async dropRemovedTables(existingTables, schemaTables) { dropRemovedTables(existingTables, schemaTables) {
const tablesToDrop = existingTables.filter((t) => !schemaTables.includes(t) && return __awaiter(this, void 0, void 0, function* () {
!schemaTables.find((scT) => t.startsWith(scT + "_"))); const tablesToDrop = existingTables.filter((t) => !schemaTables.includes(t) &&
for (const tableName of tablesToDrop) { !schemaTables.find((scT) => t.startsWith(scT + "_")));
console.log(`Dropping table: ${tableName}`); for (const tableName of tablesToDrop) {
this.db.run(`DROP TABLE IF EXISTS "${tableName}"`); console.log(`Dropping table: ${tableName}`);
this.db.run(`DELETE FROM ${this.db_manager_table_name} WHERE table_name = "${tableName}"`); this.db.exec(`DROP TABLE IF EXISTS "${tableName}"`);
} this.db.exec(`DELETE FROM ${this.db_manager_table_name} WHERE table_name = "${tableName}"`);
}
});
} }
/** /**
* Sync a single table (create or update) * Sync a single table (create or update)
*/ */
async syncTable(table, existingTables) { syncTable(table, existingTables) {
let tableExists = existingTables.includes(table.tableName); return __awaiter(this, void 0, void 0, function* () {
// Handle table rename let tableExists = existingTables.includes(table.tableName);
if (table.tableNameOld && table.tableNameOld !== table.tableName) { // Handle table rename
if (existingTables.includes(table.tableNameOld)) { if (table.tableNameOld && table.tableNameOld !== table.tableName) {
console.log(`Renaming table: ${table.tableNameOld} -> ${table.tableName}`); if (existingTables.includes(table.tableNameOld)) {
this.db.run(`ALTER TABLE "${table.tableNameOld}" RENAME TO "${table.tableName}"`); console.log(`Renaming table: ${table.tableNameOld} -> ${table.tableName}`);
this.insertDbManagerTable(table.tableName); this.db.exec(`ALTER TABLE "${table.tableNameOld}" RENAME TO "${table.tableName}"`);
this.removeDbManagerTable(table.tableNameOld); this.insertDbManagerTable(table.tableName);
tableExists = true; this.removeDbManagerTable(table.tableNameOld);
tableExists = true;
}
} }
} if (!tableExists) {
if (!tableExists) { // Create new table
// Create new table yield this.createTable(table);
await this.createTable(table); this.insertDbManagerTable(table.tableName);
this.insertDbManagerTable(table.tableName); }
} else {
else { // Update existing table
// Update existing table yield this.updateTable(table);
await this.updateTable(table); }
} // Sync indexes
// Sync indexes yield this.syncIndexes(table);
await this.syncIndexes(table); });
} }
/** /**
* Create a new table * Create a new table
*/ */
async createTable(table) { createTable(table) {
console.log(`Creating table: ${table.tableName}`); return __awaiter(this, void 0, void 0, function* () {
let new_table = _.cloneDeep(table); console.log(`Creating table: ${table.tableName}`);
if (new_table.parentTableName) { let new_table = lodash_1.default.cloneDeep(table);
const parent_table = this.db_schema.tables.find((t) => t.tableName === new_table.parentTableName); if (new_table.parentTableName) {
if (!parent_table) { const parent_table = this.db_schema.tables.find((t) => t.tableName === new_table.parentTableName);
throw new Error(`Parent table \`${new_table.parentTableName}\` not found for \`${new_table.tableName}\``); if (!parent_table) {
throw new Error(`Parent table \`${new_table.parentTableName}\` not found for \`${new_table.tableName}\``);
}
new_table = lodash_1.default.merge(parent_table, {
tableName: new_table.tableName,
tableDescription: new_table.tableDescription,
});
} }
new_table = _.merge(parent_table, { const columns = [];
tableName: new_table.tableName, const foreignKeys = [];
tableDescription: new_table.tableDescription, for (const field of new_table.fields) {
}); const columnDef = this.buildColumnDefinition(field);
} columns.push(columnDef);
const columns = []; if (field.foreignKey) {
const foreignKeys = []; foreignKeys.push(this.buildForeignKeyConstraint(field));
for (const field of new_table.fields) {
const columnDef = this.buildColumnDefinition(field);
columns.push(columnDef);
if (field.foreignKey) {
foreignKeys.push(this.buildForeignKeyConstraint(field));
}
}
// Add unique constraints
if (new_table.uniqueConstraints) {
for (const constraint of new_table.uniqueConstraints) {
if (constraint.constraintTableFields &&
constraint.constraintTableFields.length > 0) {
const fields = constraint.constraintTableFields
.map((f) => `"${f.value}"`)
.join(", ");
const constraintName = constraint.constraintName ||
`unique_${fields.replace(/"/g, "")}`;
columns.push(`CONSTRAINT "${constraintName}" UNIQUE (${fields})`);
} }
} }
} // Add unique constraints
const allConstraints = [...columns, ...foreignKeys]; if (new_table.uniqueConstraints) {
const sql = new_table.isVector for (const constraint of new_table.uniqueConstraints) {
? `CREATE VIRTUAL TABLE "${new_table.tableName}" USING ${new_table.vectorType || "vec0"}(${allConstraints.join(", ")})` if (constraint.constraintTableFields &&
: `CREATE TABLE "${new_table.tableName}" (${allConstraints.join(", ")})`; constraint.constraintTableFields.length > 0) {
this.db.run(sql); const fields = constraint.constraintTableFields
.map((f) => `"${f.value}"`)
.join(", ");
const constraintName = constraint.constraintName ||
`unique_${fields.replace(/"/g, "")}`;
columns.push(`CONSTRAINT "${constraintName}" UNIQUE (${fields})`);
}
}
}
const allConstraints = [...columns, ...foreignKeys];
const sql = new_table.isVector
? `CREATE VIRTUAL TABLE "${new_table.tableName}" USING ${new_table.vectorType || "vec0"}(${allConstraints.join(", ")})`
: `CREATE TABLE "${new_table.tableName}" (${allConstraints.join(", ")})`;
this.db.exec(sql);
});
} }
/** /**
* Update an existing table * Update an existing table
*/ */
async updateTable(table) { updateTable(table) {
console.log(`Updating table: ${table.tableName}`); return __awaiter(this, void 0, void 0, function* () {
const existingColumns = this.getTableColumns(table.tableName); console.log(`Updating table: ${table.tableName}`);
const schemaColumns = table.fields.map((f) => f.fieldName || ""); const existingColumns = this.getTableColumns(table.tableName);
// SQLite has limited ALTER TABLE support const schemaColumns = table.fields.map((f) => f.fieldName || "");
// We need to use the recreation strategy for complex changes // SQLite has limited ALTER TABLE support
const columnsToAdd = table.fields.filter((f) => f.fieldName && // We need to use the recreation strategy for complex changes
!existingColumns.find((c) => c.name == f.fieldName && c.type == this.mapDataType(f))); const columnsToAdd = table.fields.filter((f) => f.fieldName &&
const columnsToRemove = existingColumns.filter((c) => !schemaColumns.includes(c.name)); !existingColumns.find((c) => c.name == f.fieldName && c.type == this.mapDataType(f)));
const columnsToUpdate = table.fields.filter((f) => f.fieldName && const columnsToRemove = existingColumns.filter((c) => !schemaColumns.includes(c.name));
f.updatedField && const columnsToUpdate = table.fields.filter((f) => f.fieldName &&
existingColumns.find((c) => c.name == f.fieldName && c.type == this.mapDataType(f))); f.updatedField &&
// Simple case: only adding columns existingColumns.find((c) => c.name == f.fieldName && c.type == this.mapDataType(f)));
if (columnsToRemove.length === 0 && columnsToUpdate.length === 0) { // Simple case: only adding columns
for (const field of columnsToAdd) { if (columnsToRemove.length === 0 && columnsToUpdate.length === 0) {
await this.addColumn(table.tableName, field); for (const field of columnsToAdd) {
yield this.addColumn(table.tableName, field);
}
} }
} else {
else { // Complex case: need to recreate table
// Complex case: need to recreate table yield this.recreateTable(table);
await this.recreateTable(table); }
} });
} }
/** /**
* Get existing columns for a table * Get existing columns for a table
*/ */
getTableColumns(tableName) { getTableColumns(tableName) {
const query = this.db.query(`PRAGMA table_info("${tableName}")`); const query = this.db.prepare(`PRAGMA table_info("${tableName}")`);
const results = query.all(); const results = query.all();
return results; return results;
} }
/** /**
* Add a new column to existing table * Add a new column to existing table
*/ */
async addColumn(tableName, field) { addColumn(tableName, field) {
console.log(`Adding column: ${tableName}.${field.fieldName}`); return __awaiter(this, void 0, void 0, function* () {
const columnDef = this.buildColumnDefinition(field); console.log(`Adding column: ${tableName}.${field.fieldName}`);
// Remove PRIMARY KEY and UNIQUE constraints for ALTER TABLE ADD COLUMN const columnDef = this.buildColumnDefinition(field);
const cleanDef = columnDef // Remove PRIMARY KEY and UNIQUE constraints for ALTER TABLE ADD COLUMN
.replace(/PRIMARY KEY/gi, "") const cleanDef = columnDef
.replace(/AUTOINCREMENT/gi, "") .replace(/PRIMARY KEY/gi, "")
.replace(/UNIQUE/gi, "") .replace(/AUTOINCREMENT/gi, "")
.trim(); .replace(/UNIQUE/gi, "")
const sql = `ALTER TABLE "${tableName}" ADD COLUMN ${cleanDef}`; .trim();
this.db.run(sql); const sql = `ALTER TABLE "${tableName}" ADD COLUMN ${cleanDef}`;
this.db.exec(sql);
});
} }
/** /**
* Recreate table (for complex schema changes) * Recreate table (for complex schema changes)
*/ */
async recreateTable(table) { recreateTable(table) {
if (table.isVector) { return __awaiter(this, void 0, void 0, function* () {
if (!this.recreate_vector_table) { if (table.isVector) {
if (!this.recreate_vector_table) {
return;
}
console.log(`Recreating vector table: ${table.tableName}`);
const existingRows = this.db
.prepare(`SELECT * FROM "${table.tableName}"`)
.all();
this.db.exec(`DROP TABLE "${table.tableName}"`);
yield this.createTable(table);
if (existingRows.length > 0) {
for (let i = 0; i < existingRows.length; i++) {
const row = existingRows[i];
if (!row)
continue;
const columns = Object.keys(row);
const placeholders = columns.map(() => "?").join(", ");
this.db
.prepare(`INSERT INTO "${table.tableName}" (${columns.join(", ")}) VALUES (${placeholders})`)
.run(...Object.values(row));
}
}
return; return;
} }
console.log(`Recreating vector table: ${table.tableName}`); const tempTableName = `${table.tableName}_temp_${Date.now()}`;
const existingRows = this.db // Get existing data
.query(`SELECT * FROM "${table.tableName}"`) const existingColumns = this.getTableColumns(table.tableName);
.all(); const columnsToKeep = table.fields
this.db.run(`DROP TABLE "${table.tableName}"`); .filter((f) => f.fieldName &&
await this.createTable(table); existingColumns.find((c) => c.name == f.fieldName &&
if (existingRows.length > 0) { c.type == this.mapDataType(f)))
for (let i = 0; i < existingRows.length; i++) { .map((f) => f.fieldName);
const row = existingRows[i]; // Create temp table with new schema
if (!row) const tempTable = Object.assign(Object.assign({}, table), { tableName: tempTableName });
continue; yield this.createTable(tempTable);
const columns = Object.keys(row); // Copy data if there are common columns
const placeholders = columns.map(() => "?").join(", "); if (columnsToKeep.length > 0) {
this.db.run(`INSERT INTO "${table.tableName}" (${columns.join(", ")}) VALUES (${placeholders})`, Object.values(row)); const columnList = columnsToKeep.map((c) => `"${c}"`).join(", ");
} this.db.exec(`INSERT INTO "${tempTableName}" (${columnList}) SELECT ${columnList} FROM "${table.tableName}"`);
} }
return; // Drop old table
} this.db.exec(`DROP TABLE "${table.tableName}"`);
const tempTableName = `${table.tableName}_temp_${Date.now()}`; // Rename temp table
// Get existing data this.db.exec(`ALTER TABLE "${tempTableName}" RENAME TO "${table.tableName}"`);
const existingColumns = this.getTableColumns(table.tableName); });
const columnsToKeep = table.fields
.filter((f) => f.fieldName &&
existingColumns.find((c) => c.name == f.fieldName &&
c.type == this.mapDataType(f)))
.map((f) => f.fieldName);
// Create temp table with new schema
const tempTable = { ...table, tableName: tempTableName };
await this.createTable(tempTable);
// Copy data if there are common columns
if (columnsToKeep.length > 0) {
const columnList = columnsToKeep.map((c) => `"${c}"`).join(", ");
this.db.run(`INSERT INTO "${tempTableName}" (${columnList}) SELECT ${columnList} FROM "${table.tableName}"`);
}
// Drop old table
this.db.run(`DROP TABLE "${table.tableName}"`);
// Rename temp table
this.db.run(`ALTER TABLE "${tempTableName}" RENAME TO "${table.tableName}"`);
} }
/** /**
* Build column definition SQL * Build column definition SQL
@ -286,7 +316,8 @@ class SQLiteSchemaManager {
* Map DSQL data types to SQLite types * Map DSQL data types to SQLite types
*/ */
mapDataType(field) { mapDataType(field) {
const dataType = field.dataType?.toLowerCase() || "text"; var _a;
const dataType = ((_a = field.dataType) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || "text";
const vectorSize = field.vectorSize || 1536; const vectorSize = field.vectorSize || 1536;
// Vector Embeddings // Vector Embeddings
if (field.isVector) { if (field.isVector) {
@ -339,37 +370,39 @@ class SQLiteSchemaManager {
/** /**
* Sync indexes for a table * Sync indexes for a table
*/ */
async syncIndexes(table) { syncIndexes(table) {
if (!table.indexes || table.indexes.length === 0) { return __awaiter(this, void 0, void 0, function* () {
return; if (!table.indexes || table.indexes.length === 0) {
} return;
// Get existing indexes
const query = this.db.query(`SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='${table.tableName}' AND name NOT LIKE 'sqlite_%'`);
const existingIndexes = query.all().map((r) => r.name);
// Drop indexes not in schema
for (const indexName of existingIndexes) {
const stillExists = table.indexes.some((idx) => idx.indexName === indexName);
if (!stillExists) {
console.log(`Dropping index: ${indexName}`);
this.db.run(`DROP INDEX IF EXISTS "${indexName}"`);
} }
} // Get existing indexes
// Create new indexes const query = this.db.prepare(`SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='${table.tableName}' AND name NOT LIKE 'sqlite_%'`);
for (const index of table.indexes) { const existingIndexes = query.all().map((r) => r.name);
if (!index.indexName || // Drop indexes not in schema
!index.indexTableFields || for (const indexName of existingIndexes) {
index.indexTableFields.length === 0) { const stillExists = table.indexes.some((idx) => idx.indexName === indexName);
continue; if (!stillExists) {
console.log(`Dropping index: ${indexName}`);
this.db.exec(`DROP INDEX IF EXISTS "${indexName}"`);
}
} }
if (!existingIndexes.includes(index.indexName)) { // Create new indexes
console.log(`Creating index: ${index.indexName}`); for (const index of table.indexes) {
const fields = index.indexTableFields if (!index.indexName ||
.map((f) => `"${f.value}"`) !index.indexTableFields ||
.join(", "); index.indexTableFields.length === 0) {
const unique = index.indexType === "regular" ? "" : ""; // SQLite doesn't have FULLTEXT in CREATE INDEX continue;
this.db.run(`CREATE ${unique}INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`); }
if (!existingIndexes.includes(index.indexName)) {
console.log(`Creating index: ${index.indexName}`);
const fields = index.indexTableFields
.map((f) => `"${f.value}"`)
.join(", ");
const unique = index.indexType === "regular" ? "" : ""; // SQLite doesn't have FULLTEXT in CREATE INDEX
this.db.exec(`CREATE ${unique}INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`);
}
} }
} });
} }
/** /**
* Close database connection * Close database connection
@ -378,79 +411,81 @@ class SQLiteSchemaManager {
this.db.close(); this.db.close();
} }
} }
exports.SQLiteSchemaManager = SQLiteSchemaManager;
// Example usage // Example usage
async function main() { function main() {
const schema = { return __awaiter(this, void 0, void 0, function* () {
dbName: "example_db", const schema = {
tables: [ dbName: "example_db",
{ tables: [
tableName: "users", {
tableDescription: "User accounts", tableName: "users",
fields: [ tableDescription: "User accounts",
{ fields: [
fieldName: "id", {
dataType: "INTEGER", fieldName: "id",
primaryKey: true, dataType: "INTEGER",
autoIncrement: true, primaryKey: true,
}, autoIncrement: true,
{
fieldName: "username",
dataType: "TEXT",
notNullValue: true,
unique: true,
},
{
fieldName: "email",
dataType: "TEXT",
notNullValue: true,
},
{
fieldName: "created_at",
dataType: "TEXT",
defaultValueLiteral: "CURRENT_TIMESTAMP",
},
],
indexes: [
{
indexName: "idx_users_email",
indexType: "regular",
indexTableFields: [
{ value: "email", dataType: "TEXT" },
],
},
],
},
{
tableName: "posts",
fields: [
{
fieldName: "id",
dataType: "INTEGER",
primaryKey: true,
autoIncrement: true,
},
{
fieldName: "user_id",
dataType: "INTEGER",
notNullValue: true,
foreignKey: {
destinationTableName: "users",
destinationTableColumnName: "id",
cascadeDelete: true,
}, },
}, {
{ fieldName: "username",
fieldName: "title", dataType: "TEXT",
dataType: "TEXT", notNullValue: true,
notNullValue: true, unique: true,
}, },
{ {
fieldName: "content", fieldName: "email",
dataType: "TEXT", dataType: "TEXT",
}, notNullValue: true,
], },
}, {
], fieldName: "created_at",
}; dataType: "TEXT",
defaultValueLiteral: "CURRENT_TIMESTAMP",
},
],
indexes: [
{
indexName: "idx_users_email",
indexType: "regular",
indexTableFields: [
{ value: "email", dataType: "TEXT" },
],
},
],
},
{
tableName: "posts",
fields: [
{
fieldName: "id",
dataType: "INTEGER",
primaryKey: true,
autoIncrement: true,
},
{
fieldName: "user_id",
dataType: "INTEGER",
notNullValue: true,
foreignKey: {
destinationTableName: "users",
destinationTableColumnName: "id",
cascadeDelete: true,
},
},
{
fieldName: "title",
dataType: "TEXT",
notNullValue: true,
},
{
fieldName: "content",
dataType: "TEXT",
},
],
},
],
};
});
} }
export { SQLiteSchemaManager };

View File

@ -1,43 +1,49 @@
import _ from "lodash"; "use strict";
import generateTypeDefinition from "./db-generate-type-defs"; var __importDefault = (this && this.__importDefault) || function (mod) {
export default function dbSchemaToType(params) { return (mod && mod.__esModule) ? mod : { "default": mod };
let datasquirelSchema = params?.dbSchema; };
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = dbSchemaToType;
const lodash_1 = __importDefault(require("lodash"));
const db_generate_type_defs_1 = __importDefault(require("./db-generate-type-defs"));
function dbSchemaToType(params) {
var _a;
let datasquirelSchema = params === null || params === void 0 ? void 0 : params.dbSchema;
if (!datasquirelSchema) if (!datasquirelSchema)
return; return;
let tableNames = `export const BunSQLiteTables = [\n${datasquirelSchema.tables let tableNames = `export const BunSQLiteTables = [\n${datasquirelSchema.tables
.map((tbl) => ` "${tbl.tableName}",`) .map((tbl) => ` "${tbl.tableName}",`)
.join("\n")}\n] as const`; .join("\n")}\n] as const`;
const dbTablesSchemas = datasquirelSchema.tables; const dbTablesSchemas = datasquirelSchema.tables;
const defDbName = datasquirelSchema.dbName const defDbName = (_a = datasquirelSchema.dbName) === null || _a === void 0 ? void 0 : _a.toUpperCase().replace(/ |\-/g, "_");
?.toUpperCase()
.replace(/ |\-/g, "_");
const defNames = []; const defNames = [];
const schemas = dbTablesSchemas const schemas = dbTablesSchemas
.map((table) => { .map((table) => {
let final_table = _.cloneDeep(table); var _a;
let final_table = lodash_1.default.cloneDeep(table);
if (final_table.parentTableName) { if (final_table.parentTableName) {
const parent_table = dbTablesSchemas.find((t) => t.tableName === final_table.parentTableName); const parent_table = dbTablesSchemas.find((t) => t.tableName === final_table.parentTableName);
if (parent_table) { if (parent_table) {
final_table = _.merge(parent_table, { final_table = lodash_1.default.merge(parent_table, {
tableName: final_table.tableName, tableName: final_table.tableName,
tableDescription: final_table.tableDescription, tableDescription: final_table.tableDescription,
}); });
} }
} }
const defObj = generateTypeDefinition({ const defObj = (0, db_generate_type_defs_1.default)({
paradigm: "TypeScript", paradigm: "TypeScript",
table: final_table, table: final_table,
typeDefName: `BUN_SQLITE_${defDbName}_${final_table.tableName.toUpperCase()}`, typeDefName: `BUN_SQLITE_${defDbName}_${final_table.tableName.toUpperCase()}`,
allValuesOptional: true, allValuesOptional: true,
addExport: true, addExport: true,
}); });
if (defObj.tdName?.match(/./)) { if ((_a = defObj.tdName) === null || _a === void 0 ? void 0 : _a.match(/./)) {
defNames.push(defObj.tdName); defNames.push(defObj.tdName);
} }
return defObj.typeDefinition; return defObj.typeDefinition;
}) })
.filter((schm) => typeof schm == "string"); .filter((schm) => typeof schm == "string");
const allTd = defNames?.[0] const allTd = (defNames === null || defNames === void 0 ? void 0 : defNames[0])
? `export type BUN_SQLITE_${defDbName}_ALL_TYPEDEFS = ${defNames.join(` & `)}` ? `export type BUN_SQLITE_${defDbName}_ALL_TYPEDEFS = ${defNames.join(` & `)}`
: ``; : ``;
return [tableNames, ...schemas, allTd]; return [tableNames, ...schemas, allTd];

View File

@ -1,48 +1,65 @@
import mysql from "mysql"; "use strict";
import DbClient from "."; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import _ from "lodash"; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
import sqlGenerator from "../../utils/sql-generator"; return new (P || (P = Promise))(function (resolve, reject) {
export default async function DbSelect({ table, query, count, targetId, }) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
try { function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
let finalQuery = query || {}; function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
if (targetId) { step((generator = generator.apply(thisArg, _arguments || [])).next());
finalQuery = _.merge(finalQuery, { });
query: { };
id: { var __importDefault = (this && this.__importDefault) || function (mod) {
value: String(targetId), return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = DbSelect;
const mysql_1 = __importDefault(require("mysql"));
const _1 = __importDefault(require("."));
const lodash_1 = __importDefault(require("lodash"));
const sql_generator_1 = __importDefault(require("../../utils/sql-generator"));
function DbSelect(_a) {
return __awaiter(this, arguments, void 0, function* ({ table, query, count, targetId, }) {
var _b;
try {
let finalQuery = query || {};
if (targetId) {
finalQuery = lodash_1.default.merge(finalQuery, {
query: {
id: {
value: String(targetId),
},
}, },
}, });
}
const sqlObj = (0, sql_generator_1.default)({
tableName: table,
genObject: finalQuery,
count,
}); });
const sql = mysql_1.default.format(sqlObj.string, sqlObj.values);
const batchRes = _1.default.prepare(sql).all();
let resp = {
success: Boolean(batchRes[0]),
payload: batchRes,
singleRes: batchRes[0],
debug: {
sqlObj,
sql,
},
};
if (count) {
const count_val = count ? (_b = batchRes[0]) === null || _b === void 0 ? void 0 : _b["COUNT(*)"] : undefined;
resp["count"] = Number(count_val);
delete resp.payload;
delete resp.singleRes;
}
return resp;
} }
const sqlObj = sqlGenerator({ catch (error) {
tableName: table, return {
genObject: finalQuery, success: false,
count, error: error.message,
}); };
const sql = mysql.format(sqlObj.string, sqlObj.values);
const res = DbClient.query(sql);
const batchRes = res.all();
let resp = {
success: Boolean(batchRes[0]),
payload: batchRes,
singleRes: batchRes[0],
debug: {
sqlObj,
sql,
},
};
if (count) {
const count_val = count ? batchRes[0]?.["COUNT(*)"] : undefined;
resp["count"] = Number(count_val);
delete resp.payload;
delete resp.singleRes;
} }
return resp; });
}
catch (error) {
return {
success: false,
error: error.message,
};
}
} }

View File

@ -1,33 +1,49 @@
import DbClient from "."; "use strict";
import _ from "lodash"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
export default async function DbSQL({ sql, values }) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
try { return new (P || (P = Promise))(function (resolve, reject) {
const res = sql.match(/^select/i) function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
? DbClient.query(sql).all(...(values || [])) function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
: DbClient.run(sql, values || []); function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
return { step((generator = generator.apply(thisArg, _arguments || [])).next());
success: true, });
payload: Array.isArray(res) ? res : undefined, };
singleRes: Array.isArray(res) ? res?.[0] : undefined, var __importDefault = (this && this.__importDefault) || function (mod) {
postInsertReturn: Array.isArray(res) return (mod && mod.__esModule) ? mod : { "default": mod };
? undefined };
: { Object.defineProperty(exports, "__esModule", { value: true });
affectedRows: res.changes, exports.default = DbSQL;
insertId: Number(res.lastInsertRowid), const _1 = __importDefault(require("."));
}, function DbSQL(_a) {
debug: { return __awaiter(this, arguments, void 0, function* ({ sql, values }) {
sqlObj: { try {
const res = sql.match(/^select/i)
? _1.default.prepare(sql).all(...(values || []))
: _1.default.prepare(sql).run(...(values || []));
return {
success: true,
payload: Array.isArray(res) ? res : undefined,
singleRes: Array.isArray(res) ? res === null || res === void 0 ? void 0 : res[0] : undefined,
postInsertReturn: Array.isArray(res)
? undefined
: {
affectedRows: res.changes,
insertId: Number(res.lastInsertRowid),
},
debug: {
sqlObj: {
sql,
values,
},
sql, sql,
values,
}, },
sql, };
}, }
}; catch (error) {
} return {
catch (error) { success: false,
return { error: error.message,
success: false, };
error: error.message, }
}; });
}
} }

View File

@ -1,68 +1,83 @@
import DbClient from "."; "use strict";
import _ from "lodash"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
import sqlGenerator from "../../utils/sql-generator"; function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
export default async function DbUpdate({ table, data, query, targetId, }) { return new (P || (P = Promise))(function (resolve, reject) {
try { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
let finalQuery = query || {}; function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
if (targetId) { function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
finalQuery = _.merge(finalQuery, { step((generator = generator.apply(thisArg, _arguments || [])).next());
query: { });
id: { };
value: String(targetId), var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = DbUpdate;
const _1 = __importDefault(require("."));
const lodash_1 = __importDefault(require("lodash"));
const sql_generator_1 = __importDefault(require("../../utils/sql-generator"));
function DbUpdate(_a) {
return __awaiter(this, arguments, void 0, function* ({ table, data, query, targetId, }) {
var _b;
try {
let finalQuery = query || {};
if (targetId) {
finalQuery = lodash_1.default.merge(finalQuery, {
query: {
id: {
value: String(targetId),
},
}, },
}, });
}); }
} const sqlQueryObj = (0, sql_generator_1.default)({
const sqlQueryObj = sqlGenerator({ tableName: table,
tableName: table, genObject: finalQuery,
genObject: finalQuery, });
}); let values = [];
let values = []; const whereClause = (_b = sqlQueryObj.string.match(/WHERE .*/)) === null || _b === void 0 ? void 0 : _b[0];
const whereClause = sqlQueryObj.string.match(/WHERE .*/)?.[0]; if (whereClause) {
if (whereClause) { let sql = `UPDATE ${table} SET`;
let sql = `UPDATE ${table} SET`; const finalData = Object.assign(Object.assign({}, data), { updated_at: Date.now() });
const finalData = { const keys = Object.keys(finalData);
...data, for (let i = 0; i < keys.length; i++) {
updated_at: Date.now(), const key = keys[i];
}; if (!key)
const keys = Object.keys(finalData); continue;
for (let i = 0; i < keys.length; i++) { const isLast = i == keys.length - 1;
const key = keys[i]; sql += ` ${key}=?`;
if (!key) values.push(String(finalData[key]));
continue; if (!isLast) {
const isLast = i == keys.length - 1; sql += `,`;
sql += ` ${key}=?`; }
values.push(String(finalData[key])); }
if (!isLast) { sql += ` ${whereClause}`;
sql += `,`; values = [...values, ...sqlQueryObj.values];
} const res = _1.default.prepare(sql).run(...values);
return {
success: Boolean(res.changes),
postInsertReturn: {
affectedRows: res.changes,
insertId: Number(res.lastInsertRowid),
},
debug: {
sql,
values,
},
};
}
else {
return {
success: false,
msg: `No WHERE clause`,
};
} }
sql += ` ${whereClause}`;
values = [...values, ...sqlQueryObj.values];
const res = DbClient.run(sql, values);
return {
success: Boolean(res.changes),
postInsertReturn: {
affectedRows: res.changes,
insertId: Number(res.lastInsertRowid),
},
debug: {
sql,
values,
},
};
} }
else { catch (error) {
return { return {
success: false, success: false,
msg: `No WHERE clause`, error: error.message,
}; };
} }
} });
catch (error) {
return {
success: false,
error: error.message,
};
}
} }

View File

@ -1,3 +1,3 @@
import { Database } from "bun:sqlite"; import { type Database as DatabaseType } from "better-sqlite3";
declare const DbClient: Database; declare const DbClient: DatabaseType;
export default DbClient; export default DbClient;

View File

@ -1,17 +1,55 @@
import { Database } from "bun:sqlite"; "use strict";
import * as sqliteVec from "sqlite-vec"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
import grabDirNames from "../../data/grab-dir-names"; if (k2 === undefined) k2 = k;
import init from "../../functions/init"; var desc = Object.getOwnPropertyDescriptor(m, k);
import grabDBDir from "../../utils/grab-db-dir"; if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
const { ROOT_DIR } = grabDirNames(); desc = { enumerable: true, get: function() { return m[k]; } };
const { config } = await init(); }
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
const sqliteVec = __importStar(require("sqlite-vec"));
const grab_dir_names_1 = __importDefault(require("../../data/grab-dir-names"));
const init_1 = __importDefault(require("../../functions/init"));
const grab_db_dir_1 = __importDefault(require("../../utils/grab-db-dir"));
const { ROOT_DIR } = (0, grab_dir_names_1.default)();
const { config } = (0, init_1.default)();
let db_dir = ROOT_DIR; let db_dir = ROOT_DIR;
if (config.db_dir) { if (config.db_dir) {
db_dir = config.db_dir; db_dir = config.db_dir;
} }
const { db_file_path } = grabDBDir({ config }); const { db_file_path } = (0, grab_db_dir_1.default)({ config });
const DbClient = new Database(db_file_path, { const DbClient = new better_sqlite3_1.default(db_file_path, {
create: true, fileMustExist: false,
}); });
sqliteVec.load(DbClient); sqliteVec.load(DbClient);
export default DbClient; exports.default = DbClient;

View File

@ -1,16 +1,22 @@
import path from "node:path"; "use strict";
import { existsSync, mkdirSync, writeFileSync } from "node:fs"; var __importDefault = (this && this.__importDefault) || function (mod) {
import dbSchemaToType from "./db-schema-to-typedef"; return (mod && mod.__esModule) ? mod : { "default": mod };
export default function dbSchemaToTypeDef({ dbSchema, dst_file }) { };
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = dbSchemaToTypeDef;
const node_path_1 = __importDefault(require("node:path"));
const node_fs_1 = require("node:fs");
const db_schema_to_typedef_1 = __importDefault(require("./db-schema-to-typedef"));
function dbSchemaToTypeDef({ dbSchema, dst_file }) {
try { try {
if (!dbSchema) if (!dbSchema)
throw new Error("No schema found"); throw new Error("No schema found");
const definitions = dbSchemaToType({ dbSchema }); const definitions = (0, db_schema_to_typedef_1.default)({ dbSchema });
const ourfileDir = path.dirname(dst_file); const ourfileDir = node_path_1.default.dirname(dst_file);
if (!existsSync(ourfileDir)) { if (!(0, node_fs_1.existsSync)(ourfileDir)) {
mkdirSync(ourfileDir, { recursive: true }); (0, node_fs_1.mkdirSync)(ourfileDir, { recursive: true });
} }
writeFileSync(dst_file, definitions?.join("\n\n") || "", "utf-8"); (0, node_fs_1.writeFileSync)(dst_file, (definitions === null || definitions === void 0 ? void 0 : definitions.join("\n\n")) || "", "utf-8");
} }
catch (error) { catch (error) {
console.log(`Schema to Typedef Error =>`, error.message); console.log(`Schema to Typedef Error =>`, error.message);

View File

@ -1,5 +1,7 @@
import _ from "lodash"; "use strict";
export const DbSchema = { Object.defineProperty(exports, "__esModule", { value: true });
exports.DbSchema = void 0;
exports.DbSchema = {
dbName: "travis-ai", dbName: "travis-ai",
tables: [], tables: [],
}; };

29
dist/types/index.js vendored
View File

@ -1,4 +1,7 @@
export const UsersOmitedFields = [ "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultFields = exports.IndexTypes = exports.DockerComposeServices = exports.QueryFields = exports.DsqlCrudActions = exports.DataCrudRequestMethodsLowerCase = exports.DataCrudRequestMethods = exports.ServerQueryEqualities = exports.ServerQueryOperators = exports.BUN_SQLITE_DATATYPES = exports.TextFieldTypesArray = exports.MariaDBCollations = exports.UsersOmitedFields = void 0;
exports.UsersOmitedFields = [
"password", "password",
"social_id", "social_id",
"verification_status", "verification_status",
@ -9,11 +12,11 @@ export const UsersOmitedFields = [
"date_updated_code", "date_updated_code",
"date_updated_timestamp", "date_updated_timestamp",
]; ];
export const MariaDBCollations = [ exports.MariaDBCollations = [
"utf8mb4_bin", "utf8mb4_bin",
"utf8mb4_unicode_520_ci", "utf8mb4_unicode_520_ci",
]; ];
export const TextFieldTypesArray = [ exports.TextFieldTypesArray = [
{ title: "Plain Text", value: "plain" }, { title: "Plain Text", value: "plain" },
{ title: "Rich Text", value: "richText" }, { title: "Rich Text", value: "richText" },
{ title: "Markdown", value: "markdown" }, { title: "Markdown", value: "markdown" },
@ -25,12 +28,12 @@ export const TextFieldTypesArray = [
{ title: "Shell", value: "shell" }, { title: "Shell", value: "shell" },
{ title: "Code", value: "code" }, { title: "Code", value: "code" },
]; ];
export const BUN_SQLITE_DATATYPES = [ exports.BUN_SQLITE_DATATYPES = [
{ value: "TEXT" }, { value: "TEXT" },
{ value: "INTEGER" }, { value: "INTEGER" },
]; ];
export const ServerQueryOperators = ["AND", "OR"]; exports.ServerQueryOperators = ["AND", "OR"];
export const ServerQueryEqualities = [ exports.ServerQueryEqualities = [
"EQUAL", "EQUAL",
"LIKE", "LIKE",
"LIKE_RAW", "LIKE_RAW",
@ -58,7 +61,7 @@ export const ServerQueryEqualities = [
"MATCH", "MATCH",
"MATCH_BOOLEAN", "MATCH_BOOLEAN",
]; ];
export const DataCrudRequestMethods = [ exports.DataCrudRequestMethods = [
"GET", "GET",
"POST", "POST",
"PUT", "PUT",
@ -66,7 +69,7 @@ export const DataCrudRequestMethods = [
"DELETE", "DELETE",
"OPTIONS", "OPTIONS",
]; ];
export const DataCrudRequestMethodsLowerCase = [ exports.DataCrudRequestMethodsLowerCase = [
"get", "get",
"post", "post",
"put", "put",
@ -74,8 +77,8 @@ export const DataCrudRequestMethodsLowerCase = [
"delete", "delete",
"options", "options",
]; ];
export const DsqlCrudActions = ["insert", "update", "delete", "get"]; exports.DsqlCrudActions = ["insert", "update", "delete", "get"];
export const QueryFields = [ exports.QueryFields = [
"duplicate", "duplicate",
"user_id", "user_id",
"delegated_user_id", "delegated_user_id",
@ -83,7 +86,7 @@ export const QueryFields = [
"table_id", "table_id",
"db_slug", "db_slug",
]; ];
export const DockerComposeServices = [ exports.DockerComposeServices = [
"setup", "setup",
"cron", "cron",
"reverse-proxy", "reverse-proxy",
@ -100,8 +103,8 @@ export const DockerComposeServices = [
"db-cron", "db-cron",
"web-app-post-db-setup", "web-app-post-db-setup",
]; ];
export const IndexTypes = ["regular", "full_text", "vector"]; exports.IndexTypes = ["regular", "full_text", "vector"];
export const DefaultFields = [ exports.DefaultFields = [
{ {
fieldName: "id", fieldName: "id",
dataType: "INTEGER", dataType: "INTEGER",

View File

@ -1,11 +1,17 @@
import _ from "lodash"; "use strict";
import { DefaultFields } from "../types"; var __importDefault = (this && this.__importDefault) || function (mod) {
export default function ({ dbSchema }) { return (mod && mod.__esModule) ? mod : { "default": mod };
const finaldbSchema = _.cloneDeep(dbSchema); };
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = default_1;
const lodash_1 = __importDefault(require("lodash"));
const types_1 = require("../types");
function default_1({ dbSchema }) {
const finaldbSchema = lodash_1.default.cloneDeep(dbSchema);
finaldbSchema.tables = finaldbSchema.tables.map((t) => { finaldbSchema.tables = finaldbSchema.tables.map((t) => {
const newTable = _.cloneDeep(t); const newTable = lodash_1.default.cloneDeep(t);
newTable.fields = newTable.fields.filter((f) => !f.fieldName?.match(/^(id|created_at|updated_at)$/)); newTable.fields = newTable.fields.filter((f) => { var _a; return !((_a = f.fieldName) === null || _a === void 0 ? void 0 : _a.match(/^(id|created_at|updated_at)$/)); });
newTable.fields.unshift(...DefaultFields); newTable.fields.unshift(...types_1.DefaultFields);
return newTable; return newTable;
}); });
return finaldbSchema; return finaldbSchema;

View File

@ -1,4 +1,7 @@
export default function grabBackupData({ backup_name }) { "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = grabBackupData;
function grabBackupData({ backup_name }) {
const backup_parts = backup_name.split("-"); const backup_parts = backup_name.split("-");
const backup_date_timestamp = Number(backup_parts.pop()); const backup_date_timestamp = Number(backup_parts.pop());
const origin_backup_name = backup_parts.join("-"); const origin_backup_name = backup_parts.join("-");

View File

@ -1,4 +1,7 @@
export default function grabDBBackupFileName({ config }) { "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = grabDBBackupFileName;
function grabDBBackupFileName({ config }) {
const new_db_file_name = `${config.db_name}-${Date.now()}`; const new_db_file_name = `${config.db_name}-${Date.now()}`;
return new_db_file_name; return new_db_file_name;
} }

View File

@ -1,14 +1,20 @@
import path from "path"; "use strict";
import grabDirNames from "../data/grab-dir-names"; var __importDefault = (this && this.__importDefault) || function (mod) {
import { AppData } from "../data/app-data"; return (mod && mod.__esModule) ? mod : { "default": mod };
export default function grabDBDir({ config }) { };
const { ROOT_DIR } = grabDirNames(); Object.defineProperty(exports, "__esModule", { value: true });
exports.default = grabDBDir;
const path_1 = __importDefault(require("path"));
const grab_dir_names_1 = __importDefault(require("../data/grab-dir-names"));
const app_data_1 = require("../data/app-data");
function grabDBDir({ config }) {
const { ROOT_DIR } = (0, grab_dir_names_1.default)();
let db_dir = ROOT_DIR; let db_dir = ROOT_DIR;
if (config.db_dir) { if (config.db_dir) {
db_dir = config.db_dir; db_dir = config.db_dir;
} }
const backup_dir_name = config.db_backup_dir || AppData["DefaultBackupDirName"]; const backup_dir_name = config.db_backup_dir || app_data_1.AppData["DefaultBackupDirName"];
const backup_dir = path.resolve(db_dir, backup_dir_name); const backup_dir = path_1.default.resolve(db_dir, backup_dir_name);
const db_file_path = path.resolve(db_dir, config.db_name); const db_file_path = path_1.default.resolve(db_dir, config.db_name);
return { db_dir, backup_dir, db_file_path }; return { db_dir, backup_dir, db_file_path };
} }

View File

@ -1,8 +1,14 @@
import grabDBDir from "../utils/grab-db-dir"; "use strict";
import fs from "fs"; var __importDefault = (this && this.__importDefault) || function (mod) {
export default function grabSortedBackups({ config }) { return (mod && mod.__esModule) ? mod : { "default": mod };
const { backup_dir } = grabDBDir({ config }); };
const backups = fs.readdirSync(backup_dir); Object.defineProperty(exports, "__esModule", { value: true });
exports.default = grabSortedBackups;
const grab_db_dir_1 = __importDefault(require("../utils/grab-db-dir"));
const fs_1 = __importDefault(require("fs"));
function grabSortedBackups({ config }) {
const { backup_dir } = (0, grab_db_dir_1.default)({ config });
const backups = fs_1.default.readdirSync(backup_dir);
/** /**
* Order Backups. Most recent first. * Order Backups. Most recent first.
*/ */

View File

@ -1,5 +1,7 @@
import { ServerQueryEqualities } from "../types"; "use strict";
export default function sqlEqualityParser(eq) { Object.defineProperty(exports, "__esModule", { value: true });
exports.default = sqlEqualityParser;
function sqlEqualityParser(eq) {
switch (eq) { switch (eq) {
case "EQUAL": case "EQUAL":
return "="; return "=";

View File

@ -1,9 +1,15 @@
import sqlEqualityParser from "./sql-equality-parser"; "use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = sqlGenOperatorGen;
const sql_equality_parser_1 = __importDefault(require("./sql-equality-parser"));
/** /**
* # SQL Gen Operator Gen * # SQL Gen Operator Gen
* @description Generates an SQL operator for node module `mysql` or `serverless-mysql` * @description Generates an SQL operator for node module `mysql` or `serverless-mysql`
*/ */
export default function sqlGenOperatorGen({ fieldName, value, equality, queryObj, isValueFieldValue, }) { function sqlGenOperatorGen({ fieldName, value, equality, queryObj, isValueFieldValue, }) {
if (queryObj.nullValue) { if (queryObj.nullValue) {
return { str: `${fieldName} IS NULL` }; return { str: `${fieldName} IS NULL` };
} }
@ -93,7 +99,7 @@ export default function sqlGenOperatorGen({ fieldName, value, equality, queryObj
} }
else if (equality) { else if (equality) {
return { return {
str: `${fieldName} ${sqlEqualityParser(equality)} ${finalValue}`, str: `${fieldName} ${(0, sql_equality_parser_1.default)(equality)} ${finalValue}`,
param: finalParams, param: finalParams,
}; };
} }
@ -113,7 +119,7 @@ export default function sqlGenOperatorGen({ fieldName, value, equality, queryObj
} }
else if (equality) { else if (equality) {
return { return {
str: `${fieldName} ${sqlEqualityParser(equality)} ?`, str: `${fieldName} ${(0, sql_equality_parser_1.default)(equality)} ?`,
param: value, param: value,
}; };
} }

View File

@ -1,11 +1,17 @@
import { isUndefined } from "lodash"; "use strict";
import sqlGenOperatorGen from "./sql-gen-operator-gen"; var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = sqlGenerator;
const lodash_1 = require("lodash");
const sql_gen_operator_gen_1 = __importDefault(require("./sql-gen-operator-gen"));
/** /**
* # SQL Query Generator * # SQL Query Generator
* @description Generates an SQL Query for node module `mysql` or `serverless-mysql` * @description Generates an SQL Query for node module `mysql` or `serverless-mysql`
*/ */
export default function sqlGenerator({ tableName, genObject, dbFullName, count }) { function sqlGenerator({ tableName, genObject, dbFullName, count }) {
const finalQuery = genObject?.query ? genObject.query : undefined; const finalQuery = (genObject === null || genObject === void 0 ? void 0 : genObject.query) ? genObject.query : undefined;
const queryKeys = finalQuery ? Object.keys(finalQuery) : undefined; const queryKeys = finalQuery ? Object.keys(finalQuery) : undefined;
const sqlSearhValues = []; const sqlSearhValues = [];
const finalDbName = dbFullName ? `${dbFullName}.` : ""; const finalDbName = dbFullName ? `${dbFullName}.` : "";
@ -14,7 +20,7 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
*/ */
function genSqlSrchStr({ queryObj, join, field, }) { function genSqlSrchStr({ queryObj, join, field, }) {
const finalFieldName = (() => { const finalFieldName = (() => {
if (queryObj?.tableName) { if (queryObj === null || queryObj === void 0 ? void 0 : queryObj.tableName) {
return `${finalDbName}${queryObj.tableName}.${field}`; return `${finalDbName}${queryObj.tableName}.${field}`;
} }
if (join) { if (join) {
@ -24,6 +30,7 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
})(); })();
let str = `${finalFieldName}=?`; let str = `${finalFieldName}=?`;
function grabValue(val) { function grabValue(val) {
var _a;
const valueParsed = val; const valueParsed = val;
if (!valueParsed) if (!valueParsed)
return; return;
@ -32,16 +39,16 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
: valueParsed : valueParsed
? valueParsed.fieldName && valueParsed.tableName ? valueParsed.fieldName && valueParsed.tableName
? `${valueParsed.tableName}.${valueParsed.fieldName}` ? `${valueParsed.tableName}.${valueParsed.fieldName}`
: valueParsed.value?.toString() : (_a = valueParsed.value) === null || _a === void 0 ? void 0 : _a.toString()
: undefined; : undefined;
const valueEquality = typeof valueParsed == "object" const valueEquality = typeof valueParsed == "object"
? valueParsed.equality || queryObj.equality ? valueParsed.equality || queryObj.equality
: queryObj.equality; : queryObj.equality;
const operatorStrParam = sqlGenOperatorGen({ const operatorStrParam = (0, sql_gen_operator_gen_1.default)({
queryObj, queryObj,
equality: valueEquality, equality: valueEquality,
fieldName: finalFieldName || "", fieldName: finalFieldName || "",
value: valueString?.toString() || "", value: (valueString === null || valueString === void 0 ? void 0 : valueString.toString()) || "",
isValueFieldValue: Boolean(typeof valueParsed == "object" && isValueFieldValue: Boolean(typeof valueParsed == "object" &&
valueParsed.fieldName && valueParsed.fieldName &&
valueParsed.tableName), valueParsed.tableName),
@ -66,7 +73,7 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
} }
else if (typeof queryObj.value == "object") { else if (typeof queryObj.value == "object") {
const operatorStrParam = grabValue(queryObj.value); const operatorStrParam = grabValue(queryObj.value);
if (operatorStrParam?.str) { if (operatorStrParam === null || operatorStrParam === void 0 ? void 0 : operatorStrParam.str) {
str = operatorStrParam.str; str = operatorStrParam.str;
if (operatorStrParam.param) { if (operatorStrParam.param) {
sqlSearhValues.push(operatorStrParam.param); sqlSearhValues.push(operatorStrParam.param);
@ -77,7 +84,7 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
const valueParsed = queryObj.value const valueParsed = queryObj.value
? String(queryObj.value) ? String(queryObj.value)
: undefined; : undefined;
const operatorStrParam = sqlGenOperatorGen({ const operatorStrParam = (0, sql_gen_operator_gen_1.default)({
equality: queryObj.equality, equality: queryObj.equality,
fieldName: finalFieldName || "", fieldName: finalFieldName || "",
value: valueParsed, value: valueParsed,
@ -128,49 +135,46 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
: mtch.target}`; : mtch.target}`;
})()}`; })()}`;
} }
let fullTextMatchStr = genObject?.fullTextSearch let fullTextMatchStr = (genObject === null || genObject === void 0 ? void 0 : genObject.fullTextSearch)
? ` MATCH(${genObject.fullTextSearch.fields ? ` MATCH(${genObject.fullTextSearch.fields
.map((f) => genObject.join ? `${tableName}.${String(f)}` : `${String(f)}`) .map((f) => genObject.join ? `${tableName}.${String(f)}` : `${String(f)}`)
.join(",")}) AGAINST (? IN BOOLEAN MODE)` .join(",")}) AGAINST (? IN BOOLEAN MODE)`
: undefined; : undefined;
const fullTextSearchStr = genObject?.fullTextSearch const fullTextSearchStr = (genObject === null || genObject === void 0 ? void 0 : genObject.fullTextSearch)
? genObject.fullTextSearch.searchTerm ? genObject.fullTextSearch.searchTerm
.split(` `) .split(` `)
.map((t) => `${t}`) .map((t) => `${t}`)
.join(" ") .join(" ")
: undefined; : undefined;
let queryString = (() => { let queryString = (() => {
var _a, _b, _c;
let str = "SELECT"; let str = "SELECT";
if (count) { if (count) {
str += ` COUNT(*)`; str += ` COUNT(*)`;
} }
else if (genObject?.selectFields?.[0]) { else if ((_a = genObject === null || genObject === void 0 ? void 0 : genObject.selectFields) === null || _a === void 0 ? void 0 : _a[0]) {
if (genObject.join) { if (genObject.join) {
str += ` ${genObject.selectFields str += ` ${(_b = genObject.selectFields) === null || _b === void 0 ? void 0 : _b.map((fld) => typeof fld == "object"
?.map((fld) => typeof fld == "object"
? `${finalDbName}${tableName}.${fld.fieldName.toString()}` + ? `${finalDbName}${tableName}.${fld.fieldName.toString()}` +
(fld.alias ? ` as ${fld.alias}` : ``) (fld.alias ? ` as ${fld.alias}` : ``)
: `${finalDbName}${tableName}.${String(fld)}`) : `${finalDbName}${tableName}.${String(fld)}`).join(",")}`;
.join(",")}`;
} }
else { else {
str += ` ${genObject.selectFields str += ` ${(_c = genObject.selectFields) === null || _c === void 0 ? void 0 : _c.map((fld) => typeof fld == "object"
?.map((fld) => typeof fld == "object"
? `${fld.fieldName.toString()}` + ? `${fld.fieldName.toString()}` +
(fld.alias ? ` as ${fld.alias}` : ``) (fld.alias ? ` as ${fld.alias}` : ``)
: fld) : fld).join(",")}`;
.join(",")}`;
} }
} }
else { else {
if (genObject?.join) { if (genObject === null || genObject === void 0 ? void 0 : genObject.join) {
str += ` ${finalDbName}${tableName}.*`; str += ` ${finalDbName}${tableName}.*`;
} }
else { else {
str += " *"; str += " *";
} }
} }
if (genObject?.countSubQueries) { if (genObject === null || genObject === void 0 ? void 0 : genObject.countSubQueries) {
let countSqls = []; let countSqls = [];
for (let i = 0; i < genObject.countSubQueries.length; i++) { for (let i = 0; i < genObject.countSubQueries.length; i++) {
const countSubQuery = genObject.countSubQueries[i]; const countSubQuery = genObject.countSubQueries[i];
@ -201,13 +205,13 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
} }
str += `, ${countSqls.join(",")}`; str += `, ${countSqls.join(",")}`;
} }
if (genObject?.join && !count) { if ((genObject === null || genObject === void 0 ? void 0 : genObject.join) && !count) {
const existingJoinTableNames = [tableName]; const existingJoinTableNames = [tableName];
str += str +=
"," + "," +
genObject.join genObject.join
.flat() .flat()
.filter((j) => !isUndefined(j)) .filter((j) => !(0, lodash_1.isUndefined)(j))
.map((joinObj) => { .map((joinObj) => {
const joinTableName = joinObj.alias const joinTableName = joinObj.alias
? joinObj.alias ? joinObj.alias
@ -239,19 +243,19 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
.filter((_) => Boolean(_)) .filter((_) => Boolean(_))
.join(","); .join(",");
} }
if (genObject?.fullTextSearch && if ((genObject === null || genObject === void 0 ? void 0 : genObject.fullTextSearch) &&
fullTextMatchStr && fullTextMatchStr &&
fullTextSearchStr) { fullTextSearchStr) {
str += `, ${fullTextMatchStr} AS ${genObject.fullTextSearch.scoreAlias}`; str += `, ${fullTextMatchStr} AS ${genObject.fullTextSearch.scoreAlias}`;
sqlSearhValues.push(fullTextSearchStr); sqlSearhValues.push(fullTextSearchStr);
} }
str += ` FROM ${finalDbName}${tableName}`; str += ` FROM ${finalDbName}${tableName}`;
if (genObject?.join) { if (genObject === null || genObject === void 0 ? void 0 : genObject.join) {
str += str +=
" " + " " +
genObject.join genObject.join
.flat() .flat()
.filter((j) => !isUndefined(j)) .filter((j) => !(0, lodash_1.isUndefined)(j))
.map((join) => { .map((join) => {
return (join.joinType + return (join.joinType +
" " + " " +
@ -280,20 +284,20 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
} }
return str; return str;
})(); })();
const sqlSearhString = queryKeys?.map((field) => { const sqlSearhString = queryKeys === null || queryKeys === void 0 ? void 0 : queryKeys.map((field) => {
const queryObj = finalQuery?.[field]; const queryObj = finalQuery === null || finalQuery === void 0 ? void 0 : finalQuery[field];
if (!queryObj) if (!queryObj)
return; return;
if (queryObj.__query) { if (queryObj.__query) {
const subQueryGroup = queryObj.__query; const subQueryGroup = queryObj.__query;
const subSearchKeys = Object.keys(subQueryGroup); const subSearchKeys = Object.keys(subQueryGroup);
const subSearchString = subSearchKeys.map((_field) => { const subSearchString = subSearchKeys.map((_field) => {
const newSubQueryObj = subQueryGroup?.[_field]; const newSubQueryObj = subQueryGroup === null || subQueryGroup === void 0 ? void 0 : subQueryGroup[_field];
if (newSubQueryObj) { if (newSubQueryObj) {
return genSqlSrchStr({ return genSqlSrchStr({
queryObj: newSubQueryObj, queryObj: newSubQueryObj,
field: newSubQueryObj.fieldName || _field, field: newSubQueryObj.fieldName || _field,
join: genObject?.join, join: genObject === null || genObject === void 0 ? void 0 : genObject.join,
}); });
} }
}); });
@ -304,20 +308,20 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
return genSqlSrchStr({ return genSqlSrchStr({
queryObj, queryObj,
field: queryObj.fieldName || field, field: queryObj.fieldName || field,
join: genObject?.join, join: genObject === null || genObject === void 0 ? void 0 : genObject.join,
}); });
}); });
const cleanedUpSearchStr = sqlSearhString?.filter((str) => typeof str == "string"); const cleanedUpSearchStr = sqlSearhString === null || sqlSearhString === void 0 ? void 0 : sqlSearhString.filter((str) => typeof str == "string");
const isSearchStr = cleanedUpSearchStr?.[0] && cleanedUpSearchStr.find((str) => str); const isSearchStr = (cleanedUpSearchStr === null || cleanedUpSearchStr === void 0 ? void 0 : cleanedUpSearchStr[0]) && cleanedUpSearchStr.find((str) => str);
if (isSearchStr) { if (isSearchStr) {
const stringOperator = genObject?.searchOperator || "AND"; const stringOperator = (genObject === null || genObject === void 0 ? void 0 : genObject.searchOperator) || "AND";
queryString += ` WHERE ${cleanedUpSearchStr.join(` ${stringOperator} `)}`; queryString += ` WHERE ${cleanedUpSearchStr.join(` ${stringOperator} `)}`;
} }
if (genObject?.fullTextSearch && fullTextSearchStr && fullTextMatchStr) { if ((genObject === null || genObject === void 0 ? void 0 : genObject.fullTextSearch) && fullTextSearchStr && fullTextMatchStr) {
queryString += `${isSearchStr ? " AND" : " WHERE"} ${fullTextMatchStr}`; queryString += `${isSearchStr ? " AND" : " WHERE"} ${fullTextMatchStr}`;
sqlSearhValues.push(fullTextSearchStr); sqlSearhValues.push(fullTextSearchStr);
} }
if (genObject?.group) { if (genObject === null || genObject === void 0 ? void 0 : genObject.group) {
let group_by_txt = ``; let group_by_txt = ``;
if (typeof genObject.group == "string") { if (typeof genObject.group == "string") {
group_by_txt = genObject.group; group_by_txt = genObject.group;
@ -352,10 +356,10 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
function grabOrderString(order) { function grabOrderString(order) {
let orderFields = []; let orderFields = [];
let orderSrt = ``; let orderSrt = ``;
if (genObject?.fullTextSearch && genObject.fullTextSearch.scoreAlias) { if ((genObject === null || genObject === void 0 ? void 0 : genObject.fullTextSearch) && genObject.fullTextSearch.scoreAlias) {
orderFields.push(genObject.fullTextSearch.scoreAlias); orderFields.push(genObject.fullTextSearch.scoreAlias);
} }
else if (genObject?.join) { else if (genObject === null || genObject === void 0 ? void 0 : genObject.join) {
orderFields.push(`${finalDbName}${tableName}.${String(order.field)}`); orderFields.push(`${finalDbName}${tableName}.${String(order.field)}`);
} }
else { else {
@ -364,7 +368,7 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
orderSrt += ` ${orderFields.join(", ")} ${order.strategy}`; orderSrt += ` ${orderFields.join(", ")} ${order.strategy}`;
return orderSrt; return orderSrt;
} }
if (genObject?.order && !count) { if ((genObject === null || genObject === void 0 ? void 0 : genObject.order) && !count) {
let orderSrt = ` ORDER BY`; let orderSrt = ` ORDER BY`;
if (Array.isArray(genObject.order)) { if (Array.isArray(genObject.order)) {
for (let i = 0; i < genObject.order.length; i++) { for (let i = 0; i < genObject.order.length; i++) {
@ -381,9 +385,9 @@ export default function sqlGenerator({ tableName, genObject, dbFullName, count }
} }
queryString += ` ${orderSrt}`; queryString += ` ${orderSrt}`;
} }
if (genObject?.limit && !count) if ((genObject === null || genObject === void 0 ? void 0 : genObject.limit) && !count)
queryString += ` LIMIT ${genObject.limit}`; queryString += ` LIMIT ${genObject.limit}`;
if (genObject?.offset && !count) if ((genObject === null || genObject === void 0 ? void 0 : genObject.offset) && !count)
queryString += ` OFFSET ${genObject.offset}`; queryString += ` OFFSET ${genObject.offset}`;
return { return {
string: queryString, string: queryString,

View File

@ -1,10 +1,13 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = sqlInsertGenerator;
/** /**
* # SQL Insert Generator * # SQL Insert Generator
*/ */
export default function sqlInsertGenerator({ tableName, data, dbFullName, }) { function sqlInsertGenerator({ tableName, data, dbFullName, }) {
const finalDbName = dbFullName ? `${dbFullName}.` : ""; const finalDbName = dbFullName ? `${dbFullName}.` : "";
try { try {
if (Array.isArray(data) && data?.[0]) { if (Array.isArray(data) && (data === null || data === void 0 ? void 0 : data[0])) {
let insertKeys = []; let insertKeys = [];
data.forEach((dt) => { data.forEach((dt) => {
const kys = Object.keys(dt); const kys = Object.keys(dt);

View File

@ -1,19 +1,25 @@
import grabDBDir from "../utils/grab-db-dir"; "use strict";
import fs from "fs"; var __importDefault = (this && this.__importDefault) || function (mod) {
import grabSortedBackups from "./grab-sorted-backups"; return (mod && mod.__esModule) ? mod : { "default": mod };
import { AppData } from "../data/app-data"; };
import path from "path"; Object.defineProperty(exports, "__esModule", { value: true });
export default function trimBackups({ config }) { exports.default = trimBackups;
const { backup_dir } = grabDBDir({ config }); const grab_db_dir_1 = __importDefault(require("../utils/grab-db-dir"));
const backups = grabSortedBackups({ config }); const fs_1 = __importDefault(require("fs"));
const max_backups = config.max_backups || AppData["MaxBackups"]; const grab_sorted_backups_1 = __importDefault(require("./grab-sorted-backups"));
const app_data_1 = require("../data/app-data");
const path_1 = __importDefault(require("path"));
function trimBackups({ config }) {
const { backup_dir } = (0, grab_db_dir_1.default)({ config });
const backups = (0, grab_sorted_backups_1.default)({ config });
const max_backups = config.max_backups || app_data_1.AppData["MaxBackups"];
for (let i = 0; i < backups.length; i++) { for (let i = 0; i < backups.length; i++) {
const backup_name = backups[i]; const backup_name = backups[i];
if (!backup_name) if (!backup_name)
continue; continue;
if (i > max_backups - 1) { if (i > max_backups - 1) {
const backup_file_to_unlink = path.join(backup_dir, backup_name); const backup_file_to_unlink = path_1.default.join(backup_dir, backup_name);
fs.unlinkSync(backup_file_to_unlink); fs_1.default.unlinkSync(backup_file_to_unlink);
} }
} }
} }

View File

@ -1,11 +1,14 @@
#!/bin/bash #!/bin/bash
set -e
if [ -z "$1" ]; then if [ -z "$1" ]; then
msg="Updates" msg="Updates"
else else
msg="$1" msg="$1"
fi fi
tsc --noEmit
rm -rf dist rm -rf dist
tsc tsc
git add . git add .

View File

@ -8,7 +8,7 @@ import type {
BUN_SQLITE_DatabaseSchemaType, BUN_SQLITE_DatabaseSchemaType,
} from "../types"; } from "../types";
export default async function init(): Promise<BunSQLiteConfigReturn> { export default function init(): BunSQLiteConfigReturn {
try { try {
const { ROOT_DIR } = grabDirNames(); const { ROOT_DIR } = grabDirNames();
const { ConfigFileName } = AppData; const { ConfigFileName } = AppData;
@ -24,7 +24,7 @@ export default async function init(): Promise<BunSQLiteConfigReturn> {
process.exit(1); process.exit(1);
} }
const ConfigImport = await import(ConfigFilePath); const ConfigImport = require(ConfigFilePath);
const Config = ConfigImport["default"] as BunSQLiteConfig; const Config = ConfigImport["default"] as BunSQLiteConfig;
if (!Config.db_name) { if (!Config.db_name) {
@ -48,7 +48,7 @@ export default async function init(): Promise<BunSQLiteConfigReturn> {
} }
const DBSchemaFilePath = path.join(db_dir, Config.db_schema_file_name); const DBSchemaFilePath = path.join(db_dir, Config.db_schema_file_name);
const DbSchemaImport = await import(DBSchemaFilePath); const DbSchemaImport = require(DBSchemaFilePath);
const DbSchema = DbSchemaImport[ const DbSchema = DbSchemaImport[
"default" "default"
] as BUN_SQLITE_DatabaseSchemaType; ] as BUN_SQLITE_DatabaseSchemaType;

View File

@ -46,7 +46,7 @@ export default async function DbDelete<
if (whereClause) { if (whereClause) {
let sql = `DELETE FROM ${table} ${whereClause}`; let sql = `DELETE FROM ${table} ${whereClause}`;
const res = DbClient.run(sql, sqlQueryObj.values); const res = DbClient.prepare(sql).run(...sqlQueryObj.values);
return { return {
success: Boolean(res.changes), success: Boolean(res.changes),

View File

@ -26,7 +26,9 @@ export default async function DbInsert<
data: finalData as any[], data: finalData as any[],
}); });
const res = DbClient.run(sqlObj?.query || "", sqlObj?.values || []); const res = DbClient.prepare(sqlObj?.query || "").run(
...(sqlObj?.values || []),
);
return { return {
success: Boolean(Number(res.lastInsertRowid)), success: Boolean(Number(res.lastInsertRowid)),

View File

@ -1,6 +1,6 @@
#!/usr/bin/env bun #!/usr/bin/env bun
import { Database } from "bun:sqlite"; import { type Database } from "better-sqlite3";
import _ from "lodash"; import _ from "lodash";
import DbClient from "."; import DbClient from ".";
import type { import type {
@ -25,14 +25,14 @@ class SQLiteSchemaManager {
}) { }) {
this.db = DbClient; this.db = DbClient;
this.db_manager_table_name = "__db_schema_manager__"; this.db_manager_table_name = "__db_schema_manager__";
this.db.run("PRAGMA foreign_keys = ON;"); this.db.exec("PRAGMA foreign_keys = ON;");
this.recreate_vector_table = recreate_vector_table; this.recreate_vector_table = recreate_vector_table;
this.createDbManagerTable(); this.createDbManagerTable();
this.db_schema = schema; this.db_schema = schema;
} }
private createDbManagerTable() { private createDbManagerTable() {
this.db.run(` this.db.exec(`
CREATE TABLE IF NOT EXISTS ${this.db_manager_table_name} ( CREATE TABLE IF NOT EXISTS ${this.db_manager_table_name} (
table_name TEXT NOT NULL, table_name TEXT NOT NULL,
created_at INTEGER NOT NULL, created_at INTEGER NOT NULL,
@ -42,17 +42,19 @@ class SQLiteSchemaManager {
} }
private insertDbManagerTable(tableName: string) { private insertDbManagerTable(tableName: string) {
this.db.run( this.db
`INSERT INTO ${this.db_manager_table_name} (table_name,created_at,updated_at) VALUES (?, ?, ?)`, .prepare(
[tableName, Date.now(), Date.now()], `INSERT INTO ${this.db_manager_table_name} (table_name,created_at,updated_at) VALUES (?, ?, ?)`,
); )
.run(...[tableName, Date.now(), Date.now()]);
} }
private removeDbManagerTable(tableName: string) { private removeDbManagerTable(tableName: string) {
this.db.run( this.db
`DELETE FROM ${this.db_manager_table_name} WHERE table_name = ?`, .prepare(
[tableName], `DELETE FROM ${this.db_manager_table_name} WHERE table_name = ?`,
); )
.run(...[tableName]);
} }
/** /**
@ -81,7 +83,7 @@ class SQLiteSchemaManager {
private getExistingTables(): string[] { private getExistingTables(): string[] {
let sql = `SELECT table_name FROM ${this.db_manager_table_name}`; let sql = `SELECT table_name FROM ${this.db_manager_table_name}`;
const query = this.db.query(sql); const query = this.db.prepare(sql);
const results = query.all() as { table_name: string }[]; const results = query.all() as { table_name: string }[];
return results.map((r) => r.table_name); return results.map((r) => r.table_name);
@ -102,8 +104,8 @@ class SQLiteSchemaManager {
for (const tableName of tablesToDrop) { for (const tableName of tablesToDrop) {
console.log(`Dropping table: ${tableName}`); console.log(`Dropping table: ${tableName}`);
this.db.run(`DROP TABLE IF EXISTS "${tableName}"`); this.db.exec(`DROP TABLE IF EXISTS "${tableName}"`);
this.db.run( this.db.exec(
`DELETE FROM ${this.db_manager_table_name} WHERE table_name = "${tableName}"`, `DELETE FROM ${this.db_manager_table_name} WHERE table_name = "${tableName}"`,
); );
} }
@ -124,7 +126,7 @@ class SQLiteSchemaManager {
console.log( console.log(
`Renaming table: ${table.tableNameOld} -> ${table.tableName}`, `Renaming table: ${table.tableNameOld} -> ${table.tableName}`,
); );
this.db.run( this.db.exec(
`ALTER TABLE "${table.tableNameOld}" RENAME TO "${table.tableName}"`, `ALTER TABLE "${table.tableNameOld}" RENAME TO "${table.tableName}"`,
); );
this.insertDbManagerTable(table.tableName); this.insertDbManagerTable(table.tableName);
@ -211,7 +213,7 @@ class SQLiteSchemaManager {
? `CREATE VIRTUAL TABLE "${new_table.tableName}" USING ${new_table.vectorType || "vec0"}(${allConstraints.join(", ")})` ? `CREATE VIRTUAL TABLE "${new_table.tableName}" USING ${new_table.vectorType || "vec0"}(${allConstraints.join(", ")})`
: `CREATE TABLE "${new_table.tableName}" (${allConstraints.join(", ")})`; : `CREATE TABLE "${new_table.tableName}" (${allConstraints.join(", ")})`;
this.db.run(sql); this.db.exec(sql);
} }
/** /**
@ -266,7 +268,7 @@ class SQLiteSchemaManager {
private getTableColumns( private getTableColumns(
tableName: string, tableName: string,
): { name: string; type: string }[] { ): { name: string; type: string }[] {
const query = this.db.query(`PRAGMA table_info("${tableName}")`); const query = this.db.prepare(`PRAGMA table_info("${tableName}")`);
const results = query.all() as { name: string; type: string }[]; const results = query.all() as { name: string; type: string }[];
return results; return results;
} }
@ -290,7 +292,7 @@ class SQLiteSchemaManager {
const sql = `ALTER TABLE "${tableName}" ADD COLUMN ${cleanDef}`; const sql = `ALTER TABLE "${tableName}" ADD COLUMN ${cleanDef}`;
this.db.run(sql); this.db.exec(sql);
} }
/** /**
@ -307,10 +309,10 @@ class SQLiteSchemaManager {
console.log(`Recreating vector table: ${table.tableName}`); console.log(`Recreating vector table: ${table.tableName}`);
const existingRows = this.db const existingRows = this.db
.query(`SELECT * FROM "${table.tableName}"`) .prepare(`SELECT * FROM "${table.tableName}"`)
.all() as { [k: string]: any }[]; .all() as { [k: string]: any }[];
this.db.run(`DROP TABLE "${table.tableName}"`); this.db.exec(`DROP TABLE "${table.tableName}"`);
await this.createTable(table); await this.createTable(table);
if (existingRows.length > 0) { if (existingRows.length > 0) {
@ -321,10 +323,11 @@ class SQLiteSchemaManager {
const columns = Object.keys(row); const columns = Object.keys(row);
const placeholders = columns.map(() => "?").join(", "); const placeholders = columns.map(() => "?").join(", ");
this.db.run( this.db
`INSERT INTO "${table.tableName}" (${columns.join(", ")}) VALUES (${placeholders})`, .prepare(
Object.values(row), `INSERT INTO "${table.tableName}" (${columns.join(", ")}) VALUES (${placeholders})`,
); )
.run(...Object.values(row));
} }
} }
@ -354,16 +357,16 @@ class SQLiteSchemaManager {
// Copy data if there are common columns // Copy data if there are common columns
if (columnsToKeep.length > 0) { if (columnsToKeep.length > 0) {
const columnList = columnsToKeep.map((c) => `"${c}"`).join(", "); const columnList = columnsToKeep.map((c) => `"${c}"`).join(", ");
this.db.run( this.db.exec(
`INSERT INTO "${tempTableName}" (${columnList}) SELECT ${columnList} FROM "${table.tableName}"`, `INSERT INTO "${tempTableName}" (${columnList}) SELECT ${columnList} FROM "${table.tableName}"`,
); );
} }
// Drop old table // Drop old table
this.db.run(`DROP TABLE "${table.tableName}"`); this.db.exec(`DROP TABLE "${table.tableName}"`);
// Rename temp table // Rename temp table
this.db.run( this.db.exec(
`ALTER TABLE "${tempTableName}" RENAME TO "${table.tableName}"`, `ALTER TABLE "${tempTableName}" RENAME TO "${table.tableName}"`,
); );
} }
@ -506,7 +509,7 @@ class SQLiteSchemaManager {
} }
// Get existing indexes // Get existing indexes
const query = this.db.query( const query = this.db.prepare(
`SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='${table.tableName}' AND name NOT LIKE 'sqlite_%'`, `SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='${table.tableName}' AND name NOT LIKE 'sqlite_%'`,
); );
const existingIndexes = (query.all() as { name: string }[]).map( const existingIndexes = (query.all() as { name: string }[]).map(
@ -520,7 +523,7 @@ class SQLiteSchemaManager {
); );
if (!stillExists) { if (!stillExists) {
console.log(`Dropping index: ${indexName}`); console.log(`Dropping index: ${indexName}`);
this.db.run(`DROP INDEX IF EXISTS "${indexName}"`); this.db.exec(`DROP INDEX IF EXISTS "${indexName}"`);
} }
} }
@ -540,7 +543,7 @@ class SQLiteSchemaManager {
.map((f) => `"${f.value}"`) .map((f) => `"${f.value}"`)
.join(", "); .join(", ");
const unique = index.indexType === "regular" ? "" : ""; // SQLite doesn't have FULLTEXT in CREATE INDEX const unique = index.indexType === "regular" ? "" : ""; // SQLite doesn't have FULLTEXT in CREATE INDEX
this.db.run( this.db.exec(
`CREATE ${unique}INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`, `CREATE ${unique}INDEX "${index.indexName}" ON "${table.tableName}" (${fields})`,
); );
} }

View File

@ -47,8 +47,7 @@ export default async function DbSelect<
const sql = mysql.format(sqlObj.string, sqlObj.values); const sql = mysql.format(sqlObj.string, sqlObj.values);
const res = DbClient.query<Schema, Schema[]>(sql); const batchRes = DbClient.prepare(sql).all() as Schema[];
const batchRes = res.all();
let resp: APIResponseObject<Schema> = { let resp: APIResponseObject<Schema> = {
success: Boolean(batchRes[0]), success: Boolean(batchRes[0]),

View File

@ -12,8 +12,8 @@ export default async function DbSQL<
>({ sql, values }: Params): Promise<APIResponseObject<T>> { >({ sql, values }: Params): Promise<APIResponseObject<T>> {
try { try {
const res = sql.match(/^select/i) const res = sql.match(/^select/i)
? DbClient.query(sql).all(...(values || [])) ? DbClient.prepare(sql).all(...(values || []))
: DbClient.run(sql, values || []); : DbClient.prepare(sql).run(...(values || []));
return { return {
success: true, success: true,

View File

@ -76,7 +76,7 @@ export default async function DbUpdate<
sql += ` ${whereClause}`; sql += ` ${whereClause}`;
values = [...values, ...sqlQueryObj.values]; values = [...values, ...sqlQueryObj.values];
const res = DbClient.run(sql, values); const res = DbClient.prepare(sql).run(...values);
return { return {
success: Boolean(res.changes), success: Boolean(res.changes),

View File

@ -5,7 +5,7 @@ import init from "../../functions/init";
import grabDBDir from "../../utils/grab-db-dir"; import grabDBDir from "../../utils/grab-db-dir";
const { ROOT_DIR } = grabDirNames(); const { ROOT_DIR } = grabDirNames();
const { config } = await init(); const { config } = init();
let db_dir = ROOT_DIR; let db_dir = ROOT_DIR;

View File

@ -1,13 +1,11 @@
{ {
"compilerOptions": { "compilerOptions": {
"lib": ["ESNext"], "lib": ["ESNext"],
"target": "ESNext", "target": "ES2015",
"module": "Preserve", "module": "commonjs",
"moduleDetection": "force", "moduleDetection": "auto",
"jsx": "react-jsx",
"allowJs": true, "allowJs": true,
"moduleResolution": "bundler", "moduleResolution": "node",
"verbatimModuleSyntax": true,
"strict": true, "strict": true,
"skipLibCheck": true, "skipLibCheck": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
@ -21,6 +19,7 @@
"maxNodeModuleJsDepth": 10, "maxNodeModuleJsDepth": 10,
"forceConsistentCasingInFileNames": true, "forceConsistentCasingInFileNames": true,
"incremental": true, "incremental": true,
"esModuleInterop": true,
"outDir": "dist" "outDir": "dist"
}, },
"include": ["src"], "include": ["src"],