--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.access.conglomerate.TemplateRow\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.store.access.conglomerate;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.io.ArrayUtil;\r
+import org.apache.derby.iapi.services.io.Storable;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.store.access.RowUtil;\r
+\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.DataValueFactory;\r
+\r
+import org.apache.derby.iapi.types.SQLLongint;\r
+\r
+import org.apache.derby.iapi.services.io.FormatableBitSet;\r
+\r
+public final class TemplateRow\r
+{\r
+\r
+ /*\r
+ ** Constructors of TemplateRow\r
+ */\r
+\r
+ private TemplateRow() {\r
+ }\r
+\r
+ /* Private/Protected methods of This class: */\r
+\r
+\r
+ /**\r
+ * Allocate new objects to array based on format id's and column_list.\r
+ * <p>\r
+ *\r
+ * @param num_cols_to_allocate The number of columns to allocate for array.\r
+ * @param column_list description of partial set of columns to \r
+ * built as described in RowUtil. If null do \r
+ * all the columns.\r
+ * @param format_ids An array of format ids representing every \r
+ * column in the table. column_list describes\r
+ * which of these columns to populate into the \r
+ * columns array.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ private static DataValueDescriptor[] allocate_objects(\r
+ Transaction rawtran,\r
+ int num_cols_to_allocate,\r
+ FormatableBitSet column_list,\r
+ int[] format_ids,\r
+ int[] collation_ids)\r
+ throws StandardException\r
+ {\r
+ int dest_pos = 0;\r
+\r
+ DataValueDescriptor[] ret_row = \r
+ new DataValueDescriptor[num_cols_to_allocate];\r
+ int num_cols = \r
+ (column_list == null ? format_ids.length : column_list.size());\r
+\r
+ DataValueFactory dvf = rawtran.getDataValueFactory();\r
+\r
+ for (int i = 0; i < num_cols; i++)\r
+ {\r
+ // does caller want this column?\r
+ if ((column_list != null) && (!column_list.get(i)))\r
+ {\r
+ // no - column should be skipped.\r
+ }\r
+ else\r
+ {\r
+ // yes - create the column \r
+\r
+ // get empty instance of object identified by the format id.\r
+ ret_row[i] = dvf.getNull(format_ids[i], collation_ids[i]);\r
+\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ DataValueDescriptor o = ret_row[i];\r
+\r
+ if (o == null)\r
+ {\r
+ SanityManager.THROWASSERT(\r
+ "obj from DataValueFactory.newNull(" +\r
+ format_ids[i] + ", " + collation_ids[i] + ") null." +\r
+ ";src column position = " + i +\r
+ ";dest column position = " + i + \r
+ ";num_cols = " + num_cols +\r
+ ";format_ids.length = " + format_ids.length);\r
+ }\r
+\r
+ if ( ! (o instanceof Storable))\r
+ SanityManager.THROWASSERT(\r
+ "object:(" + o.getClass() +"):(" + o + \r
+ ") not an instanceof Storable");\r
+ }\r
+ }\r
+ }\r
+\r
+ return(ret_row);\r
+ }\r
+\r
+ /* Public Methods of This class: */\r
+\r
+ /**\r
+ Constuctor for creating a template row which stores n SQLLongint's\r
+ **/\r
+ public static DataValueDescriptor[] newU8Row(int nkeys)\r
+ {\r
+ DataValueDescriptor[] columns = new DataValueDescriptor[nkeys];\r
+\r
+ for (int i = 0; i < columns.length; i++)\r
+ {\r
+ columns[i] = new SQLLongint(Long.MIN_VALUE);\r
+ }\r
+\r
+ return columns;\r
+ }\r
+\r
+ /**\r
+ * Generate an "empty" row to match the format id specification.\r
+ * <p>\r
+ * Generate an array of new'd objects matching the format id specification\r
+ * passed in. This routine is mostly used by the btree code to generate\r
+ * temporary rows needed during operations like split. It is more\r
+ * efficient to allocate new objects based on the old object vs. calling\r
+ * the Monitor.\r
+ * <p>\r
+ *\r
+ *\r
+ * @param template An array which represents a row as described in\r
+ * RowUtil.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ *\r
+ * @return The new row.\r
+ *\r
+ * @see RowUtil\r
+ **/\r
+ public static DataValueDescriptor[] newRow(\r
+ DataValueDescriptor[] template)\r
+ throws StandardException\r
+ {\r
+ DataValueDescriptor[] columns = \r
+ new DataValueDescriptor[template.length];\r
+\r
+ for (int i = template.length; i-- > 0 ;)\r
+ {\r
+ // get empty instance of object identified by the format id.\r
+ columns[i] = template[i].getNewNull();\r
+ }\r
+\r
+ return columns;\r
+ }\r
+\r
+ /**\r
+ * Generate an "empty" row to match the format id specification.\r
+ * <p>\r
+ * Generate an array of new'd objects matching the format id specification\r
+ * passed in. This routine is mostly used by the btree code to generate\r
+ * temporary rows needed during operations like split.\r
+ * <p>\r
+ *\r
+ * @return The new row.\r
+ *\r
+ * @param format_ids an array of format id's, one per column in row.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public static DataValueDescriptor[] newRow(\r
+ Transaction rawtran,\r
+ FormatableBitSet column_list,\r
+ int[] format_ids,\r
+ int[] collation_ids) \r
+ throws StandardException\r
+ {\r
+ return(\r
+ allocate_objects(\r
+ rawtran, format_ids.length, column_list, \r
+ format_ids, collation_ids));\r
+ }\r
+\r
+ /**\r
+ * Generate an "empty" row to match the format id + coluumn specification.\r
+ * <p>\r
+ * Generate an array of new'd objects matching the format id specification\r
+ * passed in, and the column passed in. The new row is first made up of\r
+ * columns matching the format ids, and then followed by one other column\r
+ * matching the column passed in. This routine is mostly used by the \r
+ * btree code to generate temporary branch rows needed during operations \r
+ * like split.\r
+ * <p>\r
+ *\r
+ * @return The new row.\r
+ *\r
+ * @param format_ids an array of format id's, one per column in row.\r
+ * @param page_ptr The object to place in the last column of the template.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public static DataValueDescriptor[] newBranchRow(\r
+ Transaction rawtran,\r
+ int[] format_ids,\r
+ int[] collation_ids,\r
+ DataValueDescriptor page_ptr) \r
+ throws StandardException\r
+ {\r
+ // allocate an object array with the number of columns in the template\r
+ // row (ie. number of columns in the leaf row) + one column to hold\r
+ // the page pointer in the branch row.\r
+ DataValueDescriptor[] columns = \r
+ allocate_objects(\r
+ rawtran,\r
+ format_ids.length + 1, \r
+ (FormatableBitSet) null, format_ids, collation_ids);\r
+\r
+ // tack on the page pointer to the extra column allocated onto the \r
+ // end of the row built from a leafrow template.\r
+ columns[format_ids.length] = page_ptr;\r
+\r
+ return(columns);\r
+ }\r
+\r
+ /**\r
+ * Check that columns in the row conform to a set of format id's, \r
+ * both in number and type.\r
+ *\r
+ * @return boolean indicating if template matches format id's\r
+ *\r
+ * @param format_ids array of format ids which are the types of cols in row\r
+ * @param row the array of columns that make up the row.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ static public boolean checkColumnTypes(\r
+ DataValueFactory dvf,\r
+ int[] format_ids, \r
+ int[] collation_ids,\r
+ DataValueDescriptor[] row)\r
+ throws StandardException\r
+ {\r
+ boolean ret_val = true;\r
+\r
+ while (true)\r
+ {\r
+ int nCols = row.length;\r
+ if (format_ids.length != row.length)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.THROWASSERT(\r
+ "format_ids[] length (" + format_ids.length +\r
+ ") expected to be = row length (" + row.length + ")");\r
+ }\r
+ ret_val = false;\r
+ break;\r
+ }\r
+\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ Object column;\r
+ Object column_template;\r
+\r
+ for (int colid = 0; colid < nCols; colid++)\r
+ {\r
+ column = row[colid];\r
+\r
+ if (column == null)\r
+ {\r
+ SanityManager.THROWASSERT(\r
+ "column[" + colid + "] is null");\r
+ }\r
+\r
+ column_template = \r
+ dvf.getNull(format_ids[colid], collation_ids[colid]);\r
+\r
+\r
+ // is this the right check?\r
+ if (column.getClass() != column_template.getClass())\r
+ {\r
+ SanityManager.DEBUG_PRINT(\r
+ "check", "row = " + RowUtil.toString(row));\r
+\r
+ SanityManager.THROWASSERT(\r
+ "input column["+colid+"] (" + column.getClass() +\r
+ ") did not match expected template class (" +\r
+ column_template.getClass() + ")" +\r
+ "\ncolumn value = " + column +\r
+ "\nformat_ids = " + \r
+ ArrayUtil.toString(format_ids) +\r
+ "\ncollation = " + \r
+ ArrayUtil.toString(collation_ids));\r
+ }\r
+ }\r
+ }\r
+ break;\r
+ }\r
+\r
+ return(ret_val);\r
+ }\r
+\r
+ /**\r
+ * Check that columns in the row conform to a set of format id's, \r
+ * both in number and type.\r
+ *\r
+ * @return boolean indicating if template matches format id's\r
+ *\r
+ * @param format_ids array of format ids which are the types of cols in row\r
+ * @param row the array of columns that make up the row.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ static public boolean checkPartialColumnTypes(\r
+ int[] format_ids, \r
+ FormatableBitSet validColumns,\r
+ int[] fieldStates,\r
+ DataValueDescriptor[] row)\r
+ throws StandardException\r
+ {\r
+ boolean ret_val = true;\r
+\r
+ return(ret_val);\r
+ }\r
+}\r