Refactor DB Handler. Use Bun native SQL adapter.
This commit is contained in:
parent
eb86e1803d
commit
44f6c18a84
2
dist/commands/admin/index.d.ts
vendored
2
dist/commands/admin/index.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
41
dist/commands/admin/index.js
vendored
41
dist/commands/admin/index.js
vendored
@ -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();
|
||||
});
|
||||
}
|
||||
3
dist/commands/admin/list-tables.d.ts
vendored
3
dist/commands/admin/list-tables.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
type Params = {};
|
||||
export default function listTables(params?: Params): Promise<"__exit__" | void>;
|
||||
export {};
|
||||
78
dist/commands/admin/list-tables.js
vendored
78
dist/commands/admin/list-tables.js
vendored
@ -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<ColumnInfo, []>(`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();
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
3
dist/commands/admin/run-sql.d.ts
vendored
3
dist/commands/admin/run-sql.d.ts
vendored
@ -1,3 +0,0 @@
|
||||
type Params = {};
|
||||
export default function runSQL(params?: Params): Promise<void>;
|
||||
export {};
|
||||
26
dist/commands/admin/run-sql.js
vendored
26
dist/commands/admin/run-sql.js
vendored
@ -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`));
|
||||
}
|
||||
}
|
||||
5
dist/commands/admin/show-entries.d.ts
vendored
5
dist/commands/admin/show-entries.d.ts
vendored
@ -1,5 +0,0 @@
|
||||
type Params = {
|
||||
tableName: string;
|
||||
};
|
||||
export default function showEntries({ tableName }: Params): Promise<"__exit__" | undefined>;
|
||||
export {};
|
||||
83
dist/commands/admin/show-entries.js
vendored
83
dist/commands/admin/show-entries.js
vendored
@ -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<ColumnInfo, []>(`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;
|
||||
// }
|
||||
}
|
||||
}
|
||||
5
dist/commands/admin/show-fields.d.ts
vendored
5
dist/commands/admin/show-fields.d.ts
vendored
@ -1,5 +0,0 @@
|
||||
type Params = {
|
||||
tableName: string;
|
||||
};
|
||||
export default function showFields({ tableName, }: Params): Promise<"__exit__" | void>;
|
||||
export {};
|
||||
69
dist/commands/admin/show-fields.js
vendored
69
dist/commands/admin/show-fields.js
vendored
@ -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<ColumnInfo, []>(`PRAGMA table_info("${tableName}")`)
|
||||
// .all();
|
||||
// const indexes = db
|
||||
// .query<IndexInfo, []>(`PRAGMA index_list("${tableName}")`)
|
||||
// .all();
|
||||
// const foreignKeys = db
|
||||
// .query<ForeignKey, []>(`PRAGMA foreign_key_list("${tableName}")`)
|
||||
// .all();
|
||||
// const indexedFields = new Map<string, { unique: boolean }>();
|
||||
// for (const idx of indexes) {
|
||||
// const cols = db
|
||||
// .query<IndexColumn, []>(`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();
|
||||
// }
|
||||
}
|
||||
2
dist/commands/backup.d.ts
vendored
2
dist/commands/backup.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
22
dist/commands/backup.js
vendored
22
dist/commands/backup.js
vendored
@ -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();
|
||||
});
|
||||
}
|
||||
6
dist/commands/index.d.ts
vendored
6
dist/commands/index.d.ts
vendored
@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env bun
|
||||
/**
|
||||
* # Declare Global Variables
|
||||
*/
|
||||
declare global { }
|
||||
export {};
|
||||
33
dist/commands/index.js
vendored
33
dist/commands/index.js
vendored
@ -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);
|
||||
2
dist/commands/restore.d.ts
vendored
2
dist/commands/restore.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
44
dist/commands/restore.js
vendored
44
dist/commands/restore.js
vendored
@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
2
dist/commands/schema.d.ts
vendored
2
dist/commands/schema.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
54
dist/commands/schema.js
vendored
54
dist/commands/schema.js
vendored
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
2
dist/commands/typedef.d.ts
vendored
2
dist/commands/typedef.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
31
dist/commands/typedef.js
vendored
31
dist/commands/typedef.js
vendored
@ -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();
|
||||
});
|
||||
}
|
||||
6
dist/data/app-data.d.ts
vendored
6
dist/data/app-data.d.ts
vendored
@ -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__";
|
||||
};
|
||||
6
dist/data/app-data.js
vendored
6
dist/data/app-data.js
vendored
@ -1,6 +0,0 @@
|
||||
export const AppData = {
|
||||
ConfigFileName: "bun-sqlite.config.ts",
|
||||
MaxBackups: 10,
|
||||
DefaultBackupDirName: ".backups",
|
||||
DbSchemaManagerTableName: "__db_schema_manager__",
|
||||
};
|
||||
12
dist/data/grab-dir-names.d.ts
vendored
12
dist/data/grab-dir-names.d.ts
vendored
@ -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 {};
|
||||
15
dist/data/grab-dir-names.js
vendored
15
dist/data/grab-dir-names.js
vendored
@ -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,
|
||||
};
|
||||
}
|
||||
2
dist/functions/init.d.ts
vendored
2
dist/functions/init.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import type { BunSQLiteConfigReturn } from "../types";
|
||||
export default function init(): Promise<BunSQLiteConfigReturn>;
|
||||
46
dist/functions/init.js
vendored
46
dist/functions/init.js
vendored
@ -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);
|
||||
}
|
||||
}
|
||||
7
dist/functions/live-schema.d.ts
vendored
7
dist/functions/live-schema.d.ts
vendored
@ -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 {};
|
||||
15
dist/functions/live-schema.js
vendored
15
dist/functions/live-schema.js
vendored
@ -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);
|
||||
}
|
||||
19
dist/index.d.ts
vendored
19
dist/index.d.ts
vendored
@ -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;
|
||||
19
dist/index.js
vendored
19
dist/index.js
vendored
@ -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;
|
||||
20
dist/lib/db-handler.d.ts
vendored
20
dist/lib/db-handler.d.ts
vendored
@ -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<T extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}>({ query, values, noErrorLogs, database, config, }: Param): Promise<DBResponseObject>;
|
||||
export {};
|
||||
46
dist/lib/db-handler.js
vendored
46
dist/lib/db-handler.js
vendored
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
6
dist/lib/grab-db-connection.d.ts
vendored
6
dist/lib/grab-db-connection.d.ts
vendored
@ -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<Connection>;
|
||||
15
dist/lib/grab-db-connection.js
vendored
15
dist/lib/grab-db-connection.js
vendored
@ -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;
|
||||
}
|
||||
}
|
||||
7
dist/lib/grab-db-ssl.d.ts
vendored
7
dist/lib/grab-db-ssl.d.ts
vendored
@ -1,7 +0,0 @@
|
||||
import type { ConnectionConfig } from "mariadb";
|
||||
type Return = ConnectionConfig["ssl"] | undefined;
|
||||
/**
|
||||
* # Grab SSL
|
||||
*/
|
||||
export default function grabDbSSL(): Return;
|
||||
export {};
|
||||
20
dist/lib/grab-db-ssl.js
vendored
20
dist/lib/grab-db-ssl.js
vendored
@ -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,
|
||||
};
|
||||
}
|
||||
6
dist/lib/grab-dsql-connection-config.d.ts
vendored
6
dist/lib/grab-dsql-connection-config.d.ts
vendored
@ -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;
|
||||
29
dist/lib/grab-dsql-connection-config.js
vendored
29
dist/lib/grab-dsql-connection-config.js
vendored
@ -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;
|
||||
}
|
||||
7
dist/lib/grab-duplicate-safe-insert-sql.d.ts
vendored
7
dist/lib/grab-duplicate-safe-insert-sql.d.ts
vendored
@ -1,7 +0,0 @@
|
||||
type Params = {
|
||||
sql: string;
|
||||
table: string;
|
||||
data: any | any[];
|
||||
};
|
||||
export default function ({ sql: passed_sql, table, data }: Params): Promise<string>;
|
||||
export {};
|
||||
24
dist/lib/grab-duplicate-safe-insert-sql.js
vendored
24
dist/lib/grab-duplicate-safe-insert-sql.js
vendored
@ -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;
|
||||
}
|
||||
16
dist/lib/mariadb/db-delete.d.ts
vendored
16
dist/lib/mariadb/db-delete.d.ts
vendored
@ -1,16 +0,0 @@
|
||||
import type { APIResponseObject, ServerQueryParam } from "../../types";
|
||||
type Params<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string> = {
|
||||
table: Table;
|
||||
query?: ServerQueryParam<Schema>;
|
||||
targetId?: number | string;
|
||||
};
|
||||
export default function DbDelete<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string>({ table, query, targetId, }: Params<Schema, Table>): Promise<APIResponseObject>;
|
||||
export {};
|
||||
56
dist/lib/mariadb/db-delete.js
vendored
56
dist/lib/mariadb/db-delete.js
vendored
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
15
dist/lib/mariadb/db-generate-type-defs.d.ts
vendored
15
dist/lib/mariadb/db-generate-type-defs.d.ts
vendored
@ -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 {};
|
||||
63
dist/lib/mariadb/db-generate-type-defs.js
vendored
63
dist/lib/mariadb/db-generate-type-defs.js
vendored
@ -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<ArrayBuffer> | Buffer<ArrayBuffer> | 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 };
|
||||
}
|
||||
16
dist/lib/mariadb/db-insert.d.ts
vendored
16
dist/lib/mariadb/db-insert.d.ts
vendored
@ -1,16 +0,0 @@
|
||||
import type { APIResponseObject } from "../../types";
|
||||
type Params<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string> = {
|
||||
table: Table;
|
||||
data: Schema[];
|
||||
update_on_duplicate?: boolean;
|
||||
};
|
||||
export default function DbInsert<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string>({ table, data, update_on_duplicate, }: Params<Schema, Table>): Promise<APIResponseObject>;
|
||||
export {};
|
||||
43
dist/lib/mariadb/db-insert.js
vendored
43
dist/lib/mariadb/db-insert.js
vendored
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
39
dist/lib/mariadb/db-schema-manager.d.ts
vendored
39
dist/lib/mariadb/db-schema-manager.d.ts
vendored
@ -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<void>;
|
||||
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 };
|
||||
419
dist/lib/mariadb/db-schema-manager.js
vendored
419
dist/lib/mariadb/db-schema-manager.js
vendored
@ -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 };
|
||||
7
dist/lib/mariadb/db-schema-to-typedef.d.ts
vendored
7
dist/lib/mariadb/db-schema-to-typedef.d.ts
vendored
@ -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 {};
|
||||
44
dist/lib/mariadb/db-schema-to-typedef.js
vendored
44
dist/lib/mariadb/db-schema-to-typedef.js
vendored
@ -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];
|
||||
}
|
||||
17
dist/lib/mariadb/db-select.d.ts
vendored
17
dist/lib/mariadb/db-select.d.ts
vendored
@ -1,17 +0,0 @@
|
||||
import type { APIResponseObject, ServerQueryParam } from "../../types";
|
||||
type Params<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string> = {
|
||||
query?: ServerQueryParam<Schema>;
|
||||
table: Table;
|
||||
count?: boolean;
|
||||
targetId?: number | string;
|
||||
};
|
||||
export default function DbSelect<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string>({ table, query, count, targetId, }: Params<Schema, Table>): Promise<APIResponseObject<Schema>>;
|
||||
export {};
|
||||
58
dist/lib/mariadb/db-select.js
vendored
58
dist/lib/mariadb/db-select.js
vendored
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
11
dist/lib/mariadb/db-sql.d.ts
vendored
11
dist/lib/mariadb/db-sql.d.ts
vendored
@ -1,11 +0,0 @@
|
||||
import type { APIResponseObject, SQLInsertGenValueType } from "../../types";
|
||||
type Params = {
|
||||
sql: string;
|
||||
values?: SQLInsertGenValueType[];
|
||||
};
|
||||
export default function DbSQL<T extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}>({ sql, values }: Params): Promise<APIResponseObject<T>>;
|
||||
export {};
|
||||
34
dist/lib/mariadb/db-sql.js
vendored
34
dist/lib/mariadb/db-sql.js
vendored
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
17
dist/lib/mariadb/db-update.d.ts
vendored
17
dist/lib/mariadb/db-update.d.ts
vendored
@ -1,17 +0,0 @@
|
||||
import type { APIResponseObject, ServerQueryParam } from "../../types";
|
||||
type Params<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string> = {
|
||||
table: Table;
|
||||
data: Schema;
|
||||
query?: ServerQueryParam<Schema>;
|
||||
targetId?: number | string;
|
||||
};
|
||||
export default function DbUpdate<Schema extends {
|
||||
[k: string]: any;
|
||||
} = {
|
||||
[k: string]: any;
|
||||
}, Table extends string = string>({ table, data, query, targetId, }: Params<Schema, Table>): Promise<APIResponseObject>;
|
||||
export {};
|
||||
74
dist/lib/mariadb/db-update.js
vendored
74
dist/lib/mariadb/db-update.js
vendored
@ -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,
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
8
dist/lib/mariadb/schema-to-typedef.d.ts
vendored
8
dist/lib/mariadb/schema-to-typedef.d.ts
vendored
@ -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 {};
|
||||
18
dist/lib/mariadb/schema-to-typedef.js
vendored
18
dist/lib/mariadb/schema-to-typedef.js
vendored
@ -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);
|
||||
}
|
||||
}
|
||||
2
dist/lib/mariadb/schema.d.ts
vendored
2
dist/lib/mariadb/schema.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import type { BUN_MARIADB_DatabaseSchemaType } from "../../types";
|
||||
export declare const DbSchema: BUN_MARIADB_DatabaseSchemaType;
|
||||
5
dist/lib/mariadb/schema.js
vendored
5
dist/lib/mariadb/schema.js
vendored
@ -1,5 +0,0 @@
|
||||
import _ from "lodash";
|
||||
export const DbSchema = {
|
||||
dbName: "travis-ai",
|
||||
tables: [],
|
||||
};
|
||||
1417
dist/types/index.d.ts
vendored
1417
dist/types/index.d.ts
vendored
File diff suppressed because it is too large
Load Diff
187
dist/types/index.js
vendored
187
dist/types/index.js
vendored
@ -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)",
|
||||
},
|
||||
];
|
||||
@ -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 {};
|
||||
12
dist/utils/append-default-fields-to-db-schema.js
vendored
12
dist/utils/append-default-fields-to-db-schema.js
vendored
@ -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;
|
||||
}
|
||||
9
dist/utils/grab-backup-data.d.ts
vendored
9
dist/utils/grab-backup-data.d.ts
vendored
@ -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 {};
|
||||
7
dist/utils/grab-backup-data.js
vendored
7
dist/utils/grab-backup-data.js
vendored
@ -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 };
|
||||
}
|
||||
6
dist/utils/grab-db-backup-file-name.d.ts
vendored
6
dist/utils/grab-db-backup-file-name.d.ts
vendored
@ -1,6 +0,0 @@
|
||||
import type { BunSQLiteConfig } from "../types";
|
||||
type Params = {
|
||||
config: BunSQLiteConfig;
|
||||
};
|
||||
export default function grabDBBackupFileName({ config }: Params): string;
|
||||
export {};
|
||||
4
dist/utils/grab-db-backup-file-name.js
vendored
4
dist/utils/grab-db-backup-file-name.js
vendored
@ -1,4 +0,0 @@
|
||||
export default function grabDBBackupFileName({ config }) {
|
||||
const new_db_file_name = `${config.db_name}-${Date.now()}`;
|
||||
return new_db_file_name;
|
||||
}
|
||||
10
dist/utils/grab-db-dir.d.ts
vendored
10
dist/utils/grab-db-dir.d.ts
vendored
@ -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 {};
|
||||
14
dist/utils/grab-db-dir.js
vendored
14
dist/utils/grab-db-dir.js
vendored
@ -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 };
|
||||
}
|
||||
1
dist/utils/grab-db-schema.d.ts
vendored
1
dist/utils/grab-db-schema.d.ts
vendored
@ -1 +0,0 @@
|
||||
export default function grabDbSchema(): Promise<import("../types").BUN_MARIADB_DatabaseSchemaType>;
|
||||
5
dist/utils/grab-db-schema.js
vendored
5
dist/utils/grab-db-schema.js
vendored
@ -1,5 +0,0 @@
|
||||
import init from "../functions/init";
|
||||
export default async function grabDbSchema() {
|
||||
const { dbSchema } = await init();
|
||||
return dbSchema;
|
||||
}
|
||||
@ -1,7 +0,0 @@
|
||||
import type { BunSQLiteQueryFieldValues, ServerQueryParam } from "../types";
|
||||
type Params<Q extends Record<string, any> = Record<string, any>> = {
|
||||
query: ServerQueryParam<Q>;
|
||||
ignore_select_fields?: boolean;
|
||||
};
|
||||
export default function grabJoinFieldsFromQueryObject<Q extends Record<string, any> = Record<string, any>, F extends string = string, T extends string = string>({ query, ignore_select_fields, }: Params<Q>): BunSQLiteQueryFieldValues<F, T>[];
|
||||
export {};
|
||||
55
dist/utils/grab-join-fields-from-query-object.js
vendored
55
dist/utils/grab-join-fields-from-query-object.js
vendored
@ -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;
|
||||
}
|
||||
6
dist/utils/grab-sorted-backups.d.ts
vendored
6
dist/utils/grab-sorted-backups.d.ts
vendored
@ -1,6 +0,0 @@
|
||||
import type { BunSQLiteConfig } from "../types";
|
||||
type Params = {
|
||||
config: BunSQLiteConfig;
|
||||
};
|
||||
export default function grabSortedBackups({ config }: Params): string[];
|
||||
export {};
|
||||
18
dist/utils/grab-sorted-backups.js
vendored
18
dist/utils/grab-sorted-backups.js
vendored
@ -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;
|
||||
}
|
||||
6
dist/utils/query-value-parser.d.ts
vendored
6
dist/utils/query-value-parser.d.ts
vendored
@ -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 {};
|
||||
21
dist/utils/query-value-parser.js
vendored
21
dist/utils/query-value-parser.js
vendored
@ -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;
|
||||
}
|
||||
2
dist/utils/sql-equality-parser.d.ts
vendored
2
dist/utils/sql-equality-parser.d.ts
vendored
@ -1,2 +0,0 @@
|
||||
import { ServerQueryEqualities } from "../types";
|
||||
export default function sqlEqualityParser(eq: (typeof ServerQueryEqualities)[number]): string;
|
||||
41
dist/utils/sql-equality-parser.js
vendored
41
dist/utils/sql-equality-parser.js
vendored
@ -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 "=";
|
||||
}
|
||||
}
|
||||
20
dist/utils/sql-gen-operator-gen.d.ts
vendored
20
dist/utils/sql-gen-operator-gen.d.ts
vendored
@ -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 {};
|
||||
133
dist/utils/sql-gen-operator-gen.js
vendored
133
dist/utils/sql-gen-operator-gen.js
vendored
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
11
dist/utils/sql-generator-gen-join-str.d.ts
vendored
11
dist/utils/sql-generator-gen-join-str.d.ts
vendored
@ -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 {};
|
||||
65
dist/utils/sql-generator-gen-join-str.js
vendored
65
dist/utils/sql-generator-gen-join-str.js
vendored
@ -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,
|
||||
};
|
||||
}
|
||||
22
dist/utils/sql-generator-gen-query-str.d.ts
vendored
22
dist/utils/sql-generator-gen-query-str.d.ts
vendored
@ -1,22 +0,0 @@
|
||||
import type { ServerQueryParam, TableSelectFieldsObject } from "../types";
|
||||
type Param<T extends {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
[key: string]: any;
|
||||
}> = {
|
||||
genObject?: ServerQueryParam<T>;
|
||||
selectFields?: (keyof T | TableSelectFieldsObject<T>)[];
|
||||
append_table_names?: boolean;
|
||||
table_name: string;
|
||||
full_text_match_str?: string;
|
||||
full_text_search_str?: string;
|
||||
};
|
||||
export default function sqlGenGenQueryStr<T extends {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
[key: string]: any;
|
||||
}>(params: Param<T>): {
|
||||
str: string;
|
||||
values: any[];
|
||||
};
|
||||
export {};
|
||||
193
dist/utils/sql-generator-gen-query-str.js
vendored
193
dist/utils/sql-generator-gen-query-str.js
vendored
@ -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 };
|
||||
}
|
||||
12
dist/utils/sql-generator-gen-search-str.d.ts
vendored
12
dist/utils/sql-generator-gen-search-str.d.ts
vendored
@ -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 {};
|
||||
92
dist/utils/sql-generator-gen-search-str.js
vendored
92
dist/utils/sql-generator-gen-search-str.js
vendored
@ -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 };
|
||||
}
|
||||
@ -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 {};
|
||||
13
dist/utils/sql-generator-grab-concat-str.js
vendored
13
dist/utils/sql-generator-grab-concat-str.js
vendored
@ -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;
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
import type { TableSelectFieldsObject } from "../types";
|
||||
type Param<T extends {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
[key: string]: any;
|
||||
}> = {
|
||||
selectFields: (keyof T | TableSelectFieldsObject<T>)[];
|
||||
append_table_names?: boolean;
|
||||
table_name: string;
|
||||
};
|
||||
export default function sqlGenGrabSelectFieldSQL<T extends {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
[key: string]: any;
|
||||
}>({ selectFields, append_table_names, table_name }: Param<T>): string;
|
||||
export {};
|
||||
@ -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;
|
||||
}
|
||||
25
dist/utils/sql-generator.d.ts
vendored
25
dist/utils/sql-generator.d.ts
vendored
@ -1,25 +0,0 @@
|
||||
import type { ServerQueryParam, SQLInsertGenValueType } from "../types";
|
||||
type Param<T extends {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
[key: string]: any;
|
||||
}> = {
|
||||
genObject?: ServerQueryParam<T>;
|
||||
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<T extends {
|
||||
[key: string]: any;
|
||||
} = {
|
||||
[key: string]: any;
|
||||
}>({ tableName, genObject, dbFullName, count }: Param<T>): Return;
|
||||
export {};
|
||||
303
dist/utils/sql-generator.js
vendored
303
dist/utils/sql-generator.js
vendored
@ -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<T>({
|
||||
// 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;
|
||||
// })();
|
||||
5
dist/utils/sql-insert-generator.d.ts
vendored
5
dist/utils/sql-insert-generator.d.ts
vendored
@ -1,5 +0,0 @@
|
||||
import type { SQLInsertGenParams, SQLInsertGenReturn } from "../types";
|
||||
/**
|
||||
* # SQL Insert Generator
|
||||
*/
|
||||
export default function sqlInsertGenerator({ tableName, data, dbFullName, }: SQLInsertGenParams): SQLInsertGenReturn | undefined;
|
||||
58
dist/utils/sql-insert-generator.js
vendored
58
dist/utils/sql-insert-generator.js
vendored
@ -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;
|
||||
}
|
||||
}
|
||||
6
dist/utils/trim-backups.d.ts
vendored
6
dist/utils/trim-backups.d.ts
vendored
@ -1,6 +0,0 @@
|
||||
import type { BunSQLiteConfig } from "../types";
|
||||
type Params = {
|
||||
config: BunSQLiteConfig;
|
||||
};
|
||||
export default function trimBackups({ config }: Params): void;
|
||||
export {};
|
||||
19
dist/utils/trim-backups.js
vendored
19
dist/utils/trim-backups.js
vendored
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/index.ts
12
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,
|
||||
|
||||
@ -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<DBResponseObject> {
|
||||
let CONNECTION: Connection | undefined;
|
||||
let results: T | null = null;
|
||||
|
||||
>({ query, values }: Param): Promise<DBResponseObject> {
|
||||
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 {
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user