Author: reschke
Date: Tue Jul 5 13:58:46 2016
New Revision: 1751478
URL: http://svn.apache.org/viewvc?rev=1751478&view=rev
Log:
OAK-4509: RDBDocumentStore: low-level read method should also support condition
on MODIFIED value
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBCTest.java
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java?rev=1751478&r1=1751477&r2=1751478&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
Tue Jul 5 13:58:46 2016
@@ -1479,7 +1479,7 @@ public class RDBDocumentStore implements
lastmodified = modifiedOf(cachedDoc);
}
connection = this.ch.getROConnection();
- RDBRow row = db.read(connection, tmd, id, lastmodcount);
+ RDBRow row = db.read(connection, tmd, id, lastmodcount,
lastmodified);
connection.commit();
if (row == null) {
docFound = false;
@@ -1490,13 +1490,6 @@ public class RDBDocumentStore implements
cachedDoc.markUpToDate(System.currentTimeMillis());
return castAsT(cachedDoc);
} else {
- // workaround: need to re-read if data is not present
- // that would be the case if the modcount did match but
the modified time did not
- // see OAK-4509
- if (row.getData() == null) {
- row = db.read(connection, tmd, id, -1);
- connection.commit();
- }
return convertFromDBObject(collection, row);
}
}
Modified:
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java?rev=1751478&r1=1751477&r2=1751478&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
Tue Jul 5 13:58:46 2016
@@ -625,28 +625,31 @@ public class RDBDocumentStoreJDBC {
}
@CheckForNull
- public RDBRow read(Connection connection, RDBTableMetaData tmd, String id,
long lastmodcount) throws SQLException {
- PreparedStatement stmt;
+ public RDBRow read(Connection connection, RDBTableMetaData tmd, String id,
long lastmodcount, long lastmodified) throws SQLException {
boolean useCaseStatement = lastmodcount != -1 &&
this.dbInfo.allowsCaseInSelect();
+ StringBuffer sql = new StringBuffer();
+ sql.append("select MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY,
DELETEDONCE, ");
if (useCaseStatement) {
// the case statement causes the actual row data not to be
// sent in case we already have it
- stmt = connection.prepareStatement(
- "select MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY,
DELETEDONCE, case MODCOUNT when ? then null else DATA end as DATA, "
- + "case MODCOUNT when ? then null else BDATA end
as BDATA from " + tmd.getName() + " where ID = ?");
+ sql.append("case when (MODCOUNT = ? and MODIFIED = ?) then null
else DATA end as DATA, ");
+ sql.append("case when (MODCOUNT = ? and MODIFIED = ?) then null
else BDATA end as BDATA ");
} else {
// either we don't have a previous version of the document
// or the database does not support CASE in SELECT
- stmt = connection.prepareStatement("select MODIFIED, MODCOUNT,
CMODCOUNT, HASBINARY, DELETEDONCE, DATA, BDATA from "
- + tmd.getName() + " where ID = ?");
+ sql.append("DATA, BDATA ");
}
+ sql.append("from " + tmd.getName() + " where ID = ?");
+ PreparedStatement stmt = connection.prepareStatement(sql.toString());
try {
int si = 1;
if (useCaseStatement) {
stmt.setLong(si++, lastmodcount);
+ stmt.setLong(si++, lastmodified);
stmt.setLong(si++, lastmodcount);
+ stmt.setLong(si++, lastmodified);
}
setIdInStatement(tmd, stmt, si, id);
Modified:
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBCTest.java
URL:
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBCTest.java?rev=1751478&r1=1751477&r2=1751478&view=diff
==============================================================================
---
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBCTest.java
(original)
+++
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBCTest.java
Tue Jul 5 13:58:46 2016
@@ -19,6 +19,8 @@ package org.apache.jackrabbit.oak.plugin
import static com.google.common.collect.ImmutableSet.of;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
@@ -30,6 +32,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@@ -37,6 +40,9 @@ import org.apache.jackrabbit.oak.plugins
import org.apache.jackrabbit.oak.plugins.document.Collection;
import org.apache.jackrabbit.oak.plugins.document.DocumentStoreException;
import org.apache.jackrabbit.oak.plugins.document.DocumentStoreFixture;
+import org.apache.jackrabbit.oak.plugins.document.NodeDocument;
+import org.apache.jackrabbit.oak.plugins.document.UpdateOp;
+import
org.apache.jackrabbit.oak.plugins.document.rdb.RDBDocumentStore.RDBTableMetaData;
import org.junit.Test;
/**
@@ -44,9 +50,57 @@ import org.junit.Test;
*/
public class RDBDocumentStoreJDBCTest extends AbstractDocumentStoreTest {
+ private RDBDocumentStoreJDBC jdbc;
+ private RDBDocumentStoreDB dbInfo;
+
public RDBDocumentStoreJDBCTest(DocumentStoreFixture dsf) {
super(dsf);
assumeTrue(super.rdbDataSource != null);
+
+ dbInfo = RDBDocumentStoreDB.getValue(((RDBDocumentStore)
super.ds).getMetadata().get("db"));
+ RDBDocumentSerializer ser = new RDBDocumentSerializer(super.ds,
Collections.singleton("_id"));
+ jdbc = new RDBDocumentStoreJDBC(dbInfo, ser, 100, 10000);
+ }
+
+ @Test
+ public void conditionalRead() throws SQLException {
+
+ // this tests functionality that relies on case statements
+ assumeTrue(dbInfo.allowsCaseInSelect());
+
+ String id = this.getClass().getName() + ".conditionalRead";
+ super.ds.remove(Collection.NODES, id);
+ UpdateOp op = new UpdateOp(id, true);
+ op.set("_id", id);
+ op.set("_modified", 1L);
+ removeMe.add(id);
+ assertTrue(super.ds.create(Collection.NODES,
Collections.singletonList(op)));
+
+ NodeDocument nd = super.ds.find(Collection.NODES, id, 0);
+ assertNotNull(nd);
+ Long lastmodcount = nd.getModCount();
+ Long lastmodified = nd.getModified();
+ assertNotNull(lastmodcount);
+ assertNotNull(lastmodified);
+
+ RDBTableMetaData tmd = ((RDBDocumentStore)
super.ds).getTable(Collection.NODES);
+ Connection con = super.rdbDataSource.getConnection();
+ con.setReadOnly(true);
+ try {
+ RDBRow rMcNotMatch = jdbc.read(con, tmd, id, lastmodcount + 1,
lastmodified);
+ assertNotNull(rMcNotMatch.getData());
+
+ RDBRow rMcNotGiven = jdbc.read(con, tmd, id, -1, lastmodified);
+ assertNotNull(rMcNotGiven.getData());
+
+ RDBRow rMcMatch = jdbc.read(con, tmd, id, lastmodcount,
lastmodified);
+ assertNull(rMcMatch.getData());
+
+ RDBRow rMcMatchModNonmatch = jdbc.read(con, tmd, id, lastmodcount,
lastmodified + 2);
+ assertNotNull(rMcMatchModNonmatch.getData());
+ } finally {
+ con.close();
+ }
}
@Test