diff --git a/base/src/org/compiere/model/Query.java b/base/src/org/compiere/model/Query.java index afd9799259..41fac71689 100644 --- a/base/src/org/compiere/model/Query.java +++ b/base/src/org/compiere/model/Query.java @@ -52,6 +52,8 @@ import org.compiere.util.Util; *
  • FR [ 2726447 ] Query aggregate methods for all return types *
  • FR [ 2818547 ] Implement Query.setOnlySelection * https://sourceforge.net/tracker/?func=detail&aid=2818547&group_id=176962&atid=879335 + *
  • FR [ 2818646 ] Implement Query.firstId/firstIdOnly + * https://sourceforge.net/tracker/?func=detail&aid=2818646&group_id=176962&atid=879335 * @author Redhuan D. Oon *
  • FR: [ 2214883 ] Remove SQL code and Replace for Query // introducing SQL String prompt in log.info *
  • FR: [ 2214883 ] - to introduce .setClient_ID @@ -306,6 +308,69 @@ public class Query } return po; } + + /** + * Return first ID + * @return first ID + * @throws DBException + */ + public int firstId() throws DBException + { + return firstId(false); + } + + /** + * Return first ID. + * If there are more results and exception is thrown. + * @return first ID + * @throws DBException + */ + public int firstIdOnly() throws DBException + { + return firstId(true); + } + + private int firstId(boolean assumeOnlyOneResult) throws DBException + { + String[] keys = table.getKeyColumns(); + if (keys.length != 1) + { + throw new DBException("Table "+table+" has 0 or more than 1 key columns"); + } + + StringBuffer selectClause = new StringBuffer("SELECT "); + selectClause.append(keys[0]); + selectClause.append(" FROM ").append(table.getTableName()); + String sql = buildSQL(selectClause, true); + + int id = -1; + PreparedStatement pstmt = null; + ResultSet rs = null; + try + { + pstmt = DB.prepareStatement(sql, trxName); + rs = createResultSet(pstmt); + if (rs.next()) + { + id = rs.getInt(1); + } + if (assumeOnlyOneResult && rs.next()) + { + throw new DBException("QueryMoreThanOneRecordsFound"); // TODO : translate + } + } + catch (SQLException e) + { + throw new DBException(e, sql); + } + finally + { + DB.close(rs, pstmt); + rs = null; pstmt = null; + } + // + return id; + } /** diff --git a/extend/src/test/functional/QueryTest.java b/extend/src/test/functional/QueryTest.java index 91c666d48e..61cb02ef8b 100644 --- a/extend/src/test/functional/QueryTest.java +++ b/extend/src/test/functional/QueryTest.java @@ -153,6 +153,16 @@ public class QueryTest extends AdempiereTestCase .first(); assertEquals("Invalid object", "C_Invoice", t.getTableName()); } + + public void testFirstId() throws Exception + { + int id = new Query(getCtx(), "AD_Table", "TableName IN (?,?)", getTrxName()) + .setParameters(new Object[]{"C_Invoice", "M_InOut"}) + .setOrderBy("TableName") + .firstId(); + int expectedId = 318; // C_Invoice + assertEquals("Invalid ID", expectedId, id); + } public void testFirstOnly() throws Exception { @@ -172,6 +182,25 @@ public class QueryTest extends AdempiereTestCase }); } + public void testFirstIdOnly() throws Exception + { + int expectedId = 318; // C_Invoice + int id = new Query(getCtx(), "AD_Table", "AD_Table_ID=?", getTrxName()) + .setParameters(new Object[]{expectedId}) + .firstIdOnly(); + assertEquals("Invalid table ID", expectedId, id); + // + assertExceptionThrown(null, DBException.class, new Runnable(){ + public void run() + { + new Query(getCtx(), "AD_Table", "TableName IN (?,?)", getTrxName()) + .setParameters(new Object[]{"C_Invoice", "M_InOut"}) + .setOrderBy("TableName") + .firstIdOnly(); + } + }); + } + public void testSetClient_ID() throws Exception { int AD_Client_ID = Env.getAD_Client_ID(getCtx());