Add Backup and Restore
This commit is contained in:
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
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();
|
||||
});
|
||||
}
|
||||
Vendored
+4
@@ -2,6 +2,8 @@
|
||||
import { program } from "commander";
|
||||
import schema from "./schema";
|
||||
import typedef from "./typedef";
|
||||
import backup from "./backup";
|
||||
import restore from "./restore";
|
||||
/**
|
||||
* # Describe Program
|
||||
*/
|
||||
@@ -14,6 +16,8 @@ program
|
||||
*/
|
||||
program.addCommand(schema());
|
||||
program.addCommand(typedef());
|
||||
program.addCommand(backup());
|
||||
program.addCommand(restore());
|
||||
/**
|
||||
* # Handle Unavailable Commands
|
||||
*/
|
||||
|
||||
Vendored
+2
@@ -0,0 +1,2 @@
|
||||
import { Command } from "commander";
|
||||
export default function (): Command;
|
||||
Vendored
+44
@@ -0,0 +1,44 @@
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
Vendored
+2
@@ -7,6 +7,7 @@ import dbSchemaToTypeDef from "../lib/sqlite/schema-to-typedef";
|
||||
import _ from "lodash";
|
||||
import { DefaultFields } from "../types";
|
||||
import appendDefaultFieldsToDbSchema from "../utils/append-default-fields-to-db-schema";
|
||||
import chalk from "chalk";
|
||||
export default function () {
|
||||
return new Command("schema")
|
||||
.description("Build DB From Schema")
|
||||
@@ -32,6 +33,7 @@ export default function () {
|
||||
dst_file: out_file,
|
||||
});
|
||||
}
|
||||
console.log(`${chalk.bold(chalk.green(`DB Schema setup success!`))}`);
|
||||
process.exit();
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+2
@@ -4,6 +4,7 @@ import dbSchemaToTypeDef from "../lib/sqlite/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")
|
||||
@@ -23,6 +24,7 @@ export default function () {
|
||||
console.error(``);
|
||||
process.exit(1);
|
||||
}
|
||||
console.log(`${chalk.bold(chalk.green(`Typedef gen success!`))}`);
|
||||
process.exit();
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
export declare const AppData: {
|
||||
readonly ConfigFileName: "bun-sqlite.config.ts";
|
||||
readonly MaxBackups: 10;
|
||||
};
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
export const AppData = {
|
||||
ConfigFileName: "bun-sqlite.config.ts",
|
||||
MaxBackups: 10,
|
||||
};
|
||||
|
||||
Vendored
+3
-3
@@ -1,16 +1,16 @@
|
||||
import { Database } from "bun:sqlite";
|
||||
import path from "node:path";
|
||||
import * as sqliteVec from "sqlite-vec";
|
||||
import grabDirNames from "../../data/grab-dir-names";
|
||||
import init from "../../functions/init";
|
||||
import grabDBDir from "../../utils/grab-db-dir";
|
||||
const { ROOT_DIR } = grabDirNames();
|
||||
const { config } = await init();
|
||||
let db_dir = ROOT_DIR;
|
||||
if (config.db_dir) {
|
||||
db_dir = config.db_dir;
|
||||
}
|
||||
const DBFilePath = path.join(db_dir, config.db_name);
|
||||
const DbClient = new Database(DBFilePath, {
|
||||
const { db_file_path } = grabDBDir({ config });
|
||||
const DbClient = new Database(db_file_path, {
|
||||
create: true,
|
||||
});
|
||||
sqliteVec.load(DbClient);
|
||||
|
||||
Vendored
+1
@@ -997,6 +997,7 @@ export type BunSQLiteConfig = {
|
||||
* The Directory for backups
|
||||
*/
|
||||
db_backup_dir: string;
|
||||
max_backups?: number;
|
||||
/**
|
||||
* The Root Directory for the DB file and schema
|
||||
*/
|
||||
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
type Params = {
|
||||
backup_name: string;
|
||||
};
|
||||
export default function grabBackupData({ backup_name }: Params): {
|
||||
backup_date: Date;
|
||||
backup_date_timestamp: number;
|
||||
origin_backup_name: string;
|
||||
};
|
||||
export {};
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
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
@@ -0,0 +1,6 @@
|
||||
import type { BunSQLiteConfig } from "../types";
|
||||
type Params = {
|
||||
config: BunSQLiteConfig;
|
||||
};
|
||||
export default function grabDBBackupFileName({ config }: Params): string;
|
||||
export {};
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
export default function grabDBBackupFileName({ config }) {
|
||||
const new_db_file_name = `${config.db_name}-${Date.now()}`;
|
||||
return new_db_file_name;
|
||||
}
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
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 {};
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
import path from "path";
|
||||
import grabDirNames from "../data/grab-dir-names";
|
||||
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 = path.resolve(db_dir, config.db_backup_dir);
|
||||
const db_file_path = path.resolve(db_dir, config.db_name);
|
||||
return { db_dir, backup_dir, db_file_path };
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import type { BunSQLiteConfig } from "../types";
|
||||
type Params = {
|
||||
config: BunSQLiteConfig;
|
||||
};
|
||||
export default function grabSortedBackups({ config }: Params): string[];
|
||||
export {};
|
||||
Vendored
+18
@@ -0,0 +1,18 @@
|
||||
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;
|
||||
}
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
import type { BunSQLiteConfig } from "../types";
|
||||
type Params = {
|
||||
config: BunSQLiteConfig;
|
||||
};
|
||||
export default function trimBackups({ config }: Params): void;
|
||||
export {};
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user