diff --git a/packages/api/src/shell/index.js b/packages/api/src/shell/index.js index 905c3e6e..2e3a42b8 100644 --- a/packages/api/src/shell/index.js +++ b/packages/api/src/shell/index.js @@ -8,6 +8,7 @@ const consoleObjectWriter = require('./consoleObjectWriter'); const jsonLinesWriter = require('./jsonLinesWriter'); const jsonArrayWriter = require('./jsonArrayWriter'); const jsonLinesReader = require('./jsonLinesReader'); +const sqlDataWriter = require('./sqlDataWriter'); const jslDataReader = require('./jslDataReader'); const archiveWriter = require('./archiveWriter'); const archiveReader = require('./archiveReader'); @@ -29,6 +30,7 @@ const dbgateApi = { jsonLinesWriter, jsonArrayWriter, jsonLinesReader, + sqlDataWriter, fakeObjectReader, consoleObjectWriter, jslDataReader, diff --git a/packages/api/src/shell/sqlDataWriter.js b/packages/api/src/shell/sqlDataWriter.js new file mode 100644 index 00000000..9783f388 --- /dev/null +++ b/packages/api/src/shell/sqlDataWriter.js @@ -0,0 +1,48 @@ +const fs = require('fs'); +const stream = require('stream'); +const path = require('path'); +const { driverBase } = require('dbgate-tools'); + +class SqlizeStream extends stream.Transform { + constructor({ fileName }) { + super({ objectMode: true }); + this.wasHeader = false; + this.tableName = path.parse(fileName).name; + } + _transform(chunk, encoding, done) { + let skip = false; + if (!this.wasHeader) { + if ( + chunk.__isStreamHeader || + // TODO remove isArray test + Array.isArray(chunk.columns) + ) { + skip = true; + this.tableName = chunk.pureName; + } + this.wasHeader = true; + } + if (!skip) { + const dmp = driverBase.createDumper(); + dmp.put( + '^insert ^into %f (%,i) ^values (%,v);\n', + { pureName: this.tableName }, + Object.keys(chunk), + Object.values(chunk) + ); + this.push(dmp.s); + } + done(); + } +} + +async function sqlDataWriter({ fileName, driver, encoding = 'utf-8' }) { + console.log(`Writing file ${fileName}`); + const stringify = new SqlizeStream({ fileName }); + const fileStream = fs.createWriteStream(fileName, encoding); + stringify.pipe(fileStream); + stringify['finisher'] = fileStream; + return stringify; +} + +module.exports = sqlDataWriter; diff --git a/packages/web/src/plugins/fileformats.ts b/packages/web/src/plugins/fileformats.ts index 6f91fa08..e1008289 100644 --- a/packages/web/src/plugins/fileformats.ts +++ b/packages/web/src/plugins/fileformats.ts @@ -15,6 +15,13 @@ const jsonFormat = { writerFunc: 'jsonArrayWriter', }; +const sqlFormat = { + storageType: 'sql', + extension: 'sql', + name: 'SQL', + writerFunc: 'sqlDataWriter', +}; + const jsonlQuickExport = { label: 'JSON lines', extension: 'jsonl', @@ -37,8 +44,19 @@ const jsonQuickExport = { }), }; +const sqlQuickExport = { + label: 'SQL', + extension: 'sql', + createWriter: fileName => ({ + functionName: 'sqlDataWriter', + props: { + fileName, + }, + }), +}; + export function buildFileFormats(plugins): FileFormatDefinition[] { - const res = [jsonlFormat, jsonFormat]; + const res = [jsonlFormat, jsonFormat, sqlFormat]; for (const { content } of plugins) { const { fileFormats } = content; if (fileFormats) res.push(...fileFormats); @@ -47,7 +65,7 @@ export function buildFileFormats(plugins): FileFormatDefinition[] { } export function buildQuickExports(plugins): QuickExportDefinition[] { - const res = [jsonQuickExport, jsonlQuickExport]; + const res = [jsonQuickExport, jsonlQuickExport, sqlQuickExport]; for (const { content } of plugins) { if (content.quickExports) res.push(...content.quickExports); }