@@ -12,6 +12,8 @@ import Statement from "../../database/statement";
12
12
import { getCopyUi } from "./copyUI" ;
13
13
import { getAdvisedIndexesStatement , getIndexesStatement , getMTIStatement , getAuthoritiesStatement , getObjectLocksStatement , getRecordLocksStatement } from "./statements" ;
14
14
import { BasicSQLObject } from "../../types" ;
15
+ import { TextDecoder } from "util" ;
16
+ import { parse } from "csv/sync" ;
15
17
16
18
const itemIcons = {
17
19
"table" : `split-horizontal` ,
@@ -393,12 +395,105 @@ export default class schemaBrowser {
393
395
this . refresh ( node ) ;
394
396
}
395
397
}
398
+ } ) ,
399
+
400
+ vscode . commands . registerCommand ( `vscode-db2i.importData` , async ( ) => {
401
+ vscode . window . withProgress ( { location : vscode . ProgressLocation . Window , title : `Generating SQL` } , async ( ) => {
402
+ try {
403
+ const uri = await this . pickFile ( ) ;
404
+ if ( ! uri ) { return ; }
405
+ const data = await this . readFile ( uri ) ;
406
+ const tableName = `SYSIBM.SYSDUMMY1` ;
407
+ let ext : string = ( uri . fsPath . split ( '.' ) . pop ( ) || '' ) . toLowerCase ( ) ;
408
+
409
+ if ( ext != `csv` && ext != `json` ) {
410
+ ext = await vscode . window . showQuickPick ( [ 'csv' , 'json' ] , { placeHolder : 'What format is this file?' } ) ;
411
+ if ( ! ext ) { return ; }
412
+ }
413
+
414
+ let rows : any [ ] = [ ] ;
415
+
416
+ if ( ext === `csv` ) {
417
+ rows = parse ( data , {
418
+ columns : true ,
419
+ cast : true
420
+ } ) ;
421
+ if ( ! rows . length ) {
422
+ vscode . window . showWarningMessage ( 'No rows found.' ) ;
423
+ return ;
424
+ }
425
+
426
+ // Get the headers and types
427
+ // Using the first two rows, first row is header names, second row will tell us the type
428
+
429
+ } else if ( ext === `json` ) {
430
+ rows = JSON . parse ( data ) ;
431
+ if ( ! Array . isArray ( rows ) ) {
432
+ throw new Error ( 'Unsupported JSON format: expected an array of objects.' ) ;
433
+ }
434
+ }
435
+
436
+ if ( ! rows . length ) {
437
+ vscode . window . showWarningMessage ( 'No rows found.' ) ;
438
+ return ;
439
+ }
440
+
441
+ // Get headers using the first row of data
442
+ const colNames = Object . keys ( rows [ 0 ] ) ;
443
+ const cols = colNames . join ( ', ' ) ;
444
+
445
+ // Generate the INSERT statement
446
+ let content : string = `INSERT INTO SYSIBM.SYSDUMMY1 (${ cols } ) \nVALUES\n` ;
447
+ for ( let i = 0 ; i < rows . length ; i ++ ) {
448
+ const row = rows [ i ] ;
449
+ let allValues = [ ] ;
450
+ for ( const col of colNames ) {
451
+ const val = row [ col ] ;
452
+ if ( typeof val === `string` ) {
453
+ allValues . push ( `'${ val } '` ) ;
454
+ } else
455
+ allValues . push ( val ) ;
456
+ }
457
+ content += ` (${ allValues . join ( ', ' ) } )` ;
458
+
459
+ // If not at last item yet, append a comma
460
+ if ( i != rows . length - 1 ) {
461
+ content += `,\n` ;
462
+ }
463
+ }
464
+
465
+ content += `;` ;
466
+
467
+ // Open the generated SQL in a new file
468
+ const textDoc = await vscode . workspace . openTextDocument ( { language : `sql` , content } ) ;
469
+ await vscode . window . showTextDocument ( textDoc ) ;
470
+ } catch ( e ) {
471
+ vscode . window . showErrorMessage ( e . message ) ;
472
+ }
473
+ } ) ;
396
474
} )
397
475
)
398
476
399
477
getInstance ( ) . subscribe ( context , `connected` , `db2i-clearCacheAndRefresh` , ( ) => this . clearCacheAndRefresh ( ) ) ;
400
478
}
401
479
480
+ async pickFile ( ) : Promise < vscode . Uri | undefined > {
481
+ const res = await vscode . window . showOpenDialog ( {
482
+ canSelectMany : false ,
483
+ openLabel : 'Import' ,
484
+ filters : {
485
+ 'Data files' : [ 'csv' , 'json' ] ,
486
+ 'All files' : [ '*' ]
487
+ }
488
+ } ) ;
489
+ return res ?. [ 0 ] ;
490
+ }
491
+
492
+ async readFile ( uri : vscode . Uri ) : Promise < string > {
493
+ const ab = await vscode . workspace . fs . readFile ( uri ) ;
494
+ return new TextDecoder ( 'utf-8' ) . decode ( ab ) ;
495
+ }
496
+
402
497
clearCacheAndRefresh ( ) {
403
498
this . cache = { } ;
404
499
this . refresh ( ) ;
0 commit comments