UNPKG

@natlibfi/oracledb-aleph

Version:

A Node.js module for Oracle Database access from JavaScript and TypeScript

123 lines (111 loc) 5.23 kB
// Copyright (c) 2022, 2023, Oracle and/or its affiliates. //----------------------------------------------------------------------------- // // This software is dual-licensed to you under the Universal Permissive License // (UPL) 1.0 as shown at https://oss.oracle.com/licenses/upl and Apache License // 2.0 as shown at http://www.apache.org/licenses/LICENSE-2.0. You may choose // either license. // // If you elect to accept the software under the Apache License, Version 2.0, // the following applies: // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //----------------------------------------------------------------------------- 'use strict'; const ResultSetImpl = require('../impl/resultset.js'); const ExecuteMessage = require('./protocol/messages/execute.js'); const FetchMessage = require('./protocol/messages/fetch.js'); class ThinResultSetImpl extends ResultSetImpl { //--------------------------------------------------------------------------- // _fetchMoreRows() // // Fetches more rows from the database. This is done by means of the full // OAL8 RPC if needed; otherwise, the simpler OFETCH RPC is used. //--------------------------------------------------------------------------- async _fetchMoreRows(options) { const cls = (this.statement.requiresFullExecute) ? ExecuteMessage : FetchMessage; const message = new cls(this.connection, this.statement, options, this); await this.connection._protocol._processMessage(message); this.statement.requiresFullExecute = false; } //--------------------------------------------------------------------------- // Set the metadata info for a new resultSet object //--------------------------------------------------------------------------- _resultSetNew(connection, statement, options) { this.connection = connection; this.statement = statement; this._nestedCursorIndices = []; this.options = options; this.prefetchRowsProcessed = false; this.statement.bufferRowIndex = 0; } //--------------------------------------------------------------------------- // Returns the statement to cache so that it can be used later //--------------------------------------------------------------------------- close() { this.connection._returnStatement(this.statement); } //--------------------------------------------------------------------------- // Returns rows fetched to the common layer in array format //--------------------------------------------------------------------------- _processRows(numRowsFetched) { const rows = []; const bufferRowIndex = this.statement.bufferRowIndex; for (let row = bufferRowIndex; row < bufferRowIndex + numRowsFetched; row++) { const rowObj = []; for (let col = 0; col < this.statement.numQueryVars; col++) { rowObj.push(this.statement.queryVars[col].values[row]); } rows.push(rowObj); } this.statement.bufferRowIndex += numRowsFetched; if (this.statement.bufferRowIndex === this.statement.bufferRowCount) { this.statement.bufferRowCount = 0; this.statement.bufferRowIndex = 0; } return rows; } //--------------------------------------------------------------------------- // getRows() // // Fetches the specified number of rows from the database and returns them to // the common layer for processing. //--------------------------------------------------------------------------- async getRows(numRows, options) { options.fetchArraySize = numRows || this.options.fetchArraySize; options.prefetchRows = this.options.prefetchRows; if (this.statement.bufferRowCount - this.statement.bufferRowIndex >= options.fetchArraySize) { return this._processRows(options.fetchArraySize); } else { // We fetch for the required number of row options.fetchArraySize = options.fetchArraySize - (this.statement.bufferRowCount - this.statement.bufferRowIndex); const prevBufferRowCount = this.statement.bufferRowCount; if (this.statement.moreRowsToFetch && options.fetchArraySize > 0) { await this._fetchMoreRows(options); } options.fetchArraySize = numRows || this.options.fetchArraySize; if (prevBufferRowCount === this.statement.bufferRowCount) { const numRowsFetched = this.statement.bufferRowCount - this.statement.bufferRowIndex; this.statement.bufferRowCount = 0; if (numRowsFetched > 0) { return this._processRows(numRowsFetched); } return []; } } const numRowsFetched = this.statement.bufferRowCount - this.statement.bufferRowIndex; return this._processRows(numRowsFetched); } } module.exports = ThinResultSetImpl;