db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ma...@apache.org
Subject svn commit: r1337032 - in /db/derby/code/branches/10.5: ./ java/ java/engine/org/apache/derby/iapi/sql/dictionary/ java/testing/org/apache/derbyTesting/functionTests/tests/lang/ java/testing/org/apache/derbyTesting/junit/
Date Fri, 11 May 2012 06:03:18 GMT
Author: mamta
Date: Fri May 11 06:03:18 2012
New Revision: 1337032

URL: http://svn.apache.org/viewvc?rev=1337032&view=rev
Log:
Backporting 2 jiras to 10.5

DERBY-5681 When a foreign key constraint on a table is dropped, the associated statistics
row for the conglomerate is not removed

DERBY-4834 Add helper class for working with index statistics in JUnit tests


Added:
    db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java
      - copied, changed from r1005347, db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java
Modified:
    db/derby/code/branches/10.5/   (props changed)
    db/derby/code/branches/10.5/java/   (props changed)
    db/derby/code/branches/10.5/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
    db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UpdateStatisticsTest.java
    db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/Utilities.java

Propchange: db/derby/code/branches/10.5/
------------------------------------------------------------------------------
  Merged /db/derby/code/branches/10.7:r1336809
  Merged /db/derby/code/trunk:r1005347,1031559,1041374,1042537,1329359

Propchange: db/derby/code/branches/10.5/java/
------------------------------------------------------------------------------
  Merged /db/derby/code/branches/10.7/java:r1336809
  Merged /db/derby/code/trunk/java:r1005347,1031559,1041374,1042537

Modified: db/derby/code/branches/10.5/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.5/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java?rev=1337032&r1=1337031&r2=1337032&view=diff
==============================================================================
--- db/derby/code/branches/10.5/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
(original)
+++ db/derby/code/branches/10.5/java/engine/org/apache/derby/iapi/sql/dictionary/ConglomerateDescriptor.java
Fri May 11 06:03:18 2012
@@ -474,11 +474,11 @@ public final class ConglomerateDescripto
 				physicalCD = null;
 		}
 
+        /* DERBY-5681 Drop statistics */
+        dd.dropStatisticsDescriptors(td.getUUID(), getUUID(), tc);
+
 	    if (dropConglom)
 	    {
-	        /* Drop statistics */
-	        dd.dropStatisticsDescriptors(td.getUUID(), getUUID(), tc);
-	        
 	        /* Drop the physical conglomerate */
 	        tc.dropConglomerate(getConglomerateNumber());
 	    }

Modified: db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UpdateStatisticsTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UpdateStatisticsTest.java?rev=1337032&r1=1337031&r2=1337032&view=diff
==============================================================================
--- db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UpdateStatisticsTest.java
(original)
+++ db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/functionTests/tests/lang/UpdateStatisticsTest.java
Fri May 11 06:03:18 2012
@@ -32,6 +32,7 @@ import org.apache.derbyTesting.junit.JDB
 import org.apache.derbyTesting.junit.TestConfiguration;
 import org.apache.derbyTesting.junit.RuntimeStatisticsParser;
 import org.apache.derbyTesting.junit.SQLUtilities;
+import org.apache.derbyTesting.junit.IndexStatsUtil;
 
 /**
  * Tests for updating the statistics of one index or all the indexes on a
@@ -199,4 +200,121 @@ public class UpdateStatisticsTest extend
         s.execute("drop table t");
         commit();
     }
+    
+    /**
+     * Fixed DERBY-5681(When a foreign key constraint on a table is dropped,
+     *  the associated statistics row for the conglomerate is not removed.)
+     * @throws Exception
+     */
+    public void testDERBY5681() throws Exception {
+        // Helper object to obtain information about index statistics.
+        IndexStatsUtil stats = new IndexStatsUtil(openDefaultConnection());
+        Statement s = createStatement();
+    	
+        //Test - primary key constraint
+        s.executeUpdate("CREATE TABLE TEST_TAB_1 (c11 int not null,"+
+                "c12 int not null, c13 int)");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        //Insert data into table with no constraint and there will be no stat
+        // for that table at this point
+        s.executeUpdate("INSERT INTO TEST_TAB_1 VALUES(1,1,1),(2,2,2)");
+        s.execute("CALL SYSCS_UTIL.SYSCS_UPDATE_STATISTICS('APP','TEST_TAB_1', null)");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        //Add primary key constraint to the table and now we should find a 
+        // statistics row for it
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        stats.assertTableStats("TEST_TAB_1",1);
+        //Dropping primary key constraint will drop the corresponding
+        // statistics
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_PK_1");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        s.execute("CALL SYSCS_UTIL.SYSCS_UPDATE_STATISTICS('APP','TEST_TAB_1', null)");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        //Add the primary key constraint back since it will be used by the next
+        // test to create foreign key constraint
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        //The statistics for primary key constraint has been added
+        stats.assertTableStats("TEST_TAB_1",1);
+
+        //Test - unique key constraint
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_UNQ_1 "+
+        		"UNIQUE (c12)");
+        stats.assertTableStats("TEST_TAB_1",2);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_UNQ_1");
+        stats.assertTableStats("TEST_TAB_1",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_PK_1");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        stats.assertTableStats("TEST_TAB_1",1);
+
+        //Test - unique key constraint on nullable column & non-nullable column
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_UNQ_2 "+
+        		"UNIQUE (c12, c13)");
+        stats.assertTableStats("TEST_TAB_1",3);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_UNQ_2");
+        stats.assertTableStats("TEST_TAB_1",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "DROP CONSTRAINT TEST_TAB_1_PK_1");
+        stats.assertNoStatsTable("TEST_TAB_1");
+        s.executeUpdate("ALTER TABLE TEST_TAB_1 "+
+                "ADD CONSTRAINT TEST_TAB_1_PK_1 "+
+        		"PRIMARY KEY (c11)");
+        stats.assertTableStats("TEST_TAB_1",1);
+        
+        //Test - foreign key but no primary key constraint
+        s.executeUpdate("CREATE TABLE TEST_TAB_3 (c31 int not null)");
+        s.executeUpdate("INSERT INTO TEST_TAB_3 VALUES(1),(2)");
+        s.executeUpdate("ALTER TABLE TEST_TAB_3 "+
+                "ADD CONSTRAINT TEST_TAB_3_FK_1 "+
+        		"FOREIGN KEY(c31) REFERENCES TEST_TAB_1(c11)");
+        stats.assertTableStats("TEST_TAB_3",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_3 "+
+                "DROP CONSTRAINT TEST_TAB_3_FK_1");
+        stats.assertNoStatsTable("TEST_TAB_3");
+
+        //Test - foreign key and primary key constraint
+        s.executeUpdate("CREATE TABLE TEST_TAB_2 (c21 int not null)");
+        s.executeUpdate("INSERT INTO TEST_TAB_2 VALUES(1),(2)");
+        s.executeUpdate("ALTER TABLE TEST_TAB_2 "+
+                "ADD CONSTRAINT TEST_TAB_2_PK_1 "+
+        		"PRIMARY KEY (c21)");
+        stats.assertTableStats("TEST_TAB_2",1);
+        //Add a foreign key constraint and now we should find 2 rows of 
+        // statistics for TEST_TAB_2 - 1 for primary key and other for
+        // foreign key constraint
+        s.executeUpdate("ALTER TABLE TEST_TAB_2 "+
+                "ADD CONSTRAINT TEST_TAB_2_FK_1 "+
+        		"FOREIGN KEY(c21) REFERENCES TEST_TAB_1(c11)");
+        //Like primary key earlier, adding foreign key constraint didn't
+        // automatically add a statistics row for it. Have to run update
+        // statistics manually to get a row added for it's stat
+        stats.assertTableStats("TEST_TAB_2",1);
+        s.execute("CALL SYSCS_UTIL.SYSCS_UPDATE_STATISTICS('APP','TEST_TAB_2', null)");
+        stats.assertTableStats("TEST_TAB_2",2);
+        //Number of statistics row for TEST_TAB_1 will remain unchanged since
+        // it has only primary key defined on it
+        stats.assertTableStats("TEST_TAB_1",1);
+        s.executeUpdate("ALTER TABLE TEST_TAB_2 "+
+                "DROP CONSTRAINT TEST_TAB_2_FK_1");
+        //Dropping the foreign key constraint should remove one of the 
+        // statistics row for TEST_TAB_2. 
+        stats.assertTableStats("TEST_TAB_2",1);
+        s.execute("CALL SYSCS_UTIL.SYSCS_UPDATE_STATISTICS('APP','TEST_TAB_2', null)");
+        stats.assertTableStats("TEST_TAB_2",1);
+        s.execute("drop table TEST_TAB_2");
+        s.execute("drop table TEST_TAB_1");
+        stats.release();
+    }
 }

Copied: db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java
(from r1005347, db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java)
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java?p2=db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java&p1=db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java&r1=1005347&r2=1337032&rev=1337032&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java (original)
+++ db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/IndexStatsUtil.java
Fri May 11 06:03:18 2012
@@ -38,10 +38,24 @@ import junit.framework.Assert;
  * Helper class for obtaining index statistics and doing asserts on them.
  * <p>
  * This implementation assumes all tables/indexes belong to the current schema.
+ * <p>
+ * The <em>timeout</em> value is used to make the utility more resilient to
+ * differences in timing due to varying scheduling decisions, processor speeds,
+ * etc. If the system table contains the wrong number of statistics objects for
+ * the query, it will be queried repeatedly until the right number of statistics
+ * objects is obtained or the query times out.
  */
 public class IndexStatsUtil {
 
+    private static final boolean INDEX = false;
+    private static final boolean TABLE = true;
+    private static final int NO_EXPECTATION = -1;
+    private static final String SEP =
+                BaseJDBCTestCase.getSystemProperty("line.separator");
+
     private final Connection con;
+    /** Timeout in milliseconds. */
+    private final long timeout;
     private PreparedStatement psGetTableId;
     private PreparedStatement psGetStatsForTable;
     private PreparedStatement psGetIndexId;
@@ -50,11 +64,39 @@ public class IndexStatsUtil {
     private PreparedStatement psGetIdToNameMapConglom;
     private PreparedStatement psGetIdToNameMapTable;
 
-    public IndexStatsUtil(Connection con)
-            throws SQLException {
+    /**
+     * Creates an instance querying the given database with no timeout set.
+     * <p>
+     * Querying with no timeout means that if there are too few or too many
+     * statistics objects matching the query, a failure will be raised
+     * immediately.
+     *
+     * @param con connection to the database to query
+     */
+    public IndexStatsUtil(Connection con) {
+        this(con, 0L);
+    }
+
+    /**
+     * Creates an instance querying the given database with the specified
+     * timeout value.
+     *
+     * @param con connection to the database to query
+     * @param timeout the longest time to wait to see if the expectations for a
+     *      query are met (milliseconds)
+     */
+    public IndexStatsUtil(Connection con, long timeout) {
         // Rely on auto-commit to release locks.
-        Assert.assertTrue(con.getAutoCommit());
+        try {
+            Assert.assertTrue(con.getAutoCommit());
+        } catch (SQLException sqle) {
+            Assert.fail("Failed to get auto commit: " + sqle.getMessage());
+        }
+        if (timeout < 0) {
+            throw new IllegalArgumentException("timeout cannot be negative");
+        }
         this.con = con;
+        this.timeout = timeout;
     }
 
     /**
@@ -68,6 +110,16 @@ public class IndexStatsUtil {
     }
 
     /**
+     * Asserts that there are no existing statistics for the specified table.
+     *
+     * @throws SQLException if obtaining the statistics fails
+     */
+    public void assertNoStatsTable(String table)
+            throws SQLException {
+        assertTableStats(table, 0);
+    }
+
+    /**
      * Asserts that the expected number of statistics exists.
      *
      * @param expectedCount expected number of statistics
@@ -75,7 +127,11 @@ public class IndexStatsUtil {
      */
     public void assertStats(int expectedCount)
             throws SQLException {
-        assertStatCount(getStats(), "<ALL>", expectedCount, false);
+        IdxStats[] ret = getStats();
+        if (ret.length != expectedCount) {
+            Assert.assertEquals(buildStatString(ret, "<ALL TABLES>"),
+                    expectedCount, ret.length);
+        }
     }
 
     /**
@@ -88,7 +144,7 @@ public class IndexStatsUtil {
      */
     public void assertTableStats(String table, int expectedCount)
             throws SQLException {
-        assertStatCount(getStatsTable(table), table, expectedCount, false);
+        getStatsTable(table, expectedCount);
     }
 
     /**
@@ -101,24 +157,7 @@ public class IndexStatsUtil {
      */
     public void assertIndexStats(String index, int expectedCount)
             throws SQLException {
-        assertStatCount(getStatsIndex(index), index, expectedCount, true);
-    }
-
-    /**
-     * Asserts that the expected number of statistics exists.
-     *
-     * @param stats statistics
-     * @param conglom conglomerate name
-     * @param expectedCount expected number of statistics
-     * @param isIndex {@code true} if the conglomerate is an index
-     */
-    private void assertStatCount(IdxStats[] stats, String conglom,
-                                 int expectedCount, boolean isIndex) {
-        if (stats.length != expectedCount) {
-            String name = (isIndex ? "index " : "table ") + "'" + conglom + "'";
-            Assert.assertEquals(buildStatString(stats, name),
-                    expectedCount, stats.length);
-        }
+        getStatsIndex(index, expectedCount);
     }
 
     /**
@@ -129,8 +168,6 @@ public class IndexStatsUtil {
      * @return A string representation of the statistics.
      */
     private String buildStatString(IdxStats[] stats, String name) {
-        String SEP =
-                BaseJDBCTestCase.getSystemProperty("line.separator");
         StringBuffer sb = new StringBuffer(
                 "Index statistics for " + name + SEP);
         for (int i=0; i < stats.length; i++) {
@@ -153,7 +190,8 @@ public class IndexStatsUtil {
             throws SQLException {
         if (psGetStats == null) {
             psGetStats = con.prepareStatement(
-                    "select * from SYS.SYSSTATISTICS");
+                    "select * from SYS.SYSSTATISTICS " +
+                    "order by TABLEID, REFERENCEID, COLCOUNT");
         }
         return buildStatisticsList(psGetStats.executeQuery(), getIdToNameMap());
     }
@@ -167,23 +205,40 @@ public class IndexStatsUtil {
      */
     public IdxStats[] getStatsTable(String table)
             throws SQLException {
+        return getStatsTable(table, NO_EXPECTATION);
+    }
+
+    /**
+     * Obtains statistics for the specified table, fails if the number of
+     * statistics objects isn't as expected within the timeout.
+     *
+     * @param table table name
+     * @param expectedCount number of expected statistics objects
+     * @return A list of statistics entries (possibly empty).
+     * @throws SQLException if obtaining the statistics fail
+     */
+    public IdxStats[] getStatsTable(String table, int expectedCount)
+            throws SQLException {
         if (psGetTableId == null) {
             psGetTableId = con.prepareStatement(
                 "select TABLEID from SYS.SYSTABLES where TABLENAME = ?");
         }
-        if (psGetStatsForTable == null) {
-            psGetStatsForTable = con.prepareStatement(
-                "select * from SYS.SYSSTATISTICS where TABLEID = ?");
-        }
         psGetTableId.setString(1, table);
         ResultSet rs = psGetTableId.executeQuery();
         Assert.assertTrue("No such table: " + table, rs.next());
         String tableId = rs.getString(1);
         Assert.assertFalse("More than one table named " + table, rs.next());
         rs.close();
-        psGetStatsForTable.setString(1, tableId);
-        return buildStatisticsList(
-                psGetStatsForTable.executeQuery(), getIdToNameMap());
+
+        IdxStats[] ret = querySystemTable(tableId, TABLE, expectedCount);
+        // Avoid building the stat string if not necessary.
+        if (expectedCount != NO_EXPECTATION && ret.length != expectedCount) {
+            Assert.assertEquals("failed to get statistics for table " + table +
+                    " (#expected=" + expectedCount + ", timeout=" + timeout +
+                    ")" + SEP + buildStatString(ret, table),
+                    expectedCount, ret.length);
+        }
+        return ret;
     }
 
     /**
@@ -195,25 +250,93 @@ public class IndexStatsUtil {
      */
     public IdxStats[] getStatsIndex(String index)
              throws SQLException {
+        return getStatsIndex(index, NO_EXPECTATION);
+    }
+
+    /**
+     * Obtains statistics for the specified index, fails if the number of
+     * statistics objects isn't as expected within the timeout.
+     *
+     * @param index index name
+     * @param expectedCount number of expected statistics objects
+     * @return A list of statistics entries (possibly empty).
+     * @throws SQLException if obtaining the statistics fail
+     */
+    public IdxStats[] getStatsIndex(String index, int expectedCount)
+             throws SQLException {
         if (psGetIndexId == null) {
             psGetIndexId = con.prepareStatement(
                     "select CONGLOMERATEID from SYS.SYSCONGLOMERATES where " +
                     "CONGLOMERATENAME = ? and " +
                     "CAST(ISINDEX as VARCHAR(5)) = 'true'");
         }
-        if (psGetStatsForIndex == null) {
-            psGetStatsForIndex = con.prepareStatement(
-                   "select * from SYS.SYSSTATISTICS where REFERENCEID = ?");
-        }
         psGetIndexId.setString(1, index);
         ResultSet rs = psGetIndexId.executeQuery();
         Assert.assertTrue("No such index: " + index, rs.next());
         String indexId = rs.getString(1);
         Assert.assertFalse("More than one index named " + index, rs.next());
         rs.close();
-        psGetStatsForIndex.setString(1, indexId);
-        return buildStatisticsList(
-                psGetStatsForIndex.executeQuery(), getIdToNameMap());
+
+        IdxStats[] ret = querySystemTable(indexId, INDEX, expectedCount);
+        // Avoid building the stat string if not necessary.
+        if (expectedCount != NO_EXPECTATION && ret.length != expectedCount) {
+            Assert.assertEquals("failed to get statistics for index " + index +
+                    " (#expected=" + expectedCount + ", timeout=" + timeout +
+                    ")" + SEP + buildStatString(ret, index),
+                    expectedCount, ret.length);
+        }
+        return ret;
+    }
+
+    /**
+     * Queries the system table {@code SYS.SYSSTATISTICS} for statistics
+     * associated with a specific table or index.
+     *
+     * @param conglomId conglomerate id (UUID)
+     * @param isTable tells if the conglomerate is a table or an index
+     * @param expectedCount the number of statistics objects expected, use
+     *      {@code NO_EXPECTATION} to return whatever matches the query
+     *      immediately
+     */
+    private IdxStats[] querySystemTable(String conglomId, boolean isTable,
+                                        int expectedCount)
+            throws SQLException {
+        // Assign the correct prepared statement.
+        PreparedStatement ps;
+        if (isTable) {
+            if (psGetStatsForTable == null) {
+                psGetStatsForTable = con.prepareStatement(
+                        "select * from SYS.SYSSTATISTICS " +
+                            "where TABLEID = ? " +
+                            "order by REFERENCEID, COLCOUNT");
+            }
+            ps = psGetStatsForTable;
+        } else {
+            if (psGetStatsForIndex == null) {
+                psGetStatsForIndex = con.prepareStatement(
+                        "select * from SYS.SYSSTATISTICS " +
+                            "where REFERENCEID = ? " +
+                            "order by COLCOUNT");
+            }
+            ps = psGetStatsForIndex;
+        }
+        ps.setString(1, conglomId);
+
+        long started = System.currentTimeMillis();
+        long waited = -1;
+        IdxStats[] ret = null;
+        while (waited < timeout) {
+            // Don't wait the first time.
+            if (ret != null) {
+                Utilities.sleep(Math.min(250L, timeout - waited));
+            }
+            ret = buildStatisticsList(ps.executeQuery(), getIdToNameMap());
+            if (expectedCount == NO_EXPECTATION || ret.length == expectedCount){
+                break;
+            }
+            waited = System.currentTimeMillis() - started;
+        }
+        return ret;
     }
 
     /**
@@ -383,10 +506,34 @@ public class IndexStatsUtil {
             sb.append("{tableId=").append(tableId).
                     append(", tableName=").append(tableName).
                     append(", indexName=").append(indexName).
+                    append(", lcols=").append(lcols).
                     append(", rows=").append(rows).
                     append(", unique/card=").append(card).
                     append(", created=").append(created).append('}');
             return sb.toString();
         }
+
+        /**
+         * Equality is based on the statistics entry UUID.
+         *
+         * @param obj other object
+         * @return {@code true} if the other object is considered equal to this
+         */
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            final IdxStats other = (IdxStats) obj;
+            return this.id.equals(other.id);
+        }
+
+        public int hashCode() {
+            int hash = 7;
+            hash = 17 * hash + this.id.hashCode();
+            return hash;
+        }
     }
 }

Modified: db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/Utilities.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/Utilities.java?rev=1337032&r1=1337031&r2=1337032&view=diff
==============================================================================
--- db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/Utilities.java
(original)
+++ db/derby/code/branches/10.5/java/testing/org/apache/derbyTesting/junit/Utilities.java
Fri May 11 06:03:18 2012
@@ -1,6 +1,6 @@
 /*
  *
- * Derby - Class Utilities
+ * Derby - Class org.apache.derbyTesting.junit.Utilities
  *
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -22,142 +22,130 @@ package org.apache.derbyTesting.junit;
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.io.StringReader;
 import java.io.UnsupportedEncodingException;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.sql.ResultSet;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.util.Arrays;
 import java.util.StringTokenizer;
 
+import junit.framework.Assert;
 
 /**
- * General non-JDBC related utilities relocated from TestUtil
- *
- *
+ * General non-JDBC related utilities.
+ * Some of these were relocated from TestUtil.
  */
 public class Utilities {
 
-    public Utilities() {
-        // TODO Auto-generated constructor stub
-    }
-        /**
-         * Just converts a string to a hex literal to assist in converting test
-         * cases that used to insert strings into bit data tables
-         * Converts using UTF-16BE just like the old casts used to.
-         *
-         * @param s  String to convert  (e.g
-         * @return hex literal that can be inserted into a bit column.
-         */
-        public static String stringToHexLiteral(String s)
-        {
-                byte[] bytes;
-                String hexLiteral = null;
-                try {
-                        bytes = s.getBytes("UTF-16BE");
-                        hexLiteral = convertToHexString(bytes);
-                }
-                catch (UnsupportedEncodingException ue)
-                {
-                        System.out.println("This shouldn't happen as UTF-16BE should be supported");
-                        ue.printStackTrace();
-                }
+    private Utilities() { }
 
-                return hexLiteral;
+    /**
+     * Converts a string to a hex literal to assist in converting test
+     * cases that used to insert strings into bit data tables.
+     * <p>
+     * Converts using UTF-16BE just like the old casts used to.
+     *
+     * @param s string to convert
+     * @return hex literal that can be inserted into a bit column.
+     */
+    public static String stringToHexLiteral(String s) {
+        byte[] bytes;
+        String hexLiteral = null;
+        try {
+            bytes = s.getBytes("UTF-16BE");
+            hexLiteral = convertToHexString(bytes);
+        } catch (UnsupportedEncodingException ue) {
+            Assert.fail("Encoding UTF-16BE unavailable: " + ue.getMessage());
         }
 
-        /**
-         * Convert a byte array to a hex string suitable for insert 
-         * @param buf  byte array to convert
-         * @return     formated string representing byte array
-         */
-        private static String convertToHexString(byte [] buf)
-        {
-                StringBuffer str = new StringBuffer();
-                str.append("X'");
-                String val;
-                int byteVal;
-                for (int i = 0; i < buf.length; i++)
-                {
-                        byteVal = buf[i] & 0xff;
-                        val = Integer.toHexString(byteVal);
-                        if (val.length() < 2)
-                                str.append("0");
-                        str.append(val);
-                }
-                return str.toString() +"'";
+        return hexLiteral;
+    }
+
+    /**
+     * Convert a byte array to a hex string suitable for insert.
+     *
+     * @param buf  byte array to convert
+     * @return     formated string representing byte array
+     */
+    private static String convertToHexString(byte[] buf) {
+        StringBuffer str = new StringBuffer();
+        str.append("X'");
+        String val;
+        int byteVal;
+        for (int i = 0; i < buf.length; i++) {
+            byteVal = buf[i] & 0xff;
+            val = Integer.toHexString(byteVal);
+            if (val.length() < 2) {
+                str.append("0");
+            }
+            str.append(val);
         }
+        return str.toString() + "'";
+    }
+
+    /**
+     * Creates a string with the specified length.
+     * <p>
+     * Called from various tests to test edge cases and such.
+     *
+     * @param c             character to repeat
+     * @param repeatCount   Number of times to repeat character
+     * @return              String of repeatCount characters c
+     */
+    public static String repeatChar(String c, int repeatCount) {
+        char[] chArray = new char[repeatCount];
+        Arrays.fill(chArray, c.charAt(0));
+        return String.valueOf(chArray);
+    }
 
-    	/**
-    	 * repeatChar is used to create strings of varying lengths.
-    	 * called from various tests to test edge cases and such.
-    	 *
-    	 * @param c             character to repeat
-    	 * @param repeatCount   Number of times to repeat character
-    	 * @return              String of repeatCount characters c
-    	 */
-       public static String repeatChar(String c, int repeatCount)
-       {
-    	   char ch = c.charAt(0);
-
-    	   char[] chArray = new char[repeatCount];
-    	   for (int i = 0; i < repeatCount; i++)
-    	   {
-    		   chArray[i] = ch;
-    	   }
-
-    	   return new String(chArray);
-
-       }
-
-        /**
-         * Print out resultSet in two dimensional array format, for use by
-         * JDBC.assertFullResultSet(rs,expectedRows) expectedRows argument.
-         * Useful while converting tests to get output in correct format.
-         * 
-         * @param rs
-         * @throws SQLException
-         */
-        public static void showResultSet(ResultSet rs) throws SQLException {
+    /**
+     * Print out resultSet in two dimensional array format, for use by
+     * JDBC.assertFullResultSet(rs,expectedRows) expectedRows argument.
+     * Useful while converting tests to get output in correct format.
+     *
+     * @param rs result set to print
+     * @throws SQLException if accessing the result set fails
+     */
+    public static void showResultSet(ResultSet rs) throws SQLException {
+        System.out.print("{");
+        int row = 0;
+        boolean next = rs.next();
+        while (next) {
+            row++;
+            ResultSetMetaData rsmd = rs.getMetaData();
+            int nocols = rsmd.getColumnCount();
             System.out.print("{");
-            int row = 0;
-            boolean next = rs.next();
-            while (next) {
-                row++;
-                ResultSetMetaData rsmd = rs.getMetaData();
-                int nocols = rsmd.getColumnCount();
-                System.out.print("{");
-                
-                for (int i = 0; i < nocols; i++)
-                {
-                	String val = rs.getString(i+1);
-                	if (val == null)
-                		System.out.print("null");
-                	else
-                		System.out.print("\"" + rs.getString(i+1) + "\"");
-                    if (i == (nocols -1))
-                        System.out.print("}");
-                    else
-                        System.out.print(",");
-                           
+
+            for (int i = 0; i < nocols; i++) {
+                String val = rs.getString(i + 1);
+                if (val == null) {
+                    System.out.print("null");
+                } else {
+                    System.out.print("\"" + rs.getString(i + 1) + "\"");
+                }
+                if (i == (nocols - 1)) {
+                    System.out.print("}");
+                } else {
+                    System.out.print(",");
                 }
-                next = rs.next();
-                   
-                if (next)
-                    System.out.println(",");
-                else
-                    System.out.println("};\n");
+
+            }
+            next = rs.next();
+
+            if (next) {
+                System.out.println(",");
+            } else {
+                System.out.println("};\n");
             }
         }
-        
+    }
+
     /**
-     * Calls the public method <code>getInfo</code> of the sysinfo tool within
-     * this JVM and returns a <code>BufferedReader</code> for reading its 
+     * Calls the public method {@code getInfo} of the sysinfo tool within
+     * this JVM and returns a {@code BufferedReader} for reading its
      * output. This is useful for obtaining system information that could be 
      * used to verify, for example, values returned by Derby MBeans.
      * 
@@ -173,13 +161,13 @@ public class Utilities {
         pw.close();
         byte[] outBytes = byteStream.toByteArray();
         BufferedReader sysinfoOutput = new BufferedReader(
-                    new InputStreamReader(
-                            new ByteArrayInputStream(outBytes)));
+                new InputStreamReader(
+                new ByteArrayInputStream(outBytes)));
         return sysinfoOutput;
     }
-    
+
     /**
-     * <p>Calls the public method <code>getSysInfo()</code> of the Network

+     * <p>Calls the public method {@code getSysInfo} of the Network
      * Server instance associated with the current test configuration and 
      * returns the result as a BufferedReader, making it easy to analyse the 
      * output line by line.</p>
@@ -192,29 +180,24 @@ public class Utilities {
      * @see org.apache.derby.drda.NetworkServerControl#getSysinfo()
      */
     public static BufferedReader getSysinfoFromServer() throws Exception {
-        
+
         return new BufferedReader(new StringReader(
                 NetworkServerTestSetup.getNetworkServerControl().getSysinfo()));
     }
-    
+
     /**
      * Splits a string around matches of the given delimiter character.
      * Copied from org.apache.derby.iapi.util.StringUtil
      *
      * Where applicable, this method can be used as a substitute for
-     * <code>String.split(String regex)</code>, which is not available
+     * {@code String.split(String regex)}, which is not available
      * on a JSR169/Java ME platform.
      *
      * @param str the string to be split
      * @param delim the delimiter
      * @throws NullPointerException if str is null
      */
-    static public String[] split(String str, char delim)
-    {
-        if (str == null) {
-            throw new NullPointerException("str can't be null");
-        }
-
+    public static String[] split(String str, char delim) {
         // Note the javadoc on StringTokenizer:
         //     StringTokenizer is a legacy class that is retained for
         //     compatibility reasons although its use is discouraged in
@@ -231,4 +214,21 @@ public class Utilities {
         return s;
     }
 
+    /**
+     * Sleeps the specified number of milliseconds.
+     *
+     * @param millis sleep duration
+     */
+    public static void sleep(long millis) {
+        long started = System.currentTimeMillis();
+        long waited = 0;
+        while (waited < millis) {
+            try {
+                Thread.sleep(millis - waited);
+            } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+            }
+            waited = System.currentTimeMillis() - started;
+        }
+    }
 }



Mime
View raw message