Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / load / ImportAbstract.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/load/ImportAbstract.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/load/ImportAbstract.java
new file mode 100644 (file)
index 0000000..83e9fe2
--- /dev/null
@@ -0,0 +1,336 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.load.ImportAbstract\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.load;\r
+\r
+import java.io.IOException;\r
+import java.sql.SQLException;\r
+import java.sql.SQLWarning;\r
+import java.sql.ResultSetMetaData;\r
+import org.apache.derby.vti.VTITemplate;\r
+import java.util.ArrayList;\r
+import org.apache.derby.iapi.util.StringUtil;\r
+import org.apache.derby.iapi.error.PublicAPI;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+\r
+/**\r
+ * \r
+ * <P>\r
+ */\r
+abstract class ImportAbstract extends VTITemplate {\r
+\r
+  ControlInfo controlFileReader;\r
+  ImportReadData importReadData;\r
+\r
+  String[] columnNames;\r
+  int numberOfColumns;\r
+  int[] columnWidths;\r
+\r
+  int lineNumber = 0;\r
+  String[] nextRow;\r
+\r
+  ResultSetMetaData importResultSetMetaData;\r
+  int noOfColumnsExpected;\r
+\r
+  protected boolean lobsInExtFile = false;\r
+\r
+  String tableColumnTypesStr;\r
+  int[] tableColumnTypes;\r
+  private boolean wasNull;\r
+\r
+       static final String COLUMNNAMEPREFIX = "COLUMN";\r
+\r
+  abstract ImportReadData getImportReadData() throws Exception;\r
+\r
+  /** Does all the work\r
+       * @exception    Exception if there is an error\r
+       */\r
+  void doAllTheWork() throws Exception {\r
+\r
+    //prepare the input file for import. Get the number of columns per row\r
+    //from the input file.\r
+    importReadData = getImportReadData();\r
+    numberOfColumns = importReadData.getNumberOfColumns();\r
+       if(numberOfColumns == 0)\r
+       {\r
+               //file is empty. Assume same number of columns expected \r
+               //and return no data , But No rows gets insereted.\r
+               this.numberOfColumns = noOfColumnsExpected;\r
+       }\r
+\r
+    columnWidths = controlFileReader.getColumnWidths();\r
+    columnNames = new String[numberOfColumns];\r
+    loadColumnNames();\r
+    nextRow = new String[numberOfColumns];\r
+    tableColumnTypes = ColumnInfo.getExpectedVtiColumnTypes(tableColumnTypesStr,\r
+                                                            numberOfColumns);\r
+       // get the ResultSetMetaData now as we know it's needed\r
+       importResultSetMetaData =\r
+               new ImportResultSetMetaData(numberOfColumns, columnNames, columnWidths,\r
+                                    tableColumnTypes);\r
+\r
+\r
+    //FIXME don't go through the resultset here. just for testing\r
+//    while (next()) ;\r
+  }\r
+  //the column names will be Column#\r
+  void loadColumnNames() {\r
+    for (int i=1; i<=numberOfColumns; i++)\r
+      columnNames[i-1] = COLUMNNAMEPREFIX + i;\r
+\r
+  }\r
+\r
+\r
+  /** Gets the resultset meta data\r
+       * @exception    SQLException if there is an error\r
+       */\r
+  public ResultSetMetaData getMetaData() {\r
+    return importResultSetMetaData;\r
+  }\r
+\r
+  //all the resultset interface methods\r
+  /** gets the next row\r
+       * @exception    SQLException if there is an error\r
+       */\r
+  public int getRow() throws SQLException {\r
+    return (importReadData.getCurrentRowNumber());\r
+  }\r
+  \r
+    /** gets the current line number */\r
+    public    int getCurrentLineNumber() { return lineNumber; }\r
+    \r
+  public boolean next() throws SQLException {\r
+    try {\r
+      lineNumber++;\r
+      return (importReadData.readNextRow(nextRow));\r
+    } catch (Exception ex) {\r
+               throw importError(ex);\r
+       }\r
+  }\r
+\r
+  /** closes the resultset\r
+       * @exception    SQLException if there is an error\r
+       */\r
+  public void close() throws SQLException {\r
+    try {\r
+               if(importReadData!=null)\r
+                       importReadData.closeStream();\r
+    } catch (Exception ex) {\r
+               throw LoadError.unexpectedError(ex);\r
+    }\r
+  }\r
+\r
+  public boolean wasNull() {\r
+               return wasNull;\r
+  }\r
+\r
+  /**\r
+       * @exception    SQLException if there is an error\r
+       */\r
+  public String getString(int columnIndex) throws SQLException {\r
+\r
+    if (columnIndex <= numberOfColumns) {\r
+               String val = nextRow[columnIndex-1];\r
+        if (isColumnInExtFile(columnIndex)) {\r
+            // a clob column data is stored in an external \r
+            // file, the reference to it is in the main file. \r
+            // read the data from the external file using the \r
+            // reference from the main file. \r
+                       val = importReadData.getClobColumnFromExtFileAsString(val, \r
+                                                                  columnIndex);\r
+        }\r
+               wasNull = (val == null);\r
+               return val;\r
+    }\r
+    else {\r
+       throw LoadError.invalidColumnNumber(numberOfColumns);\r
+    }\r
+  }\r
+\r
+\r
+    /**\r
+     * Returns <code> java.sql.Clob </code> type object that \r
+     * contains the columnn data from the import file. \r
+     * @param columnIndex number of the column. starts at 1.\r
+     * @exception SQLException if any occurs during create of the clob object.\r
+     */\r
+       public java.sql.Clob getClob(int columnIndex) throws SQLException {\r
+\r
+        java.sql.Clob clob = null;\r
+               if (lobsInExtFile) \r
+        {\r
+            // lob data is in another file, read from the external file.\r
+            clob = importReadData.getClobColumnFromExtFile(\r
+                                         nextRow[columnIndex-1], columnIndex);\r
+        } else {\r
+            // data is in the main export file.\r
+            String data =  nextRow[columnIndex-1];\r
+            if (data != null) {\r
+                clob = new ImportClob(data);                \r
+            }\r
+        }\r
+        \r
+        wasNull = (clob == null);\r
+        return clob;\r
+       }\r
+\r
+       \r
+    /**\r
+     * Returns <code> java.sql.Blob </code> type object that \r
+     * contains the columnn data from the import file. \r
+     * @param columnIndex number of the column. starts at 1.\r
+     * @exception SQLException if any occurs during create of the blob object.\r
+     */\r
+       public java.sql.Blob getBlob(int columnIndex) throws SQLException {\r
+\r
+        java.sql.Blob blob = null;\r
+               if (lobsInExtFile) \r
+        {\r
+            // lob data is in another file, read from the external file.\r
+            blob = importReadData.getBlobColumnFromExtFile(\r
+                                         nextRow[columnIndex-1], columnIndex);\r
+        } else {\r
+            // data is in the main export file, stored in hex format.\r
+            String hexData = nextRow[columnIndex-1];\r
+            byte[] data = null;\r
+            if (hexData != null) {\r
+                // Derby export calls Resultset.getString() method\r
+                // when blob column data is not exported to an \r
+                // external file. Derby getString() method return \r
+                // the data in hex format for binary types, by \r
+                // calling  StringUtil.toHexString(). If the data \r
+                // is being imported from a file that exported \r
+                // from non-derby source, hex data is expected to be \r
+                // same format as one written using \r
+                // StringUtil.toHexString(). StringUtil.fromHexString() \r
+                // is used to covert the hex data  to byte array. \r
+\r
+                data = StringUtil.fromHexString(\r
+                               hexData, 0, hexData.length());\r
+                // fromHexString() returns null if the hex string \r
+                // is invalid one. It is invalid if the data string \r
+                // length is not multiple of 2 or the data string \r
+                // contains non-hex characters. \r
+                if (data == null) {\r
+                    throw PublicAPI.wrapStandardException(\r
+                      StandardException.newException(\r
+                      SQLState.IMPORTFILE_HAS_INVALID_HEXSTRING, \r
+                      hexData));\r
+                }\r
+\r
+                blob = new ImportBlob(data);                \r
+            }\r
+        }\r
+        \r
+        wasNull = (blob == null);\r
+        return blob;\r
+       }\r
+\r
+\r
+\r
+\r
+    /**\r
+     * Returns byte array that contains the columnn data \r
+     * from the import file. \r
+     * @param columnIndex number of the column. starts at 1.\r
+     * @exception SQLException if any error occurs.\r
+     */\r
+       public byte[] getBytes(int columnIndex) throws SQLException {\r
+        \r
+        // This method is called to import data into \r
+        // LONG VARCHAR FOR BIT DATA VARCHAR FOR BIT DATA,  \r
+        // and CHAR FOR BIT DATA  type columns. Data for \r
+        // these type of columns expected to be in the  \r
+        // main import file in hex format.  \r
+\r
+        // convert the binary data in the hex format to a byte array.\r
+        String hexData = nextRow[columnIndex-1];\r
+        // if hex data is null, then column value is SQL NULL\r
+        wasNull = (hexData == null);\r
+        byte[] data = null;\r
+        if (hexData != null) {\r
+            // Derby export calls Resultset.getString() method\r
+            // to write binary data types.  Derby getString() \r
+            // method return the data in hex format for binary types,\r
+            // by  calling  StringUtil.toHexString(). If the data \r
+            // is being imported from a file that is exported \r
+            // from non-derby source, hex data is expected to be \r
+            // same format as one written using \r
+            // StringUtil.toHexString(). StringUtil.fromHexString() \r
+            // is used to covert the hex data  to byte array. \r
+\r
+            data = StringUtil.fromHexString(hexData, 0, hexData.length());\r
+            // fromHexString() returns null if the hex string is invalid one.\r
+            // It is invalid if the data string length is not multiple of 2 \r
+            // or the data string contains non-hex characters. \r
+            if (data == null) {\r
+                throw PublicAPI.wrapStandardException(\r
+                      StandardException.newException(\r
+                      SQLState.IMPORTFILE_HAS_INVALID_HEXSTRING, \r
+                      hexData));\r
+            }\r
+        }\r
+        return data;\r
+       }\r
+\r
+\r
+\r
+    /**\r
+     * Check if for this column type, real data is stored in an \r
+     * external file and only the reference is in the main import \r
+     * file.\r
+     * @param colIndex number of the column. starts at 1.\r
+     * @return         true, if the column data in a different file \r
+     *                 from the main import file , otherwise false.\r
+     */\r
+       private boolean isColumnInExtFile(int colIndex) \r
+       {\r
+               if (lobsInExtFile && \r
+            (tableColumnTypes[colIndex -1] == java.sql.Types.BLOB || \r
+             tableColumnTypes[colIndex -1] == java.sql.Types.CLOB ))\r
+                       return true;\r
+               else \r
+                       return false;\r
+\r
+       }\r
+        \r
+        /**\r
+         * Close the stream and wrap exception in a SQLException\r
+         * \r
+         * @param ex  Exception causing the import error\r
+         * @throws SQLException\r
+         */\r
+        public  SQLException importError(Exception ex) {\r
+            Exception closeException = null;\r
+            if (importReadData != null)\r
+                try {\r
+                    importReadData.closeStream(); \r
+                } catch (Exception e) {\r
+                    closeException = e;\r
+                }\r
+                SQLException le = LoadError.unexpectedError(ex);\r
+                if (closeException != null)\r
+                    le.setNextException(LoadError.unexpectedError(closeException));\r
+                return le;\r
+        }\r
+}\r