You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by tr...@apache.org on 2008/04/19 02:38:25 UTC
svn commit: r649733 - in
/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle:
BundleDbPersistenceManager.java util/BundleBinding.java
Author: tripod
Date: Fri Apr 18 17:38:07 2008
New Revision: 649733
URL: http://svn.apache.org/viewvc?rev=649733&view=rev
Log:
JCR-1474 consistency check fails with derbypm
Modified:
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java?rev=649733&r1=649732&r2=649733&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/BundleDbPersistenceManager.java Fri Apr 18 17:38:07 2008
@@ -360,7 +360,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();
@@ -488,7 +488,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
@@ -675,17 +675,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
@@ -694,7 +691,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;
}
@@ -760,35 +757,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 {
@@ -799,13 +820,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 {
- IOUtils.closeQuietly(din);
closeResultSet(rs);
total = count;
}
@@ -1048,8 +1068,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);
@@ -1068,12 +1087,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.
@@ -1082,7 +1125,6 @@
throws ItemStateException {
ResultSet rs = null;
InputStream in = null;
- byte[] bytes = null;
try {
Statement stmt = connectionManager.executeStmt(bundleSelectSQL, getKey(id.getUUID()));
rs = stmt.getResultSet();
@@ -1090,14 +1132,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) {
@@ -1111,7 +1146,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;
@@ -1347,15 +1382,15 @@
/**
* 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);
}
- 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);
}
/**
@@ -1540,7 +1575,7 @@
/**
* Iterator over an in-memory list of node ids.
- * This helper class is used by {@link BundleDbPersistenceManager#getAllNodeIds()}.
+ * This helper class is used by {@link BundleDbPersistenceManager#getAllNodeIds}.
*/
private class ListNodeIdIterator implements NodeIdIterator {
Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java?rev=649733&r1=649732&r2=649733&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java (original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/util/BundleBinding.java Fri Apr 18 17:38:07 2008
@@ -71,7 +71,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.
*/
@@ -168,22 +168,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;
@@ -191,7 +191,7 @@
try {
Name mixinName = readIndexedQName(in);
while (mixinName != null) {
- log.info("MixinTypeName: " + mixinName);
+ log.debug("MixinTypeName: " + mixinName);
mixinName = readIndexedQName(in);
}
} catch (IOException e) {
@@ -201,7 +201,7 @@
try {
Name propName = readIndexedQName(in);
while (propName != null) {
- log.info("PropertyName: " + propName);
+ log.debug("PropertyName: " + propName);
if (!checkPropertyState(in)) {
return false;
}
@@ -213,7 +213,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;
@@ -222,7 +222,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) {
@@ -233,7 +233,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;
@@ -315,7 +315,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.
*/
@@ -412,22 +412,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;
@@ -436,7 +436,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;
@@ -447,7 +447,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;
@@ -455,7 +455,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;
@@ -463,7 +467,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;
@@ -473,7 +477,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;
@@ -483,7 +487,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;
@@ -492,7 +496,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;
@@ -501,7 +505,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;
@@ -510,7 +514,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;
@@ -519,7 +523,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;
@@ -531,7 +535,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;
@@ -539,7 +543,12 @@
try {
byte[] bytes = new byte[len];
in.readFully(bytes);
- 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;
@@ -675,7 +684,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[]
}
}