Author: reschke
Date: Tue Mar 25 15:38:15 2014
New Revision: 1581378

URL: http://svn.apache.org/r1581378
Log:
OAK-1544: fix field widths and add BLOB column for big documents; add DB2 
fixture

Modified:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/document/rdb/RDBDocumentStore.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.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=1581378&r1=1581377&r2=1581378&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 Mar 25 15:38:15 2014
@@ -16,6 +16,9 @@
  */
 package org.apache.jackrabbit.oak.plugins.document.rdb;
 
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.sql.Connection;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
@@ -36,6 +39,7 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.sql.DataSource;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.mk.api.MicroKernelException;
 import org.apache.jackrabbit.oak.cache.CacheStats;
 import org.apache.jackrabbit.oak.cache.CacheValue;
@@ -67,7 +71,7 @@ public class RDBDocumentStore implements
      */
     public RDBDocumentStore(DocumentMK.Builder builder) {
         try {
-            String jdbcurl = "jdbc:h2:mem:oaknodes";
+            String jdbcurl = "jdbc:h2:file:oaknodes";
             DataSource ds = RDBDataSourceFactory.forJdbcUrl(jdbcurl, "sa", "");
             initialize(ds, builder);
         } catch (Exception ex) {
@@ -246,6 +250,9 @@ public class RDBDocumentStore implements
 
     private DataSource ds;
 
+    // string length at which we switch to BLOB storage
+    private static int DATALIMIT = 16384 / 4;
+
     private void initialize(DataSource ds, DocumentMK.Builder builder) throws 
Exception {
 
         this.ds = ds;
@@ -260,9 +267,9 @@ public class RDBDocumentStore implements
             con.setAutoCommit(false);
 
             Statement stmt = con.createStatement();
-            stmt.execute("create table if not exists CLUSTERNODES(ID varchar 
primary key, MODIFIED bigint, MODCOUNT bigint, DATA varchar)");
-            stmt.execute("create table if not exists NODES(ID varchar primary 
key, MODIFIED bigint, MODCOUNT bigint, DATA varchar)");
-            stmt.execute("create table if not exists SETTINGS(ID varchar 
primary key, MODIFIED bigint, MODCOUNT bigint, DATA varchar)");
+            stmt.execute("create table if not exists CLUSTERNODES(ID 
varchar(1000) primary key, MODIFIED bigint, MODCOUNT bigint, DATA 
varchar(16384), BDATA blob)");
+            stmt.execute("create table if not exists NODES(ID varchar(1000) 
primary key, MODIFIED bigint, MODCOUNT bigint, DATA varchar(16384), BDATA 
blob)");
+            stmt.execute("create table if not exists SETTINGS(ID varchar(1000) 
primary key, MODIFIED bigint, MODCOUNT bigint, DATA varchar(16384), BDATA 
blob)");
             stmt.close();
 
             con.commit();
@@ -540,14 +547,37 @@ public class RDBDocumentStore implements
 
     // low level operations
 
+    private String getData(ResultSet rs, int stringIndex, int blobIndex) 
throws SQLException {
+        try {
+            String data = rs.getString(stringIndex);
+            byte[] bdata = rs.getBytes(blobIndex);
+            if (bdata == null) {
+                return data;
+            } else {
+                return IOUtils.toString(bdata, "UTF-8");
+            }
+        } catch (IOException e) {
+            throw new SQLException(e);
+        }
+    }
+
+    private static ByteArrayInputStream asInputStream(String data) {
+        try {
+            return new ByteArrayInputStream(data.getBytes("UTF-8"));
+        } catch (UnsupportedEncodingException ex) {
+            LOG.error("This REALLY is not supposed to happen", ex);
+            return null;
+        }
+    }
+
     @CheckForNull
     private String dbRead(Connection connection, String tableName, String id) 
throws SQLException {
-        PreparedStatement stmt = connection.prepareStatement("select DATA from 
" + tableName + " where ID = ?");
+        PreparedStatement stmt = connection.prepareStatement("select DATA, 
BDATA from " + tableName + " where ID = ?");
         try {
             stmt.setString(1, id);
             ResultSet rs = stmt.executeQuery();
             if (rs.next()) {
-                return rs.getString(1);
+                return getData(rs, 1, 2);
             } else {
                 return null;
             }
@@ -558,7 +588,7 @@ public class RDBDocumentStore implements
 
     private List<String> dbQuery(Connection connection, String tableName, 
String minId, String maxId, String indexedProperty,
             long startValue, int limit) throws SQLException {
-        String t = "select DATA from " + tableName + " where ID > ? and ID < 
?";
+        String t = "select DATA, BDATA from " + tableName + " where ID > ? and 
ID < ?";
         if (indexedProperty != null) {
             t += " and MODIFIED >= ?";
         }
@@ -580,7 +610,7 @@ public class RDBDocumentStore implements
             }
             ResultSet rs = stmt.executeQuery();
             while (rs.next()) {
-                String data = rs.getString(1);
+                String data = getData(rs, 1, 2);
                 result.add(data);
             }
         } finally {
@@ -591,7 +621,7 @@ public class RDBDocumentStore implements
 
     private boolean dbUpdate(Connection connection, String tableName, String 
id, Long modified, Long modcount, Long oldmodcount,
             String data) throws SQLException {
-        String t = "update " + tableName + " set MODIFIED = ?, MODCOUNT = ?, 
DATA = ? where ID = ?";
+        String t = "update " + tableName + " set MODIFIED = ?, MODCOUNT = ?, 
DATA = ?, BDATA = ? where ID = ?";
         if (oldmodcount != null) {
             t += " and MODCOUNT = ?";
         }
@@ -600,7 +630,16 @@ public class RDBDocumentStore implements
             int si = 1;
             stmt.setObject(si++, modified, Types.BIGINT);
             stmt.setObject(si++, modcount, Types.BIGINT);
-            stmt.setString(si++, data);
+
+            if (data.length() < DATALIMIT) {
+                stmt.setString(si++, data);
+                stmt.setBinaryStream(si++, null, 0);
+            } else {
+                stmt.setString(si++, "truncated...:" + data.substring(0, 
1023));
+                ByteArrayInputStream bis = asInputStream(data);
+                stmt.setBinaryStream(si++, bis, bis.available());
+            }
+
             stmt.setString(si++, id);
             if (oldmodcount != null) {
                 stmt.setObject(si++, oldmodcount, Types.BIGINT);
@@ -617,12 +656,21 @@ public class RDBDocumentStore implements
 
     private boolean dbInsert(Connection connection, String tableName, String 
id, Long modified, Long modcount, String data)
             throws SQLException {
-        PreparedStatement stmt = connection.prepareStatement("insert into " + 
tableName + " values(?, ?, ?, ?)");
+        PreparedStatement stmt = connection.prepareStatement("insert into " + 
tableName + " values(?, ?, ?, ?, ?)");
         try {
-            stmt.setString(1, id);
-            stmt.setObject(2, modified, Types.BIGINT);
-            stmt.setObject(3, modcount, Types.BIGINT);
-            stmt.setString(4, data);
+            int si = 1;
+            stmt.setString(si++, id);
+            stmt.setObject(si++, modified, Types.BIGINT);
+            stmt.setObject(si++, modcount, Types.BIGINT);
+            if (data.length() < DATALIMIT) {
+                stmt.setString(si++, data);
+                stmt.setBinaryStream(si++, null, 0);
+            } else {
+                stmt.setString(si++, "truncated...:" + data.substring(0, 
1023));
+                ByteArrayInputStream bis = asInputStream(data);
+                stmt.setBinaryStream(si++, bis, bis.available());
+            }
+
             int result = stmt.executeUpdate();
             if (result != 1) {
                 LOG.debug("DB insert failed for " + tableName + "/" + id);
@@ -683,7 +731,7 @@ public class RDBDocumentStore implements
      * the cache with the document key. This method does not acquire a lock 
from
      * {@link #locks}! The caller must ensure a lock is held for the given
      * document.
-     *
+     * 
      * @param doc
      *            the document to add to the cache.
      * @return either the given <code>doc</code> or the document already 
present

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java?rev=1581378&r1=1581377&r2=1581378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/AbstractDocumentStoreTest.java
 Tue Mar 25 15:38:15 2014
@@ -37,7 +37,7 @@ public abstract class AbstractDocumentSt
     public static Collection<Object[]> fixtures() {
         Collection<Object[]> result = new ArrayList<Object[]>();
         DocumentStoreFixture candidates[] = new DocumentStoreFixture[] { 
DocumentStoreFixture.MEMORY, DocumentStoreFixture.MONGO,
-                DocumentStoreFixture.RDB_H2, DocumentStoreFixture.RDB_PG};
+                DocumentStoreFixture.RDB_H2, DocumentStoreFixture.RDB_PG, 
DocumentStoreFixture.RDB_DB2 };
 
         for (DocumentStoreFixture dsf : candidates) {
             if (dsf.isAvailable()) {

Modified: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java?rev=1581378&r1=1581377&r2=1581378&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/document/DocumentStoreFixture.java
 Tue Mar 25 15:38:15 2014
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.oak.plugins.document;
 
-import java.sql.SQLException;
-
 import javax.sql.DataSource;
 
 import org.apache.jackrabbit.oak.plugins.document.memory.MemoryDocumentStore;
@@ -37,6 +35,7 @@ public abstract class DocumentStoreFixtu
     public static final DocumentStoreFixture MEMORY = new MemoryFixture();
     public static final DocumentStoreFixture RDB_H2 = new RDBH2Fixture();
     public static final DocumentStoreFixture RDB_PG = new 
RDBFixture("RDB-Postgres", "jdbc:postgresql:oak", "postgres", "geheim");
+    public static final DocumentStoreFixture RDB_DB2 = new 
RDBFixture("RDB-DB2", "jdbc:db2://localhost:50000/OAK", "oak", "geheim");
     public static final DocumentStoreFixture MONGO = new 
MongoFixture("mongodb://localhost:27017/oak");
 
     public abstract String getName();
@@ -87,8 +86,8 @@ public abstract class DocumentStoreFixtu
             try {
                 DataSource datas = RDBDataSourceFactory.forJdbcUrl(url, 
username, passwd);
                 this.ds = new RDBDocumentStore(datas, new 
DocumentMK.Builder());
-            } catch (SQLException ex) {
-                LOG.info("Postgres instance not available at " + url + ", 
skipping tests...");
+            } catch (Exception ex) {
+                LOG.info("Database instance not available at " + url + ", 
skipping tests...", ex);
             }
         }
 


Reply via email to