New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

odbc

Package Overview
Dependencies
Maintainers
3
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

odbc - npm Package Compare versions

Comparing version 2.4.0-beta.1 to 2.4.0-beta.2

3

CHANGELOG.md
# Changelog
All notable changes to this project will be documented in this file.
## [2.3.6] - 2020-02-19
- Emergency version to fix a push made to `npm` in error.
## [2.3.5] - 2020-09-14

@@ -5,0 +8,0 @@ ### Fixed

@@ -93,3 +93,8 @@ const { Statement } = require('./Statement');

} else {
if (options && options.hasOwnProperty('fetchSize'))
if (options &&
(
options.hasOwnProperty('fetchSize') ||
options.hasOwnProperty('cursor')
)
)
{

@@ -109,3 +114,8 @@ const cursor = new Cursor(result);

process.nextTick(() => {
if (options && options.hasOwnProperty('fetchSize'))
if (options &&
(
options.hasOwnProperty('fetchSize') ||
options.hasOwnProperty('cursor')
)
)
{

@@ -112,0 +122,0 @@ this.odbcConnection.query(sql, parameters, options, (error, result) => {

30

lib/odbc.d.ts

@@ -5,3 +5,6 @@ declare namespace odbc {

name: string;
datayType: number;
dataType: number;
columnSize: number;
decimalDigits: number;
nullable: boolean;
}

@@ -54,2 +57,17 @@

interface ConnectionParameters {
connectionString: string;
connectionTimeout?: number;
loginTimeout?: number;
}
interface PoolParameters {
connectionString: string;
connectionTimeout?: number;
loginTimeout?: number;
initialSize?: number;
incrementSize?: number;
maxSize?: number;
shrink?: boolean;
}
class Connection {

@@ -131,15 +149,15 @@

function connect(connectionString: string, callback: (error: NodeOdbcError, connection: Connection) => undefined): undefined;
function connect(connectionObject: object, callback: (error: NodeOdbcError, connection: Connection) => undefined): undefined;
function connect(connectionObject: ConnectionParameters, callback: (error: NodeOdbcError, connection: Connection) => undefined): undefined;
function connect(connectionString: string): Promise<Connection>;
function connect(connectionObject: object): Promise<Connection>;
function connect(connectionObject: ConnectionParameters): Promise<Connection>;
function pool(connectionString: string, callback: (error: NodeOdbcError, pool: Pool) => undefined): undefined;
function pool(connectionObject: object, callback: (error: NodeOdbcError, pool: Pool) => undefined): undefined;
function pool(connectionObject: PoolParameters, callback: (error: NodeOdbcError, pool: Pool) => undefined): undefined;
function pool(connectionString: string): Promise<Pool>;
function pool(connectionObject: object): Promise<Pool>;
function pool(connectionObject: PoolParameters): Promise<Pool>;
}
export = odbc;
export = odbc;

@@ -1,2 +0,2 @@

const binary = require('node-pre-gyp');
const binary = require('@mapbox/node-pre-gyp');
const path = require('path');

@@ -38,4 +38,8 @@

return new Promise(async (resolve, reject) => {
await poolObj.init();
resolve(poolObj);
try {
await poolObj.init();
resolve(poolObj);
} catch(e) {
reject(e);
}
});

@@ -42,0 +46,0 @@ }

const EventEmitter = require('events');
const async = require('async');
const binary = require('node-pre-gyp');
const binary = require('@mapbox/node-pre-gyp');
const path = require('path');

@@ -19,3 +19,43 @@

const LOGIN_TIMEOUT_DEFAULT = 0;
const MAX_ACTIVELY_CONNECTING = 1;
// A queue for tracking the connections
class ConnectionQueue
{
static queuedConnections = [];
static activelyConnectingCount = 0;
static maxActivelyConnecting = MAX_ACTIVELY_CONNECTING;
static enqueue = async function(pool, promiseGenerator, configObject)
{
ConnectionQueue.queuedConnections.push({
pool,
promiseGenerator,
configObject
});
ConnectionQueue.dequeue();
return;
}
static dequeue = async function()
{
if (this.activelyConnectingCount >= this.maxActivelyConnecting) {
return;
}
const item = this.queuedConnections.shift();
if (!item) {
return;
}
ConnectionQueue.activelyConnectingCount++;
try {
await item.promiseGenerator(item.configObject);
} catch (error) {
// We don't actually do anything with errors here
}
ConnectionQueue.activelyConnectingCount--;
ConnectionQueue.dequeue();
return;
}
}
class Pool {

@@ -25,11 +65,32 @@

this.connectionConfig = {};
this.waitingConnectionWork = [];
this.isOpen = false;
this.freeConnections = [];
this.connectionsBeingCreatedCount = 0;
this.poolSize = 0;
// Keeps track of when connections have sucessfully connected
this.connectionEmitter = new EventEmitter();
// Fires when a connection has been made
this.connectionEmitter.on('connected', (connection) => {
if (this.connectionQueue.length > 0)
// A connection has finished connecting, but there is some waiting call
// to connect() that is waiting for a connection. shift() that work from
// the front of the waitingConnectionWork queue, then either call the
// callback function provided by the user, or resolve the Promise that was
// returned to the user.
if (this.waitingConnectionWork.length > 0)
{
let connectionWork = this.connectionQueue.pop();
let connectionWork = this.waitingConnectionWork.shift();
// If the user passed a callback function, then call the function with
// no error in the first parameter and the connection in the second
// parameter
if (typeof connectionWork == 'function')
{
// callback function
return connectionWork(null, connection);
// If the user didn't pass a callback function, we returned a promise to
// them. Resolve that promise with the connection that was just created.
} else {

@@ -39,2 +100,7 @@ // Promise (stored resolve function)

}
// A connection finished connecting, and there was no work waiting for
// that connection to be made. Simply add it to the array of
// freeConnections, and the next time work comes in it can simply be
// retrieved from there.
} else {

@@ -45,11 +111,6 @@ this.freeConnections.push(connection);

this.isOpen = false;
this.freeConnections = [];
this.connectingCount = 0;
this.poolSize = 0;
this.connectionQueue = [];
// connectionString is a...
// connectionString is a string, so use defaults for all of the
// configuration options.
if (typeof connectionString === 'string') {
this.connectionString = connectionString;
this.connectionConfig.connectionString = connectionString;

@@ -61,6 +122,9 @@ this.reuseConnections = REUSE_CONNECTIONS_DEFAULT;

this.shrink = SHRINK_DEFAULT;
this.connectionTimeout = CONNECTION_TIMEOUT_DEFAULT;
this.loginTimeout = LOGIN_TIMEOUT_DEFAULT;
} else if (typeof connectionString === 'object') {
this.connectionConfig.connectionTimeout = CONNECTION_TIMEOUT_DEFAULT;
this.connectionConfig.loginTimeout = LOGIN_TIMEOUT_DEFAULT;
}
// connectionString is an object, so ensure that connectionString is a
// property on that object and then copy over any configuration options.
else if (typeof connectionString === 'object')
{
const configObject = connectionString;

@@ -70,3 +134,3 @@ if (!Object.prototype.hasOwnProperty.call(configObject, 'connectionString')) {

}
this.connectionString = configObject.connectionString;
this.connectionConfig.connectionString = configObject.connectionString;

@@ -89,7 +153,18 @@ // reuseConnections

// connectionTimeout
this.connectionTimeout = configObject.connectionTimeout !== undefined ? configObject.connectionTimeout : CONNECTION_TIMEOUT_DEFAULT;
this.connectionConfig.connectionTimeout = configObject.connectionTimeout !== undefined ? configObject.connectionTimeout : CONNECTION_TIMEOUT_DEFAULT;
// loginTimeout
this.loginTimeout = configObject.loginTimeout !== undefined ? configObject.loginTimeout : LOGIN_TIMEOUT_DEFAULT;
} else {
this.connectionConfig.loginTimeout = configObject.loginTimeout !== undefined ? configObject.loginTimeout : LOGIN_TIMEOUT_DEFAULT;
// connectingQueueMax
// unlike other configuration values, this one is set statically on the
// ConnectionQueue object and not on the Pool intance
if (configObject.maxActivelyConnecting !== undefined)
{
ConnectionQueue.maxActivelyConnecting = configObject.maxActivelyConnecting
}
}
// connectionString was neither a string nor and object, so throw an error.
else
{
throw TypeError('Pool constructor must passed a connection string or a configuration object');

@@ -99,5 +174,2 @@ }

// TODO: Documentation
// TODO: Does this need to be async?
// returns a open connection, ready to use.

@@ -114,7 +186,7 @@ // should overwrite the 'close' function of the connection, and rename it is 'nativeClose', so

// equal to the number of connections connecting, and the number of
// connections in the pool, in the process of connecting and that will be
// connections in the pool, in the process of connecting, and that will be
// added is less than the maximum number of allowable connections, then
// we will need to create MORE connections.
if (this.connectingCount <= this.connectionQueue.length &&
this.poolSize + this.connectingCount + this.incrementSize <= this.maxSize)
if (this.connectionsBeingCreatedCount <= this.waitingConnectionWork.length &&
this.poolSize + this.connectionsBeingCreatedCount + this.incrementSize <= this.maxSize)
{

@@ -124,2 +196,6 @@ this.increasePoolSize(this.incrementSize);

// If no callback was provided when connect was called, we need to create
// a promise to return back. We also need to save off the resolve function
// of that promises callback, so that we can call it to resolve the
// function we returned
if (typeof callback == 'undefined') {

@@ -135,9 +211,21 @@ let resolveConnectionPromise;

}
this.connectionQueue.unshift(promiseObj);
// push the promise onto the waitingConnectionWork queue, then return
// it to the user
this.waitingConnectionWork.push(promiseObj);
return promise;
} else {
this.connectionQueue.unshift(callback)
}
// If a callback was provided, we can just add that to the
// waitingConnectionWork queue, then return undefined to the user. Their
// callback will execute when a connection is ready
else
{
this.waitingConnectionWork.push(callback)
return undefined;
}
} else {
}
// Else, there was a free connection available for the user, so either
// return an immediately resolved promise, or call their callback
// immediately.
else
{
connection = this.freeConnections.pop();

@@ -261,74 +349,63 @@

// odbc.connect runs on an AsyncWorker, so this is truly non-blocking
async increasePoolSize(count) {
this.connectingCount += count;
const connectionConfig = {
connectionString: this.connectionString,
connectionTimeout: this.connectionTimeout,
loginTimeout: this.loginTimeout,
};
return new Promise(async (resolve, reject) => {
const connectArray = [];
for (let i = 0; i < count; i += 1) {
let promise = new Promise((resolve, reject) => {
odbc.connect(connectionConfig, (error, nativeConnection) => {
this.connectingCount--;
if (error) {
reject(error);
return;
}
generateConnectPromise = function(connectionConfig) {
return new Promise((resolve, reject) => {
odbc.connect(connectionConfig, (error, nativeConnection) => {
if (error) {
reject(error);
return;
}
this.poolSize++;
let connection = new Connection(nativeConnection);
connection.nativeClose = connection.close;
this.pool.connectionsBeingCreatedCount--;
this.pool.poolSize++;
let connection = new Connection(nativeConnection);
connection.nativeClose = connection.close;
if (this.reuseConnections) {
connection.close = async (closeCallback = undefined) => {
this.connectionEmitter.emit('connected', connection);
if (this.pool.reuseConnections) {
connection.close = async (closeCallback = undefined) => {
this.pool.connectionEmitter.emit('connected', connection);
if (typeof closeCallback === 'undefined') {
return new Promise((resolve, reject) => {
resolve();
})
}
if (typeof closeCallback === 'undefined') {
return new Promise((resolve, reject) => {
resolve();
})
}
return closeCallback(null);
};
} else {
connection.close = async (closeCallback = undefined) => {
this.increasePoolSize(1);
if (typeof closeCallback === 'undefined') {
return new Promise((resolve, reject) => {
connection.nativeClose((error, result) => {
this.poolSize--;
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
connection.nativeClose(closeCallback);
}
return closeCallback(null);
};
} else {
connection.close = async (closeCallback = undefined) => {
this.pool.increasePoolSize(1);
if (typeof closeCallback === 'undefined') {
return new Promise((resolve, reject) => {
connection.nativeClose((error, result) => {
this.pool.poolSize--;
if (error) {
reject(error);
} else {
resolve(result);
}
});
});
}
connection.nativeClose(closeCallback);
}
}
this.connectionEmitter.emit('connected', connection);
resolve();
});
});
connectArray.push(promise);
}
if (connectArray.length > 0)
{
await Promise.race(connectArray);
this.pool.connectionEmitter.emit('connected', connection);
resolve();
} else {
resolve();
}
});
});
}
// odbc.connect runs on an AsyncWorker, so this is truly non-blocking
async increasePoolSize(count) {
this.connectionsBeingCreatedCount += count;
for (let i = 0; i < count; i++)
{
ConnectionQueue.enqueue(this, this.generateConnectPromise, this.connectionConfig);
}
}
}
module.exports.Pool = Pool;
{
"name": "odbc",
"description": "unixodbc bindings for node",
"version": "2.4.0-beta.1",
"version": "2.4.0-beta.2",
"homepage": "http://github.com/markdirish/node-odbc/",

@@ -41,5 +41,5 @@ "main": "lib/odbc.js",

"dependencies": {
"@mapbox/node-pre-gyp": "^1.0.5",
"async": "^3.0.1",
"node-addon-api": "^3.0.2",
"node-pre-gyp": "^0.15.0"
"node-addon-api": "^3.0.2"
},

@@ -52,3 +52,3 @@ "gypfile": true,

"eslint-plugin-import": "^2.16.0",
"mocha": "^5.2.0"
"mocha": "^8.4.0"
},

@@ -55,0 +55,0 @@ "binary": {

@@ -1,9 +0,11 @@

node-odbc
---------
# odbc
An asynchronous interface for Node.js to unixODBC and its supported drivers.
requirements
------------
---
## Requirements
* unixODBC binaries and development libraries for module compilation

@@ -16,10 +18,16 @@ * on Ubuntu/Debian `sudo apt-get install unixodbc unixodbc-dev`

* on IBM i `yum install unixODBC unixODBC-devel` (requires [yum](http://ibm.biz/ibmi-rpms))
* odbc drivers for target database
* ODBC drivers for target database
* properly configured odbc.ini and odbcinst.ini.
install
-------
---
`node-odbc` is an ODBC database interface for Node.js. It allows connecting to any database management system if the system has been correctly configured, including installing of unixODBC and unixODBC-devel packages, installing an ODBC driver for your desired database, and configuring your odbc.ini and odbcinst.ini files. By using an ODBC, and it makes remote development a breeze through the use of ODBC data sources, and switching between DBMS systems is as easy as modifying your queries, as all your code can stay the same.
## Node.js Version Support
This package is a native addon, built with C++ code using `node-addon-api`, a C++ wrapper for [N-API](https://nodejs.org/api/n-api.html). `node-addon-api` only supports versions of Node.js that are in LTS or newer. [A list of supported versions can be found on the Node.js website](https://nodejs.org/en/about/releases/). Current versions supported include:
* Node.js 10
* Node.js 12
* Node.js 14
* Node.js 15
---

@@ -50,2 +58,23 @@

## Debugging
This package used to contain its own method of tracing ODBC calls, which was enabled by recompiling the package with `DEBUG` defined. Because this information was almost wholly redundant with existing methods of tracing available through ODBC driver managers, it was removed in v2.4.0.
Instead, tracing should be enabled through your driver manager, and that information can be analyzed and included with the description of issues encountered.
* **unixODBC (Linux, MacOS, IBM i):**
In your `odbcinst.ini` file, add the following entry:
```
[ODBC]
Trace=yes
TraceFile=/tmp/odbc.log
```
Debug information will be appended to the trace file.
* **ODBC Data Source Administrator (Windows):**
Open up ODBC Data Source Administrator and select the "Tracing" tab. Enter the location where you want the log file to go in **"Log File Path"**, then click **"Start Tracing Now"**.
---
## Drivers

@@ -1057,3 +1086,3 @@

* Copyright (c) 2019 IBM
* Copyright (c) 2019, 2021 IBM
* Copyright (c) 2013 Dan VerWeire <dverweire@gmail.com>

@@ -1060,0 +1089,0 @@ * Copyright (c) 2010 Lee Smith <notwink@gmail.com>

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc