svn commit: r513569 [1/2] - in /db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker: ./ accesslayer/ accesslayer/sql/ core/ metadata/ platforms/ query/
[email protected] Fri, 02 Mar 2007 00:58:57 -0000
| Newsgroups | gmane.comp.jakarta.ojb.devel |
|---|---|
| Message-ID | <[email protected]> |
Author: arminw
Date: Thu Mar 1 16:58:55 2007
New Revision: 513569
URL: http://svn.apache.org/viewvc?view=rev&rev=513569
Log:
add support for database dependent LIMIT/OFFSET queries
Modified:
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceBroker.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/ChainingIterator.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/OJBIterator.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/PagingIterator.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerBean.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/JdbcConnectionDescriptor.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/Platform.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDb2Impl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDefaultImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformOracleImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformPostgreSQLImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformSapdbImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/AbstractQueryImpl.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/Query.java
db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/query/QueryByCriteria.java
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceBroker.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceBroker.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceBroker.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/PersistenceBroker.java Thu Mar 1 16:58:55 2007
@@ -322,6 +322,18 @@
*
* @param obj The object to store
* @param modification Specifies what operation to perform (for generating optimized SQL)
+ * @param ignoreReferences If set <em>true</em> OJB will ignore all referenced objects
+ * and only insert/update the fields of the object.
+ */
+ public void store(Object obj,
+ ObjectModification modification, boolean ignoreReferences) throws PersistenceBrokerException;
+
+ /**
+ * Makes the given object persistent in the underlying persistence system.
+ * This is usually done by issuing an INSERT ... or UPDATE ... in an RDBMS.
+ *
+ * @param obj The object to store
+ * @param modification Specifies what operation to perform (for generating optimized SQL)
*/
public void store(Object obj,
ObjectModification modification) throws PersistenceBrokerException;
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/ChainingIterator.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/ChainingIterator.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/ChainingIterator.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/ChainingIterator.java Thu Mar 1 16:58:55 2007
@@ -18,12 +18,11 @@
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
+import java.util.Collection;
import org.apache.ojb.broker.PersistenceBrokerException;
/**
- * @author matthew.baird ([email protected])
- *
* The ChainingIterator is an extent aware Iterator.
*
* How the ChainingIterator works:
@@ -53,8 +52,6 @@
private int m_activeIteratorIndex = 0;
private int m_fullSize = -1;
private int m_currentCursorPosition = 0;
- /** if true do not fire PBLifeCycleEvent. */
- private boolean disableLifeCycleEvents = false;
/**
* Constructor for ChainingIterator.
@@ -67,9 +64,9 @@
/**
* Constructor for ChainingIterator.
*/
- public ChainingIterator(List iterators)
+ public ChainingIterator(Collection ojbIterators)
{
- Iterator checkIterator = iterators.iterator();
+ Iterator checkIterator = ojbIterators.iterator();
OJBIterator temp;
/**
@@ -131,6 +128,65 @@
return size();
}
+ protected OJBIterator getActiveIterator()
+ {
+ OJBIterator result;
+ if(m_activeIterator == null)
+ {
+ if(m_rsIterators.size() > 0)
+ {
+ result = (OJBIterator) m_rsIterators.get(0);
+ }
+ else
+ {
+ result = OJBIterator.EMPTY_ITERATOR;
+ }
+ }
+ else
+ {
+ result = m_activeIterator;
+ }
+ return result;
+ }
+
+ protected OJBIterator getIterator(int index)
+ {
+ return (OJBIterator) m_rsIterators.get(index);
+ }
+
+ protected OJBIterator setActiveIterator(int iteratorNumber)
+ {
+ m_activeIterator = getIterator(iteratorNumber);
+ m_activeIteratorIndex = iteratorNumber;
+ return m_activeIterator;
+ }
+
+ protected boolean setActiveAbsolute(int row)
+ {
+ OJBIterator it = getActiveIterator();
+ boolean result = it.absolute(row);
+ if(result)
+ {
+ if(row > 0) m_currentCursorPosition = row;
+ else
+ {
+ m_currentCursorPosition = it.size() + 1 + row;
+ }
+ }
+ return result;
+ }
+
+ protected boolean setActiveRelative(int row)
+ {
+ OJBIterator it = getActiveIterator();
+ boolean result = it.relative(row);
+ if(result)
+ {
+ m_currentCursorPosition += row;
+ }
+ return result;
+ }
+
/**
* the absolute and relative calls are the trickiest parts. We have to
* move across cursor boundaries potentially.
@@ -143,74 +199,65 @@
*/
public boolean absolute(int row) throws PersistenceBrokerException
{
- // 1. handle the special cases first.
+ // 1. handle the special cases first
if (row == 0)
{
return true;
}
-
if (row == 1)
{
- m_activeIteratorIndex = 0;
- m_activeIterator = (OJBIterator) m_rsIterators.get(m_activeIteratorIndex);
- m_activeIterator.absolute(1);
- return true;
+ setActiveIterator(0);
+ return setActiveAbsolute(1);
}
if (row == -1)
{
- m_activeIteratorIndex = m_rsIterators.size();
- m_activeIterator = (OJBIterator) m_rsIterators.get(m_activeIteratorIndex);
- m_activeIterator.absolute(-1);
- return true;
+ setActiveIterator(m_rsIterators.size() - 1);
+ return setActiveAbsolute(-1);
}
-
- // now do the real work.
- boolean movedToAbsolute = false;
+ // 2. now do the real work
boolean retval = false;
- setNextIterator();
-
// row is positive, so index from beginning.
if (row > 0)
{
int sizeCount = 0;
- Iterator it = m_rsIterators.iterator();
- OJBIterator temp = null;
- while (it.hasNext() && !movedToAbsolute)
+ OJBIterator temp;
+ for(int i = 0; i < m_rsIterators.size(); i++)
+ //while (it.hasNext() && !movedToAbsolute)
{
- temp = (OJBIterator) it.next();
- if (temp.size() < row)
+ temp = getIterator(i);
+ int tempMax = temp.size();
+ if(sizeCount + tempMax < row)
{
- sizeCount += temp.size();
+ sizeCount += tempMax;
}
else
{
- // move to the offset - sizecount
- m_currentCursorPosition = row - sizeCount;
- retval = temp.absolute(m_currentCursorPosition);
- movedToAbsolute = true;
+ setActiveIterator(i);
+ retval = setActiveAbsolute(row - sizeCount);
+ break;
}
}
}
-
// row is negative, so index from end
else if (row < 0)
{
int sizeCount = 0;
- OJBIterator temp = null;
- for (int i = m_rsIterators.size(); ((i >= 0) && !movedToAbsolute); i--)
+ int rowAbs = Math.abs(row);
+ OJBIterator temp;
+ for (int i = m_rsIterators.size() - 1; i >= 0; i--)
{
- temp = (OJBIterator) m_rsIterators.get(i);
- if (temp.size() < row)
+ temp = getIterator(i);
+ int tempMax = temp.size();
+ if (sizeCount + tempMax < rowAbs)
{
sizeCount += temp.size();
}
else
{
- // move to the offset - sizecount
- m_currentCursorPosition = row + sizeCount;
- retval = temp.absolute(m_currentCursorPosition);
- movedToAbsolute = true;
+ setActiveIterator(i);
+ retval = setActiveAbsolute(row + sizeCount);
+ break;
}
}
}
@@ -235,46 +282,79 @@
*/
public boolean relative(int row) throws PersistenceBrokerException
{
+ // 1. handle the special cases first.
if (row == 0)
{
return true;
}
-
- boolean movedToRelative = false;
+ // 2. now do the real work.
boolean retval = false;
- setNextIterator();
-
+ OJBIterator it = getActiveIterator();
+ // positive shift
if (row > 0)
{
// special case checking for the iterator we're currently in
// (since it isn't positioned on the boundary potentially)
- if (row > (m_activeIterator.size() - m_currentCursorPosition))
+ if (row > (it.size() - m_currentCursorPosition))
{
// the relative position lies over the border of the
// current iterator.
// starting position counter should be set to whatever we have left in
// active iterator.
- int positionCounter = m_activeIterator.size() - m_currentCursorPosition;
- for (int i = m_activeIteratorIndex + 1; ((i < m_rsIterators.size()) && !movedToRelative); i++)
+ int positionCounter = it.size() - m_currentCursorPosition;
+ for (int i = m_activeIteratorIndex + 1; i < m_rsIterators.size(); i++)
{
- m_activeIteratorIndex = i;
- m_currentCursorPosition = 0;
- m_activeIterator = (OJBIterator) m_rsIterators.get(m_activeIteratorIndex);
- if (!((row - positionCounter) > m_activeIterator.size()))
+ OJBIterator temp = getIterator(i);
+ if ((row - positionCounter) > temp.size())
+ {
+ positionCounter += temp.size();
+ }
+ else
{
// the relative position requested is within this iterator.
- m_currentCursorPosition = row - positionCounter;
- retval = m_activeIterator.relative(m_currentCursorPosition);
- movedToRelative = true;
+ setActiveIterator(i);
+ retval = setActiveRelative(row - positionCounter);
+ break;
}
}
}
else
{
// the relative position lays within the current iterator.
- retval = m_activeIterator.relative(row);
- movedToRelative = true;
+ retval = setActiveRelative(row);
+ }
+ }
+ else // negative shift
+ {
+ int rowAbs = Math.abs(row);
+ if(m_currentCursorPosition < rowAbs)
+ {
+ // the relative position lies over the border of the
+ // current iterator.
+
+ // starting position counter should be set to whatever we have left in
+ // active iterator.
+ int positionCounter = m_currentCursorPosition;
+ for (int i = m_activeIteratorIndex - 1; i > -1; i--)
+ {
+ OJBIterator temp = getIterator(i);
+ if ((rowAbs - positionCounter) > temp.size())
+ {
+ positionCounter += temp.size();
+ }
+ else
+ {
+ // the relative position requested is within this iterator.
+ setActiveIterator(i);
+ retval = setActiveRelative(row + positionCounter);
+ break;
+ }
+ }
+ }
+ else
+ {
+ retval = setActiveRelative(row);
}
}
@@ -367,8 +447,6 @@
/**
* Answer true if an Iterator for a Table is already available
- * @param aTable
- * @return
*/
public boolean containsIteratorForTable(String aTable)
{
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/JdbcAccessImpl.java Thu Mar 1 16:58:55 2007
@@ -19,6 +19,7 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
+import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -215,7 +216,7 @@
if (logger.isDebugEnabled()) logger.debug("executeInsert: " + stmt);
stmt.executeUpdate();
// after insert read and assign identity columns
- postSequenceProcess(cld, obj);
+ postSequenceProcess(stmt, cld, obj);
// Harvest any return values.
harvestReturnValues(cld.getInsertProcedure(), obj, stmt);
@@ -252,6 +253,16 @@
logger.debug("executeQuery: " + query);
}
/*
+ arminw:
+ we need platform dependent information below, so we have to pre-process the
+ query object, this can cause twice invocation of method Query.preprocess
+ because in class PersistencebrokerImpl#getRsIteratorFromQuery this method
+ is called too
+ TODO: fix twice call of method Query.preprocess if possible
+ */
+ query.preprocess(broker);
+
+ /*
* MBAIRD: we should create a scrollable resultset if the start at
* index or end at index is set
*/
@@ -807,11 +818,11 @@
}
}
- protected void postSequenceProcess(final ClassDescriptor cld, final Object target) throws SequenceManagerException
+ protected void postSequenceProcess(final Statement stmt, final ClassDescriptor cld, final Object target) throws SequenceManagerException
{
// post insert sequence manager call, e.g. to lookup identity column PK value
// from DB and set PK in persistent object
- broker.serviceSequenceManager().afterStore(this, cld, target);
+ broker.serviceSequenceManager().afterStore(this, stmt, cld, target);
}
/**
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/OJBIterator.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/OJBIterator.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/OJBIterator.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/OJBIterator.java Thu Mar 1 16:58:55 2007
@@ -39,13 +39,27 @@
public interface OJBIterator extends Iterator
{
/**
+ * Returns the size of the iterator in consideration of limit-seetings
+ * (see {@link org.apache.ojb.broker.query.Query#setStartAtIndex(int)}
+ * and {@link org.apache.ojb.broker.query.Query#setEndAtIndex(int)}) of the
+ * underlying {@link org.apache.ojb.broker.query.Query}.
+ * <br/>
+ * This may differ from the result of method {@link #fullSize()}.
+ *
* @return the size of the iterator, aka the number of rows in this iterator.
*/
int size() throws PersistenceBrokerException;
/**
- * @return the unlimited size of the iterator,
- * fullSize() may differ from size() for PagingIterator
+ * Returns the full size of the iterator.
+ *
+ * @return the unlimited size of the iterator, this may differ from {@link #size()}
+ * dependent of the used implementation - e.g. if
+ * {@link org.apache.ojb.broker.query.Query#setStartAtIndex(int)}
+ * and {@link org.apache.ojb.broker.query.Query#setEndAtIndex(int)} is used in the
+ * underlying {@link org.apache.ojb.broker.query.Query} but the used database does not
+ * support native LIMIT/OFFSET, thus {@link #fullSize()} will return the full iterator size and
+ * {@link #size()} take care of limit boundaries.
*/
int fullSize() throws PersistenceBrokerException;
@@ -53,14 +67,17 @@
* Moves the cursor to the given row number in the iterator.
* If the row number is positive, the cursor moves to the given row number with
* respect to the beginning of the iterator. The first row is row 1, the second is row 2, and so on.
+ *
* @param row the row to move to in this iterator, by absolute number
*/
boolean absolute(int row) throws PersistenceBrokerException;
/**
- * Moves the cursor a relative number of rows, either positive or negative. Attempting to move beyond the first/last
- * row in the iterator positions the cursor before/after the the first/last row. Calling relative(0) is valid,
+ * Moves the cursor a relative number of rows, either positive or negative.
+ * Attempting to move beyond the first/last row in the iterator positions the
+ * cursor before/after the first/last row. Calling relative(0) is valid,
* but does not change the cursor position.
+ *
* @param row the row to move to in this iterator, by relative number
*/
boolean relative(int row) throws PersistenceBrokerException;
@@ -72,9 +89,56 @@
* this method will be called implicitely.
*/
public void releaseDbResources();
-
+
/**
- * Do not fire any PBLifeCycleEvent when reading next item.
+ * Do not fire any PBLifeCycleEvent when reading next item.
*/
public void disableLifeCycleEvents();
+
+ /**
+ * A NOOP implementation of this interface.
+ */
+ public static final OJBIterator EMPTY_ITERATOR = new OJBIterator(){
+ public boolean absolute(int row) throws PersistenceBrokerException
+ {
+ return false;
+ }
+
+ public void disableLifeCycleEvents()
+ {
+ }
+
+ public int fullSize() throws PersistenceBrokerException
+ {
+ return 0;
+ }
+
+ public boolean relative(int row) throws PersistenceBrokerException
+ {
+ return false;
+ }
+
+ public void releaseDbResources()
+ {
+ }
+
+ public int size() throws PersistenceBrokerException
+ {
+ return 0;
+ }
+
+ public boolean hasNext()
+ {
+ return false;
+ }
+
+ public Object next()
+ {
+ return null;
+ }
+
+ public void remove()
+ {
+ }
+ };
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/PagingIterator.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/PagingIterator.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/PagingIterator.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/PagingIterator.java Thu Mar 1 16:58:55 2007
@@ -16,6 +16,8 @@
*/
import org.apache.ojb.broker.PersistenceBrokerException;
+import org.apache.ojb.broker.util.logging.Logger;
+import org.apache.ojb.broker.util.logging.LoggerFactory;
import org.apache.ojb.broker.query.Query;
/**
@@ -26,17 +28,18 @@
* startAt = 1, endAt = 11 returns rows 1 to 11 if available
* if endAt == Query.NO_END_AT_INDEX endAt is set to the last available row
*
- * @author <a href="mailto:[email protected]">Jakob Braeuchi</a>
* @version $Id$
*/
public class PagingIterator implements OJBIterator
{
+ private Logger log = LoggerFactory.getLogger(PagingIterator.class);
private final OJBIterator m_iterator;
private int m_startAt;
private int m_endAt;
- private int m_rowLimit;
+ private int m_rowLimitSize;
private int m_fullSize;
- private int m_currentCursorPosition; // position of the wrapped iterator
+ // position of the wrapped iterator
+ private int m_currentCursorPosition;
/**
* Constructor
@@ -47,36 +50,29 @@
public PagingIterator(OJBIterator anIterator, int startAt, int endAt)
{
super();
-
- if (endAt != Query.NO_START_AT_INDEX && startAt > endAt)
+ if (endAt != Query.NO_END_AT_INDEX && startAt > endAt)
{
throw new PersistenceBrokerException("startAt must be less than endAt.");
}
- m_iterator = anIterator;
- m_fullSize = m_iterator.size();
-
- if (startAt == Query.NO_START_AT_INDEX)
- {
- m_startAt = 1;
- }
- else
- {
- m_startAt = startAt;
- }
-
- if (endAt == Query.NO_END_AT_INDEX)
- {
- m_endAt = m_fullSize;
+ m_fullSize = anIterator.size();
+ m_startAt = (startAt == Query.NO_START_AT_INDEX ? 1 : startAt);
+ m_endAt = (endAt == Query.NO_END_AT_INDEX || endAt > m_fullSize ? m_fullSize : endAt);
+ m_rowLimitSize = Math.max(0, m_endAt - m_startAt + 1);
+ m_currentCursorPosition = m_startAt;
+ if(m_startAt > m_endAt || m_startAt > m_fullSize)
+ {
+ log.warn("Index out of bound, Query.startAt=" + m_startAt
+ + " and Query.endAt=" + m_endAt + " doesn't match results");
+ m_iterator = OJBIterator.EMPTY_ITERATOR;
+ m_rowLimitSize = 0;
+ m_fullSize = 0;
+ anIterator.releaseDbResources();
}
else
{
- m_endAt = Math.min(endAt, m_fullSize);
+ m_iterator = anIterator;
}
-
- m_rowLimit = Math.max(0, m_endAt - m_startAt + 1);
- m_currentCursorPosition = m_startAt - 1;
-
m_iterator.absolute(m_currentCursorPosition);
}
@@ -85,13 +81,13 @@
*/
public int size() throws PersistenceBrokerException
{
- if (m_fullSize < m_rowLimit)
+ if (m_fullSize < m_rowLimitSize)
{
return m_fullSize;
}
else
{
- return m_rowLimit;
+ return m_rowLimitSize;
}
}
@@ -108,20 +104,23 @@
*/
public boolean absolute(int row) throws PersistenceBrokerException
{
- int newPosition = (m_startAt - 1) + row;
-
- if (newPosition < m_startAt)
+ boolean result = false;
+ int newPosition = 0;
+ if(row > 0)
+ {
+ newPosition = m_startAt - 1 + row;
+ result = m_iterator.absolute(newPosition);
+ }
+ else if(row < 0)
{
- newPosition = Math.max(m_endAt + row, m_startAt - 1);
+ newPosition = m_endAt + 1 + row;
+ result = m_iterator.absolute(newPosition);
}
-
- if (newPosition > m_endAt)
+ if(result)
{
- newPosition = m_endAt;
+ m_currentCursorPosition = newPosition;
}
-
- m_currentCursorPosition = newPosition;
- return m_iterator.absolute(newPosition);
+ return result;
}
/**
@@ -129,7 +128,30 @@
*/
public boolean relative(int row) throws PersistenceBrokerException
{
- return absolute(m_currentCursorPosition - (m_startAt - 1) + row);
+ boolean result = false;
+ if(row > 0)
+ {
+ if(row <= m_endAt - m_currentCursorPosition)
+ {
+ result = m_iterator.relative(row);
+ if(result)
+ {
+ m_currentCursorPosition += row;
+ }
+ }
+ }
+ else if(row < 0)
+ {
+ if(Math.abs(row) <= m_currentCursorPosition - m_startAt)
+ {
+ result = m_iterator.relative(row);
+ if(result)
+ {
+ m_currentCursorPosition += row;
+ }
+ }
+ }
+ return result;
}
/**
@@ -153,16 +175,12 @@
*/
public boolean hasNext()
{
- if (m_currentCursorPosition < m_endAt)
- {
- return true;
- }
- else
+ boolean result = m_currentCursorPosition <= m_endAt && m_iterator.hasNext();
+ if(!result)
{
releaseDbResources();
- return false;
}
-
+ return result;
}
/**
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/RsIterator.java Thu Mar 1 16:58:55 2007
@@ -70,10 +70,6 @@
* It will NOT work with JDBC 1.0 Drivers (e.g. SUN's JdbcOdbcDriver) If you
* are forced to use such a driver, you can use code from the 0.1.30 release.
* </p>
- * @author <a href="mailto:[email protected]">Thomas Mahler <a>
- * @author <a href="mailto:[email protected]">Matthew Baird <a>- added the
- * support for extents mapped to single table - added the .size
- * functionality - added cursor control
*
* @version $Id$
*/
@@ -233,6 +229,7 @@
{
setHasCalledCheck(true);
setHasNext(getRsAndStmt().m_rs.next());
+ m_current_row++;
if (!getHasNext())
{
autoReleaseDbResources();
@@ -278,7 +275,7 @@
if (getHasNext())
{
Object obj = getObjectFromResultSet();
- m_current_row++;
+ //m_current_row++;
// Invoke events on PersistenceBrokerAware instances and listeners
// set target object
@@ -566,8 +563,7 @@
{
if (!JDBCSupportAssessed)
{
- if (getConnectionDescriptor().getJdbcLevel() >= 2.0)
- advancedJDBCSupport = true;
+ advancedJDBCSupport = getConnectionDescriptor().getJdbcLevel() >= 2.0;
JDBCSupportAssessed = true;
}
return advancedJDBCSupport;
@@ -618,7 +614,6 @@
{
rsStmt.close();
}
-
return count;
}
@@ -727,38 +722,47 @@
private boolean absoluteBasic(int row)
{
boolean retval = false;
-
- if (row > m_current_row)
+ if(row == -1)
{
- try
+ int size = size();
+ if(getQueryObject().usePaging())
{
- while (m_current_row < row && getRsAndStmt().m_rs.next())
+ int span = getQueryObject().getEndIndex() + 1 - getQueryObject().getStartIndex();
+ if(span < size)
{
- m_current_row++;
+ size = span;
}
- if (m_current_row == row)
- {
- retval = true;
- }
- else
+ }
+ row = size;
+ }
+ if (row > m_current_row)
+ {
+ try
+ {
+ retval = true;
+ while (m_current_row < row && retval)
{
- setHasCalledCheck(true);
- setHasNext(false);
- retval = false;
- autoReleaseDbResources();
+ retval = getRsAndStmt().m_rs.next();
+ if(retval) m_current_row++;
+ else break;
}
+ setHasCalledCheck(true);
+ setHasNext(retval);
+ if(!retval) autoReleaseDbResources();
+ System.out.println("result: " + getRsAndStmt().m_rs.getString(1) +", "+ getRsAndStmt().m_rs.getString("Lagerbestand"));
}
catch (Exception ex)
{
setHasCalledCheck(true);
setHasNext(false);
retval = false;
+ autoReleaseDbResources();
}
}
else
{
- logger.info("Your driver does not support advanced JDBC Functionality, " +
- "you cannot call absolute() with a position < current");
+ logger.warn("Your driver does not support advanced JDBC Functionality, " +
+ "you cannot call absolute() with a 'position' < 'current'");
}
return retval;
}
@@ -770,21 +774,26 @@
private boolean absoluteAdvanced(int row)
{
boolean retval = false;
-
try
{
if (getRsAndStmt().m_rs != null)
{
- if (row == 0)
+ if(row == 1 || row == 0)
+ {
+ retval = getRsAndStmt().m_rs.first();
+ //retval = getRsAndStmt().m_rs.absolute(1);
+ }
+ else if (row == -1)
{
- getRsAndStmt().m_rs.beforeFirst();
+ retval = getRsAndStmt().m_rs.last();
}
else
{
- retval = getRsAndStmt().m_rs.absolute(row);
+ retval = getRsAndStmt().m_rs.absolute(row);
}
- m_current_row = row;
- setHasCalledCheck(false);
+ if(retval) m_current_row = row;
+ setHasCalledCheck(retval);
+ setHasNext(retval);
}
}
catch (SQLException e)
@@ -829,7 +838,8 @@
}
else
{
- logger.info("Your driver does not support advanced JDBC Functionality, you cannot call relative() with a negative value");
+ logger.warn("Your driver does not support advanced JDBC Functionality, you cannot call" +
+ " relative() with a negative value");
}
}
return retval;
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/StatementManager.java Thu Mar 1 16:58:55 2007
@@ -20,6 +20,7 @@
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
+import java.sql.Types;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
@@ -44,6 +45,7 @@
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.SelectionCriteria;
import org.apache.ojb.broker.query.SqlCriteria;
+import org.apache.ojb.broker.query.AbstractQueryImpl;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
@@ -325,13 +327,43 @@
*/
public int bindStatement(PreparedStatement stmt, Query query, ClassDescriptor cld, int param) throws SQLException
{
- int result;
+ int result = param;
+ //TODO: rework limit/offset support, avoid this cast
+ int[] limitValues = ((AbstractQueryImpl) query).getLimitValues();
+ boolean limitOrOffset = query.usePaging() && limitValues.length > 0;
+ if(limitOrOffset)
+ {
+ if(m_platform.limitAfterSelect())
+ {
+ for(int i = 0; i < limitValues.length; i++)
+ {
+ int limitValue = limitValues[i];
+ m_platform.setObjectForStatement(stmt, result, new Integer(limitValue), Types.INTEGER);
+ ++result;
+ }
+ }
- result = bindStatement(stmt, query.getCriteria(), cld, param);
- result = bindStatement(stmt, query.getHavingCriteria(), cld, result);
+ result = bindStatement(stmt, query.getCriteria(), cld, result);
+ result = bindStatement(stmt, query.getHavingCriteria(), cld, result);
+ if(!m_platform.limitAfterSelect())
+ {
+ for(int i = 0; i < limitValues.length; i++)
+ {
+ int limitValue = limitValues[i];
+ m_platform.setObjectForStatement(stmt, result, new Integer(limitValue), Types.INTEGER);
+ ++result;
+ }
+ }
+ }
+ else
+ {
+ result = bindStatement(stmt, query.getCriteria(), cld, result);
+ result = bindStatement(stmt, query.getHavingCriteria(), cld, result);
+ }
return result;
}
+
/**
* bind a Query based Select Statement
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/accesslayer/sql/SqlSelectStatement.java Thu Mar 1 16:58:55 2007
@@ -15,12 +15,12 @@
* limitations under the License.
*/
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.lang.ref.WeakReference;
import org.apache.commons.collections.set.ListOrderedSet;
import org.apache.ojb.broker.metadata.ClassDescriptor;
@@ -377,16 +377,30 @@
((ReportQueryByCriteria) query).setAttributeFieldDescriptors(m_attrToFld);
}
- if(query.isSelectForUpdate())
- {
- stmt.append(getPlatform().getSelectForUpdateClause());
- }
+ stmt = prepareLimitAndOffset(stmt);
+
+ appendSelectForUpdate(stmt);
+
if(query.getQueryAffix() != null)
{
stmt.append(" ").append(query.getQueryAffix());
}
return stmt.toString();
+ }
+
+ protected StringBuffer prepareLimitAndOffset(StringBuffer stmt)
+ {
+ //TODO: Rework this section
+ return getQuery().prepareLimitAndOffset(stmt);
+ }
+
+ protected void appendSelectForUpdate(StringBuffer stmt)
+ {
+ if(getQuery().isSelectForUpdate())
+ {
+ stmt.append(getPlatform().getSelectForUpdateClause());
+ }
}
/*
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/DelegatingPersistenceBroker.java Thu Mar 1 16:58:55 2007
@@ -220,12 +220,17 @@
getBroker().delete(obj);
}
- public void store(Object obj) throws PersistenceBrokerException
+ public void store(Object obj, ObjectModification modification, boolean ignoreReferences) throws PersistenceBrokerException
+ {
+ getBroker().store(obj, modification, ignoreReferences);
+ }
+
+ public void store(Object obj) throws PersistenceBrokerException
{
getBroker().store(obj);
}
- public void store(Object obj,
+ public void store(Object obj,
ObjectModification modification) throws PersistenceBrokerException
{
getBroker().store(obj, modification);
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerBean.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerBean.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerBean.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerBean.java Thu Mar 1 16:58:55 2007
@@ -311,7 +311,17 @@
return getBroker().getPKEnumerationByQuery(PrimaryKeyClass, query);
}
- /**
+ /**
+ * @ejb:interface-method
+ * @see org.apache.ojb.broker.PersistenceBroker#store(Object, ObjectModification)
+ */
+ public void store(Object obj, ObjectModification modification, boolean ignoreReferences)
+ throws PersistenceBrokerException
+ {
+ getBroker().store(obj, modification, ignoreReferences);
+ }
+
+ /**
* @ejb:interface-method
* @see org.apache.ojb.broker.PersistenceBroker#store(Object, ObjectModification)
*/
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/core/PersistenceBrokerImpl.java Thu Mar 1 16:58:55 2007
@@ -19,6 +19,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -74,6 +75,7 @@
import org.apache.ojb.broker.metadata.ObjectReferenceDescriptor;
import org.apache.ojb.broker.metadata.SequenceDescriptor;
import org.apache.ojb.broker.metadata.fieldaccess.PersistentField;
+import org.apache.ojb.broker.platforms.Platform;
import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.query.QueryByIdentity;
import org.apache.ojb.broker.query.QueryBySQL;
@@ -85,9 +87,9 @@
import org.apache.ojb.broker.util.configuration.ConfigurationException;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
+import org.apache.ojb.broker.util.sequence.PerFieldManager;
import org.apache.ojb.broker.util.sequence.SequenceManager;
import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
-import org.apache.ojb.broker.util.sequence.PerFieldManager;
/**
* The PersistenceBrokerImpl is an implementation of the PersistenceBroker
@@ -1728,25 +1730,6 @@
return getIteratorFromQuery(query, cld);
}
- /**
- * Get an extent aware Iterator based on the Query
- *
- * @param query
- * @param cld the ClassDescriptor
- * @return OJBIterator
- */
- protected OJBIterator getIteratorFromQuery(Query query, ClassDescriptor cld) throws PersistenceBrokerException
- {
- RsIteratorFactory factory = RsIteratorFactoryImpl.getInstance();
- OJBIterator result = getRsIteratorFromQuery(query, cld, factory);
-
- if (query.usePaging())
- {
- result = new PagingIterator(result, query.getStartAtIndex(), query.getEndAtIndex());
- }
- return result;
- }
-
public Object getObjectByIdentity(Identity id) throws PersistenceBrokerException
{
objectCache.enableMaterializationCache();
@@ -1927,16 +1910,13 @@
return new PkEnumeration(query, cld, primaryKeyClass, this);
}
- /**
- * Makes object obj persistent in the underlying persistence system.
- * E.G. by INSERT INTO ... or UPDATE ... in an RDBMS.
- * The ObjectModification parameter can be used to determine whether INSERT or update is to be used.
- * This functionality is typically called from transaction managers, that
- * track which objects have to be stored. If the object is an unmaterialized
- * proxy the method return immediately.
- */
public void store(Object obj, ObjectModification mod) throws PersistenceBrokerException
{
+ store(obj, mod, false);
+ }
+
+ public void store(Object obj, ObjectModification mod, boolean ignoreReferences) throws PersistenceBrokerException
+ {
obj = extractObjectToStore(obj);
// null for unmaterialized Proxy
if (obj == null)
@@ -1950,11 +1930,11 @@
// select flag for insert / update selection by checking the ObjectModification
if (mod.needsInsert())
{
- store(obj, oid, cld, true);
+ store(obj, oid, cld, true, ignoreReferences);
}
else if (mod.needsUpdate())
{
- store(obj, oid, cld, false);
+ store(obj, oid, cld, false, ignoreReferences);
}
/*
arminw
@@ -2185,6 +2165,32 @@
}
/**
+ * Get an extent aware Iterator based on the ReportQuery
+ *
+ * @param query
+ * @param cld
+ * @return OJBIterator
+ */
+ protected OJBIterator getReportQueryIteratorFromQuery(Query query, ClassDescriptor cld) throws PersistenceBrokerException
+ {
+ RsIteratorFactory factory = ReportRsIteratorFactoryImpl.getInstance();
+ return getRsIteratorFromQuery(query, cld, factory);
+ }
+
+ /**
+ * Get an extent aware Iterator based on the Query
+ *
+ * @param query
+ * @param cld the ClassDescriptor
+ * @return OJBIterator
+ */
+ protected OJBIterator getIteratorFromQuery(Query query, ClassDescriptor cld) throws PersistenceBrokerException
+ {
+ RsIteratorFactory factory = RsIteratorFactoryImpl.getInstance();
+ return getRsIteratorFromQuery(query, cld, factory);
+ }
+
+ /**
* Get an extent aware RsIterator based on the Query
*
* @param query
@@ -2195,74 +2201,101 @@
private OJBIterator getRsIteratorFromQuery(Query query, ClassDescriptor cld, RsIteratorFactory factory)
throws PersistenceBrokerException
{
- query.setFetchSize(1);
+ // arminw: we use iterator for all kind of query, so I think
+ // this setting doesn't make sense and will override user settings
+ //query.setFetchSize(1);
+ /*
+ arminw:
+ we need platform dependent information below, so we have to pre-process the
+ query object, this will cause twice invocation of method Query.preprocess
+ because in class JdbcAccess this method is called too
+ TODO: fix twice call of method Query.preprocess if possible
+ */
query.preprocess(this);
+ OJBIterator result;
if (query instanceof QueryBySQL)
{
if(logger.isDebugEnabled()) logger.debug("Creating SQL-RsIterator for class ["+cld.getClassNameOfObject()+"]");
- return factory.createRsIterator((QueryBySQL) query, cld, this);
+ result = factory.createRsIterator((QueryBySQL) query, cld, this);
+ result = wrapWithPagingIteratorIfNeeded(result, query);
}
-
- if (!cld.isExtent() || !query.getWithExtents())
+ else if (!cld.isExtent() || !query.getWithExtents())
{
// no extents just use the plain vanilla RsIterator
if(logger.isDebugEnabled()) logger.debug("Creating RsIterator for class ["+cld.getClassNameOfObject()+"]");
-
- return factory.createRsIterator(query, cld, this);
- }
-
- if(logger.isDebugEnabled()) logger.debug("Creating ChainingIterator for class ["+cld.getClassNameOfObject()+"]");
-
- ChainingIterator chainingIter = new ChainingIterator();
-
- // BRJ: add base class iterator
- if (!cld.isInterface())
- {
- if(logger.isDebugEnabled()) logger.debug("Adding RsIterator for class ["+cld.getClassNameOfObject()+"] to ChainingIterator");
-
- chainingIter.addIterator(factory.createRsIterator(query, cld, this));
+ result = factory.createRsIterator(query, cld, this);
+ result = wrapWithPagingIteratorIfNeeded(result, query);
}
-
- Iterator extents = getDescriptorRepository().getAllConcreteSubclassDescriptors(cld).iterator();
- while (extents.hasNext())
+ else
{
- ClassDescriptor extCld = (ClassDescriptor) extents.next();
-
- // read same table only once
- if (chainingIter.containsIteratorForTable(extCld.getFullTableName()))
- {
- if(logger.isDebugEnabled()) logger.debug("Skipping class ["+extCld.getClassNameOfObject()+"]");
+ HashMap iteratorMap = new HashMap();
+ if(logger.isDebugEnabled()) logger.debug("ChainingIterator for class ["+cld.getClassNameOfObject()+"]");
+ // BRJ: add base class iterator
+ if (!cld.isInterface())
+ {
+ if(logger.isDebugEnabled()) logger.debug("ChainingIterator: Adding RsIterator for class ["+cld.getClassNameOfObject()+"] to ChainingIterator");
+ OJBIterator tmp = factory.createRsIterator(query, cld, this);
+ iteratorMap.put(cld.getFullTableName() ,wrapWithPagingIteratorIfNeeded(tmp, query));
}
- else
+
+ Iterator extents = getDescriptorRepository().getAllConcreteSubclassDescriptors(cld).iterator();
+ while (extents.hasNext())
{
- if(logger.isDebugEnabled()) logger.debug("Adding RsIterator of class ["+extCld.getClassNameOfObject()+"] to ChainingIterator");
+ ClassDescriptor extCld = (ClassDescriptor) extents.next();
+
+ // read same table only once
+ if (iteratorMap.containsKey(extCld.getFullTableName()))
+ {
+ if(logger.isDebugEnabled()) logger.debug("ChainingIterator: Skipping class ["+extCld.getClassNameOfObject()+"]");
+ }
+ else
+ {
+ if(logger.isDebugEnabled()) logger.debug("ChainingIterator: Adding RsIterator of class ["+extCld.getClassNameOfObject()+"] to ChainingIterator");
- // add the iterator to the chaining iterator.
- chainingIter.addIterator(factory.createRsIterator(query, extCld, this));
+ // add the iterator to the chaining iterator.
+ OJBIterator tmp = factory.createRsIterator(query, extCld, this);
+ iteratorMap.put(extCld.getFullTableName() ,wrapWithPagingIteratorIfNeeded(tmp, query));
+ }
}
+ result = new ChainingIterator(iteratorMap.values());
}
-
- return chainingIter;
+ return result;
}
/**
- * Get an extent aware Iterator based on the ReportQuery
+ * If native paging (LIMIT and/or LIMIT OFFSET) is not supported by the current
+ * database, wrap the current OJBIterator with a paging wrapper.
*
- * @param query
- * @param cld
- * @return OJBIterator
+ * @param iter The normal iterator.
+ * @param query The query.
+ * @return A paging capable iterator or the specified iterator if native paging
+ * is supported.
*/
- private OJBIterator getReportQueryIteratorFromQuery(Query query, ClassDescriptor cld) throws PersistenceBrokerException
+ protected OJBIterator wrapWithPagingIteratorIfNeeded(OJBIterator iter, Query query)
{
- RsIteratorFactory factory = ReportRsIteratorFactoryImpl.getInstance();
- OJBIterator result = getRsIteratorFromQuery(query, cld, factory);
-
- if (query.usePaging())
+ OJBIterator result = iter;
+ boolean isNativeLimitOffset = serviceConnectionManager().getConnectionDescriptor().isNativeLimitOffset();
+ if(query.usePaging())
{
- result = new PagingIterator(result, query.getStartAtIndex(), query.getEndAtIndex());
+ Platform platform = serviceConnectionManager().getSupportedPlatform();
+ // limit offset needed, full paging
+ if(query.hasOffset())
+ {
+ if(!isNativeLimitOffset || !platform.supportsOffset())
+ {
+ result = new PagingIterator(iter, query.getStartAtIndex(), query.getEndAtIndex());
+ }
+ }
+ // only limit
+ else if (query.hasLimit())
+ {
+ if(!isNativeLimitOffset || !platform.supportsLimit())
+ {
+ result = new PagingIterator(iter, query.getStartAtIndex(), query.getEndAtIndex());
+ }
+ }
}
-
return result;
}
@@ -2373,8 +2406,6 @@
{
return getProxyFactory().createProxy(baseClassForProxy,handler);
}
-
-
}
catch (Exception ex)
{
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/JdbcConnectionDescriptor.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/JdbcConnectionDescriptor.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/JdbcConnectionDescriptor.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/JdbcConnectionDescriptor.java Thu Mar 1 16:58:55 2007
@@ -25,6 +25,7 @@
import org.apache.ojb.broker.platforms.Platform;
import org.apache.ojb.broker.platforms.PlatformFactory;
import org.apache.ojb.broker.util.XmlHelper;
+import org.apache.ojb.broker.util.ConvertHelper;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
@@ -42,6 +43,7 @@
public static final int AUTO_COMMIT_IGNORE_STATE = 0;
public static final int AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE = 1;
public static final int AUTO_COMMIT_SET_FALSE = 2;
+ protected static final String ATTRIBUTE_NATIVE_LIMIT_OFFSET = "nativeLimitOffset";
private String m_jcdAlias;
private String m_Dbms;
@@ -58,6 +60,7 @@
private boolean defaultConnection = false;
private int useAutoCommit = AUTO_COMMIT_SET_TRUE_AND_TEMPORARY_FALSE;
private boolean ignoreAutoCommitExceptions = false;
+ private Boolean nativeLimitOffset;
private PBKey pbKey;
private ConnectionPoolDescriptor cpd;
private SequenceDescriptor sequenceDescriptor;
@@ -415,6 +418,42 @@
m_batchMode = flag;
}
+ /**
+ * Get the query limit/offset mode. If set <em>true</em> OJB use the native database specific
+ * LIMIT and OFFSET arguments for limit and paging queries (if it's supported by the DB and
+ * OJB's {@link Platform} implementation class). If set <em>false</em> OJB simulate limit
+ * and paging by a specific result set iterator (this can result in bad performance on big
+ * result sets).
+ *
+ * @return The current used limit and paging mode.
+ */
+ public boolean isNativeLimitOffset()
+ {
+ if(nativeLimitOffset == null)
+ {
+ nativeLimitOffset = ConvertHelper.toBoolean(getAttribute(ATTRIBUTE_NATIVE_LIMIT_OFFSET));
+ // by default we support native limit/paging
+ if(nativeLimitOffset == null)
+ {
+ nativeLimitOffset = Boolean.TRUE;
+ }
+ }
+ return nativeLimitOffset.booleanValue();
+ }
+
+ /**
+ * Sets the query limit/paging mode - see {@link #isNativeLimitOffset()}.
+ *
+ * @param nativeLimitOffset The limit paging mode.
+ */
+ public void setNativeLimitOffset(boolean nativeLimitOffset)
+ {
+ this.nativeLimitOffset = nativeLimitOffset ? Boolean.TRUE : Boolean.FALSE;
+ }
+
+ /**
+ * Returns the associated {@link org.apache.ojb.broker.platforms.Platform}.
+ */
public Platform getPlatform()
{
// no need to synchronize, dosen't matter if we use different instances
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/Platform.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/Platform.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/Platform.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/Platform.java Thu Mar 1 16:58:55 2007
@@ -18,6 +18,7 @@
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import org.apache.ojb.broker.metadata.FieldDescriptor;
import org.apache.ojb.broker.query.LikeCriteria;
+import org.apache.ojb.broker.query.Query;
import java.sql.CallableStatement;
import java.sql.Connection;
@@ -34,7 +35,6 @@
* each jdbc-connection-descriptor entry in the repository file.
*
* @version $Id$
- * @author Thomas Mahler
*/
public interface Platform
{
@@ -224,33 +224,80 @@
*/
String getLastInsertIdentityQuery(String tableName);
+
+ //===================================================================
+ // Limit and paging methods
+ //===================================================================
+
+ /**
+ * Answer <em>true</em> if LIMIT or equivalent is supported.
+ */
+ boolean supportsLimit();
+
+ /**
+ * Add the LIMIT to the SQL.
+ */
+ StringBuffer addLimitSql(Query query, StringBuffer anSqlString);
+
+ /**
+ * Answer <em>true</em> if LIMIT OFFSET or equivalent is supported.
+ */
+ boolean supportsOffset();
+
+ /**
+ * Add the LIMIT with LIMIT OFFSET to the SQL.
+ */
+ StringBuffer addPagingSql(Query query, StringBuffer anSqlString);
+
+ /**
+ * Builds the platform dependend LIMIT OFFSET value of the
+ * {@link org.apache.ojb.broker.query.Query#getStartAtIndex()} value
+ * (Note: take care of include/exclude boundary conditions).
+ *
+ * @param query The query.
+ * @return The platform dependend limit offset value.
+ */
+ int buildOffset(Query query);
+
/**
- * Answer true if LIMIT or equivalent is supported
- * <b> SQL-Paging is not yet supported </b>
+ * Builds the platform dependend LIMIT value of the
+ * {@link org.apache.ojb.broker.query.Query#getEndAtIndex()} value
+ * (Note: take care of include/exclude boundary conditions).
+ *
+ * @param query The query.
+ * @return The platform dependend limit value.
*/
- boolean supportsPaging();
+ int buildLimit(Query query);
/**
- * Add the LIMIT or equivalent to the SQL
- * <b> SQL-Paging is not yet supported </b>
+ * Returns the order of the LIMIT and OFFSET value setting
+ * in the LIMIT/OFFSET clause (e.g. in "LIMIT ?, ?").
+ * If <em>true</em> the limit argument have to be set before the offset
+ * argument. If <em>false</em> the reverse order is mandatory.
+ *
+ * @return The order of the LIMIT/OFFSET values.
*/
- void addPagingSql(StringBuffer anSqlString);
+ boolean limitBeforeOffset();
/**
- * Answer true if the LIMIT parameters are bound before the query parameters
- * <b> SQL-Paging is not yet supported </b>
+ * Returns <em>true</em> if the LIMIT/OFFSET clause is added after the
+ * SELECT-expression (e.g. "SELECT TOP n ..."). If <em>false</em> the
+ * LIMIT/OFFSET clause is added after the ORDER BY clause (e.g. "SELECT ... ORDER BY 1 LIMIT n,m").
*/
- boolean bindPagingParametersFirst();
+ boolean limitAfterSelect();
/**
- * Bind the Paging Parameters
- * <b> SQL-Paging is not yet supported </b>
- * @param ps
- * @param index parameter index
- * @param startAt
- * @param endAt
+ * If <em>true</em> the LIMIT/OFFSET values will be embedded in
+ * the limit/paging SQL-query when calling {@link #addLimitSql(org.apache.ojb.broker.query.Query, StringBuffer)}
+ * or {@link #addPagingSql(org.apache.ojb.broker.query.Query, StringBuffer)}. If <em>false</em> prepared statement
+ * paceholder "?" are used in these methods and OJB have bind the values.
+ *
+ * @return Whether or not the LIMIT/OFFSET values will be embedded in the SQL-query.
*/
- int bindPagingParameters(PreparedStatement ps, int index, int startAt, int endAt) throws SQLException;
+ boolean limitOffsetValuesEmbedded();
+
+ //===================================================================
+
/**
* Whether the platform supports a COUNT DISTINCT across multiple columns.
@@ -326,4 +373,20 @@
* @return The post prepared column value.
*/
public Object postPrepareReadInValue(FieldDescriptor fld, Object value);
+
+ /**
+ * If <em>true</em> auto-generated keys can be retrieved after a statement
+ * has been executed.
+ */
+ boolean supportsGetGeneratedKeys();
+
+ /**
+ * Show same behavior as <em>Statement.getGeneratedKeys()</em> - JDBC quotation:
+ * <br/>
+ * "Retrieves any auto-generated keys created as a result of executing this Statement object.
+ * If this Statement object did not generate any keys, an empty ResultSet object is returned."
+ * @param stmt
+ * @return The generated keys.
+ */
+ ResultSet getGeneratedKeys(Statement stmt) throws SQLException;
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDb2Impl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDb2Impl.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDb2Impl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDb2Impl.java Thu Mar 1 16:58:55 2007
@@ -22,6 +22,7 @@
import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+import org.apache.ojb.broker.query.Query;
/**
* This class extends <code>PlatformDefaultImpl</code> and defines specific
@@ -260,5 +261,77 @@
// work with DB2 Z/os v7 (reported on user-list) thus rollback to
//
return "select IDENTITY_VAL_LOCAL() from sysibm.sysdummy1";
+ }
+
+
+
+ public boolean supportsLimit()
+ {
+ return true;
+ }
+
+ public StringBuffer addLimitSql(Query query, StringBuffer anSqlString)
+ {
+ /*
+ see http://troels.arvin.dk/db/rdbms/
+ "When doing casual work, it's often easier to use DB2's non-standard
+ SELECT ... FETCH FIRST n ROWS ONLY construct."
+ Seems parameter marker '?' are not allowed.
+ */
+ return anSqlString
+ .append(" FETCH FIRST ")
+ .append(buildLimit(query))
+ .append(" ROWS ONLY");
+ }
+
+ public boolean supportsOffset()
+ {
+ return false;
+ }
+
+ public StringBuffer addPagingSql(Query query, StringBuffer anSqlString)
+ {
+ // TODO: native paging support
+ // not supported
+ throw new UnsupportedOperationException("OFFSET is not supported by this platform" +
+ " implementation class (" + this.getClass().getName() +
+ "), please disable the native limit/offset flag in the" +
+ " connection metadata mapping file using attribute 'nativeLimitOffset'" +
+ " then OJB will use specific paging/limit result set iterator to simulate it!");
+ }
+
+ public int buildLimit(Query query)
+ {
+ int result = 0;
+ if(query.hasLimit())
+ {
+ return query.getEndAtIndex();
+ }
+ else if(query.hasOffset())
+ {
+ return MAX_LIMIT_VALUE;
+ }
+ return result;
+ }
+
+ public int buildOffset(Query query)
+ {
+ return query.getStartAtIndex();
+ }
+
+ public boolean limitOffsetValuesEmbedded()
+ {
+ // parameter marker '?' are not allowed, we embed limit/offset values
+ return true;
+ }
+
+ public boolean limitBeforeOffset()
+ {
+ return false;
+ }
+
+ public boolean limitAfterSelect()
+ {
+ return false;
}
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDefaultImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDefaultImpl.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDefaultImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformDefaultImpl.java Thu Mar 1 16:58:55 2007
@@ -36,6 +36,7 @@
import org.apache.ojb.broker.metadata.FieldDescriptor;
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import org.apache.ojb.broker.query.LikeCriteria;
+import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.util.SqlHelper;
import org.apache.ojb.broker.util.logging.Logger;
import org.apache.ojb.broker.util.logging.LoggerFactory;
@@ -54,14 +55,23 @@
private static final String INITIALIZATION_CHECK_AUTOCOMMIT = "initializationCheck";
private static final String FALSE_STR = "false";
+ /**
+ * Doesn't make sense to use the maximal possible integer as maximal limit value,
+ * thus OJB use '900000000'. Don't use Integer.MAX because not all DB INTEGER
+ * data type support it.
+ */
+ protected static final int MAX_LIMIT_VALUE = 900000000;
+
protected boolean m_batchUpdatesChecked = false;
protected boolean m_supportsBatchUpdates = false;
- protected Boolean locatorsUpdateCopy;
+ private Boolean locatorsUpdateCopy;
+ private Boolean supportsGetGeneratedKeys;
protected JdbcConnectionDescriptor jcd;
public PlatformDefaultImpl(JdbcConnectionDescriptor jcd)
{
this.jcd = jcd;
+
}
public boolean supportsBatchOperations()
@@ -98,6 +108,40 @@
}
}
+ /**
+ * Sets platform information for if the jdbc driver/db combo support
+ * get auto-generated keys. Will only be checked once.
+ *
+ * @param conn
+ */
+ protected void checkForGetGeneratedKeys(Connection conn)
+ {
+ if(supportsGetGeneratedKeys == null)
+ {
+ try
+ {
+//#ifdef JDBC30
+
+ DatabaseMetaData meta = conn.getMetaData();
+ boolean result = meta.supportsGetGeneratedKeys();
+
+//#else
+
+/*
+ boolean result = false;
+*/
+
+//#endif
+ supportsGetGeneratedKeys = result ? Boolean.TRUE : Boolean.FALSE;
+ }
+ catch(Exception e)
+ {
+ log.warn("Get auto-generated keys support check failed", e);
+ supportsGetGeneratedKeys = Boolean.FALSE;
+ }
+ }
+ }
+
public void afterStatementCreate(Statement stmt) throws PlatformException
{
//noop
@@ -164,6 +208,7 @@
public void initializeJdbcConnection(Connection conn) throws PlatformException
{
if(jcd.getBatchMode()) checkForBatchSupport(conn);
+ checkForGetGeneratedKeys(conn);
switch(jcd.getUseAutoCommit())
{
@@ -499,42 +544,76 @@
throw new UnsupportedOperationException("This feature is not supported by this implementation");
}
- /**
- * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
- */
- public void addPagingSql(StringBuffer anSqlString)
+
+
+ public boolean supportsLimit()
{
- // do nothing
+ return false;
}
- /**
- * @see org.apache.ojb.broker.platforms.Platform#bindPagingParametersFirst()
- */
- public boolean bindPagingParametersFirst()
+ public StringBuffer addLimitSql(Query query, StringBuffer anSqlString)
+ {
+ // not supported
+ throw new UnsupportedOperationException("LIMIT/OFFSET is not supported by this platform" +
+ " implementation class (" + this.getClass().getName() +
+ "), please disable the native limit/offset flag in the" +
+ " connection metadata mapping file using attribute 'nativeLimitOffset'" +
+ " then OJB will use specific paging/limit result set iterator to simulate it!");
+ }
+
+ public boolean supportsOffset()
{
return false;
}
- /**
- * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
- */
- public boolean supportsPaging()
+ public StringBuffer addPagingSql(Query query, StringBuffer anSqlString)
+ {
+ // not supported
+ throw new UnsupportedOperationException("LIMIT/OFFSET is not supported by this platform" +
+ " implementation class (" + this.getClass().getName() +
+ "), please disable the native limit/offset flag in the" +
+ " connection metadata mapping file using attribute 'nativeLimitOffset'" +
+ " then OJB will use specific paging/limit result set iterator to simulate it!");
+ }
+
+ public int buildOffset(Query query)
+ {
+ // if start index not set return 0
+ return query.hasOffset() ? query.getStartAtIndex() - 1 : 0;
+ }
+
+ public int buildLimit(Query query)
+ {
+ if(query.hasLimit())
+ {
+ return query.getEndAtIndex() - (query.getStartAtIndex() > 0 ? query.getStartAtIndex() - 1 : 0);
+ } // offset set without limit, we return all rows starting with the offset
+ else if(query.hasOffset())
+ {
+ return MAX_LIMIT_VALUE;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ public boolean limitBeforeOffset()
{
return false;
}
- /**
- * @see org.apache.ojb.broker.platforms.Platform#bindPagingParameters(java.sql.PreparedStatement, int, int, int)
- */
- public int bindPagingParameters(PreparedStatement ps, int index, int startAt, int endAt) throws SQLException
+ public boolean limitAfterSelect()
{
- ps.setInt(index, startAt - 1); // zero based start
- index++;
- ps.setInt(index, endAt - (startAt - 1)); // number of rows to fetch
- index++;
- return index;
+ return false;
}
+ public boolean limitOffsetValuesEmbedded()
+ {
+ return false;
+ }
+
+
/**
* Answer the Character for Concatenation
*/
@@ -702,4 +781,28 @@
{
return value;
}
+
+ public boolean supportsGetGeneratedKeys()
+ {
+ return supportsGetGeneratedKeys != null && supportsGetGeneratedKeys.booleanValue();
+ }
+
+ public ResultSet getGeneratedKeys(Statement stmt) throws SQLException
+ {
+
+//#ifdef JDBC30
+
+ return stmt.getGeneratedKeys();
+
+//#else
+
+/*
+ // not supported
+ throw new UnsupportedOperationException("Not supported in used JDBC-specification version");
+*/
+
+//#endif
+
+ }
+
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformHsqldbImpl.java Thu Mar 1 16:58:55 2007
@@ -19,6 +19,7 @@
import org.apache.ojb.broker.util.sequence.SequenceManagerHelper;
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+import org.apache.ojb.broker.query.Query;
/**
* This class extends <code>PlatformDefaultImpl</code> and defines specific
@@ -88,26 +89,29 @@
return LAST_INSERT;
}
- /* (non-Javadoc)
- * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
- */
- public void addPagingSql(StringBuffer anSqlString)
+
+
+ public boolean supportsLimit()
{
- anSqlString.insert(6, " LIMIT ? ? ");
+ return true;
}
- /* (non-Javadoc)
- * @see org.apache.ojb.broker.platforms.Platform#bindPagingParametersFirst()
- */
- public boolean bindPagingParametersFirst()
+ public StringBuffer addLimitSql(Query query, StringBuffer anSqlString)
+ {
+ return anSqlString.append(" LIMIT ?");
+ }
+
+ public boolean supportsOffset()
{
return true;
}
- /* (non-Javadoc)
- * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
- */
- public boolean supportsPaging()
+ public StringBuffer addPagingSql(Query query, StringBuffer anSqlString)
+ {
+ return anSqlString.append(" LIMIT ? OFFSET ?");
+ }
+
+ public boolean limitBeforeOffset()
{
return true;
}
@@ -116,6 +120,8 @@
{
return false;
}
+
+
public String createSequenceQuery(String sequenceName, Properties prop)
{
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMsSQLServerImpl.java Thu Mar 1 16:58:55 2007
@@ -21,6 +21,8 @@
import java.sql.SQLException;
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
+import org.apache.ojb.broker.query.Query;
+import org.apache.commons.lang.StringUtils;
/**
* This class extends <code>PlatformDefaultImpl</code> and defines specific behavior for the
@@ -93,5 +95,71 @@
protected String getQuotedName(String aString)
{
return '[' + aString + ']';
+ }
+
+
+
+ public boolean supportsLimit()
+ {
+ return true;
+ }
+
+ public StringBuffer addLimitSql(Query query, StringBuffer anSqlString)
+ {
+ /*
+ See http://troels.arvin.dk/db/rdbms/#select-top-n-standard
+ SELECT TOP 3 WITH TIES * FROM person ORDER BY age ASC
+ */
+ return new StringBuffer(StringUtils.replace(anSqlString.toString(), "SELECT", "SELECT TOP ?", 1));
+ }
+
+ public boolean supportsOffset()
+ {
+ return true;
+ }
+
+ public StringBuffer addPagingSql(Query query, StringBuffer anSqlString)
+ {
+ /*
+ See http://troels.arvin.dk/db/rdbms/#select-top-n-standard
+ SELECT * FROM (
+ SELECT TOP n * FROM (
+ SELECT TOP z columns -- (z=n+skip)
+ FROM tablename ORDER BY key ASC)
+ AS FOO ORDER BY key DESC -- ('FOO' may be anything)
+ ) AS BAR ORDER BY key ASC -- ('BAR' may be anything)
+ */
+ StringBuffer tmp = new StringBuffer(StringUtils.replace(
+ anSqlString.toString(), "SELECT", "SELECT * FROM ( SELECT TOP ? * FROM ( SELECT TOP ?", 1));
+ return tmp.append(") AS FOO ORDER BY key DESC ) AS BAR ORDER BY key ASC");
+ }
+
+ public int buildLimit(Query query)
+ {
+ int result = 0;
+ if(query.hasLimit())
+ {
+ return query.getEndAtIndex();
+ }
+ else if(query.hasOffset())
+ {
+ return MAX_LIMIT_VALUE;
+ }
+ return result;
+ }
+
+ public int buildOffset(Query query)
+ {
+ return super.buildOffset(query);
+ }
+
+ public boolean limitBeforeOffset()
+ {
+ return false;
+ }
+
+ public boolean limitAfterSelect()
+ {
+ return true;
}
}
Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java
URL: http://svn.apache.org/viewvc/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java?view=diff&rev=513569&r1=513568&r2=513569
==============================================================================
--- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java (original)
+++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/platforms/PlatformMySQLImpl.java Thu Mar 1 16:58:55 2007
@@ -26,6 +26,7 @@
import java.sql.Connection;
import org.apache.ojb.broker.query.LikeCriteria;
+import org.apache.ojb.broker.query.Query;
import org.apache.ojb.broker.metadata.FieldDescriptor;
import org.apache.ojb.broker.metadata.JdbcConnectionDescriptor;
import org.apache.commons.lang.SerializationUtils;
@@ -140,24 +141,34 @@
return LAST_INSERT + tableName + LIMIT;
}
- /*
- * (non-Javadoc)
- *
- * @see org.apache.ojb.broker.platforms.Platform#addPagingSql(java.lang.StringBuffer)
- */
- public void addPagingSql(StringBuffer anSqlString)
+ public boolean supportsLimit()
{
- anSqlString.append(" LIMIT ?,?");
+ return true;
}
- /*
- * (non-Javadoc)
- *
- * @see org.apache.ojb.broker.platforms.Platform#supportsPaging()
- */
- public boolean supportsPaging()
+ public StringBuffer addLimitSql(Query query, StringBuffer anSqlString)
+ {
+ return anSqlString.append(" LIMIT ?");
+ }
+
+ public boolean supportsOffset()
{
return true;
+ }
+
+ public StringBuffer addPagingSql(Query query, StringBuffer anSqlString)
+ {
+ return anSqlString.append(" LIMIT ?, ?");
+ }
+
+ public boolean limitAfterSelect()
+ {
+ return false;
+ }
+
+ public boolean limitBeforeOffset()
+ {
+ return false;
}
/**