@libsql/sqlite3
Version:
node-sqlite3-compatible API for libSQL
212 lines (211 loc) • 7.13 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Statement = void 0;
const node_buffer_1 = require("node:buffer");
const node_events_1 = require("node:events");
const hrana = __importStar(require("@libsql/hrana-client"));
class Statement extends node_events_1.EventEmitter {
#database;
#stmt;
lastID;
changes;
/** @private */
constructor(database, sql) {
super();
this.#database = database;
this.#stmt = new hrana.Stmt(sql);
this.lastID = NaN;
this.changes = 0;
}
bind(...args) {
this.#stmt.unbindAll();
const callback = bindArgs(this.#stmt, args);
this.#database._enqueue(() => Promise.resolve(null).then(callback));
return this;
}
reset(callback) {
this.#database._enqueue(() => Promise.resolve(null).then(callback));
return this;
}
finalize(callback) {
this.#database._enqueue(() => Promise.resolve(null).then(callback));
return this.#database;
}
run(...args) {
const callback = bindArgs(this.#stmt, args);
this.#database._enqueueStream((stream) => stream.run(this.#stmt)
.then((stmtResult) => {
this.#setRunResult(stmtResult);
if (callback !== undefined) {
callback.apply(this, [null]);
}
})
.catch((e) => {
if (callback !== undefined) {
callback.apply(this, [e]);
}
}));
return this;
}
get(...args) {
const callback = bindArgs(this.#stmt, args);
this.#database._enqueueStream((stream) => stream.queryRow(this.#stmt)
.then((rowResult) => {
this.#setRunResult(rowResult);
if (callback !== undefined) {
callback.apply(this, [null, rowResult.row]);
}
})
.catch((e) => {
if (callback !== undefined) {
callback.apply(this, [e]);
}
}));
return this;
}
all(...args) {
const callback = bindArgs(this.#stmt, args);
this.#database._enqueueStream((stream) => stream.query(this.#stmt)
.then((rowsResult) => {
this.#setRunResult(rowsResult);
if (callback !== undefined) {
callback.apply(this, [null, rowsResult.rows]);
}
})
.catch((e) => {
if (callback !== undefined) {
callback.apply(this, [e, []]);
}
}));
return this;
}
map(...args) {
const callback = bindArgs(this.#stmt, args);
this.#database._enqueueStream((stream) => stream.query(this.#stmt)
.then((rowsResult) => {
this.#setRunResult(rowsResult);
if (callback !== undefined) {
const resultObj = mapRowsToObject(rowsResult);
callback.apply(this, [null, resultObj]);
}
})
.catch((e) => {
if (callback !== undefined) {
callback.apply(this, [e, []]);
}
}));
return this;
}
each(...args) {
let completeCallback;
if (args.length >= 2 && typeof args[args.length - 1] === "function" &&
typeof args[args.length - 2] == "function") {
completeCallback = args.pop();
}
const rowCallback = bindArgs(this.#stmt, args);
this.#database._enqueueStream((stream) => stream.query(this.#stmt)
.then((rowsResult) => {
this.#setRunResult(rowsResult);
if (rowCallback !== undefined) {
for (const row of rowsResult.rows) {
rowCallback.apply(this, [null, row]);
}
}
if (completeCallback !== undefined) {
completeCallback(null, rowsResult.rows.length);
}
})
.catch((e) => {
if (rowCallback !== undefined) {
rowCallback.apply(this, [e, []]);
}
if (completeCallback !== undefined) {
completeCallback(e, 0);
}
}));
return this;
}
#setRunResult(result) {
this.lastID = +(result.lastInsertRowid ?? "NaN");
this.changes = result.affectedRowCount;
}
}
exports.Statement = Statement;
// this logic is taken from `Statement::Bind` in `node-sqlite3/src/statement.cc`
function bindArgs(stmt, args) {
let callback = undefined;
if (args.length > 0 && typeof args[args.length - 1] === "function") {
callback = args.pop();
}
if (args.length > 0) {
stmt.unbindAll();
const arg0 = args[0];
if (Array.isArray(arg0)) {
for (let i = 0; i < arg0.length; ++i) {
if (arg0[i] !== undefined) {
stmt.bindIndex(i + 1, arg0[i]);
}
}
}
else if (typeof arg0 !== "object" || arg0 instanceof RegExp
|| arg0 instanceof Date || node_buffer_1.Buffer.isBuffer(arg0)) {
for (let i = 0; i < args.length; ++i) {
if (args[i] !== undefined) {
stmt.bindIndex(i + 1, args[i]);
}
}
}
else if (typeof arg0 === "object") {
for (let name in arg0) {
if (arg0[name] !== undefined) {
stmt.bindName(name, arg0[name]);
}
}
}
else {
throw new TypeError("Unsupported type of argument");
}
}
return callback;
}
function mapRowsToObject(rowsResult) {
const resultObj = {};
const columnCount = rowsResult.columnNames.length;
rowsResult.rows.forEach((row) => {
let value;
if (columnCount === 2) {
value = row[1];
}
else if (columnCount === 1) {
value = undefined;
}
else {
value = row;
}
resultObj[row[0]] = value;
});
return resultObj;
}