mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-27 21:56:00 +00:00
auto-detect CSV delimiter
This commit is contained in:
@@ -18,11 +18,14 @@ function readFirstLine(file) {
|
|||||||
}
|
}
|
||||||
if (reader.hasNextLine()) {
|
if (reader.hasNextLine()) {
|
||||||
reader.nextLine((err, line) => {
|
reader.nextLine((err, line) => {
|
||||||
if (err) reject(err);
|
if (err) {
|
||||||
resolve(line);
|
reader.close(() => reject(err)); // Ensure reader is closed on error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reader.close(() => resolve(line)); // Ensure reader is closed after reading
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
resolve(null);
|
reader.close(() => resolve(null)); // Properly close if no lines are present
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -34,8 +34,9 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"csv": "^6.3.10",
|
"csv": "^6.3.10",
|
||||||
"dbgate-plugin-tools": "^1.0.7",
|
"dbgate-plugin-tools": "^1.0.7",
|
||||||
|
"line-reader": "^0.4.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"webpack": "^5.91.0",
|
"webpack": "^5.91.0",
|
||||||
"webpack-cli": "^5.1.4"
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,32 @@ const zipObject = require('lodash/zipObject');
|
|||||||
const csv = require('csv');
|
const csv = require('csv');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const stream = require('stream');
|
const stream = require('stream');
|
||||||
|
const lineReader = require('line-reader');
|
||||||
|
|
||||||
let dbgateApi;
|
let dbgateApi;
|
||||||
|
|
||||||
|
function readFirstLine(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
lineReader.open(file, (err, reader) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (reader.hasNextLine()) {
|
||||||
|
reader.nextLine((err, line) => {
|
||||||
|
if (err) {
|
||||||
|
reader.close(() => reject(err)); // Ensure reader is closed on error
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reader.close(() => resolve(line)); // Ensure reader is closed after reading
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reader.close(() => resolve(null)); // Properly close if no lines are present
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
class CsvPrepareStream extends stream.Transform {
|
class CsvPrepareStream extends stream.Transform {
|
||||||
constructor({ header }) {
|
constructor({ header }) {
|
||||||
super({ objectMode: true });
|
super({ objectMode: true });
|
||||||
@@ -46,6 +70,22 @@ class CsvPrepareStream extends stream.Transform {
|
|||||||
|
|
||||||
async function reader({ fileName, encoding = 'utf-8', header = true, delimiter, limitRows = undefined }) {
|
async function reader({ fileName, encoding = 'utf-8', header = true, delimiter, limitRows = undefined }) {
|
||||||
console.log(`Reading file ${fileName}`);
|
console.log(`Reading file ${fileName}`);
|
||||||
|
const downloadedFile = await dbgateApi.download(fileName);
|
||||||
|
|
||||||
|
if (!delimiter) {
|
||||||
|
// auto detect delimiter
|
||||||
|
// read first line from downloadedFile
|
||||||
|
const firstLine = await readFirstLine(downloadedFile);
|
||||||
|
if (firstLine) {
|
||||||
|
const delimiterCounts = {
|
||||||
|
',': firstLine.replace(/[^,]/g, '').length,
|
||||||
|
';': firstLine.replace(/[^;]/g, '').length,
|
||||||
|
'|': firstLine.replace(/[^|]/g, '').length,
|
||||||
|
};
|
||||||
|
|
||||||
|
delimiter = Object.keys(delimiterCounts).reduce((a, b) => (delimiterCounts[a] > delimiterCounts[b] ? a : b), ',');
|
||||||
|
}
|
||||||
|
}
|
||||||
const csvStream = csv.parse({
|
const csvStream = csv.parse({
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
delimiter,
|
delimiter,
|
||||||
@@ -53,7 +93,6 @@ async function reader({ fileName, encoding = 'utf-8', header = true, delimiter,
|
|||||||
to_line: limitRows ? limitRows + 1 : undefined,
|
to_line: limitRows ? limitRows + 1 : undefined,
|
||||||
ltrim: true,
|
ltrim: true,
|
||||||
});
|
});
|
||||||
const downloadedFile = await dbgateApi.download(fileName);
|
|
||||||
const fileStream = fs.createReadStream(downloadedFile, encoding);
|
const fileStream = fs.createReadStream(downloadedFile, encoding);
|
||||||
const csvPrepare = new CsvPrepareStream({ header });
|
const csvPrepare = new CsvPrepareStream({ header });
|
||||||
fileStream.pipe(csvStream);
|
fileStream.pipe(csvStream);
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ const fileFormat = {
|
|||||||
name: 'delimiter',
|
name: 'delimiter',
|
||||||
label: 'Delimiter',
|
label: 'Delimiter',
|
||||||
options: [
|
options: [
|
||||||
|
{ name: 'Auto-detect', value: '' },
|
||||||
{ name: 'Comma (,)', value: ',' },
|
{ name: 'Comma (,)', value: ',' },
|
||||||
{ name: 'Semicolon (;)', value: ';' },
|
{ name: 'Semicolon (;)', value: ';' },
|
||||||
{ name: 'Tab', value: '\t' },
|
{ name: 'Tab', value: '\t' },
|
||||||
|
|||||||
Reference in New Issue
Block a user