@@ -4,6 +4,8 @@ import { Database } from "../../storage/db"
44import { Database as BunDatabase } from "bun:sqlite"
55import { UI } from "../ui"
66import { cmd } from "./cmd"
7+ import { JsonMigration } from "../../storage/json-migration"
8+ import { EOL } from "os"
79
810const QueryCommand = cmd ( {
911 command : "$0 [query]" ,
@@ -58,11 +60,59 @@ const PathCommand = cmd({
5860 } ,
5961} )
6062
63+ const MigrateCommand = cmd ( {
64+ command : "migrate" ,
65+ describe : "migrate JSON data to SQLite (merges with existing data)" ,
66+ handler : async ( ) => {
67+ const sqlite = new BunDatabase ( Database . Path )
68+ const tty = process . stderr . isTTY
69+ const width = 36
70+ const orange = "\x1b[38;5;214m"
71+ const muted = "\x1b[0;2m"
72+ const reset = "\x1b[0m"
73+ let last = - 1
74+ if ( tty ) process . stderr . write ( "\x1b[?25l" )
75+ try {
76+ const stats = await JsonMigration . run ( sqlite , {
77+ progress : ( event ) => {
78+ const percent = Math . floor ( ( event . current / event . total ) * 100 )
79+ if ( percent === last ) return
80+ last = percent
81+ if ( tty ) {
82+ const fill = Math . round ( ( percent / 100 ) * width )
83+ const bar = `${ "■" . repeat ( fill ) } ${ "・" . repeat ( width - fill ) } `
84+ process . stderr . write (
85+ `\r${ orange } ${ bar } ${ percent . toString ( ) . padStart ( 3 ) } %${ reset } ${ muted } ${ event . current } /${ event . total } ${ reset } ` ,
86+ )
87+ } else {
88+ process . stderr . write ( `sqlite-migration:${ percent } ${ EOL } ` )
89+ }
90+ } ,
91+ } )
92+ if ( tty ) process . stderr . write ( "\n" )
93+ if ( tty ) process . stderr . write ( "\x1b[?25h" )
94+ else process . stderr . write ( `sqlite-migration:done${ EOL } ` )
95+ UI . println (
96+ `Migration complete: ${ stats . projects } projects, ${ stats . sessions } sessions, ${ stats . messages } messages` ,
97+ )
98+ if ( stats . errors . length > 0 ) {
99+ UI . println ( `${ stats . errors . length } errors occurred during migration` )
100+ }
101+ } catch ( err ) {
102+ if ( tty ) process . stderr . write ( "\x1b[?25h" )
103+ UI . error ( `Migration failed: ${ err instanceof Error ? err . message : String ( err ) } ` )
104+ process . exit ( 1 )
105+ } finally {
106+ sqlite . close ( )
107+ }
108+ } ,
109+ } )
110+
61111export const DbCommand = cmd ( {
62112 command : "db" ,
63113 describe : "database tools" ,
64114 builder : ( yargs : Argv ) => {
65- return yargs . command ( QueryCommand ) . command ( PathCommand ) . demandCommand ( )
115+ return yargs . command ( QueryCommand ) . command ( PathCommand ) . command ( MigrateCommand ) . demandCommand ( )
66116 } ,
67117 handler : ( ) => { } ,
68118} )
0 commit comments