PACKAGE BODY psg_array IS /*------------------------Package Variable ---------------------*/ /* The number of arrays created in session. */ array_count INTEGER := 0; /*------------------------Private Modules ----------------------*/ FUNCTION row_count_name (array_in IN INTEGER) RETURN VARCHAR2 /* || Returns the name of the global containing the row count. */ IS BEGIN RETURN 'PSG_ARRAY_RC_' || TO_CHAR (array_in); END; FUNCTION column_count_name (array_in IN INTEGER) RETURN VARCHAR2 /* || Returns the name of the global containing the column count. */ IS BEGIN RETURN 'PSG_ARRAY_CC_' || TO_CHAR (array_in); END; FUNCTION first_row_name (array_in IN INTEGER) RETURN VARCHAR2 /* || Returns the name of the global containing the first row. */ IS BEGIN RETURN 'PSG_ARRAY_FR_' || TO_CHAR (array_in); END; FUNCTION last_row_name (array_in IN INTEGER) RETURN VARCHAR2 /* || Returns the name of the global containing the last row. */ IS BEGIN RETURN 'PSG_ARRAY_LR_' || TO_CHAR (array_in); END; FUNCTION first_row (array_in IN INTEGER) RETURN INTEGER IS return_value INTEGER; BEGIN PS_global.getval (first_row_name (array_in), return_value); RETURN return_value; END; FUNCTION last_row (array_in IN INTEGER) RETURN INTEGER IS return_value INTEGER; BEGIN PS_global.getval (last_row_name (array_in), return_value); RETURN return_value; END; FUNCTION row_for_cell (array_in IN INTEGER, row_in IN INTEGER, col_in IN INTEGER) RETURN INTEGER /* || Returns the row in the table that stores the value for || the specified cell in the array. */ IS start_row INTEGER := first_row (array_in); end_row INTEGER := last_row (array_in); row_offset INTEGER := (col_in - 1) * row_count (array_in) + row_in; BEGIN RETURN start_row + SIGN (end_row - start_row) * row_offset; END; /*------------------------Public Modules ----------------------*/ FUNCTION row_count (array_in IN INTEGER) RETURN INTEGER IS return_value INTEGER; BEGIN PS_global.getval (row_count_name (array_in), return_value); RETURN return_value; END; FUNCTION column_count (array_in IN INTEGER) RETURN INTEGER IS return_value INTEGER; BEGIN PS_global.getval (column_count_name (array_in), return_value); RETURN return_value; END; FUNCTION make (num_rows_in IN INTEGER := 10, num_columns_in IN INTEGER := 1, initial_value_in IN NUMBER := NULL) RETURN INTEGER /* || Create an array of the specified size, with the initial value. */ IS global_handle INTEGER; return_value INTEGER; BEGIN /* Generate handle to the array */ array_count := array_count + 1; return_value := array_count; /* Create named globals to hold the information about the array */ PS_global.putval (row_count_name (return_value), num_rows_in); PS_global.putval (column_count_name (return_value), num_columns_in); FOR col_index IN 1 .. num_columns_in LOOP FOR row_index IN 1 .. num_rows_in LOOP global_handle := PS_global.putval (initial_value_in); IF col_index = 1 AND row_index = 1 THEN PS_global.putval (first_row_name (return_value), global_handle); END IF; END LOOP; END LOOP; PS_global.putval (last_row_name (return_value), global_handle); RETURN return_value; END; FUNCTION cell (array_in IN INTEGER, row_in IN INTEGER, col_in IN INTEGER) RETURN NUMBER /* || Retrieve the value in a cell using row_for_cell. */ IS return_value NUMBER; BEGIN PS_global.getval (row_for_cell (array_in, row_in, col_in), return_value); RETURN return_value; END; PROCEDURE change (array_in IN INTEGER, row_in IN INTEGER, col_in IN INTEGER, value_in IN NUMBER) /* || Change the value in a cell using row_for_cell. */ IS BEGIN PS_global.newval (value_in, row_for_cell (array_in, row_in, col_in)); END; PROCEDURE erase (array_in IN INTEGER) /* || Erase a table by assigning an empty table to a non-empty || array. Then set the size globals for the array to NULL. */ IS start_row INTEGER := first_row (array_in); end_row INTEGER := last_row (array_in); switch_row INTEGER; BEGIN IF end_row < start_row THEN switch_row := end_row; end_row := start_row; start_row := switch_row; END IF; FOR row_index IN start_row .. end_row LOOP PS_global.clrval_number (row_index); END LOOP; PS_global.clrval (row_count_name (array_in)); PS_global.clrval (column_count_name (array_in)); PS_global.clrval (first_row_name (array_in)); PS_global.clrval (last_row_name (array_in)); IF array_in = array_count THEN array_count := array_count - 1; END IF; END; END psg_array;