Repository navigation
Release v5.6.0
What's changed
Fixes
- prints, errors and results after a failed statement in a batch were lost (#475)
- bulk insert / update / delete committed every row separately (#472)
- segv cancelling a non polling query while rows are fetched (#473)
- cancel leaving the connection busy, pause ending queries early, nvarchar output params (#470)
Full Changelog: v5.5.1...v5.6.0
Notes
-
Cancel works on every query (#470, #473). - Ordinary non-polling queries can now be cancelled while they run or stream rows, by cancelQuery, promises.cancel, timeoutMs or the pool.
-
The error always contains Operation canceled, so callers should match on that text rather than the full message.
-
The intermittent Linux segfault is fixed.
-
Bulk insert / update / delete (#472). - About 100x faster. - Each batch is now atomic: a failure rolls the batch back instead of leaving partial rows. - If a transaction is already open, the bulk operation joins it. BCP is unchanged.
-
Errors mid-batch (#475). - Everything after a failed statement is now delivered, including proc output params and the return code. - This is the main thing to warn about: more events and callbacks can arrive after the first error, more stays true until the batch ends, and err._results carries everything collected. - A print that arrives with the final error is no longer dropped. - The Linux/macOS limitation is described.
-
Proc output params (#470): nvarchar, nchar and (max) outputs come back correctly.
-
Pause / resume (#470): pausing part way through a batch of rows no longer ends the query early.
Prebuilt binaries ship inside the npm package
Since 5.5.0 the per-platform N-API binary is bundled in the published
package. There is no download at install time and no compile step on a
supported platform — npm install unpacks the right binary and that is the
whole install.
This means the package installs behind a corporate proxy, from an Artifactory
or Nexus mirror, on an airgapped host, and under npm ci --ignore-scripts.
node_modules/msnodesqlv8/prebuilds/
├── win32-x64/msnodesqlv8.node
├── darwin-arm64/msnodesqlv8.node
└── linux-x64/
├── msnodesqlv8.glibc.node
└── msnodesqlv8.musl.node
The correct file is selected at require time, by platform, architecture and
libc — not pinned at install time. One binary per platform serves every Node
line and every Electron version, because the addon is pure N-API with no V8
ABI coupling.
| Platform | Bundled | Notes |
|---|---|---|
| Windows x64 | yes | |
| Linux x64 (glibc) | yes | built on Ubuntu 22.04, needs glibc 2.35+ |
| Linux x64 (musl) | yes | Alpine, built in node:22-alpine |
| macOS arm64 | yes | Apple Silicon |
| macOS x64 (Intel) | no | compiles from source on install |
| Linux arm64 | no | compiles from source on install |
| Windows arm64 | no | compiles from source on install |
Where there is no bundled binary the install script falls back to a
node-gyp source build, which needs a C++ toolchain and the unixODBC headers.
Runtime requirements: any Node with N-API ≥ 8 (engines: node >=18), and
any Electron with N-API ≥ 8. Electron needs no electron-rebuild and no
Electron-specific artifact.
Installing without any network access
Because the binaries are plain files with predictable names, there are three
ways to place one, in increasing order of scope:
- Normal install —
npm install msnodesqlv8. Works with
--ignore-scripts; nothing is fetched or built. - Global install —
npm install -g msnodesqlv8now succeeds with no
network fetch of a binary. Note that npm's globalnode_modulesis not on
Node's module resolution path, so a project still needsNODE_PATHset to
$(npm root -g)torequireit. - Beside the node executable — drop
prebuilds/<platform>-<arch>/msnodesqlv8.nodenext tonodeitself and
every project on that machine resolves it, with no per-project install.
Sample apps
| description | link |
|---|---|
| Start here: the whole API in one file | msnodesqlv8-api-tour |
| next js example, note cant run driver on UI thread. | todo-with-nextjs_msnodesqlv8 |
| next js example using app router, note cant run driver on UI thread. | todo-with-nextjs-app-router_msnodesqlv8 |
| using vite + express | msnodesqlv8-vite |
| using in typescript | msnodesqlv8_ts_sample |
| js example typings in IDE | msnodesqlv8_yarn_sample |
| using sequelize | msnodesqlv8-sequelize |
| using mssql | msnodesqlv8_mssql_sample |
| using electron | msnodesqlv8-electron |
| using react | msnodesqlv8-react |
Quick start
JavaScript:
const sql = require('msnodesqlv8')
const connectionString = "Driver={ODBC Driver 18 for SQL Server};Server=(localdb)\\node;Database=scratch;Trusted_Connection=yes;"
const query = 'SELECT top 2 * FROM syscolumns'
async function runner () {
const res = await sql.promises.query(connectionString, query)
console.log(JSON.stringify(res, null, 4))
}
runner().then(() => console.log('done.')).catch(e => console.error(e))TypeScript:
import sql from 'msnodesqlv8'
import Connection = MsNodeSqlV8.Connection
import ConnectionPromises = MsNodeSqlV8.ConnectionPromises
async function t () {
const connectionString = "Driver={ODBC Driver 18 for SQL Server};Server=(localdb)\\node;Database=scratch;Trusted_Connection=yes;"
const con: Connection = await sql.promises.open(connectionString)
const promises: ConnectionPromises = con.promises
const res = await promises.query('select @@servername as server')
console.log(JSON.stringify(res, null, 4))
await con.promises.close()
}
t().then(() => console.log('closed'))Feature highlights
Connection pool with transaction support. Pull a connection out of the
pool, keep it busy for the life of a transaction, then commit or roll back and
release it:
pool.beginTransaction(function (err, description) { /* description.connection.query() */ })
pool.commitTransaction(description, function (err) { /* IF (@@TRANCOUNT > 0) COMMIT TRANSACTION */ })
pool.rollbackTransaction(description, function (err) { /* IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION */ })The same methods exist on the promised pool, plus a wrapper that commits on
success and rolls back on a thrown error:
pool.promises.transaction(async function (description) {
await description.connection.promises.query(`Do transaction query here`)
})Pool growth strategies. exponential or gradual, so a burst of queries
does not immediately open connections up to the ceiling:
const pool = new sql.Pool({
connectionString,
ceiling: 10,
scalingStrategy: 'gradual',
scalingIncrement: 3,
scalingDelay: 0
})Detailed logging. Switchable logging across both the JavaScript and C++
layers, to console or to a file, for seeing exactly what the driver is doing:
const sql = require('msnodesqlv8')
sql.logger.setLogLevel(sql.LogLevel.TRACE)
sql.logger.setConsoleLogging(true)
// sql.logger.setLogFile('/var/log/myapp/sql-trace.log')
// sql.logger.configureForDevelopment() // TRACE, console
// sql.logger.configureForProduction('/var/log/myapp') // ERROR, file only
// sql.logger.configureForTesting() // SILENT
// sql.logger.setLogLevel(sql.LogLevel.SILENT) // default for productionMigrating from 4.x
The 4.x → 5.x step is a large change and should be tested carefully before a
production rollout.
- The C++ layer moved from nan to Node-API (N-API).
- Extensive switchable logging was added, to see exactly what the driver is
doing. - Building and testing moved to GitHub Actions.
- Linux support requires glibc 2.35+ (Ubuntu 22.04 or later). Earlier
distributions must build the driver themselves. - As close to a drop-in replacement for 4.x as possible.
- win32 (32-bit Windows) is no longer supported.
- Windows, Linux and macOS are the supported platforms.
- Alpine/musl was originally best-effort and out of scope. As of 5.5.0 a
musl binary is built, smoke tested in CI and shipped in the package.