Skip to content

Commit d56ef99

Browse files
committed
Create INSERT statement based on imported csv or json
1 parent 7a84ed2 commit d56ef99

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

src/contributes.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@
110110
"command": "vscode-db2i.getStatementUri",
111111
"title": "Copy sharable statement URI",
112112
"category": "Db2 for i"
113+
},
114+
{
115+
"command": "vscode-db2i.importData",
116+
"title": "Generate Insert from File",
117+
"category": "Db2 for IBM i"
113118
}
114119
],
115120
"menus": {

src/views/schemaBrowser/index.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import Statement from "../../database/statement";
1212
import { getCopyUi } from "./copyUI";
1313
import { getAdvisedIndexesStatement, getIndexesStatement, getMTIStatement, getAuthoritiesStatement, getObjectLocksStatement, getRecordLocksStatement } from "./statements";
1414
import { BasicSQLObject } from "../../types";
15+
import { TextDecoder } from "util";
16+
import { parse } from "csv/sync";
1517

1618
const itemIcons = {
1719
"table": `split-horizontal`,
@@ -393,12 +395,105 @@ export default class schemaBrowser {
393395
this.refresh(node);
394396
}
395397
}
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+
});
396474
})
397475
)
398476

399477
getInstance().subscribe(context, `connected`, `db2i-clearCacheAndRefresh`, () => this.clearCacheAndRefresh());
400478
}
401479

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+
402497
clearCacheAndRefresh() {
403498
this.cache = {};
404499
this.refresh();

0 commit comments

Comments
 (0)