db.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import type { Argv } from "yargs"
  2. import { spawn } from "child_process"
  3. import { Database } from "../../storage/db"
  4. import { Database as BunDatabase } from "bun:sqlite"
  5. import { UI } from "../ui"
  6. import { cmd } from "./cmd"
  7. const QueryCommand = cmd({
  8. command: "$0 [query]",
  9. describe: "open an interactive sqlite3 shell or run a query",
  10. builder: (yargs: Argv) => {
  11. return yargs
  12. .positional("query", {
  13. type: "string",
  14. describe: "SQL query to execute",
  15. })
  16. .option("format", {
  17. type: "string",
  18. choices: ["json", "tsv"],
  19. default: "tsv",
  20. describe: "Output format",
  21. })
  22. },
  23. handler: async (args: { query?: string; format: string }) => {
  24. const query = args.query as string | undefined
  25. if (query) {
  26. const db = new BunDatabase(Database.Path, { readonly: true })
  27. try {
  28. const result = db.query(query).all() as Record<string, unknown>[]
  29. if (args.format === "json") {
  30. console.log(JSON.stringify(result, null, 2))
  31. } else if (result.length > 0) {
  32. const keys = Object.keys(result[0])
  33. console.log(keys.join("\t"))
  34. for (const row of result) {
  35. console.log(keys.map((k) => row[k]).join("\t"))
  36. }
  37. }
  38. } catch (err) {
  39. UI.error(err instanceof Error ? err.message : String(err))
  40. process.exit(1)
  41. }
  42. db.close()
  43. return
  44. }
  45. const child = spawn("sqlite3", [Database.Path], {
  46. stdio: "inherit",
  47. })
  48. await new Promise((resolve) => child.on("close", resolve))
  49. },
  50. })
  51. const PathCommand = cmd({
  52. command: "path",
  53. describe: "print the database path",
  54. handler: () => {
  55. console.log(Database.Path)
  56. },
  57. })
  58. export const DbCommand = cmd({
  59. command: "db",
  60. describe: "database tools",
  61. builder: (yargs: Argv) => {
  62. return yargs.command(QueryCommand).command(PathCommand).demandCommand()
  63. },
  64. handler: () => {},
  65. })