Cursor Helper

Statements that require using a Cursor, will use the Cursor Helper and other functions to have functional equivalence.

This helper also uses Raise helper and EXEC helper.

Cursor Helper Function Definition

var FETCH_INTO_COLLECTIONS = function (collections,fetchValues) {
   for(let i = 0;i < collections.length;i++) {
      collections[i].push(fetchValues[i]);
   }
};   
var CURSOR = function (stmt,binds,isRefCursor,isOut) {
   var statementObj, result_set, total_rows, ISOPEN = false, result_set_table = '', self = this, row_count, found;
   this.CURRENT = new Object;
   this.INTO = function () {
         return self.res;
      };
   this.OPEN = function (openParameters) {
         if (ISOPEN && !isRefCursor) RAISE(-6511,"CURSOR_ALREADY_OPEN","cursor already open");
         var finalStmt = openParameters && openParameters.query || stmt;
         var parameters = openParameters && openParameters.binds || [];
         var finalBinds = binds instanceof Function ? binds(...parameters) : binds;
         finalBinds = finalBinds || parameters;
         try {
            if (isOut) {
               if (!temptable_prefix) {
                  temptable_prefix = `${procname}_TEMP_${(EXEC(`select current_session() || '_' || to_varchar(current_timestamp, 'yyyymmddhh24missss')`,{
                        sql : 0
                     }))[0]}_`;
               }
               if (!result_set_table) {
                  result_set_table = temptable_prefix + outCursorResultNumber++;
                  EXEC(`CREATE OR REPLACE TEMPORARY TABLE ${result_set_table} AS ${finalStmt}`,{
                     sql : 0
                  });
               }
               finalStmt = "SELECT * FROM " + result_set_table
            }
            [result_set,statementObj,total_rows] = [EXEC(finalStmt,finalBinds,{
                  sql : 0,
                  row : 2
               }),_RS,_RS.getColumnCount()]
            ISOPEN = true;
            row_count = 0;
         } catch(error) {
            RAISE(error.code,"error",error.message);
         }
         return this;
      };
   this.NEXT = function () {
         if (total_rows && result_set.next()) {
            this.CURRENT = new Object;
            for(let i = 1;i <= statementObj.getColumnCount();i++) {
               (this.CURRENT)[statementObj.getColumnName(i)] = result_set.getColumnValue(i);
            }
            return true;
         } else return false;
      };
   this.FETCH = function (record) {
         var recordKeys = record ? Object.keys(record) : undefined;
         self.res = [];
         if (!ISOPEN) RAISE(-1001,"INVALID_CURSOR","invalid cursor");
         if (recordKeys && recordKeys.length != statementObj.getColumnCount()) RAISE(-6504,"ROWTYPE_MISMATCH","Return types of Result Set variables or query do not match");
         self.res = fetch(statementObj,result_set);
         if (self.res && self.res.length > 0) {
            found = true;
            row_count++;
            if (recordKeys) {
               for(let i = 0;i < self.res.length;i++) {
                  record[recordKeys[i]] = (self.res)[i];
               }
               return false;
            }
            return true;
         } else found = false;
         return false;
      };
   this.CLOSE = function () {
         if (!ISOPEN) RAISE(-1001,"INVALID_CURSOR","invalid cursor");
         found = row_count = result_set_table = total_rows = result_set = statementObj = undefined;
         ISOPEN = false;
      };
   this.FETCH_BULK_COLLECT_INTO = function (variables,limit) {
         if (variables.length != statementObj.getColumnCount()) RAISE(-6504,"ROWTYPE_MISMATCH","Return types of Result Set variables or query do not match");
         if (limit) {
            for(let i = 0;i < limit && this.FETCH();i++)FETCH_INTO_COLLECTIONS(variables,self.res);
         } else {
            while ( this.FETCH() )
               FETCH_INTO_COLLECTIONS(variables,self.res);
         }
      };
   this.FOUND = () => ISOPEN ? typeof(found) == "boolean" ? found : null : RAISE(-1001,"INVALID_CURSOR","invalid cursor");
   this.NOTFOUND = () => ISOPEN ? typeof(found) == "boolean" ? !found : null : RAISE(-1001,"INVALID_CURSOR","invalid cursor");
   this.ROWCOUNT = () => ISOPEN ? row_count : RAISE(-1001,"INVALID_CURSOR","invalid cursor");
   this.ISOPEN = () => ISOPEN;
   this.SAVE_STATE = function () {
         return {
            tempTable : result_set_table,
            position : row_count
         };
      };
   this.RESTORE_STATE = function (tempTable,position) {
         result_set_table = tempTable
         if (result_set_table) {
            isOut = true
            this.OPEN();
            for(let i = 0;i < position;i++)this.FETCH();
         }
      };
   this.ROWTYPE = () => ROWTYPE(stmt,binds());
};
var outCursorResultNumber = 0;

Last updated