/**
* @file connection.js is the file for the Connection class. Connection
* is used to interact with a Database instance.
*/
"use strict";
const KuzuWasm = require("./kuzu.js");
const QueryResult = require("./query_result.js");
const PreparedStatement = require("./prepared_statement.js");
class Connection {
/**
* Initialize a new Connection object.
*
* @param {kuzu.sync.Database} database the database object to connect to.
* @param {Number} numThreads the maximum number of threads to use for query
* execution.
*/
constructor(database, numThreads = null) {
KuzuWasm.checkInit();
const kuzu = KuzuWasm._kuzu;
if (!database || typeof database !== "object") {
throw new Error("Database must be an object.");
}
if (database._isClosed) {
throw new Error("Database is already closed.");
}
numThreads = parseInt(numThreads);
this._connection = new kuzu.Connection(database._database);
if (numThreads && numThreads > 0) {
this._connection.setMaxNumThreadForExec(numThreads);
}
this._isClosed = false;
}
/**
* Internal function to check if the connection is closed.
* @throws {Error} if the connection is closed.
* @private
*/
_checkConnection() {
KuzuWasm.checkInit();
if (this._isClosed) {
throw new Error("Connection is already closed.");
}
}
/**
* Set the maximum number of threads to use for query execution.
* @param {Number} numThreads the maximum number of threads to use for query
* execution.
* @throws {Error} if the connection is closed.
* @throws {Error} if numThreads is not a positive integer.
*/
setMaxNumThreadForExec(numThreads) {
this._checkConnection();
this._connection.setMaxNumThreadForExec(numThreads);
this._numThreads = numThreads;
}
/**
* Set the query timeout in milliseconds.
* @param {Number} timeout the query timeout in milliseconds.
* @throws {Error} if the connection is closed.
* @throws {Error} if timeout is not a positive integer.
*/
setQueryTimeout(timeout) {
this._checkConnection();
this._connection.setQueryTimeout(timeout);
}
/**
* Get the maximum number of threads to use for query execution.
* @returns {Number} the maximum number of threads to use for query execution.
* @throws {Error} if the connection is closed.
*/
getMaxNumThreadForExec() {
this._checkConnection();
return this._connection.getMaxNumThreadForExec();
}
/**
* Execute a query.
* @param {String} statement the statement to execute.
* @returns {kuzu.sync.QueryResult} the query result.
* @throws {Error} if the connection is closed.
* @throws {Error} if statement is not a string.
*/
query(statement) {
this._checkConnection();
if (typeof statement !== "string") {
throw new Error("Statement must be a string.");
}
const _queryResult = this._connection.query(statement);
return new QueryResult(_queryResult);
}
/**
* Prepare a statement for execution.
* @param {String} statement the statement to prepare.
* @returns {Promise<kuzu.sync.PreparedStatement>} the prepared statement.
*/
prepare(statement) {
this._checkConnection();
if (typeof statement !== "string") {
throw new Error("Statement must be a string.");
}
const _preparedStatement = this._connection.prepare(statement);
return new PreparedStatement(_preparedStatement);
}
/**
* Execute a prepared statement.
* @param {kuzu.sync.PreparedStatement} preparedStatement the prepared
* statement to execute.
* @param {Object} params a plain object mapping parameter names to values.
* @returns {kuzu.sync.QueryResult} the query result.
* @throws {Error} if the connection is closed.
* @throws {Error} if preparedStatement is not a valid PreparedStatement
* object.
* @throws {Error} if preparedStatement is not successful.
* @throws {Error} if params is not a plain object.
*/
execute(preparedStatement, params = {}) {
this._checkConnection();
if (!preparedStatement ||
typeof preparedStatement !== "object" ||
preparedStatement.constructor.name !== "PreparedStatement" ||
preparedStatement._isClosed) {
throw new Error("preparedStatement must be a valid PreparedStatement object.");
}
if (!preparedStatement.isSuccess()) {
throw new Error(preparedStatement.getErrorMessage());
}
if (params.constructor.name !== "Object") {
throw new Error("params must be a plain object.");
}
const paramsArray = [];
for (const key in params) {
paramsArray.push({
name: key,
value: params[key]
});
}
const _queryResult = this._connection.execute(preparedStatement._statement, paramsArray);
return new QueryResult(_queryResult);
}
/**
* Close the connection.
*/
close() {
if (!this._isClosed) {
this._connection.delete();
this._isClosed = true;
}
}
}
module.exports = Connection;