89 lines
2.4 KiB
JavaScript
89 lines
2.4 KiB
JavaScript
/**
|
|
* Extracts rows from a string of values in a SQL INSERT INTO statement, where each row is a comma-separated list of values enclosed in parentheses, possibly with the last row incomplete.
|
|
* @param {string} input
|
|
* @returns {{rows: string[][], unCompleted:string}}
|
|
* @example extractRowsFromSQLValues("(1,'-)',0),(2,'Demographics_of_American_Samoa',0)") // { rows: [["1","'-)'","0"],["2","'Demographics_of_American_Samoa'","0"]], unCompleted: "" }
|
|
*/
|
|
export const extractRowsFromSQLValues = (input) => {
|
|
const rows = []
|
|
let index = 0
|
|
let unCompleted = ""
|
|
|
|
while (index < input.length) {
|
|
if (input[index] === "(") {
|
|
const row = []
|
|
index++ // Skip the opening '('
|
|
let value = ""
|
|
let insideQuotes = false
|
|
let rowComplete = false
|
|
|
|
while (index < input.length && !rowComplete) {
|
|
if (input[index] === "'") {
|
|
// An escaped quote is preceded by an odd number of backslashes.
|
|
let backslashCount = 0
|
|
let backIndex = index - 1
|
|
while (backIndex >= 0 && input[backIndex] === "\\") {
|
|
backslashCount++
|
|
backIndex--
|
|
}
|
|
if (backslashCount % 2 === 0) {
|
|
insideQuotes = !insideQuotes
|
|
}
|
|
}
|
|
|
|
if (input[index] === "," && !insideQuotes) {
|
|
row.push(value)
|
|
value = ""
|
|
} else if (input[index] === ")" && !insideQuotes) {
|
|
row.push(value)
|
|
rows.push(row)
|
|
rowComplete = true
|
|
} else {
|
|
value += input[index]
|
|
}
|
|
index++
|
|
}
|
|
|
|
if (!rowComplete) {
|
|
// If row is not completed, save it to unCompleted
|
|
unCompleted = "("
|
|
if (row.length > 0) {
|
|
unCompleted += row.join(",") + "," + value
|
|
} else if (value.length > 0) {
|
|
unCompleted += value
|
|
}
|
|
break
|
|
}
|
|
} else {
|
|
index++
|
|
}
|
|
}
|
|
|
|
return { rows, unCompleted }
|
|
}
|
|
|
|
/**
|
|
* Swaps the keys and values of an object.
|
|
* @param {*} object
|
|
* @returns
|
|
*/
|
|
export const swapKeysAndValues = (object) => {
|
|
return Object.fromEntries(
|
|
Object.entries(object).map(([key, value]) => {
|
|
return [value, key]
|
|
}),
|
|
)
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param {number} number
|
|
* @param {number} places
|
|
* @returns {string}
|
|
* @example zeroPad(1, 2) // '01'
|
|
* @example zeroPad(10, 2) // '10'
|
|
*/
|
|
export const zeroPad = (number, places = 2) => {
|
|
return number.toString().padStart(places, "0")
|
|
}
|