--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.store.raw.data.D_DiagnosticUtil\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.raw.data;\r
+\r
+import org.apache.derby.iapi.services.context.ContextService;\r
+import org.apache.derby.iapi.services.diag.Diagnosticable;\r
+import org.apache.derby.iapi.services.diag.DiagnosticUtil;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.store.access.AccessFactory;\r
+import org.apache.derby.iapi.store.access.ConglomerateController;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.store.raw.ContainerHandle;\r
+import org.apache.derby.iapi.store.raw.ContainerKey;\r
+import org.apache.derby.iapi.store.raw.Page;\r
+import org.apache.derby.iapi.store.raw.Transaction;\r
+import org.apache.derby.iapi.store.raw.RawStoreFactory;\r
+\r
+\r
+// import com.ibm.db2j.impl.BasicServices.TestService.TestTemplate.T_MultiIterations;\r
+// import com.ibm.db2j.impl.BasicServices.TestService.TestTemplate.T_Fail;\r
+import org.apache.derby.iapi.reference.Property;\r
+\r
+// import java.util.Properties;\r
+\r
+// DEBUGGING:\r
+\r
+/**\r
+\r
+ This class provides some utility functions used to debug on disk structures\r
+ of the store.\r
+\r
+**/\r
+\r
+\r
+public class D_DiagnosticUtil\r
+{\r
+\r
+\r
+ /* Constructors for This class: */\r
+\r
+ /**\r
+ * No arg Constructor.\r
+ **/\r
+ public D_DiagnosticUtil()\r
+ {\r
+ }\r
+\r
+ /* Private/Protected methods of This class: */\r
+\r
+ /**\r
+ * Given a database name come up with a module.\r
+ * <p>\r
+ *\r
+ * @return The store module associated with given database name.\r
+ *\r
+ * @param db_name name of the database.\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ private static Object getModuleFromDbName(String db_name)\r
+ throws StandardException\r
+ {\r
+ Object store_module = null;\r
+\r
+ Object db = Monitor.findService(Property.DATABASE_MODULE, db_name);\r
+\r
+ // RESOLVE (mikem) - find a single way to find the current \r
+ // AccessFactory that works both for ij and unit tests.\r
+ if (db == null)\r
+ {\r
+ // maybe it is a module test - try this hack:\r
+ store_module = Monitor.findService(AccessFactory.MODULE, db_name);\r
+ }\r
+ else\r
+ {\r
+ // Find the AccessFactory\r
+ store_module = Monitor.findServiceModule(db, AccessFactory.MODULE);\r
+ }\r
+\r
+ return(store_module);\r
+ }\r
+\r
+ /* Public Methods of This class: */\r
+ /**\r
+ * Given a Database name and conglomid print out diagnostic info.\r
+ * <p>\r
+ * Print diagnostic information about a particular conglomerate, can be\r
+ * called for either a btree or heap conglomerate. This routine\r
+ * prints out the string to "System.out"; "ij", depending on it's \r
+ * configuration, will only print out a fixed length (default 128 bytes),\r
+ * so having ij print the string can be a problem.\r
+ * <p>\r
+ *\r
+ * Can be called from ij to find out info about conglomid 19 in database\r
+ * 'msgdb' by using the following syntax:\r
+ *\r
+ maximumdisplaywidth 9000;\r
+\r
+ CREATE FUNCTION D_CONGLOMID_PRINT(DBNAME VARCHAR(128), CONGLOMID INT)\r
+ RETURNS VARCHAR(32000) RETURNS NULL ON NULL INPUT\r
+ EXTERNAL NAME\r
+ 'org.apache.derby.impl.store.raw.data.D_DiagnosticUtil.diag_conglomid_print'\r
+ LANGUAGE JAVA PARAMETER STYLE JAVA;\r
+\r
+ values D_CONGLOMID_PRINT('msgdb', 19);\r
+ com.ibm.db2j.protocol.BasicServices.Diagnostic.T_Diagnosticable::\r
+ diag_conglomid_print('msgdb', 19);\r
+ *\r
+ * RESOLVE - An interface that takes a table name would be nice.\r
+ *\r
+ * @param db_name name of the database \r
+ * @param conglomid conglomerate id of the conglomerate to debug\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public static String diag_conglomid_print(String db_name, long conglomid)\r
+ throws StandardException\r
+ {\r
+ try \r
+ {\r
+ System.out.println(diag_conglomid(db_name, conglomid));\r
+ }\r
+ catch (Throwable t)\r
+ {\r
+ t.printStackTrace();\r
+ }\r
+\r
+ return("");\r
+ }\r
+ \r
+ /**\r
+ * Given a Database name and conglomid, return diagnositic string.\r
+ * <p>\r
+ * Return a string with diagnostic information about a particular\r
+ * conglomerate, can be called for any type of conglomerate (some types\r
+ * may not return any info though).\r
+ * <p>\r
+ * Can be called from ij to find out info about conglomid 19 in database\r
+ * 'msgdb' by using the following syntax:\r
+ *\r
+ * values \r
+ * com.ibm.db2j.protocol.BasicServices.Diagnostic.T_Diagnosticable::\r
+ * diag_conglomid('msgdb', 19);\r
+ maximumdisplaywidth 9000;\r
+\r
+ CREATE FUNCTION DIAG_CONGLOMID(DBNAME VARCHAR(128), CONGLOMID INT)\r
+ RETURNS VARCHAR(32000) RETURNS NULL ON NULL INPUT\r
+ EXTERNAL NAME\r
+ 'org.apache.derby.impl.store.raw.data.D_DiagnosticUtil.diag_conglomid'\r
+ LANGUAGE JAVA PARAMETER STYLE JAVA;\r
+\r
+ values DIAG_CONGLOMID('msgdb', 19);\r
+ com.ibm.db2j.protocol.BasicServices.Diagnostic.T_Diagnosticable::\r
+ diag_conglomid_print('msgdb', 19);\r
+ *\r
+ * RESOLVE - An interface that takes a table name would be nice.\r
+ *\r
+ * @param db_name name of the database \r
+ * @param conglomid conglomerate id of the conglomerate to debug\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public static String diag_conglomid(String db_name, long conglomid)\r
+ throws StandardException\r
+ {\r
+ String ret_string = null;\r
+ AccessFactory store_module = null;\r
+\r
+ store_module = (AccessFactory) getModuleFromDbName(db_name);\r
+\r
+ if (store_module != null)\r
+ {\r
+\r
+ TransactionController tc =\r
+ store_module.getTransaction(\r
+ ContextService.getFactory().getCurrentContextManager());\r
+\r
+ ConglomerateController open_table = \r
+ tc.openConglomerate(\r
+ conglomid, false, 0, TransactionController.MODE_TABLE,\r
+ TransactionController.ISOLATION_SERIALIZABLE);\r
+\r
+ open_table.debugConglomerate();\r
+\r
+ Diagnosticable diag_obj = DiagnosticUtil.findDiagnostic(open_table);\r
+\r
+ ret_string = diag_obj.diag();\r
+\r
+ open_table.close();\r
+ }\r
+ else\r
+ {\r
+ System.out.println(\r
+ "Could not find module for database: " + db_name);\r
+ }\r
+\r
+ return(ret_string);\r
+ }\r
+\r
+ /**\r
+ * Dump raw contents of a page.\r
+ * <p>\r
+ * A utility routine that can be called from an ij session that will \r
+ * dump the raw contents of a page, in the raw store dump format.\r
+ *\r
+ * @param db_name name of the database \r
+ * @param segmentid segmentid of the table (usually 0)\r
+ * @param containerid containerid of the table (not conglomid)\r
+ * @param pagenumber pagenumber of page to dump.\r
+ *\r
+ **/\r
+ public static void diag_dump_page(\r
+ String db_name, \r
+ long segmentid, \r
+ long containerid, \r
+ long pagenumber)\r
+ {\r
+ Transaction xact = null;\r
+ try\r
+ {\r
+ Object module = getModuleFromDbName(db_name);\r
+\r
+ RawStoreFactory store_module = (RawStoreFactory)\r
+ Monitor.findServiceModule(module, RawStoreFactory.MODULE);\r
+\r
+ xact = store_module.startInternalTransaction(ContextService.getFactory().getCurrentContextManager());\r
+\r
+ ContainerKey id = new ContainerKey(segmentid, containerid);\r
+ ContainerHandle container = \r
+ xact.openContainer(id,\r
+ ContainerHandle.MODE_READONLY);\r
+ Page page = container.getPage(pagenumber);\r
+\r
+ if (page != null)\r
+ {\r
+ System.out.println(page.toString());\r
+ page.unlatch();\r
+ }\r
+ else\r
+ {\r
+ System.out.println("page " + pagenumber + " not found");\r
+ }\r
+ xact.abort();\r
+ xact.close();\r
+ xact = null;\r
+ }\r
+ catch (StandardException se)\r
+ {\r
+ se.printStackTrace();\r
+ }\r
+ finally\r
+ {\r
+ if (xact != null)\r
+ {\r
+ try\r
+ {\r
+ xact.abort();\r
+ xact.close();\r
+ }\r
+ catch (StandardException se)\r
+ {\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Given a Database name and conglomid, return container id.\r
+ * <p>\r
+ * Return the containerid of a given conglomerate id.\r
+ * <p>\r
+ * Can be called from ij to find out info about conglomid 19 in database\r
+ * 'msgdb' by using the following syntax:\r
+ *\r
+ values \r
+ com.ibm.db2j.protocol.BasicServices.Diagnostic.T_Diagnosticable).\r
+ diag_containerid_to_conglomid('msgdb', 924300359390);\r
+ *\r
+ * RESOLVE - An interface that takes a table name would be nice.\r
+ *\r
+ * @param db_name name of the database \r
+ * @param containerid container id of the conglomerate to look up\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public static long diag_containerid_to_conglomid(\r
+ String db_name,\r
+ long containerid)\r
+ throws StandardException\r
+ {\r
+ // Find the AccessFactory\r
+ Object store_module = getModuleFromDbName(db_name);\r
+\r
+ return(diag_containerid_to_conglomid(store_module, containerid));\r
+ }\r
+\r
+ public static long diag_containerid_to_conglomid(\r
+ Object module,\r
+ long containerid)\r
+ {\r
+ String ret_string = null;\r
+ AccessFactory store_module = null;\r
+ long conglom_id = Long.MIN_VALUE;\r
+\r
+ // Find the AccessFactory\r
+ store_module = (AccessFactory) \r
+ Monitor.getServiceModule(module, AccessFactory.MODULE);\r
+\r
+ if (store_module != null)\r
+ {\r
+ try\r
+ {\r
+ TransactionController tc = \r
+ store_module.getTransaction(\r
+ ContextService.getFactory().getCurrentContextManager());\r
+\r
+ conglom_id = tc.findConglomid(containerid);\r
+ }\r
+ catch (Throwable t)\r
+ {\r
+ t.printStackTrace();\r
+ // on error just return the initialized bad value conglom_id\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // during access boot this does not exist, assume for now that\r
+ // is why we got here. RESOLVE - it would be nice if we could\r
+ // actuallly figure that is why we failed.\r
+ \r
+ /*\r
+ System.out.println(\r
+ "Could not find module for module: " + module);\r
+ */\r
+ }\r
+\r
+ return(conglom_id);\r
+ }\r
+\r
+ /**\r
+ * Given a Database name and containerid, return conglomerate id.\r
+ * <p>\r
+ * Return the conglomerate id of a given conainer id.\r
+ * <p>\r
+ * Can be called from ij to find out info about conglomid 19 in database\r
+ * 'msgdb' by using the following syntax:\r
+ *\r
+ values \r
+ com.ibm.db2j.protocol.BasicServices.Diagnostic.T_Diagnosticable).\r
+ diag_conglomid_to_containerid('msgdb', 19);\r
+ *\r
+ * RESOLVE - An interface that takes a table name would be nice.\r
+ *\r
+ * @param db_name name of the database\r
+ * @param conglomid conglomerate id of the conglomerate to debug\r
+ *\r
+ * @exception StandardException Standard exception policy.\r
+ **/\r
+ public static long diag_conglomid_to_containerid(\r
+ String db_name,\r
+ long conglomid)\r
+ throws StandardException\r
+ {\r
+ String ret_string = null;\r
+ Object store_module = null;\r
+ long conglom_id = Long.MIN_VALUE;\r
+\r
+ // Find the AccessFactory\r
+ store_module = getModuleFromDbName(db_name);\r
+\r
+ return(diag_conglomid_to_containerid(store_module, conglomid));\r
+ }\r
+\r
+ public static long diag_conglomid_to_containerid(\r
+ Object module,\r
+ long conglomid)\r
+ {\r
+ String ret_string = null;\r
+ AccessFactory store_module = null;\r
+ long container_id = Long.MIN_VALUE;\r
+\r
+ // Find the AccessFactory\r
+ store_module = (AccessFactory) \r
+ Monitor.getServiceModule(module, AccessFactory.MODULE);\r
+\r
+ if (store_module != null)\r
+ {\r
+ try\r
+ {\r
+ TransactionController tc =\r
+ store_module.getTransaction(\r
+ ContextService.getFactory().getCurrentContextManager());\r
+\r
+ container_id = tc.findContainerid(conglomid);\r
+ }\r
+ catch (Throwable t)\r
+ {\r
+ t.printStackTrace();\r
+ // on error just return the initialized bad value conglom_id\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // during access boot this does not exist, assume for now that\r
+ // is why we got here. RESOLVE - it would be nice if we could\r
+ // actuallly figure that is why we failed.\r
+ \r
+ /*\r
+ System.out.println(\r
+ "Could not find module for module: " + module);\r
+ */\r
+ }\r
+\r
+ return(container_id);\r
+ }\r
+\r
+}\r