Commit iniziale
This commit is contained in:
22
node_modules/mssql/LICENSE.md
generated
vendored
Normal file
22
node_modules/mssql/LICENSE.md
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2013-2018 Patrik Simek and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
2192
node_modules/mssql/README.md
generated
vendored
Normal file
2192
node_modules/mssql/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
131
node_modules/mssql/bin/mssql
generated
vendored
Executable file
131
node_modules/mssql/bin/mssql
generated
vendored
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env node
|
||||
const { Command } = require('commander')
|
||||
const { version } = require('../package.json')
|
||||
const { resolve: resolvePath } = require('node:path')
|
||||
const { constants: { R_OK } } = require('node:fs')
|
||||
const { ConnectionPool } = require('../')
|
||||
const { lstat, access, readFile } = require('node:fs/promises')
|
||||
Buffer.prototype.toJSON = () => {
|
||||
return `0x${this.toString('hex')}`
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Readable} stream
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
async function streamToBuffer (stream) {
|
||||
const chunks = []
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on('data', (chunk) => {
|
||||
chunks.push(chunk)
|
||||
})
|
||||
stream.on('end', () => {
|
||||
resolve(Buffer.concat(chunks))
|
||||
})
|
||||
stream.on('error', reject)
|
||||
})
|
||||
}
|
||||
|
||||
async function resolveConfig (opts, cfgFile) {
|
||||
const cfg = Object.entries({
|
||||
options: {
|
||||
encrypt: opts.encrypt,
|
||||
trustServerCertificate: opts.trustServerCertificate
|
||||
},
|
||||
user: opts.user,
|
||||
password: opts.password,
|
||||
server: opts.server,
|
||||
database: opts.database,
|
||||
port: opts.port
|
||||
}).reduce((config, [key, value]) => {
|
||||
if (value) {
|
||||
Object.assign(config, {
|
||||
[key]: value
|
||||
})
|
||||
}
|
||||
return config
|
||||
}, {})
|
||||
let cfgPath = cfgFile || process.cwd()
|
||||
const stat = await lstat(resolvePath(cfgPath))
|
||||
if (stat.isDirectory()) {
|
||||
cfgPath = resolvePath(cfgPath, opts.config)
|
||||
}
|
||||
const configAccess = await access(cfgPath, R_OK).then(() => true).catch(() => false)
|
||||
if (!configAccess) {
|
||||
return cfg;
|
||||
}
|
||||
const config = await (readFile(cfgPath))
|
||||
.then((content) => JSON.parse(content.toString()))
|
||||
|
||||
return {
|
||||
...config,
|
||||
...cfg,
|
||||
options: {
|
||||
...(config.options || {}),
|
||||
...cfg.options
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const program = new Command()
|
||||
|
||||
program
|
||||
.name('mssql')
|
||||
.argument('[configPath]')
|
||||
.description('CLI tools for node-mssql')
|
||||
.version(version)
|
||||
.option('--config <file>', 'Configuration file for the connection', './.mssql.json')
|
||||
.option('--user <user>', 'User for the database connection')
|
||||
.option('--password <password>', 'Password for the database connection')
|
||||
.option('--server <server>', 'Server for the database connection')
|
||||
.option('--database <database>', 'Database for the database connection')
|
||||
.option('--port <port>', 'Port for the database connection', parseInt)
|
||||
.option('--encrypt', 'Use the encrypt option for this connection', false)
|
||||
.option('--trust-server-certificate', 'Trust the server certificate for this connection', false)
|
||||
// .option('--format <format>', 'The output format to use, eg: JSON', 'json')
|
||||
.action(async function (configPath, opts) {
|
||||
const [config, statement] = await Promise.all([
|
||||
resolveConfig(opts, configPath),
|
||||
streamToBuffer(process.stdin).then((stmt) => stmt.toString().trim())
|
||||
])
|
||||
if (!statement.length) {
|
||||
throw new Error('Statement is empty.')
|
||||
}
|
||||
const pool = await (new ConnectionPool(config)).connect()
|
||||
const request = pool.request()
|
||||
request.stream = true
|
||||
let started = false
|
||||
request.on('error', (e) => {
|
||||
pool.close()
|
||||
throw e
|
||||
})
|
||||
request.on('recordset', () => {
|
||||
if (started) {
|
||||
process.stdout.write('],')
|
||||
} else {
|
||||
process.stdout.write('[')
|
||||
}
|
||||
started = false
|
||||
})
|
||||
request.on('row', (row) => {
|
||||
if (!started) {
|
||||
started = true
|
||||
process.stdout.write('[')
|
||||
} else {
|
||||
process.stdout.write(',')
|
||||
}
|
||||
process.stdout.write(JSON.stringify(row))
|
||||
})
|
||||
request.on('done', () => {
|
||||
if (started) {
|
||||
process.stdout.write(']]')
|
||||
}
|
||||
process.stdout.write('\n')
|
||||
pool.close()
|
||||
})
|
||||
request.query(statement)
|
||||
})
|
||||
|
||||
program.parseAsync(process.argv).catch((e) => {
|
||||
program.error(e.message, { exitCode: 1 });
|
||||
})
|
||||
1
node_modules/mssql/index.js
generated
vendored
Normal file
1
node_modules/mssql/index.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('./lib/tedious')
|
||||
643
node_modules/mssql/lib/base/connection-pool.js
generated
vendored
Normal file
643
node_modules/mssql/lib/base/connection-pool.js
generated
vendored
Normal file
@@ -0,0 +1,643 @@
|
||||
'use strict'
|
||||
|
||||
const { EventEmitter } = require('node:events')
|
||||
const debug = require('debug')('mssql:base')
|
||||
const { parseSqlConnectionString } = require('@tediousjs/connection-string')
|
||||
const tarn = require('tarn')
|
||||
const { IDS } = require('../utils')
|
||||
const ConnectionError = require('../error/connection-error')
|
||||
const shared = require('../shared')
|
||||
const clone = require('rfdc/default')
|
||||
const { MSSQLError } = require('../error')
|
||||
|
||||
/**
|
||||
* Class ConnectionPool.
|
||||
*
|
||||
* Internally, each `Connection` instance is a separate pool of TDS connections. Once you create a new `Request`/`Transaction`/`Prepared Statement`, a new TDS connection is acquired from the pool and reserved for desired action. Once the action is complete, connection is released back to the pool.
|
||||
*
|
||||
* @property {Boolean} connected If true, connection is established.
|
||||
* @property {Boolean} connecting If true, connection is being established.
|
||||
*
|
||||
* @fires ConnectionPool#connect
|
||||
* @fires ConnectionPool#close
|
||||
*/
|
||||
|
||||
class ConnectionPool extends EventEmitter {
|
||||
/**
|
||||
* Create new Connection.
|
||||
*
|
||||
* @param {Object|String} config Connection configuration object or connection string.
|
||||
* @param {basicCallback} [callback] A callback which is called after connection has established, or an error has occurred.
|
||||
*/
|
||||
|
||||
constructor (config, callback) {
|
||||
super()
|
||||
|
||||
IDS.add(this, 'ConnectionPool')
|
||||
debug('pool(%d): created', IDS.get(this))
|
||||
|
||||
this._connectStack = []
|
||||
this._closeStack = []
|
||||
|
||||
this._connected = false
|
||||
this._connecting = false
|
||||
this._healthy = false
|
||||
|
||||
if (typeof config === 'string') {
|
||||
try {
|
||||
this.config = this.constructor.parseConnectionString(config)
|
||||
} catch (ex) {
|
||||
if (typeof callback === 'function') {
|
||||
return setImmediate(callback, ex)
|
||||
}
|
||||
throw ex
|
||||
}
|
||||
} else {
|
||||
this.config = clone(config)
|
||||
}
|
||||
|
||||
// set defaults
|
||||
this.config.port = this.config.port || 1433
|
||||
this.config.options = this.config.options || {}
|
||||
this.config.stream = this.config.stream || false
|
||||
this.config.parseJSON = this.config.parseJSON || false
|
||||
this.config.arrayRowMode = this.config.arrayRowMode || false
|
||||
this.config.validateConnection = 'validateConnection' in this.config ? this.config.validateConnection : true
|
||||
|
||||
const namedServer = /^(.*)\\(.*)$/.exec(this.config.server)
|
||||
if (namedServer) {
|
||||
this.config.server = namedServer[1]
|
||||
this.config.options.instanceName = namedServer[2]
|
||||
}
|
||||
|
||||
if (typeof this.config.options.useColumnNames !== 'undefined' && this.config.options.useColumnNames !== true) {
|
||||
const ex = new MSSQLError('Invalid options `useColumnNames`, use `arrayRowMode` instead')
|
||||
if (typeof callback === 'function') {
|
||||
return setImmediate(callback, ex)
|
||||
}
|
||||
throw ex
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
this.connect(callback)
|
||||
}
|
||||
}
|
||||
|
||||
get connected () {
|
||||
return this._connected
|
||||
}
|
||||
|
||||
get connecting () {
|
||||
return this._connecting
|
||||
}
|
||||
|
||||
get healthy () {
|
||||
return this._healthy
|
||||
}
|
||||
|
||||
static parseConnectionString (connectionString) {
|
||||
return this._parseConnectionString(connectionString)
|
||||
}
|
||||
|
||||
static _parseAuthenticationType (type, entries) {
|
||||
switch (type.toLowerCase()) {
|
||||
case 'active directory integrated':
|
||||
if (entries.includes('token')) {
|
||||
return 'azure-active-directory-access-token'
|
||||
} else if (['client id', 'client secret', 'tenant id'].every(entry => entries.includes(entry))) {
|
||||
return 'azure-active-directory-service-principal-secret'
|
||||
} else if (['client id', 'msi endpoint', 'msi secret'].every(entry => entries.includes(entry))) {
|
||||
return 'azure-active-directory-msi-app-service'
|
||||
} else if (['client id', 'msi endpoint'].every(entry => entries.includes(entry))) {
|
||||
return 'azure-active-directory-msi-vm'
|
||||
}
|
||||
return 'azure-active-directory-default'
|
||||
case 'active directory password':
|
||||
return 'azure-active-directory-password'
|
||||
case 'ntlm':
|
||||
return 'ntlm'
|
||||
default:
|
||||
return 'default'
|
||||
}
|
||||
}
|
||||
|
||||
static _parseConnectionString (connectionString) {
|
||||
const parsed = parseSqlConnectionString(connectionString, true, true)
|
||||
return Object.entries(parsed).reduce((config, [key, value]) => {
|
||||
switch (key) {
|
||||
case 'application name':
|
||||
break
|
||||
case 'applicationintent':
|
||||
Object.assign(config.options, {
|
||||
readOnlyIntent: value === 'readonly'
|
||||
})
|
||||
break
|
||||
case 'asynchronous processing':
|
||||
break
|
||||
case 'attachdbfilename':
|
||||
break
|
||||
case 'authentication':
|
||||
Object.assign(config, {
|
||||
authentication_type: this._parseAuthenticationType(value, Object.keys(parsed))
|
||||
})
|
||||
break
|
||||
case 'column encryption setting':
|
||||
break
|
||||
case 'connection timeout':
|
||||
Object.assign(config, {
|
||||
connectionTimeout: value * 1000
|
||||
})
|
||||
break
|
||||
case 'connection lifetime':
|
||||
break
|
||||
case 'connectretrycount':
|
||||
break
|
||||
case 'connectretryinterval':
|
||||
Object.assign(config.options, {
|
||||
connectionRetryInterval: value * 1000
|
||||
})
|
||||
break
|
||||
case 'context connection':
|
||||
break
|
||||
case 'client id':
|
||||
Object.assign(config, {
|
||||
clientId: value
|
||||
})
|
||||
break
|
||||
case 'client secret':
|
||||
Object.assign(config, {
|
||||
clientSecret: value
|
||||
})
|
||||
break
|
||||
case 'current language':
|
||||
Object.assign(config.options, {
|
||||
language: value
|
||||
})
|
||||
break
|
||||
case 'data source':
|
||||
{
|
||||
let server = value
|
||||
let instanceName
|
||||
let port = 1433
|
||||
if (/^np:/i.test(server)) {
|
||||
throw new Error('Connection via Named Pipes is not supported.')
|
||||
}
|
||||
if (/^tcp:/i.test(server)) {
|
||||
server = server.substr(4)
|
||||
}
|
||||
const namedServerParts = /^(.*)\\(.*)$/.exec(server)
|
||||
if (namedServerParts) {
|
||||
server = namedServerParts[1].trim()
|
||||
instanceName = namedServerParts[2].trim()
|
||||
}
|
||||
const serverParts = /^(.*),(.*)$/.exec(server)
|
||||
if (serverParts) {
|
||||
server = serverParts[1].trim()
|
||||
port = parseInt(serverParts[2].trim(), 10)
|
||||
} else {
|
||||
const instanceParts = /^(.*),(.*)$/.exec(instanceName)
|
||||
if (instanceParts) {
|
||||
instanceName = instanceParts[1].trim()
|
||||
port = parseInt(instanceParts[2].trim(), 10)
|
||||
}
|
||||
}
|
||||
if (server === '.' || server === '(.)' || server.toLowerCase() === '(localdb)' || server.toLowerCase() === '(local)') {
|
||||
server = 'localhost'
|
||||
}
|
||||
Object.assign(config, {
|
||||
port,
|
||||
server
|
||||
})
|
||||
if (instanceName) {
|
||||
Object.assign(config.options, {
|
||||
instanceName
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'encrypt':
|
||||
Object.assign(config.options, {
|
||||
encrypt: !!value
|
||||
})
|
||||
break
|
||||
case 'enlist':
|
||||
break
|
||||
case 'failover partner':
|
||||
break
|
||||
case 'initial catalog':
|
||||
Object.assign(config, {
|
||||
database: value
|
||||
})
|
||||
break
|
||||
case 'integrated security':
|
||||
break
|
||||
case 'max pool size':
|
||||
Object.assign(config.pool, {
|
||||
max: value
|
||||
})
|
||||
break
|
||||
case 'min pool size':
|
||||
Object.assign(config.pool, {
|
||||
min: value
|
||||
})
|
||||
break
|
||||
case 'msi endpoint':
|
||||
Object.assign(config, {
|
||||
msiEndpoint: value
|
||||
})
|
||||
break
|
||||
case 'msi secret':
|
||||
Object.assign(config, {
|
||||
msiSecret: value
|
||||
})
|
||||
break
|
||||
case 'multipleactiveresultsets':
|
||||
break
|
||||
case 'multisubnetfailover':
|
||||
Object.assign(config.options, {
|
||||
multiSubnetFailover: value
|
||||
})
|
||||
break
|
||||
case 'network library':
|
||||
break
|
||||
case 'packet size':
|
||||
Object.assign(config.options, {
|
||||
packetSize: value
|
||||
})
|
||||
break
|
||||
case 'password':
|
||||
Object.assign(config, {
|
||||
password: value
|
||||
})
|
||||
break
|
||||
case 'persist security info':
|
||||
break
|
||||
case 'poolblockingperiod':
|
||||
break
|
||||
case 'pooling':
|
||||
break
|
||||
case 'replication':
|
||||
break
|
||||
case 'tenant id':
|
||||
Object.assign(config, {
|
||||
tenantId: value
|
||||
})
|
||||
break
|
||||
case 'token':
|
||||
Object.assign(config, {
|
||||
token: value
|
||||
})
|
||||
break
|
||||
case 'transaction binding':
|
||||
Object.assign(config.options, {
|
||||
enableImplicitTransactions: value.toLowerCase() === 'implicit unbind'
|
||||
})
|
||||
break
|
||||
case 'transparentnetworkipresolution':
|
||||
break
|
||||
case 'trustservercertificate':
|
||||
Object.assign(config.options, {
|
||||
trustServerCertificate: value
|
||||
})
|
||||
break
|
||||
case 'type system version':
|
||||
break
|
||||
case 'user id': {
|
||||
let user = value
|
||||
let domain
|
||||
const domainUser = /^(.*)\\(.*)$/.exec(user)
|
||||
if (domainUser) {
|
||||
domain = domainUser[1]
|
||||
user = domainUser[2]
|
||||
}
|
||||
if (domain) {
|
||||
Object.assign(config, {
|
||||
domain
|
||||
})
|
||||
}
|
||||
if (user) {
|
||||
Object.assign(config, {
|
||||
user
|
||||
})
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'user instance':
|
||||
break
|
||||
case 'workstation id':
|
||||
Object.assign(config.options, {
|
||||
workstationId: value
|
||||
})
|
||||
break
|
||||
case 'request timeout':
|
||||
Object.assign(config, {
|
||||
requestTimeout: parseInt(value, 10)
|
||||
})
|
||||
break
|
||||
case 'stream':
|
||||
Object.assign(config, {
|
||||
stream: !!value
|
||||
})
|
||||
break
|
||||
case 'useutc':
|
||||
Object.assign(config.options, {
|
||||
useUTC: !!value
|
||||
})
|
||||
break
|
||||
case 'parsejson':
|
||||
Object.assign(config, {
|
||||
parseJSON: !!value
|
||||
})
|
||||
break
|
||||
}
|
||||
return config
|
||||
}, { options: {}, pool: {} })
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire connection from this connection pool.
|
||||
*
|
||||
* @param {ConnectionPool|Transaction|PreparedStatement} requester Requester.
|
||||
* @param {acquireCallback} [callback] A callback which is called after connection has been acquired, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {ConnectionPool|Promise}
|
||||
*/
|
||||
|
||||
acquire (requester, callback) {
|
||||
const acquirePromise = shared.Promise.resolve(this._acquire()).catch(err => {
|
||||
this.emit('error', err)
|
||||
throw err
|
||||
})
|
||||
if (typeof callback === 'function') {
|
||||
acquirePromise.then(connection => callback(null, connection, this.config)).catch(callback)
|
||||
return this
|
||||
}
|
||||
|
||||
return acquirePromise
|
||||
}
|
||||
|
||||
_acquire () {
|
||||
if (!this.pool) {
|
||||
return shared.Promise.reject(new ConnectionError('Connection not yet open.', 'ENOTOPEN'))
|
||||
} else if (this.pool.destroyed) {
|
||||
return shared.Promise.reject(new ConnectionError('Connection is closing', 'ENOTOPEN'))
|
||||
}
|
||||
|
||||
return this.pool.acquire().promise
|
||||
}
|
||||
|
||||
/**
|
||||
* Release connection back to the pool.
|
||||
*
|
||||
* @param {Connection} connection Previously acquired connection.
|
||||
* @return {ConnectionPool}
|
||||
*/
|
||||
|
||||
release (connection) {
|
||||
debug('connection(%d): released', IDS.get(connection))
|
||||
|
||||
if (this.pool) {
|
||||
this.pool.release(connection)
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new connection pool with one active connection. This one initial connection serves as a probe to find out whether the configuration is valid.
|
||||
*
|
||||
* @param {basicCallback} [callback] A callback which is called after connection has established, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {ConnectionPool|Promise}
|
||||
*/
|
||||
|
||||
connect (callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this._connect(callback)
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
return this._connect(err => {
|
||||
if (err) return reject(err)
|
||||
resolve(this)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {basicCallback} callback
|
||||
*/
|
||||
|
||||
_connect (callback) {
|
||||
if (this._connected) {
|
||||
debug('pool(%d): already connected, executing connect callback immediately', IDS.get(this))
|
||||
return setImmediate(callback, null, this)
|
||||
}
|
||||
|
||||
this._connectStack.push(callback)
|
||||
|
||||
if (this._connecting) {
|
||||
return
|
||||
}
|
||||
|
||||
this._connecting = true
|
||||
debug('pool(%d): connecting', IDS.get(this))
|
||||
|
||||
// create one test connection to check if everything is ok
|
||||
this._poolCreate().then((connection) => {
|
||||
debug('pool(%d): connected', IDS.get(this))
|
||||
this._healthy = true
|
||||
|
||||
return this._poolDestroy(connection).then(() => {
|
||||
// prepare pool
|
||||
this.pool = new tarn.Pool(
|
||||
Object.assign({
|
||||
create: () => this._poolCreate()
|
||||
.then(connection => {
|
||||
this._healthy = true
|
||||
return connection
|
||||
})
|
||||
.catch(err => {
|
||||
if (this.pool.numUsed() + this.pool.numFree() <= 0) {
|
||||
this._healthy = false
|
||||
}
|
||||
throw err
|
||||
}),
|
||||
validate: this._poolValidate.bind(this),
|
||||
destroy: this._poolDestroy.bind(this),
|
||||
max: 10,
|
||||
min: 0,
|
||||
idleTimeoutMillis: 30000,
|
||||
propagateCreateError: true
|
||||
}, this.config.pool)
|
||||
)
|
||||
|
||||
this._connecting = false
|
||||
this._connected = true
|
||||
})
|
||||
}).then(() => {
|
||||
this._connectStack.forEach((cb) => {
|
||||
setImmediate(cb, null, this)
|
||||
})
|
||||
}).catch(err => {
|
||||
this._connecting = false
|
||||
this._connectStack.forEach((cb) => {
|
||||
setImmediate(cb, err)
|
||||
})
|
||||
}).then(() => {
|
||||
this._connectStack = []
|
||||
})
|
||||
}
|
||||
|
||||
get size () {
|
||||
return this.pool.numFree() + this.pool.numUsed() + this.pool.numPendingCreates()
|
||||
}
|
||||
|
||||
get available () {
|
||||
return this.pool.numFree()
|
||||
}
|
||||
|
||||
get pending () {
|
||||
return this.pool.numPendingAcquires()
|
||||
}
|
||||
|
||||
get borrowed () {
|
||||
return this.pool.numUsed()
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all active connections in the pool.
|
||||
*
|
||||
* @param {basicCallback} [callback] A callback which is called after connection has closed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {ConnectionPool|Promise}
|
||||
*/
|
||||
|
||||
close (callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this._close(callback)
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._close(err => {
|
||||
if (err) return reject(err)
|
||||
resolve(this)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {basicCallback} callback
|
||||
*/
|
||||
|
||||
_close (callback) {
|
||||
// we don't allow pools in a connecting state to be closed because it means there are far too many
|
||||
// edge cases to deal with
|
||||
if (this._connecting) {
|
||||
debug('pool(%d): close called while connecting', IDS.get(this))
|
||||
setImmediate(callback, new ConnectionError('Cannot close a pool while it is connecting'))
|
||||
}
|
||||
|
||||
if (!this.pool) {
|
||||
debug('pool(%d): already closed, executing close callback immediately', IDS.get(this))
|
||||
return setImmediate(callback, null)
|
||||
}
|
||||
|
||||
this._closeStack.push(callback)
|
||||
|
||||
if (this.pool.destroyed) return
|
||||
|
||||
this._connecting = this._connected = this._healthy = false
|
||||
|
||||
this.pool.destroy().then(() => {
|
||||
debug('pool(%d): pool closed, removing pool reference and executing close callbacks', IDS.get(this))
|
||||
this.pool = null
|
||||
this._closeStack.forEach(cb => {
|
||||
setImmediate(cb, null)
|
||||
})
|
||||
}).catch(err => {
|
||||
this.pool = null
|
||||
this._closeStack.forEach(cb => {
|
||||
setImmediate(cb, err)
|
||||
})
|
||||
}).then(() => {
|
||||
this._closeStack = []
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new request using this connection.
|
||||
*
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
request () {
|
||||
return new shared.driver.Request(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new transaction using this connection.
|
||||
*
|
||||
* @return {Transaction}
|
||||
*/
|
||||
|
||||
transaction () {
|
||||
return new shared.driver.Transaction(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new query using this connection from a tagged template string.
|
||||
*
|
||||
* @variation 1
|
||||
* @param {Array} strings Array of string literals.
|
||||
* @param {...*} keys Values.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the SQL command.
|
||||
*
|
||||
* @variation 2
|
||||
* @param {String} command T-SQL command to be executed.
|
||||
* @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
query () {
|
||||
if (typeof arguments[0] === 'string') { return new shared.driver.Request(this).query(arguments[0], arguments[1]) }
|
||||
|
||||
const values = Array.prototype.slice.call(arguments)
|
||||
const strings = values.shift()
|
||||
|
||||
return new shared.driver.Request(this)._template(strings, values, 'query')
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new batch using this connection from a tagged template string.
|
||||
*
|
||||
* @variation 1
|
||||
* @param {Array} strings Array of string literals.
|
||||
* @param {...*} keys Values.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the SQL command.
|
||||
*
|
||||
* @variation 2
|
||||
* @param {String} command T-SQL command to be executed.
|
||||
* @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
batch () {
|
||||
if (typeof arguments[0] === 'string') { return new shared.driver.Request(this).batch(arguments[0], arguments[1]) }
|
||||
|
||||
const values = Array.prototype.slice.call(arguments)
|
||||
const strings = values.shift()
|
||||
|
||||
return new shared.driver.Request(this)._template(strings, values, 'batch')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConnectionPool
|
||||
138
node_modules/mssql/lib/base/index.js
generated
vendored
Normal file
138
node_modules/mssql/lib/base/index.js
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
'use strict'
|
||||
|
||||
const ConnectionPool = require('./connection-pool')
|
||||
const PreparedStatement = require('./prepared-statement')
|
||||
const Request = require('./request')
|
||||
const Transaction = require('./transaction')
|
||||
const { ConnectionError, TransactionError, RequestError, PreparedStatementError, MSSQLError } = require('../error')
|
||||
const shared = require('../shared')
|
||||
const Table = require('../table')
|
||||
const ISOLATION_LEVEL = require('../isolationlevel')
|
||||
const { TYPES } = require('../datatypes')
|
||||
const { connect, close, on, off, removeListener, query, batch } = require('../global-connection')
|
||||
|
||||
module.exports = {
|
||||
ConnectionPool,
|
||||
Transaction,
|
||||
Request,
|
||||
PreparedStatement,
|
||||
ConnectionError,
|
||||
TransactionError,
|
||||
RequestError,
|
||||
PreparedStatementError,
|
||||
MSSQLError,
|
||||
driver: shared.driver,
|
||||
exports: {
|
||||
ConnectionError,
|
||||
TransactionError,
|
||||
RequestError,
|
||||
PreparedStatementError,
|
||||
MSSQLError,
|
||||
Table,
|
||||
ISOLATION_LEVEL,
|
||||
TYPES,
|
||||
MAX: 65535, // (1 << 16) - 1
|
||||
map: shared.map,
|
||||
getTypeByValue: shared.getTypeByValue,
|
||||
connect,
|
||||
close,
|
||||
on,
|
||||
removeListener,
|
||||
off,
|
||||
query,
|
||||
batch
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(module.exports, 'Promise', {
|
||||
enumerable: true,
|
||||
get: () => {
|
||||
return shared.Promise
|
||||
},
|
||||
set: (value) => {
|
||||
shared.Promise = value
|
||||
}
|
||||
})
|
||||
|
||||
Object.defineProperty(module.exports, 'valueHandler', {
|
||||
enumerable: true,
|
||||
value: shared.valueHandler,
|
||||
writable: false,
|
||||
configurable: false
|
||||
})
|
||||
|
||||
for (const key in TYPES) {
|
||||
const value = TYPES[key]
|
||||
module.exports.exports[key] = value
|
||||
module.exports.exports[key.toUpperCase()] = value
|
||||
}
|
||||
|
||||
/**
|
||||
* @callback Request~requestCallback
|
||||
* @param {Error} err Error on error, otherwise null.
|
||||
* @param {Object} [result] Request result.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback Request~bulkCallback
|
||||
* @param {Error} err Error on error, otherwise null.
|
||||
* @param {Number} [rowsAffected] Number of affected rows.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback basicCallback
|
||||
* @param {Error} err Error on error, otherwise null.
|
||||
* @param {Connection} [connection] Acquired connection.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback acquireCallback
|
||||
* @param {Error} err Error on error, otherwise null.
|
||||
* @param {Connection} [connection] Acquired connection.
|
||||
* @param {Object} [config] Connection config
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched after connection has established.
|
||||
* @event ConnectionPool#connect
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched after connection has closed a pool (by calling close).
|
||||
* @event ConnectionPool#close
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched when transaction begin.
|
||||
* @event Transaction#begin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched on successful commit.
|
||||
* @event Transaction#commit
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched on successful rollback.
|
||||
* @event Transaction#rollback
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched when metadata for new recordset are parsed.
|
||||
* @event Request#recordset
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched when new row is parsed.
|
||||
* @event Request#row
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched when request is complete.
|
||||
* @event Request#done
|
||||
*/
|
||||
|
||||
/**
|
||||
* Dispatched on error.
|
||||
* @event Request#error
|
||||
*/
|
||||
384
node_modules/mssql/lib/base/prepared-statement.js
generated
vendored
Normal file
384
node_modules/mssql/lib/base/prepared-statement.js
generated
vendored
Normal file
@@ -0,0 +1,384 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('mssql:base')
|
||||
const { EventEmitter } = require('node:events')
|
||||
const { IDS, objectHasProperty } = require('../utils')
|
||||
const globalConnection = require('../global-connection')
|
||||
const { TransactionError, PreparedStatementError } = require('../error')
|
||||
const shared = require('../shared')
|
||||
const { TYPES, declare } = require('../datatypes')
|
||||
|
||||
/**
|
||||
* Class PreparedStatement.
|
||||
*
|
||||
* IMPORTANT: Rememeber that each prepared statement means one reserved connection from the pool. Don't forget to unprepare a prepared statement!
|
||||
*
|
||||
* @property {String} statement Prepared SQL statement.
|
||||
*/
|
||||
|
||||
class PreparedStatement extends EventEmitter {
|
||||
/**
|
||||
* Creates a new Prepared Statement.
|
||||
*
|
||||
* @param {ConnectionPool|Transaction} [holder]
|
||||
*/
|
||||
|
||||
constructor (parent) {
|
||||
super()
|
||||
|
||||
IDS.add(this, 'PreparedStatement')
|
||||
debug('ps(%d): created', IDS.get(this))
|
||||
|
||||
this.parent = parent || globalConnection.pool
|
||||
this._handle = 0
|
||||
this.prepared = false
|
||||
this.parameters = {}
|
||||
}
|
||||
|
||||
get config () {
|
||||
return this.parent.config
|
||||
}
|
||||
|
||||
get connected () {
|
||||
return this.parent.connected
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire connection from connection pool.
|
||||
*
|
||||
* @param {Request} request Request.
|
||||
* @param {ConnectionPool~acquireCallback} [callback] A callback which is called after connection has established, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {PreparedStatement|Promise}
|
||||
*/
|
||||
|
||||
acquire (request, callback) {
|
||||
if (!this._acquiredConnection) {
|
||||
setImmediate(callback, new PreparedStatementError('Statement is not prepared. Call prepare() first.', 'ENOTPREPARED'))
|
||||
return this
|
||||
}
|
||||
|
||||
if (this._activeRequest) {
|
||||
setImmediate(callback, new TransactionError("Can't acquire connection for the request. There is another request in progress.", 'EREQINPROG'))
|
||||
return this
|
||||
}
|
||||
|
||||
this._activeRequest = request
|
||||
setImmediate(callback, null, this._acquiredConnection, this._acquiredConfig)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Release connection back to the pool.
|
||||
*
|
||||
* @param {Connection} connection Previously acquired connection.
|
||||
* @return {PreparedStatement}
|
||||
*/
|
||||
|
||||
release (connection) {
|
||||
if (connection === this._acquiredConnection) {
|
||||
this._activeRequest = null
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an input parameter to the prepared statement.
|
||||
*
|
||||
* @param {String} name Name of the input parameter without @ char.
|
||||
* @param {*} type SQL data type of input parameter.
|
||||
* @return {PreparedStatement}
|
||||
*/
|
||||
|
||||
input (name, type) {
|
||||
if (/--| |\/\*|\*\/|'/.test(name)) {
|
||||
throw new PreparedStatementError(`SQL injection warning for param '${name}'`, 'EINJECT')
|
||||
}
|
||||
|
||||
if (arguments.length < 2) {
|
||||
throw new PreparedStatementError('Invalid number of arguments. 2 arguments expected.', 'EARGS')
|
||||
}
|
||||
|
||||
if (type instanceof Function) {
|
||||
type = type()
|
||||
}
|
||||
|
||||
if (objectHasProperty(this.parameters, name)) {
|
||||
throw new PreparedStatementError(`The parameter name ${name} has already been declared. Parameter names must be unique`, 'EDUPEPARAM')
|
||||
}
|
||||
|
||||
this.parameters[name] = {
|
||||
name,
|
||||
type: type.type,
|
||||
io: 1,
|
||||
length: type.length,
|
||||
scale: type.scale,
|
||||
precision: type.precision,
|
||||
tvpType: type.tvpType
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace an input parameter on the request.
|
||||
*
|
||||
* @param {String} name Name of the input parameter without @ char.
|
||||
* @param {*} [type] SQL data type of input parameter. If you omit type, module automaticaly decide which SQL data type should be used based on JS data type.
|
||||
* @param {*} value Input parameter value. `undefined` and `NaN` values are automatically converted to `null` values.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
replaceInput (name, type, value) {
|
||||
delete this.parameters[name]
|
||||
|
||||
return this.input(name, type, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an output parameter to the prepared statement.
|
||||
*
|
||||
* @param {String} name Name of the output parameter without @ char.
|
||||
* @param {*} type SQL data type of output parameter.
|
||||
* @return {PreparedStatement}
|
||||
*/
|
||||
|
||||
output (name, type) {
|
||||
if (/--| |\/\*|\*\/|'/.test(name)) {
|
||||
throw new PreparedStatementError(`SQL injection warning for param '${name}'`, 'EINJECT')
|
||||
}
|
||||
|
||||
if (arguments.length < 2) {
|
||||
throw new PreparedStatementError('Invalid number of arguments. 2 arguments expected.', 'EARGS')
|
||||
}
|
||||
|
||||
if (type instanceof Function) type = type()
|
||||
|
||||
if (objectHasProperty(this.parameters, name)) {
|
||||
throw new PreparedStatementError(`The parameter name ${name} has already been declared. Parameter names must be unique`, 'EDUPEPARAM')
|
||||
}
|
||||
|
||||
this.parameters[name] = {
|
||||
name,
|
||||
type: type.type,
|
||||
io: 2,
|
||||
length: type.length,
|
||||
scale: type.scale,
|
||||
precision: type.precision
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace an output parameter on the request.
|
||||
*
|
||||
* @param {String} name Name of the output parameter without @ char.
|
||||
* @param {*} type SQL data type of output parameter.
|
||||
* @return {PreparedStatement}
|
||||
*/
|
||||
|
||||
replaceOutput (name, type) {
|
||||
delete this.parameters[name]
|
||||
|
||||
return this.output(name, type)
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare a statement.
|
||||
*
|
||||
* @param {String} statement SQL statement to prepare.
|
||||
* @param {basicCallback} [callback] A callback which is called after preparation has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {PreparedStatement|Promise}
|
||||
*/
|
||||
|
||||
prepare (statement, callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this._prepare(statement, callback)
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._prepare(statement, err => {
|
||||
if (err) return reject(err)
|
||||
resolve(this)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} statement
|
||||
* @param {basicCallback} callback
|
||||
*/
|
||||
|
||||
_prepare (statement, callback) {
|
||||
debug('ps(%d): prepare', IDS.get(this))
|
||||
|
||||
if (typeof statement === 'function') {
|
||||
callback = statement
|
||||
statement = undefined
|
||||
}
|
||||
|
||||
if (this.prepared) {
|
||||
return setImmediate(callback, new PreparedStatementError('Statement is already prepared.', 'EALREADYPREPARED'))
|
||||
}
|
||||
|
||||
this.statement = statement || this.statement
|
||||
|
||||
this.parent.acquire(this, (err, connection, config) => {
|
||||
if (err) return callback(err)
|
||||
|
||||
this._acquiredConnection = connection
|
||||
this._acquiredConfig = config
|
||||
|
||||
const req = new shared.driver.Request(this)
|
||||
req.stream = false
|
||||
req.output('handle', TYPES.Int)
|
||||
req.input('params', TYPES.NVarChar, ((() => {
|
||||
const result = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
result.push(`@${name} ${declare(param.type, param)}${param.io === 2 ? ' output' : ''}`)
|
||||
}
|
||||
return result
|
||||
})()).join(','))
|
||||
req.input('stmt', TYPES.NVarChar, this.statement)
|
||||
req.execute('sp_prepare', (err, result) => {
|
||||
if (err) {
|
||||
this.parent.release(this._acquiredConnection)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
debug('ps(%d): prepared', IDS.get(this))
|
||||
|
||||
this._handle = result.output.handle
|
||||
this.prepared = true
|
||||
|
||||
callback(null)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute a prepared statement.
|
||||
*
|
||||
* @param {Object} values An object whose names correspond to the names of parameters that were added to the prepared statement before it was prepared.
|
||||
* @param {basicCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
execute (values, callback) {
|
||||
if (this.stream || (typeof callback === 'function')) {
|
||||
return this._execute(values, callback)
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._execute(values, (err, recordset) => {
|
||||
if (err) return reject(err)
|
||||
resolve(recordset)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Object} values
|
||||
* @param {basicCallback} callback
|
||||
*/
|
||||
|
||||
_execute (values, callback) {
|
||||
const req = new shared.driver.Request(this)
|
||||
req.stream = this.stream
|
||||
req.arrayRowMode = this.arrayRowMode
|
||||
req.input('handle', TYPES.Int, this._handle)
|
||||
|
||||
// copy parameters with new values
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
req.parameters[name] = {
|
||||
name,
|
||||
type: param.type,
|
||||
io: param.io,
|
||||
value: values[name],
|
||||
length: param.length,
|
||||
scale: param.scale,
|
||||
precision: param.precision
|
||||
}
|
||||
}
|
||||
|
||||
req.execute('sp_execute', (err, result) => {
|
||||
if (err) return callback(err)
|
||||
|
||||
callback(null, result)
|
||||
})
|
||||
|
||||
return req
|
||||
}
|
||||
|
||||
/**
|
||||
* Unprepare a prepared statement.
|
||||
*
|
||||
* @param {basicCallback} [callback] A callback which is called after unpreparation has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {PreparedStatement|Promise}
|
||||
*/
|
||||
|
||||
unprepare (callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this._unprepare(callback)
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._unprepare(err => {
|
||||
if (err) return reject(err)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {basicCallback} callback
|
||||
*/
|
||||
|
||||
_unprepare (callback) {
|
||||
debug('ps(%d): unprepare', IDS.get(this))
|
||||
|
||||
if (!this.prepared) {
|
||||
return setImmediate(callback, new PreparedStatementError('Statement is not prepared. Call prepare() first.', 'ENOTPREPARED'))
|
||||
}
|
||||
|
||||
if (this._activeRequest) {
|
||||
return setImmediate(callback, new TransactionError("Can't unprepare the statement. There is a request in progress.", 'EREQINPROG'))
|
||||
}
|
||||
|
||||
const req = new shared.driver.Request(this)
|
||||
req.stream = false
|
||||
req.input('handle', TYPES.Int, this._handle)
|
||||
req.execute('sp_unprepare', err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
this.parent.release(this._acquiredConnection)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
this._handle = 0
|
||||
this.prepared = false
|
||||
|
||||
debug('ps(%d): unprepared', IDS.get(this))
|
||||
|
||||
return callback(null)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PreparedStatement
|
||||
642
node_modules/mssql/lib/base/request.js
generated
vendored
Normal file
642
node_modules/mssql/lib/base/request.js
generated
vendored
Normal file
@@ -0,0 +1,642 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('mssql:base')
|
||||
const { EventEmitter } = require('node:events')
|
||||
const { Readable } = require('node:stream')
|
||||
const { IDS, objectHasProperty } = require('../utils')
|
||||
const globalConnection = require('../global-connection')
|
||||
const { RequestError, ConnectionError } = require('../error')
|
||||
const { TYPES } = require('../datatypes')
|
||||
const shared = require('../shared')
|
||||
|
||||
/**
|
||||
* Class Request.
|
||||
*
|
||||
* @property {Transaction} transaction Reference to transaction when request was created in transaction.
|
||||
* @property {*} parameters Collection of input and output parameters.
|
||||
* @property {Boolean} canceled `true` if request was canceled.
|
||||
*
|
||||
* @fires Request#recordset
|
||||
* @fires Request#row
|
||||
* @fires Request#done
|
||||
* @fires Request#error
|
||||
*/
|
||||
|
||||
class Request extends EventEmitter {
|
||||
/**
|
||||
* Create new Request.
|
||||
*
|
||||
* @param {Connection|ConnectionPool|Transaction|PreparedStatement} parent If omitted, global connection is used instead.
|
||||
*/
|
||||
|
||||
constructor (parent) {
|
||||
super()
|
||||
|
||||
IDS.add(this, 'Request')
|
||||
debug('request(%d): created', IDS.get(this))
|
||||
|
||||
this.canceled = false
|
||||
this._paused = false
|
||||
this.parent = parent || globalConnection.pool
|
||||
this.parameters = {}
|
||||
this.stream = null
|
||||
this.arrayRowMode = null
|
||||
}
|
||||
|
||||
get paused () {
|
||||
return this._paused
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate sql string and set input parameters from tagged template string.
|
||||
*
|
||||
* @param {Template literal} template
|
||||
* @return {String}
|
||||
*/
|
||||
template () {
|
||||
const values = Array.prototype.slice.call(arguments)
|
||||
const strings = values.shift()
|
||||
return this._template(strings, values)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch request from tagged template string.
|
||||
*
|
||||
* @private
|
||||
* @param {Array} strings
|
||||
* @param {Array} values
|
||||
* @param {String} [method] If provided, method is automatically called with serialized command on this object.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
_template (strings, values, method) {
|
||||
const command = [strings[0]]
|
||||
|
||||
for (let index = 0; index < values.length; index++) {
|
||||
const value = values[index]
|
||||
// if value is an array, prepare each items as it's own comma separated parameter
|
||||
if (Array.isArray(value)) {
|
||||
for (let parameterIndex = 0; parameterIndex < value.length; parameterIndex++) {
|
||||
this.input(`param${index + 1}_${parameterIndex}`, value[parameterIndex])
|
||||
command.push(`@param${index + 1}_${parameterIndex}`)
|
||||
if (parameterIndex < value.length - 1) {
|
||||
command.push(', ')
|
||||
}
|
||||
}
|
||||
command.push(strings[index + 1])
|
||||
} else {
|
||||
this.input(`param${index + 1}`, value)
|
||||
command.push(`@param${index + 1}`, strings[index + 1])
|
||||
}
|
||||
}
|
||||
|
||||
if (method) {
|
||||
return this[method](command.join(''))
|
||||
} else {
|
||||
return command.join('')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an input parameter to the request.
|
||||
*
|
||||
* @param {String} name Name of the input parameter without @ char.
|
||||
* @param {*} [type] SQL data type of input parameter. If you omit type, module automaticaly decide which SQL data type should be used based on JS data type.
|
||||
* @param {*} value Input parameter value. `undefined` and `NaN` values are automatically converted to `null` values.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
input (name, type, value) {
|
||||
if (/--| |\/\*|\*\/|'/.test(name)) {
|
||||
throw new RequestError(`SQL injection warning for param '${name}'`, 'EINJECT')
|
||||
}
|
||||
|
||||
if (arguments.length < 2) {
|
||||
throw new RequestError('Invalid number of arguments. At least 2 arguments expected.', 'EARGS')
|
||||
} else if (arguments.length === 2) {
|
||||
value = type
|
||||
type = shared.getTypeByValue(value)
|
||||
}
|
||||
|
||||
// support for custom data types
|
||||
if (value && typeof value.valueOf === 'function' && !(value instanceof Date)) value = value.valueOf()
|
||||
|
||||
if (value === undefined) value = null // undefined to null
|
||||
if (typeof value === 'number' && isNaN(value)) value = null // NaN to null
|
||||
if (type instanceof Function) type = type()
|
||||
|
||||
if (objectHasProperty(this.parameters, name)) {
|
||||
throw new RequestError(`The parameter name ${name} has already been declared. Parameter names must be unique`, 'EDUPEPARAM')
|
||||
}
|
||||
|
||||
this.parameters[name] = {
|
||||
name,
|
||||
type: type.type,
|
||||
io: 1,
|
||||
value,
|
||||
length: type.length,
|
||||
scale: type.scale,
|
||||
precision: type.precision,
|
||||
tvpType: type.tvpType
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace an input parameter on the request.
|
||||
*
|
||||
* @param {String} name Name of the input parameter without @ char.
|
||||
* @param {*} [type] SQL data type of input parameter. If you omit type, module automaticaly decide which SQL data type should be used based on JS data type.
|
||||
* @param {*} value Input parameter value. `undefined` and `NaN` values are automatically converted to `null` values.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
replaceInput (name, type, value) {
|
||||
delete this.parameters[name]
|
||||
|
||||
return this.input(name, type, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an output parameter to the request.
|
||||
*
|
||||
* @param {String} name Name of the output parameter without @ char.
|
||||
* @param {*} type SQL data type of output parameter.
|
||||
* @param {*} [value] Output parameter value initial value. `undefined` and `NaN` values are automatically converted to `null` values. Optional.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
output (name, type, value) {
|
||||
if (!type) { type = TYPES.NVarChar }
|
||||
|
||||
if (/--| |\/\*|\*\/|'/.test(name)) {
|
||||
throw new RequestError(`SQL injection warning for param '${name}'`, 'EINJECT')
|
||||
}
|
||||
|
||||
if ((type === TYPES.Text) || (type === TYPES.NText) || (type === TYPES.Image)) {
|
||||
throw new RequestError('Deprecated types (Text, NText, Image) are not supported as OUTPUT parameters.', 'EDEPRECATED')
|
||||
}
|
||||
|
||||
// support for custom data types
|
||||
if (value && typeof value.valueOf === 'function' && !(value instanceof Date)) value = value.valueOf()
|
||||
|
||||
if (value === undefined) value = null // undefined to null
|
||||
if (typeof value === 'number' && isNaN(value)) value = null // NaN to null
|
||||
if (type instanceof Function) type = type()
|
||||
|
||||
if (objectHasProperty(this.parameters, name)) {
|
||||
throw new RequestError(`The parameter name ${name} has already been declared. Parameter names must be unique`, 'EDUPEPARAM')
|
||||
}
|
||||
|
||||
this.parameters[name] = {
|
||||
name,
|
||||
type: type.type,
|
||||
io: 2,
|
||||
value,
|
||||
length: type.length,
|
||||
scale: type.scale,
|
||||
precision: type.precision
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace an output parameter on the request.
|
||||
*
|
||||
* @param {String} name Name of the output parameter without @ char.
|
||||
* @param {*} type SQL data type of output parameter.
|
||||
* @param {*} [value] Output parameter value initial value. `undefined` and `NaN` values are automatically converted to `null` values. Optional.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
replaceOutput (name, type, value) {
|
||||
delete this.parameters[name]
|
||||
|
||||
return this.output(name, type, value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the SQL batch.
|
||||
*
|
||||
* @param {String} batch T-SQL batch to be executed.
|
||||
* @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
batch (batch, callback) {
|
||||
if (this.stream === null && this.parent) this.stream = this.parent.config.stream
|
||||
if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
|
||||
this.rowsAffected = 0
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
this._batch(batch, (err, recordsets, output, rowsAffected) => {
|
||||
if (this.stream) {
|
||||
if (err) this.emit('error', err)
|
||||
err = null
|
||||
|
||||
this.emit('done', {
|
||||
output,
|
||||
rowsAffected
|
||||
})
|
||||
}
|
||||
|
||||
if (err) return callback(err)
|
||||
callback(null, {
|
||||
recordsets,
|
||||
recordset: recordsets && recordsets[0],
|
||||
output,
|
||||
rowsAffected
|
||||
})
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
// Check is method was called as tagged template
|
||||
if (typeof batch === 'object') {
|
||||
const values = Array.prototype.slice.call(arguments)
|
||||
const strings = values.shift()
|
||||
batch = this._template(strings, values)
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._batch(batch, (err, recordsets, output, rowsAffected) => {
|
||||
if (this.stream) {
|
||||
if (err) this.emit('error', err)
|
||||
err = null
|
||||
|
||||
this.emit('done', {
|
||||
output,
|
||||
rowsAffected
|
||||
})
|
||||
}
|
||||
|
||||
if (err) return reject(err)
|
||||
resolve({
|
||||
recordsets,
|
||||
recordset: recordsets && recordsets[0],
|
||||
output,
|
||||
rowsAffected
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} batch
|
||||
* @param {Request~requestCallback} callback
|
||||
*/
|
||||
|
||||
_batch (batch, callback) {
|
||||
if (!this.parent) {
|
||||
return setImmediate(callback, new RequestError('No connection is specified for that request.', 'ENOCONN'))
|
||||
}
|
||||
|
||||
if (!this.parent.connected) {
|
||||
return setImmediate(callback, new ConnectionError('Connection is closed.', 'ECONNCLOSED'))
|
||||
}
|
||||
|
||||
this.canceled = false
|
||||
setImmediate(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk load.
|
||||
*
|
||||
* @param {Table} table SQL table.
|
||||
* @param {object} [options] Options to be passed to the underlying driver (tedious only).
|
||||
* @param {Request~bulkCallback} [callback] A callback which is called after bulk load has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
bulk (table, options, callback) {
|
||||
if (typeof options === 'function') {
|
||||
callback = options
|
||||
options = {}
|
||||
} else if (typeof options === 'undefined') {
|
||||
options = {}
|
||||
}
|
||||
|
||||
if (this.stream === null && this.parent) this.stream = this.parent.config.stream
|
||||
if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
|
||||
|
||||
if (this.stream || typeof callback === 'function') {
|
||||
this._bulk(table, options, (err, rowsAffected) => {
|
||||
if (this.stream) {
|
||||
if (err) this.emit('error', err)
|
||||
return this.emit('done', {
|
||||
rowsAffected
|
||||
})
|
||||
}
|
||||
|
||||
if (err) return callback(err)
|
||||
callback(null, {
|
||||
rowsAffected
|
||||
})
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._bulk(table, options, (err, rowsAffected) => {
|
||||
if (err) return reject(err)
|
||||
resolve({
|
||||
rowsAffected
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Table} table
|
||||
* @param {object} options
|
||||
* @param {Request~bulkCallback} callback
|
||||
*/
|
||||
|
||||
_bulk (table, options, callback) {
|
||||
if (!this.parent) {
|
||||
return setImmediate(callback, new RequestError('No connection is specified for that request.', 'ENOCONN'))
|
||||
}
|
||||
|
||||
if (!this.parent.connected) {
|
||||
return setImmediate(callback, new ConnectionError('Connection is closed.', 'ECONNCLOSED'))
|
||||
}
|
||||
|
||||
this.canceled = false
|
||||
setImmediate(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap original request in a Readable stream that supports back pressure and return.
|
||||
* It also sets request to `stream` mode and pulls all rows from all recordsets to a given stream.
|
||||
*
|
||||
* @param {Object} streamOptions - optional options to configure the readable stream with like highWaterMark
|
||||
* @return {Stream}
|
||||
*/
|
||||
toReadableStream (streamOptions = {}) {
|
||||
this.stream = true
|
||||
this.pause()
|
||||
const readableStream = new Readable({
|
||||
...streamOptions,
|
||||
objectMode: true,
|
||||
read: (/* size */) => {
|
||||
this.resume()
|
||||
}
|
||||
})
|
||||
this.on('row', (row) => {
|
||||
if (!readableStream.push(row)) {
|
||||
this.pause()
|
||||
}
|
||||
})
|
||||
this.on('error', (error) => {
|
||||
readableStream.emit('error', error)
|
||||
})
|
||||
this.on('done', () => {
|
||||
readableStream.push(null)
|
||||
})
|
||||
return readableStream
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap original request in a Readable stream that supports back pressure and pipe to the Writable stream.
|
||||
* It also sets request to `stream` mode and pulls all rows from all recordsets to a given stream.
|
||||
*
|
||||
* @param {Stream} stream Stream to pipe data into.
|
||||
* @return {Stream}
|
||||
*/
|
||||
pipe (writableStream) {
|
||||
const readableStream = this.toReadableStream()
|
||||
return readableStream.pipe(writableStream)
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the SQL command.
|
||||
*
|
||||
* @param {String} command T-SQL command to be executed.
|
||||
* @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
query (command, callback) {
|
||||
if (this.stream === null && this.parent) this.stream = this.parent.config.stream
|
||||
if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
|
||||
this.rowsAffected = 0
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
this._query(command, (err, recordsets, output, rowsAffected, columns) => {
|
||||
if (this.stream) {
|
||||
if (err) this.emit('error', err)
|
||||
err = null
|
||||
|
||||
this.emit('done', {
|
||||
output,
|
||||
rowsAffected
|
||||
})
|
||||
}
|
||||
|
||||
if (err) return callback(err)
|
||||
const result = {
|
||||
recordsets,
|
||||
recordset: recordsets && recordsets[0],
|
||||
output,
|
||||
rowsAffected
|
||||
}
|
||||
if (this.arrayRowMode) result.columns = columns
|
||||
callback(null, result)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
// Check is method was called as tagged template
|
||||
if (typeof command === 'object') {
|
||||
const values = Array.prototype.slice.call(arguments)
|
||||
const strings = values.shift()
|
||||
command = this._template(strings, values)
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._query(command, (err, recordsets, output, rowsAffected, columns) => {
|
||||
if (this.stream) {
|
||||
if (err) this.emit('error', err)
|
||||
err = null
|
||||
|
||||
this.emit('done', {
|
||||
output,
|
||||
rowsAffected
|
||||
})
|
||||
}
|
||||
|
||||
if (err) return reject(err)
|
||||
const result = {
|
||||
recordsets,
|
||||
recordset: recordsets && recordsets[0],
|
||||
output,
|
||||
rowsAffected
|
||||
}
|
||||
if (this.arrayRowMode) result.columns = columns
|
||||
resolve(result)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} command
|
||||
* @param {Request~bulkCallback} callback
|
||||
*/
|
||||
|
||||
_query (command, callback) {
|
||||
if (!this.parent) {
|
||||
return setImmediate(callback, new RequestError('No connection is specified for that request.', 'ENOCONN'))
|
||||
}
|
||||
|
||||
if (!this.parent.connected) {
|
||||
return setImmediate(callback, new ConnectionError('Connection is closed.', 'ECONNCLOSED'))
|
||||
}
|
||||
|
||||
this.canceled = false
|
||||
setImmediate(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Call a stored procedure.
|
||||
*
|
||||
* @param {String} procedure Name of the stored procedure to be executed.
|
||||
* @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
execute (command, callback) {
|
||||
if (this.stream === null && this.parent) this.stream = this.parent.config.stream
|
||||
if (this.arrayRowMode === null && this.parent) this.arrayRowMode = this.parent.config.arrayRowMode
|
||||
this.rowsAffected = 0
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
this._execute(command, (err, recordsets, output, returnValue, rowsAffected, columns) => {
|
||||
if (this.stream) {
|
||||
if (err) this.emit('error', err)
|
||||
err = null
|
||||
|
||||
this.emit('done', {
|
||||
output,
|
||||
rowsAffected,
|
||||
returnValue
|
||||
})
|
||||
}
|
||||
|
||||
if (err) return callback(err)
|
||||
const result = {
|
||||
recordsets,
|
||||
recordset: recordsets && recordsets[0],
|
||||
output,
|
||||
rowsAffected,
|
||||
returnValue
|
||||
}
|
||||
if (this.arrayRowMode) result.columns = columns
|
||||
callback(null, result)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._execute(command, (err, recordsets, output, returnValue, rowsAffected, columns) => {
|
||||
if (this.stream) {
|
||||
if (err) this.emit('error', err)
|
||||
err = null
|
||||
|
||||
this.emit('done', {
|
||||
output,
|
||||
rowsAffected,
|
||||
returnValue
|
||||
})
|
||||
}
|
||||
|
||||
if (err) return reject(err)
|
||||
const result = {
|
||||
recordsets,
|
||||
recordset: recordsets && recordsets[0],
|
||||
output,
|
||||
rowsAffected,
|
||||
returnValue
|
||||
}
|
||||
if (this.arrayRowMode) result.columns = columns
|
||||
resolve(result)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {String} procedure
|
||||
* @param {Request~bulkCallback} callback
|
||||
*/
|
||||
|
||||
_execute (procedure, callback) {
|
||||
if (!this.parent) {
|
||||
return setImmediate(callback, new RequestError('No connection is specified for that request.', 'ENOCONN'))
|
||||
}
|
||||
|
||||
if (!this.parent.connected) {
|
||||
return setImmediate(callback, new ConnectionError('Connection is closed.', 'ECONNCLOSED'))
|
||||
}
|
||||
|
||||
this.canceled = false
|
||||
setImmediate(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel currently executed request.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
cancel () {
|
||||
this._cancel()
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
|
||||
_cancel () {
|
||||
this.canceled = true
|
||||
}
|
||||
|
||||
pause () {
|
||||
if (this.stream) {
|
||||
this._pause()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
_pause () {
|
||||
this._paused = true
|
||||
}
|
||||
|
||||
resume () {
|
||||
if (this.stream) {
|
||||
this._resume()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
_resume () {
|
||||
this._paused = false
|
||||
}
|
||||
|
||||
_setCurrentRequest (request) {
|
||||
this._currentRequest = request
|
||||
if (this._paused) {
|
||||
this.pause()
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Request
|
||||
265
node_modules/mssql/lib/base/transaction.js
generated
vendored
Normal file
265
node_modules/mssql/lib/base/transaction.js
generated
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('mssql:base')
|
||||
const { EventEmitter } = require('node:events')
|
||||
const { IDS } = require('../utils')
|
||||
const globalConnection = require('../global-connection')
|
||||
const { TransactionError } = require('../error')
|
||||
const shared = require('../shared')
|
||||
const ISOLATION_LEVEL = require('../isolationlevel')
|
||||
|
||||
/**
|
||||
* Class Transaction.
|
||||
*
|
||||
* @property {Number} isolationLevel Controls the locking and row versioning behavior of TSQL statements issued by a connection. READ_COMMITTED by default.
|
||||
* @property {String} name Transaction name. Empty string by default.
|
||||
*
|
||||
* @fires Transaction#begin
|
||||
* @fires Transaction#commit
|
||||
* @fires Transaction#rollback
|
||||
*/
|
||||
|
||||
class Transaction extends EventEmitter {
|
||||
/**
|
||||
* Create new Transaction.
|
||||
*
|
||||
* @param {Connection} [parent] If ommited, global connection is used instead.
|
||||
*/
|
||||
|
||||
constructor (parent) {
|
||||
super()
|
||||
|
||||
IDS.add(this, 'Transaction')
|
||||
debug('transaction(%d): created', IDS.get(this))
|
||||
|
||||
this.parent = parent || globalConnection.pool
|
||||
this.isolationLevel = Transaction.defaultIsolationLevel
|
||||
this.name = ''
|
||||
}
|
||||
|
||||
get config () {
|
||||
return this.parent.config
|
||||
}
|
||||
|
||||
get connected () {
|
||||
return this.parent.connected
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquire connection from connection pool.
|
||||
*
|
||||
* @param {Request} request Request.
|
||||
* @param {ConnectionPool~acquireCallback} [callback] A callback which is called after connection has established, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Transaction|Promise}
|
||||
*/
|
||||
|
||||
acquire (request, callback) {
|
||||
if (!this._acquiredConnection) {
|
||||
setImmediate(callback, new TransactionError('Transaction has not begun. Call begin() first.', 'ENOTBEGUN'))
|
||||
return this
|
||||
}
|
||||
|
||||
if (this._activeRequest) {
|
||||
setImmediate(callback, new TransactionError("Can't acquire connection for the request. There is another request in progress.", 'EREQINPROG'))
|
||||
return this
|
||||
}
|
||||
|
||||
this._activeRequest = request
|
||||
setImmediate(callback, null, this._acquiredConnection, this._acquiredConfig)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Release connection back to the pool.
|
||||
*
|
||||
* @param {Connection} connection Previously acquired connection.
|
||||
* @return {Transaction}
|
||||
*/
|
||||
|
||||
release (connection) {
|
||||
if (connection === this._acquiredConnection) {
|
||||
this._activeRequest = null
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin a transaction.
|
||||
*
|
||||
* @param {Number} [isolationLevel] Controls the locking and row versioning behavior of TSQL statements issued by a connection.
|
||||
* @param {basicCallback} [callback] A callback which is called after transaction has began, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Transaction|Promise}
|
||||
*/
|
||||
|
||||
begin (isolationLevel, callback) {
|
||||
if (isolationLevel instanceof Function) {
|
||||
callback = isolationLevel
|
||||
isolationLevel = undefined
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
this._begin(isolationLevel, err => {
|
||||
if (!err) {
|
||||
this.emit('begin')
|
||||
}
|
||||
callback(err)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._begin(isolationLevel, err => {
|
||||
if (err) return reject(err)
|
||||
this.emit('begin')
|
||||
resolve(this)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Number} [isolationLevel]
|
||||
* @param {basicCallback} [callback]
|
||||
* @return {Transaction}
|
||||
*/
|
||||
|
||||
_begin (isolationLevel, callback) {
|
||||
if (this._acquiredConnection) {
|
||||
return setImmediate(callback, new TransactionError('Transaction has already begun.', 'EALREADYBEGUN'))
|
||||
}
|
||||
|
||||
this._aborted = false
|
||||
this._rollbackRequested = false
|
||||
if (isolationLevel) {
|
||||
if (Object.keys(ISOLATION_LEVEL).some(key => {
|
||||
return ISOLATION_LEVEL[key] === isolationLevel
|
||||
})) {
|
||||
this.isolationLevel = isolationLevel
|
||||
} else {
|
||||
throw new TransactionError('Invalid isolation level.')
|
||||
}
|
||||
}
|
||||
|
||||
setImmediate(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Commit a transaction.
|
||||
*
|
||||
* @param {basicCallback} [callback] A callback which is called after transaction has commited, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Transaction|Promise}
|
||||
*/
|
||||
|
||||
commit (callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this._commit(err => {
|
||||
if (!err) {
|
||||
this.emit('commit')
|
||||
}
|
||||
callback(err)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this._commit(err => {
|
||||
if (err) return reject(err)
|
||||
this.emit('commit')
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {basicCallback} [callback]
|
||||
* @return {Transaction}
|
||||
*/
|
||||
|
||||
_commit (callback) {
|
||||
if (this._aborted) {
|
||||
return setImmediate(callback, new TransactionError('Transaction has been aborted.', 'EABORT'))
|
||||
}
|
||||
|
||||
if (!this._acquiredConnection) {
|
||||
return setImmediate(callback, new TransactionError('Transaction has not begun. Call begin() first.', 'ENOTBEGUN'))
|
||||
}
|
||||
|
||||
if (this._activeRequest) {
|
||||
return setImmediate(callback, new TransactionError("Can't commit transaction. There is a request in progress.", 'EREQINPROG'))
|
||||
}
|
||||
|
||||
setImmediate(callback)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns new request using this transaction.
|
||||
*
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
request () {
|
||||
return new shared.driver.Request(this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Rollback a transaction.
|
||||
*
|
||||
* @param {basicCallback} [callback] A callback which is called after transaction has rolled back, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Transaction|Promise}
|
||||
*/
|
||||
|
||||
rollback (callback) {
|
||||
if (typeof callback === 'function') {
|
||||
this._rollback(err => {
|
||||
if (!err) {
|
||||
this.emit('rollback', this._aborted)
|
||||
}
|
||||
callback(err)
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
return this._rollback(err => {
|
||||
if (err) return reject(err)
|
||||
this.emit('rollback', this._aborted)
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {basicCallback} [callback]
|
||||
* @return {Transaction}
|
||||
*/
|
||||
|
||||
_rollback (callback) {
|
||||
if (this._aborted) {
|
||||
return setImmediate(callback, new TransactionError('Transaction has been aborted.', 'EABORT'))
|
||||
}
|
||||
|
||||
if (!this._acquiredConnection) {
|
||||
return setImmediate(callback, new TransactionError('Transaction has not begun. Call begin() first.', 'ENOTBEGUN'))
|
||||
}
|
||||
|
||||
if (this._activeRequest) {
|
||||
return setImmediate(callback, new TransactionError("Can't rollback transaction. There is a request in progress.", 'EREQINPROG'))
|
||||
}
|
||||
|
||||
this._rollbackRequested = true
|
||||
|
||||
setImmediate(callback)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Default isolation level used for any transactions that don't explicitly specify an isolation level.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
Transaction.defaultIsolationLevel = ISOLATION_LEVEL.READ_COMMITTED
|
||||
|
||||
module.exports = Transaction
|
||||
193
node_modules/mssql/lib/datatypes.js
generated
vendored
Normal file
193
node_modules/mssql/lib/datatypes.js
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
'use strict'
|
||||
const objectHasProperty = require('./utils').objectHasProperty
|
||||
const inspect = Symbol.for('nodejs.util.inspect.custom')
|
||||
|
||||
const TYPES = {
|
||||
VarChar (length) {
|
||||
return { type: TYPES.VarChar, length }
|
||||
},
|
||||
NVarChar (length) {
|
||||
return { type: TYPES.NVarChar, length }
|
||||
},
|
||||
Text () {
|
||||
return { type: TYPES.Text }
|
||||
},
|
||||
Int () {
|
||||
return { type: TYPES.Int }
|
||||
},
|
||||
BigInt () {
|
||||
return { type: TYPES.BigInt }
|
||||
},
|
||||
TinyInt () {
|
||||
return { type: TYPES.TinyInt }
|
||||
},
|
||||
SmallInt () {
|
||||
return { type: TYPES.SmallInt }
|
||||
},
|
||||
Bit () {
|
||||
return { type: TYPES.Bit }
|
||||
},
|
||||
Float () {
|
||||
return { type: TYPES.Float }
|
||||
},
|
||||
Numeric (precision, scale) {
|
||||
return { type: TYPES.Numeric, precision, scale }
|
||||
},
|
||||
Decimal (precision, scale) {
|
||||
return { type: TYPES.Decimal, precision, scale }
|
||||
},
|
||||
Real () {
|
||||
return { type: TYPES.Real }
|
||||
},
|
||||
Date () {
|
||||
return { type: TYPES.Date }
|
||||
},
|
||||
DateTime () {
|
||||
return { type: TYPES.DateTime }
|
||||
},
|
||||
DateTime2 (scale) {
|
||||
return { type: TYPES.DateTime2, scale }
|
||||
},
|
||||
DateTimeOffset (scale) {
|
||||
return { type: TYPES.DateTimeOffset, scale }
|
||||
},
|
||||
SmallDateTime () {
|
||||
return { type: TYPES.SmallDateTime }
|
||||
},
|
||||
Time (scale) {
|
||||
return { type: TYPES.Time, scale }
|
||||
},
|
||||
UniqueIdentifier () {
|
||||
return { type: TYPES.UniqueIdentifier }
|
||||
},
|
||||
SmallMoney () {
|
||||
return { type: TYPES.SmallMoney }
|
||||
},
|
||||
Money () {
|
||||
return { type: TYPES.Money }
|
||||
},
|
||||
Binary (length) {
|
||||
return { type: TYPES.Binary, length }
|
||||
},
|
||||
VarBinary (length) {
|
||||
return { type: TYPES.VarBinary, length }
|
||||
},
|
||||
Image () {
|
||||
return { type: TYPES.Image }
|
||||
},
|
||||
Xml () {
|
||||
return { type: TYPES.Xml }
|
||||
},
|
||||
Char (length) {
|
||||
return { type: TYPES.Char, length }
|
||||
},
|
||||
NChar (length) {
|
||||
return { type: TYPES.NChar, length }
|
||||
},
|
||||
NText () {
|
||||
return { type: TYPES.NText }
|
||||
},
|
||||
TVP (tvpType) {
|
||||
return { type: TYPES.TVP, tvpType }
|
||||
},
|
||||
UDT () {
|
||||
return { type: TYPES.UDT }
|
||||
},
|
||||
Geography () {
|
||||
return { type: TYPES.Geography }
|
||||
},
|
||||
Geometry () {
|
||||
return { type: TYPES.Geometry }
|
||||
},
|
||||
Variant () {
|
||||
return { type: TYPES.Variant }
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.TYPES = TYPES
|
||||
module.exports.DECLARATIONS = {}
|
||||
|
||||
const zero = function (value, length) {
|
||||
if (length == null) length = 2
|
||||
|
||||
value = String(value)
|
||||
if (value.length < length) {
|
||||
for (let i = 1; i <= length - value.length; i++) {
|
||||
value = `0${value}`
|
||||
}
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
for (const key in TYPES) {
|
||||
if (objectHasProperty(TYPES, key)) {
|
||||
const value = TYPES[key]
|
||||
value.declaration = key.toLowerCase()
|
||||
module.exports.DECLARATIONS[value.declaration] = value;
|
||||
|
||||
((key, value) => {
|
||||
value[inspect] = () => `[sql.${key}]`
|
||||
})(key, value)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.declare = (type, options) => {
|
||||
switch (type) {
|
||||
case TYPES.VarChar: case TYPES.VarBinary:
|
||||
return `${type.declaration} (${options.length > 8000 ? 'MAX' : (options.length == null ? 'MAX' : options.length)})`
|
||||
case TYPES.NVarChar:
|
||||
return `${type.declaration} (${options.length > 4000 ? 'MAX' : (options.length == null ? 'MAX' : options.length)})`
|
||||
case TYPES.Char: case TYPES.NChar: case TYPES.Binary:
|
||||
return `${type.declaration} (${options.length == null ? 1 : options.length})`
|
||||
case TYPES.Decimal: case TYPES.Numeric:
|
||||
return `${type.declaration} (${options.precision == null ? 18 : options.precision}, ${options.scale == null ? 0 : options.scale})`
|
||||
case TYPES.Time: case TYPES.DateTime2: case TYPES.DateTimeOffset:
|
||||
return `${type.declaration} (${options.scale == null ? 7 : options.scale})`
|
||||
case TYPES.TVP:
|
||||
return `${options.tvpType} readonly`
|
||||
default:
|
||||
return type.declaration
|
||||
}
|
||||
}
|
||||
|
||||
module.exports.cast = (value, type, options) => {
|
||||
if (value == null) {
|
||||
return null
|
||||
}
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
return `N'${value.replace(/'/g, '\'\'')}'`
|
||||
|
||||
case 'number':
|
||||
case 'bigint':
|
||||
return value
|
||||
|
||||
case 'boolean':
|
||||
return value ? 1 : 0
|
||||
|
||||
case 'object':
|
||||
if (value instanceof Date) {
|
||||
let ns = value.getUTCMilliseconds() / 1000
|
||||
if (value.nanosecondDelta != null) {
|
||||
ns += value.nanosecondDelta
|
||||
}
|
||||
const scale = options.scale == null ? 7 : options.scale
|
||||
|
||||
if (scale > 0) {
|
||||
ns = String(ns).substr(1, scale + 1)
|
||||
} else {
|
||||
ns = ''
|
||||
}
|
||||
|
||||
return `N'${value.getUTCFullYear()}-${zero(value.getUTCMonth() + 1)}-${zero(value.getUTCDate())} ${zero(value.getUTCHours())}:${zero(value.getUTCMinutes())}:${zero(value.getUTCSeconds())}${ns}'`
|
||||
} else if (Buffer.isBuffer(value)) {
|
||||
return `0x${value.toString('hex')}`
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
24
node_modules/mssql/lib/error/connection-error.js
generated
vendored
Normal file
24
node_modules/mssql/lib/error/connection-error.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const MSSQLError = require('./mssql-error')
|
||||
|
||||
/**
|
||||
* Class ConnectionError.
|
||||
*/
|
||||
|
||||
class ConnectionError extends MSSQLError {
|
||||
/**
|
||||
* Creates a new ConnectionError.
|
||||
*
|
||||
* @param {String} message Error message.
|
||||
* @param {String} [code] Error code.
|
||||
*/
|
||||
|
||||
constructor (message, code) {
|
||||
super(message, code)
|
||||
|
||||
this.name = 'ConnectionError'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConnectionError
|
||||
15
node_modules/mssql/lib/error/index.js
generated
vendored
Normal file
15
node_modules/mssql/lib/error/index.js
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict'
|
||||
|
||||
const ConnectionError = require('./connection-error')
|
||||
const MSSQLError = require('./mssql-error')
|
||||
const PreparedStatementError = require('./prepared-statement-error')
|
||||
const RequestError = require('./request-error')
|
||||
const TransactionError = require('./transaction-error')
|
||||
|
||||
module.exports = {
|
||||
ConnectionError,
|
||||
MSSQLError,
|
||||
PreparedStatementError,
|
||||
RequestError,
|
||||
TransactionError
|
||||
}
|
||||
27
node_modules/mssql/lib/error/mssql-error.js
generated
vendored
Normal file
27
node_modules/mssql/lib/error/mssql-error.js
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict'
|
||||
|
||||
class MSSQLError extends Error {
|
||||
/**
|
||||
* Creates a new ConnectionError.
|
||||
*
|
||||
* @param {String} message Error message.
|
||||
* @param {String} [code] Error code.
|
||||
*/
|
||||
|
||||
constructor (message, code) {
|
||||
if (message instanceof Error) {
|
||||
super(message.message)
|
||||
this.code = message.code || code
|
||||
|
||||
Error.captureStackTrace(this, this.constructor)
|
||||
Object.defineProperty(this, 'originalError', { enumerable: true, value: message })
|
||||
} else {
|
||||
super(message)
|
||||
this.code = code
|
||||
}
|
||||
|
||||
this.name = 'MSSQLError'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MSSQLError
|
||||
24
node_modules/mssql/lib/error/prepared-statement-error.js
generated
vendored
Normal file
24
node_modules/mssql/lib/error/prepared-statement-error.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const MSSQLError = require('./mssql-error')
|
||||
|
||||
/**
|
||||
* Class PreparedStatementError.
|
||||
*/
|
||||
|
||||
class PreparedStatementError extends MSSQLError {
|
||||
/**
|
||||
* Creates a new PreparedStatementError.
|
||||
*
|
||||
* @param {String} message Error message.
|
||||
* @param {String} [code] Error code.
|
||||
*/
|
||||
|
||||
constructor (message, code) {
|
||||
super(message, code)
|
||||
|
||||
this.name = 'PreparedStatementError'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PreparedStatementError
|
||||
53
node_modules/mssql/lib/error/request-error.js
generated
vendored
Normal file
53
node_modules/mssql/lib/error/request-error.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
'use strict'
|
||||
|
||||
const MSSQLError = require('./mssql-error')
|
||||
|
||||
/**
|
||||
* Class RequestError.
|
||||
*
|
||||
* @property {String} number Error number.
|
||||
* @property {Number} lineNumber Line number.
|
||||
* @property {String} state Error state.
|
||||
* @property {String} class Error class.
|
||||
* @property {String} serverName Server name.
|
||||
* @property {String} procName Procedure name.
|
||||
*/
|
||||
|
||||
class RequestError extends MSSQLError {
|
||||
/**
|
||||
* Creates a new RequestError.
|
||||
*
|
||||
* @param {String} message Error message.
|
||||
* @param {String} [code] Error code.
|
||||
*/
|
||||
|
||||
constructor (message, code) {
|
||||
super(message, code)
|
||||
if (message instanceof Error) {
|
||||
if (message.info) {
|
||||
this.number = message.info.number || message.code // err.code is returned by msnodesql driver
|
||||
this.lineNumber = message.info.lineNumber
|
||||
this.state = message.info.state || message.sqlstate // err.sqlstate is returned by msnodesql driver
|
||||
this.class = message.info.class
|
||||
this.serverName = message.info.serverName
|
||||
this.procName = message.info.procName
|
||||
} else {
|
||||
// Use err attributes returned by msnodesql driver
|
||||
this.number = message.code
|
||||
this.lineNumber = message.lineNumber
|
||||
this.state = message.sqlstate
|
||||
this.class = message.severity
|
||||
this.serverName = message.serverName
|
||||
this.procName = message.procName
|
||||
}
|
||||
}
|
||||
|
||||
this.name = 'RequestError'
|
||||
const parsedMessage = (/^\[Microsoft\]\[SQL Server Native Client 11\.0\](?:\[SQL Server\])?([\s\S]*)$/).exec(this.message)
|
||||
if (parsedMessage) {
|
||||
this.message = parsedMessage[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RequestError
|
||||
24
node_modules/mssql/lib/error/transaction-error.js
generated
vendored
Normal file
24
node_modules/mssql/lib/error/transaction-error.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict'
|
||||
|
||||
const MSSQLError = require('./mssql-error')
|
||||
|
||||
/**
|
||||
* Class TransactionError.
|
||||
*/
|
||||
|
||||
class TransactionError extends MSSQLError {
|
||||
/**
|
||||
* Creates a new TransactionError.
|
||||
*
|
||||
* @param {String} message Error message.
|
||||
* @param {String} [code] Error code.
|
||||
*/
|
||||
|
||||
constructor (message, code) {
|
||||
super(message, code)
|
||||
|
||||
this.name = 'TransactionError'
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TransactionError
|
||||
193
node_modules/mssql/lib/global-connection.js
generated
vendored
Normal file
193
node_modules/mssql/lib/global-connection.js
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
'use strict'
|
||||
|
||||
const shared = require('./shared')
|
||||
|
||||
let globalConnection = null
|
||||
const globalConnectionHandlers = {}
|
||||
|
||||
/**
|
||||
* Open global connection pool.
|
||||
*
|
||||
* @param {Object|String} config Connection configuration object or connection string.
|
||||
* @param {basicCallback} [callback] A callback which is called after connection has established, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Promise.<ConnectionPool>}
|
||||
*/
|
||||
|
||||
function connect (config, callback) {
|
||||
if (!globalConnection) {
|
||||
globalConnection = new shared.driver.ConnectionPool(config)
|
||||
|
||||
for (const event in globalConnectionHandlers) {
|
||||
for (let i = 0, l = globalConnectionHandlers[event].length; i < l; i++) {
|
||||
globalConnection.on(event, globalConnectionHandlers[event][i])
|
||||
}
|
||||
}
|
||||
|
||||
const ogClose = globalConnection.close
|
||||
|
||||
const globalClose = function (callback) {
|
||||
// remove event handlers from the global connection
|
||||
for (const event in globalConnectionHandlers) {
|
||||
for (let i = 0, l = globalConnectionHandlers[event].length; i < l; i++) {
|
||||
this.removeListener(event, globalConnectionHandlers[event][i])
|
||||
}
|
||||
}
|
||||
|
||||
// attach error handler to prevent process crash in case of error
|
||||
this.on('error', err => {
|
||||
if (globalConnectionHandlers.error) {
|
||||
for (let i = 0, l = globalConnectionHandlers.error.length; i < l; i++) {
|
||||
globalConnectionHandlers.error[i].call(this, err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
globalConnection = null
|
||||
return ogClose.call(this, callback)
|
||||
}
|
||||
|
||||
globalConnection.close = globalClose.bind(globalConnection)
|
||||
}
|
||||
if (typeof callback === 'function') {
|
||||
return globalConnection.connect((err, connection) => {
|
||||
if (err) {
|
||||
globalConnection = null
|
||||
}
|
||||
callback(err, connection)
|
||||
})
|
||||
}
|
||||
return globalConnection.connect().catch((err) => {
|
||||
globalConnection = null
|
||||
return shared.Promise.reject(err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Close all active connections in the global pool.
|
||||
*
|
||||
* @param {basicCallback} [callback] A callback which is called after connection has closed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {ConnectionPool|Promise}
|
||||
*/
|
||||
|
||||
function close (callback) {
|
||||
if (globalConnection) {
|
||||
const gc = globalConnection
|
||||
globalConnection = null
|
||||
return gc.close(callback)
|
||||
}
|
||||
|
||||
if (typeof callback === 'function') {
|
||||
setImmediate(callback)
|
||||
return null
|
||||
}
|
||||
|
||||
return new shared.Promise((resolve) => {
|
||||
resolve(globalConnection)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach event handler to global connection pool.
|
||||
*
|
||||
* @param {String} event Event name.
|
||||
* @param {Function} handler Event handler.
|
||||
* @return {ConnectionPool}
|
||||
*/
|
||||
|
||||
function on (event, handler) {
|
||||
if (!globalConnectionHandlers[event]) globalConnectionHandlers[event] = []
|
||||
globalConnectionHandlers[event].push(handler)
|
||||
|
||||
if (globalConnection) globalConnection.on(event, handler)
|
||||
return globalConnection
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach event handler from global connection.
|
||||
*
|
||||
* @param {String} event Event name.
|
||||
* @param {Function} handler Event handler.
|
||||
* @return {ConnectionPool}
|
||||
*/
|
||||
|
||||
function removeListener (event, handler) {
|
||||
if (!globalConnectionHandlers[event]) return globalConnection
|
||||
const index = globalConnectionHandlers[event].indexOf(handler)
|
||||
if (index === -1) return globalConnection
|
||||
globalConnectionHandlers[event].splice(index, 1)
|
||||
if (globalConnectionHandlers[event].length === 0) globalConnectionHandlers[event] = undefined
|
||||
|
||||
if (globalConnection) globalConnection.removeListener(event, handler)
|
||||
return globalConnection
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new query using global connection from a tagged template string.
|
||||
*
|
||||
* @variation 1
|
||||
* @param {Array|String} strings Array of string literals or sql command.
|
||||
* @param {...*} keys Values.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the SQL command.
|
||||
*
|
||||
* @variation 2
|
||||
* @param {String} command T-SQL command to be executed.
|
||||
* @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
function query () {
|
||||
if (typeof arguments[0] === 'string') { return new shared.driver.Request().query(arguments[0], arguments[1]) }
|
||||
|
||||
const values = Array.prototype.slice.call(arguments)
|
||||
const strings = values.shift()
|
||||
|
||||
return new shared.driver.Request()._template(strings, values, 'query')
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new batch using global connection from a tagged template string.
|
||||
*
|
||||
* @variation 1
|
||||
* @param {Array} strings Array of string literals.
|
||||
* @param {...*} keys Values.
|
||||
* @return {Request}
|
||||
*/
|
||||
|
||||
/**
|
||||
* Execute the SQL command.
|
||||
*
|
||||
* @variation 2
|
||||
* @param {String} command T-SQL command to be executed.
|
||||
* @param {Request~requestCallback} [callback] A callback which is called after execution has completed, or an error has occurred. If omited, method returns Promise.
|
||||
* @return {Request|Promise}
|
||||
*/
|
||||
|
||||
function batch () {
|
||||
if (typeof arguments[0] === 'string') { return new shared.driver.Request().batch(arguments[0], arguments[1]) }
|
||||
|
||||
const values = Array.prototype.slice.call(arguments)
|
||||
const strings = values.shift()
|
||||
|
||||
return new shared.driver.Request()._template(strings, values, 'batch')
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
batch,
|
||||
close,
|
||||
connect,
|
||||
off: removeListener,
|
||||
on,
|
||||
query,
|
||||
removeListener
|
||||
}
|
||||
|
||||
Object.defineProperty(module.exports, 'pool', {
|
||||
get: () => {
|
||||
return globalConnection
|
||||
},
|
||||
set: () => {}
|
||||
})
|
||||
9
node_modules/mssql/lib/isolationlevel.js
generated
vendored
Normal file
9
node_modules/mssql/lib/isolationlevel.js
generated
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
|
||||
module.exports = {
|
||||
READ_UNCOMMITTED: 0x01,
|
||||
READ_COMMITTED: 0x02,
|
||||
REPEATABLE_READ: 0x03,
|
||||
SERIALIZABLE: 0x04,
|
||||
SNAPSHOT: 0x05
|
||||
}
|
||||
84
node_modules/mssql/lib/msnodesqlv8/connection-pool.js
generated
vendored
Normal file
84
node_modules/mssql/lib/msnodesqlv8/connection-pool.js
generated
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
'use strict'
|
||||
|
||||
const msnodesql = require('msnodesqlv8')
|
||||
const debug = require('debug')('mssql:msv8')
|
||||
const BaseConnectionPool = require('../base/connection-pool')
|
||||
const { IDS, INCREMENT } = require('../utils')
|
||||
const shared = require('../shared')
|
||||
const ConnectionError = require('../error/connection-error')
|
||||
const { platform } = require('node:os')
|
||||
const { buildConnectionString } = require('@tediousjs/connection-string')
|
||||
|
||||
const CONNECTION_DRIVER = ['darwin', 'linux'].includes(platform()) ? 'ODBC Driver 17 for SQL Server' : 'SQL Server Native Client 11.0'
|
||||
|
||||
class ConnectionPool extends BaseConnectionPool {
|
||||
_poolCreate () {
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
this.config.requestTimeout = this.config.requestTimeout ?? this.config.timeout ?? 15000
|
||||
|
||||
const cfg = {
|
||||
conn_str: this.config.connectionString,
|
||||
conn_timeout: (this.config.connectionTimeout ?? this.config.timeout ?? 15000) / 1000
|
||||
}
|
||||
|
||||
if (!this.config.connectionString) {
|
||||
cfg.conn_str = buildConnectionString({
|
||||
Driver: CONNECTION_DRIVER,
|
||||
Server: this.config.options.instanceName ? `${this.config.server}\\${this.config.options.instanceName}` : `${this.config.server},${this.config.port}`,
|
||||
Database: this.config.database,
|
||||
Uid: this.config.user,
|
||||
Pwd: this.config.password,
|
||||
Trusted_Connection: !!this.config.options.trustedConnection,
|
||||
Encrypt: !!this.config.options.encrypt
|
||||
})
|
||||
}
|
||||
|
||||
const connedtionId = INCREMENT.Connection++
|
||||
debug('pool(%d): connection #%d created', IDS.get(this), connedtionId)
|
||||
debug('connection(%d): establishing', connedtionId)
|
||||
|
||||
if (typeof this.config.beforeConnect === 'function') {
|
||||
this.config.beforeConnect(cfg)
|
||||
}
|
||||
|
||||
msnodesql.open(cfg, (err, tds) => {
|
||||
if (err) {
|
||||
err = new ConnectionError(err)
|
||||
return reject(err)
|
||||
}
|
||||
|
||||
IDS.add(tds, 'Connection', connedtionId)
|
||||
tds.setUseUTC(this.config.options.useUTC)
|
||||
debug('connection(%d): established', IDS.get(tds))
|
||||
resolve(tds)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_poolValidate (tds) {
|
||||
if (tds && !tds.hasError) {
|
||||
return !this.config.validateConnection || new shared.Promise((resolve) => {
|
||||
tds.query('SELECT 1;', (err) => {
|
||||
resolve(!err)
|
||||
})
|
||||
})
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
_poolDestroy (tds) {
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
if (!tds) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
debug('connection(%d): destroying', IDS.get(tds))
|
||||
tds.close(() => {
|
||||
debug('connection(%d): destroyed', IDS.get(tds))
|
||||
resolve()
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConnectionPool
|
||||
35
node_modules/mssql/lib/msnodesqlv8/index.js
generated
vendored
Normal file
35
node_modules/mssql/lib/msnodesqlv8/index.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
|
||||
const base = require('../base')
|
||||
const ConnectionPool = require('./connection-pool')
|
||||
const Transaction = require('./transaction')
|
||||
const Request = require('./request')
|
||||
|
||||
module.exports = Object.assign({
|
||||
ConnectionPool,
|
||||
Transaction,
|
||||
Request,
|
||||
PreparedStatement: base.PreparedStatement
|
||||
}, base.exports)
|
||||
|
||||
Object.defineProperty(module.exports, 'Promise', {
|
||||
enumerable: true,
|
||||
get: () => {
|
||||
return base.Promise
|
||||
},
|
||||
set: (value) => {
|
||||
base.Promise = value
|
||||
}
|
||||
})
|
||||
|
||||
Object.defineProperty(module.exports, 'valueHandler', {
|
||||
enumerable: true,
|
||||
value: base.valueHandler,
|
||||
writable: false,
|
||||
configurable: false
|
||||
})
|
||||
|
||||
base.driver.name = 'msnodesqlv8'
|
||||
base.driver.ConnectionPool = ConnectionPool
|
||||
base.driver.Transaction = Transaction
|
||||
base.driver.Request = Request
|
||||
769
node_modules/mssql/lib/msnodesqlv8/request.js
generated
vendored
Normal file
769
node_modules/mssql/lib/msnodesqlv8/request.js
generated
vendored
Normal file
@@ -0,0 +1,769 @@
|
||||
'use strict'
|
||||
|
||||
const msnodesql = require('msnodesqlv8')
|
||||
const debug = require('debug')('mssql:msv8')
|
||||
const BaseRequest = require('../base/request')
|
||||
const RequestError = require('../error/request-error')
|
||||
const { IDS, objectHasProperty } = require('../utils')
|
||||
const { TYPES, DECLARATIONS, declare } = require('../datatypes')
|
||||
const { PARSERS: UDT } = require('../udt')
|
||||
const Table = require('../table')
|
||||
const { valueHandler } = require('../shared')
|
||||
|
||||
const JSON_COLUMN_ID = 'JSON_F52E2B61-18A1-11d1-B105-00805F49916B'
|
||||
const XML_COLUMN_ID = 'XML_F52E2B61-18A1-11d1-B105-00805F49916B'
|
||||
const EMPTY_BUFFER = Buffer.alloc(0)
|
||||
|
||||
const castParameter = function (value, type) {
|
||||
if (value == null) {
|
||||
if ((type === TYPES.Binary) || (type === TYPES.VarBinary) || (type === TYPES.Image)) {
|
||||
// msnodesql has some problems with NULL values in those types, so we need to replace it with empty buffer
|
||||
return EMPTY_BUFFER
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TYPES.VarChar:
|
||||
case TYPES.NVarChar:
|
||||
case TYPES.Char:
|
||||
case TYPES.NChar:
|
||||
case TYPES.Xml:
|
||||
case TYPES.Text:
|
||||
case TYPES.NText:
|
||||
if ((typeof value !== 'string') && !(value instanceof String)) {
|
||||
value = value.toString()
|
||||
}
|
||||
break
|
||||
|
||||
case TYPES.Int:
|
||||
case TYPES.TinyInt:
|
||||
case TYPES.BigInt:
|
||||
case TYPES.SmallInt:
|
||||
if ((typeof value !== 'number') && !(value instanceof Number)) {
|
||||
value = parseInt(value)
|
||||
if (isNaN(value)) { value = null }
|
||||
}
|
||||
break
|
||||
|
||||
case TYPES.Float:
|
||||
case TYPES.Real:
|
||||
case TYPES.Decimal:
|
||||
case TYPES.Numeric:
|
||||
case TYPES.SmallMoney:
|
||||
case TYPES.Money:
|
||||
if ((typeof value !== 'number') && !(value instanceof Number)) {
|
||||
value = parseFloat(value)
|
||||
if (isNaN(value)) { value = null }
|
||||
}
|
||||
break
|
||||
|
||||
case TYPES.Bit:
|
||||
if ((typeof value !== 'boolean') && !(value instanceof Boolean)) {
|
||||
value = Boolean(value)
|
||||
}
|
||||
break
|
||||
|
||||
case TYPES.DateTime:
|
||||
case TYPES.SmallDateTime:
|
||||
case TYPES.DateTimeOffset:
|
||||
case TYPES.Date:
|
||||
if (!(value instanceof Date)) {
|
||||
value = new Date(value)
|
||||
}
|
||||
break
|
||||
|
||||
case TYPES.Binary:
|
||||
case TYPES.VarBinary:
|
||||
case TYPES.Image:
|
||||
if (!(value instanceof Buffer)) {
|
||||
value = Buffer.from(value.toString())
|
||||
}
|
||||
break
|
||||
case TYPES.TVP:
|
||||
value = msnodesql.TvpFromTable(value)
|
||||
break
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
const createColumns = function (metadata, arrayRowMode) {
|
||||
let out = {}
|
||||
if (arrayRowMode) out = []
|
||||
for (let index = 0, length = metadata.length; index < length; index++) {
|
||||
const column = metadata[index]
|
||||
const colName = column.name
|
||||
const outColumn = {
|
||||
index,
|
||||
name: column.name,
|
||||
length: column.size,
|
||||
type: DECLARATIONS[column.sqlType],
|
||||
nullable: column.nullable
|
||||
}
|
||||
|
||||
if (column.udtType != null) {
|
||||
outColumn.udt = {
|
||||
name: column.udtType
|
||||
}
|
||||
|
||||
if (DECLARATIONS[column.udtType]) {
|
||||
outColumn.type = DECLARATIONS[column.udtType]
|
||||
}
|
||||
}
|
||||
if (arrayRowMode) {
|
||||
out.push(outColumn)
|
||||
} else {
|
||||
out[colName] = outColumn
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
const valueCorrection = function (value, metadata) {
|
||||
const type = metadata && objectHasProperty(metadata, 'sqlType') && objectHasProperty(DECLARATIONS, metadata.sqlType)
|
||||
? DECLARATIONS[metadata.sqlType]
|
||||
: null
|
||||
if (type && valueHandler.has(type)) {
|
||||
return valueHandler.get(type)(value)
|
||||
} else if ((metadata.sqlType === 'time') && (value != null)) {
|
||||
value.setFullYear(1970)
|
||||
return value
|
||||
} else if ((metadata.sqlType === 'udt') && (value != null)) {
|
||||
if (UDT[metadata.udtType]) {
|
||||
return UDT[metadata.udtType](value)
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
} else {
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
class Request extends BaseRequest {
|
||||
_batch (batch, callback) {
|
||||
this._isBatch = true
|
||||
this._query(batch, callback)
|
||||
}
|
||||
|
||||
_bulk (table, options, callback) {
|
||||
super._bulk(table, options, err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
try {
|
||||
table._makeBulk()
|
||||
} catch (e) {
|
||||
return callback(new RequestError(e, 'EREQUEST'))
|
||||
}
|
||||
|
||||
if (!table.name) {
|
||||
setImmediate(callback, new RequestError('Table name must be specified for bulk insert.', 'ENAME'))
|
||||
}
|
||||
|
||||
if (table.name.charAt(0) === '@') {
|
||||
setImmediate(callback, new RequestError("You can't use table variables for bulk insert.", 'ENAME'))
|
||||
}
|
||||
|
||||
this.parent.acquire(this, (err, connection) => {
|
||||
let hasReturned = false
|
||||
if (!err) {
|
||||
debug('connection(%d): borrowed to request #%d', IDS.get(connection), IDS.get(this))
|
||||
|
||||
if (this.canceled) {
|
||||
debug('request(%d): canceled', IDS.get(this))
|
||||
this.parent.release(connection)
|
||||
return callback(new RequestError('Canceled.', 'ECANCEL'))
|
||||
}
|
||||
|
||||
const done = (err, rowCount) => {
|
||||
if (hasReturned) {
|
||||
return
|
||||
}
|
||||
|
||||
hasReturned = true
|
||||
|
||||
if (err) {
|
||||
if ((typeof err.sqlstate === 'string') && (err.sqlstate.toLowerCase() === '08s01')) {
|
||||
connection.hasError = true
|
||||
}
|
||||
|
||||
err = new RequestError(err)
|
||||
err.code = 'EREQUEST'
|
||||
}
|
||||
|
||||
this.parent.release(connection)
|
||||
|
||||
if (err) {
|
||||
callback(err)
|
||||
} else {
|
||||
callback(null, table.rows.length)
|
||||
}
|
||||
}
|
||||
|
||||
const go = () => {
|
||||
const tm = connection.tableMgr()
|
||||
return tm.bind(table.path.replace(/\[|\]/g, ''), mgr => {
|
||||
if (mgr.columns.length === 0) {
|
||||
return done(new RequestError('Table was not found on the server.', 'ENAME'))
|
||||
}
|
||||
|
||||
const rows = []
|
||||
for (const row of Array.from(table.rows)) {
|
||||
const item = {}
|
||||
for (let index = 0; index < table.columns.length; index++) {
|
||||
const col = table.columns[index]
|
||||
item[col.name] = row[index]
|
||||
}
|
||||
|
||||
rows.push(item)
|
||||
}
|
||||
|
||||
mgr.insertRows(rows, done)
|
||||
})
|
||||
}
|
||||
|
||||
if (table.create) {
|
||||
let objectid
|
||||
if (table.temporary) {
|
||||
objectid = `tempdb..[${table.name}]`
|
||||
} else {
|
||||
objectid = table.path
|
||||
}
|
||||
|
||||
return connection.queryRaw(`if object_id('${objectid.replace(/'/g, '\'\'')}') is null ${table.declare()}`, function (err) {
|
||||
if (err) { return done(err) }
|
||||
go()
|
||||
})
|
||||
} else {
|
||||
go()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_query (command, callback) {
|
||||
super._query(command, err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
if (command.length === 0) {
|
||||
return callback(null, [])
|
||||
}
|
||||
|
||||
const recordsets = []
|
||||
const recordsetcolumns = []
|
||||
const errors = []
|
||||
const errorHandlers = {}
|
||||
const output = {}
|
||||
const rowsAffected = []
|
||||
|
||||
let hasReturned = false
|
||||
let row = null
|
||||
let columns = null
|
||||
let recordset = null
|
||||
let handleOutput = false
|
||||
let isChunkedRecordset = false
|
||||
let chunksBuffer = null
|
||||
|
||||
const handleError = (req, connection, info, moreErrors) => {
|
||||
const doReturn = !moreErrors
|
||||
if ((typeof info.sqlstate === 'string') && (info.sqlstate.toLowerCase() === '08s01')) {
|
||||
connection.hasError = true
|
||||
}
|
||||
|
||||
const err = new RequestError(info, 'EREQUEST')
|
||||
err.code = 'EREQUEST'
|
||||
|
||||
if (this.stream) {
|
||||
this.emit('error', err)
|
||||
} else {
|
||||
if (doReturn && !hasReturned) {
|
||||
if (req) {
|
||||
for (const event in errorHandlers) {
|
||||
req.removeListener(event, errorHandlers[event])
|
||||
}
|
||||
}
|
||||
if (connection) {
|
||||
this.parent.release(connection)
|
||||
delete this._cancel
|
||||
|
||||
debug('request(%d): failed', IDS.get(this), err)
|
||||
}
|
||||
|
||||
let previous
|
||||
if (errors.length) {
|
||||
previous = errors.pop()
|
||||
if (!err.precedingErrors) {
|
||||
err.precedingErrors = []
|
||||
}
|
||||
err.precedingErrors.push(previous)
|
||||
}
|
||||
|
||||
hasReturned = true
|
||||
callback(err)
|
||||
}
|
||||
}
|
||||
|
||||
// we must collect errors even in stream mode
|
||||
errors.push(err)
|
||||
}
|
||||
|
||||
// nested = function is called by this.execute
|
||||
|
||||
if (!this._nested) {
|
||||
const input = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
input.push(`@${param.name} ${declare(param.type, param)}`)
|
||||
}
|
||||
|
||||
const sets = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 1) {
|
||||
sets.push(`set @${param.name}=?`)
|
||||
}
|
||||
}
|
||||
|
||||
const output = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 2) {
|
||||
output.push(`@${param.name} as '${param.name}'`)
|
||||
}
|
||||
}
|
||||
|
||||
if (input.length) command = `declare ${input.join(',')};${sets.join(';')};${command};`
|
||||
if (output.length) {
|
||||
command += `select ${output.join(',')};`
|
||||
handleOutput = true
|
||||
}
|
||||
}
|
||||
|
||||
this.parent.acquire(this, (err, connection, config) => {
|
||||
if (err) return callback(err)
|
||||
|
||||
debug('connection(%d): borrowed to request #%d', IDS.get(connection), IDS.get(this))
|
||||
|
||||
if (this.canceled) {
|
||||
debug('request(%d): canceled', IDS.get(this))
|
||||
this.parent.release(connection)
|
||||
return callback(new RequestError('Canceled.', 'ECANCEL'))
|
||||
}
|
||||
|
||||
const params = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 1 || (param.io === 2 && param.value)) {
|
||||
params.push(castParameter(param.value, param.type))
|
||||
}
|
||||
}
|
||||
|
||||
debug('request(%d): query', IDS.get(this), command)
|
||||
|
||||
const req = connection.queryRaw({
|
||||
query_str: command,
|
||||
query_timeout: config.requestTimeout / 1000 // msnodesqlv8 timeouts are in seconds (<1 second not supported)
|
||||
}, params)
|
||||
|
||||
this._setCurrentRequest(req)
|
||||
|
||||
this._cancel = () => {
|
||||
debug('request(%d): cancel', IDS.get(this))
|
||||
req.cancelQuery(err => {
|
||||
if (err) debug('request(%d): failed to cancel', IDS.get(this), err)
|
||||
// this fixes an issue where paused connections don't emit a done event
|
||||
try {
|
||||
if (req.isPaused()) req.emit('done')
|
||||
} catch (err) {
|
||||
// do nothing
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
req.on('meta', metadata => {
|
||||
if (row) {
|
||||
if (isChunkedRecordset) {
|
||||
const concatenatedChunks = chunksBuffer.join('')
|
||||
if ((columns[0].name === JSON_COLUMN_ID) && (config.parseJSON === true)) {
|
||||
try {
|
||||
if (concatenatedChunks === '') {
|
||||
row = null
|
||||
} else {
|
||||
row = JSON.parse(concatenatedChunks)
|
||||
}
|
||||
if (!this.stream) { recordsets[recordsets.length - 1][0] = row }
|
||||
} catch (ex) {
|
||||
row = null
|
||||
const ex2 = new RequestError(`Failed to parse incoming JSON. ${ex.message}`, 'EJSON')
|
||||
|
||||
if (this.stream) {
|
||||
this.emit('error', ex2)
|
||||
} else {
|
||||
console.error(ex2)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
row[columns[0].name] = concatenatedChunks
|
||||
}
|
||||
|
||||
chunksBuffer = null
|
||||
if (row && row.___return___ == null) {
|
||||
// row with ___return___ col is the last row
|
||||
if (this.stream && !this.paused) this.emit('row', row)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
row = null
|
||||
columns = metadata
|
||||
recordset = []
|
||||
|
||||
Object.defineProperty(recordset, 'columns', {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value: createColumns(metadata, this.arrayRowMode)
|
||||
})
|
||||
|
||||
Object.defineProperty(recordset, 'toTable', {
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
value (name) { return Table.fromRecordset(this, name) }
|
||||
})
|
||||
|
||||
isChunkedRecordset = false
|
||||
if ((metadata.length === 1) && (metadata[0].name === JSON_COLUMN_ID || metadata[0].name === XML_COLUMN_ID)) {
|
||||
isChunkedRecordset = true
|
||||
chunksBuffer = []
|
||||
}
|
||||
|
||||
let hasReturnColumn = false
|
||||
if (recordset.columns.___return___ != null) {
|
||||
hasReturnColumn = true
|
||||
} else if (this.arrayRowMode) {
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
if (columns[i].name === '___return___') {
|
||||
hasReturnColumn = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.stream) {
|
||||
if (!hasReturnColumn) {
|
||||
this.emit('recordset', recordset.columns)
|
||||
}
|
||||
} else {
|
||||
recordsets.push(recordset)
|
||||
}
|
||||
if (this.arrayRowMode) recordsetcolumns.push(recordset.columns)
|
||||
})
|
||||
|
||||
req.on('row', rownumber => {
|
||||
if (row && isChunkedRecordset) return
|
||||
|
||||
if (this.arrayRowMode) {
|
||||
row = []
|
||||
} else {
|
||||
row = {}
|
||||
}
|
||||
|
||||
if (!this.stream) recordset.push(row)
|
||||
})
|
||||
|
||||
req.on('column', (idx, data, more) => {
|
||||
if (isChunkedRecordset) {
|
||||
chunksBuffer.push(data)
|
||||
} else {
|
||||
data = valueCorrection(data, columns[idx])
|
||||
|
||||
if (this.arrayRowMode) {
|
||||
row.push(data)
|
||||
} else {
|
||||
const exi = row[columns[idx].name]
|
||||
if (exi != null) {
|
||||
if (exi instanceof Array) {
|
||||
exi.push(data)
|
||||
} else {
|
||||
row[columns[idx].name] = [exi, data]
|
||||
}
|
||||
} else {
|
||||
row[columns[idx].name] = data
|
||||
}
|
||||
}
|
||||
let hasReturnColumn = false
|
||||
if (row && row.___return___ != null) {
|
||||
hasReturnColumn = true
|
||||
} else if (this.arrayRowMode) {
|
||||
for (let i = 0; i < columns.length; i++) {
|
||||
if (columns[i].name === '___return___') {
|
||||
hasReturnColumn = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasReturnColumn) {
|
||||
if (this.stream && !this.paused && idx === columns.length - 1) {
|
||||
this.emit('row', row)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
req.on('rowcount', rowCount => {
|
||||
rowsAffected.push(rowCount)
|
||||
if (this.stream) {
|
||||
this.emit('rowsaffected', rowCount)
|
||||
}
|
||||
})
|
||||
|
||||
req.on('info', msg => {
|
||||
const parsedMessage = (/^\[Microsoft\]\[SQL Server Native Client 11\.0\](?:\[SQL Server\])?([\s\S]*)$/).exec(msg.message)
|
||||
if (parsedMessage) {
|
||||
msg.message = parsedMessage[1]
|
||||
}
|
||||
|
||||
this.emit('info', {
|
||||
message: msg.message,
|
||||
number: msg.code,
|
||||
state: msg.sqlstate,
|
||||
class: msg.class || 0,
|
||||
lineNumber: msg.lineNumber || 0,
|
||||
serverName: msg.serverName,
|
||||
procName: msg.procName
|
||||
})
|
||||
|
||||
// query terminated
|
||||
if (msg.code === 3621 && !hasReturned) {
|
||||
// if the query has been terminated it's probably best to throw the last meaningful error if there was one
|
||||
// pop it off the errors array so it doesn't get put in twice
|
||||
const error = errors.length > 0 ? errors.pop() : msg
|
||||
handleError(req, connection, error.originalError || error, false)
|
||||
}
|
||||
})
|
||||
|
||||
req.on('error', errorHandlers.error = handleError.bind(null, req, connection))
|
||||
|
||||
req.once('done', () => {
|
||||
if (hasReturned) {
|
||||
return
|
||||
}
|
||||
|
||||
hasReturned = true
|
||||
|
||||
if (!this._nested) {
|
||||
if (row) {
|
||||
if (isChunkedRecordset) {
|
||||
const concatenatedChunks = chunksBuffer.join('')
|
||||
if ((columns[0].name === JSON_COLUMN_ID) && (config.parseJSON === true)) {
|
||||
try {
|
||||
if (concatenatedChunks === '') {
|
||||
row = null
|
||||
} else {
|
||||
row = JSON.parse(concatenatedChunks)
|
||||
}
|
||||
if (!this.stream) { recordsets[recordsets.length - 1][0] = row }
|
||||
} catch (ex) {
|
||||
row = null
|
||||
const ex2 = new RequestError(`Failed to parse incoming JSON. ${ex.message}`, 'EJSON')
|
||||
|
||||
if (this.stream) {
|
||||
this.emit('error', ex2)
|
||||
} else {
|
||||
console.error(ex2)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
row[columns[0].name] = concatenatedChunks
|
||||
}
|
||||
|
||||
chunksBuffer = null
|
||||
if (row && row.___return___ == null) {
|
||||
// row with ___return___ col is the last row
|
||||
if (this.stream && !this.paused) { this.emit('row', row) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do we have output parameters to handle?
|
||||
if (handleOutput && recordsets.length) {
|
||||
const last = recordsets.pop()[0]
|
||||
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 2) {
|
||||
output[param.name] = last[param.name]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete this._cancel
|
||||
this.parent.release(connection)
|
||||
|
||||
debug('request(%d): completed', IDS.get(this))
|
||||
|
||||
if (this.stream) {
|
||||
callback(null, this._nested ? row : null, output, rowsAffected, recordsetcolumns)
|
||||
} else {
|
||||
callback(null, recordsets, output, rowsAffected, recordsetcolumns)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_execute (procedure, callback) {
|
||||
super._execute(procedure, err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
const params = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 2) {
|
||||
params.push(`@${param.name} ${declare(param.type, param)}`)
|
||||
}
|
||||
}
|
||||
|
||||
// set output params w/ values
|
||||
const sets = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 2 && param.value) {
|
||||
sets.push(`set @${param.name}=?`)
|
||||
}
|
||||
}
|
||||
|
||||
let cmd = `declare ${['@___return___ int'].concat(params).join(', ')};${sets.join(';')};`
|
||||
cmd += `exec @___return___ = ${procedure} `
|
||||
|
||||
const spp = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
|
||||
if (param.io === 2) {
|
||||
// output parameter
|
||||
spp.push(`@${param.name}=@${param.name} output`)
|
||||
} else {
|
||||
// input parameter
|
||||
spp.push(`@${param.name}=?`)
|
||||
}
|
||||
}
|
||||
|
||||
const params2 = []
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 2) {
|
||||
params2.push(`@${param.name} as '${param.name}'`)
|
||||
}
|
||||
}
|
||||
|
||||
cmd += `${spp.join(', ')};`
|
||||
cmd += `select ${['@___return___ as \'___return___\''].concat(params2).join(', ')};`
|
||||
|
||||
this._nested = true
|
||||
|
||||
this._query(cmd, (err, recordsets, output, rowsAffected, recordsetcolumns) => {
|
||||
this._nested = false
|
||||
|
||||
if (err) return callback(err)
|
||||
|
||||
let last, returnValue
|
||||
if (this.stream) {
|
||||
last = recordsets
|
||||
} else {
|
||||
last = recordsets.pop()
|
||||
if (last) last = last[0]
|
||||
}
|
||||
const lastColumns = recordsetcolumns.pop()
|
||||
|
||||
if (last && this.arrayRowMode && lastColumns) {
|
||||
let returnColumnIdx = null
|
||||
const parametersNameToLastIdxDict = {}
|
||||
for (let i = 0; i < lastColumns.length; i++) {
|
||||
if (lastColumns[i].name === '___return___') {
|
||||
returnColumnIdx = i
|
||||
} else if (objectHasProperty(this.parameters, lastColumns[i].name)) {
|
||||
parametersNameToLastIdxDict[lastColumns[i].name] = i
|
||||
}
|
||||
}
|
||||
if (returnColumnIdx != null) {
|
||||
returnValue = last[returnColumnIdx]
|
||||
}
|
||||
for (const name in parametersNameToLastIdxDict) {
|
||||
if (!objectHasProperty(parametersNameToLastIdxDict, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 2) {
|
||||
output[param.name] = last[parametersNameToLastIdxDict[name]]
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (last && (last.___return___ != null)) {
|
||||
returnValue = last.___return___
|
||||
|
||||
for (const name in this.parameters) {
|
||||
if (!objectHasProperty(this.parameters, name)) {
|
||||
continue
|
||||
}
|
||||
const param = this.parameters[name]
|
||||
if (param.io === 2) {
|
||||
output[param.name] = last[param.name]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.stream) {
|
||||
callback(null, null, output, returnValue, rowsAffected, recordsetcolumns)
|
||||
} else {
|
||||
callback(null, recordsets, output, returnValue, rowsAffected, recordsetcolumns)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_pause () {
|
||||
super._pause()
|
||||
if (this._currentRequest) {
|
||||
this._currentRequest.pauseQuery()
|
||||
}
|
||||
}
|
||||
|
||||
_resume () {
|
||||
super._resume()
|
||||
if (this._currentRequest) {
|
||||
this._currentRequest.resumeQuery()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Request
|
||||
98
node_modules/mssql/lib/msnodesqlv8/transaction.js
generated
vendored
Normal file
98
node_modules/mssql/lib/msnodesqlv8/transaction.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('mssql:msv8')
|
||||
const BaseTransaction = require('../base/transaction')
|
||||
const { IDS } = require('../utils')
|
||||
const Request = require('./request')
|
||||
const ISOLATION_LEVEL = require('../isolationlevel')
|
||||
const TransactionError = require('../error/transaction-error')
|
||||
|
||||
const isolationLevelDeclaration = function (type) {
|
||||
switch (type) {
|
||||
case ISOLATION_LEVEL.READ_UNCOMMITTED: return 'READ UNCOMMITTED'
|
||||
case ISOLATION_LEVEL.READ_COMMITTED: return 'READ COMMITTED'
|
||||
case ISOLATION_LEVEL.REPEATABLE_READ: return 'REPEATABLE READ'
|
||||
case ISOLATION_LEVEL.SERIALIZABLE: return 'SERIALIZABLE'
|
||||
case ISOLATION_LEVEL.SNAPSHOT: return 'SNAPSHOT'
|
||||
default: throw new TransactionError('Invalid isolation level.')
|
||||
}
|
||||
}
|
||||
|
||||
class Transaction extends BaseTransaction {
|
||||
_begin (isolationLevel, callback) {
|
||||
super._begin(isolationLevel, err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
debug('transaction(%d): begin', IDS.get(this))
|
||||
|
||||
this.parent.acquire(this, (err, connection, config) => {
|
||||
if (err) return callback(err)
|
||||
|
||||
this._acquiredConnection = connection
|
||||
this._acquiredConfig = config
|
||||
|
||||
const req = new Request(this)
|
||||
req.stream = false
|
||||
req.query(`set transaction isolation level ${isolationLevelDeclaration(this.isolationLevel)};begin tran;`, err => {
|
||||
if (err) {
|
||||
this.parent.release(this._acquiredConnection)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
|
||||
return callback(err)
|
||||
}
|
||||
|
||||
debug('transaction(%d): begun', IDS.get(this))
|
||||
|
||||
callback(null)
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_commit (callback) {
|
||||
super._commit(err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
debug('transaction(%d): commit', IDS.get(this))
|
||||
|
||||
const req = new Request(this)
|
||||
req.stream = false
|
||||
req.query('commit tran', err => {
|
||||
if (err) err = new TransactionError(err)
|
||||
|
||||
this.parent.release(this._acquiredConnection)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
|
||||
if (!err) debug('transaction(%d): commited', IDS.get(this))
|
||||
|
||||
callback(null)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_rollback (callback) {
|
||||
super._commit(err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
debug('transaction(%d): rollback', IDS.get(this))
|
||||
|
||||
const req = new Request(this)
|
||||
req.stream = false
|
||||
req.query('rollback tran', err => {
|
||||
if (err) err = new TransactionError(err)
|
||||
|
||||
this.parent.release(this._acquiredConnection)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
|
||||
if (!err) debug('transaction(%d): rolled back', IDS.get(this))
|
||||
|
||||
callback(null)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Transaction
|
||||
120
node_modules/mssql/lib/shared.js
generated
vendored
Normal file
120
node_modules/mssql/lib/shared.js
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
'use strict'
|
||||
|
||||
const TYPES = require('./datatypes').TYPES
|
||||
const Table = require('./table')
|
||||
|
||||
let PromiseLibrary = Promise
|
||||
const driver = {}
|
||||
const map = []
|
||||
|
||||
/**
|
||||
* Register you own type map.
|
||||
*
|
||||
* @path module.exports.map
|
||||
* @param {*} jstype JS data type.
|
||||
* @param {*} sqltype SQL data type.
|
||||
*/
|
||||
|
||||
map.register = function (jstype, sqltype) {
|
||||
for (let index = 0; index < this.length; index++) {
|
||||
const item = this[index]
|
||||
if (item.js === jstype) {
|
||||
this.splice(index, 1)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
this.push({
|
||||
js: jstype,
|
||||
sql: sqltype
|
||||
})
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
map.register(String, TYPES.NVarChar)
|
||||
map.register(Number, TYPES.Int)
|
||||
map.register(Boolean, TYPES.Bit)
|
||||
map.register(Date, TYPES.DateTime)
|
||||
map.register(Buffer, TYPES.VarBinary)
|
||||
map.register(Table, TYPES.TVP)
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
const getTypeByValue = function (value) {
|
||||
if ((value === null) || (value === undefined)) { return TYPES.NVarChar }
|
||||
|
||||
switch (typeof value) {
|
||||
case 'string':
|
||||
for (const item of Array.from(map)) {
|
||||
if (item.js === String) {
|
||||
return item.sql
|
||||
}
|
||||
}
|
||||
|
||||
return TYPES.NVarChar
|
||||
|
||||
case 'number':
|
||||
if (value % 1 === 0) {
|
||||
if (value < -2147483648 || value > 2147483647) {
|
||||
return TYPES.BigInt
|
||||
} else {
|
||||
return TYPES.Int
|
||||
}
|
||||
} else {
|
||||
return TYPES.Float
|
||||
}
|
||||
|
||||
case 'bigint':
|
||||
if (value < -2147483648n || value > 2147483647n) {
|
||||
return TYPES.BigInt
|
||||
} else {
|
||||
return TYPES.Int
|
||||
}
|
||||
|
||||
case 'boolean':
|
||||
for (const item of Array.from(map)) {
|
||||
if (item.js === Boolean) {
|
||||
return item.sql
|
||||
}
|
||||
}
|
||||
|
||||
return TYPES.Bit
|
||||
|
||||
case 'object':
|
||||
for (const item of Array.from(map)) {
|
||||
if (value instanceof item.js) {
|
||||
return item.sql
|
||||
}
|
||||
}
|
||||
|
||||
return TYPES.NVarChar
|
||||
|
||||
default:
|
||||
return TYPES.NVarChar
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
driver,
|
||||
getTypeByValue,
|
||||
map
|
||||
}
|
||||
|
||||
Object.defineProperty(module.exports, 'Promise', {
|
||||
get: () => {
|
||||
return PromiseLibrary
|
||||
},
|
||||
set: (value) => {
|
||||
PromiseLibrary = value
|
||||
}
|
||||
})
|
||||
|
||||
Object.defineProperty(module.exports, 'valueHandler', {
|
||||
enumerable: true,
|
||||
value: new Map(),
|
||||
writable: false,
|
||||
configurable: false
|
||||
})
|
||||
220
node_modules/mssql/lib/table.js
generated
vendored
Normal file
220
node_modules/mssql/lib/table.js
generated
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
'use strict'
|
||||
|
||||
const TYPES = require('./datatypes').TYPES
|
||||
const declareType = require('./datatypes').declare
|
||||
const objectHasProperty = require('./utils').objectHasProperty
|
||||
|
||||
const MAX = 65535 // (1 << 16) - 1
|
||||
const JSON_COLUMN_ID = 'JSON_F52E2B61-18A1-11d1-B105-00805F49916B'
|
||||
|
||||
function Table (name) {
|
||||
if (name) {
|
||||
const parsed = Table.parseName(name)
|
||||
this.name = parsed.name
|
||||
this.schema = parsed.schema
|
||||
this.database = parsed.database
|
||||
this.path = (this.database ? `[${this.database}].` : '') + (this.schema ? `[${this.schema}].` : '') + `[${this.name}]`
|
||||
this.temporary = this.name.charAt(0) === '#'
|
||||
}
|
||||
|
||||
this.columns = []
|
||||
this.rows = []
|
||||
|
||||
Object.defineProperty(this.columns, 'add', {
|
||||
value (name, column, options) {
|
||||
if (column == null) {
|
||||
throw new Error('Column data type is not defined.')
|
||||
}
|
||||
if (column instanceof Function) {
|
||||
column = column()
|
||||
}
|
||||
|
||||
options = options || {}
|
||||
column.name = name;
|
||||
|
||||
['nullable', 'primary', 'identity', 'readOnly', 'length'].forEach(prop => {
|
||||
if (objectHasProperty(options, prop)) {
|
||||
column[prop] = options[prop]
|
||||
}
|
||||
})
|
||||
|
||||
return this.push(column)
|
||||
}
|
||||
})
|
||||
|
||||
Object.defineProperty(this.rows, 'add', {
|
||||
value () {
|
||||
return this.push(Array.prototype.slice.call(arguments))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Object.defineProperty(this.rows, 'clear', {
|
||||
value () {
|
||||
return this.splice(0, this.length)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
@private
|
||||
*/
|
||||
|
||||
Table.prototype._makeBulk = function _makeBulk () {
|
||||
for (let i = 0; i < this.columns.length; i++) {
|
||||
const col = this.columns[i]
|
||||
switch (col.type) {
|
||||
case TYPES.Date:
|
||||
case TYPES.DateTime:
|
||||
case TYPES.DateTime2:
|
||||
for (let j = 0; j < this.rows.length; j++) {
|
||||
const dateValue = this.rows[j][i]
|
||||
if (typeof dateValue === 'string' || typeof dateValue === 'number') {
|
||||
const date = new Date(dateValue)
|
||||
if (isNaN(date.getDate())) {
|
||||
throw new TypeError('Invalid date value passed to bulk rows')
|
||||
}
|
||||
this.rows[j][i] = date
|
||||
}
|
||||
}
|
||||
break
|
||||
|
||||
case TYPES.Xml:
|
||||
col.type = TYPES.NVarChar(MAX).type
|
||||
break
|
||||
|
||||
case TYPES.UDT:
|
||||
case TYPES.Geography:
|
||||
case TYPES.Geometry:
|
||||
col.type = TYPES.VarBinary(MAX).type
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Table.prototype.declare = function declare () {
|
||||
const pkey = this.columns.filter(col => col.primary === true).map(col => `[${col.name}]`)
|
||||
const cols = this.columns.map(col => {
|
||||
const def = [`[${col.name}] ${declareType(col.type, col)}`]
|
||||
|
||||
if (col.nullable === true) {
|
||||
def.push('null')
|
||||
} else if (col.nullable === false) {
|
||||
def.push('not null')
|
||||
}
|
||||
|
||||
if (col.primary === true && pkey.length === 1) {
|
||||
def.push('primary key')
|
||||
}
|
||||
|
||||
return def.join(' ')
|
||||
})
|
||||
|
||||
const constraint = pkey.length > 1 ? `, constraint [PK_${this.temporary ? this.name.substr(1) : this.name}] primary key (${pkey.join(', ')})` : ''
|
||||
return `create table ${this.path} (${cols.join(', ')}${constraint})`
|
||||
}
|
||||
|
||||
Table.fromRecordset = function fromRecordset (recordset, name) {
|
||||
const t = new this(name)
|
||||
|
||||
for (const colName in recordset.columns) {
|
||||
if (objectHasProperty(recordset.columns, colName)) {
|
||||
const col = recordset.columns[colName]
|
||||
|
||||
t.columns.add(colName, {
|
||||
type: col.type,
|
||||
length: col.length,
|
||||
scale: col.scale,
|
||||
precision: col.precision
|
||||
}, {
|
||||
nullable: col.nullable,
|
||||
identity: col.identity,
|
||||
readOnly: col.readOnly
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if (t.columns.length === 1 && t.columns[0].name === JSON_COLUMN_ID) {
|
||||
for (let i = 0; i < recordset.length; i++) {
|
||||
t.rows.add(JSON.stringify(recordset[i]))
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < recordset.length; i++) {
|
||||
t.rows.add.apply(t.rows, t.columns.map(col => recordset[i][col.name]))
|
||||
}
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
Table.parseName = function parseName (name) {
|
||||
const length = name.length
|
||||
let cursor = -1
|
||||
let buffer = ''
|
||||
let escaped = false
|
||||
const path = []
|
||||
|
||||
while (++cursor < length) {
|
||||
const char = name.charAt(cursor)
|
||||
if (char === '[') {
|
||||
if (escaped) {
|
||||
buffer += char
|
||||
} else {
|
||||
escaped = true
|
||||
}
|
||||
} else if (char === ']') {
|
||||
if (escaped) {
|
||||
escaped = false
|
||||
} else {
|
||||
throw new Error('Invalid table name.')
|
||||
}
|
||||
} else if (char === '.') {
|
||||
if (escaped) {
|
||||
buffer += char
|
||||
} else {
|
||||
path.push(buffer)
|
||||
buffer = ''
|
||||
}
|
||||
} else {
|
||||
buffer += char
|
||||
}
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
path.push(buffer)
|
||||
}
|
||||
|
||||
switch (path.length) {
|
||||
case 1:
|
||||
return {
|
||||
name: path[0],
|
||||
schema: null,
|
||||
database: null
|
||||
}
|
||||
|
||||
case 2:
|
||||
return {
|
||||
name: path[1],
|
||||
schema: path[0],
|
||||
database: null
|
||||
}
|
||||
|
||||
case 3:
|
||||
return {
|
||||
name: path[2],
|
||||
schema: path[1],
|
||||
database: path[0]
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error('Invalid table name.')
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Table
|
||||
154
node_modules/mssql/lib/tedious/connection-pool.js
generated
vendored
Normal file
154
node_modules/mssql/lib/tedious/connection-pool.js
generated
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
'use strict'
|
||||
|
||||
const tds = require('tedious')
|
||||
const debug = require('debug')('mssql:tedi')
|
||||
const BaseConnectionPool = require('../base/connection-pool')
|
||||
const { IDS } = require('../utils')
|
||||
const shared = require('../shared')
|
||||
const ConnectionError = require('../error/connection-error')
|
||||
|
||||
class ConnectionPool extends BaseConnectionPool {
|
||||
_config () {
|
||||
const cfg = {
|
||||
server: this.config.server,
|
||||
options: Object.assign({
|
||||
encrypt: typeof this.config.encrypt === 'boolean' ? this.config.encrypt : true,
|
||||
trustServerCertificate: typeof this.config.trustServerCertificate === 'boolean' ? this.config.trustServerCertificate : false
|
||||
}, this.config.options),
|
||||
authentication: Object.assign({
|
||||
type: this.config.domain !== undefined ? 'ntlm' : this.config.authentication_type !== undefined ? this.config.authentication_type : 'default',
|
||||
options: Object.entries({
|
||||
userName: this.config.user,
|
||||
password: this.config.password,
|
||||
domain: this.config.domain,
|
||||
clientId: this.config.clientId,
|
||||
clientSecret: this.config.clientSecret,
|
||||
tenantId: this.config.tenantId,
|
||||
token: this.config.token,
|
||||
msiEndpoint: this.config.msiEndpoint,
|
||||
msiSecret: this.config.msiSecret
|
||||
}).reduce((acc, [key, val]) => {
|
||||
if (typeof val !== 'undefined') {
|
||||
return { ...acc, [key]: val }
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
}, this.config.authentication)
|
||||
}
|
||||
|
||||
cfg.options.database = cfg.options.database || this.config.database
|
||||
cfg.options.port = cfg.options.port || this.config.port
|
||||
cfg.options.connectTimeout = cfg.options.connectTimeout ?? this.config.connectionTimeout ?? this.config.timeout ?? 15000
|
||||
cfg.options.requestTimeout = cfg.options.requestTimeout ?? this.config.requestTimeout ?? this.config.timeout ?? 15000
|
||||
cfg.options.tdsVersion = cfg.options.tdsVersion || '7_4'
|
||||
cfg.options.rowCollectionOnDone = cfg.options.rowCollectionOnDone || false
|
||||
cfg.options.rowCollectionOnRequestCompletion = cfg.options.rowCollectionOnRequestCompletion || false
|
||||
cfg.options.useColumnNames = cfg.options.useColumnNames || false
|
||||
cfg.options.appName = cfg.options.appName || 'node-mssql'
|
||||
|
||||
// tedious always connect via tcp when port is specified
|
||||
if (cfg.options.instanceName) delete cfg.options.port
|
||||
|
||||
if (isNaN(cfg.options.requestTimeout)) cfg.options.requestTimeout = 15000
|
||||
if (cfg.options.requestTimeout === Infinity || cfg.options.requestTimeout < 0) cfg.options.requestTimeout = 0
|
||||
|
||||
if (!cfg.options.debug && this.config.debug) {
|
||||
cfg.options.debug = {
|
||||
packet: true,
|
||||
token: true,
|
||||
data: true,
|
||||
payload: true
|
||||
}
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
_poolCreate () {
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
const resolveOnce = (v) => {
|
||||
resolve(v)
|
||||
resolve = reject = () => {}
|
||||
}
|
||||
const rejectOnce = (e) => {
|
||||
reject(e)
|
||||
resolve = reject = () => {}
|
||||
}
|
||||
let tedious
|
||||
try {
|
||||
tedious = new tds.Connection(this._config())
|
||||
} catch (err) {
|
||||
rejectOnce(err)
|
||||
return
|
||||
}
|
||||
tedious.connect(err => {
|
||||
if (err) {
|
||||
err = new ConnectionError(err)
|
||||
return rejectOnce(err)
|
||||
}
|
||||
|
||||
debug('connection(%d): established', IDS.get(tedious))
|
||||
this.collation = tedious.databaseCollation
|
||||
resolveOnce(tedious)
|
||||
})
|
||||
IDS.add(tedious, 'Connection')
|
||||
debug('pool(%d): connection #%d created', IDS.get(this), IDS.get(tedious))
|
||||
debug('connection(%d): establishing', IDS.get(tedious))
|
||||
|
||||
tedious.on('end', () => {
|
||||
const err = new ConnectionError('The connection ended without ever completing the connection')
|
||||
rejectOnce(err)
|
||||
})
|
||||
tedious.on('error', err => {
|
||||
if (err.code === 'ESOCKET') {
|
||||
tedious.hasError = true
|
||||
} else {
|
||||
this.emit('error', err)
|
||||
}
|
||||
rejectOnce(err)
|
||||
})
|
||||
|
||||
if (this.config.debug) {
|
||||
tedious.on('debug', this.emit.bind(this, 'debug', tedious))
|
||||
}
|
||||
if (typeof this.config.beforeConnect === 'function') {
|
||||
this.config.beforeConnect(tedious)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
_poolValidate (tedious) {
|
||||
if (tedious && !tedious.closed && !tedious.hasError) {
|
||||
return !this.config.validateConnection || new shared.Promise((resolve) => {
|
||||
const req = new tds.Request('SELECT 1;', (err) => {
|
||||
resolve(!err)
|
||||
})
|
||||
tedious.execSql(req)
|
||||
})
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
_poolDestroy (tedious) {
|
||||
return new shared.Promise((resolve, reject) => {
|
||||
if (!tedious) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
debug('connection(%d): destroying', IDS.get(tedious))
|
||||
|
||||
if (tedious.closed) {
|
||||
debug('connection(%d): already closed', IDS.get(tedious))
|
||||
resolve()
|
||||
} else {
|
||||
tedious.once('end', () => {
|
||||
debug('connection(%d): destroyed', IDS.get(tedious))
|
||||
resolve()
|
||||
})
|
||||
|
||||
tedious.close()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ConnectionPool
|
||||
35
node_modules/mssql/lib/tedious/index.js
generated
vendored
Normal file
35
node_modules/mssql/lib/tedious/index.js
generated
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
'use strict'
|
||||
|
||||
const base = require('../base')
|
||||
const ConnectionPool = require('./connection-pool')
|
||||
const Transaction = require('./transaction')
|
||||
const Request = require('./request')
|
||||
|
||||
module.exports = Object.assign({
|
||||
ConnectionPool,
|
||||
Transaction,
|
||||
Request,
|
||||
PreparedStatement: base.PreparedStatement
|
||||
}, base.exports)
|
||||
|
||||
Object.defineProperty(module.exports, 'Promise', {
|
||||
enumerable: true,
|
||||
get: () => {
|
||||
return base.Promise
|
||||
},
|
||||
set: (value) => {
|
||||
base.Promise = value
|
||||
}
|
||||
})
|
||||
|
||||
Object.defineProperty(module.exports, 'valueHandler', {
|
||||
enumerable: true,
|
||||
value: base.valueHandler,
|
||||
writable: false,
|
||||
configurable: false
|
||||
})
|
||||
|
||||
base.driver.name = 'tedious'
|
||||
base.driver.ConnectionPool = ConnectionPool
|
||||
base.driver.Transaction = Transaction
|
||||
base.driver.Request = Request
|
||||
1002
node_modules/mssql/lib/tedious/request.js
generated
vendored
Normal file
1002
node_modules/mssql/lib/tedious/request.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
98
node_modules/mssql/lib/tedious/transaction.js
generated
vendored
Normal file
98
node_modules/mssql/lib/tedious/transaction.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
'use strict'
|
||||
|
||||
const debug = require('debug')('mssql:tedi')
|
||||
const BaseTransaction = require('../base/transaction')
|
||||
const { IDS } = require('../utils')
|
||||
const TransactionError = require('../error/transaction-error')
|
||||
|
||||
class Transaction extends BaseTransaction {
|
||||
constructor (parent) {
|
||||
super(parent)
|
||||
|
||||
this._abort = () => {
|
||||
if (!this._rollbackRequested) {
|
||||
// transaction interrupted because of XACT_ABORT
|
||||
|
||||
const pc = this._acquiredConnection
|
||||
|
||||
// defer releasing so connection can switch from SentClientRequest to LoggedIn state
|
||||
setImmediate(this.parent.release.bind(this.parent), pc)
|
||||
|
||||
this._acquiredConnection.removeListener('rollbackTransaction', this._abort)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
this._aborted = true
|
||||
|
||||
this.emit('rollback', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_begin (isolationLevel, callback) {
|
||||
super._begin(isolationLevel, err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
debug('transaction(%d): begin', IDS.get(this))
|
||||
|
||||
this.parent.acquire(this, (err, connection, config) => {
|
||||
if (err) return callback(err)
|
||||
|
||||
this._acquiredConnection = connection
|
||||
this._acquiredConnection.on('rollbackTransaction', this._abort)
|
||||
this._acquiredConfig = config
|
||||
|
||||
connection.beginTransaction(err => {
|
||||
if (err) err = new TransactionError(err)
|
||||
|
||||
debug('transaction(%d): begun', IDS.get(this))
|
||||
|
||||
callback(err)
|
||||
}, this.name, this.isolationLevel)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_commit (callback) {
|
||||
super._commit(err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
debug('transaction(%d): commit', IDS.get(this))
|
||||
|
||||
this._acquiredConnection.commitTransaction(err => {
|
||||
if (err) err = new TransactionError(err)
|
||||
|
||||
this._acquiredConnection.removeListener('rollbackTransaction', this._abort)
|
||||
this.parent.release(this._acquiredConnection)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
|
||||
if (!err) debug('transaction(%d): commited', IDS.get(this))
|
||||
|
||||
callback(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
_rollback (callback) {
|
||||
super._rollback(err => {
|
||||
if (err) return callback(err)
|
||||
|
||||
debug('transaction(%d): rollback', IDS.get(this))
|
||||
|
||||
this._acquiredConnection.rollbackTransaction(err => {
|
||||
if (err) err = new TransactionError(err)
|
||||
|
||||
this._acquiredConnection.removeListener('rollbackTransaction', this._abort)
|
||||
this.parent.release(this._acquiredConnection)
|
||||
this._acquiredConnection = null
|
||||
this._acquiredConfig = null
|
||||
|
||||
if (!err) debug('transaction(%d): rolled back', IDS.get(this))
|
||||
|
||||
callback(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Transaction
|
||||
320
node_modules/mssql/lib/udt.js
generated
vendored
Normal file
320
node_modules/mssql/lib/udt.js
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
'use strict'
|
||||
|
||||
/* const FIGURE = {
|
||||
INTERIOR_RING: 0x00,
|
||||
STROKE: 0x01,
|
||||
EXTERIOR_RING: 0x02
|
||||
};
|
||||
|
||||
const FIGURE_V2 = {
|
||||
POINT: 0x00,
|
||||
LINE: 0x01,
|
||||
ARC: 0x02,
|
||||
COMPOSITE_CURVE: 0x03
|
||||
};
|
||||
|
||||
const SHAPE = {
|
||||
POINT: 0x01,
|
||||
LINESTRING: 0x02,
|
||||
POLYGON: 0x03,
|
||||
MULTIPOINT: 0x04,
|
||||
MULTILINESTRING: 0x05,
|
||||
MULTIPOLYGON: 0x06,
|
||||
GEOMETRY_COLLECTION: 0x07
|
||||
};
|
||||
|
||||
const SHAPE_V2 = {
|
||||
POINT: 0x01,
|
||||
LINESTRING: 0x02,
|
||||
POLYGON: 0x03,
|
||||
MULTIPOINT: 0x04,
|
||||
MULTILINESTRING: 0x05,
|
||||
MULTIPOLYGON: 0x06,
|
||||
GEOMETRY_COLLECTION: 0x07,
|
||||
CIRCULAR_STRING: 0x08,
|
||||
COMPOUND_CURVE: 0x09,
|
||||
CURVE_POLYGON: 0x0A,
|
||||
FULL_GLOBE: 0x0B
|
||||
};
|
||||
|
||||
const SEGMENT = {
|
||||
LINE: 0x00,
|
||||
ARC: 0x01,
|
||||
FIRST_LINE: 0x02,
|
||||
FIRST_ARC: 0x03
|
||||
}; */
|
||||
|
||||
class Point {
|
||||
constructor () {
|
||||
this.x = 0
|
||||
this.y = 0
|
||||
this.z = null
|
||||
this.m = null
|
||||
}
|
||||
}
|
||||
|
||||
const parsePoints = (buffer, count, isGeometryPoint) => {
|
||||
// s2.1.5 + s2.1.6
|
||||
// The key distinction for parsing is that a GEOGRAPHY POINT is ordered Lat (y) then Long (x),
|
||||
// while a GEOMETRY POINT is ordered x then y.
|
||||
// Further, there are additional range constraints on GEOGRAPHY POINT that are useful for testing that the coordinate order has not been flipped, such as that Lat must be in the range [-90, +90].
|
||||
|
||||
const points = []
|
||||
if (count < 1) {
|
||||
return points
|
||||
}
|
||||
|
||||
if (isGeometryPoint) {
|
||||
// GEOMETRY POINT (s2.1.6): x then y.
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const point = new Point()
|
||||
points.push(point)
|
||||
point.x = buffer.readDoubleLE(buffer.position)
|
||||
point.y = buffer.readDoubleLE(buffer.position + 8)
|
||||
buffer.position += 16
|
||||
}
|
||||
} else {
|
||||
// GEOGRAPHY POINT (s2.1.5): Lat (y) then Long (x).
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const point = new Point()
|
||||
points.push(point)
|
||||
point.lat = buffer.readDoubleLE(buffer.position)
|
||||
point.lng = buffer.readDoubleLE(buffer.position + 8)
|
||||
|
||||
// For backwards compatibility, preserve the coordinate inversion in x and y.
|
||||
// A future breaking change likely eliminate x and y for geography points in favor of just the lat and lng fields, as they've proven marvelously confusing.
|
||||
// See discussion at: https://github.com/tediousjs/node-mssql/pull/1282#discussion_r677769531
|
||||
point.x = point.lat
|
||||
point.y = point.lng
|
||||
|
||||
buffer.position += 16
|
||||
}
|
||||
}
|
||||
|
||||
return points
|
||||
}
|
||||
|
||||
const parseZ = (buffer, points) => {
|
||||
// s2.1.1 + s.2.1.2
|
||||
|
||||
if (points < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
points.forEach(point => {
|
||||
point.z = buffer.readDoubleLE(buffer.position)
|
||||
buffer.position += 8
|
||||
})
|
||||
}
|
||||
|
||||
const parseM = (buffer, points) => {
|
||||
// s2.1.1 + s.2.1.2
|
||||
|
||||
if (points < 1) {
|
||||
return
|
||||
}
|
||||
|
||||
points.forEach(point => {
|
||||
point.m = buffer.readDoubleLE(buffer.position)
|
||||
buffer.position += 8
|
||||
})
|
||||
}
|
||||
|
||||
const parseFigures = (buffer, count, properties) => {
|
||||
// s2.1.3
|
||||
|
||||
const figures = []
|
||||
if (count < 1) {
|
||||
return figures
|
||||
}
|
||||
|
||||
if (properties.P) {
|
||||
figures.push({
|
||||
attribute: 0x01,
|
||||
pointOffset: 0
|
||||
})
|
||||
} else if (properties.L) {
|
||||
figures.push({
|
||||
attribute: 0x01,
|
||||
pointOffset: 0
|
||||
})
|
||||
} else {
|
||||
for (let i = 1; i <= count; i++) {
|
||||
figures.push({
|
||||
attribute: buffer.readUInt8(buffer.position),
|
||||
pointOffset: buffer.readInt32LE(buffer.position + 1)
|
||||
})
|
||||
|
||||
buffer.position += 5
|
||||
}
|
||||
}
|
||||
|
||||
return figures
|
||||
}
|
||||
|
||||
const parseShapes = (buffer, count, properties) => {
|
||||
// s2.1.4
|
||||
|
||||
const shapes = []
|
||||
if (count < 1) {
|
||||
return shapes
|
||||
}
|
||||
|
||||
if (properties.P) {
|
||||
shapes.push({
|
||||
parentOffset: -1,
|
||||
figureOffset: 0,
|
||||
type: 0x01
|
||||
})
|
||||
} else if (properties.L) {
|
||||
shapes.push({
|
||||
parentOffset: -1,
|
||||
figureOffset: 0,
|
||||
type: 0x02
|
||||
})
|
||||
} else {
|
||||
for (let i = 1; i <= count; i++) {
|
||||
shapes.push({
|
||||
parentOffset: buffer.readInt32LE(buffer.position),
|
||||
figureOffset: buffer.readInt32LE(buffer.position + 4),
|
||||
type: buffer.readUInt8(buffer.position + 8)
|
||||
})
|
||||
|
||||
buffer.position += 9
|
||||
}
|
||||
}
|
||||
|
||||
return shapes
|
||||
}
|
||||
|
||||
const parseSegments = (buffer, count) => {
|
||||
// s2.1.7
|
||||
|
||||
const segments = []
|
||||
if (count < 1) {
|
||||
return segments
|
||||
}
|
||||
|
||||
for (let i = 1; i <= count; i++) {
|
||||
segments.push({ type: buffer.readUInt8(buffer.position) })
|
||||
|
||||
buffer.position++
|
||||
}
|
||||
|
||||
return segments
|
||||
}
|
||||
|
||||
const parseGeography = (buffer, isUsingGeometryPoints) => {
|
||||
// s2.1.1 + s.2.1.2
|
||||
|
||||
const srid = buffer.readInt32LE(0)
|
||||
if (srid === -1) {
|
||||
return null
|
||||
}
|
||||
|
||||
const value = {
|
||||
srid,
|
||||
version: buffer.readUInt8(4)
|
||||
}
|
||||
|
||||
const flags = buffer.readUInt8(5)
|
||||
buffer.position = 6
|
||||
|
||||
// console.log("srid", srid)
|
||||
// console.log("version", version)
|
||||
|
||||
const properties = {
|
||||
Z: (flags & (1 << 0)) > 0,
|
||||
M: (flags & (1 << 1)) > 0,
|
||||
V: (flags & (1 << 2)) > 0,
|
||||
P: (flags & (1 << 3)) > 0,
|
||||
L: (flags & (1 << 4)) > 0
|
||||
}
|
||||
|
||||
if (value.version === 2) {
|
||||
properties.H = (flags & (1 << 3)) > 0
|
||||
}
|
||||
|
||||
// console.log("properties", properties);
|
||||
|
||||
let numberOfPoints
|
||||
if (properties.P) {
|
||||
numberOfPoints = 1
|
||||
} else if (properties.L) {
|
||||
numberOfPoints = 2
|
||||
} else {
|
||||
numberOfPoints = buffer.readUInt32LE(buffer.position)
|
||||
buffer.position += 4
|
||||
}
|
||||
|
||||
// console.log("numberOfPoints", numberOfPoints)
|
||||
|
||||
value.points = parsePoints(buffer, numberOfPoints, isUsingGeometryPoints)
|
||||
|
||||
if (properties.Z) {
|
||||
parseZ(buffer, value.points)
|
||||
}
|
||||
|
||||
if (properties.M) {
|
||||
parseM(buffer, value.points)
|
||||
}
|
||||
|
||||
// console.log("points", points)
|
||||
|
||||
let numberOfFigures
|
||||
if (properties.P) {
|
||||
numberOfFigures = 1
|
||||
} else if (properties.L) {
|
||||
numberOfFigures = 1
|
||||
} else {
|
||||
numberOfFigures = buffer.readUInt32LE(buffer.position)
|
||||
buffer.position += 4
|
||||
}
|
||||
|
||||
// console.log("numberOfFigures", numberOfFigures)
|
||||
|
||||
value.figures = parseFigures(buffer, numberOfFigures, properties)
|
||||
|
||||
// console.log("figures", figures)
|
||||
|
||||
let numberOfShapes
|
||||
if (properties.P) {
|
||||
numberOfShapes = 1
|
||||
} else if (properties.L) {
|
||||
numberOfShapes = 1
|
||||
} else {
|
||||
numberOfShapes = buffer.readUInt32LE(buffer.position)
|
||||
buffer.position += 4
|
||||
}
|
||||
|
||||
// console.log("numberOfShapes", numberOfShapes)
|
||||
|
||||
value.shapes = parseShapes(buffer, numberOfShapes, properties)
|
||||
|
||||
// console.log( "shapes", shapes)
|
||||
|
||||
if (value.version === 2 && buffer.position < buffer.length) {
|
||||
const numberOfSegments = buffer.readUInt32LE(buffer.position)
|
||||
buffer.position += 4
|
||||
|
||||
// console.log("numberOfSegments", numberOfSegments)
|
||||
|
||||
value.segments = parseSegments(buffer, numberOfSegments)
|
||||
|
||||
// console.log("segments", segments)
|
||||
} else {
|
||||
value.segments = []
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
module.exports.PARSERS = {
|
||||
geography (buffer) {
|
||||
return parseGeography(buffer, /* isUsingGeometryPoints: */false)
|
||||
},
|
||||
|
||||
geometry (buffer) {
|
||||
return parseGeography(buffer, /* isUsingGeometryPoints: */true)
|
||||
}
|
||||
}
|
||||
20
node_modules/mssql/lib/utils.js
generated
vendored
Normal file
20
node_modules/mssql/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
const IDS = new WeakMap()
|
||||
const INCREMENT = {
|
||||
Connection: 1,
|
||||
ConnectionPool: 1,
|
||||
Request: 1,
|
||||
Transaction: 1,
|
||||
PreparedStatement: 1
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
objectHasProperty: (object, property) => Object.prototype.hasOwnProperty.call(object, property),
|
||||
INCREMENT,
|
||||
IDS: {
|
||||
get: IDS.get.bind(IDS),
|
||||
add: (object, type, id) => {
|
||||
if (id) return IDS.set(object, id)
|
||||
IDS.set(object, INCREMENT[type]++)
|
||||
}
|
||||
}
|
||||
}
|
||||
1
node_modules/mssql/msnodesqlv8.js
generated
vendored
Normal file
1
node_modules/mssql/msnodesqlv8.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('./lib/msnodesqlv8')
|
||||
20
node_modules/mssql/node_modules/debug/LICENSE
generated
vendored
Normal file
20
node_modules/mssql/node_modules/debug/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2018-2021 Josh Junon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
|
||||
and associated documentation files (the 'Software'), to deal in the Software without restriction,
|
||||
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
||||
portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
481
node_modules/mssql/node_modules/debug/README.md
generated
vendored
Normal file
481
node_modules/mssql/node_modules/debug/README.md
generated
vendored
Normal file
@@ -0,0 +1,481 @@
|
||||
# debug
|
||||
[](#backers)
|
||||
[](#sponsors)
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
|
||||
|
||||
A tiny JavaScript debugging utility modelled after Node.js core's debugging
|
||||
technique. Works in Node.js and web browsers.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
$ npm install debug
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
`debug` exposes a function; simply pass this function the name of your module, and it will return a decorated version of `console.error` for you to pass debug statements to. This will allow you to toggle the debug output for different parts of your module as well as the module as a whole.
|
||||
|
||||
Example [_app.js_](./examples/node/app.js):
|
||||
|
||||
```js
|
||||
var debug = require('debug')('http')
|
||||
, http = require('http')
|
||||
, name = 'My App';
|
||||
|
||||
// fake app
|
||||
|
||||
debug('booting %o', name);
|
||||
|
||||
http.createServer(function(req, res){
|
||||
debug(req.method + ' ' + req.url);
|
||||
res.end('hello\n');
|
||||
}).listen(3000, function(){
|
||||
debug('listening');
|
||||
});
|
||||
|
||||
// fake worker of some kind
|
||||
|
||||
require('./worker');
|
||||
```
|
||||
|
||||
Example [_worker.js_](./examples/node/worker.js):
|
||||
|
||||
```js
|
||||
var a = require('debug')('worker:a')
|
||||
, b = require('debug')('worker:b');
|
||||
|
||||
function work() {
|
||||
a('doing lots of uninteresting work');
|
||||
setTimeout(work, Math.random() * 1000);
|
||||
}
|
||||
|
||||
work();
|
||||
|
||||
function workb() {
|
||||
b('doing some work');
|
||||
setTimeout(workb, Math.random() * 2000);
|
||||
}
|
||||
|
||||
workb();
|
||||
```
|
||||
|
||||
The `DEBUG` environment variable is then used to enable these based on space or
|
||||
comma-delimited names.
|
||||
|
||||
Here are some examples:
|
||||
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 04 pm" src="https://user-images.githubusercontent.com/71256/29091703-a6302cdc-7c38-11e7-8304-7c0b3bc600cd.png">
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 38 pm" src="https://user-images.githubusercontent.com/71256/29091700-a62a6888-7c38-11e7-800b-db911291ca2b.png">
|
||||
<img width="647" alt="screen shot 2017-08-08 at 12 53 25 pm" src="https://user-images.githubusercontent.com/71256/29091701-a62ea114-7c38-11e7-826a-2692bedca740.png">
|
||||
|
||||
#### Windows command prompt notes
|
||||
|
||||
##### CMD
|
||||
|
||||
On Windows the environment variable is set using the `set` command.
|
||||
|
||||
```cmd
|
||||
set DEBUG=*,-not_this
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
set DEBUG=* & node app.js
|
||||
```
|
||||
|
||||
##### PowerShell (VS Code default)
|
||||
|
||||
PowerShell uses different syntax to set environment variables.
|
||||
|
||||
```cmd
|
||||
$env:DEBUG = "*,-not_this"
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```cmd
|
||||
$env:DEBUG='app';node app.js
|
||||
```
|
||||
|
||||
Then, run the program to be debugged as usual.
|
||||
|
||||
npm script example:
|
||||
```js
|
||||
"windowsDebug": "@powershell -Command $env:DEBUG='*';node app.js",
|
||||
```
|
||||
|
||||
## Namespace Colors
|
||||
|
||||
Every debug instance has a color generated for it based on its namespace name.
|
||||
This helps when visually parsing the debug output to identify which debug instance
|
||||
a debug line belongs to.
|
||||
|
||||
#### Node.js
|
||||
|
||||
In Node.js, colors are enabled when stderr is a TTY. You also _should_ install
|
||||
the [`supports-color`](https://npmjs.org/supports-color) module alongside debug,
|
||||
otherwise debug will only use a small handful of basic colors.
|
||||
|
||||
<img width="521" src="https://user-images.githubusercontent.com/71256/29092181-47f6a9e6-7c3a-11e7-9a14-1928d8a711cd.png">
|
||||
|
||||
#### Web Browser
|
||||
|
||||
Colors are also enabled on "Web Inspectors" that understand the `%c` formatting
|
||||
option. These are WebKit web inspectors, Firefox ([since version
|
||||
31](https://hacks.mozilla.org/2014/05/editable-box-model-multiple-selection-sublime-text-keys-much-more-firefox-developer-tools-episode-31/))
|
||||
and the Firebug plugin for Firefox (any version).
|
||||
|
||||
<img width="524" src="https://user-images.githubusercontent.com/71256/29092033-b65f9f2e-7c39-11e7-8e32-f6f0d8e865c1.png">
|
||||
|
||||
|
||||
## Millisecond diff
|
||||
|
||||
When actively developing an application it can be useful to see when the time spent between one `debug()` call and the next. Suppose for example you invoke `debug()` before requesting a resource, and after as well, the "+NNNms" will show you how much time was spent between calls.
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091486-fa38524c-7c37-11e7-895f-e7ec8e1039b6.png">
|
||||
|
||||
When stdout is not a TTY, `Date#toISOString()` is used, making it more useful for logging the debug information as shown below:
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/71256/29091956-6bd78372-7c39-11e7-8c55-c948396d6edd.png">
|
||||
|
||||
|
||||
## Conventions
|
||||
|
||||
If you're using this in one or more of your libraries, you _should_ use the name of your library so that developers may toggle debugging as desired without guessing names. If you have more than one debuggers you _should_ prefix them with your library name and use ":" to separate features. For example "bodyParser" from Connect would then be "connect:bodyParser". If you append a "*" to the end of your name, it will always be enabled regardless of the setting of the DEBUG environment variable. You can then use it for normal output as well as debug output.
|
||||
|
||||
## Wildcards
|
||||
|
||||
The `*` character may be used as a wildcard. Suppose for example your library has
|
||||
debuggers named "connect:bodyParser", "connect:compress", "connect:session",
|
||||
instead of listing all three with
|
||||
`DEBUG=connect:bodyParser,connect:compress,connect:session`, you may simply do
|
||||
`DEBUG=connect:*`, or to run everything using this module simply use `DEBUG=*`.
|
||||
|
||||
You can also exclude specific debuggers by prefixing them with a "-" character.
|
||||
For example, `DEBUG=*,-connect:*` would include all debuggers except those
|
||||
starting with "connect:".
|
||||
|
||||
## Environment Variables
|
||||
|
||||
When running through Node.js, you can set a few environment variables that will
|
||||
change the behavior of the debug logging:
|
||||
|
||||
| Name | Purpose |
|
||||
|-----------|-------------------------------------------------|
|
||||
| `DEBUG` | Enables/disables specific debugging namespaces. |
|
||||
| `DEBUG_HIDE_DATE` | Hide date from debug output (non-TTY). |
|
||||
| `DEBUG_COLORS`| Whether or not to use colors in the debug output. |
|
||||
| `DEBUG_DEPTH` | Object inspection depth. |
|
||||
| `DEBUG_SHOW_HIDDEN` | Shows hidden properties on inspected objects. |
|
||||
|
||||
|
||||
__Note:__ The environment variables beginning with `DEBUG_` end up being
|
||||
converted into an Options object that gets used with `%o`/`%O` formatters.
|
||||
See the Node.js documentation for
|
||||
[`util.inspect()`](https://nodejs.org/api/util.html#util_util_inspect_object_options)
|
||||
for the complete list.
|
||||
|
||||
## Formatters
|
||||
|
||||
Debug uses [printf-style](https://wikipedia.org/wiki/Printf_format_string) formatting.
|
||||
Below are the officially supported formatters:
|
||||
|
||||
| Formatter | Representation |
|
||||
|-----------|----------------|
|
||||
| `%O` | Pretty-print an Object on multiple lines. |
|
||||
| `%o` | Pretty-print an Object all on a single line. |
|
||||
| `%s` | String. |
|
||||
| `%d` | Number (both integer and float). |
|
||||
| `%j` | JSON. Replaced with the string '[Circular]' if the argument contains circular references. |
|
||||
| `%%` | Single percent sign ('%'). This does not consume an argument. |
|
||||
|
||||
|
||||
### Custom formatters
|
||||
|
||||
You can add custom formatters by extending the `debug.formatters` object.
|
||||
For example, if you wanted to add support for rendering a Buffer as hex with
|
||||
`%h`, you could do something like:
|
||||
|
||||
```js
|
||||
const createDebug = require('debug')
|
||||
createDebug.formatters.h = (v) => {
|
||||
return v.toString('hex')
|
||||
}
|
||||
|
||||
// …elsewhere
|
||||
const debug = createDebug('foo')
|
||||
debug('this is hex: %h', new Buffer('hello world'))
|
||||
// foo this is hex: 68656c6c6f20776f726c6421 +0ms
|
||||
```
|
||||
|
||||
|
||||
## Browser Support
|
||||
|
||||
You can build a browser-ready script using [browserify](https://github.com/substack/node-browserify),
|
||||
or just use the [browserify-as-a-service](https://wzrd.in/) [build](https://wzrd.in/standalone/debug@latest),
|
||||
if you don't want to build it yourself.
|
||||
|
||||
Debug's enable state is currently persisted by `localStorage`.
|
||||
Consider the situation shown below where you have `worker:a` and `worker:b`,
|
||||
and wish to debug both. You can enable this using `localStorage.debug`:
|
||||
|
||||
```js
|
||||
localStorage.debug = 'worker:*'
|
||||
```
|
||||
|
||||
And then refresh the page.
|
||||
|
||||
```js
|
||||
a = debug('worker:a');
|
||||
b = debug('worker:b');
|
||||
|
||||
setInterval(function(){
|
||||
a('doing some work');
|
||||
}, 1000);
|
||||
|
||||
setInterval(function(){
|
||||
b('doing some work');
|
||||
}, 1200);
|
||||
```
|
||||
|
||||
In Chromium-based web browsers (e.g. Brave, Chrome, and Electron), the JavaScript console will—by default—only show messages logged by `debug` if the "Verbose" log level is _enabled_.
|
||||
|
||||
<img width="647" src="https://user-images.githubusercontent.com/7143133/152083257-29034707-c42c-4959-8add-3cee850e6fcf.png">
|
||||
|
||||
## Output streams
|
||||
|
||||
By default `debug` will log to stderr, however this can be configured per-namespace by overriding the `log` method:
|
||||
|
||||
Example [_stdout.js_](./examples/node/stdout.js):
|
||||
|
||||
```js
|
||||
var debug = require('debug');
|
||||
var error = debug('app:error');
|
||||
|
||||
// by default stderr is used
|
||||
error('goes to stderr!');
|
||||
|
||||
var log = debug('app:log');
|
||||
// set this namespace to log via console.log
|
||||
log.log = console.log.bind(console); // don't forget to bind to console!
|
||||
log('goes to stdout');
|
||||
error('still goes to stderr!');
|
||||
|
||||
// set all output to go via console.info
|
||||
// overrides all per-namespace log settings
|
||||
debug.log = console.info.bind(console);
|
||||
error('now goes to stdout via console.info');
|
||||
log('still goes to stdout, but via console.info now');
|
||||
```
|
||||
|
||||
## Extend
|
||||
You can simply extend debugger
|
||||
```js
|
||||
const log = require('debug')('auth');
|
||||
|
||||
//creates new debug instance with extended namespace
|
||||
const logSign = log.extend('sign');
|
||||
const logLogin = log.extend('login');
|
||||
|
||||
log('hello'); // auth hello
|
||||
logSign('hello'); //auth:sign hello
|
||||
logLogin('hello'); //auth:login hello
|
||||
```
|
||||
|
||||
## Set dynamically
|
||||
|
||||
You can also enable debug dynamically by calling the `enable()` method :
|
||||
|
||||
```js
|
||||
let debug = require('debug');
|
||||
|
||||
console.log(1, debug.enabled('test'));
|
||||
|
||||
debug.enable('test');
|
||||
console.log(2, debug.enabled('test'));
|
||||
|
||||
debug.disable();
|
||||
console.log(3, debug.enabled('test'));
|
||||
|
||||
```
|
||||
|
||||
print :
|
||||
```
|
||||
1 false
|
||||
2 true
|
||||
3 false
|
||||
```
|
||||
|
||||
Usage :
|
||||
`enable(namespaces)`
|
||||
`namespaces` can include modes separated by a colon and wildcards.
|
||||
|
||||
Note that calling `enable()` completely overrides previously set DEBUG variable :
|
||||
|
||||
```
|
||||
$ DEBUG=foo node -e 'var dbg = require("debug"); dbg.enable("bar"); console.log(dbg.enabled("foo"))'
|
||||
=> false
|
||||
```
|
||||
|
||||
`disable()`
|
||||
|
||||
Will disable all namespaces. The functions returns the namespaces currently
|
||||
enabled (and skipped). This can be useful if you want to disable debugging
|
||||
temporarily without knowing what was enabled to begin with.
|
||||
|
||||
For example:
|
||||
|
||||
```js
|
||||
let debug = require('debug');
|
||||
debug.enable('foo:*,-foo:bar');
|
||||
let namespaces = debug.disable();
|
||||
debug.enable(namespaces);
|
||||
```
|
||||
|
||||
Note: There is no guarantee that the string will be identical to the initial
|
||||
enable string, but semantically they will be identical.
|
||||
|
||||
## Checking whether a debug target is enabled
|
||||
|
||||
After you've created a debug instance, you can determine whether or not it is
|
||||
enabled by checking the `enabled` property:
|
||||
|
||||
```javascript
|
||||
const debug = require('debug')('http');
|
||||
|
||||
if (debug.enabled) {
|
||||
// do stuff...
|
||||
}
|
||||
```
|
||||
|
||||
You can also manually toggle this property to force the debug instance to be
|
||||
enabled or disabled.
|
||||
|
||||
## Usage in child processes
|
||||
|
||||
Due to the way `debug` detects if the output is a TTY or not, colors are not shown in child processes when `stderr` is piped. A solution is to pass the `DEBUG_COLORS=1` environment variable to the child process.
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
worker = fork(WORKER_WRAP_PATH, [workerPath], {
|
||||
stdio: [
|
||||
/* stdin: */ 0,
|
||||
/* stdout: */ 'pipe',
|
||||
/* stderr: */ 'pipe',
|
||||
'ipc',
|
||||
],
|
||||
env: Object.assign({}, process.env, {
|
||||
DEBUG_COLORS: 1 // without this settings, colors won't be shown
|
||||
}),
|
||||
});
|
||||
|
||||
worker.stderr.pipe(process.stderr, { end: false });
|
||||
```
|
||||
|
||||
|
||||
## Authors
|
||||
|
||||
- TJ Holowaychuk
|
||||
- Nathan Rajlich
|
||||
- Andrew Rhyne
|
||||
- Josh Junon
|
||||
|
||||
## Backers
|
||||
|
||||
Support us with a monthly donation and help us continue our activities. [[Become a backer](https://opencollective.com/debug#backer)]
|
||||
|
||||
<a href="https://opencollective.com/debug/backer/0/website" target="_blank"><img src="https://opencollective.com/debug/backer/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/1/website" target="_blank"><img src="https://opencollective.com/debug/backer/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/2/website" target="_blank"><img src="https://opencollective.com/debug/backer/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/3/website" target="_blank"><img src="https://opencollective.com/debug/backer/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/4/website" target="_blank"><img src="https://opencollective.com/debug/backer/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/5/website" target="_blank"><img src="https://opencollective.com/debug/backer/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/6/website" target="_blank"><img src="https://opencollective.com/debug/backer/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/7/website" target="_blank"><img src="https://opencollective.com/debug/backer/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/8/website" target="_blank"><img src="https://opencollective.com/debug/backer/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/9/website" target="_blank"><img src="https://opencollective.com/debug/backer/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/10/website" target="_blank"><img src="https://opencollective.com/debug/backer/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/11/website" target="_blank"><img src="https://opencollective.com/debug/backer/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/12/website" target="_blank"><img src="https://opencollective.com/debug/backer/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/13/website" target="_blank"><img src="https://opencollective.com/debug/backer/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/14/website" target="_blank"><img src="https://opencollective.com/debug/backer/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/15/website" target="_blank"><img src="https://opencollective.com/debug/backer/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/16/website" target="_blank"><img src="https://opencollective.com/debug/backer/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/17/website" target="_blank"><img src="https://opencollective.com/debug/backer/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/18/website" target="_blank"><img src="https://opencollective.com/debug/backer/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/19/website" target="_blank"><img src="https://opencollective.com/debug/backer/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/20/website" target="_blank"><img src="https://opencollective.com/debug/backer/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/21/website" target="_blank"><img src="https://opencollective.com/debug/backer/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/22/website" target="_blank"><img src="https://opencollective.com/debug/backer/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/23/website" target="_blank"><img src="https://opencollective.com/debug/backer/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/24/website" target="_blank"><img src="https://opencollective.com/debug/backer/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/25/website" target="_blank"><img src="https://opencollective.com/debug/backer/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/26/website" target="_blank"><img src="https://opencollective.com/debug/backer/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/27/website" target="_blank"><img src="https://opencollective.com/debug/backer/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/28/website" target="_blank"><img src="https://opencollective.com/debug/backer/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/backer/29/website" target="_blank"><img src="https://opencollective.com/debug/backer/29/avatar.svg"></a>
|
||||
|
||||
|
||||
## Sponsors
|
||||
|
||||
Become a sponsor and get your logo on our README on Github with a link to your site. [[Become a sponsor](https://opencollective.com/debug#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/debug/sponsor/0/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/1/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/2/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/3/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/4/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/5/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/6/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/7/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/8/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/9/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/9/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/10/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/10/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/11/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/11/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/12/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/12/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/13/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/13/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/14/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/14/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/15/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/15/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/16/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/16/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/17/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/17/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/18/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/18/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/19/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/19/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/20/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/20/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/21/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/21/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/22/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/22/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/23/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/23/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/24/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/24/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/25/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/25/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/26/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/26/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/27/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/27/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/28/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/28/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/debug/sponsor/29/website" target="_blank"><img src="https://opencollective.com/debug/sponsor/29/avatar.svg"></a>
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2014-2017 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2018-2021 Josh Junon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
65
node_modules/mssql/node_modules/debug/package.json
generated
vendored
Normal file
65
node_modules/mssql/node_modules/debug/package.json
generated
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "debug",
|
||||
"version": "4.4.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/debug-js/debug.git"
|
||||
},
|
||||
"description": "Lightweight debugging utility for Node.js and the browser",
|
||||
"keywords": [
|
||||
"debug",
|
||||
"log",
|
||||
"debugger"
|
||||
],
|
||||
"files": [
|
||||
"src",
|
||||
"LICENSE",
|
||||
"README.md"
|
||||
],
|
||||
"author": "Josh Junon (https://github.com/qix-)",
|
||||
"contributors": [
|
||||
"TJ Holowaychuk <tj@vision-media.ca>",
|
||||
"Nathan Rajlich <nathan@tootallnate.net> (http://n8.io)",
|
||||
"Andrew Rhyne <rhyneandrew@gmail.com>"
|
||||
],
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"lint": "xo",
|
||||
"test": "npm run test:node && npm run test:browser && npm run lint",
|
||||
"test:node": "istanbul cover _mocha -- test.js test.node.js",
|
||||
"test:browser": "karma start --single-run",
|
||||
"test:coverage": "cat ./coverage/lcov.info | coveralls"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"brfs": "^2.0.1",
|
||||
"browserify": "^16.2.3",
|
||||
"coveralls": "^3.0.2",
|
||||
"istanbul": "^0.4.5",
|
||||
"karma": "^3.1.4",
|
||||
"karma-browserify": "^6.0.0",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-mocha": "^1.3.0",
|
||||
"mocha": "^5.2.0",
|
||||
"mocha-lcov-reporter": "^1.2.0",
|
||||
"sinon": "^14.0.0",
|
||||
"xo": "^0.23.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"main": "./src/index.js",
|
||||
"browser": "./src/browser.js",
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"xo": {
|
||||
"rules": {
|
||||
"import/extensions": "off"
|
||||
}
|
||||
}
|
||||
}
|
||||
272
node_modules/mssql/node_modules/debug/src/browser.js
generated
vendored
Normal file
272
node_modules/mssql/node_modules/debug/src/browser.js
generated
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
/* eslint-env browser */
|
||||
|
||||
/**
|
||||
* This is the web browser implementation of `debug()`.
|
||||
*/
|
||||
|
||||
exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.storage = localstorage();
|
||||
exports.destroy = (() => {
|
||||
let warned = false;
|
||||
|
||||
return () => {
|
||||
if (!warned) {
|
||||
warned = true;
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
exports.colors = [
|
||||
'#0000CC',
|
||||
'#0000FF',
|
||||
'#0033CC',
|
||||
'#0033FF',
|
||||
'#0066CC',
|
||||
'#0066FF',
|
||||
'#0099CC',
|
||||
'#0099FF',
|
||||
'#00CC00',
|
||||
'#00CC33',
|
||||
'#00CC66',
|
||||
'#00CC99',
|
||||
'#00CCCC',
|
||||
'#00CCFF',
|
||||
'#3300CC',
|
||||
'#3300FF',
|
||||
'#3333CC',
|
||||
'#3333FF',
|
||||
'#3366CC',
|
||||
'#3366FF',
|
||||
'#3399CC',
|
||||
'#3399FF',
|
||||
'#33CC00',
|
||||
'#33CC33',
|
||||
'#33CC66',
|
||||
'#33CC99',
|
||||
'#33CCCC',
|
||||
'#33CCFF',
|
||||
'#6600CC',
|
||||
'#6600FF',
|
||||
'#6633CC',
|
||||
'#6633FF',
|
||||
'#66CC00',
|
||||
'#66CC33',
|
||||
'#9900CC',
|
||||
'#9900FF',
|
||||
'#9933CC',
|
||||
'#9933FF',
|
||||
'#99CC00',
|
||||
'#99CC33',
|
||||
'#CC0000',
|
||||
'#CC0033',
|
||||
'#CC0066',
|
||||
'#CC0099',
|
||||
'#CC00CC',
|
||||
'#CC00FF',
|
||||
'#CC3300',
|
||||
'#CC3333',
|
||||
'#CC3366',
|
||||
'#CC3399',
|
||||
'#CC33CC',
|
||||
'#CC33FF',
|
||||
'#CC6600',
|
||||
'#CC6633',
|
||||
'#CC9900',
|
||||
'#CC9933',
|
||||
'#CCCC00',
|
||||
'#CCCC33',
|
||||
'#FF0000',
|
||||
'#FF0033',
|
||||
'#FF0066',
|
||||
'#FF0099',
|
||||
'#FF00CC',
|
||||
'#FF00FF',
|
||||
'#FF3300',
|
||||
'#FF3333',
|
||||
'#FF3366',
|
||||
'#FF3399',
|
||||
'#FF33CC',
|
||||
'#FF33FF',
|
||||
'#FF6600',
|
||||
'#FF6633',
|
||||
'#FF9900',
|
||||
'#FF9933',
|
||||
'#FFCC00',
|
||||
'#FFCC33'
|
||||
];
|
||||
|
||||
/**
|
||||
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
||||
* and the Firebug extension (any Firefox version) are known
|
||||
* to support "%c" CSS customizations.
|
||||
*
|
||||
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line complexity
|
||||
function useColors() {
|
||||
// NB: In an Electron preload script, document will be defined but not fully
|
||||
// initialized. Since we know we're in Chrome, we'll just detect this case
|
||||
// explicitly
|
||||
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Internet Explorer and Edge do not support colors.
|
||||
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let m;
|
||||
|
||||
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
||||
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
||||
// eslint-disable-next-line no-return-assign
|
||||
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
||||
// Is firebug? http://stackoverflow.com/a/398120/376773
|
||||
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
||||
// Is firefox >= v31?
|
||||
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
|
||||
// Double check webkit in userAgent just in case we are in a worker
|
||||
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorize log arguments if enabled.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function formatArgs(args) {
|
||||
args[0] = (this.useColors ? '%c' : '') +
|
||||
this.namespace +
|
||||
(this.useColors ? ' %c' : ' ') +
|
||||
args[0] +
|
||||
(this.useColors ? '%c ' : ' ') +
|
||||
'+' + module.exports.humanize(this.diff);
|
||||
|
||||
if (!this.useColors) {
|
||||
return;
|
||||
}
|
||||
|
||||
const c = 'color: ' + this.color;
|
||||
args.splice(1, 0, c, 'color: inherit');
|
||||
|
||||
// The final "%c" is somewhat tricky, because there could be other
|
||||
// arguments passed either before or after the %c, so we need to
|
||||
// figure out the correct index to insert the CSS into
|
||||
let index = 0;
|
||||
let lastC = 0;
|
||||
args[0].replace(/%[a-zA-Z%]/g, match => {
|
||||
if (match === '%%') {
|
||||
return;
|
||||
}
|
||||
index++;
|
||||
if (match === '%c') {
|
||||
// We only are interested in the *last* %c
|
||||
// (the user may have provided their own)
|
||||
lastC = index;
|
||||
}
|
||||
});
|
||||
|
||||
args.splice(lastC, 0, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `console.debug()` when available.
|
||||
* No-op when `console.debug` is not a "function".
|
||||
* If `console.debug` is not available, falls back
|
||||
* to `console.log`.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
exports.log = console.debug || console.log || (() => {});
|
||||
|
||||
/**
|
||||
* Save `namespaces`.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api private
|
||||
*/
|
||||
function save(namespaces) {
|
||||
try {
|
||||
if (namespaces) {
|
||||
exports.storage.setItem('debug', namespaces);
|
||||
} else {
|
||||
exports.storage.removeItem('debug');
|
||||
}
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load `namespaces`.
|
||||
*
|
||||
* @return {String} returns the previously persisted debug modes
|
||||
* @api private
|
||||
*/
|
||||
function load() {
|
||||
let r;
|
||||
try {
|
||||
r = exports.storage.getItem('debug');
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
|
||||
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
|
||||
if (!r && typeof process !== 'undefined' && 'env' in process) {
|
||||
r = process.env.DEBUG;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Localstorage attempts to return the localstorage.
|
||||
*
|
||||
* This is necessary because safari throws
|
||||
* when a user disables cookies/localstorage
|
||||
* and you attempt to access it.
|
||||
*
|
||||
* @return {LocalStorage}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function localstorage() {
|
||||
try {
|
||||
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
|
||||
// The Browser also has localStorage in the global context.
|
||||
return localStorage;
|
||||
} catch (error) {
|
||||
// Swallow
|
||||
// XXX (@Qix-) should we be logging these?
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = require('./common')(exports);
|
||||
|
||||
const {formatters} = module.exports;
|
||||
|
||||
/**
|
||||
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
||||
*/
|
||||
|
||||
formatters.j = function (v) {
|
||||
try {
|
||||
return JSON.stringify(v);
|
||||
} catch (error) {
|
||||
return '[UnexpectedJSONParseError]: ' + error.message;
|
||||
}
|
||||
};
|
||||
292
node_modules/mssql/node_modules/debug/src/common.js
generated
vendored
Normal file
292
node_modules/mssql/node_modules/debug/src/common.js
generated
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
|
||||
/**
|
||||
* This is the common logic for both the Node.js and web browser
|
||||
* implementations of `debug()`.
|
||||
*/
|
||||
|
||||
function setup(env) {
|
||||
createDebug.debug = createDebug;
|
||||
createDebug.default = createDebug;
|
||||
createDebug.coerce = coerce;
|
||||
createDebug.disable = disable;
|
||||
createDebug.enable = enable;
|
||||
createDebug.enabled = enabled;
|
||||
createDebug.humanize = require('ms');
|
||||
createDebug.destroy = destroy;
|
||||
|
||||
Object.keys(env).forEach(key => {
|
||||
createDebug[key] = env[key];
|
||||
});
|
||||
|
||||
/**
|
||||
* The currently active debug mode names, and names to skip.
|
||||
*/
|
||||
|
||||
createDebug.names = [];
|
||||
createDebug.skips = [];
|
||||
|
||||
/**
|
||||
* Map of special "%n" handling functions, for the debug "format" argument.
|
||||
*
|
||||
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
|
||||
*/
|
||||
createDebug.formatters = {};
|
||||
|
||||
/**
|
||||
* Selects a color for a debug namespace
|
||||
* @param {String} namespace The namespace string for the debug instance to be colored
|
||||
* @return {Number|String} An ANSI color code for the given namespace
|
||||
* @api private
|
||||
*/
|
||||
function selectColor(namespace) {
|
||||
let hash = 0;
|
||||
|
||||
for (let i = 0; i < namespace.length; i++) {
|
||||
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
}
|
||||
|
||||
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
||||
}
|
||||
createDebug.selectColor = selectColor;
|
||||
|
||||
/**
|
||||
* Create a debugger with the given `namespace`.
|
||||
*
|
||||
* @param {String} namespace
|
||||
* @return {Function}
|
||||
* @api public
|
||||
*/
|
||||
function createDebug(namespace) {
|
||||
let prevTime;
|
||||
let enableOverride = null;
|
||||
let namespacesCache;
|
||||
let enabledCache;
|
||||
|
||||
function debug(...args) {
|
||||
// Disabled?
|
||||
if (!debug.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const self = debug;
|
||||
|
||||
// Set `diff` timestamp
|
||||
const curr = Number(new Date());
|
||||
const ms = curr - (prevTime || curr);
|
||||
self.diff = ms;
|
||||
self.prev = prevTime;
|
||||
self.curr = curr;
|
||||
prevTime = curr;
|
||||
|
||||
args[0] = createDebug.coerce(args[0]);
|
||||
|
||||
if (typeof args[0] !== 'string') {
|
||||
// Anything else let's inspect with %O
|
||||
args.unshift('%O');
|
||||
}
|
||||
|
||||
// Apply any `formatters` transformations
|
||||
let index = 0;
|
||||
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
||||
// If we encounter an escaped % then don't increase the array index
|
||||
if (match === '%%') {
|
||||
return '%';
|
||||
}
|
||||
index++;
|
||||
const formatter = createDebug.formatters[format];
|
||||
if (typeof formatter === 'function') {
|
||||
const val = args[index];
|
||||
match = formatter.call(self, val);
|
||||
|
||||
// Now we need to remove `args[index]` since it's inlined in the `format`
|
||||
args.splice(index, 1);
|
||||
index--;
|
||||
}
|
||||
return match;
|
||||
});
|
||||
|
||||
// Apply env-specific formatting (colors, etc.)
|
||||
createDebug.formatArgs.call(self, args);
|
||||
|
||||
const logFn = self.log || createDebug.log;
|
||||
logFn.apply(self, args);
|
||||
}
|
||||
|
||||
debug.namespace = namespace;
|
||||
debug.useColors = createDebug.useColors();
|
||||
debug.color = createDebug.selectColor(namespace);
|
||||
debug.extend = extend;
|
||||
debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
|
||||
|
||||
Object.defineProperty(debug, 'enabled', {
|
||||
enumerable: true,
|
||||
configurable: false,
|
||||
get: () => {
|
||||
if (enableOverride !== null) {
|
||||
return enableOverride;
|
||||
}
|
||||
if (namespacesCache !== createDebug.namespaces) {
|
||||
namespacesCache = createDebug.namespaces;
|
||||
enabledCache = createDebug.enabled(namespace);
|
||||
}
|
||||
|
||||
return enabledCache;
|
||||
},
|
||||
set: v => {
|
||||
enableOverride = v;
|
||||
}
|
||||
});
|
||||
|
||||
// Env-specific initialization logic for debug instances
|
||||
if (typeof createDebug.init === 'function') {
|
||||
createDebug.init(debug);
|
||||
}
|
||||
|
||||
return debug;
|
||||
}
|
||||
|
||||
function extend(namespace, delimiter) {
|
||||
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
|
||||
newDebug.log = this.log;
|
||||
return newDebug;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables a debug mode by namespaces. This can include modes
|
||||
* separated by a colon and wildcards.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api public
|
||||
*/
|
||||
function enable(namespaces) {
|
||||
createDebug.save(namespaces);
|
||||
createDebug.namespaces = namespaces;
|
||||
|
||||
createDebug.names = [];
|
||||
createDebug.skips = [];
|
||||
|
||||
const split = (typeof namespaces === 'string' ? namespaces : '')
|
||||
.trim()
|
||||
.replace(' ', ',')
|
||||
.split(',')
|
||||
.filter(Boolean);
|
||||
|
||||
for (const ns of split) {
|
||||
if (ns[0] === '-') {
|
||||
createDebug.skips.push(ns.slice(1));
|
||||
} else {
|
||||
createDebug.names.push(ns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given string matches a namespace template, honoring
|
||||
* asterisks as wildcards.
|
||||
*
|
||||
* @param {String} search
|
||||
* @param {String} template
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function matchesTemplate(search, template) {
|
||||
let searchIndex = 0;
|
||||
let templateIndex = 0;
|
||||
let starIndex = -1;
|
||||
let matchIndex = 0;
|
||||
|
||||
while (searchIndex < search.length) {
|
||||
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
|
||||
// Match character or proceed with wildcard
|
||||
if (template[templateIndex] === '*') {
|
||||
starIndex = templateIndex;
|
||||
matchIndex = searchIndex;
|
||||
templateIndex++; // Skip the '*'
|
||||
} else {
|
||||
searchIndex++;
|
||||
templateIndex++;
|
||||
}
|
||||
} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
|
||||
// Backtrack to the last '*' and try to match more characters
|
||||
templateIndex = starIndex + 1;
|
||||
matchIndex++;
|
||||
searchIndex = matchIndex;
|
||||
} else {
|
||||
return false; // No match
|
||||
}
|
||||
}
|
||||
|
||||
// Handle trailing '*' in template
|
||||
while (templateIndex < template.length && template[templateIndex] === '*') {
|
||||
templateIndex++;
|
||||
}
|
||||
|
||||
return templateIndex === template.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable debug output.
|
||||
*
|
||||
* @return {String} namespaces
|
||||
* @api public
|
||||
*/
|
||||
function disable() {
|
||||
const namespaces = [
|
||||
...createDebug.names,
|
||||
...createDebug.skips.map(namespace => '-' + namespace)
|
||||
].join(',');
|
||||
createDebug.enable('');
|
||||
return namespaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given mode name is enabled, false otherwise.
|
||||
*
|
||||
* @param {String} name
|
||||
* @return {Boolean}
|
||||
* @api public
|
||||
*/
|
||||
function enabled(name) {
|
||||
for (const skip of createDebug.skips) {
|
||||
if (matchesTemplate(name, skip)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (const ns of createDebug.names) {
|
||||
if (matchesTemplate(name, ns)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce `val`.
|
||||
*
|
||||
* @param {Mixed} val
|
||||
* @return {Mixed}
|
||||
* @api private
|
||||
*/
|
||||
function coerce(val) {
|
||||
if (val instanceof Error) {
|
||||
return val.stack || val.message;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* XXX DO NOT USE. This is a temporary stub function.
|
||||
* XXX It WILL be removed in the next major release.
|
||||
*/
|
||||
function destroy() {
|
||||
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
||||
}
|
||||
|
||||
createDebug.enable(createDebug.load());
|
||||
|
||||
return createDebug;
|
||||
}
|
||||
|
||||
module.exports = setup;
|
||||
10
node_modules/mssql/node_modules/debug/src/index.js
generated
vendored
Normal file
10
node_modules/mssql/node_modules/debug/src/index.js
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Detect Electron renderer / nwjs process, which is node, but we should
|
||||
* treat as a browser.
|
||||
*/
|
||||
|
||||
if (typeof process === 'undefined' || process.type === 'renderer' || process.browser === true || process.__nwjs) {
|
||||
module.exports = require('./browser.js');
|
||||
} else {
|
||||
module.exports = require('./node.js');
|
||||
}
|
||||
263
node_modules/mssql/node_modules/debug/src/node.js
generated
vendored
Normal file
263
node_modules/mssql/node_modules/debug/src/node.js
generated
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
const tty = require('tty');
|
||||
const util = require('util');
|
||||
|
||||
/**
|
||||
* This is the Node.js implementation of `debug()`.
|
||||
*/
|
||||
|
||||
exports.init = init;
|
||||
exports.log = log;
|
||||
exports.formatArgs = formatArgs;
|
||||
exports.save = save;
|
||||
exports.load = load;
|
||||
exports.useColors = useColors;
|
||||
exports.destroy = util.deprecate(
|
||||
() => {},
|
||||
'Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'
|
||||
);
|
||||
|
||||
/**
|
||||
* Colors.
|
||||
*/
|
||||
|
||||
exports.colors = [6, 2, 3, 4, 5, 1];
|
||||
|
||||
try {
|
||||
// Optional dependency (as in, doesn't need to be installed, NOT like optionalDependencies in package.json)
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
const supportsColor = require('supports-color');
|
||||
|
||||
if (supportsColor && (supportsColor.stderr || supportsColor).level >= 2) {
|
||||
exports.colors = [
|
||||
20,
|
||||
21,
|
||||
26,
|
||||
27,
|
||||
32,
|
||||
33,
|
||||
38,
|
||||
39,
|
||||
40,
|
||||
41,
|
||||
42,
|
||||
43,
|
||||
44,
|
||||
45,
|
||||
56,
|
||||
57,
|
||||
62,
|
||||
63,
|
||||
68,
|
||||
69,
|
||||
74,
|
||||
75,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
92,
|
||||
93,
|
||||
98,
|
||||
99,
|
||||
112,
|
||||
113,
|
||||
128,
|
||||
129,
|
||||
134,
|
||||
135,
|
||||
148,
|
||||
149,
|
||||
160,
|
||||
161,
|
||||
162,
|
||||
163,
|
||||
164,
|
||||
165,
|
||||
166,
|
||||
167,
|
||||
168,
|
||||
169,
|
||||
170,
|
||||
171,
|
||||
172,
|
||||
173,
|
||||
178,
|
||||
179,
|
||||
184,
|
||||
185,
|
||||
196,
|
||||
197,
|
||||
198,
|
||||
199,
|
||||
200,
|
||||
201,
|
||||
202,
|
||||
203,
|
||||
204,
|
||||
205,
|
||||
206,
|
||||
207,
|
||||
208,
|
||||
209,
|
||||
214,
|
||||
215,
|
||||
220,
|
||||
221
|
||||
];
|
||||
}
|
||||
} catch (error) {
|
||||
// Swallow - we only care if `supports-color` is available; it doesn't have to be.
|
||||
}
|
||||
|
||||
/**
|
||||
* Build up the default `inspectOpts` object from the environment variables.
|
||||
*
|
||||
* $ DEBUG_COLORS=no DEBUG_DEPTH=10 DEBUG_SHOW_HIDDEN=enabled node script.js
|
||||
*/
|
||||
|
||||
exports.inspectOpts = Object.keys(process.env).filter(key => {
|
||||
return /^debug_/i.test(key);
|
||||
}).reduce((obj, key) => {
|
||||
// Camel-case
|
||||
const prop = key
|
||||
.substring(6)
|
||||
.toLowerCase()
|
||||
.replace(/_([a-z])/g, (_, k) => {
|
||||
return k.toUpperCase();
|
||||
});
|
||||
|
||||
// Coerce string value into JS value
|
||||
let val = process.env[key];
|
||||
if (/^(yes|on|true|enabled)$/i.test(val)) {
|
||||
val = true;
|
||||
} else if (/^(no|off|false|disabled)$/i.test(val)) {
|
||||
val = false;
|
||||
} else if (val === 'null') {
|
||||
val = null;
|
||||
} else {
|
||||
val = Number(val);
|
||||
}
|
||||
|
||||
obj[prop] = val;
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
/**
|
||||
* Is stdout a TTY? Colored output is enabled when `true`.
|
||||
*/
|
||||
|
||||
function useColors() {
|
||||
return 'colors' in exports.inspectOpts ?
|
||||
Boolean(exports.inspectOpts.colors) :
|
||||
tty.isatty(process.stderr.fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ANSI color escape codes if enabled.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function formatArgs(args) {
|
||||
const {namespace: name, useColors} = this;
|
||||
|
||||
if (useColors) {
|
||||
const c = this.color;
|
||||
const colorCode = '\u001B[3' + (c < 8 ? c : '8;5;' + c);
|
||||
const prefix = ` ${colorCode};1m${name} \u001B[0m`;
|
||||
|
||||
args[0] = prefix + args[0].split('\n').join('\n' + prefix);
|
||||
args.push(colorCode + 'm+' + module.exports.humanize(this.diff) + '\u001B[0m');
|
||||
} else {
|
||||
args[0] = getDate() + name + ' ' + args[0];
|
||||
}
|
||||
}
|
||||
|
||||
function getDate() {
|
||||
if (exports.inspectOpts.hideDate) {
|
||||
return '';
|
||||
}
|
||||
return new Date().toISOString() + ' ';
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes `util.formatWithOptions()` with the specified arguments and writes to stderr.
|
||||
*/
|
||||
|
||||
function log(...args) {
|
||||
return process.stderr.write(util.formatWithOptions(exports.inspectOpts, ...args) + '\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Save `namespaces`.
|
||||
*
|
||||
* @param {String} namespaces
|
||||
* @api private
|
||||
*/
|
||||
function save(namespaces) {
|
||||
if (namespaces) {
|
||||
process.env.DEBUG = namespaces;
|
||||
} else {
|
||||
// If you set a process.env field to null or undefined, it gets cast to the
|
||||
// string 'null' or 'undefined'. Just delete instead.
|
||||
delete process.env.DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load `namespaces`.
|
||||
*
|
||||
* @return {String} returns the previously persisted debug modes
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function load() {
|
||||
return process.env.DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init logic for `debug` instances.
|
||||
*
|
||||
* Create a new `inspectOpts` object in case `useColors` is set
|
||||
* differently for a particular `debug` instance.
|
||||
*/
|
||||
|
||||
function init(debug) {
|
||||
debug.inspectOpts = {};
|
||||
|
||||
const keys = Object.keys(exports.inspectOpts);
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
debug.inspectOpts[keys[i]] = exports.inspectOpts[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = require('./common')(exports);
|
||||
|
||||
const {formatters} = module.exports;
|
||||
|
||||
/**
|
||||
* Map %o to `util.inspect()`, all on a single line.
|
||||
*/
|
||||
|
||||
formatters.o = function (v) {
|
||||
this.inspectOpts.colors = this.useColors;
|
||||
return util.inspect(v, this.inspectOpts)
|
||||
.split('\n')
|
||||
.map(str => str.trim())
|
||||
.join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Map %O to `util.inspect()`, allowing multiple lines if needed.
|
||||
*/
|
||||
|
||||
formatters.O = function (v) {
|
||||
this.inspectOpts.colors = this.useColors;
|
||||
return util.inspect(v, this.inspectOpts);
|
||||
};
|
||||
162
node_modules/mssql/node_modules/ms/index.js
generated
vendored
Normal file
162
node_modules/mssql/node_modules/ms/index.js
generated
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Helpers.
|
||||
*/
|
||||
|
||||
var s = 1000;
|
||||
var m = s * 60;
|
||||
var h = m * 60;
|
||||
var d = h * 24;
|
||||
var w = d * 7;
|
||||
var y = d * 365.25;
|
||||
|
||||
/**
|
||||
* Parse or format the given `val`.
|
||||
*
|
||||
* Options:
|
||||
*
|
||||
* - `long` verbose formatting [false]
|
||||
*
|
||||
* @param {String|Number} val
|
||||
* @param {Object} [options]
|
||||
* @throws {Error} throw an error if val is not a non-empty string or a number
|
||||
* @return {String|Number}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
module.exports = function (val, options) {
|
||||
options = options || {};
|
||||
var type = typeof val;
|
||||
if (type === 'string' && val.length > 0) {
|
||||
return parse(val);
|
||||
} else if (type === 'number' && isFinite(val)) {
|
||||
return options.long ? fmtLong(val) : fmtShort(val);
|
||||
}
|
||||
throw new Error(
|
||||
'val is not a non-empty string or a valid number. val=' +
|
||||
JSON.stringify(val)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given `str` and return milliseconds.
|
||||
*
|
||||
* @param {String} str
|
||||
* @return {Number}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function parse(str) {
|
||||
str = String(str);
|
||||
if (str.length > 100) {
|
||||
return;
|
||||
}
|
||||
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
||||
str
|
||||
);
|
||||
if (!match) {
|
||||
return;
|
||||
}
|
||||
var n = parseFloat(match[1]);
|
||||
var type = (match[2] || 'ms').toLowerCase();
|
||||
switch (type) {
|
||||
case 'years':
|
||||
case 'year':
|
||||
case 'yrs':
|
||||
case 'yr':
|
||||
case 'y':
|
||||
return n * y;
|
||||
case 'weeks':
|
||||
case 'week':
|
||||
case 'w':
|
||||
return n * w;
|
||||
case 'days':
|
||||
case 'day':
|
||||
case 'd':
|
||||
return n * d;
|
||||
case 'hours':
|
||||
case 'hour':
|
||||
case 'hrs':
|
||||
case 'hr':
|
||||
case 'h':
|
||||
return n * h;
|
||||
case 'minutes':
|
||||
case 'minute':
|
||||
case 'mins':
|
||||
case 'min':
|
||||
case 'm':
|
||||
return n * m;
|
||||
case 'seconds':
|
||||
case 'second':
|
||||
case 'secs':
|
||||
case 'sec':
|
||||
case 's':
|
||||
return n * s;
|
||||
case 'milliseconds':
|
||||
case 'millisecond':
|
||||
case 'msecs':
|
||||
case 'msec':
|
||||
case 'ms':
|
||||
return n;
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Short format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtShort(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return Math.round(ms / d) + 'd';
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return Math.round(ms / h) + 'h';
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return Math.round(ms / m) + 'm';
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return Math.round(ms / s) + 's';
|
||||
}
|
||||
return ms + 'ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Long format for `ms`.
|
||||
*
|
||||
* @param {Number} ms
|
||||
* @return {String}
|
||||
* @api private
|
||||
*/
|
||||
|
||||
function fmtLong(ms) {
|
||||
var msAbs = Math.abs(ms);
|
||||
if (msAbs >= d) {
|
||||
return plural(ms, msAbs, d, 'day');
|
||||
}
|
||||
if (msAbs >= h) {
|
||||
return plural(ms, msAbs, h, 'hour');
|
||||
}
|
||||
if (msAbs >= m) {
|
||||
return plural(ms, msAbs, m, 'minute');
|
||||
}
|
||||
if (msAbs >= s) {
|
||||
return plural(ms, msAbs, s, 'second');
|
||||
}
|
||||
return ms + ' ms';
|
||||
}
|
||||
|
||||
/**
|
||||
* Pluralization helper.
|
||||
*/
|
||||
|
||||
function plural(ms, msAbs, n, name) {
|
||||
var isPlural = msAbs >= n * 1.5;
|
||||
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
|
||||
}
|
||||
21
node_modules/mssql/node_modules/ms/license.md
generated
vendored
Normal file
21
node_modules/mssql/node_modules/ms/license.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2020 Vercel, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
38
node_modules/mssql/node_modules/ms/package.json
generated
vendored
Normal file
38
node_modules/mssql/node_modules/ms/package.json
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "ms",
|
||||
"version": "2.1.3",
|
||||
"description": "Tiny millisecond conversion utility",
|
||||
"repository": "vercel/ms",
|
||||
"main": "./index",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"scripts": {
|
||||
"precommit": "lint-staged",
|
||||
"lint": "eslint lib/* bin/*",
|
||||
"test": "mocha tests.js"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "eslint:recommended",
|
||||
"env": {
|
||||
"node": true,
|
||||
"es6": true
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.js": [
|
||||
"npm run lint",
|
||||
"prettier --single-quote --write",
|
||||
"git add"
|
||||
]
|
||||
},
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"eslint": "4.18.2",
|
||||
"expect.js": "0.3.1",
|
||||
"husky": "0.14.3",
|
||||
"lint-staged": "5.0.0",
|
||||
"mocha": "4.0.1",
|
||||
"prettier": "2.0.5"
|
||||
}
|
||||
}
|
||||
59
node_modules/mssql/node_modules/ms/readme.md
generated
vendored
Normal file
59
node_modules/mssql/node_modules/ms/readme.md
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
# ms
|
||||
|
||||

|
||||
|
||||
Use this package to easily convert various time formats to milliseconds.
|
||||
|
||||
## Examples
|
||||
|
||||
```js
|
||||
ms('2 days') // 172800000
|
||||
ms('1d') // 86400000
|
||||
ms('10h') // 36000000
|
||||
ms('2.5 hrs') // 9000000
|
||||
ms('2h') // 7200000
|
||||
ms('1m') // 60000
|
||||
ms('5s') // 5000
|
||||
ms('1y') // 31557600000
|
||||
ms('100') // 100
|
||||
ms('-3 days') // -259200000
|
||||
ms('-1h') // -3600000
|
||||
ms('-200') // -200
|
||||
```
|
||||
|
||||
### Convert from Milliseconds
|
||||
|
||||
```js
|
||||
ms(60000) // "1m"
|
||||
ms(2 * 60000) // "2m"
|
||||
ms(-3 * 60000) // "-3m"
|
||||
ms(ms('10 hours')) // "10h"
|
||||
```
|
||||
|
||||
### Time Format Written-Out
|
||||
|
||||
```js
|
||||
ms(60000, { long: true }) // "1 minute"
|
||||
ms(2 * 60000, { long: true }) // "2 minutes"
|
||||
ms(-3 * 60000, { long: true }) // "-3 minutes"
|
||||
ms(ms('10 hours'), { long: true }) // "10 hours"
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- Works both in [Node.js](https://nodejs.org) and in the browser
|
||||
- If a number is supplied to `ms`, a string with a unit is returned
|
||||
- If a string that contains the number is supplied, it returns it as a number (e.g.: it returns `100` for `'100'`)
|
||||
- If you pass a string with a number and a valid unit, the number of equivalent milliseconds is returned
|
||||
|
||||
## Related Packages
|
||||
|
||||
- [ms.macro](https://github.com/knpwrs/ms.macro) - Run `ms` as a macro at build-time.
|
||||
|
||||
## Caught a Bug?
|
||||
|
||||
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
|
||||
2. Link the package to the global module directory: `npm link`
|
||||
3. Within the module you want to test your local development instance of ms, just link it to the dependencies: `npm link ms`. Instead of the default one from npm, Node.js will now use your clone of ms!
|
||||
|
||||
As always, you can run the tests using: `npm test`
|
||||
69
node_modules/mssql/package.json
generated
vendored
Normal file
69
node_modules/mssql/package.json
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"author": {
|
||||
"name": "Patrik Simek",
|
||||
"url": "https://patriksimek.cz"
|
||||
},
|
||||
"name": "mssql",
|
||||
"description": "Microsoft SQL Server client for Node.js.",
|
||||
"keywords": [
|
||||
"database",
|
||||
"mssql",
|
||||
"sql",
|
||||
"server",
|
||||
"msnodesql",
|
||||
"sqlserver",
|
||||
"tds",
|
||||
"node-tds",
|
||||
"tedious",
|
||||
"node-sqlserver",
|
||||
"sqlserver",
|
||||
"msnodesqlv8",
|
||||
"azure",
|
||||
"node-mssql"
|
||||
],
|
||||
"version": "11.0.1",
|
||||
"main": "index.js",
|
||||
"type": "commonjs",
|
||||
"repository": "github:tediousjs/node-mssql",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tediousjs/connection-string": "^0.5.0",
|
||||
"commander": "^11.0.0",
|
||||
"debug": "^4.3.3",
|
||||
"rfdc": "^1.3.0",
|
||||
"tarn": "^3.0.2",
|
||||
"tedious": "^18.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^19.3.0",
|
||||
"@commitlint/config-conventional": "^19.2.2",
|
||||
"@semantic-release/commit-analyzer": "^11.1.0",
|
||||
"@semantic-release/github": "^9.2.6",
|
||||
"@semantic-release/npm": "^11.0.3",
|
||||
"@semantic-release/release-notes-generator": "^12.1.0",
|
||||
"mocha": "^10.0.0",
|
||||
"semantic-release": "^22.0.12",
|
||||
"standard": "^17.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"files": [
|
||||
"lib/",
|
||||
"bin/",
|
||||
"tedious.js",
|
||||
"msnodesqlv8.js"
|
||||
],
|
||||
"scripts": {
|
||||
"commitlint": "commitlint --from origin/master --to HEAD",
|
||||
"test": "npm run lint && npm run test-unit",
|
||||
"lint": "standard",
|
||||
"test-unit": "mocha --exit -t 15000 test/common/unit.js",
|
||||
"test-tedious": "mocha --exit -t 15000 test/tedious",
|
||||
"test-msnodesqlv8": "mocha --exit -t 30000 test/msnodesqlv8",
|
||||
"test-cli": "mocha --exit -t 15000 test/common/cli.js"
|
||||
},
|
||||
"bin": {
|
||||
"mssql": "./bin/mssql"
|
||||
}
|
||||
}
|
||||
1
node_modules/mssql/tedious.js
generated
vendored
Normal file
1
node_modules/mssql/tedious.js
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = require('./lib/tedious')
|
||||
Reference in New Issue
Block a user