Author: reschke
Date: Fri Nov 10 15:39:38 2017
New Revision: 1814876

URL: http://svn.apache.org/viewvc?rev=1814876&view=rev
Log:
OAK-6927: RDBDocumentStore: allow schema evolution part 4: read VERSION column 
and let RDBRow handle it

Modified:
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBExport.java
    
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBRow.java
    
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentSerializerTest.java

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java?rev=1814876&r1=1814875&r2=1814876&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStoreJDBC.java
 Fri Nov 10 15:39:38 2017
@@ -407,26 +407,34 @@ public class RDBDocumentStoreJDBC {
         List<RDBRow> result = new ArrayList<RDBRow>();
         long dataTotal = 0, bdataTotal = 0;
         PreparedStatement stmt = null;
+        String fields;
+        if (tmd.hasVersion()) {
+            fields = "ID, MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, 
DELETEDONCE, VERSION, DATA, BDATA";
+        } else {
+            fields = "ID, MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, 
DELETEDONCE, DATA, BDATA";
+        }
         ResultSet rs = null;
         try {
-            stmt = prepareQuery(connection, tmd, "ID, MODIFIED, MODCOUNT, 
CMODCOUNT, HASBINARY, DELETEDONCE, DATA, BDATA", minId,
+            stmt = prepareQuery(connection, tmd, fields, minId,
                     maxId, excludeKeyPatterns, conditions, limit, "ID");
             rs = stmt.executeQuery();
             while (rs.next() && result.size() < limit) {
-                String id = getIdFromRS(tmd, rs, 1);
+                int field = 1;
+                String id = getIdFromRS(tmd, rs, field++);
 
                 if ((minId != null && id.compareTo(minId) < 0) || (maxId != 
null && id.compareTo(maxId) > 0)) {
                     throw new DocumentStoreException(
                             "unexpected query result: '" + minId + "' < '" + 
id + "' < '" + maxId + "' - broken DB collation?");
                 }
-                long modified = readLongFromResultSet(rs, 2);
-                long modcount = readLongFromResultSet(rs, 3);
-                long cmodcount = readLongFromResultSet(rs, 4);
-                Long hasBinary = readLongOrNullFromResultSet(rs, 5);
-                Boolean deletedOnce = readBooleanOrNullFromResultSet(rs, 6);
-                String data = rs.getString(7);
-                byte[] bdata = rs.getBytes(8);
-                result.add(new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, data, bdata));
+                long modified = readLongFromResultSet(rs, field++);
+                long modcount = readLongFromResultSet(rs, field++);
+                long cmodcount = readLongFromResultSet(rs, field++);
+                Long hasBinary = readLongOrNullFromResultSet(rs, field++);
+                Boolean deletedOnce = readBooleanOrNullFromResultSet(rs, 
field++);
+                long schemaVersion = tmd.hasVersion() ? 
readLongFromResultSet(rs, field++) : 0;
+                String data = rs.getString(field++);
+                byte[] bdata = rs.getBytes(field++);
+                result.add(new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, schemaVersion, data, bdata));
                 dataTotal += data.length();
                 bdataTotal += bdata == null ? 0 : bdata.length;
             }
@@ -523,8 +531,13 @@ public class RDBDocumentStoreJDBC {
                 this.ch = ch;
                 this.connection = ch.getROConnection();
                 this.tmd = tmd;
-                this.stmt = prepareQuery(connection, tmd, "ID, MODIFIED, 
MODCOUNT, CMODCOUNT, HASBINARY, DELETEDONCE, DATA, BDATA",
-                        minId, maxId, excludeKeyPatterns, conditions, limit, 
sortBy);
+                String fields;
+                if (tmd.hasVersion()) {
+                    fields = "ID, MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, 
DELETEDONCE, VERSION, DATA, BDATA";
+                } else {
+                    fields = "ID, MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, 
DELETEDONCE, DATA, BDATA";
+                }
+                this.stmt = prepareQuery(connection, tmd, fields, minId, 
maxId, excludeKeyPatterns, conditions, limit, sortBy);
                 this.rs = stmt.executeQuery();
                 this.next = internalNext();
                 this.message = String.format("Query on %s with params minid 
'%s' maxid '%s' excludeKeyPatterns %s conditions %s.",
@@ -563,15 +576,17 @@ public class RDBDocumentStoreJDBC {
             long start = System.currentTimeMillis();
             try {
                 if (this.rs.next()) {
-                    String id = getIdFromRS(this.tmd, this.rs, 1);
-                    long modified = readLongFromResultSet(this.rs, 2);
-                    long modcount = readLongFromResultSet(this.rs, 3);
-                    long cmodcount = readLongFromResultSet(this.rs, 4);
-                    Long hasBinary = readLongOrNullFromResultSet(this.rs, 5);
-                    Boolean deletedOnce = 
readBooleanOrNullFromResultSet(this.rs, 6);
-                    String data = this.rs.getString(7);
-                    byte[] bdata = this.rs.getBytes(8);
-                    return new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, data, bdata);
+                    int field = 1;
+                    String id = getIdFromRS(this.tmd, this.rs, field++);
+                    long modified = readLongFromResultSet(this.rs, field++);
+                    long modcount = readLongFromResultSet(this.rs, field++);
+                    long cmodcount = readLongFromResultSet(this.rs, field++);
+                    Long hasBinary = readLongOrNullFromResultSet(this.rs, 
field++);
+                    Boolean deletedOnce = 
readBooleanOrNullFromResultSet(this.rs, field++);
+                    long schemaVersion = tmd.hasVersion() ? 
readLongFromResultSet(rs, field++) : 0;
+                    String data = this.rs.getString(field++);
+                    byte[] bdata = this.rs.getBytes(field++);
+                    return new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, schemaVersion, data, bdata);
                 } else {
                     this.rs = closeResultSet(this.rs);
                     this.stmt = closeStatement(this.stmt);
@@ -684,7 +699,11 @@ public class RDBDocumentStoreJDBC {
         for (List<String> keys : Iterables.partition(allKeys, 
RDBJDBCTools.MAX_IN_CLAUSE)) {
             PreparedStatementComponent inClause = 
RDBJDBCTools.createInStatement("ID", keys, tmd.isIdBinary());
             StringBuilder query = new StringBuilder();
-            query.append("select ID, MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, 
DELETEDONCE, DATA, BDATA from ");
+            if (tmd.hasVersion()) {
+                query.append("select ID, MODIFIED, MODCOUNT, CMODCOUNT, 
HASBINARY, DELETEDONCE, VERSION, DATA, BDATA from ");
+            } else {
+                query.append("select ID, MODIFIED, MODCOUNT, CMODCOUNT, 
HASBINARY, DELETEDONCE, DATA, BDATA from ");
+            }
             query.append(tmd.getName());
             query.append(" where ").append(inClause.getStatementComponent());
 
@@ -696,16 +715,17 @@ public class RDBDocumentStoreJDBC {
                 rs = stmt.executeQuery();
 
                 while (rs.next()) {
-                    int col = 1;
-                    String id = getIdFromRS(tmd, rs, col++);
-                    long modified = readLongFromResultSet(rs, col++);
-                    long modcount = readLongFromResultSet(rs, col++);
-                    long cmodcount = readLongFromResultSet(rs, col++);
-                    Long hasBinary = readLongOrNullFromResultSet(rs, col++);
-                    Boolean deletedOnce = readBooleanOrNullFromResultSet(rs, 
col++);
-                    String data = rs.getString(col++);
-                    byte[] bdata = rs.getBytes(col++);
-                    RDBRow row = new RDBRow(id, hasBinary, deletedOnce, 
modified, modcount, cmodcount, data, bdata);
+                    int field = 1;
+                    String id = getIdFromRS(tmd, rs, field++);
+                    long modified = readLongFromResultSet(rs, field++);
+                    long modcount = readLongFromResultSet(rs, field++);
+                    long cmodcount = readLongFromResultSet(rs, field++);
+                    Long hasBinary = readLongOrNullFromResultSet(rs, field++);
+                    Boolean deletedOnce = readBooleanOrNullFromResultSet(rs, 
field++);
+                    long schemaVersion = tmd.hasVersion() ? 
readLongFromResultSet(rs, field++) : 0;
+                    String data = rs.getString(field++);
+                    byte[] bdata = rs.getBytes(field++);
+                    RDBRow row = new RDBRow(id, hasBinary, deletedOnce, 
modified, modcount, cmodcount, schemaVersion, data, bdata);
                     rows.add(row);
                 }
             } catch (SQLException ex) {
@@ -735,7 +755,14 @@ public class RDBDocumentStoreJDBC {
 
         boolean useCaseStatement = lastmodcount != -1 && lastmodified >= 1;
         StringBuffer sql = new StringBuffer();
-        sql.append("select MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, 
DELETEDONCE, ");
+        String fields;
+        if (tmd.hasVersion()) {
+            fields = "MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, DELETEDONCE, 
VERSION, ";
+        } else {
+            fields = "MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, DELETEDONCE, ";
+        }
+
+        sql.append("select ").append(fields);
         if (useCaseStatement) {
             // the case statement causes the actual row data not to be
             // sent in case we already have it
@@ -762,14 +789,16 @@ public class RDBDocumentStoreJDBC {
 
             rs = stmt.executeQuery();
             if (rs.next()) {
-                long modified = readLongFromResultSet(rs, 1);
-                long modcount = readLongFromResultSet(rs, 2);
-                long cmodcount = readLongFromResultSet(rs, 3);
-                Long hasBinary = readLongOrNullFromResultSet(rs, 4);
-                Boolean deletedOnce = readBooleanOrNullFromResultSet(rs, 5);
-                String data = rs.getString(6);
-                byte[] bdata = rs.getBytes(7);
-                return new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, data, bdata);
+                int field = 1;
+                long modified = readLongFromResultSet(rs, field++);
+                long modcount = readLongFromResultSet(rs, field++);
+                long cmodcount = readLongFromResultSet(rs, field++);
+                Long hasBinary = readLongOrNullFromResultSet(rs, field++);
+                Boolean deletedOnce = readBooleanOrNullFromResultSet(rs, 
field++);
+                long schemaVersion = tmd.hasVersion() ? 
readLongFromResultSet(rs, field++) : 0;
+                String data = rs.getString(field++);
+                byte[] bdata = rs.getBytes(field++);
+                return new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, schemaVersion, data, bdata);
             } else {
                 return null;
             }

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBExport.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBExport.java?rev=1814876&r1=1814875&r2=1814876&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBExport.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBExport.java
 Fri Nov 10 15:39:38 2017
@@ -219,7 +219,7 @@ public class RDBExport {
             try {
                 RDBRow row = new RDBRow(id, "1".equals(shasbinary) ? 1L : 0L, 
"1".equals(sdeletedonce),
                         smodified.length() == 0 ? 0 : 
Long.parseLong(smodified), Long.parseLong(smodcount),
-                        Long.parseLong(scmodcount), sdata, bytes);
+                        Long.parseLong(scmodcount), -1L, sdata, bytes);
                 StringBuilder fulljson = dumpRow(ser, id, row);
                 if (format == Format.CSV) {
                     out.println(asCSV(fieldNames, fulljson));
@@ -321,7 +321,7 @@ public class RDBExport {
             String data = rs.getString("DATA");
             byte[] bdata = rs.getBytes("BDATA");
 
-            RDBRow row = new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, data, bdata);
+            RDBRow row = new RDBRow(id, hasBinary, deletedOnce, modified, 
modcount, cmodcount, -1L, data, bdata);
             StringBuilder fulljson = dumpRow(ser, id, row);
             if (format == Format.CSV) {
                 out.println(asCSV(fieldNames, fulljson));

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBRow.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBRow.java?rev=1814876&r1=1814875&r2=1814876&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBRow.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBRow.java
 Fri Nov 10 15:39:38 2017
@@ -22,9 +22,8 @@ import javax.annotation.Nonnull;
 /**
  * Container for the information in a RDB database column.
  * <p>
- * Note that the String "data" and the byte[] "bdata" may be null
- * when the SQL SELECT request was conditional on "modcount" being
- * unchanged.
+ * Note that the String "data" and the byte[] "bdata" may be {@code null} when
+ * the SQL SELECT request was conditional on "modcount" being unchanged.
  */
 public class RDBRow {
 
@@ -34,16 +33,19 @@ public class RDBRow {
     private final Long hasBinaryProperties;
     private final Boolean deletedOnce;
     private final long modified, modcount, cmodcount;
+    private final long schemaVersion;
     private final String data;
     private final byte[] bdata;
 
-    public RDBRow(String id, Long hasBinaryProperties, Boolean deletedOnce, 
Long modified, Long modcount, Long cmodcount, String data, byte[] bdata) {
+    public RDBRow(String id, Long hasBinaryProperties, Boolean deletedOnce, 
Long modified, Long modcount, Long cmodcount,
+            Long schemaVersion, String data, byte[] bdata) {
         this.id = id;
         this.hasBinaryProperties = hasBinaryProperties;
         this.deletedOnce = deletedOnce;
         this.modified = modified != null ? modified.longValue() : LONG_UNSET;
         this.modcount = modcount != null ? modcount.longValue() : LONG_UNSET;
         this.cmodcount = cmodcount != null ? cmodcount.longValue() : 
LONG_UNSET;
+        this.schemaVersion = schemaVersion != null ? schemaVersion.longValue() 
: LONG_UNSET;
         this.data = data;
         this.bdata = bdata;
     }
@@ -89,6 +91,13 @@ public class RDBRow {
         return cmodcount;
     }
 
+    /**
+     * @return {@link #LONG_UNSET} when not set in the database
+     */
+    public long getSchemaVersion() {
+        return schemaVersion;
+    }
+
     @CheckForNull
     public byte[] getBdata() {
         return bdata;

Modified: 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentSerializerTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentSerializerTest.java?rev=1814876&r1=1814875&r2=1814876&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentSerializerTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-store-document/src/test/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentSerializerTest.java
 Fri Nov 10 15:39:38 2017
@@ -56,7 +56,7 @@ public class RDBDocumentSerializerTest {
 
     @Test
     public void testSimpleString() {
-        RDBRow row = new RDBRow("_foo", 1L, true, 1l, 2l, 3l, "{}", null);
+        RDBRow row = new RDBRow("_foo", 1L, true, 1l, 2l, 3l, 0L, "{}", null);
         NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
         assertEquals("_foo", doc.getId());
         assertEquals(true, doc.hasBinary());
@@ -66,7 +66,7 @@ public class RDBDocumentSerializerTest {
 
     @Test
     public void testNoSysprops() {
-        RDBRow row = new RDBRow("_foo", null, null, 1l, 2l, 3l, "{}", null);
+        RDBRow row = new RDBRow("_foo", null, null, 1l, 2l, 3l, 0L, "{}", 
null);
         NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
         assertEquals("_foo", doc.getId());
         assertEquals(false, doc.hasBinary());
@@ -78,7 +78,7 @@ public class RDBDocumentSerializerTest {
 
     @Test
     public void testSimpleBlob() throws UnsupportedEncodingException {
-        RDBRow row = new RDBRow("_foo", 0L, false, 1l, 2l, 3l, "\"blob\"", 
"{}".getBytes("UTF-8"));
+        RDBRow row = new RDBRow("_foo", 0L, false, 1l, 2l, 3l, 0L, "\"blob\"", 
"{}".getBytes("UTF-8"));
         NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
         assertEquals("_foo", doc.getId());
         assertEquals(false, doc.hasBinary());
@@ -87,7 +87,7 @@ public class RDBDocumentSerializerTest {
 
     @Test
     public void testSimpleBlob2() throws UnsupportedEncodingException {
-        RDBRow row = new RDBRow("_foo", 0L, false, 1l, 2l, 3l, "\"blob\"",
+        RDBRow row = new RDBRow("_foo", 0L, false, 1l, 2l, 3l, 0L, "\"blob\"",
                 "{\"s\":\"string\", \"b\":true, \"i\":1}".getBytes("UTF-8"));
         NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
         assertEquals("_foo", doc.getId());
@@ -101,7 +101,7 @@ public class RDBDocumentSerializerTest {
     @Test
     public void testSimpleBoth() throws UnsupportedEncodingException {
         try {
-            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, "{}", 
"{}".getBytes("UTF-8"));
+            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, 0L, "{}", 
"{}".getBytes("UTF-8"));
             this.ser.fromRow(Collection.NODES, row);
             fail("should fail");
         } catch (DocumentStoreException expected) {
@@ -110,7 +110,7 @@ public class RDBDocumentSerializerTest {
 
     @Test
     public void testBlobAndDiff() throws UnsupportedEncodingException {
-        RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l,
+        RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, 0L,
                 "\"blob\", [[\"=\", \"foo\", \"bar\"],[\"M\", \"m1\", 
1],[\"M\", \"m2\", 3]]",
                 "{\"m1\":2, \"m2\":2}".getBytes("UTF-8"));
         NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
@@ -122,7 +122,7 @@ public class RDBDocumentSerializerTest {
     @Test
     public void testBlobAndDiffBorked() throws UnsupportedEncodingException {
         try {
-            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, "[[\"\", 
\"\", \"\"]]", "{}".getBytes("UTF-8"));
+            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, 0L, 
"[[\"\", \"\", \"\"]]", "{}".getBytes("UTF-8"));
             this.ser.fromRow(Collection.NODES, row);
             fail("should fail");
         } catch (DocumentStoreException expected) {
@@ -131,7 +131,7 @@ public class RDBDocumentSerializerTest {
 
     @Test
     public void testNullModified() throws UnsupportedEncodingException {
-        RDBRow row = new RDBRow("_foo", 1L, true, null, 2l, 3l, "{}", null);
+        RDBRow row = new RDBRow("_foo", 1L, true, null, 2l, 3l, 0L, "{}", 
null);
         NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
         assertNull(doc.getModified());
     }
@@ -139,7 +139,7 @@ public class RDBDocumentSerializerTest {
     @Test
     public void testBrokenJSONTrailingComma() throws 
UnsupportedEncodingException {
         try {
-            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, "{ \"x\" : 
1, }", null);
+            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, 0L, "{ 
\"x\" : 1, }", null);
             this.ser.fromRow(Collection.NODES, row);
             fail("should fail");
         } catch (DocumentStoreException expected) {
@@ -149,7 +149,7 @@ public class RDBDocumentSerializerTest {
     @Test
     public void testBrokenJSONUnquotedIdentifier() throws 
UnsupportedEncodingException {
         try {
-            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, "{ x : 1, 
}", null);
+            RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, 0L, "{ x : 
1, }", null);
             this.ser.fromRow(Collection.NODES, row);
             fail("should fail");
         } catch (DocumentStoreException expected) {
@@ -158,7 +158,7 @@ public class RDBDocumentSerializerTest {
 
     @Test
     public void testSimpleStringNonAscii() {
-        RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, 
"{\"x\":\"\u20ac\uD834\uDD1E\"}", null);
+        RDBRow row = new RDBRow("_foo", 1L, false, 1l, 2l, 3l, 0L, 
"{\"x\":\"\u20ac\uD834\uDD1E\"}", null);
         NodeDocument doc = this.ser.fromRow(Collection.NODES, row);
         assertEquals("_foo", doc.getId());
         assertEquals("\u20ac\uD834\uDD1E", doc.get("x"));


Reply via email to