RDBDocumentStoreJDBC { public List<RDBRow> read(Connection connection, RDBTableMetaData tmd, Collection<String> allKeys) throws SQLException { List<RDBRow> rows = new ArrayList<RDBRow>(); for (List<String> keys : Iterables.partition(allKeys, RDBJDBCTools.MAX_IN_CLAUSE)) { long pstart = PERFLOG.start(PERFLOG.isDebugEnabled() ? ("reading: " + keys) : null); PreparedStatementComponent inClause = RDBJDBCTools.createInStatement("ID", keys, tmd.isIdBinary()); StringBuilder query = new StringBuilder(); if (tmd.hasSplitDocs()) { query.append("select ID, MODIFIED, MODCOUNT, CMODCOUNT, HASBINARY, DELETEDONCE, VERSION, SDTYPE, SDMAXREVTIME, DATA, BDATA from "); } else 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()); PreparedStatement stmt = connection.prepareStatement(query.toString()); ResultSet rs = null; stmt.setPoolable(false); try { inClause.setParameters(stmt, 1); rs = stmt.executeQuery(); while (rs.next()) { 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; long sdType = tmd.hasSplitDocs() ? readLongFromResultSet(rs, field++) : RDBRow.LONG_UNSET; long sdMaxRevTime = tmd.hasSplitDocs() ? readLongFromResultSet(rs, field++) : RDBRow.LONG_UNSET; String data = rs.getString(field++); byte[] bdata = rs.getBytes(field++); RDBRow row = new RDBRow(id, hasBinary, deletedOnce, modified, modcount, cmodcount, schemaVersion, sdType, sdMaxRevTime, data, bdata); rows.add(row); PERFLOG.end(pstart, 10, "read: table={}, id={} -> modcount={}, modified={}, data={}, bdata={}", tmd.getName(), id, modcount, modified, (data == null ? 0 : data.length()), (bdata == null ? 0 : bdata.length)); } } catch (SQLException ex) { LOG.debug("attempting to read " + keys, ex); PERFLOG.end(pstart, 10, "read: table={} -> exception={}", tmd.getName(), ex.getMessage()); if ("22001".equals(ex.getSQLState())) { try { connection.rollback(); } catch (SQLException ex2) { LOG.debug("failed to rollback", ex2); } return null; } else { throw (ex); } } finally { closeResultSet(rs); closeStatement(stmt); } } return rows; } RDBDocumentStoreJDBC(RDBDocumentStoreDB dbInfo, RDBDocumentSerializer ser, int queryHitsLimit, int queryTimeLimit); boolean appendingUpdate(Connection connection, RDBTableMetaData tmd, String id, Long modified,
            boolean setModifiedConditionally, Number hasBinary, Boolean deletedOnce, Long modcount, Long cmodcount,
            Long oldmodcount, String appendData); int delete(Connection connection, RDBTableMetaData tmd, List<String> allIds); int delete(Connection connection, RDBTableMetaData tmd, Map<String, Long> toDelete); int deleteWithCondition(Connection connection, RDBTableMetaData tmd, List<QueryCondition> conditions); long determineServerTimeDifferenceMillis(Connection connection); Set<String> insert(Connection connection, RDBTableMetaData tmd, List<T> documents); Set<String> update(Connection connection, RDBTableMetaData tmd, List<T> documents, boolean upsert); @NotNull List<RDBRow> query(Connection connection, RDBTableMetaData tmd, String minId, String maxId,
            List<String> excludeKeyPatterns, List<QueryCondition> conditions, int limit); long getLong(Connection connection, RDBTableMetaData tmd, String aggregate, String field, String minId, String maxId,
            List<String> excludeKeyPatterns, List<QueryCondition> conditions); @NotNull Iterator<RDBRow> queryAsIterator(RDBConnectionHandler ch, RDBTableMetaData tmd, String minId, String maxId,
            List<String> excludeKeyPatterns, List<QueryCondition> conditions, int limit, String sortBy); List<RDBRow> read(Connection connection, RDBTableMetaData tmd, Collection<String> allKeys); @Nullable RDBRow read(Connection connection, RDBTableMetaData tmd, String id, long lastmodcount, long lastmodified); boolean update(Connection connection, RDBTableMetaData tmd, String id, Long modified, Number hasBinary,
            Boolean deletedOnce, Long modcount, Long cmodcount, Long oldmodcount, String data);  }
@Test public void conditionalRead() throws SQLException { String id = this.getClass().getName() + ".conditionalRead"; super.ds.remove(Collection.NODES, id); UpdateOp op = new UpdateOp(id, true); 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(); } }