You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by ju...@apache.org on 2008/04/22 03:58:19 UTC

svn commit: r650355 - in /jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle: BundleDbPersistenceManager.java util/BundleBinding.java

Author: jukka
Date: Mon Apr 21 18:58:18 2008
New Revision: 650355

URL: http://svn.apache.org/viewvc?rev=650355&view=rev
Log:
1.4: Merged revision 649733 (JCR-1474)

Modified:
    jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
    jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java

Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java?rev=650355&r1=650354&r2=650355&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java Mon Apr 21 18:58:18 2008
@@ -364,7 +364,7 @@
      * Sets the minimum blob size. This size defines the threshold of which
      * size a property is included in the bundle or is stored in the blob store.
      *
-     * @param minBlobSize the minimum blobsize in bytes.
+     * @param minBlobSize the minimum blob size in bytes.
      */
     public void setMinBlobSize(String minBlobSize) {
         this.minBlobSize = Integer.decode(minBlobSize).intValue();
@@ -496,7 +496,7 @@
     }
 
     /**
-     * Indicates if the username should be included when retrieving the tables
+     * Indicates if the user name should be included when retrieving the tables
      * during {@link #checkTablesExist()}.
      * <p/>
      * Please note that this currently only needs to be changed for oracle based
@@ -753,17 +753,14 @@
      * Checks a single bundle for inconsistencies, ie. inexistent child nodes
      * and inexistent parents.
      *
-     * @param id
-     *            node id for the bundle to check
-     * @param bundle
-     *            the bundle to check
-     * @param fix
-     *            if true, repair things that can be repaired
-     * @param modifications
-     *            if <code>fix == true</code>, collect the repaired
-     *            {@linkplain NodePropBundle bundles} here
+     * @param id node id for the bundle to check
+     * @param bundle the bundle to check
+     * @param fix if <code>true</code>, repair things that can be repaired
+     * @param modifications if <code>fix == true</code>, collect the repaired
+     * {@linkplain NodePropBundle bundles} here
      */
-    protected void checkBundleConsistency(NodeId id, NodePropBundle bundle, boolean fix, Collection modifications) {
+    protected void checkBundleConsistency(NodeId id, NodePropBundle bundle,
+                                          boolean fix, Collection modifications) {
         //log.info(name + ": checking bundle '" + id + "'");
 
         // look at the node's children
@@ -772,7 +769,7 @@
         while (iter.hasNext()) {
             NodePropBundle.ChildNodeEntry entry = (NodePropBundle.ChildNodeEntry) iter.next();
 
-            // skip check for system nodes (root, system root, version storage, nodetypes)
+            // skip check for system nodes (root, system root, version storage, node types)
             if (entry.getId().toString().endsWith("babecafebabe")) {
                 continue;
             }
@@ -835,35 +832,59 @@
             // get all node bundles in the database with a single sql statement,
             // which is (probably) faster than loading each bundle and traversing the tree
             ResultSet rs = null;
-            DataInputStream din = null;
             try {
-                String sql;
+                String sql = "select count(*) from " + schemaObjectPrefix + "BUNDLE";
+                Statement stmt = connectionManager.executeStmt(sql, new Object[0]);
+                try {
+                    rs = stmt.getResultSet();
+                    if (!rs.next()) {
+                        log.error("Could not retrieve total number of bundles. empty result set.");
+                        return;
+                    }
+                    total = rs.getInt(1);
+                } finally {
+                    closeResultSet(rs);
+                }
                 if (getStorageModel() == SM_BINARY_KEYS) {
-                    sql = "select NODE_ID, BUNDLE_DATA from " + schemaObjectPrefix + "BUNDLE";
+                    sql = "select NODE_ID from " + schemaObjectPrefix + "BUNDLE";
                 } else {
-                    sql = "select NODE_ID_HI, NODE_ID_LO, BUNDLE_DATA from " + schemaObjectPrefix + "BUNDLE";
+                    sql = "select NODE_ID_HI, NODE_ID_LO from " + schemaObjectPrefix + "BUNDLE";
                 }
-                Statement stmt = connectionManager.executeStmt(sql, new Object[0]);
+                stmt = connectionManager.executeStmt(sql, new Object[0]);
                 rs = stmt.getResultSet();
 
-                // iterate over all nodebundles in the db
+                // iterate over all node bundles in the db
                 while (rs.next()) {
                     NodeId id;
-                    Blob blob;
                     if (getStorageModel() == SM_BINARY_KEYS) {
                         id = new NodeId(new UUID(rs.getBytes(1)));
-                        blob = rs.getBlob(2);
                     } else {
                         id = new NodeId(new UUID(rs.getLong(1), rs.getLong(2)));
-                        blob = rs.getBlob(3);
                     }
-                    din = new DataInputStream(blob.getBinaryStream());
+
+                    // issuing 2nd statement to circumvent issue JCR-1474
+                    ResultSet bRs = null;
+                    byte[] data = null;
+                    try {
+                        Statement bSmt = connectionManager.executeStmt(bundleSelectSQL, getKey(id.getUUID()));
+                        bRs = bSmt.getResultSet();
+                        if (!bRs.next()) {
+                            throw new SQLException("bundle cannot be retrieved?");
+                        }
+                        Blob blob = bRs.getBlob(1);
+                        data = getBytes(blob);
+                    } finally {
+                        closeResultSet(bRs);
+                    }
+
+
                     try {
                         // parse and check bundle
-                        // check bundle will log any problems itself
+                        // checkBundle will log any problems itself
+                        DataInputStream din = new DataInputStream(new ByteArrayInputStream(data));
                         if (binding.checkBundle(din)) {
                             // reset stream for readBundle()
-                            din = new DataInputStream(blob.getBinaryStream());
+                            din = new DataInputStream(new ByteArrayInputStream(data));
                             NodePropBundle bundle = binding.readBundle(din, id);
                             checkBundleConsistency(id, bundle, fix, modifications);
                         } else {
@@ -874,13 +895,12 @@
                     }
                     count++;
                     if (count % 1000 == 0) {
-                        log.info(name + ": checked " + count + " bundles...");
+                        log.info(name + ": checked " + count + "/" + total + " bundles...");
                     }
                 }
             } catch (Exception e) {
                 log.error("Error loading bundle", e);
             } finally {
-                closeStream(din);
                 closeResultSet(rs);
                 total = count;
             }
@@ -1122,8 +1142,7 @@
                 }
                 result.add(current);
             }        
-            ListNodeIdIterator it = new ListNodeIdIterator(result);
-            return it;
+            return new ListNodeIdIterator(result);
         } catch (SQLException e) {
             String msg = "getAllNodeIds failed.";
             log.error(msg, e);
@@ -1142,12 +1161,36 @@
     }
     
     /**
+     * Reads the blob's bytes and returns it. this is a helper method to
+     * circumvent issue JCR-1039 and JCR-1474
+     * @param blob blob to read
+     * @return bytes of the blob
+     * @throws SQLException if an SQL error occurs
+     * @throws IOException if an I/O error occurs
+     */
+    private byte[] getBytes(Blob blob) throws SQLException, IOException {
+        InputStream in = null;
+        try {
+            long length = blob.length();
+            byte[] bytes = new byte[(int) length];
+            in = blob.getBinaryStream();
+            int read, pos = 0;
+            while ((read = in.read(bytes, pos, bytes.length - pos)) > 0) {
+                pos += read;
+            }
+            return bytes;
+        } finally {
+            IOUtils.closeQuietly(in);
+        }
+    }
+
+    /**
      * Loads a bundle from the underlying system and optionally performs
      * a check on the bundle first.
      *
      * @param id the node id of the bundle
      * @param checkBeforeLoading check the bundle before loading it and log
-     *                           detailed informations about it (slower)
+     *                           detailed information about it (slower)
      * @return the loaded bundle or <code>null</code> if the bundle does not
      *         exist.
      * @throws ItemStateException if an error while loading occurs.
@@ -1156,7 +1199,6 @@
             throws ItemStateException {
         ResultSet rs = null;
         InputStream in = null;
-        byte[] bytes = null;
         try {
             Statement stmt = connectionManager.executeStmt(bundleSelectSQL, getKey(id.getUUID()));
             rs = stmt.getResultSet();
@@ -1164,14 +1206,7 @@
                 return null;
             }
             Blob b = rs.getBlob(1);
-            // JCR-1039: pre-fetch/buffer blob data
-            long length = b.length();
-            bytes = new byte[(int) length];
-            in = b.getBinaryStream();
-            int read, pos = 0;
-            while ((read = in.read(bytes, pos, bytes.length - pos)) > 0) {
-                pos += read;
-            }
+            byte[] bytes = getBytes(b);
             DataInputStream din = new DataInputStream(new ByteArrayInputStream(bytes));
             
             if (checkBeforeLoading) {
@@ -1185,7 +1220,7 @@
             }
             
             NodePropBundle bundle = binding.readBundle(din, id);
-            bundle.setSize(length);
+            bundle.setSize(bytes.length);
             return bundle;
         } catch (Exception e) {
             String msg = "failed to read bundle: " + id + ": " + e;
@@ -1435,16 +1470,22 @@
     /**
      * logs an sql exception
      * @param message the message
-     * @param se the exception
+     * @param e the exception
      */
-    protected void logException(String message, SQLException se) {
+    protected void logException(String message, SQLException e) {
         if (message != null) {
             log.error(message);
         }
+<<<<<<< .working
         log.error("       Reason: " + se.getMessage());
         log.error("   State/Code: " + se.getSQLState() + "/" +
                 se.getErrorCode());
         log.debug("   dump:", se);
+=======
+        log.error("       Reason: " + e.getMessage());
+        log.error("   State/Code: " + e.getSQLState() + "/" + e.getErrorCode());
+        log.debug("   dump:", e);
+>>>>>>> .merge-right.r649733
     }
 
     /**
@@ -1620,6 +1661,13 @@
         }
     }
 
+<<<<<<< .working
+=======
+    /**
+     * Iterator over an in-memory list of node ids.
+     * This helper class is used by {@link BundleDbPersistenceManager#getAllNodeIds}.
+     */
+>>>>>>> .merge-right.r649733
     private class ListNodeIdIterator implements NodeIdIterator {
         
         private final ArrayList list;

Modified: jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java?rev=650355&r1=650354&r2=650355&view=diff
==============================================================================
--- jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java (original)
+++ jackrabbit/branches/1.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java Mon Apr 21 18:58:18 2008
@@ -74,7 +74,7 @@
      * Deserializes a <code>NodePropBundle</code> from a data input stream.
      *
      * @param in the input stream
-     * @param id the nodeid for the new budle
+     * @param id the node id for the new bundle
      * @return the bundle
      * @throws IOException if an I/O error occurs.
      */
@@ -158,22 +158,22 @@
             String local = nameIndex.indexToString(in.readInt());
             Name nodeTypeName = NameFactoryImpl.getInstance().create(uri, local);
 
-            log.info("Serialzation Version: " + version);
-            log.info("NodeTypeName: " + nodeTypeName);
+            log.debug("Serialzation Version: " + version);
+            log.debug("NodeTypeName: " + nodeTypeName);
         } catch (IOException e) {
             log.error("Error while reading NodeTypeName: " + e);
             return false;
         }
         try {
             UUID parentUuid = readUUID(in);
-            log.info("ParentUUID: " + parentUuid);
+            log.debug("ParentUUID: " + parentUuid);
         } catch (IOException e) {
             log.error("Error while reading ParentUUID: " + e);
             return false;
         }
         try {
             String definitionId = in.readUTF();
-            log.info("DefinitionId: " + definitionId);
+            log.debug("DefinitionId: " + definitionId);
         } catch (IOException e) {
             log.error("Error while reading DefinitionId: " + e);
             return false;
@@ -181,7 +181,7 @@
         try {
             Name mixinName = readIndexedQName(in);
             while (mixinName != null) {
-                log.info("MixinTypeName: " + mixinName);
+                log.debug("MixinTypeName: " + mixinName);
                 mixinName = readIndexedQName(in);
             }
         } catch (IOException e) {
@@ -191,7 +191,7 @@
         try {
             Name propName = readIndexedQName(in);
             while (propName != null) {
-                log.info("PropertyName: " + propName);
+                log.debug("PropertyName: " + propName);
                 if (!checkPropertyState(in)) {
                     return false;
                 }
@@ -203,7 +203,7 @@
         }
         try {
             boolean hasUUID = in.readBoolean();
-            log.info("hasUUID: " + hasUUID);
+            log.debug("hasUUID: " + hasUUID);
         } catch (IOException e) {
             log.error("Error while reading 'hasUUID': " + e);
             return false;
@@ -212,7 +212,7 @@
             UUID cneUUID = readUUID(in);
             while (cneUUID != null) {
                 Name cneName = readQName(in);
-                log.info("ChildNodentry: " + cneUUID + ":" + cneName);
+                log.debug("ChildNodentry: " + cneUUID + ":" + cneName);
                 cneUUID = readUUID(in);
             }
         } catch (IOException e) {
@@ -223,7 +223,7 @@
         if (version >= VERSION_1) {
             try {
                 short modCount = readModCount(in);
-                log.info("modCount: " + modCount);
+                log.debug("modCount: " + modCount);
             } catch (IOException e) {
                 log.error("Error while reading mod cout: " + e);
                 return false;
@@ -298,7 +298,7 @@
      * Deserializes a <code>PropertyState</code> from the data input stream.
      *
      * @param in the input stream
-     * @param id the property id for the new propert entry
+     * @param id the property id for the new property entry
      * @return the property entry
      * @throws IOException if an I/O error occurs.
      */
@@ -398,22 +398,22 @@
             type = in.readInt();
             short modCount = (short) ((type >> 16) | 0xffff);
             type &= 0xffff;
-            log.info("  PropertyType: " + PropertyType.nameFromValue(type));
-            log.info("  ModCount: " + modCount);
+            log.debug("  PropertyType: " + PropertyType.nameFromValue(type));
+            log.debug("  ModCount: " + modCount);
         } catch (IOException e) {
             log.error("Error while reading property type: " + e);
             return false;
         }
         try {
             boolean isMV = in.readBoolean();
-            log.info("  MultiValued: " + isMV);
+            log.debug("  MultiValued: " + isMV);
         } catch (IOException e) {
             log.error("Error while reading multivalued: " + e);
             return false;
         }
         try {
             String defintionId = in.readUTF();
-            log.info("  DefinitionId: " + defintionId);
+            log.debug("  DefinitionId: " + defintionId);
         } catch (IOException e) {
             log.error("Error while reading definition id: " + e);
             return false;
@@ -422,7 +422,7 @@
         int count;
         try {
             count = in.readInt();
-            log.info("  num values: " + count);
+            log.debug("  num values: " + count);
         } catch (IOException e) {
             log.error("Error while reading number of values: " + e);
             return false;
@@ -433,7 +433,7 @@
                     int size;
                     try {
                         size = in.readInt();
-                        log.info("  binary size: " + size);
+                        log.debug("  binary size: " + size);
                     } catch (IOException e) {
                         log.error("Error while reading size of binary: " + e);
                         return false;
@@ -441,7 +441,11 @@
                     if (InternalValue.USE_DATA_STORE && size == -2) {
                         try {
                             String s = in.readUTF();
-                            log.info("  global data store id: " + s);
+                            // truncate log output
+                            if (s.length() > 80) {
+                                s = s.substring(80) + "...";
+                            }
+                            log.debug("  global data store id: " + s);
                         } catch (IOException e) {
                             log.error("Error while reading blob id: " + e);
                             return false;
@@ -449,7 +453,7 @@
                     } else if (size == -1) {
                         try {
                             String s = in.readUTF();
-                            log.info("  blobid: " + s);
+                            log.debug("  blobid: " + s);
                         } catch (IOException e) {
                             log.error("Error while reading blob id: " + e);
                             return false;
@@ -459,7 +463,7 @@
                         byte[] data = new byte[size];
                         try {
                             in.readFully(data);
-                            log.info("  binary: " + data.length + " bytes");
+                            log.debug("  binary: " + data.length + " bytes");
                         } catch (IOException e) {
                             log.error("Error while reading inlined binary: " + e);
                             return false;
@@ -469,7 +473,7 @@
                 case PropertyType.DOUBLE:
                     try {
                         double d = in.readDouble();
-                        log.info("  double: " + d);
+                        log.debug("  double: " + d);
                     } catch (IOException e) {
                         log.error("Error while reading double value: " + e);
                         return false;
@@ -478,7 +482,7 @@
                 case PropertyType.LONG:
                     try {
                         double l = in.readLong();
-                        log.info("  long: " + l);
+                        log.debug("  long: " + l);
                     } catch (IOException e) {
                         log.error("Error while reading long value: " + e);
                         return false;
@@ -487,7 +491,7 @@
                 case PropertyType.BOOLEAN:
                     try {
                         boolean b = in.readBoolean();
-                        log.info("  boolean: " + b);
+                        log.debug("  boolean: " + b);
                     } catch (IOException e) {
                         log.error("Error while reading boolean value: " + e);
                         return false;
@@ -496,7 +500,7 @@
                 case PropertyType.NAME:
                     try {
                         Name name = readQName(in);
-                        log.info("  name: " + name);
+                        log.debug("  name: " + name);
                     } catch (IOException e) {
                         log.error("Error while reading name value: " + e);
                         return false;
@@ -505,7 +509,7 @@
                 case PropertyType.REFERENCE:
                     try {
                         UUID uuid = readUUID(in);
-                        log.info("  reference: " + uuid);
+                        log.debug("  reference: " + uuid);
                     } catch (IOException e) {
                         log.error("Error while reading reference value: " + e);
                         return false;
@@ -517,7 +521,7 @@
                     int len;
                     try {
                         len = in.readInt();
-                        log.info("  size of string value: " + len);
+                        log.debug("  size of string value: " + len);
                     } catch (IOException e) {
                         log.error("Error while reading size of string value: " + e);
                         return false;
@@ -528,7 +532,12 @@
                         while (pos < len) {
                             pos += in.read(bytes, pos, len - pos);
                         }
-                        log.info("  string: " + new String(bytes, "UTF-8"));
+                        String s = new String(bytes, "UTF-8");
+                        // truncate log output
+                        if (s.length() > 80) {
+                            s = s.substring(80) + "...";
+                        }
+                        log.debug("  string: " + s);
                     } catch (IOException e) {
                         log.error("Error while reading string value: " + e);
                         return false;
@@ -678,7 +687,7 @@
                     // because writeUTF(String) has a size limit of 64k,
                     // we're using write(byte[]) instead
                     byte[] bytes = val.toString().getBytes("UTF-8");
-                    out.writeInt(bytes.length); // lenght of byte[]
+                    out.writeInt(bytes.length); // length of byte[]
                     out.write(bytes);   // byte[]
             }
         }