UNPKG

teradatasql

Version:
636 lines 31.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.main = exports.connect = exports.timestampFromTicks = exports.timestamp = exports.dateFromTicks = exports.date = exports.paramstyle = exports.threadsafety = exports.apilevel = exports.ProgrammingError = exports.OperationalError = exports.IntegrityError = exports.DataError = exports.DatabaseError = exports.InterfaceError = exports.TeradataLogging = exports.TeradataCursor = exports.STRING = exports.NUMBER = exports.DATE = exports.BINARY = exports.TeradataConnection = void 0; const teradata_connection_1 = require("./teradata-connection"); Object.defineProperty(exports, "TeradataConnection", { enumerable: true, get: function () { return teradata_connection_1.TeradataConnection; } }); const teradata_exceptions_1 = require("./teradata-exceptions"); var teradata_cursor_1 = require("./teradata-cursor"); Object.defineProperty(exports, "BINARY", { enumerable: true, get: function () { return teradata_cursor_1.BINARY; } }); Object.defineProperty(exports, "DATE", { enumerable: true, get: function () { return teradata_cursor_1.DATE; } }); Object.defineProperty(exports, "NUMBER", { enumerable: true, get: function () { return teradata_cursor_1.NUMBER; } }); Object.defineProperty(exports, "STRING", { enumerable: true, get: function () { return teradata_cursor_1.STRING; } }); Object.defineProperty(exports, "TeradataCursor", { enumerable: true, get: function () { return teradata_cursor_1.TeradataCursor; } }); var teradata_logging_1 = require("./teradata-logging"); Object.defineProperty(exports, "TeradataLogging", { enumerable: true, get: function () { return teradata_logging_1.TeradataLogging; } }); var teradata_exceptions_2 = require("./teradata-exceptions"); Object.defineProperty(exports, "InterfaceError", { enumerable: true, get: function () { return teradata_exceptions_2.InterfaceError; } }); Object.defineProperty(exports, "DatabaseError", { enumerable: true, get: function () { return teradata_exceptions_2.DatabaseError; } }); Object.defineProperty(exports, "DataError", { enumerable: true, get: function () { return teradata_exceptions_2.DataError; } }); Object.defineProperty(exports, "IntegrityError", { enumerable: true, get: function () { return teradata_exceptions_2.IntegrityError; } }); Object.defineProperty(exports, "OperationalError", { enumerable: true, get: function () { return teradata_exceptions_2.OperationalError; } }); Object.defineProperty(exports, "ProgrammingError", { enumerable: true, get: function () { return teradata_exceptions_2.ProgrammingError; } }); exports.apilevel = "2.0"; exports.threadsafety = 2; exports.paramstyle = "qmark"; function date(year, month, day) { const oDate = new Date(Date.UTC(year, month, day, 0, 0, 0)); return oDate.toISOString().slice(0, 10); } exports.date = date; function dateFromTicks(seconds) { const oDate = new Date(seconds * 1000); const sDate = oDate.toISOString().slice(0, 10); const sTime = oDate.toISOString().slice(11, 23); return `${sDate} ${sTime}000`; } exports.dateFromTicks = dateFromTicks; function timestamp(year, month, day, hour, minute, second) { return new Date(year, month, day, hour, minute, second); } exports.timestamp = timestamp; function timestampFromTicks(seconds) { return new Date(seconds * 1000); } exports.timestampFromTicks = timestampFromTicks; function connect(objConParams = {}, strConParams = "{}") { const con = new teradata_connection_1.TeradataConnection(); con.connect(objConParams, strConParams); return con; } exports.connect = connect; const fs = __importStar(require("fs")); const teradata_connection_2 = require("./teradata-connection"); function quoteText(s) { return s === null ? "null" : '"' + s.replaceAll(/[\r\n]+/g, " ").replaceAll('"', '""') + '"'; } const SPACE = " ".charCodeAt(0); const COMMA = ",".charCodeAt(0); const DQUOT = '"'.charCodeAt(0); function quoteCsvText(s) { if (s === null) { return ""; } if (s.length === 0) { return '""'; } for (let i = 0; i < s.length; i++) { let c = s.charCodeAt(i); if (c < SPACE || c === COMMA || c === DQUOT) { return '"' + s.replaceAll('"', '""') + '"'; } } return s; } const FORMAT_TEXT = 1; const FORMAT_RAW = 2; const FORMAT_CSV = 3; function formatValue(nFormat, bIsProp, nColumn, sKey, sValue) { if (nFormat === FORMAT_TEXT) { return sKey + " = " + quoteText(sValue); } else if (nFormat === FORMAT_RAW) { return (bIsProp ? sKey + "=" : nColumn > 1 ? " " : "") + (sValue === null ? "null" : sValue.replaceAll(/[\r\n]+/g, "\n")); } else { return (nColumn > 1 ? "," : "") + (sValue === null ? "" : quoteCsvText(sValue)); } } const rStdin = process.stdin.fd; const wStdout = process.stdout.fd; function printValue(wCurrent, nFormat, bIsProp, nColumn, nColumnCount, sKey, sValue) { let s = formatValue(nFormat, bIsProp, nColumn, sKey, sValue); let bOneValuePerLine = nFormat === FORMAT_TEXT || (nFormat === FORMAT_RAW && bIsProp); let bLastValueOnLine = nColumn >= nColumnCount; if (bOneValuePerLine || bLastValueOnLine) { fs.writeSync(wCurrent, s + "\n"); } else { fs.writeSync(wCurrent, s); } } function printArray(wCurrent, nFormat, bIsProp, aasData) { let asNames = aasData[0]; let iRowStart = nFormat === FORMAT_CSV ? 0 : 1; for (let iRow = iRowStart; iRow < aasData.length; iRow++) { let asRow = aasData[iRow]; for (let iColumn = 0; iColumn < asRow.length; iColumn++) { printValue(wCurrent, nFormat, bIsProp, iColumn + 1, asRow.length, asNames[iColumn], asRow[iColumn]); } } } function printNameValue(wCurrent, nFormat, sName, sValue) { printArray(wCurrent, nFormat, false, [[sName], [sValue]]); } function printResultSet(wCurrent, nFormat, sTitle, cur) { if (nFormat === FORMAT_CSV) { for (let iColumn = 0; iColumn < cur.description.length; iColumn++) { printValue(wCurrent, nFormat, false, iColumn + 1, cur.description.length, "", cur.description[iColumn][0]); } } let iRow = 0; for (let row of cur.fetchall()) { let iColumn = 0; for (let oValue of row) { let sKey = sTitle + " Row " + (iRow + 1) + " Column " + (iColumn + 1) + " " + quoteText(cur.description[iColumn][0]) + " " + cur.columntypename[iColumn]; let sValue = oValue ? oValue.toString() : null; printValue(wCurrent, nFormat, false, iColumn + 1, row.length, sKey, sValue); iColumn++; } iRow++; } } const CR = 13; const LF = 10; function readLine(h) { let bufLine = null; let bufByte = Buffer.alloc(1); for (;;) { let nBytesRead = 0; let exCaught = null; try { nBytesRead = fs.readSync(h, bufByte); } catch (ex) { exCaught = ex; } if (exCaught !== null) { if (exCaught.code === "EOF") { break; } throw exCaught; } else if (nBytesRead === bufByte.length) { if (bufLine === null) { bufLine = Buffer.alloc(0); } if (bufByte[0] === LF) { break; } if (bufByte[0] !== CR) { bufLine = Buffer.concat([bufLine, bufByte]); } } else if (nBytesRead === 0 && h !== rStdin) { break; } } return bufLine !== null ? bufLine.toString() : null; } function safePeek(stack) { return stack.length > 0 ? stack[stack.length - 1] : null; } function pushDiff(stack, o) { if (o !== safePeek(stack)) { stack.push(o); } } function popClose(stack, exclude) { let h = stack.pop(); if (h && h !== exclude) { fs.closeSync(h); } } function findAllMatches(sInput, re) { let asOutput = []; let aMatches = [...sInput.matchAll(re)]; for (let mat of aMatches) { asOutput.push(mat[1]); } return asOutput; } function convertStringArrayToIntArray(asInput) { let anOutput = []; for (let s of asInput) { anOutput.push(parseInt(s)); } return anOutput; } function convertStringArrayToIntSet(asInput) { return new Set(convertStringArrayToIntArray(asInput)); } function intersect(set1, set2) { let setOutput = new Set(); for (let o of set1) { if (set2.has(o)) { setOutput.add(o); } } return setOutput; } function threadSleep(nMillis) { Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, nMillis); } function main(asArgs) { if (asArgs.length === 0) { console.log("Arguments: Command..."); console.log("-i turns on interactive mode to prompt for commands from System.in"); console.log("-im turns on interactive mode and sql:multi"); console.log("-is turns on interactive mode and sql:semicolon"); console.log("# begins a comment"); console.log("autocommit:off turns off autocommit"); console.log("autocommit:on turns on autocommit"); console.log("commit calls the connection commit method"); console.log("cont:message sets the continuation prompt to the specified message"); console.log("driver prints the driver name and version"); console.log("echo:message prints the specified message"); console.log("exit stops reading commands from the current input source"); console.log("format:raw avoids formatting output"); console.log("format:text (the default) formats output as text"); console.log("host= prefix begins a comma-separated list of connection parameters for a database connection"); console.log("ignore:sql:all ignores all SQL exceptions"); console.log("ignore:sql:code,code,... ignores SQL exceptions with one of the specified error codes"); console.log("ignore:sql:none stops for any SQL exceptions"); console.log("input:filename reads commands from the specified file until EOF"); console.log("input:stdin reads commands from stdin until EOF (interactive Ctrl+Z on Windows)"); console.log("jdbc: prefix begins an ignored JDBC Driver connection URL"); console.log("nativeSQL:command calls the connection nativeSQL method for the command"); console.log("output:filename sends output to specified file"); console.log("output:stdout (the default) sends output to stdout"); console.log("pause waits for a line from stdin"); console.log("pid prints the process ID of Python"); console.log("prompt:message sets the prompt to the specified message"); console.log("rollback calls the connection rollback method"); console.log("sleep:ms sleeps for the specified number of milliseconds"); console.log("sql:multi accepts multiple arguments or input lines as a SQL request up to an empty argument or input line"); console.log("sql:semicolon accepts multiple arguments or input lines as a SQL request up to an argument or input line ending with a semicolon"); console.log("sql:single (the default) accepts a single argument or input line as a SQL request"); console.log("time prints the current date and time"); console.log("verbose:connection (the default) and verbose:-connection control printing connection status"); console.log("verbose:sleep (the default) and verbose:-sleep control printing sleep status"); console.log("verbose:sql and verbose:-sql (the default) control printing the SQL request before executing"); console.log("verbose:transaction and verbose:-transaction (the default) control printing transaction commands"); console.log("version prints the teradatasql version"); console.log("Otherwise the SQL request is executed"); return; } let nFormat = FORMAT_TEXT; let stackInput = []; try { let wCurrent = wStdout; try { let con = null; try { const MULTI = 1; const SEMICOLON = 2; const SINGLE = 3; let nSQLEnd = SINGLE; let sPendingCommand = null; let sContinuationPrompt = null; let sPrompt = null; let setIgnoreSQLErrors = null; let bVerboseConnection = true; let bVerboseSleep = true; let bVerboseSQL = false; let bVerboseTransaction = false; for (let iArg = 0;;) { let sCommand = null; if (safePeek(stackInput) === rStdin) { if (sPendingCommand !== null && sContinuationPrompt !== null) { fs.writeSync(wStdout, sContinuationPrompt); } else if (sPendingCommand === null && sPrompt !== null) { fs.writeSync(wStdout, sPrompt); } } while (sCommand === null && safePeek(stackInput) !== null) { sCommand = readLine(safePeek(stackInput)); if (sCommand === null) { popClose(stackInput, rStdin); } } if (sCommand === null && iArg < asArgs.length) { sCommand = asArgs[iArg++]; } let bCompleteSQL = false; if (sPendingCommand !== null) { if (sCommand === null) { sCommand = sPendingCommand; sPendingCommand = null; bCompleteSQL = true; } else if (nSQLEnd === MULTI && sCommand === "") { sCommand = sPendingCommand; sPendingCommand = null; bCompleteSQL = true; } else if (nSQLEnd === SEMICOLON && sCommand.endsWith(";")) { sCommand = sPendingCommand + " " + sCommand; sPendingCommand = null; bCompleteSQL = true; } else { sPendingCommand += " " + sCommand; continue; } } if (sCommand === null) { break; } try { if (sCommand === "") { } else if (sCommand === "-i" || sCommand === "-im" || sCommand === "-is") { pushDiff(stackInput, rStdin); sPrompt = ">>> "; sContinuationPrompt = "... "; setIgnoreSQLErrors = new Set(); if (sCommand === "-im") { nSQLEnd = MULTI; } else if (sCommand === "-is") { nSQLEnd = SEMICOLON; } } else if (sCommand === "sql:multi") { nSQLEnd = MULTI; } else if (sCommand === "sql:semicolon") { nSQLEnd = SEMICOLON; } else if (sCommand === "sql:single") { nSQLEnd = SINGLE; } else if (sCommand.startsWith("cont:")) { sContinuationPrompt = sCommand.substring("cont:".length); } else if (sCommand.startsWith("prompt:")) { sPrompt = sCommand.substring("prompt:".length); } else if (sCommand === "exit") { if (stackInput.length > 0) { popClose(stackInput, rStdin); } } else if (sCommand.startsWith("#")) { } else if (sCommand === "time") { let d = new Date(); printNameValue(wCurrent, nFormat, sCommand, d.getFullYear().toString() + "-" + ("0" + (d.getMonth() + 1).toString()).slice(-2) + "-" + ("0" + d.getDate().toString()).slice(-2) + " " + ("0" + d.getHours().toString()).slice(-2) + ":" + ("0" + d.getMinutes().toString()).slice(-2) + ":" + ("0" + d.getSeconds().toString()).slice(-2) + "." + ("00" + d.getMilliseconds().toString()).slice(-3)); } else if (sCommand === "verbose:sleep") { bVerboseSleep = true; } else if (sCommand === "verbose:-sleep") { bVerboseSleep = false; } else if (sCommand.startsWith("sleep:")) { let nMillis = parseInt(sCommand.substring("sleep:".length)); if (bVerboseSleep) { fs.writeSync(wCurrent, "Sleeping for " + nMillis + " ms\n"); } threadSleep(nMillis); if (bVerboseSleep) { fs.writeSync(wCurrent, "Done sleeping for " + nMillis + " ms\n"); } } else if (sCommand === "driver") { printNameValue(wCurrent, nFormat, sCommand, "Teradata SQL Driver for Node.js " + (0, teradata_connection_2.getPackageVersion)()); } else if (sCommand === "version") { printNameValue(wCurrent, nFormat, sCommand, (0, teradata_connection_2.getPackageVersion)()); } else if (sCommand === "pid") { printNameValue(wCurrent, nFormat, sCommand, process.pid.toString()); } else if (sCommand.startsWith("echo:")) { let s = sCommand.substring("echo:".length); fs.writeSync(wCurrent, s + "\n"); } else if (sCommand === "pause") { fs.writeSync(wCurrent, "Paused. Press Enter to continue:\n"); readLine(rStdin); } else if (sCommand === "verbose:connection") { bVerboseConnection = true; } else if (sCommand === "verbose:-connection") { bVerboseConnection = false; } else if (sCommand.startsWith("jdbc:")) { printNameValue(wCurrent, nFormat, "Ignored", sCommand); } else if (sCommand.startsWith("host=")) { if (con) { let conToClose = con; con = null; conToClose.close(); } sCommand = sCommand.replaceAll(",,", "\x01"); let mapParams = new Map(); for (let sPair of sCommand.split(",")) { sPair = sPair.replaceAll("\x01", ","); let asPair = sPair.split("=", 2); if (asPair.length === 2) { mapParams.set(asPair[0], asPair[1]); } else { throw new Error("Missing equal sign in connection parameter " + sPair); } } let sConnect = JSON.stringify(Object.fromEntries(mapParams)); con = connect({}, sConnect); if (bVerboseConnection) { let sResult = con.nativeSQL("{fn teradata_connected}|{fn teradata_session_number}|{fn teradata_provide(remote_address)}:{fn teradata_provide(remote_port)}|Teradata Database {fn teradata_database_version}"); let asValues = sResult.split("|", 4); let bConnected = asValues[0] === "true"; let sStatus = bConnected ? "Connected" : "Closed"; let sSession = bConnected ? asValues[1] : null; let sRemote = asValues[2]; let sVersion = asValues[3]; printArray(wCurrent, nFormat, false, [ ["Status", "Remote", "Version", "Session"], [sStatus, sRemote, sVersion, sSession], ]); } } else if (sCommand.startsWith("input:")) { let s = sCommand.substring("input:".length); pushDiff(stackInput, s === "stdin" ? rStdin : fs.openSync(s, "r")); } else if (sCommand.startsWith("output:")) { let s = sCommand.substring("output:".length); if (wCurrent !== wStdout) { fs.closeSync(wCurrent); } wCurrent = wStdout; if (s !== "stdout") { wCurrent = fs.openSync(s, "w"); } } else if (sCommand.startsWith("format:")) { let s = sCommand.substring("format:".length); if (s === "text") { nFormat = FORMAT_TEXT; } else if (s === "raw") { nFormat = FORMAT_RAW; } else if (s === "csv") { nFormat = FORMAT_CSV; } else { throw new Error("Unknown format " + s); } } else if (sCommand === "ignore:sql:all") { setIgnoreSQLErrors = new Set(); } else if (sCommand === "ignore:sql:none") { setIgnoreSQLErrors = null; } else if (sCommand.startsWith("ignore:sql:")) { let s = sCommand.substring("ignore:sql:".length); let asTokens = s.split(","); if (asTokens.length === 0) { throw new Error(sCommand); } setIgnoreSQLErrors = convertStringArrayToIntSet(asTokens); } else if (sCommand === "verbose:sql") { bVerboseSQL = true; } else if (sCommand === "verbose:-sql") { bVerboseSQL = false; } else if (sCommand === "verbose:transaction") { bVerboseTransaction = true; } else if (sCommand === "verbose:-transaction") { bVerboseTransaction = false; } else if (con === null) { throw new Error("No connection available for " + sCommand); } else if (sCommand === "autocommit:off") { if (bVerboseTransaction) { fs.writeSync(wCurrent, sCommand + "\n"); } con.autocommit = false; } else if (sCommand === "autocommit:on") { if (bVerboseTransaction) { fs.writeSync(wCurrent, sCommand + "\n"); } con.autocommit = true; } else if (sCommand === "commit") { if (bVerboseTransaction) { fs.writeSync(wCurrent, sCommand + "\n"); } con.commit(); } else if (sCommand === "rollback") { if (bVerboseTransaction) { fs.writeSync(wCurrent, sCommand + "\n"); } con.rollback(); } else if (sCommand.startsWith("nativeSQL:")) { printNameValue(wCurrent, nFormat, "nativeSQL", con.nativeSQL(sCommand.substring("nativeSQL:".length))); } else if (nSQLEnd === MULTI && !bCompleteSQL) { sPendingCommand = sCommand; } else if (nSQLEnd === SEMICOLON && !bCompleteSQL && !sCommand.endsWith(";")) { sPendingCommand = sCommand; } else { if (bVerboseSQL) { fs.writeSync(wCurrent, sCommand + "\n"); } let cur = con.cursor(); try { cur.execute(sCommand); for (let nResult = 1;; nResult++) { printResultSet(wCurrent, nFormat, "Result " + nResult, cur); if (!cur.nextset()) { break; } } } finally { cur.close(); } } } catch (ex) { if (ex instanceof teradata_exceptions_1.DatabaseError) { let sErrMsg = ex.toString(); var bIgnore; if (setIgnoreSQLErrors === null) { bIgnore = false; } else if (setIgnoreSQLErrors.size === 0) { bIgnore = true; } else { let setErrorCodes = convertStringArrayToIntSet(findAllMatches(sErrMsg, /\[Error (\d+)\]/g)); let setIntersection = intersect(setErrorCodes, setIgnoreSQLErrors); bIgnore = setIntersection.size > 0; } if (bIgnore) { printNameValue(wCurrent, nFormat, "Exception", sErrMsg); } else { throw ex; } } else { throw ex; } } } } finally { if (con) { con.close(); } } } finally { if (wCurrent !== wStdout) { fs.closeSync(wCurrent); } } } finally { while (stackInput.length > 0) { popClose(stackInput, rStdin); } } } exports.main = main; //# sourceMappingURL=index.js.map