summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2006-09-11 04:48:34 +0000
committerBrian S. O'Neill <bronee@gmail.com>2006-09-11 04:48:34 +0000
commitb845f7f86bfb7150924d968335535ce26c592b82 (patch)
tree3d5f5373470a43db51146545a202edf3431a4f32 /src/main/java
parent9024b39d2c44818a5616ad4d3d74ead28a7d486b (diff)
Switch JDBC repository to use new query engine.
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/com/amazon/carbonado/qe/QueryExecutorCache.java2
-rw-r--r--src/main/java/com/amazon/carbonado/qe/StandardQuery.java31
-rw-r--r--src/main/java/com/amazon/carbonado/qe/StandardQueryFactory.java23
-rw-r--r--src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java420
4 files changed, 242 insertions, 234 deletions
diff --git a/src/main/java/com/amazon/carbonado/qe/QueryExecutorCache.java b/src/main/java/com/amazon/carbonado/qe/QueryExecutorCache.java
index da944fa..2729851 100644
--- a/src/main/java/com/amazon/carbonado/qe/QueryExecutorCache.java
+++ b/src/main/java/com/amazon/carbonado/qe/QueryExecutorCache.java
@@ -42,7 +42,7 @@ public class QueryExecutorCache<S extends Storable> implements QueryExecutorFact
// Maps filters to maps which map ordering lists to executors.
private final Map<Filter<S>, Map<OrderingList<S>, QueryExecutor<S>>> mFilterToExecutor;
- protected QueryExecutorCache(QueryExecutorFactory<S> factory) {
+ public QueryExecutorCache(QueryExecutorFactory<S> factory) {
if (factory == null) {
throw new IllegalArgumentException();
}
diff --git a/src/main/java/com/amazon/carbonado/qe/StandardQuery.java b/src/main/java/com/amazon/carbonado/qe/StandardQuery.java
index bb1dcc3..2e1cdfc 100644
--- a/src/main/java/com/amazon/carbonado/qe/StandardQuery.java
+++ b/src/main/java/com/amazon/carbonado/qe/StandardQuery.java
@@ -364,10 +364,22 @@ public abstract class StandardQuery<S extends Storable> extends AbstractQuery<S>
}
/**
+ * Returns the executor in use by this query.
+ */
+ protected QueryExecutor<S> executor() throws RepositoryException {
+ QueryExecutor<S> executor = mExecutor;
+ if (executor == null) {
+ Filter<S> filter = mValues == null ? null : mValues.getFilter();
+ mExecutor = executor = executorFactory().executor(filter, mOrdering);
+ }
+ return executor;
+ }
+
+ /**
* Ensures that a cached query executor reference is available. If not, the
* query executor factory is called and the executor is cached.
*/
- protected void setExecutorReference() throws RepositoryException {
+ protected void setExecutor() throws RepositoryException {
executor();
}
@@ -375,7 +387,7 @@ public abstract class StandardQuery<S extends Storable> extends AbstractQuery<S>
* Resets any cached reference to a query executor. If a reference is
* available, it is replaced, but a clear reference is not set.
*/
- protected void resetExecutorReference() throws RepositoryException {
+ protected void resetExecutor() throws RepositoryException {
if (mExecutor != null) {
Filter<S> filter = mValues == null ? null : mValues.getFilter();
mExecutor = executorFactory().executor(filter, mOrdering);
@@ -387,7 +399,7 @@ public abstract class StandardQuery<S extends Storable> extends AbstractQuery<S>
* Query is used, it will get an executor from the query executor factory
* and cache a reference to it.
*/
- protected void clearExecutorReference() {
+ protected void clearExecutor() {
mExecutor = null;
}
@@ -415,10 +427,10 @@ public abstract class StandardQuery<S extends Storable> extends AbstractQuery<S>
* passed in the constructor.
*
* @param values optional values object, defaults to open filter if null
- * @param orderings order-by properties, never null
+ * @param ordering order-by properties, never null
*/
protected abstract StandardQuery<S> newInstance(FilterValues<S> values,
- OrderingList<S> orderings);
+ OrderingList<S> ordering);
private StandardQuery<S> newInstance(FilterValues<S> values) {
return newInstance(values, mOrdering);
@@ -433,13 +445,4 @@ public abstract class StandardQuery<S extends Storable> extends AbstractQuery<S>
{
return queryFactory().query(values, ordering);
}
-
- private QueryExecutor<S> executor() throws RepositoryException {
- QueryExecutor<S> executor = mExecutor;
- if (executor == null) {
- Filter<S> filter = mValues == null ? null : mValues.getFilter();
- mExecutor = executor = executorFactory().executor(filter, mOrdering);
- }
- return executor;
- }
}
diff --git a/src/main/java/com/amazon/carbonado/qe/StandardQueryFactory.java b/src/main/java/com/amazon/carbonado/qe/StandardQueryFactory.java
index 8b9a3a9..c9b0557 100644
--- a/src/main/java/com/amazon/carbonado/qe/StandardQueryFactory.java
+++ b/src/main/java/com/amazon/carbonado/qe/StandardQueryFactory.java
@@ -135,7 +135,7 @@ public abstract class StandardQueryFactory<S extends Storable> implements QueryF
StandardQuery<S> standardQuery = createQuery(values, ordering);
if (!mLazySetExecutor) {
try {
- standardQuery.setExecutorReference();
+ standardQuery.setExecutor();
} catch (RepositoryException e) {
throw e.toFetchException();
}
@@ -168,33 +168,33 @@ public abstract class StandardQueryFactory<S extends Storable> implements QueryF
}
/**
- * For each cached query, calls {@link StandardQuery#setExecutorReference}.
+ * For each cached query, calls {@link StandardQuery#setExecutor}.
*/
- public void setExecutorReferences() throws RepositoryException {
+ public void setExecutors() throws RepositoryException {
for (StandardQuery<S> query : gatherQueries()) {
- query.setExecutorReference();
+ query.setExecutor();
}
}
/**
- * For each cached query, calls {@link StandardQuery#resetExecutorReference}.
+ * For each cached query, calls {@link StandardQuery#resetExecutor}.
* This call can be used to rebuild all cached query plans after the set of
* available indexes has changed.
*/
- public void resetExecutorReferences() throws RepositoryException {
+ public void resetExecutors() throws RepositoryException {
for (StandardQuery<S> query : gatherQueries()) {
- query.resetExecutorReference();
+ query.resetExecutor();
}
}
/**
- * For each cached query, calls {@link StandardQuery#clearExecutorReference}.
+ * For each cached query, calls {@link StandardQuery#clearExecutor}.
* This call can be used to clear all cached query plans after the set of
* available indexes has changed.
*/
- public void clearExecutorReferences() {
+ public void clearExecutos() {
for (StandardQuery<S> query : gatherQueries()) {
- query.clearExecutorReference();
+ query.clearExecutor();
}
}
@@ -205,7 +205,8 @@ public abstract class StandardQueryFactory<S extends Storable> implements QueryF
* @param ordering optional order-by properties
*/
protected abstract StandardQuery<S> createQuery(FilterValues<S> values,
- OrderingList<S> ordering);
+ OrderingList<S> ordering)
+ throws FetchException;
private ArrayList<StandardQuery<S>> gatherQueries() {
// Copy all queries and operate on the copy instead of holding lock for
diff --git a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java
index d5b2187..5d4a4a2 100644
--- a/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java
+++ b/src/main/java/com/amazon/carbonado/repo/jdbc/JDBCStorage.java
@@ -37,6 +37,7 @@ import org.apache.commons.logging.LogFactory;
import com.amazon.carbonado.Cursor;
import com.amazon.carbonado.FetchException;
+import com.amazon.carbonado.IsolationLevel;
import com.amazon.carbonado.PersistException;
import com.amazon.carbonado.Query;
import com.amazon.carbonado.Repository;
@@ -44,6 +45,7 @@ import com.amazon.carbonado.RepositoryException;
import com.amazon.carbonado.Storable;
import com.amazon.carbonado.Storage;
import com.amazon.carbonado.SupportException;
+import com.amazon.carbonado.Transaction;
import com.amazon.carbonado.Trigger;
import com.amazon.carbonado.capability.IndexInfo;
@@ -61,19 +63,26 @@ import com.amazon.carbonado.info.OrderedProperty;
import com.amazon.carbonado.info.StorableProperty;
import com.amazon.carbonado.info.StorablePropertyAdapter;
-import com.amazon.carbonado.spi.BaseQuery;
-import com.amazon.carbonado.spi.BaseQueryCompiler;
import com.amazon.carbonado.spi.SequenceValueProducer;
import com.amazon.carbonado.spi.TriggerManager;
import com.amazon.carbonado.util.QuickConstructorGenerator;
+import com.amazon.carbonado.qe.AbstractQueryExecutor;
+import com.amazon.carbonado.qe.OrderingList;
+import com.amazon.carbonado.qe.QueryExecutor;
+import com.amazon.carbonado.qe.QueryExecutorFactory;
+import com.amazon.carbonado.qe.QueryExecutorCache;
+import com.amazon.carbonado.qe.QueryFactory;
+import com.amazon.carbonado.qe.StandardQuery;
+import com.amazon.carbonado.qe.StandardQueryFactory;
+
/**
*
*
* @author Brian S O'Neill
*/
-class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
+class JDBCStorage<S extends Storable> extends StandardQueryFactory<S>
implements Storage<S>, JDBCSupport<S>
{
private static final String TABLE_ALIAS_PREFIX = "T";
@@ -83,13 +92,14 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
final JDBCSupportStrategy mSupportStrategy;
final JDBCStorableInfo<S> mInfo;
final InstanceFactory mInstanceFactory;
+ final QueryExecutorFactory<S> mExecutorFactory;
final TriggerManager<S> mTriggerManager;
JDBCStorage(JDBCRepository repository, JDBCStorableInfo<S> info)
throws SupportException
{
- super(info);
+ super(info.getStorableType());
mRepository = repository;
mSupportStrategy = repository.getSupportStrategy();
mInfo = info;
@@ -98,6 +108,8 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
mInstanceFactory = QuickConstructorGenerator
.getInstance(generatedStorableClass, InstanceFactory.class);
+ mExecutorFactory = new QueryExecutorCache<S>(new ExecutorFactory());
+
mTriggerManager = new TriggerManager<S>();
}
@@ -109,18 +121,6 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
return (S) mInstanceFactory.instantiate(this);
}
- public Query<S> query() throws FetchException {
- return getCompiledQuery();
- }
-
- public Query<S> query(String filter) throws FetchException {
- return getCompiledQuery(filter);
- }
-
- public Query<S> query(Filter<S> filter) throws FetchException {
- return getCompiledQuery(filter);
- }
-
public JDBCRepository getJDBCRepository() {
return mRepository;
}
@@ -248,127 +248,137 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
return mInfo;
}
- protected Query<S> compileQuery(FilterValues<S> values, OrderedProperty<S>[] orderings)
- throws FetchException, UnsupportedOperationException
- {
- JoinNode jn;
- try {
- JoinNodeBuilder jnb = new JoinNodeBuilder();
- if (values == null) {
- jn = new JoinNode(getStorableInfo(), null);
- } else {
- values.getFilter().accept(jnb, null);
- jn = jnb.getRootJoinNode();
- }
- jnb.captureOrderings(orderings);
- } catch (UndeclaredThrowableException e) {
- throw mRepository.toFetchException(e);
- }
-
- StatementBuilder selectBuilder = new StatementBuilder();
- selectBuilder.append("SELECT ");
-
- // Don't bother using a table alias for one table. With just one table,
- // there's no need to disambiguate.
- String alias = jn.hasAnyJoins() ? jn.getAlias() : null;
+ protected StandardQuery<S> createQuery(FilterValues<S> values, OrderingList<S> ordering) {
+ return new JDBCQuery(values, ordering);
+ }
- Map<String, JDBCStorableProperty<S>> properties = getStorableInfo().getAllProperties();
- int ordinal = 0;
- for (JDBCStorableProperty<S> property : properties.values()) {
- if (!property.isSelectable()) {
- continue;
- }
- if (ordinal > 0) {
- selectBuilder.append(',');
- }
- if (alias != null) {
- selectBuilder.append(alias);
- selectBuilder.append('.');
- }
- selectBuilder.append(property.getColumnName());
- ordinal++;
- }
+ public S instantiate(ResultSet rs) throws SQLException {
+ return (S) mInstanceFactory.instantiate(this, rs, FIRST_RESULT_INDEX);
+ }
- selectBuilder.append(" FROM");
+ public static interface InstanceFactory {
+ Storable instantiate(JDBCSupport storage);
- StatementBuilder fromWhereBuilder = new StatementBuilder();
- fromWhereBuilder.append(" FROM");
+ Storable instantiate(JDBCSupport storage, ResultSet rs, int offset) throws SQLException;
+ }
- if (alias == null) {
- // Don't bother defining a table alias for one table.
- jn.appendTableNameTo(selectBuilder);
- jn.appendTableNameTo(fromWhereBuilder);
- } else {
- jn.appendFullJoinTo(selectBuilder);
- jn.appendFullJoinTo(fromWhereBuilder);
+ private class ExecutorFactory implements QueryExecutorFactory<S> {
+ public Class<S> getStorableType() {
+ return JDBCStorage.this.getStorableType();
}
- PropertyFilter<S>[] propertyFilters;
- boolean[] propertyFilterNullable;
-
- if (values == null) {
- propertyFilters = null;
- propertyFilterNullable = null;
- } else {
- // Build the WHERE clause only if anything to filter on.
- selectBuilder.append(" WHERE ");
- fromWhereBuilder.append(" WHERE ");
-
- WhereBuilder wb = new WhereBuilder(selectBuilder, alias == null ? null : jn);
- FetchException e = values.getFilter().accept(wb, null);
- if (e != null) {
- throw e;
+ public QueryExecutor<S> executor(Filter<S> filter, OrderingList<S> ordering)
+ throws RepositoryException
+ {
+ JoinNode jn;
+ try {
+ JoinNodeBuilder jnb = new JoinNodeBuilder();
+ if (filter == null) {
+ jn = new JoinNode(getStorableInfo(), null);
+ } else {
+ filter.accept(jnb, null);
+ jn = jnb.getRootJoinNode();
+ }
+ jnb.captureOrderings(ordering);
+ } catch (UndeclaredThrowableException e) {
+ throw mRepository.toFetchException(e);
}
- propertyFilters = wb.getPropertyFilters();
- propertyFilterNullable = wb.getPropertyFilterNullable();
+ StatementBuilder selectBuilder = new StatementBuilder();
+ selectBuilder.append("SELECT ");
- wb = new WhereBuilder(fromWhereBuilder, alias == null ? null : jn);
- e = values.getFilter().accept(wb, null);
- if (e != null) {
- throw e;
- }
- }
+ // Don't bother using a table alias for one table. With just one table,
+ // there's no need to disambiguate.
+ String alias = jn.hasAnyJoins() ? jn.getAlias() : null;
- // Append order-by clause.
- if (orderings != null && orderings.length != 0) {
- selectBuilder.append(" ORDER BY ");
- ordinal = 0;
- for (OrderedProperty<S> orderedProperty : orderings) {
+ Map<String, JDBCStorableProperty<S>> properties = getStorableInfo().getAllProperties();
+ int ordinal = 0;
+ for (JDBCStorableProperty<S> property : properties.values()) {
+ if (!property.isSelectable()) {
+ continue;
+ }
if (ordinal > 0) {
selectBuilder.append(',');
}
- selectBuilder.appendColumn(alias == null ? null : jn,
- orderedProperty.getChainedProperty());
- if (orderedProperty.getDirection() == Direction.DESCENDING) {
- selectBuilder.append(" DESC");
+ if (alias != null) {
+ selectBuilder.append(alias);
+ selectBuilder.append('.');
}
+ selectBuilder.append(property.getColumnName());
ordinal++;
}
- }
- try {
- CursorFactory factory = new CursorFactory(selectBuilder.build(),
- fromWhereBuilder.build(),
- propertyFilters,
- propertyFilterNullable);
- return new JDBCQuery(factory, values, orderings);
- } catch (RepositoryException e) {
- throw mRepository.toFetchException(e);
- }
- }
+ selectBuilder.append(" FROM");
- public S instantiate(ResultSet rs) throws SQLException {
- return (S) mInstanceFactory.instantiate(this, rs, FIRST_RESULT_INDEX);
- }
+ StatementBuilder fromWhereBuilder = new StatementBuilder();
+ fromWhereBuilder.append(" FROM");
- public static interface InstanceFactory {
- Storable instantiate(JDBCSupport storage);
+ if (alias == null) {
+ // Don't bother defining a table alias for one table.
+ jn.appendTableNameTo(selectBuilder);
+ jn.appendTableNameTo(fromWhereBuilder);
+ } else {
+ jn.appendFullJoinTo(selectBuilder);
+ jn.appendFullJoinTo(fromWhereBuilder);
+ }
- Storable instantiate(JDBCSupport storage, ResultSet rs, int offset) throws SQLException;
+ PropertyFilter<S>[] propertyFilters;
+ boolean[] propertyFilterNullable;
+
+ if (filter == null) {
+ propertyFilters = null;
+ propertyFilterNullable = null;
+ } else {
+ // Build the WHERE clause only if anything to filter on.
+ selectBuilder.append(" WHERE ");
+ fromWhereBuilder.append(" WHERE ");
+
+ WhereBuilder wb = new WhereBuilder(selectBuilder, alias == null ? null : jn);
+ FetchException e = filter.accept(wb, null);
+ if (e != null) {
+ throw e;
+ }
+
+ propertyFilters = wb.getPropertyFilters();
+ propertyFilterNullable = wb.getPropertyFilterNullable();
+
+ wb = new WhereBuilder(fromWhereBuilder, alias == null ? null : jn);
+ e = filter.accept(wb, null);
+ if (e != null) {
+ throw e;
+ }
+ }
+
+ // Append order-by clause.
+ if (ordering != null && ordering.size() != 0) {
+ selectBuilder.append(" ORDER BY ");
+ ordinal = 0;
+ for (OrderedProperty<S> orderedProperty : ordering) {
+ if (ordinal > 0) {
+ selectBuilder.append(',');
+ }
+ selectBuilder.appendColumn(alias == null ? null : jn,
+ orderedProperty.getChainedProperty());
+ if (orderedProperty.getDirection() == Direction.DESCENDING) {
+ selectBuilder.append(" DESC");
+ }
+ ordinal++;
+ }
+ }
+
+ return new Executor(filter,
+ ordering,
+ selectBuilder.build(),
+ fromWhereBuilder.build(),
+ propertyFilters,
+ propertyFilterNullable);
+ }
}
- private class CursorFactory {
+ private class Executor extends AbstractQueryExecutor<S> {
+ private final Filter<S> mFilter;
+ private final OrderingList<S> mOrdering;
+
private final Statement<S> mSelectStatement;
private final int mMaxSelectStatementLength;
private final Statement<S> mFromWhereStatement;
@@ -387,12 +397,17 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
// Some entries may be null if no adapter required.
private final Object[] mAdapterInstances;
- CursorFactory(Statement<S> selectStatement,
- Statement<S> fromWhereStatement,
- PropertyFilter<S>[] propertyFilters,
- boolean[] propertyFilterNullable)
+ Executor(Filter<S> filter,
+ OrderingList<S> ordering,
+ Statement<S> selectStatement,
+ Statement<S> fromWhereStatement,
+ PropertyFilter<S>[] propertyFilters,
+ boolean[] propertyFilterNullable)
throws RepositoryException
{
+ mFilter = filter;
+ mOrdering = ordering;
+
mSelectStatement = selectStatement;
mMaxSelectStatementLength = selectStatement.maxLength();
mFromWhereStatement = fromWhereStatement;
@@ -440,21 +455,69 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
}
}
- JDBCCursor<S> openCursor(FilterValues<S> filterValues, boolean forUpdate)
- throws FetchException
- {
+ public Cursor<S> fetch(FilterValues<S> values) throws FetchException {
+ boolean forUpdate = mRepository.openTransactionManager().isForUpdate();
Connection con = mRepository.getConnection();
try {
- PreparedStatement ps =
- con.prepareStatement(prepareSelect(filterValues, forUpdate));
-
- setParameters(ps, filterValues);
+ PreparedStatement ps = con.prepareStatement(prepareSelect(values, forUpdate));
+ setParameters(ps, values);
return new JDBCCursor<S>(JDBCStorage.this, con, ps);
} catch (Exception e) {
throw mRepository.toFetchException(e);
}
}
+ @Override
+ public long count(FilterValues<S> values) throws FetchException {
+ Connection con = mRepository.getConnection();
+ try {
+ PreparedStatement ps = con.prepareStatement(prepareCount(values));
+ setParameters(ps, values);
+ ResultSet rs = ps.executeQuery();
+ try {
+ rs.next();
+ return rs.getLong(1);
+ } finally {
+ rs.close();
+ }
+ } catch (Exception e) {
+ throw mRepository.toFetchException(e);
+ } finally {
+ mRepository.yieldConnection(con);
+ }
+ }
+
+ public Filter<S> getFilter() {
+ return mFilter;
+ }
+
+ public OrderingList<S> getOrdering() {
+ return mOrdering;
+ }
+
+ public boolean printNative(Appendable app, int indentLevel, FilterValues<S> values)
+ throws IOException
+ {
+ indent(app, indentLevel);
+ boolean forUpdate = mRepository.openTransactionManager().isForUpdate();
+ app.append(prepareSelect(values, forUpdate));
+ app.append('\n');
+ return true;
+ }
+
+ public boolean printPlan(Appendable app, int indentLevel, FilterValues<S> values)
+ throws IOException
+ {
+ try {
+ boolean forUpdate = mRepository.openTransactionManager().isForUpdate();
+ String statement = prepareSelect(values, forUpdate);
+ return mRepository.getSupportStrategy().printPlan(app, indentLevel, statement);
+ } catch (FetchException e) {
+ LogFactory.getLog(JDBCStorage.class).error(null, e);
+ return false;
+ }
+ }
+
/**
* Delete operation is included in cursor factory for ease of implementation.
*/
@@ -480,29 +543,7 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
}
}
- /**
- * Count operation is included in cursor factory for ease of implementation.
- */
- long executeCount(FilterValues<S> filterValues) throws FetchException {
- Connection con = mRepository.getConnection();
- try {
- PreparedStatement ps = con.prepareStatement(prepareCount(filterValues));
- setParameters(ps, filterValues);
- ResultSet rs = ps.executeQuery();
- try {
- rs.next();
- return rs.getLong(1);
- } finally {
- rs.close();
- }
- } catch (Exception e) {
- throw mRepository.toFetchException(e);
- } finally {
- mRepository.yieldConnection(con);
- }
- }
-
- String prepareSelect(FilterValues<S> filterValues, boolean forUpdate) {
+ private String prepareSelect(FilterValues<S> filterValues, boolean forUpdate) {
if (!forUpdate) {
return mSelectStatement.buildStatement(mMaxSelectStatementLength, filterValues);
}
@@ -514,7 +555,7 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
return b.toString();
}
- String prepareDelete(FilterValues<S> filterValues) {
+ private String prepareDelete(FilterValues<S> filterValues) {
// Allocate with extra room for "DELETE"
StringBuilder b = new StringBuilder(6 + mMaxFromWhereStatementLength);
b.append("DELETE");
@@ -522,7 +563,7 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
return b.toString();
}
- String prepareCount(FilterValues<S> filterValues) {
+ private String prepareCount(FilterValues<S> filterValues) {
// Allocate with extra room for "SELECT COUNT(*)"
StringBuilder b = new StringBuilder(15 + mMaxFromWhereStatementLength);
b.append("SELECT COUNT(*)");
@@ -569,77 +610,40 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
}
}
- private class JDBCQuery extends BaseQuery<S> {
- private final CursorFactory mCursorFactory;
-
- JDBCQuery(CursorFactory factory,
- FilterValues<S> values,
- OrderedProperty<S>[] orderings)
- {
- super(mRepository, JDBCStorage.this, values, orderings);
- mCursorFactory = factory;
- }
-
- JDBCQuery(CursorFactory factory,
- FilterValues<S> values,
- String[] orderings)
- {
- super(mRepository, JDBCStorage.this, values, orderings);
- mCursorFactory = factory;
- }
-
- public Query<S> orderBy(String property)
- throws FetchException, UnsupportedOperationException
- {
- return JDBCStorage.this.getOrderedQuery(getFilterValues(), property);
- }
-
- public Query<S> orderBy(String... properties)
- throws FetchException, UnsupportedOperationException
- {
- return JDBCStorage.this.getOrderedQuery(getFilterValues(), properties);
- }
-
- public Cursor<S> fetch() throws FetchException {
- boolean forUpdate = mRepository.openTransactionManager().isForUpdate();
- return mCursorFactory.openCursor(getFilterValues(), forUpdate);
+ private class JDBCQuery extends StandardQuery<S> {
+ JDBCQuery(FilterValues<S> values, OrderingList<S> ordering) {
+ super(values, ordering);
}
+ @Override
public void deleteAll() throws PersistException {
if (mTriggerManager.getDeleteTrigger() != null) {
// Super implementation loads one at time and calls
// delete. This allows delete trigger to be invoked on each.
super.deleteAll();
} else {
- mCursorFactory.executeDelete(getFilterValues());
+ try {
+ ((Executor) executor()).executeDelete(getFilterValues());
+ } catch (RepositoryException e) {
+ throw e.toPersistException();
+ }
}
}
- public long count() throws FetchException {
- return mCursorFactory.executeCount(getFilterValues());
+ protected Transaction enterTransaction(IsolationLevel level) {
+ return getRootRepository().enterTransaction(level);
}
- public boolean printNative(Appendable app, int indentLevel) throws IOException {
- indent(app, indentLevel);
- boolean forUpdate = mRepository.openTransactionManager().isForUpdate();
- app.append(mCursorFactory.prepareSelect(getFilterValues(), forUpdate));
- app.append('\n');
- return true;
+ protected QueryFactory<S> queryFactory() {
+ return JDBCStorage.this;
}
- public boolean printPlan(Appendable app, int indentLevel) throws IOException {
- try {
- boolean forUpdate = mRepository.openTransactionManager().isForUpdate();
- String statement = mCursorFactory.prepareSelect(getFilterValues(), forUpdate);
- return mRepository.getSupportStrategy().printPlan(app, indentLevel, statement);
- } catch (FetchException e) {
- LogFactory.getLog(JDBCStorage.class).error(null, e);
- return false;
- }
+ protected QueryExecutorFactory<S> executorFactory() {
+ return JDBCStorage.this.mExecutorFactory;
}
- protected BaseQuery<S> newInstance(FilterValues<S> values) {
- return new JDBCQuery(mCursorFactory, values, getOrderings());
+ protected StandardQuery<S> newInstance(FilterValues<S> values, OrderingList<S> ordering) {
+ return new JDBCQuery(values, ordering);
}
}
@@ -818,10 +822,10 @@ class JDBCStorage<S extends Storable> extends BaseQueryCompiler<S>
*
* @throws UndeclaredThrowableException wraps a RepositoryException
*/
- public void captureOrderings(OrderedProperty<?>[] orderings) {
+ public void captureOrderings(OrderingList<?> ordering) {
try {
- if (orderings != null) {
- for (OrderedProperty<?> orderedProperty : orderings) {
+ if (ordering != null) {
+ for (OrderedProperty<?> orderedProperty : ordering) {
ChainedProperty<?> chained = orderedProperty.getChainedProperty();
mAliasCounter = mRootJoinNode.addJoin(chained, mAliasCounter);
}