diff --git a/index.js b/index.js index ea015e1..2c70f3d 100644 --- a/index.js +++ b/index.js @@ -1,45 +1,52 @@ -import fs from "node:fs/promises" -import { existsSync } from "node:fs" -import { createIfNot } from "./utils/fileUtils.mjs" -import path from "node:path" +import fs from "node:fs/promises"; +import { existsSync } from "node:fs"; +import { createIfNot } from "./utils/fileUtils.mjs"; +import { logEvents } from "./middleware/logEvents.js"; +import path from "node:path"; async function writeSQL(statement, saveFileAs = "") { try { - const destinationFile = process.argv[2] || saveFileAs + const destinationFile = process.argv[2] || saveFileAs; if (!destinationFile) { - throw new Error("Missing saveFileAs parameter") + logEvents(`Missing saveFileAs parameter: ${destinationFile}`, "fileSystemError.txt"); + throw new Error("Missing saveFileAs parameter"); } - createIfNot(path.resolve(`./sql/${destinationFile}`)) - await fs.writeFile(`sql/${process.argv[2]}.sql`, statement) + createIfNot(path.resolve(`./sql/${destinationFile}`)); + await fs.writeFile(`sql/${process.argv[2]}.sql`, statement); } catch (err) { - console.log(err) + logEvents(`${err}`, "Error.txt"); + console.log(err); } } async function readCSV(csvFileName = "") { try { - const fileAndTableName = process.argv[2] || csvFileName + const fileAndTableName = process.argv[2] || csvFileName; if (!fileAndTableName) { - throw new Error("Missing csvFileName parameter") + logEvents(`Missing csvFileName parameter: ${fileAndTableName}`, "fileSystemError.txt"); + throw new Error("Missing csvFileName parameter"); } if (!existsSync(path.resolve(`./csv/${fileAndTableName}.csv`))) { - console.log("file not found") - return + logEvents(`File not found: ./csv${fileAndTableName}`, "fileSystemError.txt"); + console.log("file not found"); + return; } const data = await fs.readFile(`csv/${fileAndTableName}.csv`, { encoding: "utf8", - }) - const linesArray = data.split(/\r|\n/).filter(line => line) - const columnNames = linesArray.shift().split(",") - let beginSQLInsert = `INSERT INTO ${fileAndTableName} (` - columnNames.forEach(name => (beginSQLInsert += `${name}, `)) - beginSQLInsert = beginSQLInsert.slice(0, -2) + ")\nVALUES\n" - let values = "" + }); + const linesArray = data.split(/\r|\n/).filter(line => line); + const columnNames = linesArray.shift().split(","); + let beginSQLInsert = `INSERT INTO ${fileAndTableName} (`; + columnNames.forEach(name => (beginSQLInsert += `${name}, `)); + beginSQLInsert = beginSQLInsert.slice(0, -2) + ")\nVALUES\n"; + let values = ""; linesArray.forEach(line => { // Parses each line of CSV into field values array - const arr = line.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/) + const arr = line.split(/,(?=(?:(?:[^"]*"){2})*[^"]*$)/); if (arr.length > columnNames.length) { - console.log(arr) + console.log(arr); + logEvents(`Too Many Values in row ${arr.length} should be equal to ${columnNames.length}`, "fileSystemError.txt"); throw new Error("Too Many Values in row") } else if (arr.length < columnNames.length) { + logEvents(`Too Few Values in row ${arr.length} should be equal to ${columnNames.length}`, "fileSystemError.txt"); console.log(arr) throw new Error("Too Few Values in row") } @@ -55,20 +62,23 @@ async function readCSV(csvFileName = "") { else { // This wraps strings in quotes // also wraps timestamps - valueLine += `"${value}", ` + valueLine += `"${value}", `; } } - }) - valueLine = valueLine.slice(0, -2) + "),\n" - values += valueLine - }) - values = values.slice(0, -2) + ";" - const sqlStatement = beginSQLInsert + values + }); + valueLine = valueLine.slice(0, -2) + "),\n"; + values += valueLine; + }); + values = values.slice(0, -2) + ";"; + const sqlStatement = beginSQLInsert + values; // Write File - writeSQL(sqlStatement) + writeSQL(sqlStatement); + logEvents("Process Finished Successfully", "Success.txt"); } catch (err) { - console.log(err) + logEvents(`${err}`, "Error.txt"); + console.log(err); } } -readCSV() -console.log("Finished!") +readCSV(); + +console.log("Finished!"); diff --git a/logs/Error.txt b/logs/Error.txt new file mode 100644 index 0000000..5644305 --- /dev/null +++ b/logs/Error.txt @@ -0,0 +1,3 @@ +2023/12/23 13:37:19 28a519dc-d8f9-44fe-9192-51adeac5190a +Error: Missing csvFileName parameter + diff --git a/logs/fileSystemError.txt b/logs/fileSystemError.txt new file mode 100644 index 0000000..3d8610c --- /dev/null +++ b/logs/fileSystemError.txt @@ -0,0 +1,3 @@ +2023/12/23 13:37:19 1e2fd97e-b2dc-4097-ada5-f532c8841458 +Missing csvFileName parameter: + diff --git a/middleware/logEvents.js b/middleware/logEvents.js new file mode 100644 index 0000000..950ef42 --- /dev/null +++ b/middleware/logEvents.js @@ -0,0 +1,29 @@ +import { format } from "date-fns"; +import { v4 as uuid } from "uuid"; +import fs from "node:fs/promises"; +import { existsSync } from "node:fs"; +import path from "node:path"; + +const __filename = new URL(import.meta.url).pathname; +const __dirname = path.dirname(__filename); + +const logEvents = async (message, logName) => { + const dateTime = `${format(new Date(), "yyyy/MM/dd HH:mm:ss")}`; + const logItem = `${dateTime}\t${uuid()}\n${message}\n\n`; + //console.log(logItem); + if (!existsSync(path.join(__dirname, "..", "logs"))) { + await fs.mkdir(path.join(__dirname, "..", "logs")); + } + try { + await fs.appendFile(path.join(__dirname, "..", "logs", logName), logItem); + } catch (e) { + console.error(e); + const errorItem = `${dateTime}\t${uuid()}\t${e}\n\n`; + await fs.appendFile( + path.join(__dirname, "..", "logs", "errorLogs.txt"), + errorItem + ); + } +}; + +export { logEvents }; diff --git a/package-lock.json b/package-lock.json index dafac35..6d27599 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,10 @@ "name": "csv-to-sql-insert", "version": "0.1.0", "license": "MIT", + "dependencies": { + "date-fns": "^3.0.6", + "uuid": "^9.0.1" + }, "devDependencies": { "@types/node": "^20.10.5", "@typescript-eslint/eslint-plugin": "^6.15.0", @@ -1309,6 +1313,15 @@ "node": ">= 8" } }, + "node_modules/date-fns": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.0.6.tgz", + "integrity": "sha512-W+G99rycpKMMF2/YD064b2lE7jJGUe+EjOES7Q8BIGY8sbNdbgcs9XFTZwvzc9Jx1f3k7LB7gZaZa7f8Agzljg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kossnocorp" + } + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -5611,6 +5624,18 @@ "punycode": "^2.1.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/v8-compile-cache": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", diff --git a/package.json b/package.json index dc05edb..0eb2c18 100644 --- a/package.json +++ b/package.json @@ -37,5 +37,9 @@ "hooks": { "pre-commit": "pretty-quick --staged" } + }, + "dependencies": { + "date-fns": "^3.0.6", + "uuid": "^9.0.1" } } diff --git a/utils/fileUtils.mjs b/utils/fileUtils.mjs new file mode 100644 index 0000000..ba6960f --- /dev/null +++ b/utils/fileUtils.mjs @@ -0,0 +1,6 @@ +import * as fs from "node:fs" +export function createIfNot(dir) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }) + } +}