Backend half
This commit is contained in:
+18
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Ok_Packet
|
||||
* see https://mariadb.com/kb/en/ok_packet/
|
||||
*/
|
||||
class OkPacket {
|
||||
constructor(affectedRows, insertId, warningStatus) {
|
||||
this.affectedRows = affectedRows;
|
||||
this.insertId = insertId;
|
||||
this.warningStatus = warningStatus;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = OkPacket;
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
||||
|
||||
'use strict';
|
||||
|
||||
const PrepareWrapper = require('./prepare-wrapper');
|
||||
|
||||
/**
|
||||
* Prepare cache wrapper
|
||||
* see https://mariadb.com/kb/en/com_stmt_prepare/#com_stmt_prepare_ok
|
||||
*/
|
||||
class PrepareCacheWrapper {
|
||||
#use = 0;
|
||||
#cached;
|
||||
#prepare;
|
||||
|
||||
constructor(prepare) {
|
||||
this.#prepare = prepare;
|
||||
this.#cached = true;
|
||||
}
|
||||
|
||||
incrementUse() {
|
||||
this.#use += 1;
|
||||
return new PrepareWrapper(this, this.#prepare);
|
||||
}
|
||||
|
||||
unCache() {
|
||||
this.#cached = false;
|
||||
if (this.#use === 0) {
|
||||
this.#prepare.close();
|
||||
}
|
||||
}
|
||||
|
||||
decrementUse() {
|
||||
this.#use -= 1;
|
||||
if (this.#use === 0 && !this.#cached) {
|
||||
this.#prepare.close();
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
return 'Prepare{use:' + this.#use + ',cached:' + this.#cached + '}';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PrepareCacheWrapper;
|
||||
+141
@@ -0,0 +1,141 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
||||
|
||||
'use strict';
|
||||
const Errors = require('../../misc/errors');
|
||||
const ExecuteStream = require('../execute-stream');
|
||||
const Parser = require('../parser');
|
||||
|
||||
/**
|
||||
* Prepare result
|
||||
* see https://mariadb.com/kb/en/com_stmt_prepare/#com_stmt_prepare_ok
|
||||
*/
|
||||
class PrepareResultPacket {
|
||||
#conn;
|
||||
constructor(statementId, parameterCount, columns, database, sql, placeHolderIndex, conn) {
|
||||
this.id = statementId;
|
||||
this.parameterCount = parameterCount;
|
||||
this.columns = columns;
|
||||
this.database = database;
|
||||
this.query = sql;
|
||||
this.closed = false;
|
||||
this._placeHolderIndex = placeHolderIndex;
|
||||
this.#conn = conn;
|
||||
}
|
||||
|
||||
get conn() {
|
||||
return this.#conn;
|
||||
}
|
||||
|
||||
execute(values, opts, cb, stack) {
|
||||
let _opts = opts,
|
||||
_cb = cb;
|
||||
|
||||
if (typeof _opts === 'function') {
|
||||
_cb = _opts;
|
||||
_opts = undefined;
|
||||
}
|
||||
|
||||
if (this.isClose()) {
|
||||
let sql = this.query;
|
||||
if (this.conn.opts.logParam) {
|
||||
if (this.query.length > this.conn.opts.debugLen) {
|
||||
sql = this.query.substring(0, this.conn.opts.debugLen) + '...';
|
||||
} else {
|
||||
let sqlMsg = this.query + ' - parameters:';
|
||||
sql = Parser.logParameters(this.conn.opts, sqlMsg, values);
|
||||
}
|
||||
}
|
||||
|
||||
const error = Errors.createError(
|
||||
`Execute fails, prepare command as already been closed`,
|
||||
Errors.ER_PREPARE_CLOSED,
|
||||
null,
|
||||
'22000',
|
||||
sql
|
||||
);
|
||||
|
||||
if (!_cb) {
|
||||
return Promise.reject(error);
|
||||
} else {
|
||||
_cb(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const cmdParam = {
|
||||
sql: this.query,
|
||||
values: values,
|
||||
opts: _opts,
|
||||
callback: _cb
|
||||
};
|
||||
if (stack) cmdParam.stack = stack;
|
||||
const conn = this.conn;
|
||||
const promise = new Promise((resolve, reject) => conn.executePromise.call(conn, cmdParam, this, resolve, reject));
|
||||
if (!_cb) {
|
||||
return promise;
|
||||
} else {
|
||||
promise
|
||||
.then((res) => {
|
||||
if (_cb) _cb(null, res, null);
|
||||
})
|
||||
.catch(_cb || function (err) {});
|
||||
}
|
||||
}
|
||||
|
||||
executeStream(values, opts, cb, stack) {
|
||||
let _opts = opts,
|
||||
_cb = cb;
|
||||
|
||||
if (typeof _opts === 'function') {
|
||||
_cb = _opts;
|
||||
_opts = undefined;
|
||||
}
|
||||
|
||||
if (this.isClose()) {
|
||||
const error = Errors.createError(
|
||||
`Execute fails, prepare command as already been closed`,
|
||||
Errors.ER_PREPARE_CLOSED,
|
||||
null,
|
||||
'22000',
|
||||
this.query
|
||||
);
|
||||
|
||||
if (!_cb) {
|
||||
throw error;
|
||||
} else {
|
||||
_cb(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const cmdParam = {
|
||||
sql: this.query,
|
||||
values: values,
|
||||
opts: _opts,
|
||||
callback: _cb
|
||||
};
|
||||
if (stack) cmdParam.stack = stack;
|
||||
|
||||
const cmd = new ExecuteStream(cmdParam, this.conn.opts, this, this.conn.socket);
|
||||
if (this.conn.opts.logger.error) cmd.on('error', this.conn.opts.logger.error);
|
||||
this.conn.addCommand(cmd, true);
|
||||
return cmd.inStream;
|
||||
}
|
||||
|
||||
isClose() {
|
||||
return this.closed;
|
||||
}
|
||||
|
||||
close() {
|
||||
if (!this.closed) {
|
||||
this.closed = true;
|
||||
this.#conn.emit('close_prepare', this);
|
||||
}
|
||||
}
|
||||
toString() {
|
||||
return 'Prepare{closed:' + this.closed + '}';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PrepareResultPacket;
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
// Copyright (c) 2015-2024 MariaDB Corporation Ab
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Prepare result wrapper
|
||||
* This permit to ensure that cache can be close only one time cache.
|
||||
*/
|
||||
class PrepareWrapper {
|
||||
#closed = false;
|
||||
#cacheWrapper;
|
||||
#prepare;
|
||||
#conn;
|
||||
|
||||
constructor(cacheWrapper, prepare) {
|
||||
this.#cacheWrapper = cacheWrapper;
|
||||
this.#prepare = prepare;
|
||||
this.#conn = prepare.conn;
|
||||
this.execute = this.#prepare.execute;
|
||||
this.executeStream = this.#prepare.executeStream;
|
||||
}
|
||||
get conn() {
|
||||
return this.#conn;
|
||||
}
|
||||
|
||||
get id() {
|
||||
return this.#prepare.id;
|
||||
}
|
||||
|
||||
get parameterCount() {
|
||||
return this.#prepare.parameterCount;
|
||||
}
|
||||
|
||||
get _placeHolderIndex() {
|
||||
return this.#prepare._placeHolderIndex;
|
||||
}
|
||||
|
||||
get columns() {
|
||||
return this.#prepare.columns;
|
||||
}
|
||||
|
||||
set columns(columns) {
|
||||
this.#prepare.columns = columns;
|
||||
}
|
||||
get database() {
|
||||
return this.#prepare.database;
|
||||
}
|
||||
|
||||
get query() {
|
||||
return this.#prepare.query;
|
||||
}
|
||||
|
||||
isClose() {
|
||||
return this.#closed;
|
||||
}
|
||||
|
||||
close() {
|
||||
if (!this.#closed) {
|
||||
this.#closed = true;
|
||||
this.#cacheWrapper.decrementUse();
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
return 'PrepareWrapper{closed:' + this.#closed + ',cache:' + this.#cacheWrapper + '}';
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = PrepareWrapper;
|
||||
Reference in New Issue
Block a user