@proddata/node-cratedb
Version:
Node.js client for CrateDB
116 lines • 3.93 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cursor = void 0;
const http_1 = __importDefault(require("http"));
const https_1 = __importDefault(require("https"));
const Error_js_1 = require("./utils/Error.js");
class Cursor {
client;
sql;
cursorName;
isOpen;
agent;
cursorOptions;
constructor(client, sql) {
this.client = client;
this.sql = sql;
this.cursorName = `cursor_${Date.now()}`;
this.isOpen = false;
const agentOptions = {
keepAlive: true,
maxSockets: 1,
};
this.agent = client.getConfig().ssl ? new https_1.default.Agent(agentOptions) : new http_1.default.Agent(agentOptions);
this.cursorOptions = {
...client.getHttpOptions(),
agent: this.agent,
};
}
async open() {
if (this.isOpen) {
throw new Error('Cursor is already open');
}
// Start a transaction and declare the cursor
await this._execute('BEGIN');
await this._execute(`DECLARE ${this.cursorName} NO SCROLL CURSOR WITH HOLD FOR ${this.sql}`);
this.isOpen = true;
}
async fetchOne() {
this._ensureOpen();
const result = await this._execute(`FETCH NEXT FROM ${this.cursorName}`);
return result.length > 0 ? result[0] : null; // Return the first row or null
}
async fetchMany(size = 10) {
if (size < 1) {
// Return an empty array if size is less than 1
return [];
}
this._ensureOpen();
return await this._execute(`FETCH ${size} FROM ${this.cursorName}`);
}
async fetchAll() {
this._ensureOpen();
return await this._execute(`FETCH ALL FROM ${this.cursorName}`);
}
async *iterate(size = 100) {
this._ensureOpen();
while (true) {
const rows = await this.fetchMany(size);
if (!rows || rows.length === 0) {
break; // Stop iteration when no more rows are returned
}
for (const row of rows) {
yield row; // Yield one row at a time
}
}
}
async close() {
this._ensureOpen();
// Close the cursor and end the transaction
await this._execute(`CLOSE ${this.cursorName}`);
await this._execute('COMMIT');
this.isOpen = false;
// Destroy the agent's socket connections to ensure the TCP connection is closed
this.agent.destroy();
}
async _execute(sql) {
try {
const response = await this.client.execute(sql, undefined, {
rowMode: 'object',
httpOptions: this.cursorOptions,
});
if (!response.rows || !response.rowcount) {
return [];
}
return response.rows;
}
catch (error) {
if (error instanceof Error_js_1.CrateDBError) {
throw error;
}
else if (error instanceof Error) {
throw new Error_js_1.RequestError(`Error executing SQL: ${sql}. Details: ${error.message}`, { cause: error });
}
throw new Error_js_1.RequestError('CrateDB request failed with an unknown error');
}
}
_rebuildObjects(cols, rows) {
return rows.map((row) => {
const obj = {};
cols.forEach((col, index) => {
obj[col] = row[index];
});
return obj;
});
}
_ensureOpen() {
if (!this.isOpen) {
throw new Error('Cursor is not open. Call open() before performing this operation.');
}
}
}
exports.Cursor = Cursor;
//# sourceMappingURL=Cursor.js.map