Author: reschke
Date: Wed Sep 16 15:21:01 2015
New Revision: 1703424

URL: http://svn.apache.org/r1703424
Log:
OAK-3394: RDBDocumentStore startup: log more DDL information (incl. index 
information) (ported to 1.2)

Modified:
    jackrabbit/oak/branches/1.2/   (props changed)
    
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
    
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java

Propchange: jackrabbit/oak/branches/1.2/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Wed Sep 16 15:21:01 2015
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673713,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678124,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680172,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1681955,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684820
 
,1684868,1685023,1685075,1685370,1685552,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688634,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689831,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691139,1691151,1691159,1691167,1691183,1691188,1691210,1691280,1691307,1691331-1691333,1691345,1691384-1691385,1691401,1691509,1692133-1692134,1692156,1692250,1692274,1692363,1692382,1692478,1692955,1693002,1693030,1693209,1693421,1693525-1693526,1694007,1694393-1694394,1695050,1695122,1695280,1695299,1695457,1695482,1695507,1695521,1695540,1696194,1696242,1696285,1696578,1696759,1696916,1697363,1697373,1697410,1697
 
582,1697589,1697616,1697672,1700191,1700231,1700397,1700403,1700506,1700571,1700727,1700749,1700769,1700775,1701065,1701619,1701733,1701743,1701750,1701768,1701806,1701810,1701814,1701948,1701955,1701959,1701986,1702022,1702272,1702387,1702405,1702423,1702942,1702960,1703212,1703411
+/jackrabbit/oak/trunk:1672350,1672468,1672537,1672603,1672642,1672644,1672834-1672835,1673351,1673410,1673414-1673415,1673436,1673644,1673662-1673664,1673669,1673695,1673713,1673738,1673787,1673791,1674046,1674065,1674075,1674107,1674228,1674780,1674880,1675054-1675055,1675319,1675332,1675354,1675357,1675382,1675555,1675566,1675593,1676198,1676237,1676407,1676458,1676539,1676670,1676693,1676703,1676725,1677579,1677581,1677609,1677611,1677774,1677788,1677797,1677804,1677806,1677939,1677991,1678023,1678095-1678096,1678124,1678171,1678173,1678211,1678323,1678758,1678938,1678954,1679144,1679165,1679191,1679232,1679235,1679503,1679958,1679961,1680170,1680172,1680182,1680222,1680232,1680236,1680461,1680633,1680643,1680747,1680805-1680806,1680903,1681282,1681767,1681918,1681955,1682042,1682218,1682235,1682437,1682494,1682555,1682855,1682904,1683059,1683089,1683213,1683249,1683259,1683278,1683323,1683687,1683700,1684174-1684175,1684186,1684376,1684442,1684561,1684570,1684601,1684618,1684820
 
,1684868,1685023,1685075,1685370,1685552,1685589-1685590,1685840,1685964,1685977,1685989,1685999,1686023,1686032,1686097,1686162,1686229,1686234,1686253,1686414,1686780,1686854,1686857,1686971,1687053-1687055,1687175,1687196,1687198,1687220,1687239-1687240,1687301,1687441,1687553,1688089-1688090,1688172,1688179,1688349,1688421,1688436,1688453,1688616,1688622,1688634,1688636,1688817,1689003-1689004,1689008,1689577,1689581,1689623,1689810,1689828,1689831,1689833,1689903,1690017,1690043,1690047,1690057,1690247,1690249,1690634-1690637,1690650,1690669,1690674,1690885,1690941,1691139,1691151,1691159,1691167,1691183,1691188,1691210,1691280,1691307,1691331-1691333,1691345,1691384-1691385,1691401,1691509,1692133-1692134,1692156,1692250,1692274,1692363,1692382,1692478,1692955,1693002,1693030,1693209,1693421,1693525-1693526,1694007,1694393-1694394,1695050,1695122,1695280,1695299,1695457,1695482,1695507,1695521,1695540,1696194,1696242,1696285,1696578,1696759,1696916,1697363,1697373,1697410,1697
 
582,1697589,1697616,1697672,1700191,1700231,1700397,1700403,1700506,1700571,1700727,1700749,1700769,1700775,1701065,1701619,1701733,1701743,1701750,1701768,1701806,1701810,1701814,1701948,1701955,1701959,1701986,1702022,1702272,1702387,1702405,1702423,1702942,1702960,1703212,1703395,1703411
 /jackrabbit/trunk:1345480

Modified: 
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java?rev=1703424&r1=1703423&r2=1703424&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
 (original)
+++ 
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
 Wed Sep 16 15:21:01 2015
@@ -38,9 +38,11 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.TreeMap;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.locks.Lock;
@@ -555,12 +557,99 @@ public class RDBDocumentStore implements
         return sqlType == Types.VARBINARY || sqlType == Types.BINARY || 
sqlType == Types.LONGVARBINARY;
     }
 
-    private static String dumpTableMeta(int idType, String idTypeName, int 
idPrecision, int dataType, String dataTypeName,
-            int dataPrecision, int bdataType, String bdataTypeName, int 
bdataPrecision) {
-        return String
-                .format("type of ID: %d (%s) precision %d (-> %s), type of 
DATA: %d (%s) precision %d, type of BDATA: %d (%s) precision %d",
-                        idType, idTypeName, idPrecision, isBinaryType(idType) 
? "binary" : "character", dataType, dataTypeName,
-                        dataPrecision, bdataType, bdataTypeName, 
bdataPrecision);
+    private void obtainFlagsFromResultSetMeta(ResultSetMetaData met) throws 
SQLException {
+        for (int i = 1; i <= met.getColumnCount(); i++) {
+            String lcName = met.getColumnName(i).toLowerCase(Locale.ENGLISH);
+            if ("id".equals(lcName)) {
+                this.isIdBinary = isBinaryType(met.getColumnType(i));
+            }
+            if ("data".equals(lcName)) {
+                this.dataLimitInOctets = met.getPrecision(i);
+            }
+        }
+    }
+
+    private String asQualifiedDbName(String one, String two) {
+        if (one == null && two == null) {
+            return null;
+        }
+        else {
+            one = one == null ? "" : one.trim();
+            two = two == null ? "" : two.trim();
+            return one.isEmpty() ? two : one + "." + two;
+        }
+    }
+
+    private String dumpIndexData(DatabaseMetaData met, ResultSetMetaData rmet, 
String tableName) {
+
+        ResultSet rs = null;
+        try {
+            // if the result set metadata provides a table name, use that (the 
other one
+            // might be inaccurate due to case insensitivity issues
+            String rmetTableName = rmet.getTableName(1);
+            if (rmetTableName != null && !rmetTableName.trim().isEmpty()) {
+                tableName = rmetTableName.trim();
+            }
+
+            String rmetSchemaName = rmet.getSchemaName(1);
+            rmetSchemaName = rmetSchemaName == null ? "" : 
rmetSchemaName.trim();
+
+            Map<String, Map<String, Object>> indices = new TreeMap<String, 
Map<String, Object>>();
+            StringBuilder sb = new StringBuilder();
+            rs = met.getIndexInfo(null, null, tableName, false, true);
+            while (rs.next()) {
+                String name = asQualifiedDbName(rs.getString(5), 
rs.getString(6));
+                if (name != null) {
+                    Map<String, Object> info = indices.get(name);
+                    if (info == null) {
+                        info = new HashMap<String, Object>();
+                        indices.put(name, info);
+                        info.put("fields", new TreeMap<Integer, String>());
+                    }
+                    info.put("nonunique", rs.getBoolean(4));
+                    info.put("type", rs.getInt(7));
+                    String inSchema = rs.getString(2);
+                    inSchema = inSchema == null ? "" : inSchema.trim();
+                    // skip indices on tables in other schemas in case we have 
that information
+                    if (rmetSchemaName.isEmpty() || inSchema.isEmpty() || 
rmetSchemaName.equals(inSchema)) {
+                        String tname = asQualifiedDbName(inSchema, 
rs.getString(3));
+                        info.put("tname", tname);
+                        String cname = rs.getString(9);
+                        if (cname != null) {
+                            String order = "A".equals(rs.getString(10)) ? " 
ASC" : ("D".equals(rs.getString(10)) ? " DESC" : "");
+                            ((Map<Integer, String>) 
info.get("fields")).put(rs.getInt(8), cname + order);
+                        }
+                    }
+                }
+            }
+            for (Entry<String, Map<String, Object>> index : 
indices.entrySet()) {
+                boolean nonUnique = ((Boolean) 
index.getValue().get("nonunique"));
+                Map<Integer, String> fields = (Map<Integer, String>) 
index.getValue().get("fields");
+                if (!fields.isEmpty()) {
+                    if (sb.length() != 0) {
+                        sb.append(", ");
+                    }
+                    sb.append(String.format("%sindex %s on %s (", nonUnique ? 
"" : "unique ", index.getKey(),
+                            index.getValue().get("tname")));
+                    String delim = "";
+                    for (String field : fields.values()) {
+                        sb.append(delim);
+                        delim = ", ";
+                        sb.append(field);
+                    }
+                    sb.append(")");
+                }
+            }
+            if (sb.length() != 0) {
+                sb.insert(0, "/* ").append(" */");
+            }
+            return sb.toString();
+        } catch (SQLException ex) {
+            // well it was best-effort
+            return "";
+        } finally {
+            this.ch.closeResultSet(rs);
+        }
     }
 
     private void createTableFor(Connection con, Collection<? extends Document> 
col, List<String> tablesCreated,
@@ -575,18 +664,20 @@ public class RDBDocumentStore implements
         ResultSet checkResultSet = null;
         Statement creatStatement = null;
         try {
-            checkStatement = con.prepareStatement("select ID, DATA, BDATA from 
" + tableName + " where ID = ?");
+            checkStatement = con.prepareStatement("select * from " + tableName 
+ " where ID = ?");
             checkStatement.setString(1, "0:/");
             checkResultSet = checkStatement.executeQuery();
 
             if (col.equals(Collection.NODES)) {
                 // try to discover size of DATA column
                 ResultSetMetaData met = checkResultSet.getMetaData();
-                this.isIdBinary = isBinaryType(met.getColumnType(1));
-                this.dataLimitInOctets = met.getPrecision(2);
-                diagnostics.append(dumpTableMeta(met.getColumnType(1), 
met.getColumnTypeName(1), met.getPrecision(1),
-                        met.getColumnType(2), met.getColumnTypeName(2), 
met.getPrecision(2), met.getColumnType(3),
-                        met.getColumnTypeName(3), met.getPrecision(3)));
+                obtainFlagsFromResultSetMeta(met);
+                String tableInfo = RDBJDBCTools.dumpResultSetMeta(met);
+                diagnostics.append(tableInfo);
+                String indexInfo = dumpIndexData(con.getMetaData(), met, 
tableName);
+                if (!indexInfo.isEmpty()) {
+                    diagnostics.append(" ").append(indexInfo);
+                }
             }
             tablesPresent.add(tableName);
         } catch (SQLException ex) {
@@ -609,15 +700,17 @@ public class RDBDocumentStore implements
                 tablesCreated.add(tableName);
 
                 if (col.equals(Collection.NODES)) {
-                    PreparedStatement pstmt = con.prepareStatement("select ID, 
DATA, BDATA from " + tableName + " where ID = ?");
+                    PreparedStatement pstmt = con.prepareStatement("select * 
from " + tableName + " where ID = ?");
                     pstmt.setString(1, "0:/");
                     ResultSet rs = pstmt.executeQuery();
                     ResultSetMetaData met = rs.getMetaData();
-                    this.isIdBinary = isBinaryType(met.getColumnType(1));
-                    this.dataLimitInOctets = met.getPrecision(2);
-                    diagnostics.append(dumpTableMeta(met.getColumnType(1), 
met.getColumnTypeName(1), met.getPrecision(1),
-                            met.getColumnType(2), met.getColumnTypeName(2), 
met.getPrecision(2), met.getColumnType(3),
-                            met.getColumnTypeName(3), met.getPrecision(3)));
+                    obtainFlagsFromResultSetMeta(met);
+                    String tableInfo = RDBJDBCTools.dumpResultSetMeta(met);
+                    diagnostics.append(tableInfo);
+                    String indexInfo = dumpIndexData(con.getMetaData(), met, 
tableName);
+                    if (!indexInfo.isEmpty()) {
+                        diagnostics.append(" ").append(indexInfo);
+                    }
                 }
             }
             catch (SQLException ex2) {

Modified: 
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java?rev=1703424&r1=1703423&r2=1703424&view=diff
==============================================================================
--- 
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java
 (original)
+++ 
jackrabbit/oak/branches/1.2/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBJDBCTools.java
 Wed Sep 16 15:21:01 2015
@@ -18,10 +18,14 @@ package org.apache.jackrabbit.oak.plugin
 
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
+import java.sql.Types;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
 
 import javax.annotation.Nonnull;
 
@@ -123,6 +127,36 @@ public class RDBJDBCTools {
         return String.format("%s (%d)", name, isolationLevel);
     }
 
+    private static String dumpColumnMeta(String columnName, int type, String 
typeName, int precision) {
+        boolean skipPrecision = precision == 0 || (type == Types.SMALLINT && 
precision == 5)
+                || (type == Types.BIGINT && precision == 19);
+        return skipPrecision ? String.format("%s %s", columnName, typeName)
+                : String.format("%s %s(%d)", columnName, typeName, precision);
+    }
+
+    /**
+     * Return approximated string representation of table DDL.
+     */
+    protected static String dumpResultSetMeta(ResultSetMetaData met) {
+        try {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format("%s.%s: ", met.getSchemaName(1).trim(), 
met.getTableName(1).trim()));
+            Map<String, Integer> types = new TreeMap<String, Integer>();
+            for (int i = 1; i <= met.getColumnCount(); i++) {
+                if (i > 1) {
+                    sb.append(", ");
+                }
+                sb.append(
+                        dumpColumnMeta(met.getColumnName(i), 
met.getColumnType(i), met.getColumnTypeName(i), met.getPrecision(i)));
+                types.put(met.getColumnTypeName(i), met.getColumnType(i));
+            }
+            sb.append(" /* " + types.toString() + " */");
+            return sb.toString();
+        } catch (SQLException ex) {
+            return "Column metadata unavailable: " + ex.getMessage();
+        }
+    }
+
     /**
      * Return a string containing additional messages from chained exceptions.
      */


Reply via email to