Home » apache-openjpa-1.1.0-source » org.apache.openjpa.jdbc » sql » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied.  See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.    
   18    */
   19   package org.apache.openjpa.jdbc.sql;
   20   
   21   import java.sql.ResultSet;
   22   import java.sql.SQLException;
   23   import java.util.BitSet;
   24   import java.util.Collection;
   25   import java.util.Collections;
   26   import java.util.Iterator;
   27   import java.util.List;
   28   
   29   import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
   30   import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
   31   import org.apache.openjpa.jdbc.kernel.JDBCStore;
   32   import org.apache.openjpa.jdbc.meta.ClassMapping;
   33   import org.apache.openjpa.jdbc.meta.FieldMapping;
   34   import org.apache.openjpa.jdbc.schema.Column;
   35   import org.apache.openjpa.jdbc.schema.ForeignKey;
   36   import org.apache.openjpa.jdbc.schema.Table;
   37   import org.apache.openjpa.lib.util.Localizer;
   38   import org.apache.openjpa.util.InternalException;
   39   import org.apache.openjpa.util.UnsupportedException;
   40   import org.apache.openjpa.util.UserException;
   41   
   42   /**
   43    * A logical union made up of multiple distinct selects whose results are
   44    * combined in memory.
   45    *
   46    * @author Abe White
   47    */
   48   public class LogicalUnion
   49       implements Union {
   50   
   51       private static final Localizer _loc = Localizer.forPackage
   52           (LogicalUnion.class);
   53   
   54       protected final UnionSelect[] sels;
   55       protected final DBDictionary dict;
   56       protected final ClassMapping[] mappings;
   57       protected final BitSet desc = new BitSet();
   58       private boolean _distinct = true;
   59      
   60   
   61       /**
   62        * Constructor.
   63        *
   64        * @param conf system configuration
   65        * @param sels the number of SQL selects to union together
   66        */
   67       public LogicalUnion(JDBCConfiguration conf, int sels) {
   68           this(conf, sels, null);
   69       }
   70   
   71       /**
   72        * Constructor used to seed the internal selects.
   73        */
   74       public LogicalUnion(JDBCConfiguration conf, Select[] seeds) {
   75           this(conf, seeds.length, seeds);
   76       }
   77   
   78       /**
   79        * Delegate constructor.
   80        */
   81       protected LogicalUnion(JDBCConfiguration conf, int sels, Select[] seeds) {
   82           if (sels == 0)
   83               throw new InternalException("sels == 0");
   84   
   85           dict = conf.getDBDictionaryInstance();
   86           mappings = new ClassMapping[sels];
   87           this.sels = new UnionSelect[sels];
   88   
   89           SelectImpl seed;
   90           for (int i = 0; i < sels; i++) {
   91               seed = (seeds == null)
   92                   ? (SelectImpl) conf.getSQLFactoryInstance().newSelect()
   93                   : (SelectImpl) seeds[i];
   94               this.sels[i] = newUnionSelect(seed, i);
   95           }
   96       }
   97   
   98       /**
   99        * Create a new union select with the given delegate and union position.
  100        */
  101       protected UnionSelect newUnionSelect(SelectImpl seed, int pos) {
  102           return new UnionSelect(seed, pos);
  103       }
  104   
  105       public Select[] getSelects() {
  106           return sels;
  107       }
  108      
  109       public boolean isUnion() {
  110           return false;
  111       }
  112   
  113       public void abortUnion() {
  114       }
  115   
  116       public String getOrdering() {
  117           return null;
  118       }
  119   
  120       public JDBCConfiguration getConfiguration() {
  121           return sels[0].getConfiguration();
  122       }
  123   
  124       public DBDictionary getDBDictionary() {
  125           return dict;
  126       }
  127   
  128       public SQLBuffer toSelect(boolean forUpdate, JDBCFetchConfiguration fetch) {
  129           return dict.toSelect(sels[0], forUpdate, fetch);
  130       }
  131   
  132       public SQLBuffer toSelectCount() {
  133           return dict.toSelectCount(sels[0]);
  134       }
  135   
  136       public boolean getAutoDistinct() {
  137           return sels[0].getAutoDistinct();
  138       }
  139   
  140       public void setAutoDistinct(boolean distinct) {
  141           for (int i = 0; i < sels.length; i++)
  142               sels[i].setAutoDistinct(distinct);
  143       }
  144   
  145       public boolean isDistinct() {
  146           return _distinct;
  147       }
  148   
  149       public void setDistinct(boolean distinct) {
  150           _distinct = distinct;
  151       }
  152   
  153       public boolean isLRS() {
  154           return sels[0].isLRS();
  155       }
  156   
  157       public void setLRS(boolean lrs) {
  158           for (int i = 0; i < sels.length; i++)
  159               sels[i].setLRS(lrs);
  160       }
  161   
  162       public int getExpectedResultCount() {
  163           return sels[0].getExpectedResultCount();
  164       }
  165       
  166       public void setExpectedResultCount(int expectedResultCount,
  167           boolean force) {
  168           for (int i = 0; i < sels.length; i++)
  169               sels[i].setExpectedResultCount(expectedResultCount, force);
  170       }
  171   
  172       public int getJoinSyntax() {
  173           return sels[0].getJoinSyntax();
  174       }
  175   
  176       public void setJoinSyntax(int syntax) {
  177           for (int i = 0; i < sels.length; i++)
  178               sels[i].setJoinSyntax(syntax);
  179       }
  180   
  181       public boolean supportsRandomAccess(boolean forUpdate) {
  182           if (sels.length == 1)
  183               return sels[0].supportsRandomAccess(forUpdate);
  184           return false;
  185       }
  186   
  187       public boolean supportsLocking() {
  188           if (sels.length == 1)
  189               return sels[0].supportsLocking();
  190           for (int i = 0; i < sels.length; i++)
  191               if (!sels[i].supportsLocking())
  192                   return false;
  193           return true;
  194       }
  195   
  196       public int getCount(JDBCStore store)
  197           throws SQLException {
  198           int count = 0;
  199           for (int i = 0; i < sels.length; i++)
  200               count += sels[i].getCount(store);
  201           return count;
  202       }
  203   
  204       public Result execute(JDBCStore store, JDBCFetchConfiguration fetch)
  205           throws SQLException {
  206           if (fetch == null)
  207               fetch = store.getFetchConfiguration();
  208           return execute(store, fetch, fetch.getReadLockLevel());
  209       }
  210   
  211       public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
  212           int lockLevel)
  213           throws SQLException {
  214           if (fetch == null)
  215               fetch = store.getFetchConfiguration();
  216   
  217           if (sels.length == 1) {
  218               Result res = sels[0].execute(store, fetch, lockLevel);
  219               ((AbstractResult) res).setBaseMapping(mappings[0]);
  220               return res;
  221           }
  222   
  223           if (getExpectedResultCount() == 1) {
  224               AbstractResult res;
  225               for (int i = 0; i < sels.length; i++) {
  226                   res = (AbstractResult) sels[i].execute(store, fetch,
  227                       lockLevel);
  228                   res.setBaseMapping(mappings[i]);
  229                   res.setIndexOf(i);
  230   
  231                   // if we get to the last select, just return its result
  232                   if (i == sels.length - 1)
  233                       return res;
  234   
  235                   // return the first result that has a row
  236                   try {
  237                       if (!res.next())
  238                           res.close();
  239                       else {
  240                           res.pushBack();
  241                           return res;
  242                       }
  243                   }
  244                   catch (SQLException se) {
  245                       res.close();
  246                       throw se;
  247                   }
  248               }
  249           }
  250   
  251           // create a single result from each select in our fake union, merging
  252           // them as needed
  253           AbstractResult[] res = new AbstractResult[sels.length];
  254           List[] orderIdxs = null;
  255           try {
  256               List l;
  257               for (int i = 0; i < res.length; i++) {
  258                   res[i] = (AbstractResult) sels[i].execute(store, fetch,
  259                       lockLevel);
  260                   res[i].setBaseMapping(mappings[i]);
  261                   res[i].setIndexOf(i);
  262   
  263                   l = sels[i].getSelectedOrderIndexes();
  264                   if (l != null) {
  265                       if (orderIdxs == null)
  266                           orderIdxs = new List[sels.length];
  267                       orderIdxs[i] = l;
  268                   }
  269               }
  270           } catch (SQLException se) {
  271               for (int i = 0; res[i] != null; i++)
  272                   res[i].close();
  273               throw se;
  274           }
  275   
  276           // if multiple selects have ordering, use a comparator to collate
  277           ResultComparator comp = null;
  278           if (orderIdxs != null)
  279               comp = new ResultComparator(orderIdxs, desc, dict);
  280           return new MergedResult(res, comp);
  281       }
  282   
  283       public void select(Union.Selector selector) {
  284           for (int i = 0; i < sels.length; i++)
  285               selector.select(sels[i], i);
  286       }
  287   
  288       public String toString() {
  289           return toSelect(false, null).getSQL();
  290       }
  291   
  292       /**
  293        * A callback used to create the selects in a SQL union.
  294        */
  295       public static interface Selector {
  296   
  297           /**
  298            * Populate the <code>i</code>th select in the union.
  299            */
  300           public void select(Select sel, int i);
  301       }
  302   
  303       /**
  304        * A select that is part of a logical union.
  305        */
  306       protected class UnionSelect
  307           implements Select {
  308   
  309           protected final SelectImpl sel;
  310           protected final int pos;
  311           protected int orders = 0;
  312           protected List orderIdxs = null;
  313          
  314           public UnionSelect(SelectImpl sel, int pos) {
  315               this.sel = sel;
  316               this.pos = pos;
  317               sel.setRecordOrderedIndexes(true);
  318           }
  319   
  320           /**
  321            * Delegate select.
  322            */
  323           public SelectImpl getDelegate() {
  324               return sel;
  325           }
  326   
  327           /**
  328            * Return the indexes of the data in the select clause this query is
  329            * ordered by.
  330            */
  331           public List getSelectedOrderIndexes() {
  332               if (orderIdxs == null)
  333                   orderIdxs = sel.getOrderedIndexes();
  334               return orderIdxs;
  335           }
  336   
  337           public JDBCConfiguration getConfiguration() {
  338               return sel.getConfiguration();
  339           }
  340   
  341           public int indexOf() {
  342               return pos;
  343           }
  344   
  345           public SQLBuffer toSelect(boolean forUpdate,
  346               JDBCFetchConfiguration fetch) {
  347               return sel.toSelect(forUpdate, fetch);
  348           }
  349   
  350           public SQLBuffer toSelectCount() {
  351               return sel.toSelectCount();
  352           }
  353   
  354           public boolean getAutoDistinct() {
  355               return sel.getAutoDistinct();
  356           }
  357   
  358           public void setAutoDistinct(boolean distinct) {
  359               sel.setAutoDistinct(distinct);
  360           }
  361   
  362           public boolean isDistinct() {
  363               return sel.isDistinct();
  364           }
  365   
  366           public void setDistinct(boolean distinct) {
  367               sel.setDistinct(distinct);
  368           }
  369   
  370           public boolean isLRS() {
  371               return sel.isLRS();
  372           }
  373   
  374           public void setLRS(boolean lrs) {
  375               sel.setLRS(lrs);
  376           }
  377   
  378           public int getJoinSyntax() {
  379               return sel.getJoinSyntax();
  380           }
  381   
  382           public void setJoinSyntax(int joinSyntax) {
  383               sel.setJoinSyntax(joinSyntax);
  384           }
  385   
  386           public boolean supportsRandomAccess(boolean forUpdate) {
  387               return sel.supportsRandomAccess(forUpdate);
  388           }
  389   
  390           public boolean supportsLocking() {
  391               return sel.supportsLocking();
  392           }
  393   
  394           public int getCount(JDBCStore store)
  395               throws SQLException {
  396               return sel.getCount(store);
  397           }
  398   
  399           public Result execute(JDBCStore store, JDBCFetchConfiguration fetch)
  400               throws SQLException {
  401               return sel.execute(store, fetch);
  402           }
  403   
  404           public Result execute(JDBCStore store, JDBCFetchConfiguration fetch,
  405               int lockLevel)
  406               throws SQLException {
  407               return sel.execute(store, fetch, lockLevel);
  408           }
  409   
  410           public List getSubselects() {
  411               return Collections.EMPTY_LIST;
  412           }
  413   
  414           public Select getParent() {
  415               return null;
  416           }
  417   
  418           public String getSubselectPath() {
  419               return null;
  420           }
  421   
  422           public void setParent(Select parent, String path) {
  423               throw new UnsupportedException(_loc.get("union-element"));
  424           }
  425   
  426           public Select getFromSelect() {
  427               return null;
  428           }
  429   
  430           public void setFromSelect(Select sel) {
  431               throw new UnsupportedException(_loc.get("union-element"));
  432           }
  433   
  434           public boolean hasEagerJoin(boolean toMany) {
  435               return sel.hasEagerJoin(toMany);
  436           }
  437   
  438           public boolean hasJoin(boolean toMany) {
  439               return sel.hasJoin(toMany);
  440           }
  441   
  442           public boolean isSelected(Table table) {
  443               return sel.isSelected(table);
  444           }
  445   
  446           public Collection getTableAliases() {
  447               return sel.getTableAliases();
  448           }
  449   
  450           public List getSelects() {
  451               return sel.getSelects();
  452           }
  453   
  454           public List getSelectAliases() {
  455               return sel.getSelectAliases();
  456           }
  457   
  458           public List getIdentifierAliases() {
  459               return sel.getIdentifierAliases();
  460           }
  461   
  462           public SQLBuffer getOrdering() {
  463               return sel.getOrdering();
  464           }
  465   
  466           public SQLBuffer getGrouping() {
  467               return sel.getGrouping();
  468           }
  469   
  470           public SQLBuffer getWhere() {
  471               return sel.getWhere();
  472           }
  473   
  474           public SQLBuffer getHaving() {
  475               return sel.getHaving();
  476           }
  477   
  478           public void addJoinClassConditions() {
  479               sel.addJoinClassConditions();
  480           }
  481   
  482           public Joins getJoins() {
  483               return sel.getJoins();
  484           }
  485   
  486           public Iterator getJoinIterator() {
  487               return sel.getJoinIterator();
  488           }
  489   
  490           public long getStartIndex() {
  491               return sel.getStartIndex();
  492           }
  493   
  494           public long getEndIndex() {
  495               return sel.getEndIndex();
  496           }
  497   
  498           public void setRange(long start, long end) {
  499               sel.setRange(start, end);
  500           }
  501   
  502           public String getColumnAlias(Column col) {
  503               return sel.getColumnAlias(col);
  504           }
  505   
  506           public String getColumnAlias(Column col, Joins joins) {
  507               return sel.getColumnAlias(col, joins);
  508           }
  509   
  510           public String getColumnAlias(String col, Table table) {
  511               return sel.getColumnAlias(col, table);
  512           }
  513   
  514           public String getColumnAlias(String col, Table table, Joins joins) {
  515               return sel.getColumnAlias(col, table, joins);
  516           }
  517   
  518           public boolean isAggregate() {
  519               return sel.isAggregate();
  520           }
  521   
  522           public void setAggregate(boolean agg) {
  523               sel.setAggregate(agg);
  524           }
  525   
  526           public boolean isLob() {
  527               return sel.isLob();
  528           }
  529   
  530           public void setLob(boolean lob) {
  531               sel.setLob(lob);
  532           }
  533   
  534           public void selectPlaceholder(String sql) {
  535               sel.selectPlaceholder(sql);
  536           }
  537   
  538           public void clearSelects() {
  539               sel.clearSelects();
  540           }
  541   
  542           public boolean select(SQLBuffer sql, Object id) {
  543               return sel.select(sql, id);
  544           }
  545   
  546           public boolean select(SQLBuffer sql, Object id, Joins joins) {
  547               return sel.select(sql, id, joins);
  548           }
  549   
  550           public boolean select(String sql, Object id) {
  551               return sel.select(sql, id);
  552           }
  553   
  554           public boolean select(String sql, Object id, Joins joins) {
  555               return sel.select(sql, id, joins);
  556           }
  557   
  558           public boolean select(Column col) {
  559               return sel.select(col);
  560           }
  561   
  562           public boolean select(Column col, Joins joins) {
  563               return sel.select(col, joins);
  564           }
  565   
  566           public int select(Column[] cols) {
  567               return sel.select(cols);
  568           }
  569   
  570           public int select(Column[] cols, Joins joins) {
  571               return sel.select(cols, joins);
  572           }
  573   
  574           public void select(ClassMapping mapping, int subclasses,
  575               JDBCStore store, JDBCFetchConfiguration fetch, int eager) {
  576               select(mapping, subclasses, store, fetch, eager, null, false);
  577           }
  578   
  579           public void select(ClassMapping mapping, int subclasses,
  580               JDBCStore store, JDBCFetchConfiguration fetch, int eager,
  581               Joins joins) {
  582               select(mapping, subclasses, store, fetch, eager, joins, false);
  583           }
  584   
  585           private void select(ClassMapping mapping, int subclasses,
  586               JDBCStore store, JDBCFetchConfiguration fetch, int eager,
  587               Joins joins, boolean identifier) {
  588               // if this is the first (primary) mapping selected for this
  589               // SELECT, record it so we can figure out what the result type is
  590               // since the discriminator might not be selected
  591               if (mappings[pos] == null)
  592                   mappings[pos] = mapping;
  593   
  594               sel.select(this, mapping, subclasses, store, fetch, eager,
  595                   joins, identifier);
  596           }
  597   
  598           public boolean selectIdentifier(Column col) {
  599               return sel.selectIdentifier(col);
  600           }
  601   
  602           public boolean selectIdentifier(Column col, Joins joins) {
  603               return sel.selectIdentifier(col, joins);
  604           }
  605   
  606           public int selectIdentifier(Column[] cols) {
  607               return sel.selectIdentifier(cols);
  608           }
  609   
  610           public int selectIdentifier(Column[] cols, Joins joins) {
  611               return sel.selectIdentifier(cols, joins);
  612           }
  613   
  614           public void selectIdentifier(ClassMapping mapping, int subclasses,
  615               JDBCStore store, JDBCFetchConfiguration fetch, int eager) {
  616               select(mapping, subclasses, store, fetch, eager, null, true);
  617           }
  618   
  619           public void selectIdentifier(ClassMapping mapping, int subclasses,
  620               JDBCStore store, JDBCFetchConfiguration fetch, int eager,
  621               Joins joins) {
  622               select(mapping, subclasses, store, fetch, eager, joins, true);
  623           }
  624   
  625           public int selectPrimaryKey(ClassMapping mapping) {
  626               return sel.selectPrimaryKey(mapping);
  627           }
  628   
  629           public int selectPrimaryKey(ClassMapping mapping, Joins joins) {
  630               return sel.selectPrimaryKey(mapping, joins);
  631           }
  632   
  633           public int orderByPrimaryKey(ClassMapping mapping, boolean asc,
  634               boolean select) {
  635               return orderByPrimaryKey(mapping, asc, null, select);
  636           }
  637   
  638           public int orderByPrimaryKey(ClassMapping mapping, boolean asc,
  639               Joins joins, boolean select) {
  640               ClassMapping pks = mapping;
  641               while (!pks.isPrimaryKeyObjectId(true))
  642                   pks = pks.getJoinablePCSuperclassMapping();
  643               Column[] cols = pks.getPrimaryKeyColumns();
  644               recordOrderColumns(cols, asc);
  645               return sel.orderByPrimaryKey(mapping, asc, joins, select,
  646                   isUnion());
  647           }
  648   
  649           /**
  650            * Record that we're ordering by a SQL expression.
  651            */
  652           protected void recordOrder(Object ord, boolean asc) {
  653               if (ord == null)
  654                   return;
  655               orderIdxs = null;
  656   
  657               int idx = orders++;
  658               if (desc.get(idx) && asc)
  659                   throw new UserException(_loc.get("incompat-ordering"));
  660               if (!asc)
  661                   desc.set(idx);
  662           }
  663   
  664           /**
  665            * Record that we're ordering by the given columns.
  666            */
  667           protected void recordOrderColumns(Column[] cols, boolean asc) {
  668               for (int i = 0; i < cols.length; i++)
  669                   recordOrder(cols[i], asc);
  670           }
  671   
  672           public boolean orderBy(Column col, boolean asc, boolean select) {
  673               return orderBy(col, asc, null, select);
  674           }
  675   
  676           public boolean orderBy(Column col, boolean asc, Joins joins,
  677               boolean select) {
  678               recordOrder(col, asc);
  679               return sel.orderBy(col, asc, joins, select, isUnion());
  680           }
  681   
  682           public int orderBy(Column[] cols, boolean asc, boolean select) {
  683               return orderBy(cols, asc, null, select);
  684           }
  685   
  686           public int orderBy(Column[] cols, boolean asc, Joins joins,
  687               boolean select) {
  688               recordOrderColumns(cols, asc);
  689               return sel.orderBy(cols, asc, joins, select, isUnion());
  690           }
  691   
  692           public boolean orderBy(SQLBuffer sql, boolean asc, boolean select) {
  693               return orderBy(sql, asc, null, select);
  694           }
  695   
  696           public boolean orderBy(SQLBuffer sql, boolean asc, Joins joins,
  697               boolean select) {
  698               recordOrder(sql.getSQL(false), asc);
  699               return sel.orderBy(sql, asc, joins, select, isUnion());
  700           }
  701   
  702           public boolean orderBy(String sql, boolean asc, boolean select) {
  703               return orderBy(sql, asc, null, select);
  704           }
  705   
  706           public boolean orderBy(String sql, boolean asc, Joins joins,
  707               boolean select) {
  708               recordOrder(sql, asc);
  709               return sel.orderBy(sql, asc, joins, select, isUnion());
  710           }
  711   
  712           public void clearOrdering() {
  713               sel.clearOrdering();
  714           }
  715   
  716           public void wherePrimaryKey(Object oid, ClassMapping mapping,
  717               JDBCStore store) {
  718               sel.wherePrimaryKey(oid, mapping, store);
  719           }
  720   
  721           public void whereForeignKey(ForeignKey fk, Object oid,
  722               ClassMapping mapping, JDBCStore store) {
  723               sel.whereForeignKey(fk, oid, mapping, store);
  724           }
  725   
  726           public void where(Joins joins) {
  727               sel.where(joins);
  728           }
  729   
  730           public void where(SQLBuffer sql) {
  731               sel.where(sql);
  732           }
  733   
  734           public void where(SQLBuffer sql, Joins joins) {
  735               sel.where(sql, joins);
  736           }
  737   
  738           public void where(String sql) {
  739               sel.where(sql);
  740           }
  741   
  742           public void where(String sql, Joins joins) {
  743               sel.where(sql, joins);
  744           }
  745   
  746           public void having(SQLBuffer sql) {
  747               sel.having(sql);
  748           }
  749   
  750           public void having(SQLBuffer sql, Joins joins) {
  751               sel.having(sql, joins);
  752           }
  753   
  754           public void having(String sql) {
  755               sel.having(sql);
  756           }
  757   
  758           public void having(String sql, Joins joins) {
  759               sel.having(sql, joins);
  760           }
  761   
  762           public void groupBy(SQLBuffer sql) {
  763               sel.groupBy(sql);
  764           }
  765   
  766           public void groupBy(SQLBuffer sql, Joins joins) {
  767               sel.groupBy(sql, joins);
  768           }
  769   
  770           public void groupBy(String sql) {
  771               sel.groupBy(sql);
  772           }
  773   
  774           public void groupBy(String sql, Joins joins) {
  775               sel.groupBy(sql, joins);
  776           }
  777   
  778           public void groupBy(Column col) {
  779               sel.groupBy(col);
  780           }
  781   
  782           public void groupBy(Column col, Joins joins) {
  783               sel.groupBy(col, joins);
  784           }
  785   
  786           public void groupBy(Column[] cols) {
  787               sel.groupBy(cols);
  788           }
  789   
  790           public void groupBy(Column[] cols, Joins joins) {
  791               sel.groupBy(cols, joins);
  792           }
  793   
  794           public void groupBy(ClassMapping mapping, int subclasses, 
  795               JDBCStore store, JDBCFetchConfiguration fetch) {
  796               sel.groupBy(mapping, subclasses, store, fetch);
  797           }
  798   
  799           public void groupBy(ClassMapping mapping, int subclasses, 
  800               JDBCStore store, JDBCFetchConfiguration fetch, Joins joins) {
  801               sel.groupBy(mapping, subclasses, store, fetch, joins);
  802           }
  803   
  804           public SelectExecutor whereClone(int sels) {
  805               return sel.whereClone(sels);
  806           }
  807   
  808           public SelectExecutor fullClone(int sels) {
  809               return sel.fullClone(sels);
  810           }
  811   
  812           public SelectExecutor eagerClone(FieldMapping key, int eagerType,
  813               boolean toMany, int sels) {
  814               SelectExecutor ex = sel.eagerClone(key, eagerType, toMany, sels);
  815               return (ex == sel) ? this : ex;
  816           }
  817   
  818           public SelectExecutor getEager(FieldMapping key) {
  819               SelectExecutor ex = sel.getEager(key);
  820               return (ex == sel) ? this : ex;
  821           }
  822   
  823           public Joins newJoins() {
  824               return sel.newJoins();
  825           }
  826   
  827           public Joins newOuterJoins() {
  828               return sel.newOuterJoins();
  829           }
  830   
  831           public void append(SQLBuffer buf, Joins joins) {
  832               sel.append(buf, joins);
  833           }
  834   
  835           public Joins and(Joins joins1, Joins joins2) {
  836               return sel.and(joins1, joins2);
  837           }
  838   
  839           public Joins or(Joins joins1, Joins joins2) {
  840               return sel.or(joins1, joins2);
  841           }
  842   
  843           public Joins outer(Joins joins) {
  844               return sel.outer(joins);
  845           }
  846   
  847           public String toString() {
  848               return sel.toString();
  849           }
  850   
  851           public int getExpectedResultCount() {
  852               return sel.getExpectedResultCount();
  853           }
  854   
  855           public void setExpectedResultCount(int expectedResultCount, 
  856               boolean force) {
  857               sel.setExpectedResultCount(expectedResultCount, force);
  858           }
  859       }
  860   
  861       /**
  862        * Comparator for collating ordered results when faking a union.
  863        */
  864       private static class ResultComparator
  865           implements MergedResult.ResultComparator {
  866   
  867           private final List[] _orders;
  868           private final BitSet _desc;
  869           private final DBDictionary _dict;
  870   
  871           public ResultComparator(List[] orders, BitSet desc, DBDictionary dict) {
  872               _orders = orders;
  873               _desc = desc;
  874               _dict = dict;
  875           }
  876   
  877           public Object getOrderingValue(Result res, int idx) {
  878               // if one value just return it
  879               ResultSet rs = ((ResultSetResult) res).getResultSet();
  880               if (_orders[idx].size() == 1)
  881                   return getOrderingValue(rs, _orders[idx].get(0));
  882   
  883               // return array of values
  884               Object[] vals = new Object[_orders[idx].size()];
  885               for (int i = 0; i < vals.length; i++)
  886                   vals[i] = getOrderingValue(rs, _orders[idx].get(i));
  887               return vals;
  888           }
  889   
  890           /**
  891            * Extract value at given index from result set.
  892            */
  893           private Object getOrderingValue(ResultSet rs, Object i) {
  894               try {
  895                   return _dict.getObject(rs, ((Integer) i).intValue() + 1, null);
  896               } catch (SQLException se) {
  897                   throw SQLExceptions.getStore(se, _dict);
  898               }
  899           }
  900   
  901           public int compare(Object o1, Object o2) {
  902               if (o1 == o2)
  903                   return 0;
  904               if (o1 == null)
  905                   return (_desc.get(0)) ? -1 : 1;
  906               if (o2 == null)
  907                   return (_desc.get(0)) ? 1 : -1;
  908   
  909               int cmp;
  910               if (!(o1 instanceof Object[])) {
  911                   if (!(o2 instanceof Object[])) {
  912                       cmp = ((Comparable) o1).compareTo(o2);
  913                       return (_desc.get(0)) ? -cmp : cmp;
  914                   }
  915   
  916                   cmp = ((Comparable) o1).compareTo(((Object[]) o2)[0]);
  917                   if (cmp != 0)
  918                       return (_desc.get(0)) ? -cmp : cmp;
  919                   return -1;
  920               }
  921   
  922               if (!(o2 instanceof Object[])) {
  923                   cmp = ((Comparable) ((Object[]) o1)[0]).compareTo(o2);
  924                   if (cmp != 0)
  925                       return (_desc.get(0)) ? -cmp : cmp;
  926                   return 1;
  927               }
  928   
  929               Object[] a1 = (Object[]) o1;
  930               Object[] a2 = (Object[]) o2;
  931               for (int i = 0; i < a1.length; i++) {
  932                   cmp = ((Comparable) a1[i]).compareTo(a2[i]);
  933                   if (cmp != 0)
  934                       return (_desc.get(i)) ? -cmp : cmp;
  935               }
  936               return a1.length - a2.length;
  937           }
  938       }
  939   }

Save This Page
Home » apache-openjpa-1.1.0-source » org.apache.openjpa.jdbc » sql » [javadoc | source]