@@ -73,37 +73,28 @@ function displayResults(results: any, isJson: boolean, isPretty: boolean) {
7373 results . forEach ( ( item ) => {
7474 Object . keys ( item ) . forEach ( ( key ) => keys . add ( key ) ) ;
7575 } ) ;
76-
76+
7777 const headers = Array . from ( keys ) ;
78-
78+
7979 // Calculate column widths (min 10, max 40)
8080 const columnWidths = headers . map ( ( header ) => {
81- const values = results . map ( ( item ) =>
81+ const values = results . map ( ( item ) =>
8282 item [ header ] !== undefined ? String ( item [ header ] ) : ''
8383 ) ;
84-
85- const maxWidth = Math . max (
86- header . length ,
87- ...values . map ( ( v ) => v . length )
88- ) ;
89-
84+
85+ const maxWidth = Math . max ( header . length , ...values . map ( ( v ) => v . length ) ) ;
86+
9087 return Math . min ( 40 , Math . max ( 10 , maxWidth ) ) ;
9188 } ) ;
92-
89+
9390 // Print headers
9491 console . log (
95- headers
96- . map ( ( header , i ) => chalk . bold ( header . padEnd ( columnWidths [ i ] ) ) )
97- . join ( ' | ' )
92+ headers . map ( ( header , i ) => chalk . bold ( header . padEnd ( columnWidths [ i ] ) ) ) . join ( ' | ' )
9893 ) ;
99-
94+
10095 // Print separator
101- console . log (
102- headers
103- . map ( ( _ , i ) => '-' . repeat ( columnWidths [ i ] ) )
104- . join ( '-+-' )
105- ) ;
106-
96+ console . log ( headers . map ( ( _ , i ) => '-' . repeat ( columnWidths [ i ] ) ) . join ( '-+-' ) ) ;
97+
10798 // Print rows
10899 results . forEach ( ( row ) => {
109100 console . log (
@@ -120,7 +111,7 @@ function displayResults(results: any, isJson: boolean, isPretty: boolean) {
120111 console . log ( results ) ;
121112 }
122113 }
123-
114+
124115 // Print record count for arrays
125116 if ( Array . isArray ( results ) ) {
126117 console . log ( chalk . cyan ( `\n${ results . length } record(s) returned` ) ) ;
@@ -134,7 +125,7 @@ async function executeQuery(queryLeaf: QueryLeaf, sql: string, isJson: boolean,
134125 const startTime = Date . now ( ) ;
135126 const results = await queryLeaf . execute ( sql ) ;
136127 const duration = Date . now ( ) - startTime ;
137-
128+
138129 displayResults ( results , isJson , isPretty ) ;
139130 console . log ( chalk . gray ( `\nExecution time: ${ duration } ms` ) ) ;
140131 return true ;
@@ -147,39 +138,40 @@ async function executeQuery(queryLeaf: QueryLeaf, sql: string, isJson: boolean,
147138// Main function
148139async function main ( ) {
149140 const mongoClient = new MongoClient ( argv . uri as string ) ;
150-
141+
151142 try {
152143 console . log ( chalk . blue ( `Connecting to MongoDB: ${ argv . uri } ` ) ) ;
153144 await mongoClient . connect ( ) ;
154145 console . log ( chalk . green ( `Connected to MongoDB, using database: ${ argv . db } ` ) ) ;
155-
146+
156147 const queryLeaf = new QueryLeaf ( mongoClient , argv . db as string ) ;
157-
148+
158149 // Execute from file
159150 if ( argv . file ) {
160151 const filePath = path . resolve ( process . cwd ( ) , argv . file as string ) ;
161152 if ( ! fs . existsSync ( filePath ) ) {
162153 console . error ( chalk . red ( `File not found: ${ filePath } ` ) ) ;
163154 process . exit ( 1 ) ;
164155 }
165-
156+
166157 console . log ( chalk . blue ( `Executing SQL from file: ${ filePath } ` ) ) ;
167158 const sqlContent = fs . readFileSync ( filePath , 'utf-8' ) ;
168-
159+
169160 // Split file content by semicolons to get individual queries
170161 // Ignore semicolons inside quotes
171- const queries = sqlContent
172- . match ( / (?: [ ^ ; " ' ] + | " (?: \\ " | [ ^ " ] ) * " | ' (?: \\ ' | [ ^ ' ] ) * ' ) + / g)
173- ?. map ( q => q . trim ( ) )
174- . filter ( q => q . length > 0 ) || [ ] ;
175-
162+ const queries =
163+ sqlContent
164+ . match ( / (?: [ ^ ; " ' ] + | " (?: \\ " | [ ^ " ] ) * " | ' (?: \\ ' | [ ^ ' ] ) * ' ) + / g)
165+ ?. map ( ( q ) => q . trim ( ) )
166+ . filter ( ( q ) => q . length > 0 ) || [ ] ;
167+
176168 if ( queries . length === 0 ) {
177169 console . log ( chalk . yellow ( 'No queries found in file.' ) ) ;
178170 process . exit ( 0 ) ;
179171 }
180-
172+
181173 console . log ( chalk . blue ( `Found ${ queries . length } queries in file.` ) ) ;
182-
174+
183175 for ( let i = 0 ; i < queries . length ; i ++ ) {
184176 const query = queries [ i ] ;
185177 console . log ( chalk . blue ( `\nExecuting query ${ i + 1 } /${ queries . length } :` ) ) ;
@@ -188,102 +180,118 @@ async function main() {
188180 }
189181 // Execute single query
190182 else if ( argv . query ) {
191- await executeQuery ( queryLeaf , argv . query as string , argv . json as boolean , argv . pretty as boolean ) ;
183+ await executeQuery (
184+ queryLeaf ,
185+ argv . query as string ,
186+ argv . json as boolean ,
187+ argv . pretty as boolean
188+ ) ;
192189 }
193190 // Interactive mode
194191 else if ( argv . interactive ) {
195- console . log ( chalk . blue ( 'Starting interactive SQL shell. Type .help for commands, .exit to quit.' ) ) ;
192+ console . log (
193+ chalk . blue ( 'Starting interactive SQL shell. Type .help for commands, .exit to quit.' )
194+ ) ;
196195 console . log ( chalk . blue ( 'Connected to database: ' + argv . db ) ) ;
197-
196+
198197 const rl = readline . createInterface ( {
199198 input : process . stdin ,
200199 output : process . stdout ,
201200 prompt : 'sql> ' ,
202201 terminal : true ,
203202 } ) ;
204-
203+
205204 rl . prompt ( ) ;
206-
205+
207206 let multilineQuery = '' ;
208-
207+
209208 rl . on ( 'line' , async ( line ) => {
210209 const trimmedLine = line . trim ( ) ;
211-
210+
212211 // Handle special commands
213212 if ( trimmedLine === '.exit' || trimmedLine === '.quit' ) {
214213 rl . close ( ) ;
215214 return ;
216215 }
217-
216+
218217 if ( trimmedLine === '.help' ) {
219218 console . log ( chalk . blue ( 'Available commands:' ) ) ;
220219 console . log ( ' .help - Show this help message' ) ;
221220 console . log ( ' .tables - List all collections in the database' ) ;
222221 console . log ( ' .exit - Exit the shell' ) ;
223222 console . log ( ' .quit - Exit the shell' ) ;
224223 console . log ( ' .clear - Clear the current query buffer' ) ;
225- console . log ( ' .json - Toggle JSON output mode (currently ' + ( argv . json ? 'ON' : 'OFF' ) + ')' ) ;
224+ console . log (
225+ ' .json - Toggle JSON output mode (currently ' + ( argv . json ? 'ON' : 'OFF' ) + ')'
226+ ) ;
226227 console . log ( '\nSQL queries can span multiple lines. End with a semicolon to execute.' ) ;
227228 rl . prompt ( ) ;
228229 return ;
229230 }
230-
231+
231232 if ( trimmedLine === '.tables' ) {
232233 try {
233- const collections = await mongoClient . db ( argv . db as string ) . listCollections ( ) . toArray ( ) ;
234+ const collections = await mongoClient
235+ . db ( argv . db as string )
236+ . listCollections ( )
237+ . toArray ( ) ;
234238 console . log ( chalk . blue ( 'Collections in database:' ) ) ;
235- collections . forEach ( collection => {
239+ collections . forEach ( ( collection ) => {
236240 console . log ( ` ${ collection . name } ` ) ;
237241 } ) ;
238242 } catch ( error ) {
239- console . error ( chalk . red ( `Error listing collections: ${ error instanceof Error ? error . message : String ( error ) } ` ) ) ;
243+ console . error (
244+ chalk . red (
245+ `Error listing collections: ${ error instanceof Error ? error . message : String ( error ) } `
246+ )
247+ ) ;
240248 }
241249 rl . prompt ( ) ;
242250 return ;
243251 }
244-
252+
245253 if ( trimmedLine === '.clear' ) {
246254 multilineQuery = '' ;
247255 console . log ( chalk . yellow ( 'Query buffer cleared.' ) ) ;
248256 rl . prompt ( ) ;
249257 return ;
250258 }
251-
259+
252260 if ( trimmedLine === '.json' ) {
253261 argv . json = ! argv . json ;
254262 console . log ( chalk . blue ( `JSON output mode: ${ argv . json ? 'ON' : 'OFF' } ` ) ) ;
255263 rl . prompt ( ) ;
256264 return ;
257265 }
258-
266+
259267 // Handle SQL query
260268 multilineQuery += line + ' ' ;
261-
269+
262270 // Execute on semicolon
263271 if ( trimmedLine . endsWith ( ';' ) ) {
264272 const query = multilineQuery . trim ( ) ;
265273 multilineQuery = '' ;
266-
267- if ( query . length > 1 ) { // Handle empty queries (just ";")
274+
275+ if ( query . length > 1 ) {
276+ // Handle empty queries (just ";")
268277 await executeQuery ( queryLeaf , query , argv . json as boolean , argv . pretty as boolean ) ;
269278 }
270279 } else {
271280 // Show continuation prompt for multiline
272281 process . stdout . write ( '... ' ) ;
273282 return ;
274283 }
275-
284+
276285 rl . prompt ( ) ;
277286 } ) ;
278-
287+
279288 rl . on ( 'close' , ( ) => {
280289 console . log ( chalk . blue ( '\nGoodbye!' ) ) ;
281290 process . exit ( 0 ) ;
282291 } ) ;
283-
292+
284293 return ; // Keep process running for interactive mode
285- }
286- else {
294+ } else {
287295 console . log ( chalk . yellow ( 'No query or file specified and not in interactive mode.' ) ) ;
288296 console . log ( chalk . yellow ( 'Use --help to see available options.' ) ) ;
289297 }
@@ -300,8 +308,10 @@ async function main() {
300308
301309// Run the main function
302310if ( require . main === module ) {
303- main ( ) . catch ( error => {
304- console . error ( chalk . red ( `Unhandled error: ${ error instanceof Error ? error . message : String ( error ) } ` ) ) ;
311+ main ( ) . catch ( ( error ) => {
312+ console . error (
313+ chalk . red ( `Unhandled error: ${ error instanceof Error ? error . message : String ( error ) } ` )
314+ ) ;
305315 process . exit ( 1 ) ;
306316 } ) ;
307- }
317+ }
0 commit comments