postgrejs
Version:
Professional PostgreSQL client NodeJS
87 lines (86 loc) • 2.78 kB
JavaScript
import DoublyLinked from 'doublylinked';
import { TaskQueue } from 'power-tasks';
import { SafeEventEmitter } from '../safe-event-emitter.js';
import { convertRowToObject } from '../util/convert-row-to-object.js';
import { parseRow } from '../util/parse-row.js';
export class Cursor extends SafeEventEmitter {
constructor(statement, portal, fields, parsers, queryOptions) {
super();
this._taskQueue = new TaskQueue({ concurrency: 1 });
this._rows = new DoublyLinked();
this._closed = false;
this._statement = statement;
this._portal = portal;
this._parsers = parsers;
this._queryOptions = queryOptions;
this.fields = fields;
}
get rowType() {
return this._queryOptions.objectRows ? 'object' : 'array';
}
get isClosed() {
return this._closed;
}
async next() {
if (!this._rows.length) {
if (this._closed)
return;
await this._fetchRows();
}
return this._rows.shift();
}
async fetch(nRows) {
const out = [];
if (this._closed)
return out;
for (let i = 0; i < nRows; i++) {
if (!this._rows.length)
await this._fetchRows();
if (this._rows.length)
out.push(this._rows.shift());
else
break;
}
return out;
}
async close() {
if (this._closed)
return;
await this._portal.close();
await this._statement.close();
this.emit('close');
this._closed = true;
}
async _fetchRows() {
if (this._closed)
return;
const portal = this._portal;
await this._taskQueue
.enqueue(async () => {
const queryOptions = this._queryOptions;
const r = await portal.execute(queryOptions.fetchCount || 100);
if (r && r.rows && r.rows.length) {
if (this._parsers) {
const objectRows = queryOptions.objectRows;
const fields = this.fields;
const rows = r.rows;
for (let i = 0; i < rows.length; i++) {
const row = rows[i];
parseRow(this._parsers, row, this._queryOptions);
if (objectRows)
rows[i] = convertRowToObject(fields, row);
}
}
this._rows.push(...r.rows);
this.emit('fetch', r.rows);
}
else {
await this.close();
}
})
.toPromise();
}
[Symbol.asyncDispose]() {
return this.close();
}
}