Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/StoreCollectionFieldStrategy.java Mon Feb 13 21:23:54 2012 @@ -26,7 +26,6 @@ import java.util.List; import java.util.Map; import org.apache.openjpa.enhance.PersistenceCapable; -import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.ClassMapping; @@ -43,7 +42,7 @@ import org.apache.openjpa.jdbc.sql.Selec import org.apache.openjpa.jdbc.sql.Union; import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.kernel.StateManagerImpl; -import org.apache.openjpa.lib.util.ThreadGate; +import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.util.ChangeTracker; @@ -58,20 +57,12 @@ import org.apache.openjpa.util.Proxy; * insert/update/delete behavior as well as overriding * {@link FieldStrategy#toDataStoreValue}, {@link FieldStrategy#join}, and * {@link FieldStrategy#joinRelation} if necessary. - * <br> - * The strategy may reuse the same {@link SelectExecutor select} if the - * {@link JDBCConfiguration#getSelectCacheEnabled() configuration option} - * instructs to do so. * * @author Abe White - * @author Pinaki Poddar (select caching) */ -@SuppressWarnings("serial") public abstract class StoreCollectionFieldStrategy extends ContainerFieldStrategy { - protected SelectExecutor _executor; - protected ThreadGate _lock = new ThreadGate(); - + /** * Return the foreign key used to join to the owning field for the given * element mapping from {@link #getIndependentElementMappings} (or null). @@ -103,7 +94,8 @@ public abstract class StoreCollectionFie * * @see FieldMapping#joinRelation */ - protected abstract Joins joinElementRelation(Joins joins, ClassMapping elem); + protected abstract Joins joinElementRelation(Joins joins, + ClassMapping elem); /** * Join to the owning field table for the given element mapping from @@ -120,9 +112,9 @@ public abstract class StoreCollectionFie * Convert the field value to a collection. Handles collections and * arrays by default. */ - protected Collection<?> toCollection(Object val) { + protected Collection toCollection(Object val) { if (field.getTypeCode() == JavaTypes.COLLECTION) - return (Collection<?>) val; + return (Collection) val; return JavaTypes.toList(val, field.getElement().getType(), false); } @@ -166,9 +158,8 @@ public abstract class StoreCollectionFie else { final ClassMapping[] elems = getIndependentElementMappings(true); Union union = (Union) sel; - if (union.isReadOnly()) if (fetch.getSubclassFetchMode(field.getElementMapping(). - getTypeMapping()) != JDBCFetchConfiguration.EAGER_JOIN) + getTypeMapping()) != fetch.EAGER_JOIN) union.abortUnion(); union.select(new Union.Selector() { public void select(Select sel, int idx) { @@ -184,13 +175,13 @@ public abstract class StoreCollectionFie // we limit further eager fetches to joins, because after this point // the select has been modified such that parallel clones may produce // invalid sql - if (sel.isReadOnly()) return; boolean outer = field.getNullValue() != FieldMapping.NULL_EXCEPTION; // force inner join for inner join fetch if (fetch.hasFetchInnerJoin(field.getFullName(false))) outer = false; selectEager(sel, getDefaultElementMapping(true), sm, store, fetch, - JDBCFetchConfiguration.EAGER_JOIN, false, outer); + JDBCFetchConfiguration.EAGER_JOIN, false, + outer); } public boolean isEagerSelectToMany() { @@ -203,8 +194,7 @@ public abstract class StoreCollectionFie private void selectEager(Select sel, ClassMapping elem, OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, int eagerMode, boolean selectOid, boolean outer) { - if (sel.isReadOnly()) return; - // force distinct if there was a to-many join to avoid duplicates, but + // force distinct if there was a to-many join to avoid dups, but // if this is a parallel select don't make distinct based on the // eager joins alone if the original wasn't distinct if (eagerMode == JDBCFetchConfiguration.EAGER_PARALLEL) { @@ -224,7 +214,8 @@ public abstract class StoreCollectionFie joins = join(joins, elem); // order, ref cols - if (field.getOrderColumn() != null || field.getOrders().length > 0 || !selectOid) { + if (field.getOrderColumn() != null || field.getOrders().length > 0 + || !selectOid) { if (outer) joins = sel.outer(joins); if (!selectOid) { @@ -362,17 +353,21 @@ public abstract class StoreCollectionFie mappedByValue = owner.getPersistenceCapable(); res.setMappedByFieldMapping(mappedByFieldMapping); res.setMappedByValue(mappedByValue); - } else if (coll instanceof Collection && !((Collection) coll).isEmpty()) { + } else if (coll instanceof Collection && + ((Collection) coll).size() > 0) { // Customer (1) <--> Orders(n) // coll contains the values of the toMany field (Orders) // get the StateManager of this toMany value // and find the value of the inverse mappedBy field (Customer) // for this toMacdny field - PersistenceCapable pc = (PersistenceCapable)((Collection) coll).iterator().next(); - OpenJPAStateManager sm1 = (OpenJPAStateManager) pc.pcGetStateManager(); + PersistenceCapable pc = (PersistenceCapable) + ((Collection) coll).iterator().next(); + OpenJPAStateManager sm1 = (OpenJPAStateManager) pc. + pcGetStateManager(); ClassMapping clm = ((ClassMapping) sm1.getMetaData()); - FieldMapping fm = (FieldMapping) clm.getField(mappedByFieldMapping.getName()); + FieldMapping fm = (FieldMapping) clm.getField( + mappedByFieldMapping.getName()); if (fm == mappedByFieldMapping) res.setMappedByValue(sm1.fetchObject(fm.getIndex())); } else { @@ -518,7 +513,8 @@ public abstract class StoreCollectionFie Result res = sel.execute(store, fetch); try { res.next(); - coll.getChangeTracker().setNextSequence(res.getInt(field) + 1); + coll.getChangeTracker().setNextSequence + (res.getInt(field) + 1); } finally { res.close(); } @@ -526,87 +522,72 @@ public abstract class StoreCollectionFie sm.storeObjectField(field.getIndex(), coll); return; } - // select data for this state manager - // Select can be configured for reuse. The locking mechanics ensures that - // under reuse scenario, the Select structure is built under a thread gate - // but later usage is unguarded because a reused select is (almost) immutable. + + // select data for this sm + final ClassMapping[] elems = getIndependentElementMappings(true); + final Joins[] resJoins = new Joins[Math.max(1, elems.length)]; + Union union = store.getSQLFactory().newUnion + (Math.max(1, elems.length)); + union.select(new Union.Selector() { + public void select(Select sel, int idx) { + ClassMapping elem = (elems.length == 0) ? null : elems[idx]; + resJoins[idx] = selectAll(sel, elem, sm, store, fetch, + JDBCFetchConfiguration.EAGER_PARALLEL); + } + }); + + // create proxy + Object coll; + ChangeTracker ct = null; + if (field.getTypeCode() == JavaTypes.ARRAY) + coll = new ArrayList(); + else { + coll = sm.newProxy(field.getIndex()); + if (coll instanceof Proxy) + ct = ((Proxy) coll).getChangeTracker(); + } + + // load values + Result res = union.execute(store, fetch); try { - _lock.lock(); - final ClassMapping[] elems = getIndependentElementMappings(true); - final Joins[] resJoins = new Joins[Math.max(1, elems.length)]; - Union union; - if (_executor == null) { - union = store.getSQLFactory().newUnion(Math.max(1, elems.length)); - if (store.getConfiguration().getSelectCacheEnabled()) { - _executor = union; - } - } else { - union = (Union)_executor; - } - union.select(new Union.Selector() { - public void select(Select sel, int idx) { - ClassMapping elem = (elems.length == 0) ? null : elems[idx]; - resJoins[idx] = selectAll(sel, elem, sm, store, fetch, JDBCFetchConfiguration.EAGER_PARALLEL); - } - }); - - // create proxy - Object coll; - ChangeTracker ct = null; - if (field.getTypeCode() == JavaTypes.ARRAY) - coll = new ArrayList(); - else { - coll = sm.newProxy(field.getIndex()); - if (coll instanceof Proxy) - ct = ((Proxy) coll).getChangeTracker(); - } - - // load values - Result res = union.execute(store, fetch); - try { - int seq = -1; - boolean ordered = ct != null && field.getOrderColumn() != null; - while (res.next()) { - if (ordered) seq = res.getInt(field.getOrderColumn()); - setMappedBy(sm.getObjectId(), sm, coll, res); - add(store, coll, loadElement(sm, store, fetch, res, resJoins[res.indexOf()])); - } - if (ordered) ct.setNextSequence(seq + 1); - } finally { - res.close(); - } - - // set into sm - if (field.getTypeCode() == JavaTypes.ARRAY) { - sm.storeObject(field.getIndex(), - JavaTypes.toArray((Collection<?>) coll, field.getElement().getType())); - } else { - sm.storeObject(field.getIndex(), coll); - } + int seq = -1; + while (res.next()) { + if (ct != null && field.getOrderColumn() != null) + seq = res.getInt(field.getOrderColumn()); + setMappedBy(sm.getObjectId(), sm, coll, res); + add(store, coll, loadElement(sm, store, fetch, res, + resJoins[res.indexOf()])); + } + if (ct != null && field.getOrderColumn() != null) + ct.setNextSequence(seq + 1); } finally { - _lock.unlock(); + res.close(); } + + // set into sm + if (field.getTypeCode() == JavaTypes.ARRAY) + sm.storeObject(field.getIndex(), JavaTypes.toArray + ((Collection) coll, field.getElement().getType())); + else + sm.storeObject(field.getIndex(), coll); } /** - * Selects data for loading, starting in field table. - * + * Select data for loading, starting in field table. */ protected Joins selectAll(Select sel, ClassMapping elem, - OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, int eagerMode) { + OpenJPAStateManager sm, JDBCStore store, JDBCFetchConfiguration fetch, + int eagerMode) { ForeignKey fk = getJoinForeignKey(elem); Object oid = getObjectIdForJoin(fk, sm); sel.whereForeignKey(fk, oid, field.getDefiningMapping(), store); - if (sel.isReadOnly()) { - return sel.getJoins(); - } + // order first, then select so that if the projection introduces // additional ordering, it will be after our required ordering field.orderLocal(sel, elem, null); Joins joins = joinElementRelation(sel.newJoins(), elem); field.orderRelation(sel, elem, joins); selectElement(sel, elem, store, fetch, eagerMode, joins); - return joins; } @@ -643,9 +624,4 @@ public abstract class StoreCollectionFie } return oid; } - - - public String toString() { - return getClass().getSimpleName() + '[' + field.getName() + ']'; - } }
Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractResult.java Mon Feb 13 21:23:54 2012 @@ -74,7 +74,7 @@ public abstract class AbstractResult private static final Joins JOINS = new NoOpJoins(); - private Map<Object,Object> _eager = null; + private Map _eager = null; private ClassMapping _base = null; private int _index = 0; private boolean _gotEager = false; @@ -86,14 +86,14 @@ public abstract class AbstractResult private Object _mappedByValue = null; public Object getEager(FieldMapping key) { - Map<Object,Object> map = getEagerMap(true); + Map map = getEagerMap(true); return (map == null) ? null : map.get(key); } public void putEager(FieldMapping key, Object res) { - Map<Object,Object> map = getEagerMap(false); + Map map = getEagerMap(false); if (map == null) { - map = new HashMap<Object,Object>(); + map = new HashMap(); setEagerMap(map); } map.put(key, res); @@ -104,7 +104,7 @@ public abstract class AbstractResult * * @param client whether the client is accessing eager information */ - protected Map<Object,Object> getEagerMap(boolean client) { + protected Map getEagerMap(boolean client) { if (client) _gotEager = true; return _eager; @@ -113,7 +113,7 @@ public abstract class AbstractResult /** * Raw eager information. */ - protected void setEagerMap(Map<Object,Object> eager) { + protected void setEagerMap(Map eager) { _eager = eager; } @@ -129,9 +129,11 @@ public abstract class AbstractResult /** * Close all results in eager map. */ - protected void closeEagerMap(Map<Object,Object> eager) { + protected void closeEagerMap(Map eager) { if (eager != null) { - for (Object res : eager.values()) { + Object res; + for (Iterator itr = eager.values().iterator(); itr.hasNext();) { + res = itr.next(); if (res != this && res instanceof Closeable) try { ((Closeable) res).close(); @@ -889,6 +891,9 @@ public abstract class AbstractResult return this; } + public void appendTo(SQLBuffer buf) { + } + public Joins setCorrelatedVariable(String var) { return this; } @@ -899,10 +904,5 @@ public abstract class AbstractResult public void moveJoinsToParent() { } - - @Override - public StringBuilder path() { - return null; - } } } Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java Mon Feb 13 21:23:54 2012 @@ -1399,9 +1399,6 @@ public class DBDictionary } else if (val instanceof Calendard) { cald = (Calendard) val; val = cald.value; - } else if (val instanceof BindParameter) { - BindParameter bParm = (BindParameter) val; - val = bParm.getValue(); } if (val == null) @@ -1894,8 +1891,7 @@ public class DBDictionary public SQLBuffer toSelectCount(Select sel) { SQLBuffer selectSQL = new SQLBuffer(this); SQLBuffer from; - if (!sel.isReadOnly()) - sel.addJoinClassConditions(); + sel.addJoinClassConditions(); if (sel.getFromSelect() != null) from = getFromSelect(sel, false); else @@ -2287,7 +2283,7 @@ public class DBDictionary if (join.isCorrelated() && join.getForeignKey() != null) { SQLBuffer where = new SQLBuffer(this); where.append("(").append(toTraditionalJoin(join)).append(")"); - sel.where(where); + sel.where(where.getSQL()); } } } @@ -2347,7 +2343,7 @@ public class DBDictionary if (join.getForeignKey() != null){ SQLBuffer where = new SQLBuffer(this); where.append("(").append(toTraditionalJoin(join)).append(")"); - sel.where(where); + sel.where(where.getSQL()); } break; } @@ -2497,7 +2493,7 @@ public class DBDictionary if (join.getForeignKey() != null){ SQLBuffer where = new SQLBuffer(this); where.append("(").append(toTraditionalJoin(join)).append(")"); - sel.where(where); + sel.where(where.getSQL()); } return null; Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JoinSet.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JoinSet.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JoinSet.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/JoinSet.java Mon Feb 13 21:23:54 2012 @@ -39,9 +39,9 @@ class JoinSet { // efficient representation with O(1) lookup, add, remove operations for // typical sets of joins, and it means we'd have to create a graph anyway // when joinIterator() is called - private final List<Node> _graph = new ArrayList<Node>(); + private final List _graph = new ArrayList(); private int _size = 0; - private List<Join> _sorted = null; + private List _sorted = null; public JoinSet() { } @@ -51,7 +51,7 @@ class JoinSet { if (copy._graph.get(i) == null) _graph.add(null); else - _graph.add((Node) copy._graph.get(i).clone()); + _graph.add(((Node) copy._graph.get(i)).clone()); } _size = copy._size; _sorted = copy._sorted; @@ -95,22 +95,23 @@ class JoinSet { /** * Iterator over joins that prepares them for SQL translation. */ - public Iterator<Join> joinIterator() { + public Iterator joinIterator() { if (_size < 2) return iterator(); if (_sorted != null) return _sorted.iterator(); - List<Join> sorted = new ArrayList<Join>(_size); - LinkedList<Node> queue = new LinkedList<Node>(); - BitSet seen = new BitSet(_graph.size() * _graph.size() + _graph.size()); + List sorted = new ArrayList(_size); + LinkedList queue = new LinkedList(); + BitSet seen = new BitSet(_graph.size() * _graph.size() + + _graph.size()); // traverse graph Node n; int idx, sidx; for (int i = 0; i < _graph.size(); i++) { // seed queue with next set of disconnected joins - for (n = _graph.get(i); n != null; n = n.next) { + for (n = (Node) _graph.get(i); n != null; n = n.next) { sidx = getSeenIndex(n.join); if (!seen.get(sidx)) { seen.set(sidx); @@ -182,8 +183,8 @@ class JoinSet { return false; boolean added = false; - for (Iterator<Join> itr = js.iterator(); itr.hasNext();) - added = add(itr.next()) || added; + for (Iterator itr = js.iterator(); itr.hasNext();) + added = add((Join) itr.next()) || added; return added; } @@ -217,8 +218,8 @@ class JoinSet { _size++; } - public Iterator<Join> iterator() { - return new Iterator<Join>() { + public Iterator iterator() { + return new Iterator() { private Node _next = null; private int _idx = -1; @@ -236,7 +237,7 @@ class JoinSet { return false; } - public Join next() { + public Object next() { if (!hasNext()) throw new NoSuchElementException(); Join j = _next.join; @@ -288,16 +289,16 @@ class JoinSet { public boolean removeAll(JoinSet js) { boolean remd = false; - for (Iterator<Join> itr = js.iterator(); itr.hasNext();) - remd = remove(itr.next()) || remd; + for (Iterator itr = js.iterator(); itr.hasNext();) + remd = remove((Join) itr.next()) || remd; return remd; } public boolean retainAll(JoinSet js) { boolean remd = false; Join join; - for (Iterator<Join> itr = iterator(); itr.hasNext();) { - join = itr.next(); + for (Iterator itr = iterator(); itr.hasNext();) { + join = (Join) itr.next(); if (!js.contains(join)) remd = remove(join); } @@ -317,8 +318,8 @@ class JoinSet { public boolean containsAll(JoinSet js) { if (js._size > _size || js._graph.size() > _graph.size()) return false; - for (Iterator<Join> itr = js.iterator(); itr.hasNext();) - if (!contains(itr.next())) + for (Iterator itr = js.iterator(); itr.hasNext();) + if (!contains((Join) itr.next())) return false; return true; } @@ -346,7 +347,7 @@ class JoinSet { public String toString() { StringBuilder buf = new StringBuilder(); buf.append("["); - for (Iterator<Join> itr = iterator(); itr.hasNext();) { + for (Iterator itr = iterator(); itr.hasNext();) { buf.append("<").append(itr.next()).append(">"); if (itr.hasNext()) buf.append(", "); Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Joins.java Mon Feb 13 21:23:54 2012 @@ -102,10 +102,4 @@ public interface Joins { * Move joins that belong to subquery's parent */ public void moveJoinsToParent(); - - /** - * Gets the current path as a mutable string. - * @return - */ - public StringBuilder path(); } Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java Mon Feb 13 21:23:54 2012 @@ -112,15 +112,6 @@ public class LogicalUnion return false; } - @Override - public boolean isReadOnly() { - for (int i = 0; i < sels.length; i++) { - if (sels[i].isReadOnly()) - return true; - } - return false; - } - public void abortUnion() { } @@ -244,7 +235,8 @@ public class LogicalUnion if (getExpectedResultCount() == 1) { AbstractResult res; for (int i = 0; i < sels.length; i++) { - res = (AbstractResult) sels[i].execute(store, fetch, lockLevel); + res = (AbstractResult) sels[i].execute(store, fetch, + lockLevel); res.setBaseMapping(mappings[i]); res.setIndexOf(i); @@ -275,7 +267,8 @@ public class LogicalUnion try { List l; for (int i = 0; i < res.length; i++) { - res[i] = (AbstractResult) sels[i].execute(store, fetch, lockLevel); + res[i] = (AbstractResult) sels[i].execute(store, fetch, + lockLevel); res[i].setBaseMapping(mappings[i]); res[i].setIndexOf(i); @@ -775,6 +768,14 @@ public class LogicalUnion sel.where(sql, joins); } + public void where(String sql) { + sel.where(sql); + } + + public void where(String sql, Joins joins) { + sel.where(sql, joins); + } + public void having(SQLBuffer sql) { sel.having(sql); } @@ -783,6 +784,14 @@ public class LogicalUnion sel.having(sql, joins); } + public void having(String sql) { + sel.having(sql); + } + + public void having(String sql, Joins joins) { + sel.having(sql, joins); + } + public void groupBy(SQLBuffer sql) { sel.groupBy(sql); } @@ -922,10 +931,6 @@ public class LogicalUnion public DBDictionary getDictionary() { return dict; } - - public boolean isReadOnly() { - return sel.isReadOnly(); - } } /** @@ -1006,5 +1011,4 @@ public class LogicalUnion return a1.length - a2.length; } } - } Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java Mon Feb 13 21:23:54 2012 @@ -32,6 +32,7 @@ import java.util.List; import org.apache.commons.lang.ObjectUtils; import org.apache.openjpa.jdbc.identifier.DBIdentifier; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; +import org.apache.openjpa.jdbc.kernel.exps.CollectionParam; import org.apache.openjpa.jdbc.kernel.exps.Val; import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.Sequence; @@ -52,7 +53,6 @@ import org.apache.openjpa.kernel.exps.Pa * * @since 0.2.4 */ -@SuppressWarnings("serial") public final class SQLBuffer implements Serializable, Cloneable { @@ -60,8 +60,14 @@ public final class SQLBuffer private final DBDictionary _dict; private final StringBuilder _sql = new StringBuilder(); - private List<Subselect> _subsels = null; - private List<BindParameter> _params = null; + private List _subsels = null; + private List _params = null; + private List _cols = null; + + // Even element refers to an index of the _params list + // Odd element refers to the user parameter + private List _userIndex = null; + private List _userParams = null; /** * Default constructor. @@ -86,7 +92,7 @@ public final class SQLBuffer } /** - * Return true if the buffer is empty. + * Return true if the buffer is emtpy. */ public boolean isEmpty() { return _sql.length() == 0; @@ -96,42 +102,87 @@ public final class SQLBuffer * Append all SQL and parameters of the given buffer. */ public SQLBuffer append(SQLBuffer buf) { - append(buf, _sql.length(), (_params == null) ? 0 : _params.size(), true); + append(buf, _sql.length(), (_params == null) ? 0 : _params.size(), + true); return this; } /** * Append all SQL and parameters of the given buffer at the given positions. */ - private void append(SQLBuffer buf, int sqlIndex, int paramIndex, boolean subsels) { + private void append(SQLBuffer buf, int sqlIndex, int paramIndex, + boolean subsels) { if (subsels) { // only allow appending of buffers with subselects, not insertion - if (_subsels != null && !_subsels.isEmpty() && sqlIndex != _sql.length()) + if (_subsels != null && !_subsels.isEmpty() + && sqlIndex != _sql.length()) throw new IllegalStateException(); if (buf._subsels != null && !buf._subsels.isEmpty()) { if (sqlIndex != _sql.length()) throw new IllegalStateException(); if (_subsels == null) - _subsels = new ArrayList<Subselect>(buf._subsels.size()); + _subsels = new ArrayList(buf._subsels.size()); for (int i = 0; i < buf._subsels.size(); i++) - _subsels.add((buf._subsels.get(i)).clone(sqlIndex, paramIndex)); + _subsels.add(((Subselect) buf._subsels.get(i)). + clone(sqlIndex, paramIndex)); } } - if (sqlIndex == _sql.length()) { + if (sqlIndex == _sql.length()) _sql.append(buf._sql.toString()); - } else { + else _sql.insert(sqlIndex, buf._sql.toString()); - } - + if (buf._params != null) { if (_params == null) - _params = new ArrayList<BindParameter>(); + _params = new ArrayList(); + if (_cols == null && buf._cols != null) { + _cols = new ArrayList(); + while (_cols.size() < _params.size()) + _cols.add(null); + } if (paramIndex == _params.size()) { _params.addAll(buf._params); + if (buf._userParams != null) { + if (_userParams == null) + _userParams = new ArrayList(); + _userParams.addAll(paramIndex, buf._userParams); + } + if (buf._userIndex != null) { + if (_userIndex == null) + _userIndex = new ArrayList(); + _userIndex.addAll(buf._userIndex); + } + if (buf._cols != null) + _cols.addAll(buf._cols); + else if (_cols != null) + while (_cols.size() < _params.size()) + _cols.add(null); } else { _params.addAll(paramIndex, buf._params); + if ( buf._userParams != null) { + if (_userParams == null) + _userParams = new ArrayList(); + _userParams.addAll(paramIndex, buf._userParams); + } + if (buf._userIndex != null) { + if (_userIndex == null) + _userIndex = new ArrayList(); + _userIndex.addAll(buf._userIndex); + } + if (buf._cols != null) + _cols.addAll(paramIndex, buf._cols); + else if (_cols != null) + while (_cols.size() < _params.size()) + _cols.add(paramIndex, null); + } + } + + if (_userIndex != null) { + // fix up user parameter index + for (int i = 0; i < _userIndex.size(); i+=2) { + _userIndex.set(i, _userParams.indexOf(_userIndex.get(i+1))); } } } @@ -190,7 +241,7 @@ public final class SQLBuffer _sql.append(")"); if (_subsels == null) - _subsels = new ArrayList<Subselect>(2); + _subsels = new ArrayList(2); _subsels.add(sub); return this; } @@ -216,7 +267,7 @@ public final class SQLBuffer * Append a parameter value. */ public SQLBuffer appendValue(Object o) { - return appendValue(o, null, null); + return appendValue(o, null); } /** @@ -242,11 +293,34 @@ public final class SQLBuffer else { _sql.append(PARAMETER_TOKEN); + // initialize param and col lists; we hold off on col list until + // we get the first non-null col if (_params == null) - _params = new ArrayList<BindParameter>(); - BindParameter param = new BindParameter(userParam == null ? col : userParam, - userParam != null, col, o); - _params.add(param); + _params = new ArrayList(); + if (_userParams == null) + _userParams = new ArrayList(); + if (col != null && _cols == null) { + _cols = new ArrayList(); + while (_cols.size() < _params.size()) + _cols.add(null); + } + + _params.add(o); + if (userParam != null) { + Object param = userParam; + if (userParam instanceof CollectionParam) + param = ((CollectionParam) userParam).clone(); + _userParams.add(param); + if (_userIndex == null) + _userIndex = new ArrayList(); + int index = _params.size()-1; + _userIndex.add(index); + _userIndex.add(param); + } + else + _userParams.add(o); + if (_cols != null) + _cols.add(col); } return this; } @@ -254,9 +328,8 @@ public final class SQLBuffer /** * Return the list of parameter values. */ - public List<BindParameter> getParameters() { - if (_params == null) return Collections.emptyList(); - return _params; + public List getParameters() { + return (_params == null) ? Collections.EMPTY_LIST : _params; } /** @@ -267,33 +340,10 @@ public final class SQLBuffer * This structure is preferred over a normal map because a user parameter * may occur more than one in the parameters. */ - public List<Object> getUserParameters() { - if (_params == null) - return Collections.emptyList(); - List<Object> userParam = new ArrayList<Object>(); - for (int i = 0; i < _params.size(); i++) { - BindParameter param = _params.get(i); - if (param.isUser()) { - userParam.add(i); - userParam.add(param.getKey()); - } - } - return userParam; - } - - /** - * Gets the columns associated with the binding parameters. - * All binding parameter may not have an associated column. - */ - public List<Column> getColumns() { - if (_params == null) - return Collections.emptyList(); - List<Column> columns = new ArrayList<Column>(); - for (BindParameter param : _params) { - columns.add(param.getColumn()); - } - return columns; - + public List getUserParameters() { + if (_userIndex == null) + return Collections.EMPTY_LIST; + return _userIndex; } /** @@ -316,14 +366,14 @@ public final class SQLBuffer return sql; StringBuilder buf = new StringBuilder(); - Iterator<BindParameter> pi = _params.iterator(); + Iterator pi = _params.iterator(); for (int i = 0; i < sql.length(); i++) { if (sql.charAt(i) != '?') { buf.append(sql.charAt(i)); continue; } - Object param = pi.hasNext() ? pi.next().getValue() : null; + Object param = pi.hasNext() ? pi.next() : null; if (param == null) buf.append("NULL"); else if (param instanceof Number || param instanceof Boolean) @@ -380,7 +430,7 @@ public final class SQLBuffer } /** - * Create and populate the parameters of a prepared statement using the + * Create and populate the parameters of a prepred statement using the * SQL in this buffer and the given fetch configuration. */ public PreparedStatement prepareStatement(Connection conn, @@ -488,9 +538,10 @@ public final class SQLBuffer if (_params == null) return; + Column col; for (int i = 0; i < _params.size(); i++) { - BindParameter param = _params.get(i); - _dict.setUnknown(ps, i + 1, param.getValue(), param.getColumn()); + col = (_cols == null) ? null : (Column) _cols.get(i); + _dict.setUnknown(ps, i + 1, _params.get(i), col); } } @@ -567,42 +618,11 @@ public final class SQLBuffer } } - /** - * Sets the binding parameters, clearing all existing parameters. - * - * @param params a non-null list of parameters. - */ - public void setParameters(List<?> params) { - if (params == null) { - throw new IllegalArgumentException("Can not set null parameter"); - } - _params = new ArrayList<BindParameter>(); - int i = 0; - for (Object p : params) { - BindParameter param = new BindParameter(i, false, null, p); - _params.add(param); - } + public void setParameters(List params) { + _params = params; } - /** - * Binds the given value to a parameter representing the given column. - * The column must be bound before this call. - * @param o a parameter value - * @param col a column to which the value is to be bound - * @return this same buffer - * @exception IllegalArgumentException is no parameter represents the given column - */ - public SQLBuffer bind(Object o, Column col) { - boolean bound = false; - for (int i = 0; i < _params.size(); i++) { - BindParameter param = _params.get(i); - if (param.getColumn() == col) { - param.setValue(o); - bound = true; - } - } - if (!bound) - throw new IllegalArgumentException("Column " + col + " does not exist to bind " + o); - return this; + public List getColumns() { + return _cols; } } Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/Select.java Mon Feb 13 21:23:54 2012 @@ -546,12 +546,12 @@ public interface Select /** * Add the given where conditions. */ -// public void where(String sql); + public void where(String sql); /** * Add the given where conditions. */ -// public void where(String sql, Joins joins); + public void where(String sql, Joins joins); /** * Add the given having conditions. @@ -566,12 +566,12 @@ public interface Select /** * Add the given having conditions. */ -// public void having(String sql); + public void having(String sql); /** * Add the given having conditions. */ -// public void having(String sql, Joins joins); + public void having(String sql, Joins joins); /** * Group by the given column. @@ -606,12 +606,12 @@ public interface Select /** * Add a GROUP BY clause. */ -// public void groupBy(String sql); + public void groupBy(String sql); /** * Add a GROUP BY clause. */ -// public void groupBy(String sql, Joins joins); + public void groupBy(String sql, Joins joins); /** * Group by the columns of the given mapping, possibly including subclasses. @@ -751,29 +751,22 @@ public interface Select /** * Set joined table metadatas for polymorphic queries */ - public void setJoinedTableClassMeta(List<ClassMapping> meta); + public void setJoinedTableClassMeta(List meta); /** * get joined table metadatas for polymorphic queries */ - public List<ClassMapping> getJoinedTableClassMeta(); + public List getJoinedTableClassMeta(); /** * Set joined table metadatas excluded for polymorphic queries */ - public void setExcludedJoinedTableClassMeta(List<ClassMapping> meta); + public void setExcludedJoinedTableClassMeta(List meta); /** * get joined table metadatas excluded for polymorphic queries */ - public List<ClassMapping> getExcludedJoinedTableClassMeta(); + public List getExcludedJoinedTableClassMeta(); - /** - * Gets the database dictionary used by this select to form the target SQL - * statement. - * - * @return the immutable database dictionary. - */ public DBDictionary getDictionary() ; - } Modified: openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java?rev=1243702&r1=1243701&r2=1243702&view=diff ============================================================================== --- openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java (original) +++ openjpa/trunk/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java Mon Feb 13 21:23:54 2012 @@ -23,7 +23,6 @@ import java.sql.SQLException; import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; -import org.apache.openjpa.jdbc.schema.Column; /** * Interface for configuring and executing a SQL select. @@ -152,19 +151,4 @@ public interface SelectExecutor { * @since 2.0.0 */ public boolean hasMultipleSelects(); - - /** - * Affirms if this select is structurally immutable. - * A select becomes immutable upon {@link #execute(JDBCStore, JDBCFetchConfiguration) execution}. - * There is no explicit way to turn a select into read-only status. - * <br> - * The immutable contract does not prevent {@link SQLBuffer#bind(Object, Column) binding} - * new values to {@link BindParameter parameters}. - * - * @return false on construction, true after execution. - * - * @since 2.2.0 - */ - boolean isReadOnly(); - }
