Skip to content

Releases: TimelordUK/node-sqlserver-v8

Linux x64 support

21 Jul 14:20
Compare
Choose a tag to compare
  1. #51
  2. #163

Note this is a major version release with a large c++ code overhaul to support both windows and Linux. Therefore all production users please test carefully before deployment.

Linux has been tested with version 18.04 and 20.04 Ubuntu on x64 using MS odbc 17.

~/dev/js/sql/node_modules/msnodesqlv8/samples/javascript$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.4 LTS
Release:	18.04
Codename:	bionic
~/dev/js/sql/node_modules/msnodesqlv8/samples/javascript$ node streaming.js 
submitted EXEC sys.sp_helpindex @objname = N'[users]' elapsed 1 ms
meta = [
    {
        "size": 128,
        "name": "index_name",
        "nullable": false,
        "type": "text",
        "sqlType": "nvarchar"
    },
    {
        "size": 210,
        "name": "index_description",
        "nullable": true,
        "type": "text",
        "sqlType": "varchar"
    },
    {
        "size": 2126,
        "name": "index_keys",
        "nullable": true,
        "type": "text",
        "sqlType": "nvarchar"
    }
]
column [0] = "PK__users__3213E83F3A5ED730"
column [1] = "clustered, unique, primary key located on PRIMARY"
column [2] = "id"
done
1 rows returned elapsed 1384
finished
free

v1.1.8: multiple interactions with driver and info messages

12 Jul 17:18
Compare
Choose a tag to compare

v1.1.7

05 Jul 14:25
Compare
Choose a tag to compare
  1. #159
  2. v9 electron native binaries included.

v1.1.6: fix for bulk methods which wrongly callback immediately

07 Jun 13:42
Compare
Choose a tag to compare

v1.1.5

17 May 13:32
Compare
Choose a tag to compare

TVP Date failure

09 May 17:26
Compare
Choose a tag to compare

TVP numeric vector crash

08 May 20:23
Compare
Choose a tag to compare

v1.1.2

26 Apr 11:34
Compare
Choose a tag to compare

Node v 14 released

bulk insert int32/int64 + proc schema on params

10 Apr 16:50
Compare
Choose a tag to compare

connection pool

04 Apr 18:54
Compare
Choose a tag to compare

you can now submit queries through a native library connection pool. This pool creates a set of connections and queues work submitting items such that all connections are busy providing work exists. A keep alive is sent periodically to check connection integrity and idle connections beyond a threshold are closed and re-created when queries submitted at a later point in time. Queries can be cancelled and paused / resumed regardless of where they are in the work lifecycle

examples can be seen here and here

export interface PoolOptions {
    floor: number
    ceiling: number
    heartbeatSecs: number
    heartbeatSql: string
    inactivityTimeoutSecs: number
    connectionString: string
}

const pool = new sql.Pool(options)

the following example shows the pool being used.

const sql = require('msnodesqlv8')

const pool = new sql.Pool({
  connectionString: 'Driver={ODBC Driver 13 for SQL Server};Server=(localdb)\\node;Database=scratch;Trusted_Connection=yes;'
})

pool.on('open', (options) => {
  console.log(`ready options = ${JSON.stringify(options, null, 4)}`)
})

pool.on('debug', msg => {
  console.log(`\t\t\t\t\t\t${new Date().toLocaleTimeString()} <pool.debug> ${msg}`)
})

pool.on('status', s => {
  console.log(`status = ${JSON.stringify(s, null, 4)}`)
})

pool.on('error', e => {
  console.log(e)
})

const testSql = 'waitfor delay \'00:00:10\';'

function submit (sql) {
  const q = pool.query(sql)
  console.log(`send ${new Date().toLocaleTimeString()}, sql = ${sql}`)
  q.on('submitted', d => {
    console.log(`query submitted ${new Date().toLocaleTimeString()}, sql = ${d.query_str}`)
    q.on('done', () => console.log(`query done ${new Date().toLocaleTimeString()}`))
  })
  return q
}

for (let i = 0; i < 7; ++i) {
  const q = submit(testSql)
  switch (i) {
    case 5:
      console.log('cancel a query')
      q.cancelQuery()
      break
    case 6:
      q.pauseQuery()
      setTimeout(() => {
        console.log('resume a paused query')
        q.resumeQuery()
      }, 50000)
      break
    default:
      break
  }
}

setInterval(() => {
  submit(testSql)
}, 60000)

pool.open()
"C:\Program Files\nodejs\node.exe" C:\dev\js\sql\node_modules\msnodesqlv8\samples\javascript\pooling.js
send 20:29:46, sql = waitfor delay '00:00:10';
send 20:29:46, sql = waitfor delay '00:00:10';
send 20:29:46, sql = waitfor delay '00:00:10';
send 20:29:46, sql = waitfor delay '00:00:10';
send 20:29:46, sql = waitfor delay '00:00:10';
send 20:29:46, sql = waitfor delay '00:00:10';
cancel a query
send 20:29:46, sql = waitfor delay '00:00:10';
						20:29:46 <pool.debug> grow creates 4 connections for pool idle = 0, busy = 0, pending = 4
status = {
    "time": "2020-04-04T19:29:46.278Z",
    "parked": 0,
    "idle": 1,
    "busy": 0,
    "pause": 0,
    "workQueue": 7,
    "op": "checkin"
}
						20:29:46 <pool.debug> [0] checkin idle = 1, parked = 0, busy = 0, pause = 0, workQueue = 7
status = {
    "time": "2020-04-04T19:29:46.278Z",
    "parked": 0,
    "idle": 2,
    "busy": 0,
    "pause": 0,
    "workQueue": 7,
    "op": "checkin"
}
						20:29:46 <pool.debug> [1] checkin idle = 2, parked = 0, busy = 0, pause = 0, workQueue = 7
status = {
    "time": "2020-04-04T19:29:46.278Z",
    "parked": 0,
    "idle": 3,
    "busy": 0,
    "pause": 0,
    "workQueue": 7,
    "op": "checkin"
}
						20:29:46 <pool.debug> [2] checkin idle = 3, parked = 0, busy = 0, pause = 0, workQueue = 7
status = {
    "time": "2020-04-04T19:29:46.278Z",
    "parked": 0,
    "idle": 4,
    "busy": 0,
    "pause": 0,
    "workQueue": 7,
    "op": "checkin"
}
						20:29:46 <pool.debug> [3] checkin idle = 4, parked = 0, busy = 0, pause = 0, workQueue = 7
ready options = {
    "floor": 0,
    "ceiling": 4,
    "heartbeatSecs": 20,
    "heartbeatSql": "select @@SPID as spid",
    "inactivityTimeoutSecs": 60,
    "connectionString": "Driver={ODBC Driver 13 for SQL Server};Server=(localdb)\\node;Database=scratch;Trusted_Connection=yes;"
}
status = {
    "time": "2020-04-04T19:29:46.279Z",
    "parked": 0,
    "idle": 3,
    "busy": 1,
    "pause": 0,
    "workQueue": 6,
    "op": "checkout"
}
						20:29:46 <pool.debug> [0] checkout idle = 3, parked = 0, busy = 1, pause = 0, workQueue = 6
						20:29:46 <pool.debug> [0] query work id = 0, workQueue = 6
status = {
    "time": "2020-04-04T19:29:46.280Z",
    "parked": 0,
    "idle": 2,
    "busy": 2,
    "pause": 0,
    "workQueue": 5,
    "op": "checkout"
}
						20:29:46 <pool.debug> [1] checkout idle = 2, parked = 0, busy = 2, pause = 0, workQueue = 5
						20:29:46 <pool.debug> [1] query work id = 1, workQueue = 5
status = {
    "time": "2020-04-04T19:29:46.280Z",
    "parked": 0,
    "idle": 1,
    "busy": 3,
    "pause": 0,
    "workQueue": 4,
    "op": "checkout"
}
						20:29:46 <pool.debug> [2] checkout idle = 1, parked = 0, busy = 3, pause = 0, workQueue = 4
						20:29:46 <pool.debug> [2] query work id = 2, workQueue = 4
status = {
    "time": "2020-04-04T19:29:46.280Z",
    "parked": 0,
    "idle": 0,
    "busy": 4,
    "pause": 0,
    "workQueue": 3,
    "op": "checkout"
}
						20:29:46 <pool.debug> [3] checkout idle = 0, parked = 0, busy = 4, pause = 0, workQueue = 3
						20:29:46 <pool.debug> [3] query work id = 3, workQueue = 3
query submitted 20:29:46, sql = waitfor delay '00:00:10';
						20:29:46 <pool.debug> [0] submitted work id 0
query submitted 20:29:46, sql = waitfor delay '00:00:10';
						20:29:46 <pool.debug> [1] submitted work id 1
query submitted 20:29:46, sql = waitfor delay '00:00:10';
						20:29:46 <pool.debug> [2] submitted work id 2
query submitted 20:29:46, sql = waitfor delay '00:00:10';
						20:29:46 <pool.debug> [3] submitted work id 3
query done 20:29:56
status = {
    "time": "2020-04-04T19:29:56.291Z",
    "parked": 0,
    "idle": 1,
    "busy": 3,
    "pause": 0,
    "workQueue": 3,
    "op": "checkin"
}
						20:29:56 <pool.debug> [0] checkin idle = 1, parked = 0, busy = 3, pause = 0, workQueue = 3
						20:29:56 <pool.debug> [0] free work id 0
query done 20:29:56
status = {
    "time": "2020-04-04T19:29:56.292Z",
    "parked": 0,
    "idle": 2,
    "busy": 2,
    "pause": 0,
    "workQueue": 3,
    "op": "checkin"
}
						20:29:56 <pool.debug> [1] checkin idle = 2, parked = 0, busy = 2, pause = 0, workQueue = 3
						20:29:56 <pool.debug> [1] free work id 1
query done 20:29:56
status = {
    "time": "2020-04-04T19:29:56.293Z",
    "parked": 0,
    "idle": 3,
    "busy": 1,
    "pause": 0,
    "workQueue": 3,
    "op": "checkin"
}
						20:29:56 <pool.debug> [2] checkin idle = 3, parked = 0, busy = 1, pause = 0, workQueue = 3
						20:29:56 <pool.debug> [2] free work id 2
query done 20:29:56
status = {
    "time": "2020-04-04T19:29:56.294Z",
    "parked": 0,
    "idle": 4,
    "busy": 0,
    "pause": 0,
    "workQueue": 3,
    "op": "checkin"
}
						20:29:56 <pool.debug> [3] checkin idle = 4, parked = 0, busy = 0, pause = 0, workQueue = 3
						20:29:56 <pool.debug> [3] free work id 3
status = {
    "time": "2020-04-04T19:29:56.294Z",
    "parked": 0,
    "idle": 3,
    "busy": 1,
    "pause": 0,
    "workQueue": 2,
    "op": "checkout"
}
						20:29:56 <pool.debug> [0] checkout idle = 3, parked = 0, busy = 1, pause = 0, workQueue = 2
						20:29:56 <pool.debug> [0] query work id = 4, workQueue = 2
						20:29:56 <pool.debug> query work id = 5 has been cancelled waiting in pool to execute, workQueue = 1
query submitted 20:29:56, sql = waitfor delay '00:00:10';
						20:29:56 <pool.debug> [0] submitted work id 4
query done 20:30:06
status = {
    "time": "2020-04-04T19:30:06.297Z",
    "parked": 0,
    "idle": 4,
    "busy": 0,
    "pause": 1,
    "workQueue": 0,
    "op": "checkin"
}
						20:30:06 <pool.debug> [0] checkin idle = 4, parked = 0, busy = 0, pause = 1, workQueue = 0
						20:30:06 <pool.debug> [0] free work id 4
status = {
    "time": "2020-04-04T19:30:06.314Z",
    "parked": 0,
    "idle": 3,
    "busy": 1,
    "pause": 1,
    "workQueue": 0,
    "op": "checkout"
}
						20:30:06 <pool.debug> [3] checkout idle = 3, parked = 0, busy = 1, pause = 1, workQueue = 0
status = {
    "time": "2020-04-04T19:30:06.317Z",
    "parked": 0,
    "idle": 4,
    "busy": 0,
    "pause": 1,
    "workQueue": 0,
    "op": "checkin"
}
						20:30:06 <pool.debug> [3] checkin idle = 4, parked = 0, busy = 0, pause = 1, workQueue = 0
						20:30:06 <pool.debug> [3] heartbeat response = '56', 20:30:06, keepAliveCount = 1 inactivePeriod = 20, inactivityTimeoutSecs = 60
status = {
    "time": "2020-04-04T19:30:06.564Z",
    "parked": 0,
    "idle": 3,
    "busy": 1,
    "pause": 1,
    "workQueue": 0,
    "op": "checkout"
}
						20:30:06 <pool.debug> [2] checkout idle = 3, parked = 0, busy = 1, pause = 1, workQueue = 0
status = {
    "time": "2020-04-04T19:30:06.566Z",
    "parked": 0,
    "idle": 4,
    "busy": 0,
    "pause": 1,
    "workQueue": 0,
    "op": "checkin"
}
						20:30:06 <pool.debug> [2] checkin idle = 4, parked = 0, busy = 0, pause = 1, workQueue = 0
						20:30:06 <pool.debug> [2] heartbeat response = '58', 20:30:06, keepAliveCount = 1 inactivePeriod = 20, inactivityTimeoutSecs = 60
status = {
    "time": "2020-04-04T19:30:06.814Z",
    "parked": 0,
    "idle": 3,
    "busy": 1,
    "pause": 1,
    "workQueue": 0,
    "op": "checkout"
}
						20:30:06 <pool.debug> [1] checkout idle = 3, parked = 0, busy = 1, pause = 1, workQueue = 0
status = {
    "time": "2020-04-04T19:30:06.815Z",
    "parked": 0,
    "idle"...
Read more