npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mimersql/node-mimer

v1.0.2

Published

Node.js bindings for Mimer SQL using Mimer API

Readme

node-mimer

Node.js driver for Mimer SQL using the Mimer SQL C API.

Features

  • Native C++ bindings to the Mimer SQL C API via Node-API — no ODBC required
  • Prebuilt binaries for supported platforms — no compiler needed at install time
  • Promise-based API
  • Parameterized queries with ? placeholders (SQL injection safe)
  • Prepared statements for repeated execution
  • Result metadata with column names, types, and nullability
  • Support for all major Mimer SQL data types (including BLOB, NCLOB, UUID)
  • Transaction support (commit/rollback)
  • Structured error objects with Mimer error codes
  • Cursor support for streaming large result sets (for await)
  • Connection pooling with automatic acquire/release

Prerequisites

  • Node.js 18.0 or later
  • Mimer SQL 11.0 or later installed (the libmimerapi shared library must be available)

Installation

npm install @mimersql/node-mimer

Prebuilt binaries are included for supported platforms (linux-x64, linux-arm64, darwin-x64, darwin-arm64, win32-x64). On other platforms, the install script will compile from source using node-gyp (requires a C++ compiler and Mimer SQL development headers).

Verifying Mimer SQL is found

npm run check-mimer

Platform-specific library locations

Linux: libmimerapi.so (found via the standard library search path)

macOS: /usr/local/lib/libmimerapi.dylib

Windows: Automatically detected via MIMER_HOME environment variable, Windows Registry, or Program Files scan (highest version wins).

Usage

Basic Example

const { connect } = require('@mimersql/node-mimer');

async function example() {
  // Connect to database
  const client = await connect({
    dsn: 'mydb',
    user: 'SYSADM',
    password: 'password'
  });

  // Execute a query
  const result = await client.query('SELECT * FROM my_table');
  console.log(result.rows);

  // Close connection
  await client.close();
}

example();

Using Transactions

const { MimerClient } = require('@mimersql/node-mimer');

async function transactionExample() {
  const client = new MimerClient();

  try {
    await client.connect({
      dsn: 'mydb',
      user: 'SYSADM',
      password: 'password'
    });

    // Start transaction
    await client.beginTransaction();

    // Execute multiple statements
    await client.query("INSERT INTO accounts VALUES (1, 1000)");
    await client.query("INSERT INTO accounts VALUES (2, 500)");

    // Commit transaction
    await client.commit();

  } catch (error) {
    // Rollback on error
    await client.rollback();
    throw error;
  } finally {
    await client.close();
  }
}

Parameterized Queries

Use ? placeholders to pass parameters safely. This prevents SQL injection and lets the database optimize execution.

// INSERT with parameters
await client.query('INSERT INTO users VALUES (?, ?)', [1, 'Anna']);

// SELECT with a WHERE parameter
const result = await client.query(
  'SELECT * FROM users WHERE id = ?', [1]
);

// Multiple types are supported
await client.query(
  'INSERT INTO readings VALUES (?, ?, ?, ?)',
  [42, 'sensor-1', 3.14, true]
);

// NULL values
await client.query(
  'INSERT INTO users VALUES (?, ?)', [2, null]
);

Parameter types are mapped automatically:

| JavaScript type | Mimer SQL binding | |-----------------|-------------------| | number (integer) | INTEGER or BIGINT | | number (decimal) | DOUBLE PRECISION | | string | VARCHAR / NVARCHAR | | boolean | BOOLEAN | | null / undefined | NULL | | Buffer | BINARY / BLOB |

Prepared Statements

For statements executed multiple times with different parameters, prepared statements avoid re-parsing the SQL on each call.

// Prepare once
const stmt = await client.prepare('INSERT INTO users VALUES (?, ?)');

// Execute many times with different parameters
await stmt.execute([1, 'Anna']);
await stmt.execute([2, 'Fredrik']);
await stmt.execute([3, 'Charlie']);

// Always close when done to release database resources
await stmt.close();

Prepared SELECT statements work the same way:

const stmt = await client.prepare(
  'SELECT * FROM users WHERE id = ?'
);

const r1 = await stmt.execute([1]);
console.log(r1.rows); // [{ id: 1, name: 'Anna' }]

const r2 = await stmt.execute([2]);
console.log(r2.rows); // [{ id: 2, name: 'Fredrik' }]

await stmt.close();

Cursors (Streaming Large Result Sets)

For large result sets, queryCursor() returns a cursor that fetches rows one at a time instead of loading everything into memory. The cursor implements the async iterator protocol, so you can use for await...of.

const cursor = await client.queryCursor('SELECT * FROM big_table');

for await (const row of cursor) {
  console.log(row);
  if (someDoneCondition) break;  // early exit closes the cursor automatically
}

You can also iterate manually with next() and close():

const cursor = await client.queryCursor(
  'SELECT * FROM orders WHERE status = ?', ['pending']
);

// Column metadata is available immediately
console.log(cursor.fields);
// [{ name: 'id', dataTypeCode: 50, dataTypeName: 'INTEGER', nullable: true }, ...]

let row;
while ((row = await cursor.next()) !== null) {
  process(row);
}
// cursor closes automatically when exhausted, or call cursor.close() to stop early

queryCursor() only accepts SELECT statements. DDL and DML statements are rejected with an error.

Connection Pool

For applications that need concurrent database access, the connection pool manages a set of reusable connections — lending them out on demand and returning them when done.

const { createPool } = require('@mimersql/node-mimer');

const pool = createPool({
  dsn: 'mydb',
  user: 'SYSADM',
  password: 'password',
  max: 10,               // maximum connections (default 10)
  idleTimeout: 30000,    // ms before idle connection is closed (default 30s)
  acquireTimeout: 5000,  // ms to wait for a connection (default 5s)
});

// Convenience — auto-acquires and releases a connection
const result = await pool.query('SELECT * FROM t WHERE id = ?', [1]);

// Cursor — connection held until cursor closes
const cursor = await pool.queryCursor('SELECT * FROM big_table');
for await (const row of cursor) { ... }
// connection auto-released when cursor closes or exhausts

// Explicit checkout — for transactions or multiple operations
const client = await pool.connect();
try {
  await client.beginTransaction();
  await client.query('INSERT INTO t VALUES (?, ?)', [1, 'a']);
  await client.commit();
} finally {
  client.release();   // return to pool (NOT client.close())
}

// Shutdown — closes all connections
await pool.end();

Result Metadata

SELECT queries return a fields array with column metadata alongside rows. This is available even when the query returns zero rows, letting you discover column names and types without needing actual data.

const result = await client.query('SELECT id, name FROM users');

console.log(result.fields);
// [
//   { name: 'id',   dataTypeCode: 50, dataTypeName: 'INTEGER', nullable: true },
//   { name: 'name', dataTypeCode: 63, dataTypeName: 'NVARCHAR',    nullable: false }
// ]

console.log(result.rows);
// [{ id: 1, name: 'Anna' }, ...]

Each field object contains:

| Property | Type | Description | |----------|------|-------------| | name | string | Column name | | dataTypeCode | number | Numeric Mimer type code | | dataTypeName | string | Human-readable SQL type (INTEGER, DOUBLE PRECISION, BOOLEAN, etc.) | | nullable | boolean | Whether the column allows NULL values |

Zero-row results still include full metadata:

const result = await client.query('SELECT * FROM users WHERE 1 = 0');
console.log(result.rowCount);       // 0
console.log(result.fields.length);  // 2 — column info is still available
console.log(result.fields[0].name); // 'id'

DML statements (INSERT, UPDATE, DELETE) do not return fields — only rowCount.

Prepared statements also return fields on each execute():

const stmt = await client.prepare('SELECT * FROM users WHERE id = ?');
const result = await stmt.execute([1]);
console.log(result.fields[0].dataTypeName); // 'INTEGER'
await stmt.close();

Error Handling

All errors from the Mimer SQL C API are thrown as JavaScript Error objects with structured properties:

try {
  await client.query('INSERT INTO nonexistent VALUES (1)');
} catch (err) {
  console.log(err.message);   // Human-readable description
  console.log(err.mimerCode);  // Numeric Mimer error code (e.g. -12200)
  console.log(err.operation);  // C API function that failed (e.g. "MimerExecute")
}

This lets you handle specific error conditions programmatically:

try {
  await client.query('CREATE TABLE t1 (id INTEGER)');
} catch (err) {
  if (err.mimerCode === -12517) {
    // Table already exists — ignore
  } else {
    throw err;
  }
}

Parameter binding errors also include structured properties:

try {
  // Wrong number of parameters
  await client.query('INSERT INTO users VALUES (?, ?)', [1]);
} catch (err) {
  console.log(err.mimerCode);  // 0 (validation error, not from Mimer API)
  console.log(err.operation);  // "BindParameters"
}

Data Type Mapping

| Mimer SQL Type | JavaScript Type | |----------------|-----------------| | INTEGER, SMALLINT | Number | | BIGINT | Number | | FLOAT, REAL, DOUBLE | Number | | VARCHAR, NVARCHAR | String | | CHARACTER, NCHAR | String | | DATE, TIME, TIMESTAMP | String | | DECIMAL, NUMERIC | String | | UUID | String | | BINARY, VARBINARY | Buffer | | BLOB | Buffer | | CLOB, NCLOB | String | | BOOLEAN | Boolean | | NULL | null |

API Reference

MimerClient

async connect(options)

Connect to a Mimer SQL database.

Parameters:

  • options.dsn (string): Database name
  • options.user (string): Username
  • options.password (string): Password

async query(sql, params)

Execute a SQL statement with optional parameter binding.

Parameters:

  • sql (string): SQL statement, may contain ? placeholders
  • params (array, optional): Values to bind to ? placeholders

Returns: Result object:

  • For SELECT: { rows, rowCount, fields }fields is an array of column metadata
  • For DML (INSERT/UPDATE/DELETE): { rowCount }
  • For DDL (CREATE/DROP/ALTER): { rowCount: 0 }

async prepare(sql)

Prepare a SQL statement for repeated execution.

Parameters:

  • sql (string): SQL statement with ? placeholders

Returns: PreparedStatement instance

PreparedStatement

async execute(params)

Execute the prepared statement with parameter values.

Parameters:

  • params (array, optional): Values to bind to ? placeholders

Returns: Result object:

  • For SELECT statements: { rows, rowCount, fields }
  • For DML statements: { rowCount }

async close()

Close the prepared statement and release its database resources. The statement cannot be used after calling close().

async queryCursor(sql, params)

Execute a SELECT query and return a cursor for row-at-a-time streaming.

Parameters:

  • sql (string): SELECT statement, may contain ? placeholders
  • params (array, optional): Values to bind to ? placeholders

Returns: ResultSet instance

Throws: Error if sql is a DDL or DML statement.

ResultSet

Returned by queryCursor(). Fetches rows one at a time from an open database cursor. Implements Symbol.asyncIterator for for await...of.

fields

Column metadata array (same format as query() results). Available immediately after creation.

async next()

Fetch the next row as a plain object, or null when all rows have been read. The cursor closes automatically when exhausted.

async close()

Close the cursor and release database resources. Safe to call multiple times. Called automatically when for await...of ends or breaks.

async beginTransaction()

Begin a new transaction.

async commit()

Commit the current transaction.

async rollback()

Rollback the current transaction.

async close()

Close the database connection.

isConnected()

Check if connected to database.

Returns: boolean

Pool

createPool(options)

Create a new connection pool.

Parameters:

  • options.dsn (string): Database name
  • options.user (string): Username
  • options.password (string): Password
  • options.max (number, optional): Maximum connections (default 10)
  • options.idleTimeout (number, optional): Ms before idle connection is closed (default 30000)
  • options.acquireTimeout (number, optional): Ms to wait for a connection (default 5000)

Returns: Pool instance

async pool.query(sql, params)

Acquire a connection, execute the query, and release the connection.

Returns: Result object (same as MimerClient.query())

async pool.queryCursor(sql, params)

Acquire a connection and open a cursor. The connection is automatically released when the cursor closes or is exhausted.

Returns: ResultSet instance

async pool.connect()

Check out a connection for multiple operations (e.g. transactions).

Returns: PoolClient instance

async pool.end()

Close all idle connections and reject pending waiters. Operations after end() will reject with an error.

PoolClient

Returned by pool.connect(). Delegates query(), queryCursor(), prepare(), beginTransaction(), commit(), and rollback() to the underlying MimerClient.

release()

Return the connection to the pool. Always call this instead of close(). Safe to call multiple times.

Helper Functions

async connect(options)

Create and connect a new MimerClient instance.

Returns: Connected MimerClient instance

Testing

Tests use the Node.js built-in test runner (node:test) and are split into focused files by category:

test/
  helper.js                        # Shared utilities (createClient, dropTable)
  connection.test.js               # Connect, isConnected, close
  basic-queries.test.js            # DDL, DML, SELECT
  transactions.test.js             # beginTransaction, commit, rollback
  result-metadata.test.js          # fields array, properties, edge cases
  unicode.test.js                  # NVARCHAR round-trip, Unicode WHERE
  parameterized-queries.test.js    # ? params, types, NULL, mismatch error
  prepared-statements.test.js      # prepare/execute/close lifecycle
  cursor.test.js                   # queryCursor, for-await-of, early break
  error-handling.test.js           # Structured errors (mimerCode, operation)
  pool.test.js                     # Connection pool, PoolClient, auto-release
# Run all tests (requires a running Mimer SQL instance)
npm test

# Run a single test file
node --test test/unicode.test.js

Architecture

Application (JavaScript)
        |
        | require('@mimersql/node-mimer')
        v
JavaScript Wrapper (Promise-based)
  index.js, lib/client.js, lib/prepared.js,
  lib/resultset.js, lib/pool.js
        |
        | lib/native.js (loads native addon)
        v
C++ Native Addon (Node-API)
  src/connection.cc, src/statement.cc,
  src/resultset.cc, src/helpers.cc
        |
        | C API calls
        v
Mimer SQL C API (libmimerapi.so)
        |
        v
Mimer SQL Database

The package ships prebuilt .node binaries for supported platforms via prebuildify. At install time, prebuild-install downloads the matching binary. If no prebuilt is available, the addon is compiled from source using node-gyp. The native addon uses Node-API (N-API v8), so binaries are stable across Node.js versions without recompilation.

Mimer SQL C API Functions Used

  • MimerBeginSession8() - Establish database connection
  • MimerEndSession() - Close connection
  • MimerBeginStatement8() - Prepare SQL statements
  • MimerExecuteStatement8() - Execute DDL statements directly
  • MimerOpenCursor() / MimerFetch() - Fetch result rows
  • MimerGetString8(), MimerGetInt32(), etc. - Get column values
  • MimerSetString8(), MimerSetInt32(), etc. - Bind parameter values
  • MimerSetLob() / MimerSetBlobData() / MimerSetNclobData8() - Write LOBs
  • MimerGetLob() / MimerGetBlobData() / MimerGetNclobData8() - Read LOBs
  • MimerBeginTransaction() / MimerEndTransaction() - Transaction control
  • MimerGetError8() - Error handling

File Structure

node-mimer/
├── src/                          # C++ native addon
│   ├── mimer_addon.cc           # Module entry point
│   ├── connection.cc/h          # Connection class
│   ├── statement.cc/h           # Prepared statement class
│   ├── resultset.cc/h           # Cursor/streaming result set class
│   └── helpers.cc/h             # Parameter binding, row fetching, errors
│
├── lib/                          # JavaScript modules
│   ├── native.js                # Loads native addon via node-gyp-build
│   ├── client.js                # MimerClient, connect()
│   ├── prepared.js              # PreparedStatement
│   ├── resultset.js             # ResultSet (cursor wrapper)
│   └── pool.js                  # Pool, PoolClient
│
├── prebuilds/                    # Prebuilt binaries (per platform)
│   └── linux-x64/               # Example: Linux x64 binary
│
├── scripts/
│   ├── check-mimer.js           # Verify Mimer installation
│   └── find-mimer-windows.js    # Auto-detect Mimer on Windows
│
├── binding.gyp                   # Native addon build configuration
├── index.js                      # Re-exports from lib/
├── index.d.ts                    # TypeScript type definitions
├── package.json
├── README.md
│
└── test/
    ├── helper.js                # Shared test utilities
    └── *.test.js                # Test suites (node:test)

License

MIT

Contributing

Contributions are welcome! Please submit pull requests or open issues on GitHub.

References