diff --git a/dist/commands/admin/index.d.ts b/dist/commands/admin/index.d.ts deleted file mode 100644 index f202e7d..0000000 --- a/dist/commands/admin/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Command } from "commander"; -export default function (): Command; diff --git a/dist/commands/admin/index.js b/dist/commands/admin/index.js deleted file mode 100644 index c2c7bdf..0000000 --- a/dist/commands/admin/index.js +++ /dev/null @@ -1,41 +0,0 @@ -import { Command } from "commander"; -import init from "../../functions/init"; -import grabDBDir from "../../utils/grab-db-dir"; -import chalk from "chalk"; -import { select } from "@inquirer/prompts"; -import listTables from "./list-tables"; -import runSQL from "./run-sql"; -export default function () { - return new Command("admin") - .description("View Tables and Data, Run SQL Queries, Etc.") - .action(async () => { - const { config } = await init(); - const { db_file_path } = grabDBDir({ config }); - console.log(chalk.bold(chalk.blue("\nBun SQLite Admin\n"))); - try { - while (true) { - const paradigm = await select({ - message: "Choose an action:", - choices: [ - { name: "Tables", value: "list_tables" }, - { name: "SQL", value: "run_sql" }, - { name: chalk.dim("✕ Exit"), value: "exit" }, - ], - }); - if (paradigm === "exit") - break; - if (paradigm === "list_tables") { - const result = await listTables(); - if (result === "__exit__") - break; - } - if (paradigm === "run_sql") - await runSQL(); - } - } - catch (error) { - console.error(error.message); - } - process.exit(); - }); -} diff --git a/dist/commands/admin/list-tables.d.ts b/dist/commands/admin/list-tables.d.ts deleted file mode 100644 index 32a5441..0000000 --- a/dist/commands/admin/list-tables.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -type Params = {}; -export default function listTables(params?: Params): Promise<"__exit__" | void>; -export {}; diff --git a/dist/commands/admin/list-tables.js b/dist/commands/admin/list-tables.js deleted file mode 100644 index 8567d37..0000000 --- a/dist/commands/admin/list-tables.js +++ /dev/null @@ -1,78 +0,0 @@ -import { Database } from "bun:sqlite"; -import chalk from "chalk"; -import { select } from "@inquirer/prompts"; -import { AppData } from "../../data/app-data"; -import showEntries from "./show-entries"; -import showFields from "./show-fields"; -import dbHandler from "../../lib/db-handler"; -export default async function listTables(params) { - const tables = (await dbHandler({ - query: `SELECT table_name FROM ${AppData["DbSchemaManagerTableName"]}`, - })).payload; - if (!tables?.length) { - console.log(chalk.yellow("\nNo tables found.\n")); - return; - } - // Level 1: table selection loop - while (true) { - const tableName = await select({ - message: "Select a table:", - choices: [ - ...tables.map((t) => ({ - name: t.table_name, - value: t.table_name, - })), - { name: chalk.dim("← Go Back"), value: "__back__" }, - { name: chalk.dim("✕ Exit"), value: "__exit__" }, - ], - }); - if (tableName === "__back__") - break; - if (tableName === "__exit__") - return "__exit__"; - // Level 2: action loop — stays here until "Go Back" - while (true) { - const action = await select({ - message: `"${tableName}" — choose an action:`, - choices: [ - { name: "Entries", value: "entries" }, - { name: "Fields", value: "fields" }, - { name: "Schema", value: "schema" }, - { name: chalk.dim("← Go Back"), value: "__back__" }, - { name: chalk.dim("✕ Exit"), value: "__exit__" }, - ], - }); - if (action === "__back__") - break; - if (action === "__exit__") - return "__exit__"; - if (action === "entries") { - const result = await showEntries({ tableName }); - if (result === "__exit__") - return "__exit__"; - } - if (action === "fields") { - const result = await showFields({ tableName }); - if (result === "__exit__") - return "__exit__"; - } - // if (action === "schema") { - // const columns = db - // .query(`PRAGMA table_info("${tableName}")`) - // .all(); - // console.log(`\n${chalk.bold(`Schema for "${tableName}":`)} \n`); - // console.table( - // columns.map((c) => ({ - // "#": c.cid, - // Name: c.name, - // Type: c.type, - // "Not Null": c.notnull ? "YES" : "NO", - // Default: c.dflt_value ?? "(none)", - // "Primary Key": c.pk ? "YES" : "NO", - // })), - // ); - // console.log(); - // } - } - } -} diff --git a/dist/commands/admin/run-sql.d.ts b/dist/commands/admin/run-sql.d.ts deleted file mode 100644 index b6f72fd..0000000 --- a/dist/commands/admin/run-sql.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -type Params = {}; -export default function runSQL(params?: Params): Promise; -export {}; diff --git a/dist/commands/admin/run-sql.js b/dist/commands/admin/run-sql.js deleted file mode 100644 index 9e5e45c..0000000 --- a/dist/commands/admin/run-sql.js +++ /dev/null @@ -1,26 +0,0 @@ -import { Database } from "bun:sqlite"; -import { input } from "@inquirer/prompts"; -import chalk from "chalk"; -import dbHandler from "../../lib/db-handler"; -export default async function runSQL(params) { - const sql = await input({ - message: "Enter SQL query:", - validate: (val) => val.trim().length > 0 || "Query cannot be empty", - }); - try { - const res = await dbHandler({ query: sql }); - if (res.payload) { - console.log(`\n${chalk.bold(`Result (${res.payload.length} row${res.payload.length !== 1 ? "s" : ""}):`)} \n`); - if (res.payload.length) - console.table(res.payload); - else - console.log(chalk.yellow("No res returned.\n")); - } - else if (res.single_res) { - console.log(chalk.green(`\nSuccess! Affected rows: ${res.single_res.changes}, Last insert ID: ${res.single_res.lastInsertRowid}\n`)); - } - } - catch (error) { - console.error(chalk.red(`\nSQL Error: ${error.message}\n`)); - } -} diff --git a/dist/commands/admin/show-entries.d.ts b/dist/commands/admin/show-entries.d.ts deleted file mode 100644 index 64206e5..0000000 --- a/dist/commands/admin/show-entries.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -type Params = { - tableName: string; -}; -export default function showEntries({ tableName }: Params): Promise<"__exit__" | undefined>; -export {}; diff --git a/dist/commands/admin/show-entries.js b/dist/commands/admin/show-entries.js deleted file mode 100644 index 4e1315e..0000000 --- a/dist/commands/admin/show-entries.js +++ /dev/null @@ -1,83 +0,0 @@ -import { Database } from "bun:sqlite"; -import chalk from "chalk"; -import { select, input } from "@inquirer/prompts"; -import dbHandler from "../../lib/db-handler"; -const LIMIT = 50; -export default async function showEntries({ tableName }) { - let page = 0; - let searchField = null; - let searchTerm = null; - while (true) { - const offset = page * LIMIT; - const rows = searchTerm - ? (await dbHandler({ - query: `SELECT * FROM "${tableName}" WHERE "${searchField}" LIKE ? LIMIT ${LIMIT} OFFSET ${offset}`, - values: [`%${searchTerm}%`], - })).payload - : (await dbHandler({ - query: `SELECT * FROM "${tableName}" LIMIT ${LIMIT} OFFSET ${offset}`, - })).payload; - const countRow = searchTerm - ? (await dbHandler({ - query: `SELECT COUNT(*) as count FROM "${tableName}" WHERE "${searchField}" LIKE ?`, - values: [`%${searchTerm}%`], - })).payload - : (await dbHandler({ - query: `SELECT COUNT(*) as count FROM "${tableName}"`, - })).payload; - const total = countRow?.[0]?.count; - const searchInfo = searchTerm - ? chalk.dim(` · searching "${searchField}" = "${searchTerm}"`) - : ""; - if (!rows) { - return; - } - console.log(`\n${chalk.bold(tableName)} — Page ${page + 1}${searchInfo} (${rows.length} of ${total}):\n`); - if (rows.length) { - console.log(rows); - // if (rows.length) console.table(rows); - } - else { - console.log(chalk.yellow("No rows found.")); - console.log(); - } - const choices = []; - if (page > 0) - choices.push({ name: "← Previous Page", value: "prev" }); - if (offset + rows.length < total) - choices.push({ name: "Next Page →", value: "next" }); - choices.push({ name: "Search by Field", value: "search" }); - if (searchTerm) - choices.push({ name: "Clear Search", value: "clear_search" }); - choices.push({ name: chalk.dim("← Go Back"), value: "__back__" }); - choices.push({ name: chalk.dim("✕ Exit"), value: "__exit__" }); - const action = await select({ message: "Navigate:", choices }); - if (action === "__back__") - break; - if (action === "__exit__") - return "__exit__"; - if (action === "next") - page++; - if (action === "prev") - page--; - if (action === "clear_search") { - searchField = null; - searchTerm = null; - page = 0; - } - // if (action === "search") { - // const columns = db - // .query(`PRAGMA table_info("${tableName}")`) - // .all(); - // searchField = await select({ - // message: "Search by field:", - // choices: columns.map((c) => ({ name: c.name, value: c.name })), - // }); - // searchTerm = await input({ - // message: `Search term for "${searchField}":`, - // validate: (v) => v.trim().length > 0 || "Cannot be empty", - // }); - // page = 0; - // } - } -} diff --git a/dist/commands/admin/show-fields.d.ts b/dist/commands/admin/show-fields.d.ts deleted file mode 100644 index 34beb3b..0000000 --- a/dist/commands/admin/show-fields.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -type Params = { - tableName: string; -}; -export default function showFields({ tableName, }: Params): Promise<"__exit__" | void>; -export {}; diff --git a/dist/commands/admin/show-fields.js b/dist/commands/admin/show-fields.js deleted file mode 100644 index 48c5f7b..0000000 --- a/dist/commands/admin/show-fields.js +++ /dev/null @@ -1,69 +0,0 @@ -import { Database } from "bun:sqlite"; -import chalk from "chalk"; -import { select } from "@inquirer/prompts"; -export default async function showFields({ tableName, }) { - // const columns = db - // .query(`PRAGMA table_info("${tableName}")`) - // .all(); - // const indexes = db - // .query(`PRAGMA index_list("${tableName}")`) - // .all(); - // const foreignKeys = db - // .query(`PRAGMA foreign_key_list("${tableName}")`) - // .all(); - // const indexedFields = new Map(); - // for (const idx of indexes) { - // const cols = db - // .query(`PRAGMA index_info("${idx.name}")`) - // .all(); - // for (const col of cols) { - // indexedFields.set(col.name, { unique: idx.unique === 1 }); - // } - // } - // while (true) { - // const fieldName = await select({ - // message: `"${tableName}" — select a field:`, - // choices: [ - // ...columns.map((c) => ({ name: c.name, value: c.name })), - // { name: chalk.dim("← Go Back"), value: "__back__" }, - // { name: chalk.dim("✕ Exit"), value: "__exit__" }, - // ], - // }); - // if (fieldName === "__back__") break; - // if (fieldName === "__exit__") return "__exit__"; - // const col = columns.find((c) => c.name === fieldName)!; - // const idx = indexedFields.get(fieldName); - // const fk = foreignKeys.find((f) => f.from === fieldName); - // console.log(`\n${chalk.bold(`Field: "${fieldName}"`)}\n`); - // console.log(` ${chalk.dim("Table")} ${tableName}`); - // console.log(` ${chalk.dim("Column #")} ${col.cid}`); - // console.log( - // ` ${chalk.dim("Type")} ${col.type || chalk.italic("(none)")}`, - // ); - // console.log( - // ` ${chalk.dim("Primary Key")} ${col.pk ? chalk.green("YES") : "NO"}`, - // ); - // console.log( - // ` ${chalk.dim("Not Null")} ${col.notnull ? chalk.yellow("YES") : "NO"}`, - // ); - // console.log( - // ` ${chalk.dim("Default")} ${col.dflt_value ?? chalk.italic("(none)")}`, - // ); - // console.log( - // ` ${chalk.dim("Indexed")} ${idx ? chalk.cyan("YES") : "NO"}`, - // ); - // console.log( - // ` ${chalk.dim("Unique")} ${idx?.unique ? chalk.cyan("YES") : "NO"}`, - // ); - // if (fk) { - // console.log( - // ` ${chalk.dim("Foreign Key")} ${chalk.magenta(`${fk.table}(${fk.to})`)}`, - // ); - // console.log(` ${chalk.dim("On Update")} ${fk.on_update}`); - // console.log(` ${chalk.dim("On Delete")} ${fk.on_delete}`); - // } else { - // console.log(` ${chalk.dim("Foreign Key")} NO`); - // } - // console.log(); - // } -} diff --git a/dist/commands/backup.d.ts b/dist/commands/backup.d.ts deleted file mode 100644 index f202e7d..0000000 --- a/dist/commands/backup.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Command } from "commander"; -export default function (): Command; diff --git a/dist/commands/backup.js b/dist/commands/backup.js deleted file mode 100644 index 03c7d3c..0000000 --- a/dist/commands/backup.js +++ /dev/null @@ -1,22 +0,0 @@ -import { Command } from "commander"; -import init from "../functions/init"; -import path from "path"; -import grabDBDir from "../utils/grab-db-dir"; -import fs from "fs"; -import grabDBBackupFileName from "../utils/grab-db-backup-file-name"; -import chalk from "chalk"; -import trimBackups from "../utils/trim-backups"; -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(); - }); -} diff --git a/dist/commands/index.d.ts b/dist/commands/index.d.ts deleted file mode 100644 index 4cb206d..0000000 --- a/dist/commands/index.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -#!/usr/bin/env bun -/** - * # Declare Global Variables - */ -declare global { } -export {}; diff --git a/dist/commands/index.js b/dist/commands/index.js deleted file mode 100644 index 7458842..0000000 --- a/dist/commands/index.js +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bun -import { program } from "commander"; -import schema from "./schema"; -import typedef from "./typedef"; -import backup from "./backup"; -import restore from "./restore"; -import admin from "./admin"; -/** - * # Describe Program - */ -program - .name(`bun-mariadb`) - .description(`MariaDB manager for Bun`) - .version(`1.0.0`); -/** - * # Declare Commands - */ -program.addCommand(schema()); -program.addCommand(typedef()); -program.addCommand(backup()); -program.addCommand(restore()); -program.addCommand(admin()); -/** - * # Handle Unavailable Commands - */ -program.on("command:*", () => { - console.error("Invalid command: %s\nSee --help for a list of available commands.", program.args.join(" ")); - process.exit(1); -}); -/** - * # Parse Arguments - */ -program.parse(Bun.argv); diff --git a/dist/commands/restore.d.ts b/dist/commands/restore.d.ts deleted file mode 100644 index f202e7d..0000000 --- a/dist/commands/restore.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Command } from "commander"; -export default function (): Command; diff --git a/dist/commands/restore.js b/dist/commands/restore.js deleted file mode 100644 index 99c4bfd..0000000 --- a/dist/commands/restore.js +++ /dev/null @@ -1,44 +0,0 @@ -import { Command } from "commander"; -import init from "../functions/init"; -import grabDBDir from "../utils/grab-db-dir"; -import fs from "fs"; -import chalk from "chalk"; -import grabSortedBackups from "../utils/grab-sorted-backups"; -import { select } from "@inquirer/prompts"; -import grabBackupData from "../utils/grab-backup-data"; -import path from "path"; -export default function () { - return new Command("restore") - .description("Restore Database") - .action(async (opts) => { - console.log(`Restoring up database ...`); - const { config } = await init(); - const { backup_dir, db_file_path } = grabDBDir({ config }); - const backups = grabSortedBackups({ config }); - if (!backups?.[0]) { - console.error(`No Backups to restore. Use the \`backup\` command to create a backup`); - process.exit(1); - } - try { - const selected_backup = await select({ - message: "Select a backup:", - choices: backups.map((b, i) => { - const { backup_date } = grabBackupData({ - backup_name: b, - }); - return { - name: `Backup #${i + 1}: ${backup_date.toDateString()} ${backup_date.getHours()}:${backup_date.getMinutes()}:${backup_date.getSeconds().toString().padStart(2, "0")}`, - value: b, - }; - }), - }); - fs.cpSync(path.join(backup_dir, selected_backup), db_file_path); - console.log(`${chalk.bold(chalk.green(`DB Restore Success!`))}`); - process.exit(); - } - catch (error) { - console.error(`Backup Restore ERROR => ${error.message}`); - process.exit(); - } - }); -} diff --git a/dist/commands/schema.d.ts b/dist/commands/schema.d.ts deleted file mode 100644 index f202e7d..0000000 --- a/dist/commands/schema.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Command } from "commander"; -export default function (): Command; diff --git a/dist/commands/schema.js b/dist/commands/schema.js deleted file mode 100644 index 4dadc36..0000000 --- a/dist/commands/schema.js +++ /dev/null @@ -1,54 +0,0 @@ -import { Command } from "commander"; -import { MariaDBSchemaManager } from "../lib/mariadb/db-schema-manager"; -import init from "../functions/init"; -import grabDirNames from "../data/grab-dir-names"; -import path from "path"; -import dbSchemaToTypeDef from "../lib/mariadb/schema-to-typedef"; -import _ from "lodash"; -import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema"; -import chalk from "chalk"; -import { writeLiveSchema } from "../functions/live-schema"; -import grabDBDir from "../utils/grab-db-dir"; -import { cpSync } from "fs"; -export default function () { - return new Command("schema") - .description("Build DB From Schema") - .option("-v, --vector", "Recreate Vector Tables. This will drop and rebuild all vector tables") - .option("-t, --typedef", "Generate typescript type definitions") - .action(async (opts) => { - console.log(`Starting process ...`); - const { config, dbSchema } = await init(); - const { ROOT_DIR, BUN_MARIADB_TEMP_DB_FILE_PATH } = grabDirNames(); - const { db_file_path } = grabDBDir({ config }); - cpSync(db_file_path, BUN_MARIADB_TEMP_DB_FILE_PATH); - try { - const isVector = Boolean(opts.vector || opts.v); - const isTypeDef = Boolean(opts.typedef || opts.t); - const finaldbSchema = appendDefaultFieldsToDbSchema({ - dbSchema, - }); - const manager = new MariaDBSchemaManager({ - schema: finaldbSchema, - recreate_vector_table: isVector, - }); - await manager.syncSchema(); - manager.close(); - if (isTypeDef && config.typedef_file_path) { - const out_file = path.resolve(ROOT_DIR, config.typedef_file_path); - dbSchemaToTypeDef({ - dbSchema: finaldbSchema, - dst_file: out_file, - config, - }); - } - writeLiveSchema({ schema: finaldbSchema }); - console.log(`${chalk.bold(chalk.green(`DB Schema setup success!`))}`); - process.exit(); - } - catch (error) { - console.log(error); - cpSync(BUN_MARIADB_TEMP_DB_FILE_PATH, db_file_path); - process.exit(1); - } - }); -} diff --git a/dist/commands/typedef.d.ts b/dist/commands/typedef.d.ts deleted file mode 100644 index f202e7d..0000000 --- a/dist/commands/typedef.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Command } from "commander"; -export default function (): Command; diff --git a/dist/commands/typedef.js b/dist/commands/typedef.js deleted file mode 100644 index 87d97d2..0000000 --- a/dist/commands/typedef.js +++ /dev/null @@ -1,31 +0,0 @@ -import { Command } from "commander"; -import init from "../functions/init"; -import dbSchemaToTypeDef from "../lib/mariadb/schema-to-typedef"; -import path from "path"; -import grabDirNames from "../data/grab-dir-names"; -import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema"; -import chalk from "chalk"; -export default function () { - return new Command("typedef") - .description("Build DB From Schema") - .action(async (opts) => { - console.log(`Creating Type Definition From DB Schema ...`); - const { config, dbSchema } = await init(); - const { ROOT_DIR } = grabDirNames(); - const finaldbSchema = appendDefaultFieldsToDbSchema({ dbSchema }); - if (config.typedef_file_path) { - const out_file = path.resolve(ROOT_DIR, config.typedef_file_path); - dbSchemaToTypeDef({ - dbSchema: finaldbSchema, - dst_file: out_file, - config, - }); - } - else { - console.error(``); - process.exit(1); - } - console.log(`${chalk.bold(chalk.green(`Typedef gen success!`))}`); - process.exit(); - }); -} diff --git a/dist/data/app-data.d.ts b/dist/data/app-data.d.ts deleted file mode 100644 index f3eb051..0000000 --- a/dist/data/app-data.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -export declare const AppData: { - readonly ConfigFileName: "bun-sqlite.config.ts"; - readonly MaxBackups: 10; - readonly DefaultBackupDirName: ".backups"; - readonly DbSchemaManagerTableName: "__db_schema_manager__"; -}; diff --git a/dist/data/app-data.js b/dist/data/app-data.js deleted file mode 100644 index 439bcb7..0000000 --- a/dist/data/app-data.js +++ /dev/null @@ -1,6 +0,0 @@ -export const AppData = { - ConfigFileName: "bun-sqlite.config.ts", - MaxBackups: 10, - DefaultBackupDirName: ".backups", - DbSchemaManagerTableName: "__db_schema_manager__", -}; diff --git a/dist/data/grab-dir-names.d.ts b/dist/data/grab-dir-names.d.ts deleted file mode 100644 index 33d56a5..0000000 --- a/dist/data/grab-dir-names.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { BunSQLiteConfig } from "../types"; -type Params = { - config?: BunSQLiteConfig; -}; -export default function grabDirNames(params?: Params): { - ROOT_DIR: string; - BUN_MARIADB_DIR: string; - BUN_MARIADB_TEMP_DIR: string; - BUN_MARIADB_LIVE_SCHEMA: string; - BUN_MARIADB_TEMP_DB_FILE_PATH: string; -}; -export {}; diff --git a/dist/data/grab-dir-names.js b/dist/data/grab-dir-names.js deleted file mode 100644 index e2b5e6b..0000000 --- a/dist/data/grab-dir-names.js +++ /dev/null @@ -1,15 +0,0 @@ -import path from "path"; -export default function grabDirNames(params) { - const ROOT_DIR = process.cwd(); - const BUN_MARIADB_DIR = path.join(ROOT_DIR, ".bun-sqlite"); - const BUN_MARIADB_TEMP_DIR = path.join(BUN_MARIADB_DIR, ".tmp"); - const BUN_MARIADB_TEMP_DB_FILE_PATH = path.join(BUN_MARIADB_TEMP_DIR, "temp.db"); - const BUN_MARIADB_LIVE_SCHEMA = path.join(BUN_MARIADB_DIR, "live-schema.json"); - return { - ROOT_DIR, - BUN_MARIADB_DIR, - BUN_MARIADB_TEMP_DIR, - BUN_MARIADB_LIVE_SCHEMA, - BUN_MARIADB_TEMP_DB_FILE_PATH, - }; -} diff --git a/dist/functions/init.d.ts b/dist/functions/init.d.ts deleted file mode 100644 index c7c6d0b..0000000 --- a/dist/functions/init.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { BunSQLiteConfigReturn } from "../types"; -export default function init(): Promise; diff --git a/dist/functions/init.js b/dist/functions/init.js deleted file mode 100644 index 4635e0b..0000000 --- a/dist/functions/init.js +++ /dev/null @@ -1,46 +0,0 @@ -import path from "path"; -import fs from "fs"; -import { AppData } from "../data/app-data"; -import grabDirNames from "../data/grab-dir-names"; -export default async function init() { - try { - const { ROOT_DIR } = grabDirNames(); - const { ConfigFileName } = AppData; - const ConfigFilePath = path.join(ROOT_DIR, ConfigFileName); - if (!fs.existsSync(ConfigFilePath)) { - console.log("ConfigFilePath", ConfigFilePath); - console.error(`Please create a \`${ConfigFileName}\` file at the root of your project.`); - process.exit(1); - } - const ConfigImport = await import(ConfigFilePath); - const Config = ConfigImport["default"]; - if (!Config.db_name) { - console.error(`\`db_name\` is required in your config`); - process.exit(1); - } - if (!Config.db_schema_file_name) { - console.error(`\`db_schema_file_name\` is required in your config`); - process.exit(1); - } - let db_dir = ROOT_DIR; - if (Config.db_dir) { - db_dir = path.resolve(ROOT_DIR, Config.db_dir); - if (!fs.existsSync(Config.db_dir)) { - fs.mkdirSync(Config.db_dir, { recursive: true }); - } - } - const DBSchemaFilePath = path.join(db_dir, Config.db_schema_file_name); - const DbSchemaImport = await import(DBSchemaFilePath); - const DbSchema = DbSchemaImport["default"]; - const backup_dir = Config.db_backup_dir || AppData["DefaultBackupDirName"]; - const BackupDir = path.resolve(db_dir, backup_dir); - if (!fs.existsSync(BackupDir)) { - fs.mkdirSync(BackupDir, { recursive: true }); - } - return { config: Config, dbSchema: DbSchema }; - } - catch (error) { - console.error(`Initialization ERROR => ` + error.message); - process.exit(1); - } -} diff --git a/dist/functions/live-schema.d.ts b/dist/functions/live-schema.d.ts deleted file mode 100644 index 5e9fcc9..0000000 --- a/dist/functions/live-schema.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { BUN_MARIADB_DatabaseSchemaType } from "../types"; -type Params = { - schema: BUN_MARIADB_DatabaseSchemaType; -}; -export declare function writeLiveSchema({ schema }: Params): void; -export declare function readLiveSchema(): BUN_MARIADB_DatabaseSchemaType | undefined; -export {}; diff --git a/dist/functions/live-schema.js b/dist/functions/live-schema.js deleted file mode 100644 index 13c282b..0000000 --- a/dist/functions/live-schema.js +++ /dev/null @@ -1,15 +0,0 @@ -import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"; -import grabDirNames from "../data/grab-dir-names"; -import path from "path"; -const { BUN_MARIADB_LIVE_SCHEMA } = grabDirNames(); -export function writeLiveSchema({ schema }) { - mkdirSync(path.dirname(BUN_MARIADB_LIVE_SCHEMA), { recursive: true }); - writeFileSync(BUN_MARIADB_LIVE_SCHEMA, JSON.stringify(schema)); -} -export function readLiveSchema() { - if (!existsSync(BUN_MARIADB_LIVE_SCHEMA)) { - return undefined; - } - const live_schema = readFileSync(BUN_MARIADB_LIVE_SCHEMA, "utf-8"); - return JSON.parse(live_schema); -} diff --git a/dist/index.d.ts b/dist/index.d.ts deleted file mode 100644 index c6f746e..0000000 --- a/dist/index.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import DbDelete from "./lib/mariadb/db-delete"; -import DbInsert from "./lib/mariadb/db-insert"; -import DbSelect from "./lib/mariadb/db-select"; -import DbSQL from "./lib/mariadb/db-sql"; -import DbUpdate from "./lib/mariadb/db-update"; -import grabDbSchema from "./utils/grab-db-schema"; -import grabJoinFieldsFromQueryObject from "./utils/grab-join-fields-from-query-object"; -declare const BunMariaDB: { - readonly select: typeof DbSelect; - readonly insert: typeof DbInsert; - readonly update: typeof DbUpdate; - readonly delete: typeof DbDelete; - readonly sql: typeof DbSQL; - readonly utils: { - readonly grab_db_schema: typeof grabDbSchema; - readonly grab_join_fields_from_query_object: typeof grabJoinFieldsFromQueryObject; - }; -}; -export default BunMariaDB; diff --git a/dist/index.js b/dist/index.js deleted file mode 100644 index d2d757f..0000000 --- a/dist/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import DbDelete from "./lib/mariadb/db-delete"; -import DbInsert from "./lib/mariadb/db-insert"; -import DbSelect from "./lib/mariadb/db-select"; -import DbSQL from "./lib/mariadb/db-sql"; -import DbUpdate from "./lib/mariadb/db-update"; -import grabDbSchema from "./utils/grab-db-schema"; -import grabJoinFieldsFromQueryObject from "./utils/grab-join-fields-from-query-object"; -const BunMariaDB = { - select: DbSelect, - insert: DbInsert, - update: DbUpdate, - delete: DbDelete, - sql: DbSQL, - utils: { - grab_db_schema: grabDbSchema, - grab_join_fields_from_query_object: grabJoinFieldsFromQueryObject, - }, -}; -export default BunMariaDB; diff --git a/dist/lib/db-handler.d.ts b/dist/lib/db-handler.d.ts deleted file mode 100644 index c4e02c1..0000000 --- a/dist/lib/db-handler.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { ConnectionConfig } from "mariadb"; -import type { BUN_MARIADB_TableSchemaType, DBResponseObject } from "../types"; -type Param = { - query: string; - values?: string[] | object; - noErrorLogs?: boolean; - database?: string; - tableSchema?: BUN_MARIADB_TableSchemaType; - config?: ConnectionConfig; -}; -/** - * # Main DB Handler Function - * @requires DSQL_DB_CONN - Gobal Variable for Datasquirel Database - */ -export default function dbHandler({ query, values, noErrorLogs, database, config, }: Param): Promise; -export {}; diff --git a/dist/lib/db-handler.js b/dist/lib/db-handler.js deleted file mode 100644 index d881eed..0000000 --- a/dist/lib/db-handler.js +++ /dev/null @@ -1,46 +0,0 @@ -import grabDBConnection from "./grab-db-connection"; -/** - * # Main DB Handler Function - * @requires DSQL_DB_CONN - Gobal Variable for Datasquirel Database - */ -export default async function dbHandler({ query, values, noErrorLogs, database, config, }) { - let CONNECTION; - let results = null; - try { - CONNECTION = await grabDBConnection({ database, config }); - if (query && values) { - const queryResults = await CONNECTION.query(query, values); - results = queryResults[0]; - } - else { - const queryResults = await CONNECTION.query(query); - results = queryResults[0]; - } - } - catch (error) { - if (error.message && - typeof error.message == "string" && - error.message.match(/Access denied for user.*password/i)) { - throw new Error("Authentication Failed!"); - } - if (!noErrorLogs) { - console.log(error); - } - results = null; - } - finally { - await CONNECTION?.end(); - } - if (results) { - return { - success: true, - payload: Array.isArray(results) ? results : undefined, - single_res: Array.isArray(results) ? undefined : results, - }; - } - else { - return { - success: false, - }; - } -} diff --git a/dist/lib/grab-db-connection.d.ts b/dist/lib/grab-db-connection.d.ts deleted file mode 100644 index c9cc96d..0000000 --- a/dist/lib/grab-db-connection.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { Connection } from "mariadb"; -import type { DsqlConnectionParam } from "../types"; -/** - * # Grab General CONNECTION for DSQL - */ -export default function grabDBConnection(param?: DsqlConnectionParam): Promise; diff --git a/dist/lib/grab-db-connection.js b/dist/lib/grab-db-connection.js deleted file mode 100644 index 93e7cca..0000000 --- a/dist/lib/grab-db-connection.js +++ /dev/null @@ -1,15 +0,0 @@ -import * as mariadb from "mariadb"; -import grabDSQLConnectionConfig from "./grab-dsql-connection-config"; -/** - * # Grab General CONNECTION for DSQL - */ -export default async function grabDBConnection(param) { - const config = grabDSQLConnectionConfig(param); - try { - return await mariadb.createConnection(config); - } - catch (error) { - console.log(`Error Grabbing DSQL Connection =>`, config); - throw error; - } -} diff --git a/dist/lib/grab-db-ssl.d.ts b/dist/lib/grab-db-ssl.d.ts deleted file mode 100644 index d507388..0000000 --- a/dist/lib/grab-db-ssl.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { ConnectionConfig } from "mariadb"; -type Return = ConnectionConfig["ssl"] | undefined; -/** - * # Grab SSL - */ -export default function grabDbSSL(): Return; -export {}; diff --git a/dist/lib/grab-db-ssl.js b/dist/lib/grab-db-ssl.js deleted file mode 100644 index 6fae64d..0000000 --- a/dist/lib/grab-db-ssl.js +++ /dev/null @@ -1,20 +0,0 @@ -import fs from "fs"; -import path from "path"; -/** - * # Grab SSL - */ -export default function grabDbSSL() { - const caProivdedPath = process.env.DSQL_SSL_CA_CERT; - if (!caProivdedPath?.match(/./)) { - return undefined; - } - const caFilePath = path.resolve(process.cwd(), caProivdedPath); - if (!fs.existsSync(caFilePath)) { - console.log(`${caFilePath} does not exist`); - return undefined; - } - return { - ca: fs.readFileSync(caFilePath), - rejectUnauthorized: false, - }; -} diff --git a/dist/lib/grab-dsql-connection-config.d.ts b/dist/lib/grab-dsql-connection-config.d.ts deleted file mode 100644 index 2a1f175..0000000 --- a/dist/lib/grab-dsql-connection-config.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type ConnectionConfig } from "mariadb"; -import type { DsqlConnectionParam } from "../types"; -/** - * # Grab General CONNECTION for DSQL - */ -export default function grabDSQLConnectionConfig(param?: DsqlConnectionParam): ConnectionConfig; diff --git a/dist/lib/grab-dsql-connection-config.js b/dist/lib/grab-dsql-connection-config.js deleted file mode 100644 index 52fe0db..0000000 --- a/dist/lib/grab-dsql-connection-config.js +++ /dev/null @@ -1,29 +0,0 @@ -import {} from "mariadb"; -import grabDbSSL from "./grab-db-ssl"; -/** - * # Grab General CONNECTION for DSQL - */ -export default function grabDSQLConnectionConfig(param) { - const CONN_TIMEOUT = 10000; - const config = { - host: process.env.DSQL_DB_HOST, - user: process.env.DSQL_DB_USERNAME, - password: process.env.DSQL_DB_PASSWORD, - // database: param?.dbFullName, - port: process.env.DSQL_DB_PORT - ? Number(process.env.DSQL_DB_PORT) - : undefined, - charset: "utf8mb4", - ssl: grabDbSSL(), - bigIntAsNumber: true, - supportBigNumbers: true, - bigNumberStrings: false, - dateStrings: true, - metaAsArray: true, - socketTimeout: CONN_TIMEOUT, - connectTimeout: CONN_TIMEOUT, - compress: true, - ...param?.config, - }; - return config; -} diff --git a/dist/lib/grab-duplicate-safe-insert-sql.d.ts b/dist/lib/grab-duplicate-safe-insert-sql.d.ts deleted file mode 100644 index 8e6211e..0000000 --- a/dist/lib/grab-duplicate-safe-insert-sql.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -type Params = { - sql: string; - table: string; - data: any | any[]; -}; -export default function ({ sql: passed_sql, table, data }: Params): Promise; -export {}; diff --git a/dist/lib/grab-duplicate-safe-insert-sql.js b/dist/lib/grab-duplicate-safe-insert-sql.js deleted file mode 100644 index c13fd87..0000000 --- a/dist/lib/grab-duplicate-safe-insert-sql.js +++ /dev/null @@ -1,24 +0,0 @@ -import init from "../functions/init"; -export default async function ({ sql: passed_sql, table, data }) { - let sql = passed_sql; - const { dbSchema } = await init(); - const table_schema = dbSchema.tables.find((t) => t.tableName == table); - const now = Date.now(); - if (table_schema?.tableName) { - const set_sql_arr = Object.keys(Array.isArray(data) ? data[0] : data).map((field) => `${field} = excluded.${field}`); - set_sql_arr.push(`updated_at = ${now}`); - const set_sql = set_sql_arr.join(", "); - const unique_fields = table_schema.fields.filter((f) => f.unique); - for (let i = 0; i < unique_fields.length; i++) { - const field = unique_fields[i]; - sql += ` ON CONFLICT(${field?.fieldName}) DO UPDATE SET ${set_sql}`; - } - if (table_schema.uniqueConstraints?.[0]) { - for (let i = 0; i < table_schema.uniqueConstraints.length; i++) { - const constraint = table_schema.uniqueConstraints[i]; - sql += ` ON CONFLICT(${constraint?.constraintTableFields?.map((c) => c.value)?.join(", ")}) DO UPDATE SET ${set_sql}`; - } - } - } - return sql; -} diff --git a/dist/lib/mariadb/db-delete.d.ts b/dist/lib/mariadb/db-delete.d.ts deleted file mode 100644 index c1c63ba..0000000 --- a/dist/lib/mariadb/db-delete.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { APIResponseObject, ServerQueryParam } from "../../types"; -type Params = { - table: Table; - query?: ServerQueryParam; - targetId?: number | string; -}; -export default function DbDelete({ table, query, targetId, }: Params): Promise; -export {}; diff --git a/dist/lib/mariadb/db-delete.js b/dist/lib/mariadb/db-delete.js deleted file mode 100644 index a23a327..0000000 --- a/dist/lib/mariadb/db-delete.js +++ /dev/null @@ -1,56 +0,0 @@ -import DbClient from "."; -import _ from "lodash"; -import sqlGenerator from "../../utils/sql-generator"; -export default async function DbDelete({ table, query, targetId, }) { - let sqlObj = null; - try { - let finalQuery = query || {}; - if (targetId) { - finalQuery = _.merge(finalQuery, { - query: { - id: { - value: String(targetId), - }, - }, - }); - } - sqlObj = sqlGenerator({ - tableName: table, - genObject: finalQuery, - }); - const whereClause = sqlObj.string.match(/WHERE .*/)?.[0]; - if (whereClause) { - let sql = `DELETE FROM ${table} ${whereClause}`; - sqlObj.string = sql; - const res = DbClient.run(sql, sqlObj.values); - return { - success: Boolean(res.changes), - postInsertReturn: { - affectedRows: res.changes, - insertId: Number(res.lastInsertRowid), - }, - debug: { - sqlObj, - }, - }; - } - else { - return { - success: false, - msg: `No WHERE clause`, - debug: { - sqlObj, - }, - }; - } - } - catch (error) { - return { - success: false, - error: error.message, - debug: { - sqlObj, - }, - }; - } -} diff --git a/dist/lib/mariadb/db-generate-type-defs.d.ts b/dist/lib/mariadb/db-generate-type-defs.d.ts deleted file mode 100644 index 81892ca..0000000 --- a/dist/lib/mariadb/db-generate-type-defs.d.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { BUN_MARIADB_TableSchemaType } from "../../types"; -type Param = { - paradigm: "JavaScript" | "TypeScript" | undefined; - table: BUN_MARIADB_TableSchemaType; - query?: any; - typeDefName?: string; - allValuesOptional?: boolean; - addExport?: boolean; - dbName?: string; -}; -export default function generateTypeDefinition({ paradigm, table, query, typeDefName, allValuesOptional, addExport, dbName, }: Param): { - typeDefinition: string | null; - tdName: string; -}; -export {}; diff --git a/dist/lib/mariadb/db-generate-type-defs.js b/dist/lib/mariadb/db-generate-type-defs.js deleted file mode 100644 index decabea..0000000 --- a/dist/lib/mariadb/db-generate-type-defs.js +++ /dev/null @@ -1,63 +0,0 @@ -export default function generateTypeDefinition({ paradigm, table, query, typeDefName, allValuesOptional, addExport, dbName, }) { - let typeDefinition = ``; - let tdName = ``; - try { - tdName = typeDefName - ? typeDefName - : dbName - ? `BUN_MARIADB_${dbName}_${table.tableName}`.toUpperCase() - : `BUN_MARIADB_${query.single}_${query.single_table}`.toUpperCase(); - const fields = table.fields; - function typeMap(schemaType) { - if (schemaType.options && schemaType.options.length > 0) { - let opts = schemaType.options.map((opt) => schemaType.dataType?.match(/int/i) || typeof opt == "number" - ? `${opt}` - : `"${opt}"`); - opts.push(`""`); - return opts.join(" | "); - } - if (schemaType.dataType?.match(/blob/i)) { - return `Float32Array | Buffer | null`; - } - if (schemaType.dataType?.match(/int|double|decimal|real/i)) { - return `number | ""`; - } - if (schemaType.dataType?.match(/text|varchar|timestamp/i)) { - return `string`; - } - if (schemaType.dataType?.match(/boolean/i)) { - return "0 | 1"; - } - return "string"; - } - const typesArrayTypeScript = []; - const typesArrayJavascript = []; - typesArrayTypeScript.push(`${addExport ? "export " : ""}type ${tdName} = {`); - typesArrayJavascript.push(`/**\n * @typedef {object} ${tdName}`); - fields.forEach((field) => { - if (field.fieldDescription) { - typesArrayTypeScript.push(` /** \n * ${field.fieldDescription}\n */`); - } - const nullValue = allValuesOptional - ? "?" - : field.notNullValue - ? "" - : "?"; - typesArrayTypeScript.push(` ${field.fieldName}${nullValue}: ${typeMap(field)};`); - typesArrayJavascript.push(` * @property {${typeMap(field)}${nullValue}} ${field.fieldName}`); - }); - typesArrayTypeScript.push(`}`); - typesArrayJavascript.push(` */`); - if (paradigm?.match(/javascript/i)) { - typeDefinition = typesArrayJavascript.join("\n"); - } - if (paradigm?.match(/typescript/i)) { - typeDefinition = typesArrayTypeScript.join("\n"); - } - } - catch (error) { - console.log(error.message); - typeDefinition = null; - } - return { typeDefinition, tdName }; -} diff --git a/dist/lib/mariadb/db-insert.d.ts b/dist/lib/mariadb/db-insert.d.ts deleted file mode 100644 index d5101ec..0000000 --- a/dist/lib/mariadb/db-insert.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { APIResponseObject } from "../../types"; -type Params = { - table: Table; - data: Schema[]; - update_on_duplicate?: boolean; -}; -export default function DbInsert({ table, data, update_on_duplicate, }: Params): Promise; -export {}; diff --git a/dist/lib/mariadb/db-insert.js b/dist/lib/mariadb/db-insert.js deleted file mode 100644 index f5d37e8..0000000 --- a/dist/lib/mariadb/db-insert.js +++ /dev/null @@ -1,43 +0,0 @@ -import DbClient from "."; -import sqlInsertGenerator from "../../utils/sql-insert-generator"; -import grabDuplicateSafeInsertSql from "../grab-duplicate-safe-insert-sql"; -export default async function DbInsert({ table, data, update_on_duplicate, }) { - let sqlObj = null; - try { - const finalData = data.map((d) => ({ - created_at: Date.now(), - updated_at: Date.now(), - ...d, - })); - sqlObj = - sqlInsertGenerator({ - tableName: table, - data: finalData, - }) || null; - let sql = sqlObj?.query || ""; - if (update_on_duplicate && data[0]) { - sql = await grabDuplicateSafeInsertSql({ data, table, sql }); - } - (sqlObj || {}).query = sql; - const res = DbClient.run(sql, sqlObj?.values || []); - return { - success: Boolean(Number(res.lastInsertRowid)), - postInsertReturn: { - affectedRows: res.changes, - insertId: Number(res.lastInsertRowid), - }, - debug: { - sqlObj, - }, - }; - } - catch (error) { - return { - success: false, - error: error.message, - debug: { - sqlObj, - }, - }; - } -} diff --git a/dist/lib/mariadb/db-schema-manager.d.ts b/dist/lib/mariadb/db-schema-manager.d.ts deleted file mode 100644 index 30f7dc6..0000000 --- a/dist/lib/mariadb/db-schema-manager.d.ts +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env bun -import type { BUN_MARIADB_DatabaseSchemaType } from "../../types"; -declare class MariaDBSchemaManager { - private db_manager_table_name; - private recreate_vector_table; - private db_schema; - constructor({ schema, recreate_vector_table, }: { - schema: BUN_MARIADB_DatabaseSchemaType; - recreate_vector_table?: boolean; - }); - syncSchema(): Promise; - private getDatabaseName; - private quoteIdentifier; - private tableSchemaWhere; - private run; - private query; - private createDbManagerTable; - private insertDbManagerTable; - private removeDbManagerTable; - private getExistingTables; - private getLiveTableNames; - private dropRemovedTables; - private syncTable; - private resolveTable; - private createTable; - private buildTableOptions; - private updateTable; - private getTableColumns; - private addColumn; - private checkIfTableExists; - private recreateTable; - private insertRows; - private buildColumnDefinition; - private mapDataType; - private buildForeignKeyConstraint; - private syncIndexes; - close(): void; -} -export { MariaDBSchemaManager }; diff --git a/dist/lib/mariadb/db-schema-manager.js b/dist/lib/mariadb/db-schema-manager.js deleted file mode 100644 index 9fcb6aa..0000000 --- a/dist/lib/mariadb/db-schema-manager.js +++ /dev/null @@ -1,419 +0,0 @@ -#!/usr/bin/env bun -import _ from "lodash"; -import dbHandler from "../db-handler"; -import { AppData } from "../../data/app-data"; -import { readLiveSchema } from "../../functions/live-schema"; -class MariaDBSchemaManager { - db_manager_table_name; - recreate_vector_table; - db_schema; - constructor({ schema, recreate_vector_table = false, }) { - this.db_manager_table_name = AppData["DbSchemaManagerTableName"]; - this.recreate_vector_table = recreate_vector_table; - this.db_schema = schema; - } - async syncSchema() { - console.log("Starting schema synchronization..."); - await this.createDbManagerTable(); - const existingTables = await this.getExistingTables(); - const schemaTables = this.db_schema.tables.map((t) => t.tableName); - for (const table of this.db_schema.tables) { - await this.syncTable(table, existingTables); - } - await this.dropRemovedTables(existingTables, schemaTables); - console.log("Schema synchronization complete!"); - } - getDatabaseName() { - return this.db_schema.dbName || this.db_schema.dbSlug; - } - quoteIdentifier(identifier) { - return `\`${identifier.replace(/`/g, "``")}\``; - } - tableSchemaWhere(tableName) { - const databaseName = this.getDatabaseName(); - if (databaseName) { - return { - where: "TABLE_SCHEMA = ?", - values: [databaseName, tableName], - }; - } - return { - where: "TABLE_SCHEMA = DATABASE()", - values: [tableName], - }; - } - async run(query, values) { - const res = await dbHandler({ - query, - values: values, - config: this.getDatabaseName() - ? { database: this.getDatabaseName() } - : undefined, - }); - if (!res.success) { - throw new Error(`Database query failed: ${query}`); - } - } - async query(query, values) { - const res = await dbHandler({ - query, - values: values, - config: this.getDatabaseName() - ? { database: this.getDatabaseName() } - : undefined, - }); - if (!res.success) { - throw new Error(`Database query failed: ${query}`); - } - return (res.payload || []); - } - async createDbManagerTable() { - await this.run(` - CREATE TABLE IF NOT EXISTS ${this.quoteIdentifier(this.db_manager_table_name)} ( - table_name VARCHAR(255) NOT NULL PRIMARY KEY, - created_at BIGINT NOT NULL, - updated_at BIGINT NOT NULL - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci - `); - } - async insertDbManagerTable(tableName) { - const now = Date.now(); - await this.run(`INSERT INTO ${this.quoteIdentifier(this.db_manager_table_name)} (table_name, created_at, updated_at) VALUES (?, ?, ?) ON DUPLICATE KEY UPDATE updated_at = VALUES(updated_at)`, [tableName, now, now]); - } - async removeDbManagerTable(tableName) { - await this.run(`DELETE FROM ${this.quoteIdentifier(this.db_manager_table_name)} WHERE table_name = ?`, [tableName]); - } - async getExistingTables() { - const rows = await this.query(`SELECT table_name FROM ${this.quoteIdentifier(this.db_manager_table_name)}`); - return rows.map((row) => row.table_name); - } - async getLiveTableNames() { - const tableSchemaWhere = this.tableSchemaWhere(""); - const rows = await this.query(`SELECT TABLE_NAME FROM information_schema.TABLES WHERE ${tableSchemaWhere.where} AND TABLE_TYPE = 'BASE TABLE'`, tableSchemaWhere.values); - return rows.map((row) => row.TABLE_NAME); - } - async dropRemovedTables(existingTables, schemaTables) { - console.log(`Cleaning up tables ...`); - const tablesToDrop = existingTables.filter((tableName) => !schemaTables.includes(tableName) && - !schemaTables.some((schemaTable) => tableName.startsWith(`${schemaTable}_`))); - const currentSchema = readLiveSchema(); - if (currentSchema?.tables?.[0]) { - for (const table of currentSchema.tables) { - if (!table?.tableName) - continue; - const doesTableExist = schemaTables.find((tableName) => tableName === table.tableName); - if (!doesTableExist) { - tablesToDrop.push(table.tableName); - } - } - } - for (const tableName of tablesToDrop) { - console.log(`Dropping table: ${tableName}`); - await this.run(`DROP TABLE IF EXISTS ${this.quoteIdentifier(tableName)}`); - await this.removeDbManagerTable(tableName); - } - } - async syncTable(table, existingTables) { - let tableExists = existingTables.includes(table.tableName); - const liveTables = await this.getLiveTableNames(); - if (table.tableNameOld && table.tableNameOld !== table.tableName) { - if (liveTables.includes(table.tableNameOld)) { - console.log(`Renaming table: ${table.tableNameOld} -> ${table.tableName}`); - await this.run(`RENAME TABLE ${this.quoteIdentifier(table.tableNameOld)} TO ${this.quoteIdentifier(table.tableName)}`); - await this.insertDbManagerTable(table.tableName); - await this.removeDbManagerTable(table.tableNameOld); - tableExists = true; - } - } - if (!tableExists) { - await this.createTable(table); - await this.insertDbManagerTable(table.tableName); - } - else { - await this.updateTable(table); - await this.insertDbManagerTable(table.tableName); - } - await this.syncIndexes(table); - } - resolveTable(table) { - if (!table.parentTableName) { - return _.cloneDeep(table); - } - const parentTable = this.db_schema.tables.find((schemaTable) => schemaTable.tableName === table.parentTableName); - if (!parentTable) { - throw new Error(`Parent table \`${table.parentTableName}\` not found for \`${table.tableName}\``); - } - return _.merge({}, parentTable, { - tableName: table.tableName, - tableDescription: table.tableDescription, - collation: table.collation, - fields: [...(parentTable.fields || []), ...(table.fields || [])], - indexes: [...(parentTable.indexes || []), ...(table.indexes || [])], - uniqueConstraints: [ - ...(parentTable.uniqueConstraints || []), - ...(table.uniqueConstraints || []), - ], - }); - } - async createTable(table) { - if (!table.tableName.match(/_temp_\d+$/)) { - console.log(`Creating table: ${table.tableName}`); - } - const newTable = this.resolveTable(table); - const columnDefinitions = []; - const foreignKeys = []; - for (const field of newTable.fields || []) { - columnDefinitions.push(this.buildColumnDefinition(field)); - if (field.foreignKey && !newTable.isVector) { - foreignKeys.push(this.buildForeignKeyConstraint(field)); - } - } - if (newTable.uniqueConstraints) { - for (const constraint of newTable.uniqueConstraints) { - if (constraint.constraintTableFields && - constraint.constraintTableFields.length > 0) { - const fields = constraint.constraintTableFields - .map((field) => this.quoteIdentifier(field.value)) - .join(", "); - const constraintName = constraint.constraintName || - `unique_${fields.replace(/`/g, "")}`; - columnDefinitions.push(`CONSTRAINT ${this.quoteIdentifier(constraintName)} UNIQUE (${fields})`); - } - } - } - const sql = `CREATE TABLE IF NOT EXISTS ${this.quoteIdentifier(newTable.tableName)} (${[...columnDefinitions, ...foreignKeys].join(", ")})${this.buildTableOptions(newTable)}`; - await this.run(sql); - } - buildTableOptions(table) { - const options = ["ENGINE=InnoDB"]; - if (table.collation) { - options.push("DEFAULT CHARSET=utf8mb4", `COLLATE ${table.collation}`); - } - return ` ${options.join(" ")}`; - } - async updateTable(table) { - console.log(`Updating table: ${table.tableName}`); - await this.recreateTable(table); - } - async getTableColumns(tableName) { - const tableSchemaWhere = this.tableSchemaWhere(tableName); - const rows = await this.query(`SELECT COLUMN_NAME AS name, COLUMN_TYPE AS type FROM information_schema.COLUMNS WHERE ${tableSchemaWhere.where} AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION`, tableSchemaWhere.values); - return rows.map((row) => ({ - name: row.COLUMN_NAME, - type: row.COLUMN_TYPE, - })); - } - async addColumn(tableName, field) { - console.log(`Adding column: ${tableName}.${field.fieldName}`); - const columnDef = this.buildColumnDefinition(field) - .replace(/PRIMARY KEY/gi, "") - .replace(/AUTO_INCREMENT/gi, "") - .replace(/UNIQUE/gi, "") - .trim(); - await this.run(`ALTER TABLE ${this.quoteIdentifier(tableName)} ADD COLUMN ${columnDef}`); - } - async checkIfTableExists(table) { - const tableSchemaWhere = this.tableSchemaWhere(table); - const row = await this.query(`SELECT 1 AS exists FROM information_schema.TABLES WHERE ${tableSchemaWhere.where} AND TABLE_NAME = ? LIMIT 1`, tableSchemaWhere.values); - return Boolean(row[0]?.exists); - } - async recreateTable(table) { - if (table.isVector && !this.recreate_vector_table) { - return; - } - const doesTableExist = await this.checkIfTableExists(table.tableName); - if (table.isVector) { - let existingRows = []; - if (doesTableExist) { - existingRows = await this.query(`SELECT * FROM ${this.quoteIdentifier(table.tableName)}`); - await this.run(`DROP TABLE ${this.quoteIdentifier(table.tableName)}`); - } - await this.createTable(table); - if (existingRows.length > 0) { - await this.insertRows(table.tableName, existingRows); - } - return; - } - const tempTableName = `${table.tableName}_temp_${Date.now()}`; - const existingColumns = await this.getTableColumns(table.tableName); - const columnsToKeep = table.fields - .filter((field) => existingColumns.some((column) => column.name === field.fieldName)) - .map((field) => field.fieldName) - .filter((fieldName) => Boolean(fieldName)); - await this.createTable({ ...table, tableName: tempTableName }); - if (columnsToKeep.length > 0) { - const columnList = columnsToKeep - .map((column) => this.quoteIdentifier(column)) - .join(", "); - await this.run(`INSERT INTO ${this.quoteIdentifier(tempTableName)} (${columnList}) SELECT ${columnList} FROM ${this.quoteIdentifier(table.tableName)}`); - } - await this.run(`DROP TABLE ${this.quoteIdentifier(table.tableName)}`); - await this.run(`RENAME TABLE ${this.quoteIdentifier(tempTableName)} TO ${this.quoteIdentifier(table.tableName)}`); - } - async insertRows(tableName, rows) { - for (const row of rows) { - const columns = Object.keys(row); - if (columns.length === 0) { - continue; - } - const values = columns.map((column) => row[column]); - const columnList = columns - .map((column) => this.quoteIdentifier(column)) - .join(", "); - const placeholders = columns.map(() => "?").join(", "); - await this.run(`INSERT INTO ${this.quoteIdentifier(tableName)} (${columnList}) VALUES (${placeholders})`, values); - } - } - buildColumnDefinition(field) { - if (!field.fieldName) { - throw new Error("Field name is required"); - } - const parts = [this.quoteIdentifier(field.fieldName)]; - parts.push(this.mapDataType(field)); - if (field.primaryKey) { - parts.push("PRIMARY KEY"); - if (field.autoIncrement) { - parts.push("AUTO_INCREMENT"); - } - } - if (field.notNullValue || field.primaryKey) { - if (!field.primaryKey) { - parts.push("NOT NULL"); - } - } - if (field.unique && !field.primaryKey) { - parts.push("UNIQUE"); - } - if (field.defaultValue !== undefined) { - if (typeof field.defaultValue === "string") { - parts.push(`DEFAULT '${field.defaultValue.replace(/'/g, "''")}'`); - } - else { - parts.push(`DEFAULT ${field.defaultValue}`); - } - } - else if (field.defaultValueLiteral) { - parts.push(`DEFAULT ${field.defaultValueLiteral}`); - } - if (field.onUpdate) { - parts.push(`ON UPDATE ${field.onUpdate}`); - } - else if (field.onUpdateLiteral) { - parts.push(`ON UPDATE ${field.onUpdateLiteral}`); - } - return parts.join(" "); - } - mapDataType(field) { - const dataType = field.dataType?.toLowerCase() || "text"; - const vectorSize = field.vectorSize || 1536; - if (field.isVector) { - return `LONGTEXT COMMENT 'vector_size=${vectorSize}'`; - } - if (dataType.includes("int") || - dataType === "bigint" || - dataType === "smallint" || - dataType === "tinyint") { - if (field.integerLength) { - return `INT(${field.integerLength})`; - } - return "INT"; - } - if (dataType === "bigint") { - if (field.integerLength) { - return `BIGINT(${field.integerLength})`; - } - return "BIGINT"; - } - if (dataType === "smallint") { - if (field.integerLength) { - return `SMALLINT(${field.integerLength})`; - } - return "SMALLINT"; - } - if (dataType === "tinyint") { - if (field.integerLength) { - return `TINYINT(${field.integerLength})`; - } - return "TINYINT"; - } - if (dataType.includes("double")) { - return "DOUBLE"; - } - if (dataType.includes("float")) { - return "FLOAT"; - } - if (dataType.includes("decimal") || dataType.includes("numeric")) { - if (field.integerLength && field.decimals) { - return `DECIMAL(${field.integerLength}, ${field.decimals})`; - } - return "DECIMAL"; - } - if (dataType.includes("blob") || dataType.includes("binary")) { - return "BLOB"; - } - if (dataType === "boolean" || dataType === "bool") { - return "TINYINT(1)"; - } - if (dataType.includes("timestamp")) { - return "TIMESTAMP"; - } - if (dataType.includes("datetime")) { - return "DATETIME"; - } - if (dataType.includes("date") || dataType.includes("time")) { - return "DATETIME"; - } - if (dataType.includes("varchar")) { - if (field.integerLength) { - return `VARCHAR(${field.integerLength})`; - } - return "VARCHAR(255)"; - } - return "TEXT"; - } - buildForeignKeyConstraint(field) { - const fk = field.foreignKey; - const constraintName = fk.foreignKeyName - ? `CONSTRAINT ${this.quoteIdentifier(fk.foreignKeyName)} ` - : ""; - let constraint = `${constraintName}FOREIGN KEY (${this.quoteIdentifier(field.fieldName)}) REFERENCES ${this.quoteIdentifier(fk.destinationTableName)}(${this.quoteIdentifier(fk.destinationTableColumnName)})`; - if (fk.cascadeDelete) { - constraint += " ON DELETE CASCADE"; - } - if (fk.cascadeUpdate) { - constraint += " ON UPDATE CASCADE"; - } - return constraint; - } - async syncIndexes(table) { - if (!table.indexes || table.indexes.length === 0) { - return; - } - const tableSchemaWhere = this.tableSchemaWhere(table.tableName); - const rows = await this.query(`SELECT INDEX_NAME AS name FROM information_schema.STATISTICS WHERE ${tableSchemaWhere.where} AND TABLE_NAME = ? AND INDEX_NAME <> 'PRIMARY' GROUP BY INDEX_NAME ORDER BY INDEX_NAME`, tableSchemaWhere.values); - const existingIndexes = rows.map((row) => row.name); - for (const indexName of existingIndexes) { - const stillExists = table.indexes.some((index) => index.indexName === indexName); - if (!stillExists) { - console.log(`Dropping index: ${indexName}`); - await this.run(`DROP INDEX ${this.quoteIdentifier(indexName)} ON ${this.quoteIdentifier(table.tableName)}`); - } - } - for (const index of table.indexes) { - if (!index.indexName || - !index.indexTableFields || - index.indexTableFields.length === 0) { - continue; - } - if (!existingIndexes.includes(index.indexName)) { - console.log(`Creating index: ${index.indexName}`); - const fields = index.indexTableFields - .map((field) => this.quoteIdentifier(field)) - .join(", "); - await this.run(`CREATE INDEX ${this.quoteIdentifier(index.indexName)} ON ${this.quoteIdentifier(table.tableName)} (${fields})`); - } - } - } - close() { } -} -export { MariaDBSchemaManager }; diff --git a/dist/lib/mariadb/db-schema-to-typedef.d.ts b/dist/lib/mariadb/db-schema-to-typedef.d.ts deleted file mode 100644 index 6b70359..0000000 --- a/dist/lib/mariadb/db-schema-to-typedef.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { BUN_MARIADB_DatabaseSchemaType, BunSQLiteConfig } from "../../types"; -type Params = { - dbSchema: BUN_MARIADB_DatabaseSchemaType; - config: BunSQLiteConfig; -}; -export default function dbSchemaToType({ config, dbSchema, }: Params): string[] | undefined; -export {}; diff --git a/dist/lib/mariadb/db-schema-to-typedef.js b/dist/lib/mariadb/db-schema-to-typedef.js deleted file mode 100644 index 6d78c14..0000000 --- a/dist/lib/mariadb/db-schema-to-typedef.js +++ /dev/null @@ -1,44 +0,0 @@ -import _ from "lodash"; -import generateTypeDefinition from "./db-generate-type-defs"; -export default function dbSchemaToType({ config, dbSchema, }) { - let datasquirelSchema = dbSchema; - if (!datasquirelSchema) - return; - let tableNames = `export const BunSQLiteTables = [\n${datasquirelSchema.tables - .map((tbl) => ` "${tbl.tableName}",`) - .join("\n")}\n] as const`; - const dbTablesSchemas = datasquirelSchema.tables; - const defDbName = config.db_name - ?.toUpperCase() - .replace(/[^a-zA-Z0-9]/g, "_"); - const defNames = []; - const schemas = dbTablesSchemas - .map((table) => { - let final_table = _.cloneDeep(table); - if (final_table.parentTableName) { - const parent_table = dbTablesSchemas.find((t) => t.tableName === final_table.parentTableName); - if (parent_table) { - final_table = _.merge(parent_table, { - tableName: final_table.tableName, - tableDescription: final_table.tableDescription, - }); - } - } - const defObj = generateTypeDefinition({ - paradigm: "TypeScript", - table: final_table, - typeDefName: `BUN_MARIADB_${defDbName}_${final_table.tableName.toUpperCase()}`, - allValuesOptional: true, - addExport: true, - }); - if (defObj.tdName?.match(/./)) { - defNames.push(defObj.tdName); - } - return defObj.typeDefinition; - }) - .filter((schm) => typeof schm == "string"); - const allTd = defNames?.[0] - ? `export type BUN_MARIADB_${defDbName}_ALL_TYPEDEFS = ${defNames.join(` & `)}` - : ``; - return [tableNames, ...schemas, allTd]; -} diff --git a/dist/lib/mariadb/db-select.d.ts b/dist/lib/mariadb/db-select.d.ts deleted file mode 100644 index ed27786..0000000 --- a/dist/lib/mariadb/db-select.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { APIResponseObject, ServerQueryParam } from "../../types"; -type Params = { - query?: ServerQueryParam; - table: Table; - count?: boolean; - targetId?: number | string; -}; -export default function DbSelect({ table, query, count, targetId, }: Params): Promise>; -export {}; diff --git a/dist/lib/mariadb/db-select.js b/dist/lib/mariadb/db-select.js deleted file mode 100644 index 8b1674f..0000000 --- a/dist/lib/mariadb/db-select.js +++ /dev/null @@ -1,58 +0,0 @@ -import mysql from "mysql"; -import DbClient from "."; -import _ from "lodash"; -import sqlGenerator from "../../utils/sql-generator"; -export default async function DbSelect({ table, query, count, targetId, }) { - let sqlObj = null; - try { - let finalQuery = query || {}; - if (targetId) { - finalQuery = _.merge(finalQuery, { - query: { - id: { - value: String(targetId), - }, - }, - }); - } - sqlObj = sqlGenerator({ - tableName: table, - genObject: finalQuery, - }); - let 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) { - let count_sql_object = sqlGenerator({ - tableName: table, - genObject: finalQuery, - count, - }); - let count_sql = mysql.format(count_sql_object.string, count_sql_object.values); - count_sql = `SELECT COUNT(*) FROM (${count_sql}) as c`; - const count_res = DbClient.query(count_sql).all(); - const count_val = count_res[0]?.["COUNT(*)"]; - resp["count"] = Number(count_val); - resp["debug"]["count_sql"] = count_sql; - } - return resp; - } - catch (error) { - return { - success: false, - error: error.message, - debug: { - sqlObj, - }, - }; - } -} diff --git a/dist/lib/mariadb/db-sql.d.ts b/dist/lib/mariadb/db-sql.d.ts deleted file mode 100644 index e528035..0000000 --- a/dist/lib/mariadb/db-sql.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { APIResponseObject, SQLInsertGenValueType } from "../../types"; -type Params = { - sql: string; - values?: SQLInsertGenValueType[]; -}; -export default function DbSQL({ sql, values }: Params): Promise>; -export {}; diff --git a/dist/lib/mariadb/db-sql.js b/dist/lib/mariadb/db-sql.js deleted file mode 100644 index 33fd427..0000000 --- a/dist/lib/mariadb/db-sql.js +++ /dev/null @@ -1,34 +0,0 @@ -import DbClient from "."; -import _ from "lodash"; -export default async function DbSQL({ sql, values }) { - try { - const trimmed_sql = sql.trim(); - const res = trimmed_sql.match(/^select/i) - ? DbClient.query(trimmed_sql).all(...(values || [])) - : DbClient.run(trimmed_sql, values || []); - return { - success: true, - payload: Array.isArray(res) ? res : undefined, - singleRes: Array.isArray(res) ? res?.[0] : undefined, - postInsertReturn: Array.isArray(res) - ? undefined - : { - affectedRows: res.changes, - insertId: Number(res.lastInsertRowid), - }, - debug: { - sqlObj: { - sql: trimmed_sql, - values, - }, - sql, - }, - }; - } - catch (error) { - return { - success: false, - error: error.message, - }; - } -} diff --git a/dist/lib/mariadb/db-update.d.ts b/dist/lib/mariadb/db-update.d.ts deleted file mode 100644 index 68bff0c..0000000 --- a/dist/lib/mariadb/db-update.d.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { APIResponseObject, ServerQueryParam } from "../../types"; -type Params = { - table: Table; - data: Schema; - query?: ServerQueryParam; - targetId?: number | string; -}; -export default function DbUpdate({ table, data, query, targetId, }: Params): Promise; -export {}; diff --git a/dist/lib/mariadb/db-update.js b/dist/lib/mariadb/db-update.js deleted file mode 100644 index 38a5daa..0000000 --- a/dist/lib/mariadb/db-update.js +++ /dev/null @@ -1,74 +0,0 @@ -import DbClient from "."; -import _ from "lodash"; -import sqlGenerator from "../../utils/sql-generator"; -export default async function DbUpdate({ table, data, query, targetId, }) { - let sqlObj = { string: "", values: [] }; - try { - let finalQuery = query || {}; - if (targetId) { - finalQuery = _.merge(finalQuery, { - query: { - id: { - value: String(targetId), - }, - }, - }); - } - const sqlQueryObj = sqlGenerator({ - tableName: table, - genObject: finalQuery, - }); - let values = []; - const whereClause = sqlQueryObj.string.match(/WHERE .*/)?.[0]; - if (whereClause) { - let sql = `UPDATE ${table} SET`; - const finalData = { - updated_at: Date.now(), - ...data, - }; - const keys = Object.keys(finalData); - for (let i = 0; i < keys.length; i++) { - const key = keys[i]; - if (!key) - continue; - const isLast = i == keys.length - 1; - sql += ` ${key}=?`; - const value = finalData[key]; - values.push(value || null); - if (!isLast) { - sql += `,`; - } - } - sql += ` ${whereClause}`; - values = [...values, ...sqlQueryObj.values]; - sqlObj.string = sql; - sqlObj.values = values; - const res = DbClient.run(sql, values); - return { - success: Boolean(res.changes), - postInsertReturn: { - affectedRows: res.changes, - insertId: Number(res.lastInsertRowid), - }, - debug: { - sqlObj, - }, - }; - } - else { - return { - success: false, - msg: `No WHERE clause`, - }; - } - } - catch (error) { - return { - success: false, - error: error.message, - debug: { - sqlObj, - }, - }; - } -} diff --git a/dist/lib/mariadb/schema-to-typedef.d.ts b/dist/lib/mariadb/schema-to-typedef.d.ts deleted file mode 100644 index 0ca673f..0000000 --- a/dist/lib/mariadb/schema-to-typedef.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type { BUN_MARIADB_DatabaseSchemaType, BunSQLiteConfig } from "../../types"; -type Params = { - dbSchema: BUN_MARIADB_DatabaseSchemaType; - dst_file: string; - config: BunSQLiteConfig; -}; -export default function dbSchemaToTypeDef({ dbSchema, dst_file, config, }: Params): void; -export {}; diff --git a/dist/lib/mariadb/schema-to-typedef.js b/dist/lib/mariadb/schema-to-typedef.js deleted file mode 100644 index f0c5ac3..0000000 --- a/dist/lib/mariadb/schema-to-typedef.js +++ /dev/null @@ -1,18 +0,0 @@ -import path from "node:path"; -import { existsSync, mkdirSync, writeFileSync } from "node:fs"; -import dbSchemaToType from "./db-schema-to-typedef"; -export default function dbSchemaToTypeDef({ dbSchema, dst_file, config, }) { - try { - if (!dbSchema) - throw new Error("No schema found"); - const definitions = dbSchemaToType({ dbSchema, config }); - const ourfileDir = path.dirname(dst_file); - if (!existsSync(ourfileDir)) { - mkdirSync(ourfileDir, { recursive: true }); - } - writeFileSync(dst_file, definitions?.join("\n\n") || "", "utf-8"); - } - catch (error) { - console.log(`Schema to Typedef Error =>`, error.message); - } -} diff --git a/dist/lib/mariadb/schema.d.ts b/dist/lib/mariadb/schema.d.ts deleted file mode 100644 index 8ce6d90..0000000 --- a/dist/lib/mariadb/schema.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import type { BUN_MARIADB_DatabaseSchemaType } from "../../types"; -export declare const DbSchema: BUN_MARIADB_DatabaseSchemaType; diff --git a/dist/lib/mariadb/schema.js b/dist/lib/mariadb/schema.js deleted file mode 100644 index 5778e50..0000000 --- a/dist/lib/mariadb/schema.js +++ /dev/null @@ -1,5 +0,0 @@ -import _ from "lodash"; -export const DbSchema = { - dbName: "travis-ai", - tables: [], -}; diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts deleted file mode 100644 index c5bee3c..0000000 --- a/dist/types/index.d.ts +++ /dev/null @@ -1,1417 +0,0 @@ -import type { RequestOptions } from "https"; -import type { ConnectionConfig } from "mariadb"; -/** - * Fully-qualified database name used when a database needs to be referenced - * across local and remote operations. - */ -export type BUN_MARIADB_DatabaseFullName = string; -/** - * User fields that should be omitted from general-purpose payloads and public - * responses. - */ -export declare const UsersOmitedFields: readonly ["password", "social_id", "verification_status", "date_created", "date_created_code", "date_created_timestamp", "date_updated", "date_updated_code", "date_updated_timestamp"]; -/** - * Describes an entire database schema, including its tables and clone/child - * database metadata. - */ -export interface BUN_MARIADB_DatabaseSchemaType { - id?: string | number; - dbName?: string; - dbSlug?: string; - dbFullName?: string; - dbDescription?: string; - dbImage?: string; - tables: BUN_MARIADB_TableSchemaType[]; - childrenDatabases?: BUN_MARIADB_ChildrenDatabaseObject[]; - childDatabase?: boolean; - childDatabaseDbId?: string | number; - updateData?: boolean; - collation?: (typeof MariaDBCollations)[number]; -} -/** - * Minimal reference to a child database linked to a parent database schema. - */ -export interface BUN_MARIADB_ChildrenDatabaseObject { - dbId?: string | number; -} -/** - * Supported MariaDB collations that can be applied at the database or table - * level. - */ -export declare const MariaDBCollations: readonly ["utf8mb4_bin", "utf8mb4_unicode_520_ci"]; -/** - * Describes a single table within a database schema, including its fields, - * indexes, unique constraints, and parent/child table relationships. - */ -export interface BUN_MARIADB_TableSchemaType { - id?: string | number; - tableName: string; - tableDescription?: string; - fields: BUN_MARIADB_FieldSchemaType[]; - indexes?: BUN_MARIADB_IndexSchemaType[]; - uniqueConstraints?: BUN_MARIADB_UniqueConstraintSchemaType[]; - childrenTables?: BUN_MARIADB_ChildrenTablesType[]; - /** - * Whether this is a child table - */ - childTable?: boolean; - updateData?: boolean; - /** - * ID of the parent table - */ - childTableId?: string | number; - /** - * ID of the parent table - */ - parentTableId?: string | number; - /** - * ID of the Database of parent table - */ - parentTableDbId?: string | number; - /** - * Name of the Database of parent table - */ - parentTableDbName?: string; - /** - * Name of the parent table - */ - parentTableName?: string; - tableNameOld?: string; - /** - * ID of the Database of parent table - */ - childTableDbId?: string | number; - collation?: (typeof MariaDBCollations)[number]; - /** - * If this is a vector table - */ - isVector?: boolean; - /** - * Type of vector. Defaults to `vec0` - */ - vectorType?: string; -} -/** - * Reference object used to link a table to one of its child tables. - */ -export interface BUN_MARIADB_ChildrenTablesType { - tableId?: string | number; - dbId?: string | number; -} -/** - * Supported editor/content modes for text fields. - */ -export declare const TextFieldTypesArray: readonly [{ - readonly title: "Plain Text"; - readonly value: "plain"; -}, { - readonly title: "Rich Text"; - readonly value: "richText"; -}, { - readonly title: "Markdown"; - readonly value: "markdown"; -}, { - readonly title: "JSON"; - readonly value: "json"; -}, { - readonly title: "YAML"; - readonly value: "yaml"; -}, { - readonly title: "HTML"; - readonly value: "html"; -}, { - readonly title: "CSS"; - readonly value: "css"; -}, { - readonly title: "Javascript"; - readonly value: "javascript"; -}, { - readonly title: "Shell"; - readonly value: "shell"; -}, { - readonly title: "Code"; - readonly value: "code"; -}]; -/** - * Core SQLite column types supported by the schema builder. - */ -export declare const BUN_MARIADB_DATATYPES: readonly [{ - readonly value: "TEXT"; -}, { - readonly value: "INTEGER"; -}, { - readonly value: "BLOB"; -}, { - readonly value: "REAL"; -}]; -/** - * Describes a table column, including SQL constraints, text editor options, - * vector metadata, and foreign key configuration. - */ -export type BUN_MARIADB_FieldSchemaType = { - id?: number | string; - fieldName?: string; - fieldDescription?: string; - originName?: string; - dataType: (typeof BUN_MARIADB_DATATYPES)[number]["value"]; - nullValue?: boolean; - notNullValue?: boolean; - primaryKey?: boolean; - encrypted?: boolean; - autoIncrement?: boolean; - defaultValue?: string | number; - defaultValueLiteral?: string; - foreignKey?: BUN_MARIADB_ForeignKeyType; - defaultField?: boolean; - plainText?: boolean; - unique?: boolean; - pattern?: string; - patternFlags?: string; - onUpdate?: string; - onUpdateLiteral?: string; - onDelete?: string; - onDeleteLiteral?: string; - cssFiles?: string[]; - integerLength?: string | number; - decimals?: string | number; - code?: boolean; - options?: (string | number)[]; - isVector?: boolean; - vectorSize?: number; - /** - * ### Adds a `+` prefix to colums - * In sqlite-vec, the + prefix is a specialized syntax for Virtual Table Columns. It essentially tells the database: "Keep this data associated with the vector, but don't try to index it for math." -Here is the breakdown of why they matter and how they work: -1. Performance Separation -In a standard table, adding a massive TEXT column (like a 2,000-word article) slows down full-table scans. In a vec0 virtual table, columns prefixed with + are stored in a separate internal side-car table. -The Vector Index: Stays lean and fast for "Nearest Neighbor" math. -The Content: Is only fetched after the vector search identifies the winning rows. -2. The "No Join" Convenience -Normally, you would store vectors in one table and the actual text content in another, linking them with a FOREIGN KEY. -Without + columns: You must JOIN two tables to get the text after finding the vector. -With + columns: You can SELECT content directly from the virtual table. It handles the "join" logic internally, making your code cleaner. -3. Syntax Example -When defining your schema, the + is only used in the CREATE statement. When querying or inserting, you treat it like a normal name. -```sql --- SCHEMA DEFINITION -CREATE VIRTUAL TABLE documents USING vec0( - embedding float, -- The vector (indexed) - +title TEXT, -- Side-car metadata (not indexed) - +raw_body TEXT -- Side-car "heavy" data (not indexed) -); - --- INSERTING (Notice: No '+' here) -INSERT INTO documents(embedding, title, raw_body) -VALUES (vec_f32(?), 'Bun Docs', 'Bun is a fast JavaScript runtime...'); - --- QUERYING (Notice: No '+' here) -SELECT title, raw_body -FROM documents -WHERE embedding MATCH ? AND k = 1; -``` - */ - sideCar?: boolean; - /** - * Eg. `cosine` - */ - vectorDistanceMetric?: string; -} & { - [key in (typeof TextFieldTypesArray)[number]["value"]]?: boolean; -}; -/** - * Defines a foreign key relationship from one field to another table column. - */ -export interface BUN_MARIADB_ForeignKeyType { - foreignKeyName?: string; - destinationTableName?: string; - destinationTableColumnName?: string; - destinationTableColumnType?: string; - cascadeDelete?: boolean; - cascadeUpdate?: boolean; -} -/** - * Describes a table index and the fields it covers. - */ -export interface BUN_MARIADB_IndexSchemaType { - /** - * Name of the index as it would appear on schema. Eg. - * `idx_user_id_index` - */ - indexName?: string; - indexTableFields?: string[]; -} -/** - * Describes a multi-field uniqueness rule for a table. - */ -export interface BUN_MARIADB_UniqueConstraintSchemaType { - id?: string | number; - constraintName?: string; - alias?: string; - constraintTableFields?: BUN_MARIADB_UniqueConstraintFieldType[]; -} -/** - * Single field reference inside a unique constraint definition. - */ -export interface BUN_MARIADB_UniqueConstraintFieldType { - value: string; -} -/** - * Field metadata used when generating SQL for indexes. - */ -export interface BUN_MARIADB_IndexTableFieldType { - value: string; - dataType: string; -} -/** - * Result shape returned by MySQL `SHOW INDEXES` queries. - */ -export interface BUN_MARIADB_MYSQL_SHOW_INDEXES_Type { - Key_name: string; - Table: string; - Column_name: string; - Collation: string; - Index_type: string; - Cardinality: string; - Index_comment: string; - Comment: string; -} -/** - * Result shape returned by MySQL `SHOW COLUMNS` queries. - */ -export interface BUN_MARIADB_MYSQL_SHOW_COLUMNS_Type { - Field: string; - Type: string; - Null: string; - Key: string; - Default: string; - Extra: string; -} -/** - * Result shape returned by MariaDB `SHOW INDEXES` queries. - */ -export interface BUN_MARIADB_MARIADB_SHOW_INDEXES_TYPE { - Table: string; - Non_unique: 0 | 1; - Key_name: string; - Seq_in_index: number; - Column_name: string; - Collation: string; - Cardinality: number; - Sub_part?: string; - Packed?: string; - Index_type?: "BTREE"; - Comment?: string; - Index_comment?: string; - Ignored?: "YES" | "NO"; -} -/** - * Minimal metadata returned when listing MySQL foreign keys. - */ -export interface BUN_MARIADB_MYSQL_FOREIGN_KEYS_Type { - CONSTRAINT_NAME: string; - CONSTRAINT_SCHEMA: string; - TABLE_NAME: string; -} -/** - * Database record describing a user-owned database and optional remote sync - * metadata. - */ -export interface BUN_MARIADB_MYSQL_user_databases_Type { - id: number; - user_id: number; - db_full_name: string; - db_name: string; - db_slug: string; - db_image: string; - db_description: string; - active_clone: number; - active_data: 0 | 1; - active_clone_parent_db: string; - remote_connected?: number; - remote_db_full_name?: string; - remote_connection_host?: string; - remote_connection_key?: string; - remote_connection_type?: string; - user_priviledge?: string; - date_created?: string; - image_thumbnail?: string; - first_name?: string; - last_name?: string; - email?: string; -} -/** - * Return value used when converting an uploaded image file to base64. - */ -export type ImageInputFileToBase64FunctionReturn = { - imageBase64?: string; - imageBase64Full?: string; - imageName?: string; - imageSize?: number; -}; -/** - * Querystring parameters accepted by generic GET data endpoints. - */ -export interface GetReqQueryObject { - db: string; - query: string; - queryValues?: string; - tableName?: string; - debug?: boolean; -} -/** - * Canonical logged-in user shape shared across auth, session, and API flows. - */ -export type DATASQUIREL_LoggedInUser = { - id: number; - uuid?: string; - first_name: string; - last_name: string; - email: string; - phone?: string; - user_type?: string; - username?: string; - image?: string; - image_thumbnail?: string; - social_login?: number; - social_platform?: string; - social_id?: string; - verification_status?: number; - csrf_k: string; - logged_in_status: boolean; - date: number; -} & { - [key: string]: any; -}; -/** - * Standard authenticated-user response wrapper. - */ -export interface AuthenticatedUser { - success: boolean; - payload: DATASQUIREL_LoggedInUser | null; - msg?: string; - userId?: number; - cookieNames?: any; -} -/** - * Minimal successful user payload returned by user creation flows. - */ -export interface SuccessUserObject { - id: number; - first_name: string; - last_name: string; - email: string; -} -/** - * Return type for helpers that create a user record. - */ -export interface AddUserFunctionReturn { - success: boolean; - payload?: SuccessUserObject | null; - msg?: string; - sqlResult?: any; -} -/** - * Shape exposed by the Google Identity prompt lifecycle callback. - */ -export interface GoogleIdentityPromptNotification { - getMomentType: () => string; - getDismissedReason: () => string; - getNotDisplayedReason: () => string; - getSkippedReason: () => string; - isDismissedMoment: () => boolean; - isDisplayMoment: () => boolean; - isDisplayed: () => boolean; - isNotDisplayed: () => boolean; - isSkippedMoment: () => boolean; -} -/** - * User data accepted by registration and profile-creation flows. - */ -export type UserDataPayload = { - first_name: string; - last_name: string; - email: string; - password?: string; - username?: string; -} & { - [key: string]: any; -}; -/** - * Return shape for helpers that fetch a single user. - */ -export interface GetUserFunctionReturn { - success: boolean; - payload: { - id: number; - first_name: string; - last_name: string; - username: string; - email: string; - phone: string; - social_id: [string]; - image: string; - image_thumbnail: string; - verification_status: [number]; - } | null; -} -/** - * Return type for reauthentication flows that refresh auth state. - */ -export interface ReauthUserFunctionReturn { - success: boolean; - payload: DATASQUIREL_LoggedInUser | null; - msg?: string; - userId?: number; - token?: string; -} -/** - * Return type for user update helpers. - */ -export interface UpdateUserFunctionReturn { - success: boolean; - payload?: Object[] | string; -} -/** - * Generic success/error wrapper for read operations. - */ -export interface GetReturn { - success: boolean; - payload?: R; - msg?: string; - error?: string; - schema?: BUN_MARIADB_TableSchemaType; - finalQuery?: string; -} -/** - * Query parameters used when requesting schema metadata. - */ -export interface GetSchemaRequestQuery { - database?: string; - table?: string; - field?: string; - user_id?: string | number; - env?: { - [k: string]: string; - }; -} -/** - * API credential payload used when a schema request must be authenticated. - */ -export interface GetSchemaAPICredentialsParam { - key: string; -} -/** - * Complete request object for authenticated schema fetches. - */ -export type GetSchemaAPIParam = GetSchemaRequestQuery & GetSchemaAPICredentialsParam; -/** - * Generic response wrapper for write operations. - */ -export interface PostReturn { - success: boolean; - payload?: Object[] | string | PostInsertReturn; - msg?: string; - error?: any; - schema?: BUN_MARIADB_TableSchemaType; -} -/** - * High-level CRUD payload accepted by server-side data mutation handlers. - */ -export interface PostDataPayload { - action: "insert" | "update" | "delete"; - table: string; - data?: object; - identifierColumnName?: string; - identifierValue?: string; - duplicateColumnName?: string; - duplicateColumnValue?: string; - update?: boolean; -} -/** - * Local-only variant of `PostReturn` used by in-process operations. - */ -export interface LocalPostReturn { - success: boolean; - payload?: any; - msg?: string; - error?: string; -} -/** - * Query object for local write operations that may accept raw SQL or a CRUD - * payload. - */ -export interface LocalPostQueryObject { - query: string | PostDataPayload; - tableName?: string; - queryValues?: string[]; -} -/** - * Insert/update metadata returned by SQL drivers after a write completes. - */ -export interface PostInsertReturn { - fieldCount?: number; - affectedRows?: number; - insertId?: number; - serverStatus?: number; - warningCount?: number; - message?: string; - protocol41?: boolean; - changedRows?: number; - error?: string; -} -/** - * Extended user object used within the application runtime. - */ -export type UserType = DATASQUIREL_LoggedInUser & { - isSuperUser?: boolean; - staticHost?: string; - appHost?: string; - appName?: string; -}; -/** - * Stored API key definition and its associated metadata. - */ -export interface ApiKeyDef { - name: string; - scope: string; - date_created: string; - apiKeyPayload: string; -} -/** - * Aggregate dashboard metrics shown in admin and overview screens. - */ -export interface MetricsType { - dbCount: number; - tablesCount: number; - mediaCount: number; - apiKeysCount: number; -} -/** - * Shape of the internal MariaDB users table. - */ -export interface MYSQL_mariadb_users_table_def { - id?: number; - user_id?: number; - username?: string; - host?: string; - password?: string; - primary?: number; - grants?: string; - date_created?: string; - date_created_code?: number; - date_created_timestamp?: string; - date_updated?: string; - date_updated_code?: number; - date_updated_timestamp?: string; -} -/** - * Credentials used to connect to a MariaDB instance as a specific user. - */ -export interface MariaDBUserCredType { - mariadb_user?: string; - mariadb_host?: string; - mariadb_pass?: string; -} -/** - * Supported logical operators for server-side query generation. - */ -export declare const ServerQueryOperators: readonly ["AND", "OR"]; -/** - * Supported comparison operators for server-side query generation. - */ -export declare const ServerQueryEqualities: readonly ["EQUAL", "LIKE", "LIKE_RAW", "LIKE_LOWER", "LIKE_LOWER_RAW", "NOT LIKE", "NOT LIKE_RAW", "NOT_LIKE_LOWER", "NOT_LIKE_LOWER_RAW", "NOT EQUAL", "REGEXP", "FULLTEXT", "IN", "NOT IN", "BETWEEN", "NOT BETWEEN", "IS NULL", "IS NOT NULL", "IS NOT", "EXISTS", "NOT EXISTS", "GREATER THAN", "GREATER THAN OR EQUAL", "LESS THAN", "LESS THAN OR EQUAL", "MATCH", "MATCH_BOOLEAN"]; -/** - * Top-level query-builder input used to generate SELECT statements, joins, - * grouping, pagination, and full-text search clauses. - */ -export type ServerQueryParam = { - selectFields?: (keyof T | TableSelectFieldsObject)[]; - omitFields?: (keyof T)[]; - query?: ServerQueryQueryObject; - limit?: number; - page?: number; - offset?: number; - order?: ServerQueryParamOrder | ServerQueryParamOrder[]; - searchOperator?: (typeof ServerQueryOperators)[number]; - searchEquality?: (typeof ServerQueryEqualities)[number]; - addUserId?: { - fieldName: keyof T; - }; - join?: (ServerQueryParamsJoin | ServerQueryParamsJoin[] | undefined)[]; - group?: keyof T | ServerQueryParamGroupBy | (keyof T | ServerQueryParamGroupBy)[]; - countSubQueries?: ServerQueryParamsCount[]; - fullTextSearch?: ServerQueryParamFullTextSearch; - /** - * Raw SQL to use as select - */ - [key: string]: any; -}; -/** - * Represents a single `GROUP BY` field, optionally qualified by table name. - */ -export type ServerQueryParamGroupBy = { - field: keyof T; - table?: string; -}; -/** - * Represents a single `ORDER BY` clause. - */ -export type ServerQueryParamOrder = { - field: keyof T; - strategy: "ASC" | "DESC"; -}; -/** - * Configuration for a full-text search query and the alias used for the score - * column. - */ -export type ServerQueryParamFullTextSearch = { - fields: (keyof T)[]; - searchTerm: string; - /** Field Name to user to Rank the Score of Search Results */ - scoreAlias: string; -}; -/** - * Describes a count subquery that is projected into the main SELECT result. - */ -export type ServerQueryParamsCount = { - table: string; - /** Alias for the Table From which the count is fetched */ - table_alias?: string; - srcTrgMap: { - src: string; - trg: string | ServerQueryParamsCountSrcTrgMap; - }[]; - alias: string; -}; -/** - * Source/target mapping used inside count subqueries. - */ -export type ServerQueryParamsCountSrcTrgMap = { - table: string; - field: string; -}; -/** - * Declares a selected field and an optional alias for the result set. - */ -export type TableSelectFieldsObject = { - fieldName: keyof T; - alias?: string; - count?: { - alias?: string; - }; - sum?: boolean; - max?: boolean; - min?: boolean; - average?: boolean; - group_concat?: Omit; - distinct?: boolean; -}; -export type TableSelectFieldsBasicDirective = { - alias: string; -}; -/** - * Value wrapper used when a query condition needs per-value metadata such as a - * custom equality or explicit table/field names. - */ -export type ServerQueryValuesObject = { - value?: string | number; - /** - * Defaults to EQUAL - */ - equality?: (typeof ServerQueryEqualities)[number]; - tableName?: string; - fieldName?: string; -}; -/** - * All value shapes accepted by a query condition, including arrays used by - * operators such as `IN` and `BETWEEN`. - */ -export type ServerQueryObjectValue = string | number | ServerQueryValuesObject | undefined | null | (string | number | ServerQueryValuesObject | undefined | null)[]; -/** - * Describes a single query condition and any nested subconditions for a field. - */ -export type ServerQueryObject = SQLComparisonsParams & { - value?: ServerQueryObjectValue; - nullValue?: boolean; - notNullValue?: boolean; - operator?: (typeof ServerQueryOperators)[number]; - equality?: (typeof ServerQueryEqualities)[number]; - tableName?: K; - /** - * This will replace the top level field name if - * provided - */ - fieldName?: string; - __query?: { - [key: string]: Omit, "__query">; - }; - vector?: boolean; - /** - * ### The Function to be used to generate the vector. - * Eg. `vec_f32`. This will come out as `vec_f32(?)` - * instead of just `?` - */ - vectorFunction?: string; -}; -/** - * Field-to-condition map for server-side query generation. - */ -export type ServerQueryQueryObject = { - [key in keyof T]: ServerQueryObject; -}; -/** - * Parameters for authenticated fetch helpers used by the frontend and internal - * SDK layers. - */ -export type FetchDataParams = { - path: string; - method?: (typeof DataCrudRequestMethods)[number]; - body?: object | string; - query?: AuthFetchQuery; - tableName?: string; -}; -/** - * Query object accepted by authenticated data-fetch helpers. - */ -export type AuthFetchQuery = ServerQueryParam & { - [key: string]: any; -}; -/** - * Join clause definition used by the server query builder. - */ -export type ServerQueryParamsJoin = { - joinType: "INNER JOIN" | "JOIN" | "LEFT JOIN" | "RIGHT JOIN"; - alias?: string; - tableName: Table; - match?: ServerQueryParamsJoinMatchObject | ServerQueryParamsJoinMatchObject[]; - selectFields?: (keyof Field | SelectFieldObject)[]; - omitFields?: (keyof Field | { - field: keyof Field; - alias?: string; - count?: boolean; - })[]; - operator?: (typeof ServerQueryOperators)[number]; - /** - * Raw SQL to use as join select - */ - /** - * Concatenate multiple matches from another table - */ - group_concat?: GroupConcatObject; -}; -export type GroupConcatObject = { - field: string; - alias: string; - /** - * Separator. Default `,` - */ - separator?: string; - distinct?: boolean; -}; -export type SelectFieldObject = { - field: keyof Field; - alias?: string; - count?: boolean; - sum?: boolean; - max?: boolean; - min?: boolean; - average?: boolean; - group_concat?: Pick; - distinct?: boolean; -}; -export declare const SQlComparisons: readonly [">", "<>", "<", "=", ">=", "<=", "!=", "IS NOT", "IS", "IS NULL", "IS NOT NULL", "IN", "NOT IN", "LIKE", "NOT LIKE", "GLOB", "NOT GLOB"]; -export type SQLBetween = { - min: SQLInsertGenValueType; - max: SQLInsertGenValueType; -}; -export type SQLComparisonsParams = { - raw_equality?: (typeof SQlComparisons)[number]; - between?: SQLBetween; - not_between?: SQLBetween; -}; -/** - * Defines how a root-table field maps to a join-table field in an `ON` clause. - */ -export type ServerQueryParamsJoinMatchObject = SQLComparisonsParams & { - /** Field name from the **Root Table** */ - source?: string | ServerQueryParamsJoinMatchSourceTargetObject; - /** Field name from the **Join Table** */ - target?: keyof Field | ServerQueryParamsJoinMatchSourceTargetObject; - /** A literal value: No source and target Needed! */ - targetLiteral?: string | number; - __batch?: { - matches: Omit, "__batch">[]; - operator: "AND" | "OR"; - }; -}; -/** - * Explicit table/field reference for join match definitions. - */ -export type ServerQueryParamsJoinMatchSourceTargetObject = { - tableName: string; - fieldName: string; -}; -/** - * Payload used when pushing or pulling a schema to or from a remote API. - */ -export type ApiConnectBody = { - url: string; - key: string; - database: BUN_MARIADB_MYSQL_user_databases_Type; - dbSchema: BUN_MARIADB_DatabaseSchemaType; - type: "pull" | "push"; - user_id?: string | number; -}; -/** - * Superuser credentials and auth state. - */ -export type SuUserType = { - email: string; - password: string; - authKey: string; - logged_in_status: boolean; - date: number; -}; -/** - * Configuration for a remote MariaDB host in replicated or load-balanced - * setups. - */ -export type MariadbRemoteServerObject = { - host: string; - port: number; - primary?: boolean; - loadBalanced?: boolean; - users?: MariadbRemoteServerUserObject[]; -}; -/** - * Credentials for a user provisioned on a remote MariaDB server. - */ -export type MariadbRemoteServerUserObject = { - name: string; - password: string; - host: string; -}; -/** - * Standard login response returned by API authentication helpers. - */ -export type APILoginFunctionReturn = { - success: boolean; - msg?: string; - payload?: DATASQUIREL_LoggedInUser | null; - userId?: number | string; - key?: string; - token?: string; - csrf?: string; - cookieNames?: any; -}; -/** - * Parameters required to create a user through the public API layer. - */ -export type APICreateUserFunctionParams = { - encryptionKey?: string; - payload: any; - database: string; - dsqlUserID?: string | number; - verify?: boolean; -}; -/** - * Function signature for API user-creation handlers. - */ -export type APICreateUserFunction = (params: APICreateUserFunctionParams) => Promise; -/** - * Result returned when reconciling a social login with the local user store. - */ -export type HandleSocialDbFunctionReturn = { - success: boolean; - user?: DATASQUIREL_LoggedInUser | null; - msg?: string; - social_id?: string | number; - social_platform?: string; - payload?: any; - alert?: boolean; - newUser?: any; - error?: any; -} | null; -/** - * Cookie definition used when setting auth/session cookies. - */ -export type CookieObject = { - name: string; - value: string; - domain?: string; - path?: string; - expires?: Date; - maxAge?: number; - secure?: boolean; - httpOnly?: boolean; - sameSite?: "Strict" | "Lax" | "None"; - priority?: "Low" | "Medium" | "High"; -}; -/** - * Request options accepted by the generic HTTP client helper. - */ -export type HttpRequestParams = RequestOptions & { - scheme?: "http" | "https"; - body?: ReqObj; - query?: ReqObj; - urlEncodedFormBody?: boolean; -}; -/** - * Function signature for the generic HTTP request helper. - */ -export type HttpRequestFunction = (param: HttpRequestParams) => Promise>; -/** - * Normalized response returned by the generic HTTP request helper. - */ -export type HttpFunctionResponse = { - status: number; - data?: ResObj; - error?: string; - str?: string; - requestedPath?: string; -}; -/** - * GET request payload for API data reads. - */ -export type ApiGetQueryObject = { - query: ServerQueryParam; - table: string; - dbFullName?: string; -}; -/** - * Uppercase HTTP methods supported by the CRUD helpers. - */ -export declare const DataCrudRequestMethods: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"]; -/** - * Lowercase variant of the supported HTTP methods, used where string casing - * must match external APIs. - */ -export declare const DataCrudRequestMethodsLowerCase: readonly ["get", "post", "put", "patch", "delete", "options"]; -/** - * Runtime parameters passed to generic CRUD handlers. - */ -export type DsqlMethodCrudParam = { - method: (typeof DataCrudRequestMethods)[number]; - body?: T; - query?: DsqlCrudQueryObject; - tableName: string; - addUser?: { - field: keyof T; - }; - user?: DATASQUIREL_LoggedInUser; - extraData?: T; - transformData?: DsqlCrudTransformDataFunction; - transformQuery?: DsqlCrudTransformQueryFunction; - existingData?: T; - targetId?: string | number; - sanitize?: ({ data, batchData }: { - data?: T; - batchData?: T[]; - }) => T | T[]; - debug?: boolean; -}; -/** - * Hook used to mutate input data before a CRUD action is executed. - */ -export type DsqlCrudTransformDataFunction = (params: { - data: T; - user?: DATASQUIREL_LoggedInUser; - existingData?: T; - reqMethod: (typeof DataCrudRequestMethods)[number]; -}) => Promise; -/** - * Hook used to mutate query input before a CRUD action is executed. - */ -export type DsqlCrudTransformQueryFunction = (params: { - query: DsqlCrudQueryObject; - user?: DATASQUIREL_LoggedInUser; - reqMethod: (typeof DataCrudRequestMethods)[number]; -}) => Promise>; -/** - * High-level CRUD actions supported by the DSQL helpers. - */ -export declare const DsqlCrudActions: readonly ["insert", "update", "delete", "get"]; -/** - * Query object used by CRUD helpers, built on top of the server query builder. - */ -export type DsqlCrudQueryObject = ServerQueryParam & { - query?: ServerQueryQueryObject; -}; -/** - * Parameters used to generate a SQL `DELETE` statement. - */ -export type SQLDeleteGeneratorParams = { - tableName: string; - deleteKeyValues?: SQLDeleteData[]; - deleteKeyValuesOperator?: "AND" | "OR"; - dbFullName?: string; - data?: any; -}; -/** - * Single key/value predicate used by the delete SQL generator. - */ -export type SQLDeleteData = { - key: keyof T; - value: string | number | null | undefined; - operator?: (typeof ServerQueryEqualities)[number]; -}; -/** - * Prebuilt SQL where-clause fragment and its bound parameters. - */ -export type DsqlCrudParamWhereClause = { - clause: string; - params?: string[]; -}; -/** - * Callback signature used when surfacing internal errors to callers. - */ -export type ErrorCallback = (title: string, error: Error, data?: any) => void; -/** - * Reserved query parameter names used throughout the API layer. - */ -export declare const QueryFields: readonly ["duplicate", "user_id", "delegated_user_id", "db_id", "table_id", "db_slug"]; -/** - * Minimal representation of a local folder entry. - */ -export type LocalFolderType = { - name: string; - isPrivate: boolean; -}; -/** - * SQL string and bound parameters produced during query generation. - */ -export type ResponseQueryObject = { - sql?: string; - params?: (string | number)[]; -}; -/** - * Common API response wrapper used by data, auth, media, and utility - * endpoints. - */ -export type APIResponseObject = { - success: boolean; - payload?: T[] | null; - singleRes?: T | null; - stringRes?: string | null; - numberRes?: number | null; - postInsertReturn?: PostInsertReturn | null; - payloadBase64?: string; - payloadThumbnailBase64?: string; - payloadURL?: string; - payloadThumbnailURL?: string; - error?: any; - msg?: string; - queryObject?: ResponseQueryObject; - countQueryObject?: ResponseQueryObject; - status?: number; - count?: number; - errors?: BUNSQLITEErrorObject[]; - debug?: any; - batchPayload?: any[][] | null; - errorData?: any; - token?: string; - csrf?: string; - cookieNames?: any; - key?: string; - userId?: string | number; - code?: string; - createdAt?: number; - email?: string; - requestOptions?: RequestOptions; - logoutUser?: boolean; - redirect?: string; -}; -/** - * # Docker Compose Types - */ -export type DockerCompose = { - services: DockerComposeServicesType; - networks: DockerComposeNetworks; - name: string; -}; -/** - * Supported Docker Compose service names used by the deployment helpers. - */ -export declare const DockerComposeServices: readonly ["setup", "cron", "reverse-proxy", "webapp", "websocket", "static", "db", "maxscale", "post-db-setup", "web-app-post-db-setup", "post-replica-db-setup", "db-replica-1", "db-replica-2", "db-cron", "web-app-post-db-setup"]; -/** - * Map of compose service names to service definitions. - */ -export type DockerComposeServicesType = { - [key in (typeof DockerComposeServices)[number]]: DockerComposeServiceWithBuildObject; -}; -/** - * Docker Compose network definitions. - */ -export type DockerComposeNetworks = { - [k: string]: { - driver?: "bridge"; - ipam?: { - config: DockerComposeNetworkConfigObject[]; - }; - external?: boolean; - }; -}; -/** - * Static network config for a Docker Compose network. - */ -export type DockerComposeNetworkConfigObject = { - subnet: string; - gateway: string; -}; -/** - * Service definition for compose services that are built from source. - */ -export type DockerComposeServiceWithBuildObject = { - build: DockerComposeServicesBuildObject; - env_file: string; - container_name: string; - hostname: string; - volumes: string[]; - environment: string[]; - ports?: string[]; - networks?: DockerComposeServiceNetworkObject; - restart?: string; - depends_on?: { - [k: string]: { - condition: string; - }; - }; - user?: string; -}; -/** - * Service definition for compose services that use a prebuilt image. - */ -export type DockerComposeServiceWithImage = Omit & { - image: string; -}; -/** - * Build instructions for a Docker Compose service. - */ -export type DockerComposeServicesBuildObject = { - context: string; - dockerfile: string; -}; -/** - * Per-network addressing information for a Docker Compose service. - */ -export type DockerComposeServiceNetworkObject = { - [k: string]: { - ipv4_address: string; - }; -}; -/** - * Metadata recorded for a table cloned from another database. - */ -export type ClonedTableInfo = { - dbId?: string | number; - tableId?: string | number; - keepUpdated?: boolean; - keepDataUpdated?: boolean; -}; -/** - * Common columns present on default/generated table entries. - */ -export type DefaultEntryType = { - id?: number; - uuid?: string; - date_created?: string; - date_created_code?: number; - date_created_timestamp?: string; - date_updated?: string; - date_updated_code?: number; - date_updated_timestamp?: string; -} & { - [k: string]: string | number | null; -}; -/** - * Supported index strategies for generated schemas. - */ -export declare const IndexTypes: readonly ["regular", "full_text", "vector"]; -/** - * Structured error payload captured alongside generated SQL. - */ -export type BUNSQLITEErrorObject = { - sql?: string; - sqlValues?: any[]; - error?: string; -}; -/** - * Output of the SQL insert generator. - */ -export interface SQLInsertGenReturn { - query: string; - values: SQLInsertGenValueType[]; -} -/** - * Values accepted by the SQL insert generator, including vector buffers. - */ -export type SQLInsertGenValueType = string | number | Float32Array | Buffer | null; -/** - * Callback variant used when a generated insert value needs a custom - * placeholder. - */ -export type SQLInsertGenDataFn = () => { - placeholder: string; - value: SQLInsertGenValueType; -}; -/** - * Record shape accepted by the SQL insert generator. - */ -export type SQLInsertGenDataType = { - [k: string]: SQLInsertGenValueType | SQLInsertGenDataFn | undefined | null; -}; -/** - * Parameters used to build a multi-row SQL insert statement. - */ -export type SQLInsertGenParams = { - data: SQLInsertGenDataType[]; - tableName: string; - dbFullName?: string; -}; -/** - * Library configuration used to locate the SQLite database, schema file, - * generated types, and backup settings. - */ -export type BunSQLiteConfig = { - db_name: string; - /** - * The Name of the Database Schema File. Eg `db_schema.ts`. This is - * relative to `db_dir`, or root dir if `db_dir` is not provided - */ - db_schema_file_name: string; - /** - * The Directory for backups. Relative to db_dir. - */ - db_backup_dir?: string; - max_backups?: number; - /** - * The Root Directory for the DB file and schema - */ - db_dir?: string; - /** - * The File Path relative to the root(working) directory for the type - * definition export. Example `db_types.ts` or `types/db_types.ts` - */ - typedef_file_path?: string; - /** - * Whether to enable `WAL` mode - */ - wal_mode?: boolean; -}; -/** - * Resolved Bun SQLite config paired with the loaded database schema. - */ -export type BunSQLiteConfigReturn = { - config: BunSQLiteConfig; - dbSchema: BUN_MARIADB_DatabaseSchemaType; -}; -/** - * Default fields automatically suggested for new tables. - */ -export declare const DefaultFields: BUN_MARIADB_FieldSchemaType[]; -export type BunSQLiteQueryFieldValues = { - field: F; - table?: T; -}; -export type QueryRawValueType = string | number | null | undefined; -export type DsqlConnectionParam = { - /** - * No Database Connection - */ - noDb?: boolean; - /** - * Database Name - */ - database?: string; - /** - * Debug - */ - config?: ConnectionConfig; -}; -export type DBResponseObject = { - success: boolean; - payload?: T[]; - single_res?: T; -}; diff --git a/dist/types/index.js b/dist/types/index.js deleted file mode 100644 index dba0d06..0000000 --- a/dist/types/index.js +++ /dev/null @@ -1,187 +0,0 @@ -/** - * User fields that should be omitted from general-purpose payloads and public - * responses. - */ -export const UsersOmitedFields = [ - "password", - "social_id", - "verification_status", - "date_created", - "date_created_code", - "date_created_timestamp", - "date_updated", - "date_updated_code", - "date_updated_timestamp", -]; -/** - * Supported MariaDB collations that can be applied at the database or table - * level. - */ -export const MariaDBCollations = [ - "utf8mb4_bin", - "utf8mb4_unicode_520_ci", -]; -/** - * Supported editor/content modes for text fields. - */ -export const TextFieldTypesArray = [ - { title: "Plain Text", value: "plain" }, - { title: "Rich Text", value: "richText" }, - { title: "Markdown", value: "markdown" }, - { title: "JSON", value: "json" }, - { title: "YAML", value: "yaml" }, - { title: "HTML", value: "html" }, - { title: "CSS", value: "css" }, - { title: "Javascript", value: "javascript" }, - { title: "Shell", value: "shell" }, - { title: "Code", value: "code" }, -]; -/** - * Core SQLite column types supported by the schema builder. - */ -export const BUN_MARIADB_DATATYPES = [ - { value: "TEXT" }, - { value: "INTEGER" }, - { value: "BLOB" }, - { value: "REAL" }, -]; -/** - * Supported logical operators for server-side query generation. - */ -export const ServerQueryOperators = ["AND", "OR"]; -/** - * Supported comparison operators for server-side query generation. - */ -export const ServerQueryEqualities = [ - "EQUAL", - "LIKE", - "LIKE_RAW", - "LIKE_LOWER", - "LIKE_LOWER_RAW", - "NOT LIKE", - "NOT LIKE_RAW", - "NOT_LIKE_LOWER", - "NOT_LIKE_LOWER_RAW", - "NOT EQUAL", - "REGEXP", - "FULLTEXT", - "IN", - "NOT IN", - "BETWEEN", - "NOT BETWEEN", - "IS NULL", - "IS NOT NULL", - "IS NOT", - "EXISTS", - "NOT EXISTS", - "GREATER THAN", - "GREATER THAN OR EQUAL", - "LESS THAN", - "LESS THAN OR EQUAL", - "MATCH", - "MATCH_BOOLEAN", -]; -export const SQlComparisons = [ - ">", - "<>", - "<", - "=", - ">=", - "<=", - "!=", - "IS NOT", - "IS", - "IS NULL", - "IS NOT NULL", - "IN", - "NOT IN", - "LIKE", - "NOT LIKE", - "GLOB", - "NOT GLOB", -]; -/** - * Uppercase HTTP methods supported by the CRUD helpers. - */ -export const DataCrudRequestMethods = [ - "GET", - "POST", - "PUT", - "PATCH", - "DELETE", - "OPTIONS", -]; -/** - * Lowercase variant of the supported HTTP methods, used where string casing - * must match external APIs. - */ -export const DataCrudRequestMethodsLowerCase = [ - "get", - "post", - "put", - "patch", - "delete", - "options", -]; -/** - * High-level CRUD actions supported by the DSQL helpers. - */ -export const DsqlCrudActions = ["insert", "update", "delete", "get"]; -/** - * Reserved query parameter names used throughout the API layer. - */ -export const QueryFields = [ - "duplicate", - "user_id", - "delegated_user_id", - "db_id", - "table_id", - "db_slug", -]; -/** - * Supported Docker Compose service names used by the deployment helpers. - */ -export const DockerComposeServices = [ - "setup", - "cron", - "reverse-proxy", - "webapp", - "websocket", - "static", - "db", - "maxscale", - "post-db-setup", - "web-app-post-db-setup", - "post-replica-db-setup", - "db-replica-1", - "db-replica-2", - "db-cron", - "web-app-post-db-setup", -]; -/** - * Supported index strategies for generated schemas. - */ -export const IndexTypes = ["regular", "full_text", "vector"]; -/** - * Default fields automatically suggested for new tables. - */ -export const DefaultFields = [ - { - fieldName: "id", - dataType: "INTEGER", - primaryKey: true, - autoIncrement: true, - notNullValue: true, - fieldDescription: "The unique identifier of the record.", - }, - { - fieldName: "created_at", - dataType: "INTEGER", - fieldDescription: "The time when the record was created. (Unix Timestamp)", - }, - { - fieldName: "updated_at", - dataType: "INTEGER", - fieldDescription: "The time when the record was updated. (Unix Timestamp)", - }, -]; diff --git a/dist/utils/append-default-fields-to-db-schema.d.ts b/dist/utils/append-default-fields-to-db-schema.d.ts deleted file mode 100644 index 9d031fc..0000000 --- a/dist/utils/append-default-fields-to-db-schema.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { type BUN_MARIADB_DatabaseSchemaType } from "../types"; -type Params = { - dbSchema: BUN_MARIADB_DatabaseSchemaType; -}; -export default function ({ dbSchema }: Params): BUN_MARIADB_DatabaseSchemaType; -export {}; diff --git a/dist/utils/append-default-fields-to-db-schema.js b/dist/utils/append-default-fields-to-db-schema.js deleted file mode 100644 index d1b758a..0000000 --- a/dist/utils/append-default-fields-to-db-schema.js +++ /dev/null @@ -1,12 +0,0 @@ -import _ from "lodash"; -import { DefaultFields } from "../types"; -export default function ({ dbSchema }) { - const finaldbSchema = _.cloneDeep(dbSchema); - finaldbSchema.tables = finaldbSchema.tables.map((t) => { - const newTable = _.cloneDeep(t); - newTable.fields = newTable.fields.filter((f) => !f.fieldName?.match(/^(id|created_at|updated_at)$/)); - newTable.fields.unshift(...DefaultFields); - return newTable; - }); - return finaldbSchema; -} diff --git a/dist/utils/grab-backup-data.d.ts b/dist/utils/grab-backup-data.d.ts deleted file mode 100644 index 04cd991..0000000 --- a/dist/utils/grab-backup-data.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -type Params = { - backup_name: string; -}; -export default function grabBackupData({ backup_name }: Params): { - backup_date: Date; - backup_date_timestamp: number; - origin_backup_name: string; -}; -export {}; diff --git a/dist/utils/grab-backup-data.js b/dist/utils/grab-backup-data.js deleted file mode 100644 index 84439d3..0000000 --- a/dist/utils/grab-backup-data.js +++ /dev/null @@ -1,7 +0,0 @@ -export default function grabBackupData({ backup_name }) { - const backup_parts = backup_name.split("-"); - const backup_date_timestamp = Number(backup_parts.pop()); - const origin_backup_name = backup_parts.join("-"); - const backup_date = new Date(backup_date_timestamp); - return { backup_date, backup_date_timestamp, origin_backup_name }; -} diff --git a/dist/utils/grab-db-backup-file-name.d.ts b/dist/utils/grab-db-backup-file-name.d.ts deleted file mode 100644 index 3744de0..0000000 --- a/dist/utils/grab-db-backup-file-name.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { BunSQLiteConfig } from "../types"; -type Params = { - config: BunSQLiteConfig; -}; -export default function grabDBBackupFileName({ config }: Params): string; -export {}; diff --git a/dist/utils/grab-db-backup-file-name.js b/dist/utils/grab-db-backup-file-name.js deleted file mode 100644 index 30c72fc..0000000 --- a/dist/utils/grab-db-backup-file-name.js +++ /dev/null @@ -1,4 +0,0 @@ -export default function grabDBBackupFileName({ config }) { - const new_db_file_name = `${config.db_name}-${Date.now()}`; - return new_db_file_name; -} diff --git a/dist/utils/grab-db-dir.d.ts b/dist/utils/grab-db-dir.d.ts deleted file mode 100644 index b01b221..0000000 --- a/dist/utils/grab-db-dir.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { BunSQLiteConfig } from "../types"; -type Params = { - config: BunSQLiteConfig; -}; -export default function grabDBDir({ config }: Params): { - db_dir: string; - backup_dir: string; - db_file_path: string; -}; -export {}; diff --git a/dist/utils/grab-db-dir.js b/dist/utils/grab-db-dir.js deleted file mode 100644 index 89f5a77..0000000 --- a/dist/utils/grab-db-dir.js +++ /dev/null @@ -1,14 +0,0 @@ -import path from "path"; -import grabDirNames from "../data/grab-dir-names"; -import { AppData } from "../data/app-data"; -export default function grabDBDir({ config }) { - const { ROOT_DIR } = grabDirNames(); - let db_dir = ROOT_DIR; - if (config.db_dir) { - db_dir = config.db_dir; - } - const backup_dir_name = config.db_backup_dir || AppData["DefaultBackupDirName"]; - const backup_dir = path.resolve(db_dir, backup_dir_name); - const db_file_path = path.resolve(db_dir, config.db_name); - return { db_dir, backup_dir, db_file_path }; -} diff --git a/dist/utils/grab-db-schema.d.ts b/dist/utils/grab-db-schema.d.ts deleted file mode 100644 index c80395a..0000000 --- a/dist/utils/grab-db-schema.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function grabDbSchema(): Promise; diff --git a/dist/utils/grab-db-schema.js b/dist/utils/grab-db-schema.js deleted file mode 100644 index 4780edb..0000000 --- a/dist/utils/grab-db-schema.js +++ /dev/null @@ -1,5 +0,0 @@ -import init from "../functions/init"; -export default async function grabDbSchema() { - const { dbSchema } = await init(); - return dbSchema; -} diff --git a/dist/utils/grab-join-fields-from-query-object.d.ts b/dist/utils/grab-join-fields-from-query-object.d.ts deleted file mode 100644 index dd16a58..0000000 --- a/dist/utils/grab-join-fields-from-query-object.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { BunSQLiteQueryFieldValues, ServerQueryParam } from "../types"; -type Params = Record> = { - query: ServerQueryParam; - ignore_select_fields?: boolean; -}; -export default function grabJoinFieldsFromQueryObject = Record, F extends string = string, T extends string = string>({ query, ignore_select_fields, }: Params): BunSQLiteQueryFieldValues[]; -export {}; diff --git a/dist/utils/grab-join-fields-from-query-object.js b/dist/utils/grab-join-fields-from-query-object.js deleted file mode 100644 index 2672c70..0000000 --- a/dist/utils/grab-join-fields-from-query-object.js +++ /dev/null @@ -1,55 +0,0 @@ -import _ from "lodash"; -export default function grabJoinFieldsFromQueryObject({ query, ignore_select_fields, }) { - const fields_values = []; - const new_query = _.cloneDeep(query); - if (new_query.join) { - for (let i = 0; i < new_query.join.length; i++) { - const join = new_query.join[i]; - if (!join) - continue; - if (Array.isArray(join)) { - for (let i = 0; i < join.length; i++) { - const single_join = join[i]; - fields_values.push(...grabSingleJoinData({ - join: single_join, - ignore_select_fields, - })); - } - } - else { - fields_values.push(...grabSingleJoinData({ - join: join, - ignore_select_fields, - })); - } - } - } - return fields_values; -} -function grabSingleJoinData({ join, ignore_select_fields, }) { - let values = []; - const join_select_fields = join?.selectFields; - if (!join_select_fields?.[0] && !ignore_select_fields) { - throw new Error(`\`selectFields\` required in joins. To ignore this error, pass the \`ignore_select_fields\` parameter`); - } - if (join_select_fields?.[0]) { - for (let i = 0; i < join_select_fields.length; i++) { - const select_field = join_select_fields[i]; - if (select_field) { - values.push({ - table: join.tableName, - field: typeof select_field == "object" - ? String(select_field.field) - : String(select_field), - }); - } - } - } - if (join.group_concat) { - values.push({ - table: join.tableName, - field: join.group_concat.field, - }); - } - return values; -} diff --git a/dist/utils/grab-sorted-backups.d.ts b/dist/utils/grab-sorted-backups.d.ts deleted file mode 100644 index 9c13c1b..0000000 --- a/dist/utils/grab-sorted-backups.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { BunSQLiteConfig } from "../types"; -type Params = { - config: BunSQLiteConfig; -}; -export default function grabSortedBackups({ config }: Params): string[]; -export {}; diff --git a/dist/utils/grab-sorted-backups.js b/dist/utils/grab-sorted-backups.js deleted file mode 100644 index 0318bb7..0000000 --- a/dist/utils/grab-sorted-backups.js +++ /dev/null @@ -1,18 +0,0 @@ -import grabDBDir from "../utils/grab-db-dir"; -import fs from "fs"; -export default function grabSortedBackups({ config }) { - const { backup_dir } = grabDBDir({ config }); - const backups = fs.readdirSync(backup_dir); - /** - * Order Backups. Most recent first. - */ - const ordered_backups = backups.sort((a, b) => { - const a_date = Number(a.split("-").pop()); - const b_date = Number(b.split("-").pop()); - if (a_date > b_date) { - return -1; - } - return 1; - }); - return ordered_backups; -} diff --git a/dist/utils/query-value-parser.d.ts b/dist/utils/query-value-parser.d.ts deleted file mode 100644 index bf5460c..0000000 --- a/dist/utils/query-value-parser.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { QueryRawValueType, ServerQueryObjectValue } from "../types"; -type Params = { - query_value: ServerQueryObjectValue; -}; -export default function queryValueParser({ query_value, }: Params): QueryRawValueType | QueryRawValueType[]; -export {}; diff --git a/dist/utils/query-value-parser.js b/dist/utils/query-value-parser.js deleted file mode 100644 index dfa68ea..0000000 --- a/dist/utils/query-value-parser.js +++ /dev/null @@ -1,21 +0,0 @@ -export default function queryValueParser({ query_value, }) { - if (typeof query_value == "string" || typeof query_value == "number") { - return query_value; - } - if (Array.isArray(query_value)) { - let values = []; - for (let i = 0; i < query_value.length; i++) { - const single_value = query_value[i]; - if (single_value) { - const single_parsed_value = queryValueParser({ - query_value: single_value, - }); - if (!Array.isArray(single_parsed_value)) { - values.push(single_parsed_value); - } - } - } - return values; - } - return query_value?.value; -} diff --git a/dist/utils/sql-equality-parser.d.ts b/dist/utils/sql-equality-parser.d.ts deleted file mode 100644 index cd5a253..0000000 --- a/dist/utils/sql-equality-parser.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { ServerQueryEqualities } from "../types"; -export default function sqlEqualityParser(eq: (typeof ServerQueryEqualities)[number]): string; diff --git a/dist/utils/sql-equality-parser.js b/dist/utils/sql-equality-parser.js deleted file mode 100644 index 77dc7a9..0000000 --- a/dist/utils/sql-equality-parser.js +++ /dev/null @@ -1,41 +0,0 @@ -import { ServerQueryEqualities } from "../types"; -export default function sqlEqualityParser(eq) { - switch (eq) { - case "EQUAL": - return "="; - case "LIKE": - return "LIKE"; - case "NOT LIKE": - return "NOT LIKE"; - case "NOT EQUAL": - return "<>"; - case "IS NOT": - return "IS NOT"; - case "IN": - return "IN"; - case "NOT IN": - return "NOT IN"; - case "BETWEEN": - return "BETWEEN"; - case "NOT BETWEEN": - return "NOT BETWEEN"; - case "IS NULL": - return "IS NULL"; - case "IS NOT NULL": - return "IS NOT NULL"; - case "EXISTS": - return "EXISTS"; - case "NOT EXISTS": - return "NOT EXISTS"; - case "GREATER THAN": - return ">"; - case "GREATER THAN OR EQUAL": - return ">="; - case "LESS THAN": - return "<"; - case "LESS THAN OR EQUAL": - return "<="; - default: - return "="; - } -} diff --git a/dist/utils/sql-gen-operator-gen.d.ts b/dist/utils/sql-gen-operator-gen.d.ts deleted file mode 100644 index d6adb66..0000000 --- a/dist/utils/sql-gen-operator-gen.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { ServerQueryEqualities, ServerQueryObject, SQLInsertGenValueType } from "../types"; -type Params = { - fieldName: string; - value?: SQLInsertGenValueType; - equality?: (typeof ServerQueryEqualities)[number]; - queryObj: ServerQueryObject<{ - [key: string]: any; - }, string>; - isValueFieldValue?: boolean; -}; -type Return = { - str?: string; - param?: SQLInsertGenValueType; -}; -/** - * # SQL Gen Operator Gen - * @description Generates an SQL operator for node module `mysql` or `serverless-mysql` - */ -export default function sqlGenOperatorGen({ fieldName, value, equality, queryObj, isValueFieldValue, }: Params): Return; -export {}; diff --git a/dist/utils/sql-gen-operator-gen.js b/dist/utils/sql-gen-operator-gen.js deleted file mode 100644 index 9e23fc4..0000000 --- a/dist/utils/sql-gen-operator-gen.js +++ /dev/null @@ -1,133 +0,0 @@ -import sqlEqualityParser from "./sql-equality-parser"; -/** - * # SQL Gen Operator Gen - * @description Generates an SQL operator for node module `mysql` or `serverless-mysql` - */ -export default function sqlGenOperatorGen({ fieldName, value, equality, queryObj, isValueFieldValue, }) { - if (queryObj.nullValue) { - return { str: `${fieldName} IS NULL` }; - } - if (queryObj.notNullValue) { - return { str: `${fieldName} IS NOT NULL` }; - } - if (value) { - const finalValue = isValueFieldValue ? value : "?"; - const finalParams = isValueFieldValue ? undefined : value; - if (equality == "MATCH") { - return { - str: `MATCH(${fieldName}) AGAINST(${finalValue} IN NATURAL LANGUAGE MODE)`, - param: finalParams, - }; - } - else if (equality == "MATCH_BOOLEAN") { - return { - str: `MATCH(${fieldName}) AGAINST(${finalValue} IN BOOLEAN MODE)`, - param: finalParams, - }; - } - else if (equality == "LIKE_LOWER") { - return { - str: `LOWER(${fieldName}) LIKE LOWER(${finalValue})`, - param: `%${finalParams}%`, - }; - } - else if (equality == "LIKE_LOWER_RAW") { - return { - str: `LOWER(${fieldName}) LIKE LOWER(${finalValue})`, - param: finalParams, - }; - } - else if (equality == "LIKE") { - return { - str: `${fieldName} LIKE ${finalValue}`, - param: `%${finalParams}%`, - }; - } - else if (equality == "LIKE_RAW") { - return { - str: `${fieldName} LIKE ${finalValue}`, - param: finalParams, - }; - } - else if (equality == "NOT_LIKE_LOWER") { - return { - str: `LOWER(${fieldName}) NOT LIKE LOWER(${finalValue})`, - param: `%${finalParams}%`, - }; - } - else if (equality == "NOT_LIKE_LOWER_RAW") { - return { - str: `LOWER(${fieldName}) NOT LIKE LOWER(${finalValue})`, - param: finalParams, - }; - } - else if (equality == "NOT LIKE") { - return { - str: `${fieldName} NOT LIKE ${finalValue}`, - param: finalParams, - }; - } - else if (equality == "NOT LIKE_RAW") { - return { - str: `${fieldName} NOT LIKE ${finalValue}`, - param: finalParams, - }; - } - else if (equality == "REGEXP") { - return { - str: `LOWER(${fieldName}) REGEXP LOWER(${finalValue})`, - param: finalParams, - }; - } - else if (equality == "FULLTEXT") { - return { - str: `MATCH(${fieldName}) AGAINST(${finalValue} IN BOOLEAN MODE)`, - param: finalParams, - }; - } - else if (equality == "NOT EQUAL") { - return { - str: `${fieldName} != ${finalValue}`, - param: finalParams, - }; - } - else if (equality == "IS NOT") { - return { - str: `${fieldName} IS NOT ${finalValue}`, - param: finalParams, - }; - } - else if (equality) { - return { - str: `${fieldName} ${sqlEqualityParser(equality)} ${finalValue}`, - param: finalParams, - }; - } - else { - return { - str: `${fieldName} = ${finalValue}`, - param: finalParams, - }; - } - } - else { - if (equality == "IS NULL") { - return { str: `${fieldName} IS NULL` }; - } - else if (equality == "IS NOT NULL") { - return { str: `${fieldName} IS NOT NULL` }; - } - else if (equality) { - return { - str: `${fieldName} ${sqlEqualityParser(equality)} ?`, - param: value, - }; - } - else { - return { - str: `${fieldName} = ?`, - param: value, - }; - } - } -} diff --git a/dist/utils/sql-generator-gen-join-str.d.ts b/dist/utils/sql-generator-gen-join-str.d.ts deleted file mode 100644 index 5dbf8cb..0000000 --- a/dist/utils/sql-generator-gen-join-str.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { ServerQueryParamsJoin, ServerQueryParamsJoinMatchObject, SQLInsertGenValueType } from "../types"; -type Param = { - mtch: ServerQueryParamsJoinMatchObject; - join: ServerQueryParamsJoin; - table_name: string; -}; -export default function sqlGenGenJoinStr({ join, mtch, table_name }: Param): { - str: string; - values: SQLInsertGenValueType[]; -}; -export {}; diff --git a/dist/utils/sql-generator-gen-join-str.js b/dist/utils/sql-generator-gen-join-str.js deleted file mode 100644 index 0120afa..0000000 --- a/dist/utils/sql-generator-gen-join-str.js +++ /dev/null @@ -1,65 +0,0 @@ -export default function sqlGenGenJoinStr({ join, mtch, table_name }) { - let values = []; - if (mtch.__batch) { - let btch_mtch = ``; - btch_mtch += `(`; - for (let i = 0; i < mtch.__batch.matches.length; i++) { - const __mtch = mtch.__batch.matches[i]; - const { str, values: batch_values } = sqlGenGenJoinStr({ - join, - mtch: __mtch, - table_name, - }); - btch_mtch += str; - values.push(...batch_values); - if (i < mtch.__batch.matches.length - 1) { - btch_mtch += ` ${mtch.__batch.operator || "OR"} `; - } - } - btch_mtch += `)`; - return { - str: btch_mtch, - values, - }; - } - const equality = mtch.raw_equality || "="; - const lhs = `${typeof mtch.source == "object" ? mtch.source.tableName : table_name}.${typeof mtch.source == "object" ? mtch.source.fieldName : mtch.source}`; - const rhs = `${(() => { - if (mtch.targetLiteral) { - values.push(mtch.targetLiteral); - // if (typeof mtch.targetLiteral == "number") { - // return `${mtch.targetLiteral}`; - // } - // return `'${mtch.targetLiteral}'`; - return `?`; - } - if (join.alias) { - return `${typeof mtch.target == "object" - ? mtch.target.tableName - : join.alias}.${typeof mtch.target == "object" - ? mtch.target.fieldName - : mtch.target}`; - } - return `${typeof mtch.target == "object" - ? mtch.target.tableName - : join.tableName}.${typeof mtch.target == "object" ? mtch.target.fieldName : mtch.target}`; - })()}`; - if (mtch.between) { - values.push(mtch.between.min, mtch.between.max); - return { - str: `${lhs} BETWEEN ? AND ?`, - values, - }; - } - if (mtch.not_between) { - values.push(mtch.not_between.min, mtch.not_between.max); - return { - str: `${lhs} NOT BETWEEN ? AND ?`, - values, - }; - } - return { - str: `${lhs} ${equality} ${rhs}`, - values, - }; -} diff --git a/dist/utils/sql-generator-gen-query-str.d.ts b/dist/utils/sql-generator-gen-query-str.d.ts deleted file mode 100644 index 886d00a..0000000 --- a/dist/utils/sql-generator-gen-query-str.d.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { ServerQueryParam, TableSelectFieldsObject } from "../types"; -type Param = { - genObject?: ServerQueryParam; - selectFields?: (keyof T | TableSelectFieldsObject)[]; - append_table_names?: boolean; - table_name: string; - full_text_match_str?: string; - full_text_search_str?: string; -}; -export default function sqlGenGenQueryStr(params: Param): { - str: string; - values: any[]; -}; -export {}; diff --git a/dist/utils/sql-generator-gen-query-str.js b/dist/utils/sql-generator-gen-query-str.js deleted file mode 100644 index 16fa389..0000000 --- a/dist/utils/sql-generator-gen-query-str.js +++ /dev/null @@ -1,193 +0,0 @@ -import { isUndefined } from "lodash"; -import sqlGenGrabConcatStr from "./sql-generator-grab-concat-str"; -import sqlGenGenJoinStr from "./sql-generator-gen-join-str"; -import sqlGenGrabSelectFieldSQL from "./sql-generator-grab-select-field-sql"; -export default function sqlGenGenQueryStr(params) { - let str = "SELECT"; - const genObject = params.genObject; - const table_name = params.table_name; - const full_text_match_str = params.full_text_match_str; - const full_text_search_str = params.full_text_search_str; - let sqlSearhValues = []; - if (genObject?.select_sql) { - str += ` ${genObject.select_sql}`; - } - else if (genObject?.selectFields?.[0]) { - if (genObject.join) { - str += sqlGenGrabSelectFieldSQL({ - selectFields: genObject.selectFields, - append_table_names: true, - table_name, - }); - } - else { - str += sqlGenGrabSelectFieldSQL({ - selectFields: genObject.selectFields, - table_name, - }); - } - } - else { - if (genObject?.join) { - str += ` ${table_name}.*`; - } - else { - str += " *"; - } - } - if (genObject?.countSubQueries) { - let countSqls = []; - for (let i = 0; i < genObject.countSubQueries.length; i++) { - const countSubQuery = genObject.countSubQueries[i]; - if (!countSubQuery) - continue; - const tableAlias = countSubQuery.table_alias; - let subQStr = `(SELECT COUNT(*)`; - subQStr += ` FROM ${countSubQuery.table}${tableAlias ? ` ${tableAlias}` : ""}`; - subQStr += ` WHERE (`; - for (let j = 0; j < countSubQuery.srcTrgMap.length; j++) { - const csqSrc = countSubQuery.srcTrgMap[j]; - if (!csqSrc) - continue; - subQStr += ` ${tableAlias || countSubQuery.table}.${csqSrc.src}`; - if (typeof csqSrc.trg == "string") { - subQStr += ` = ?`; - sqlSearhValues.push(csqSrc.trg); - } - else if (typeof csqSrc.trg == "object") { - subQStr += ` = ${csqSrc.trg.table}.${csqSrc.trg.field}`; - } - if (j < countSubQuery.srcTrgMap.length - 1) { - subQStr += ` AND `; - } - } - subQStr += ` )) AS ${countSubQuery.alias}`; - countSqls.push(subQStr); - } - str += `, ${countSqls.join(",")}`; - } - if (genObject?.join) { - const existingJoinTableNames = [table_name]; - str += - "," + - genObject.join - .flat() - .filter((j) => !isUndefined(j)) - .map((joinObj) => { - const joinTableName = joinObj.alias - ? joinObj.alias - : joinObj.tableName; - if (existingJoinTableNames.includes(joinTableName)) - return null; - existingJoinTableNames.push(joinTableName); - if (joinObj.group_concat) { - return sqlGenGrabConcatStr({ - field: `${joinTableName}.${joinObj.group_concat.field}`, - alias: joinObj.group_concat.alias, - separator: joinObj.group_concat.separator, - }); - } - else if (joinObj.selectFields) { - return joinObj.selectFields - .map((selectField) => { - if (typeof selectField == "string") { - return `${joinTableName}.${selectField}`; - } - else if (typeof selectField == "object") { - let aliasSelectField = `${joinTableName}.${selectField.field}`; - if (selectField.count) { - aliasSelectField = `COUNT(${joinTableName}.${selectField.field})`; - } - else if (selectField.sum) { - aliasSelectField = `SUM(${selectField.distinct ? "DISTINCT " : ""}${joinTableName}.${selectField.field})`; - } - else if (selectField.average) { - aliasSelectField = `AVERAGE(${joinTableName}.${selectField.field})`; - } - else if (selectField.max) { - aliasSelectField = `MAX(${joinTableName}.${selectField.field})`; - } - else if (selectField.min) { - aliasSelectField = `MIN(${joinTableName}.${selectField.field})`; - } - else if (selectField.group_concat && - selectField.alias) { - return sqlGenGrabConcatStr({ - field: `${joinTableName}.${selectField.field}`, - alias: selectField.alias, - separator: selectField.group_concat - .separator, - distinct: selectField.group_concat - .distinct, - }); - } - else if (selectField.distinct) { - aliasSelectField = `DISTINCT ${joinTableName}.${selectField.field}`; - } - if (selectField.alias) - aliasSelectField += ` AS ${selectField.alias}`; - return aliasSelectField; - } - }) - .join(","); - } - else { - return `${joinTableName}.*`; - } - }) - .filter((_) => Boolean(_)) - .join(","); - } - if (genObject?.fullTextSearch && - full_text_match_str && - full_text_search_str) { - str += `, ${full_text_match_str} AS ${genObject.fullTextSearch.scoreAlias}`; - sqlSearhValues.push(full_text_search_str); - } - str += ` FROM ${table_name}`; - if (genObject?.join) { - str += - " " + - genObject.join - .flat() - .filter((j) => !isUndefined(j)) - .map((join) => { - return (join.joinType + - " " + - (join.alias - ? `${join.tableName}` + " " + join.alias - : `${join.tableName}`) + - " ON " + - (() => { - if (Array.isArray(join.match)) { - return ("(" + - join.match - .map((mtch) => { - const { str, values } = sqlGenGenJoinStr({ - mtch, - join, - table_name, - }); - sqlSearhValues.push(...values); - return str; - }) - .join(join.operator - ? ` ${join.operator} ` - : " AND ") + - ")"); - } - else if (typeof join.match == "object") { - const { str, values } = sqlGenGenJoinStr({ - mtch: join.match, - join, - table_name, - }); - sqlSearhValues.push(...values); - return str; - } - })()); - }) - .join(" "); - } - return { str, values: sqlSearhValues }; -} diff --git a/dist/utils/sql-generator-gen-search-str.d.ts b/dist/utils/sql-generator-gen-search-str.d.ts deleted file mode 100644 index 563daf8..0000000 --- a/dist/utils/sql-generator-gen-search-str.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { ServerQueryParamsJoin, ServerQueryQueryObject, SQLInsertGenValueType } from "../types"; -type Param = { - queryObj: ServerQueryQueryObject[string]; - join?: (ServerQueryParamsJoin | ServerQueryParamsJoin[] | undefined)[]; - field?: string; - table_name: string; -}; -export default function sqlGenGenSearchStr({ queryObj, join, field, table_name, }: Param): { - str: string; - values: SQLInsertGenValueType[]; -}; -export {}; diff --git a/dist/utils/sql-generator-gen-search-str.js b/dist/utils/sql-generator-gen-search-str.js deleted file mode 100644 index e7cf269..0000000 --- a/dist/utils/sql-generator-gen-search-str.js +++ /dev/null @@ -1,92 +0,0 @@ -import sqlGenOperatorGen from "./sql-gen-operator-gen"; -export default function sqlGenGenSearchStr({ queryObj, join, field, table_name, }) { - let sqlSearhValues = []; - const finalFieldName = (() => { - if (queryObj?.tableName) { - return `${queryObj.tableName}.${field}`; - } - if (join) { - return `${table_name}.${field}`; - } - return field; - })(); - let str = `${finalFieldName}=?`; - function grabValue(val) { - const valueParsed = val; - if (!valueParsed) - return; - const valueString = typeof valueParsed == "string" || typeof valueParsed == "number" - ? valueParsed - : valueParsed - ? valueParsed.fieldName && valueParsed.tableName - ? `${valueParsed.tableName}.${valueParsed.fieldName}` - : valueParsed.value - : undefined; - const valueEquality = typeof valueParsed == "object" - ? valueParsed.equality || queryObj.equality - : queryObj.equality; - const operatorStrParam = sqlGenOperatorGen({ - queryObj, - equality: valueEquality, - fieldName: finalFieldName || "", - value: valueString || "", - isValueFieldValue: Boolean(typeof valueParsed == "object" && - valueParsed.fieldName && - valueParsed.tableName), - }); - return operatorStrParam; - } - if (Array.isArray(queryObj.value)) { - const strArray = []; - queryObj.value.forEach((val) => { - const operatorStrParam = grabValue(val); - if (!operatorStrParam) - return; - if (operatorStrParam.str && operatorStrParam.param) { - strArray.push(operatorStrParam.str); - sqlSearhValues.push(operatorStrParam.param); - } - else if (operatorStrParam.str) { - strArray.push(operatorStrParam.str); - } - }); - str = "(" + strArray.join(` ${queryObj.operator || "AND"} `) + ")"; - } - else if (typeof queryObj.value == "object") { - const operatorStrParam = grabValue(queryObj.value); - if (operatorStrParam?.str) { - str = operatorStrParam.str; - if (operatorStrParam.param) { - sqlSearhValues.push(operatorStrParam.param); - } - } - } - else if (queryObj.raw_equality && queryObj.value) { - str = `${finalFieldName} ${queryObj.raw_equality} ?`; - sqlSearhValues.push(queryObj.value); - } - else if (queryObj.between) { - str = `${finalFieldName} BETWEEN ? AND ?`; - sqlSearhValues.push(queryObj.between.min, queryObj.between.max); - } - else { - const valueParsed = queryObj.value ? queryObj.value : undefined; - const operatorStrParam = sqlGenOperatorGen({ - equality: queryObj.equality, - fieldName: finalFieldName || "", - value: valueParsed, - queryObj, - }); - if (operatorStrParam.str && operatorStrParam.param) { - str = operatorStrParam.str; - sqlSearhValues.push(operatorStrParam.param); - } - else if (operatorStrParam.str && !operatorStrParam.str.match(/\?/)) { - str = operatorStrParam.str; - } - else { - sqlSearhValues.push(valueParsed || ""); - } - } - return { str, values: sqlSearhValues }; -} diff --git a/dist/utils/sql-generator-grab-concat-str.d.ts b/dist/utils/sql-generator-grab-concat-str.d.ts deleted file mode 100644 index 3eb39c7..0000000 --- a/dist/utils/sql-generator-grab-concat-str.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -type Param = { - field: string; - alias: string; - separator?: string; - distinct?: boolean; -}; -export default function sqlGenGrabConcatStr({ alias, field, separator, distinct, }: Param): string; -export {}; diff --git a/dist/utils/sql-generator-grab-concat-str.js b/dist/utils/sql-generator-grab-concat-str.js deleted file mode 100644 index 8993f00..0000000 --- a/dist/utils/sql-generator-grab-concat-str.js +++ /dev/null @@ -1,13 +0,0 @@ -export default function sqlGenGrabConcatStr({ alias, field, separator = ",", distinct, }) { - let gc = `GROUP_CONCAT(`; - if (distinct) { - gc += `DISTINCT `; - } - gc += `${field}`; - if (!distinct) { - gc += `, '${separator}'`; - } - gc += `)`; - gc += ` AS ${alias}`; - return gc; -} diff --git a/dist/utils/sql-generator-grab-select-field-sql.d.ts b/dist/utils/sql-generator-grab-select-field-sql.d.ts deleted file mode 100644 index 83d13cc..0000000 --- a/dist/utils/sql-generator-grab-select-field-sql.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { TableSelectFieldsObject } from "../types"; -type Param = { - selectFields: (keyof T | TableSelectFieldsObject)[]; - append_table_names?: boolean; - table_name: string; -}; -export default function sqlGenGrabSelectFieldSQL({ selectFields, append_table_names, table_name }: Param): string; -export {}; diff --git a/dist/utils/sql-generator-grab-select-field-sql.js b/dist/utils/sql-generator-grab-select-field-sql.js deleted file mode 100644 index 4056788..0000000 --- a/dist/utils/sql-generator-grab-select-field-sql.js +++ /dev/null @@ -1,55 +0,0 @@ -import sqlGenGrabConcatStr from "./sql-generator-grab-concat-str"; -export default function sqlGenGrabSelectFieldSQL({ selectFields, append_table_names, table_name }) { - let str = ""; - str += ` ${selectFields - ?.map((fld) => { - let fld_str = ``; - const final_fld_name = typeof fld == "object" - ? append_table_names - ? `${table_name}.${String(fld)}` - : `${String(fld.fieldName)}` - : `${String(fld)}`; - if (typeof fld == "object") { - const fld_name = `${String(fld.fieldName)}`; - if (fld.count) { - fld_str += `COUNT(${fld_name})`; - } - else if (fld.sum) { - fld_str += `SUM(${fld_name})`; - } - else if (fld.average) { - fld_str += `AVERAGE(${fld_name})`; - } - else if (fld.max) { - fld_str += `MAX(${fld_name})`; - } - else if (fld.min) { - fld_str += `MIN(${fld_name})`; - } - else if (fld.distinct) { - fld_str += `DISTINCT ${fld_name}`; - } - else if (fld.group_concat) { - fld_str += sqlGenGrabConcatStr({ - field: fld_name, - alias: fld.group_concat.alias, - separator: fld.group_concat.separator, - distinct: fld.group_concat.distinct, - }); - } - else { - fld_str += - final_fld_name + (fld.alias ? ` as ${fld.alias}` : ``); - } - if (fld.alias) { - fld_str += ` AS ${fld.alias}`; - } - } - else { - fld_str += final_fld_name; - } - return fld_str; - }) - .join(",")}`; - return str; -} diff --git a/dist/utils/sql-generator.d.ts b/dist/utils/sql-generator.d.ts deleted file mode 100644 index b6eea8f..0000000 --- a/dist/utils/sql-generator.d.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { ServerQueryParam, SQLInsertGenValueType } from "../types"; -type Param = { - genObject?: ServerQueryParam; - tableName: string; - dbFullName?: string; - count?: boolean; -}; -type Return = { - string: string; - values: SQLInsertGenValueType[]; -}; -/** - * # SQL Query Generator - * @description Generates an SQL Query for node module `mysql` or `serverless-mysql` - */ -export default function sqlGenerator({ tableName, genObject, dbFullName, count }: Param): Return; -export {}; diff --git a/dist/utils/sql-generator.js b/dist/utils/sql-generator.js deleted file mode 100644 index 16aa373..0000000 --- a/dist/utils/sql-generator.js +++ /dev/null @@ -1,303 +0,0 @@ -import sqlGenGenSearchStr from "./sql-generator-gen-search-str"; -import sqlGenGenQueryStr from "./sql-generator-gen-query-str"; -/** - * # SQL Query Generator - * @description Generates an SQL Query for node module `mysql` or `serverless-mysql` - */ -export default function sqlGenerator({ tableName, genObject, dbFullName, count }) { - const finalQuery = genObject?.query ? genObject.query : undefined; - const queryKeys = finalQuery ? Object.keys(finalQuery) : undefined; - const sqlSearhValues = []; - let fullTextMatchStr = genObject?.fullTextSearch - ? ` MATCH(${genObject.fullTextSearch.fields - .map((f) => genObject.join ? `${tableName}.${String(f)}` : `${String(f)}`) - .join(",")}) AGAINST (? IN BOOLEAN MODE)` - : undefined; - const fullTextSearchStr = genObject?.fullTextSearch - ? genObject.fullTextSearch.searchTerm - .split(` `) - .map((t) => `${t}`) - .join(" ") - : undefined; - let { str: queryString, values } = sqlGenGenQueryStr({ - table_name: tableName, - append_table_names: true, - full_text_match_str: fullTextMatchStr, - full_text_search_str: fullTextSearchStr, - genObject, - }); - sqlSearhValues.push(...values); - const sqlSearhString = queryKeys?.map((field) => { - const queryObj = finalQuery?.[field]; - if (!queryObj) - return; - if (queryObj.__query) { - const subQueryGroup = queryObj.__query; - const subSearchKeys = Object.keys(subQueryGroup); - const subSearchString = subSearchKeys.map((_field) => { - const newSubQueryObj = subQueryGroup?.[_field]; - if (newSubQueryObj) { - const { str, values } = sqlGenGenSearchStr({ - queryObj: newSubQueryObj, - field: newSubQueryObj.fieldName || _field, - join: genObject?.join, - table_name: tableName, - }); - sqlSearhValues.push(...values); - return str; - } - }); - return ("(" + - subSearchString.join(` ${queryObj.operator || "AND"} `) + - ")"); - } - const { str, values } = sqlGenGenSearchStr({ - queryObj, - field: queryObj.fieldName || field, - join: genObject?.join, - table_name: tableName, - }); - sqlSearhValues.push(...values); - return str; - }); - const cleanedUpSearchStr = sqlSearhString?.filter((str) => typeof str == "string"); - const isSearchStr = cleanedUpSearchStr?.[0] && cleanedUpSearchStr.find((str) => str); - if (isSearchStr) { - const stringOperator = genObject?.searchOperator || "AND"; - queryString += ` WHERE ${cleanedUpSearchStr.join(` ${stringOperator} `)}`; - } - if (genObject?.fullTextSearch && fullTextSearchStr && fullTextMatchStr) { - queryString += `${isSearchStr ? " AND" : " WHERE"} ${fullTextMatchStr}`; - sqlSearhValues.push(fullTextSearchStr); - } - if (genObject?.group) { - let group_by_txt = ``; - if (typeof genObject.group == "string") { - group_by_txt = genObject.group; - } - else if (Array.isArray(genObject.group)) { - for (let i = 0; i < genObject.group.length; i++) { - const group = genObject.group[i]; - if (typeof group == "string") { - group_by_txt += `\`${group.toString()}\``; - } - else if (typeof group == "object" && group.table) { - group_by_txt += `${group.table}.${String(group.field)}`; - } - else if (typeof group == "object") { - group_by_txt += `${String(group.field)}`; - } - if (i < genObject.group.length - 1) { - group_by_txt += ","; - } - } - } - else if (typeof genObject.group == "object") { - if (genObject.group.table) { - group_by_txt = `${genObject.group.table}.${String(genObject.group.field)}`; - } - else { - group_by_txt = `${String(genObject.group.field)}`; - } - } - queryString += ` GROUP BY ${group_by_txt}`; - } - function grabOrderString(order) { - let orderFields = []; - let orderSrt = ``; - if (genObject?.fullTextSearch && genObject.fullTextSearch.scoreAlias) { - orderFields.push(genObject.fullTextSearch.scoreAlias); - } - else if (genObject?.join) { - orderFields.push(`${tableName}.${String(order.field)}`); - } - else { - orderFields.push(order.field); - } - orderSrt += ` ${orderFields.join(", ")} ${order.strategy}`; - return orderSrt; - } - if (genObject?.order) { - let orderSrt = ` ORDER BY`; - if (Array.isArray(genObject.order)) { - for (let i = 0; i < genObject.order.length; i++) { - const order = genObject.order[i]; - if (order) { - orderSrt += - grabOrderString(order) + - (i < genObject.order.length - 1 ? `,` : ""); - } - } - } - else { - orderSrt += grabOrderString(genObject.order); - } - queryString += ` ${orderSrt}`; - } - if (genObject?.limit && !count) - queryString += ` LIMIT ${genObject.limit}`; - if (genObject?.offset) { - queryString += ` OFFSET ${genObject.offset}`; - } - else if (genObject?.page && genObject.limit && !count) { - queryString += ` OFFSET ${(genObject.page - 1) * genObject.limit}`; - } - return { - string: queryString, - values: sqlSearhValues, - }; -} -// let queryString = (() => { -// let str = "SELECT"; -// if (genObject?.select_sql) { -// str += ` ${genObject.select_sql}`; -// } else if (genObject?.selectFields?.[0]) { -// if (genObject.join) { -// str += sqlGenGrabSelectFieldSQL({ -// selectFields: genObject.selectFields, -// append_table_names: true, -// table_name: tableName, -// }); -// } else { -// str += sqlGenGrabSelectFieldSQL({ -// selectFields: genObject.selectFields, -// table_name: tableName, -// }); -// } -// } else { -// if (genObject?.join) { -// str += ` ${tableName}.*`; -// } else { -// str += " *"; -// } -// } -// if (genObject?.countSubQueries) { -// let countSqls: string[] = []; -// for (let i = 0; i < genObject.countSubQueries.length; i++) { -// const countSubQuery = genObject.countSubQueries[i]; -// if (!countSubQuery) continue; -// const tableAlias = countSubQuery.table_alias; -// let subQStr = `(SELECT COUNT(*)`; -// subQStr += ` FROM ${countSubQuery.table}${ -// tableAlias ? ` ${tableAlias}` : "" -// }`; -// subQStr += ` WHERE (`; -// for (let j = 0; j < countSubQuery.srcTrgMap.length; j++) { -// const csqSrc = countSubQuery.srcTrgMap[j]; -// if (!csqSrc) continue; -// subQStr += ` ${tableAlias || countSubQuery.table}.${ -// csqSrc.src -// }`; -// if (typeof csqSrc.trg == "string") { -// subQStr += ` = ?`; -// sqlSearhValues.push(csqSrc.trg); -// } else if (typeof csqSrc.trg == "object") { -// subQStr += ` = ${csqSrc.trg.table}.${csqSrc.trg.field}`; -// } -// if (j < countSubQuery.srcTrgMap.length - 1) { -// subQStr += ` AND `; -// } -// } -// subQStr += ` )) AS ${countSubQuery.alias}`; -// countSqls.push(subQStr); -// } -// str += `, ${countSqls.join(",")}`; -// } -// if (genObject?.join) { -// const existingJoinTableNames: string[] = [tableName]; -// str += -// "," + -// genObject.join -// .flat() -// .filter((j) => !isUndefined(j)) -// .map((joinObj) => { -// const joinTableName = joinObj.alias -// ? joinObj.alias -// : joinObj.tableName; -// if (existingJoinTableNames.includes(joinTableName)) -// return null; -// existingJoinTableNames.push(joinTableName); -// if (joinObj.group_concat) { -// return sqlGenGrabConcatStr({ -// field: `${joinTableName}.${joinObj.group_concat.field}`, -// alias: joinObj.group_concat.alias, -// separator: joinObj.group_concat.separator, -// }); -// } else if (joinObj.selectFields) { -// return joinObj.selectFields -// .map((selectField) => { -// if (typeof selectField == "string") { -// return `${joinTableName}.${selectField}`; -// } else if (typeof selectField == "object") { -// let aliasSelectField = selectField.count -// ? `COUNT(${joinTableName}.${selectField.field})` -// : `${joinTableName}.${selectField.field}`; -// if (selectField.alias) -// aliasSelectField += ` AS ${selectField.alias}`; -// return aliasSelectField; -// } -// }) -// .join(","); -// } else { -// return `${joinTableName}.*`; -// } -// }) -// .filter((_) => Boolean(_)) -// .join(","); -// } -// if ( -// genObject?.fullTextSearch && -// fullTextMatchStr && -// fullTextSearchStr -// ) { -// str += `, ${fullTextMatchStr} AS ${genObject.fullTextSearch.scoreAlias}`; -// sqlSearhValues.push(fullTextSearchStr); -// } -// str += ` FROM ${tableName}`; -// if (genObject?.join) { -// str += -// " " + -// genObject.join -// .flat() -// .filter((j) => !isUndefined(j)) -// .map((join) => { -// return ( -// join.joinType + -// " " + -// (join.alias -// ? `${join.tableName}` + " " + join.alias -// : `${join.tableName}`) + -// " ON " + -// (() => { -// if (Array.isArray(join.match)) { -// return ( -// "(" + -// join.match -// .map((mtch) => -// sqlGenGenJoinStr({ -// mtch, -// join, -// table_name: tableName, -// }), -// ) -// .join( -// join.operator -// ? ` ${join.operator} ` -// : " AND ", -// ) + -// ")" -// ); -// } else if (typeof join.match == "object") { -// return sqlGenGenJoinStr({ -// mtch: join.match, -// join, -// table_name: tableName, -// }); -// } -// })() -// ); -// }) -// .join(" "); -// } -// return str; -// })(); diff --git a/dist/utils/sql-insert-generator.d.ts b/dist/utils/sql-insert-generator.d.ts deleted file mode 100644 index 1b43778..0000000 --- a/dist/utils/sql-insert-generator.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type { SQLInsertGenParams, SQLInsertGenReturn } from "../types"; -/** - * # SQL Insert Generator - */ -export default function sqlInsertGenerator({ tableName, data, dbFullName, }: SQLInsertGenParams): SQLInsertGenReturn | undefined; diff --git a/dist/utils/sql-insert-generator.js b/dist/utils/sql-insert-generator.js deleted file mode 100644 index 2168122..0000000 --- a/dist/utils/sql-insert-generator.js +++ /dev/null @@ -1,58 +0,0 @@ -/** - * # SQL Insert Generator - */ -export default function sqlInsertGenerator({ tableName, data, dbFullName, }) { - const finalDbName = dbFullName ? `${dbFullName}.` : ""; - try { - if (Array.isArray(data) && data?.[0]) { - let insertKeys = []; - data.forEach((dt) => { - const kys = Object.keys(dt); - kys.forEach((ky) => { - if (!insertKeys.includes(ky)) { - insertKeys.push(ky); - } - }); - }); - let queryBatches = []; - let queryValues = []; - data.forEach((item) => { - queryBatches.push(`(${insertKeys - .map((ky) => { - const value = item[ky]; - const finalValue = typeof value == "string" || - typeof value == "number" - ? value - : typeof value == "function" - ? value().value - : value - ? value - : null; - if (!finalValue) { - queryValues.push(null); - return "?"; - } - queryValues.push(finalValue); - const placeholder = typeof value == "function" - ? value().placeholder - : "?"; - return placeholder; - }) - .filter((k) => Boolean(k)) - .join(",")})`); - }); - let query = `INSERT INTO ${finalDbName}${tableName} (${insertKeys.join(",")}) VALUES ${queryBatches.join(",")}`; - return { - query: query, - values: queryValues, - }; - } - else { - return undefined; - } - } - catch ( /** @type {any} */error) { - console.log(`SQL insert gen ERROR: ${error.message}`); - return undefined; - } -} diff --git a/dist/utils/trim-backups.d.ts b/dist/utils/trim-backups.d.ts deleted file mode 100644 index 49dd159..0000000 --- a/dist/utils/trim-backups.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { BunSQLiteConfig } from "../types"; -type Params = { - config: BunSQLiteConfig; -}; -export default function trimBackups({ config }: Params): void; -export {}; diff --git a/dist/utils/trim-backups.js b/dist/utils/trim-backups.js deleted file mode 100644 index a9bd3a7..0000000 --- a/dist/utils/trim-backups.js +++ /dev/null @@ -1,19 +0,0 @@ -import grabDBDir from "../utils/grab-db-dir"; -import fs from "fs"; -import grabSortedBackups from "./grab-sorted-backups"; -import { AppData } from "../data/app-data"; -import path from "path"; -export default function trimBackups({ config }) { - const { backup_dir } = grabDBDir({ config }); - const backups = grabSortedBackups({ config }); - const max_backups = config.max_backups || AppData["MaxBackups"]; - for (let i = 0; i < backups.length; i++) { - const backup_name = backups[i]; - if (!backup_name) - continue; - if (i > max_backups - 1) { - const backup_file_to_unlink = path.join(backup_dir, backup_name); - fs.unlinkSync(backup_file_to_unlink); - } - } -} diff --git a/src/index.ts b/src/index.ts index 3794aa5..8417ce8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,18 +13,6 @@ declare global { var DB_SCHEMA: BUN_MARIADB_DatabaseSchemaType; } -await init(); - -if (!global.CONFIG) { - console.error(`Couldn't grab global Config.`); - process.exit(1); -} - -if (!global.DB_SCHEMA) { - console.error(`Couldn't grab Database Schema.`); - process.exit(1); -} - const BunMariaDB = { select: DbSelect, insert: DbInsert, diff --git a/src/lib/db-handler.ts b/src/lib/db-handler.ts index 8c9ac74..84fdf30 100644 --- a/src/lib/db-handler.ts +++ b/src/lib/db-handler.ts @@ -1,11 +1,9 @@ -import type { Connection, ConnectionConfig } from "mariadb"; -import type { BUN_MARIADB_TableSchemaType, DBResponseObject } from "../types"; -import grabDBConnection from "./grab-db-connection"; +import type { DBInsertReturn, DBResponseObject } from "../types"; +import MariaDBClient from "./mariadb"; type Param = { query: string; - values?: string[] | object; - config?: ConnectionConfig; + values?: any[]; }; /** @@ -14,43 +12,40 @@ type Param = { */ export default async function dbHandler< T extends { [k: string]: any } = { [k: string]: any }, ->({ query, values, config }: Param): Promise { - let CONNECTION: Connection | undefined; - let results: T | null = null; - +>({ query, values }: Param): Promise { try { - CONNECTION = await grabDBConnection({ config }); + const res = await MariaDBClient.unsafe(query, values); - if (query && values) { - const queryResults = await CONNECTION.query(query, values); - results = queryResults[0]; - } else { - const queryResults = await CONNECTION.query(query); - results = queryResults[0]; - } - } catch (error: any) { - if ( - error.message && - typeof error.message == "string" && - error.message.match(/Access denied for user.*password/i) - ) { - throw new Error("Authentication Failed!"); - } + const count = res.count; + const last_insert_id = res.lastInsertRowid; + const affected_rows = res.affectedRows; - results = null; - } finally { - await CONNECTION?.end(); - } + const res_array = (() => { + try { + return JSON.parse(JSON.stringify(res)) as T[]; + } catch (error) { + return undefined; + } + })(); + + const insert_return: DBInsertReturn = { + count, + last_insert_id, + affected_rows, + }; - if (results) { return { success: true, - payload: Array.isArray(results) ? results : undefined, - single_res: Array.isArray(results) ? undefined : results, + payload: res_array, + single_res: res_array?.[0], + insert_return, }; - } else { + } catch (error: any) { return { success: false, + error: "DB Handler Error => " + error.message, + msg: "DB Handler Error => " + error.message, }; + } finally { } } diff --git a/src/lib/grab-db-connection.ts b/src/lib/grab-db-connection.ts index fb5296d..2511d55 100644 --- a/src/lib/grab-db-connection.ts +++ b/src/lib/grab-db-connection.ts @@ -1,7 +1,7 @@ import * as mariadb from "mariadb"; import type { Connection } from "mariadb"; -import grabDSQLConnectionConfig from "./grab-dsql-connection-config"; import type { DsqlConnectionParam } from "../types"; +import grabDbSSL from "./grab-db-ssl"; /** * # Grab General CONNECTION for DSQL @@ -9,7 +9,29 @@ import type { DsqlConnectionParam } from "../types"; export default async function grabDBConnection( param?: DsqlConnectionParam, ): Promise { - const config = grabDSQLConnectionConfig(param); + const configData = global.CONFIG; + const CONN_TIMEOUT = configData?.connection_timeout || 10000; + + const config: mariadb.ConnectionConfig = { + host: process.env.BUN_MARIADB_SERVER_HOST, + user: process.env.BUN_MARIADB_SERVER_USERNAME, + password: process.env.BUN_MARIADB_SERVER_PASSWORD, + database: configData?.db_name, + port: process.env.BUN_MARIADB_SERVER_PORT + ? Number(process.env.BUN_MARIADB_SERVER_PORT) + : undefined, + charset: configData?.charset || "utf8mb4", + ssl: grabDbSSL(), + bigIntAsNumber: true, + supportBigNumbers: true, + bigNumberStrings: false, + dateStrings: true, + metaAsArray: true, + socketTimeout: CONN_TIMEOUT, + connectTimeout: CONN_TIMEOUT, + compress: true, + ...param?.config, + }; try { return await mariadb.createConnection(config); diff --git a/src/lib/grab-db-ssl.ts b/src/lib/grab-db-ssl.ts index 7a2c21b..057046d 100644 --- a/src/lib/grab-db-ssl.ts +++ b/src/lib/grab-db-ssl.ts @@ -2,27 +2,28 @@ import fs from "fs"; import type { ConnectionConfig } from "mariadb"; import path from "path"; -type Return = ConnectionConfig["ssl"] | undefined; - /** * # Grab SSL */ -export default function grabDbSSL(): Return { - const caProivdedPath = process.env.BUN_MARIADB_SERVER_SSL_KEY_PATH; +export default function grabDbSSL(): ConnectionConfig["ssl"] { + const caProivdedPath = + global.CONFIG.ssl_ca || process.env.BUN_MARIADB_SERVER_SSL_KEY_PATH; if (!caProivdedPath?.match(/./)) { - return undefined; + return { + rejectUnauthorized: false, + }; } - const caFilePath = path.resolve(process.cwd(), caProivdedPath); + const ca_file_path = path.resolve(process.cwd(), caProivdedPath); - if (!fs.existsSync(caFilePath)) { - console.log(`${caFilePath} does not exist`); + if (!fs.existsSync(ca_file_path)) { + console.log(`${ca_file_path} does not exist`); return undefined; } return { - ca: fs.readFileSync(caFilePath), + ca: fs.readFileSync(ca_file_path), rejectUnauthorized: false, }; } diff --git a/src/lib/grab-dsql-connection-config.ts b/src/lib/grab-dsql-connection-config.ts deleted file mode 100644 index 70389b9..0000000 --- a/src/lib/grab-dsql-connection-config.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { type ConnectionConfig } from "mariadb"; -import type { DsqlConnectionParam } from "../types"; -import grabDbSSL from "./grab-db-ssl"; - -/** - * # Grab General CONNECTION for DSQL - */ -export default function grabDSQLConnectionConfig( - param?: DsqlConnectionParam, -): ConnectionConfig { - const configData = global.CONFIG; - const CONN_TIMEOUT = configData?.connection_timeout || 10000; - - const config: ConnectionConfig = { - host: process.env.BUN_MARIADB_SERVER_HOST, - user: process.env.BUN_MARIADB_SERVER_USERNAME, - password: process.env.BUN_MARIADB_SERVER_PASSWORD, - database: configData?.db_name, - port: process.env.BUN_MARIADB_SERVER_PORT - ? Number(process.env.BUN_MARIADB_SERVER_PORT) - : undefined, - charset: configData?.charset || "utf8mb4", - ssl: grabDbSSL(), - bigIntAsNumber: true, - supportBigNumbers: true, - bigNumberStrings: false, - dateStrings: true, - metaAsArray: true, - socketTimeout: CONN_TIMEOUT, - connectTimeout: CONN_TIMEOUT, - compress: true, - ...param?.config, - }; - - return config; -} diff --git a/src/lib/grab-duplicate-safe-insert-sql.ts b/src/lib/grab-duplicate-safe-insert-sql.ts index ba78ecc..501cca0 100644 --- a/src/lib/grab-duplicate-safe-insert-sql.ts +++ b/src/lib/grab-duplicate-safe-insert-sql.ts @@ -28,8 +28,9 @@ export default async function ({ sql: passedSql, table, data }: Params) { } const hasUniqueField = - tableSchema.fields.some((field) => field.unique) || - Boolean(tableSchema.uniqueConstraints?.length); + tableSchema.fields.some( + (field: { unique?: boolean }) => field.unique, + ) || Boolean(tableSchema.uniqueConstraints?.length); if (!hasUniqueField) { return passedSql; diff --git a/src/lib/mariadb/db-schema-manager.ts b/src/lib/mariadb/db-schema-manager.ts index f3ef2db..4670bde 100644 --- a/src/lib/mariadb/db-schema-manager.ts +++ b/src/lib/mariadb/db-schema-manager.ts @@ -27,18 +27,10 @@ type IndexInfoRow = { class MariaDBSchemaManager { private db_manager_table_name: string; - private recreate_vector_table: boolean; private db_schema: BUN_MARIADB_DatabaseSchemaType; - constructor({ - schema, - recreate_vector_table = false, - }: { - schema: BUN_MARIADB_DatabaseSchemaType; - recreate_vector_table?: boolean; - }) { + constructor({ schema }: { schema: BUN_MARIADB_DatabaseSchemaType }) { this.db_manager_table_name = AppData["DbSchemaManagerTableName"]; - this.recreate_vector_table = recreate_vector_table; this.db_schema = schema; } @@ -63,32 +55,27 @@ class MariaDBSchemaManager { return `\`${identifier.replace(/`/g, "``")}\``; } - private tableSchemaWhere(tableName: string): { - where: string; - values: QueryValues; - } { + private schemaCondition(): { where: string; values: string[] } { const config = global.CONFIG; const databaseName = config?.db_name; if (databaseName) { return { where: "TABLE_SCHEMA = ?", - values: [databaseName, tableName], + values: [databaseName], }; } return { where: "TABLE_SCHEMA = DATABASE()", - values: [tableName], + values: [], }; } private async run(query: string, values?: QueryValues): Promise { - const config = global.CONFIG; const res = await dbHandler({ query, values: values as any, - config: config?.db_config, }); if (!res.success) { @@ -103,10 +90,12 @@ class MariaDBSchemaManager { const res = await dbHandler({ query, values: values as any, - config: global.CONFIG.db_config, }); if (!res.success) { + console.log("res", res); + console.log("query", query); + console.log("values", values); throw new Error(`Database query failed: ${query}`); } @@ -148,10 +137,10 @@ class MariaDBSchemaManager { } private async getLiveTableNames(): Promise { - const tableSchemaWhere = this.tableSchemaWhere(""); + const schemaCond = this.schemaCondition(); const rows = await this.query<{ TABLE_NAME: string }>( - `SELECT TABLE_NAME FROM information_schema.TABLES WHERE ${tableSchemaWhere.where} AND TABLE_TYPE = 'BASE TABLE'`, - tableSchemaWhere.values, + `SELECT TABLE_NAME FROM information_schema.TABLES WHERE ${schemaCond.where} AND TABLE_TYPE = 'BASE TABLE'`, + schemaCond.values, ); return rows.map((row) => row.TABLE_NAME); @@ -163,7 +152,7 @@ class MariaDBSchemaManager { ): Promise { console.log(`Cleaning up tables ...`); - const tablesToDrop = existingTables.filter( + const tablesToDrop: string[] = existingTables.filter( (tableName) => !schemaTables.includes(tableName) && !schemaTables.some((schemaTable) => @@ -187,7 +176,9 @@ class MariaDBSchemaManager { } } - for (const tableName of tablesToDrop) { + const uniqueTablesToDrop = _.uniq(tablesToDrop); + + for (const tableName of uniqueTablesToDrop) { console.log(`Dropping table: ${tableName}`); await this.run( `DROP TABLE IF EXISTS ${this.quoteIdentifier(tableName)}`, @@ -202,6 +193,7 @@ class MariaDBSchemaManager { ): Promise { let tableExists = existingTables.includes(table.tableName); const liveTables = await this.getLiveTableNames(); + let wasRenamed = false; if (table.tableNameOld && table.tableNameOld !== table.tableName) { if (liveTables.includes(table.tableNameOld)) { @@ -214,13 +206,14 @@ class MariaDBSchemaManager { await this.insertDbManagerTable(table.tableName); await this.removeDbManagerTable(table.tableNameOld); tableExists = true; + wasRenamed = true; } } if (!tableExists) { await this.createTable(table); await this.insertDbManagerTable(table.tableName); - } else { + } else if (!wasRenamed) { await this.updateTable(table); await this.insertDbManagerTable(table.tableName); } @@ -228,7 +221,9 @@ class MariaDBSchemaManager { await this.syncIndexes(table); } - private resolveTable(table: BUN_MARIADB_TableSchemaType) { + private resolveTable( + table: BUN_MARIADB_TableSchemaType, + ): BUN_MARIADB_TableSchemaType { if (!table.parentTableName) { return _.cloneDeep(table); } @@ -243,11 +238,24 @@ class MariaDBSchemaManager { ); } + const mergedFieldsMap = new Map(); + + (parentTable.fields || []).forEach((f) => { + if (f.fieldName) mergedFieldsMap.set(f.fieldName, f); + }); + + (table.fields || []).forEach((f) => { + if (f.fieldName) { + const existing = mergedFieldsMap.get(f.fieldName) || {}; + mergedFieldsMap.set(f.fieldName, { ...existing, ...f }); + } + }); + return _.merge({}, parentTable, { tableName: table.tableName, tableDescription: table.tableDescription, collation: table.collation, - fields: [...(parentTable.fields || []), ...(table.fields || [])], + fields: Array.from(mergedFieldsMap.values()), indexes: [...(parentTable.indexes || []), ...(table.indexes || [])], uniqueConstraints: [ ...(parentTable.uniqueConstraints || []), @@ -317,17 +325,49 @@ class MariaDBSchemaManager { table: BUN_MARIADB_TableSchemaType, ): Promise { console.log(`Updating table: ${table.tableName}`); - await this.recreateTable(table); + + const resolvedTable = this.resolveTable(table); + const existingColumns = await this.getTableColumns( + resolvedTable.tableName, + ); + + const missingFields = (resolvedTable.fields || []).filter( + (field) => + !existingColumns.some((col) => col.name === field.fieldName), + ); + + const hasModifiedFields = (resolvedTable.fields || []).some((field) => { + const current = existingColumns.find( + (col) => col.name === field.fieldName, + ); + if (!current) return false; + + const resolvedType = this.mapDataType(field).toLowerCase(); + return !resolvedType.startsWith(current.type.toLowerCase()); + }); + + if ( + missingFields.length > 0 && + !hasModifiedFields && + !resolvedTable.isVector + ) { + for (const field of missingFields) { + await this.addColumn(resolvedTable.tableName, field); + } + return; + } + + await this.recreateTable(resolvedTable); } private async getTableColumns(tableName: string): Promise { - const tableSchemaWhere = this.tableSchemaWhere(tableName); + const schemaCond = this.schemaCondition(); const rows = await this.query<{ COLUMN_NAME: string; COLUMN_TYPE: string; }>( - `SELECT COLUMN_NAME AS name, COLUMN_TYPE AS type FROM information_schema.COLUMNS WHERE ${tableSchemaWhere.where} AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION`, - tableSchemaWhere.values, + `SELECT COLUMN_NAME, COLUMN_TYPE FROM information_schema.COLUMNS WHERE ${schemaCond.where} AND TABLE_NAME = ? ORDER BY ORDINAL_POSITION`, + [...schemaCond.values, tableName], ); return rows.map((row) => ({ @@ -352,24 +392,18 @@ class MariaDBSchemaManager { `ALTER TABLE ${this.quoteIdentifier(tableName)} ADD COLUMN ${columnDef}`, ); } - private async checkIfTableExists(table: string): Promise { - const tableSchemaWhere = this.tableSchemaWhere(table); - const row = await this.query<{ exists: number }>( - `SELECT 1 AS exists FROM information_schema.TABLES WHERE ${tableSchemaWhere.where} AND TABLE_NAME = ? LIMIT 1`, - tableSchemaWhere.values, + const schemaCond = this.schemaCondition(); + const row = await this.query<{ table_exists: number }>( + `SELECT 1 AS \`table_exists\` FROM information_schema.TABLES WHERE ${schemaCond.where} AND TABLE_NAME = ? LIMIT 1`, + [...schemaCond.values, table], ); - return Boolean(row[0]?.exists); + return Boolean(row[0]?.table_exists); } - private async recreateTable( table: BUN_MARIADB_TableSchemaType, ): Promise { - if (table.isVector && !this.recreate_vector_table) { - return; - } - const doesTableExist = await this.checkIfTableExists(table.tableName); if (table.isVector) { @@ -394,8 +428,10 @@ class MariaDBSchemaManager { } const tempTableName = `${table.tableName}_temp_${Date.now()}`; + const backupOldTableName = `${table.tableName}_old_${Date.now()}`; const existingColumns = await this.getTableColumns(table.tableName); - const columnsToKeep = table.fields + + const columnsToKeep = (table.fields || []) .filter((field) => existingColumns.some( (column) => column.name === field.fieldName, @@ -416,10 +452,15 @@ class MariaDBSchemaManager { ); } - await this.run(`DROP TABLE ${this.quoteIdentifier(table.tableName)}`); + await this.run( + `RENAME TABLE ${this.quoteIdentifier(table.tableName)} TO ${this.quoteIdentifier(backupOldTableName)}`, + ); await this.run( `RENAME TABLE ${this.quoteIdentifier(tempTableName)} TO ${this.quoteIdentifier(table.tableName)}`, ); + await this.run( + `DROP TABLE ${this.quoteIdentifier(backupOldTableName)}`, + ); } private async insertRows( @@ -495,95 +536,68 @@ class MariaDBSchemaManager { } private mapDataType(field: BUN_MARIADB_FieldSchemaType): string { - const dataType = field.dataType?.toLowerCase() || "text"; + const dataType = field.dataType?.toUpperCase() || "TEXT"; const vectorSize = field.vectorSize || 1536; if (field.isVector) { return `LONGTEXT COMMENT 'vector_size=${vectorSize}'`; } - if (dataType === "bigint") { - if (field.integerLength) { - return `BIGINT(${field.integerLength})`; - } + switch (dataType) { + case "VARCHAR": + return `VARCHAR(${field.integerLength || 255})`; - return "BIGINT"; + case "TEXT": + return "TEXT"; + + case "LONGTEXT": + return "LONGTEXT"; + + case "TINYINT": + return field.integerLength + ? `TINYINT(${field.integerLength})` + : "TINYINT"; + + case "INT": + return field.integerLength + ? `INT(${field.integerLength})` + : "INT"; + + case "BIGINT": + return field.integerLength + ? `BIGINT(${field.integerLength})` + : "BIGINT"; + + case "DECIMAL": + if (field.integerLength && field.decimals) { + return `DECIMAL(${field.integerLength}, ${field.decimals})`; + } + return "DECIMAL(10,2)"; + + case "DOUBLE": + return "DOUBLE"; + + case "BLOB": + return "BLOB"; + + case "LONGBLOB": + return "LONGBLOB"; + + case "BOOLEAN": + return "TINYINT(1)"; + + case "DATETIME": + return "DATETIME"; + + case "TIMESTAMP": + return "TIMESTAMP"; + + case "DATE": + return "DATE"; + + default: + return "TEXT"; } - - if (dataType === "smallint") { - if (field.integerLength) { - return `SMALLINT(${field.integerLength})`; - } - - return "SMALLINT"; - } - - if (dataType === "tinyint") { - if (field.integerLength) { - return `TINYINT(${field.integerLength})`; - } - - return "TINYINT"; - } - - if ( - dataType.includes("int") || - dataType === "bigint" || - dataType === "smallint" || - dataType === "tinyint" - ) { - if (field.integerLength) { - return `INT(${field.integerLength})`; - } - - return "INT"; - } - - if (dataType.includes("double")) { - return "DOUBLE"; - } - - if (dataType.includes("float")) { - return "FLOAT"; - } - - if (dataType.includes("decimal") || dataType.includes("numeric")) { - if (field.integerLength && field.decimals) { - return `DECIMAL(${field.integerLength}, ${field.decimals})`; - } - - return "DECIMAL"; - } - - if (dataType.includes("blob") || dataType.includes("binary")) { - return "BLOB"; - } - - if (dataType === "boolean" || dataType === "bool") { - return "TINYINT(1)"; - } - - if (dataType.includes("timestamp")) { - return "TIMESTAMP"; - } - - if (dataType.includes("datetime")) { - return "DATETIME"; - } - - if (dataType.includes("date") || dataType.includes("time")) { - return "DATETIME"; - } - - if (dataType.includes("varchar")) { - if (field.integerLength) { - return `VARCHAR(${field.integerLength})`; - } - - return "VARCHAR(255)"; - } - - return "TEXT"; } private buildForeignKeyConstraint( @@ -614,10 +628,10 @@ class MariaDBSchemaManager { return; } - const tableSchemaWhere = this.tableSchemaWhere(table.tableName); + const schemaCond = this.schemaCondition(); const rows = await this.query( - `SELECT INDEX_NAME AS name FROM information_schema.STATISTICS WHERE ${tableSchemaWhere.where} AND TABLE_NAME = ? AND INDEX_NAME <> 'PRIMARY' GROUP BY INDEX_NAME ORDER BY INDEX_NAME`, - tableSchemaWhere.values, + `SELECT INDEX_NAME AS name FROM information_schema.STATISTICS WHERE ${schemaCond.where} AND TABLE_NAME = ? AND INDEX_NAME <> 'PRIMARY' GROUP BY INDEX_NAME ORDER BY INDEX_NAME`, + [...schemaCond.values, table.tableName], ); const existingIndexes = rows.map((row) => row.name); @@ -645,13 +659,27 @@ class MariaDBSchemaManager { if (!existingIndexes.includes(index.indexName)) { console.log(`Creating index: ${index.indexName}`); + const fields = index.indexTableFields .map((field) => this.quoteIdentifier(field)) .join(", "); - await this.run( - `CREATE INDEX ${this.quoteIdentifier(index.indexName)} ON ${this.quoteIdentifier(table.tableName)} (${fields})`, - ); + // Determine if we need a specialized modifier prefix like FULLTEXT or SPATIAL + const typeUpper = index.indexType?.toUpperCase(); + const isSpecialType = + typeUpper === "FULLTEXT" || typeUpper === "SPATIAL"; + const indexPrefix = isSpecialType ? `${typeUpper} ` : ""; + + // Append USING BTREE/HASH if it's a normal index type option + const indexSuffix = + !isSpecialType && + (typeUpper === "BTREE" || typeUpper === "HASH") + ? ` USING ${typeUpper}` + : ""; + + const sql = `CREATE ${indexPrefix}INDEX ${this.quoteIdentifier(index.indexName)} ON ${this.quoteIdentifier(table.tableName)} (${fields})${indexSuffix}`; + + await this.run(sql); } } } diff --git a/src/lib/mariadb/index.ts b/src/lib/mariadb/index.ts new file mode 100644 index 0000000..4e105b1 --- /dev/null +++ b/src/lib/mariadb/index.ts @@ -0,0 +1,50 @@ +import { SQL } from "bun"; +import init from "../../functions/init"; +import grabDirNames from "../../data/grab-dir-names"; +import path from "path"; + +await init(); + +if (!global.CONFIG) { + console.error(`Couldn't grab global Config.`); + process.exit(1); +} + +if (!global.DB_SCHEMA) { + console.error(`Couldn't grab Database Schema.`); + process.exit(1); +} + +const config = global.CONFIG; + +const { ROOT_DIR } = grabDirNames(); + +const MariaDBClient = new SQL({ + hostname: process.env.BUN_MARIADB_SERVER_HOST, + username: process.env.BUN_MARIADB_SERVER_USERNAME, + password: process.env.BUN_MARIADB_SERVER_PASSWORD, + database: config.db_name, + port: process.env.BUN_MARIADB_SERVER_PORT + ? Number(process.env.BUN_MARIADB_SERVER_PORT) + : undefined, + ...config.db_config, + tls: config.ssl_ca + ? { + ca: Bun.file(path.resolve(ROOT_DIR, config.ssl_ca)), + rejectUnauthorized: false, + } + : { + rejectUnauthorized: false, + }, + adapter: "mariadb", +}); + +const test = await MariaDBClient.unsafe(`SHOW DATABASES`); + +if (!test.count) { + console.error(`MariaDBClient Error: Database not ready.`); + console.log(test); + process.exit(1); +} + +export default MariaDBClient; diff --git a/src/types/index.ts b/src/types/index.ts index 7552e89..1fdb84e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -132,13 +132,23 @@ export const TextFieldTypesArray = [ ] as const; /** - * Core MariaDB column types supported by the schema builder. + * Native MariaDB column types supported by the schema builder. */ export const BUN_MARIADB_DATATYPES = [ + { value: "VARCHAR" }, { value: "TEXT" }, - { value: "INTEGER" }, + { value: "LONGTEXT" }, + { value: "TINYINT" }, + { value: "INT" }, + { value: "BIGINT" }, + { value: "DECIMAL" }, + { value: "DOUBLE" }, { value: "BLOB" }, - { value: "REAL" }, + { value: "LONGBLOB" }, + { value: "BOOLEAN" }, + { value: "DATETIME" }, + { value: "TIMESTAMP" }, + { value: "DATE" }, ] as const; /** @@ -191,6 +201,15 @@ export interface BUN_MARIADB_ForeignKeyType { cascadeUpdate?: boolean; } +export const MariaDBIndexTypes = [ + "BTREE", + "HASH", + "FULLTEXT", + "SPATIAL", +] as const; + +export type MariaDBIndexType = (typeof MariaDBIndexTypes)[number]; + /** * Describes a table index and the fields it covers. */ @@ -200,7 +219,19 @@ export interface BUN_MARIADB_IndexSchemaType { * `idx_user_id_index` */ indexName?: string; + /** + * The columns included in the index. + */ indexTableFields?: string[]; + /** + * Under the hood index type (BTREE, HASH) or modifier (FULLTEXT, SPATIAL) + */ + indexType?: MariaDBIndexType; + + /** + * Optional documentation or tuning note inside the DB metadata + */ + comment?: string; } /** @@ -1511,7 +1542,7 @@ export type BunMariaDBConfig = { /** * Configuration for the MariaDB Connection */ - db_config?: ConnectionConfig; + db_config?: Bun.SQL.Options; /** * Database charset. Defaults to `utf8mb4` */ @@ -1520,6 +1551,10 @@ export type BunMariaDBConfig = { * Database Connection timeout. Defaults to `10000` */ connection_timeout?: number; + /** + * File path to the SSL certificate + */ + ssl_ca?: string; }; /** @@ -1536,7 +1571,7 @@ export type BunMariaDBConfigReturn = { export const DefaultFields: BUN_MARIADB_FieldSchemaType[] = [ { fieldName: "id", - dataType: "INTEGER", + dataType: "BIGINT", primaryKey: true, autoIncrement: true, notNullValue: true, @@ -1544,13 +1579,13 @@ export const DefaultFields: BUN_MARIADB_FieldSchemaType[] = [ }, { fieldName: "created_at", - dataType: "INTEGER", + dataType: "BIGINT", fieldDescription: "The time when the record was created. (Unix Timestamp)", }, { fieldName: "updated_at", - dataType: "INTEGER", + dataType: "BIGINT", fieldDescription: "The time when the record was updated. (Unix Timestamp)", }, @@ -1587,6 +1622,15 @@ export type DBResponseObject< success: boolean; payload?: T[]; single_res?: T; + insert_return?: DBInsertReturn; + error?: any; + msg?: string; +}; + +export type DBInsertReturn = { + count?: number; + last_insert_id?: number; + affected_rows?: number; }; export const RequiredENVs = [