IDEMPIERE-422 Complete Native Sequence feature / peer review and tests

This commit is contained in:
Carlos Ruiz 2012-10-05 19:03:57 -05:00
parent 7874f573e4
commit 595fda5ef4
11 changed files with 181 additions and 427 deletions

View File

@ -16,15 +16,9 @@ CREATE OR REPLACE PROCEDURE nextID
* Title: Get Next ID - no Commit * Title: Get Next ID - no Commit
* Description: * Description:
* Test via * Test via
DECLARE
v_NextID NUMBER;
BEGIN
nextID(2, 'Y', v_NextID);
DBMS_OUTPUT.PUT_LINE(v_NextID);
END;
* *
************************************************************************/ ************************************************************************/
As AS
Isnativeseqon NVARCHAR2(1); Isnativeseqon NVARCHAR2(1);
Tablename Nvarchar2(60); Tablename Nvarchar2(60);
sqlcmd VARCHAR2(200); sqlcmd VARCHAR2(200);
@ -43,23 +37,13 @@ BEGIN
WHERE AD_Sequence_ID=p_AD_Sequence_ID; WHERE AD_Sequence_ID=p_AD_Sequence_ID;
ELSE ELSE
BEGIN Isnativeseqon := get_Sysconfig('SYSTEM_NATIVE_SEQUENCE','N',0,0);
SELECT Value
Into Isnativeseqon
From Ad_Sysconfig
Where Name ='SYSTEM_NATIVE_SEQUENCE';
EXCEPTION
WHEN NO_DATA_FOUND THEN
Isnativeseqon:= 'N';
END;
IF Isnativeseqon = 'Y' THEN IF Isnativeseqon = 'Y' THEN
Select Name SELECT Name
INTO tablename INTO tablename
From Ad_Sequence FROM Ad_Sequence
Where Ad_Sequence_Id=P_Ad_Sequence_Id WHERE Ad_Sequence_Id=P_Ad_Sequence_Id;
And Istableid = 'Y';
-- --
Sqlcmd := 'SELECT '||Tablename||'_SQ.Nextval FROM DUAL'; Sqlcmd := 'SELECT '||Tablename||'_SQ.Nextval FROM DUAL';
-- --
@ -73,9 +57,9 @@ BEGIN
WHERE AD_Sequence_ID=p_AD_Sequence_ID WHERE AD_Sequence_ID=p_AD_Sequence_ID
FOR UPDATE OF CurrentNext; FOR UPDATE OF CurrentNext;
-- --
Update Ad_Sequence UPDATE Ad_Sequence
Set Currentnext = Currentnext + Incrementno SET Currentnext = Currentnext + Incrementno
Where Ad_Sequence_Id=P_Ad_Sequence_Id; WHERE Ad_Sequence_Id=P_Ad_Sequence_Id;
-- --
END IF; END IF;
END IF; END IF;

View File

@ -1,4 +1,4 @@
CREATE OR REPLACE FUNCTION nextid( CREATE OR REPLACE FUNCTION nextid(
p_AD_Sequence_ID IN INTEGER, p_AD_Sequence_ID IN INTEGER,
p_System IN VARCHAR, p_System IN VARCHAR,
o_NextID OUT INTEGER o_NextID OUT INTEGER
@ -37,16 +37,7 @@ BEGIN
WHERE AD_Sequence_ID=p_AD_Sequence_ID; WHERE AD_Sequence_ID=p_AD_Sequence_ID;
ELSE ELSE
BEGIN Isnativeseqon := get_Sysconfig('SYSTEM_NATIVE_SEQUENCE','N',0,0);
SELECT Value
INTO Isnativeseqon
FROM AD_SYSCONFIG
WHERE Name ='SYSTEM_NATIVE_SEQUENCE';
EXCEPTION
WHEN NO_DATA_FOUND THEN
Isnativeseqon:= 'N';
END;
IF Isnativeseqon = 'Y' THEN IF Isnativeseqon = 'Y' THEN
SELECT Name SELECT Name
INTO tablename INTO tablename
@ -74,5 +65,3 @@ END;
$body$ LANGUAGE plpgsql; $body$ LANGUAGE plpgsql;

View File

@ -16,15 +16,9 @@ CREATE OR REPLACE PROCEDURE nextID
* Title: Get Next ID - no Commit * Title: Get Next ID - no Commit
* Description: * Description:
* Test via * Test via
DECLARE
v_NextID NUMBER;
BEGIN
nextID(2, 'Y', v_NextID);
DBMS_OUTPUT.PUT_LINE(v_NextID);
END;
* *
************************************************************************/ ************************************************************************/
As AS
Isnativeseqon NVARCHAR2(1); Isnativeseqon NVARCHAR2(1);
Tablename Nvarchar2(60); Tablename Nvarchar2(60);
sqlcmd VARCHAR2(200); sqlcmd VARCHAR2(200);
@ -43,23 +37,13 @@ BEGIN
WHERE AD_Sequence_ID=p_AD_Sequence_ID; WHERE AD_Sequence_ID=p_AD_Sequence_ID;
ELSE ELSE
BEGIN Isnativeseqon := get_Sysconfig('SYSTEM_NATIVE_SEQUENCE','N',0,0);
SELECT Value
Into Isnativeseqon
From Ad_Sysconfig
Where Name ='SYSTEM_NATIVE_SEQUENCE';
EXCEPTION
WHEN NO_DATA_FOUND THEN
Isnativeseqon:= 'N';
END;
IF Isnativeseqon = 'Y' THEN IF Isnativeseqon = 'Y' THEN
Select Name SELECT Name
INTO tablename INTO tablename
From Ad_Sequence FROM Ad_Sequence
Where Ad_Sequence_Id=P_Ad_Sequence_Id WHERE Ad_Sequence_Id=P_Ad_Sequence_Id;
And Istableid = 'Y';
-- --
Sqlcmd := 'SELECT '||Tablename||'_SQ.Nextval FROM DUAL'; Sqlcmd := 'SELECT '||Tablename||'_SQ.Nextval FROM DUAL';
-- --
@ -73,9 +57,9 @@ BEGIN
WHERE AD_Sequence_ID=p_AD_Sequence_ID WHERE AD_Sequence_ID=p_AD_Sequence_ID
FOR UPDATE OF CurrentNext; FOR UPDATE OF CurrentNext;
-- --
Update Ad_Sequence UPDATE Ad_Sequence
Set Currentnext = Currentnext + Incrementno SET Currentnext = Currentnext + Incrementno
Where Ad_Sequence_Id=P_Ad_Sequence_Id; WHERE Ad_Sequence_Id=P_Ad_Sequence_Id;
-- --
END IF; END IF;
END IF; END IF;
@ -85,5 +69,19 @@ EXCEPTION
DBMS_OUTPUT.PUT_LINE(SQLERRM); DBMS_OUTPUT.PUT_LINE(SQLERRM);
END nextID; END nextID;
/ /
SELECT register_migration_script('921_IDEMPIERE-422_NativeSequence.sql') FROM dual;
DROP SEQUENCE ad_error_seq
;
DROP SEQUENCE ad_pinstance_seq
;
DROP SEQUENCE t_spool_seq
;
DROP SEQUENCE w_basket_seq
;
SELECT register_migration_script('921_IDEMPIERE-422_NativeSequence.sql') FROM dual
;

View File

@ -1,4 +1,4 @@
CREATE OR REPLACE FUNCTION nextid( CREATE OR REPLACE FUNCTION nextid(
p_AD_Sequence_ID IN INTEGER, p_AD_Sequence_ID IN INTEGER,
p_System IN VARCHAR, p_System IN VARCHAR,
o_NextID OUT INTEGER o_NextID OUT INTEGER
@ -37,16 +37,7 @@ BEGIN
WHERE AD_Sequence_ID=p_AD_Sequence_ID; WHERE AD_Sequence_ID=p_AD_Sequence_ID;
ELSE ELSE
BEGIN Isnativeseqon := get_Sysconfig('SYSTEM_NATIVE_SEQUENCE','N',0,0);
SELECT Value
INTO Isnativeseqon
FROM AD_SYSCONFIG
WHERE Name ='SYSTEM_NATIVE_SEQUENCE';
EXCEPTION
WHEN NO_DATA_FOUND THEN
Isnativeseqon:= 'N';
END;
IF Isnativeseqon = 'Y' THEN IF Isnativeseqon = 'Y' THEN
SELECT Name SELECT Name
INTO tablename INTO tablename
@ -71,8 +62,21 @@ EXCEPTION
WHEN OTHERS THEN WHEN OTHERS THEN
RAISE NOTICE '%',SQLERRM; RAISE NOTICE '%',SQLERRM;
END; END;
$body$ LANGUAGE plpgsql; $body$ LANGUAGE plpgsql;
DROP SEQUENCE ad_error_seq
;
DROP SEQUENCE ad_pinstance_seq
;
DROP SEQUENCE t_spool_seq
;
DROP SEQUENCE w_basket_seq
;
SELECT register_migration_script('921_IDEMPIERE-422_NativeSequence.sql') FROM dual SELECT register_migration_script('921_IDEMPIERE-422_NativeSequence.sql') FROM dual
; ;

View File

@ -40,26 +40,17 @@ BEGIN
DBMS_OUTPUT.PUT_LINE ('Table not found'); DBMS_OUTPUT.PUT_LINE ('Table not found');
DBMS_OUTPUT.PUT_LINE (cmdsys); DBMS_OUTPUT.PUT_LINE (cmdsys);
GOTO next_iteration; GOTO next_iteration;
End; END;
BEGIN
SELECT Value
Into Isnativeseqon
From Ad_Sysconfig
Where Name ='SYSTEM_NATIVE_SEQUENCE';
Exception
When NO_DATA_FOUND Then
Isnativeseqon :='N';
End;
Isnativeseqon := get_Sysconfig('SYSTEM_NATIVE_SEQUENCE','N',0,0);
IF currentnextsys IS NULL IF currentnextsys IS NULL
THEN THEN
currentnextsys := 0; currentnextsys := 0;
END IF; END IF;
SELECT DECODE (SIGN (currentnextsys - 50000), SELECT DECODE (SIGN (currentnextsys - 200000),
-1, 50000, -1, 200000,
NVL (currentnextsys + 1, 50000) NVL (currentnextsys + 1, 200000)
) )
INTO currentnextsys INTO currentnextsys
FROM DUAL; FROM DUAL;

View File

@ -1,4 +1,4 @@
CREATE OR REPLACE FUNCTION update_sequences() RETURNS void as $func$ CREATE OR REPLACE FUNCTION update_sequences() RETURNS void as $func$
-- TODO: Currently not inserting new sequences -- TODO: Currently not inserting new sequences
DECLARE DECLARE
cmdsys VARCHAR (1000); cmdsys VARCHAR (1000);
@ -42,25 +42,15 @@ BEGIN
END; END;
IF ok THEN IF ok THEN
isnativeseqon := get_Sysconfig('SYSTEM_NATIVE_SEQUENCE','N',0,0);
BEGIN
SELECT Value
INTO isnativeseqon
FROM AD_SYSCONFIG
WHERE Name ='SYSTEM_NATIVE_SEQUENCE';
EXCEPTION
WHEN NO_DATA_FOUND THEN
isnativeseqon:= 'N';
END;
IF currentnextsys IS NULL IF currentnextsys IS NULL
THEN THEN
currentnextsys := 0; currentnextsys := 0;
END IF; END IF;
SELECT INTO currentnextsys CASE SIGN (currentnextsys - 50000) SELECT INTO currentnextsys CASE SIGN (currentnextsys - 200000)
WHEN -1 THEN 50000 WHEN -1 THEN 200000
ELSE coalesce (currentnextsys + 1, 50000) ELSE coalesce (currentnextsys + 1, 200000)
END; END;
cmdnosys := cmdnosys :=
@ -116,10 +106,8 @@ BEGIN
EXECUTE cmdupd; EXECUTE cmdupd;
END IF; END IF;
IF currentseq < currentnext AND isnativeseqon ='Y' THEN IF currentseq < currentnext AND isnativeseqon ='Y' THEN
--RAISE NOTICE 'currentseq % ,currentnext %',currentseq,currentnext;
WHILE NOT currentseq >= (currentnext-1) LOOP WHILE NOT currentseq >= (currentnext-1) LOOP
EXECUTE 'SELECT nextval('''||trim(r.tablename)||'_sq'''||')' INTO currentseq; EXECUTE 'SELECT nextval('''||trim(r.tablename)||'_sq'''||')' INTO currentseq;
--RAISE NOTICE 'currentseq % ,currentnext %',currentseq,currentnext;
END LOOP; END LOOP;
END IF; END IF;
END IF; END IF;

View File

@ -117,7 +117,6 @@ public class SequenceCheck extends SvrProcess
} }
else else
{ {
rs.close();
throw new Exception ("Error creating Table Sequence for " + tableName); throw new Exception ("Error creating Table Sequence for " + tableName);
} }
} }
@ -213,6 +212,10 @@ public class SequenceCheck extends SvrProcess
while (rs.next()) while (rs.next())
{ {
MSequence seq = new MSequence (ctx, rs, trxName); MSequence seq = new MSequence (ctx, rs, trxName);
/* NOTE: When using native sequences - every time the sequence check process is run
* a sequence number is lost on all sequences - because with native sequences
* reading the sequence consumes a number
*/
String tableValidation = seq.validateTableIDValue(); String tableValidation = seq.validateTableIDValue();
if (tableValidation != null) { if (tableValidation != null) {
if (sp != null) if (sp != null)
@ -225,17 +228,13 @@ public class SequenceCheck extends SvrProcess
else else
s_log.severe("Not updated: " + seq); s_log.severe("Not updated: " + seq);
} }
// else if (CLogMgt.isLevel(6))
// log.fine("checkTableID - skipped " + tableName);
} }
rs.close();
pstmt.close();
pstmt = null;
} }
catch (Exception e) catch (Exception e)
{ {
s_log.log(Level.SEVERE, sql, e); s_log.log(Level.SEVERE, sql, e);
}finally }
finally
{ {
DB.close(rs, pstmt); DB.close(rs, pstmt);
rs = null; pstmt = null; rs = null; pstmt = null;

View File

@ -54,7 +54,7 @@ public class MSequence extends X_AD_Sequence
/** /**
* *
*/ */
private static final long serialVersionUID = -1204207754819125876L; private static final long serialVersionUID = -631878634759124313L;
/** Log Level for Next ID Call */ /** Log Level for Next ID Call */
private static final Level LOGLEVEL = Level.ALL; private static final Level LOGLEVEL = Level.ALL;
@ -63,12 +63,6 @@ public class MSequence extends X_AD_Sequence
private static final String NoYearNorMonth = "-"; private static final String NoYearNorMonth = "-";
@Deprecated
public static int getNextID (int AD_Client_ID, String TableName)
{
return getNextID(AD_Client_ID, TableName, null);
}
/** /**
* *
* Get next number for Key column = 0 is Error. * Get next number for Key column = 0 is Error.
@ -76,207 +70,14 @@ public class MSequence extends X_AD_Sequence
* @param TableName table name * @param TableName table name
* @param trxName deprecated. * @param trxName deprecated.
* @return next no or (-1=not found, -2=error) * @return next no or (-1=not found, -2=error)
*
* WARNING!! This method doesn't take into account the native sequence setting, it always read from table AD_Sequence
* must be used JUST for the method Enable Native Sequence
*
* @deprecated
*/ */
public static int getNextID (int AD_Client_ID, String TableName, String trxName) public static int getNextID (int AD_Client_ID, String TableName, String trxName)
{ {
if (TableName == null || TableName.length() == 0) if (TableName == null || TableName.length() == 0)
throw new IllegalArgumentException("TableName missing"); throw new IllegalArgumentException("TableName missing");
int retValue = -1; MSequence seq = MSequence.get (Env.getCtx(), TableName, trxName, true);
return seq.getNextID();
// Check AdempiereSys
boolean adempiereSys = false;
if (Ini.isClient())
{
adempiereSys = Ini.isPropertyBool(Ini.P_ADEMPIERESYS);
}
else
{
String sysProperty = Env.getCtx().getProperty("AdempiereSys", "N");
adempiereSys = "y".equalsIgnoreCase(sysProperty) || "true".equalsIgnoreCase(sysProperty);
}
if (adempiereSys && AD_Client_ID > 11)
adempiereSys = false;
//
if (CLogMgt.isLevel(LOGLEVEL))
s_log.log(LOGLEVEL, TableName + " - AdempiereSys=" + adempiereSys + " [" + trxName + "]");
//begin vpj-cd e-evolution 09/02/2005 PostgreSQL
String selectSQL = null;
if (DB.isOracle() == false)
{
selectSQL = "SELECT CurrentNext, CurrentNextSys, IncrementNo, AD_Sequence_ID "
+ "FROM AD_Sequence "
+ "WHERE Name=?"
+ " AND IsActive='Y' AND IsTableID='Y' AND IsAutoSequence='Y' "
+ " FOR UPDATE OF AD_Sequence ";
}
else
{
selectSQL = "SELECT CurrentNext, CurrentNextSys, IncrementNo, AD_Sequence_ID "
+ "FROM AD_Sequence "
+ "WHERE Name=?"
+ " AND IsActive='Y' AND IsTableID='Y' AND IsAutoSequence='Y' ";
}
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
for (int i = 0; i < 3; i++)
{
try
{
conn = DB.getConnectionID();
// Error
if (conn == null)
return -1;
pstmt = conn.prepareStatement(selectSQL,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_UPDATABLE);
pstmt.setString(1, TableName);
//
//postgresql use special syntax instead of the setQueryTimeout method
if (DB.isPostgreSQL())
{
Statement timeoutStatement = conn.createStatement();
timeoutStatement.execute("SET LOCAL statement_timeout TO " + ( QUERY_TIME_OUT * 1000 ));
}
else if (DB.getDatabase().isQueryTimeoutSupported())
{
pstmt.setQueryTimeout(QUERY_TIME_OUT);
}
rs = pstmt.executeQuery();
if (CLogMgt.isLevelFinest())
s_log.finest("AC=" + conn.getAutoCommit() + ", RO=" + conn.isReadOnly()
+ " - Isolation=" + conn.getTransactionIsolation() + "(" + Connection.TRANSACTION_READ_COMMITTED
+ ") - RSType=" + pstmt.getResultSetType() + "(" + ResultSet.TYPE_SCROLL_SENSITIVE
+ "), RSConcur=" + pstmt.getResultSetConcurrency() + "(" + ResultSet.CONCUR_UPDATABLE
+ ")");
if (rs.next())
{
// Get the table
MTable table = MTable.get(Env.getCtx(), TableName);
int AD_Sequence_ID = rs.getInt(4);
boolean gotFromHTTP = false;
// If maintaining official dictionary try to get the ID from http official server
if (adempiereSys) {
String isUseCentralizedID = MSysConfig.getValue(MSysConfig.DICTIONARY_ID_USE_CENTRALIZED_ID, "Y"); // defaults to Y
if ( ( ! isUseCentralizedID.equals("N") ) && ( ! isExceptionCentralized(TableName) ) ) {
// get ID from http site
retValue = getNextOfficialID_HTTP(TableName);
if (retValue > 0) {
PreparedStatement updateSQL;
updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNextSys = ? + 1 WHERE AD_Sequence_ID = ?");
try {
updateSQL.setInt(1, retValue);
updateSQL.setInt(2, AD_Sequence_ID);
updateSQL.executeUpdate();
} finally {
updateSQL.close();
}
}
gotFromHTTP = true;
}
}
boolean queryProjectServer = false;
if (table.getColumn("EntityType") != null)
queryProjectServer = true;
if (!queryProjectServer && MSequence.Table_Name.equalsIgnoreCase(TableName))
queryProjectServer = true;
// If not official dictionary try to get the ID from http custom server - if configured
if (queryProjectServer && ( ! adempiereSys ) && ( ! isExceptionCentralized(TableName) ) ) {
String isUseProjectCentralizedID = MSysConfig.getValue(MSysConfig.PROJECT_ID_USE_CENTRALIZED_ID, "N"); // defaults to N
if (isUseProjectCentralizedID.equals("Y")) {
// get ID from http site
retValue = getNextProjectID_HTTP(TableName);
if (retValue > 0) {
PreparedStatement updateSQL;
updateSQL = conn.prepareStatement("UPDATE AD_Sequence SET CurrentNext = GREATEST(CurrentNext, ? + 1) WHERE AD_Sequence_ID = ?");
try {
updateSQL.setInt(1, retValue);
updateSQL.setInt(2, AD_Sequence_ID);
updateSQL.executeUpdate();
} finally {
updateSQL.close();
}
}
gotFromHTTP = true;
}
}
if (! gotFromHTTP) {
PreparedStatement updateSQL;
int incrementNo = rs.getInt(3);
if (adempiereSys) {
updateSQL = conn
.prepareStatement("UPDATE AD_Sequence SET CurrentNextSys = CurrentNextSys + ? WHERE AD_Sequence_ID = ?");
retValue = rs.getInt(2);
} else {
updateSQL = conn
.prepareStatement("UPDATE AD_Sequence SET CurrentNext = CurrentNext + ? WHERE AD_Sequence_ID = ?");
retValue = rs.getInt(1);
}
try {
updateSQL.setInt(1, incrementNo);
updateSQL.setInt(2, AD_Sequence_ID);
updateSQL.executeUpdate();
} finally {
updateSQL.close();
}
}
//if (trx == null)
conn.commit();
}
else
s_log.severe ("No record found - " + TableName);
//
break; // EXIT
}
catch (Exception e)
{
s_log.log(Level.SEVERE, TableName + " - " + e.getMessage(), e);
try
{
if (conn != null)
conn.rollback();
} catch (SQLException e1) { }
}
finally
{
DB.close(rs, pstmt);
pstmt = null;
rs = null;
if (conn != null)
{
try {
conn.close();
} catch (SQLException e) {}
conn = null;
}
}
Thread.yield(); // give it time
}
//s_log.finest (retValue + " - Table=" + TableName + " [" + trx + "]");
return retValue;
} // getNextID } // getNextID
/************************************************************************** /**************************************************************************
@ -690,7 +491,7 @@ public class MSequence extends X_AD_Sequence
if (tableID && SYSTEM_NATIVE_SEQUENCE) if (tableID && SYSTEM_NATIVE_SEQUENCE)
{ {
int next_id = MSequence.getNextID(Env.getAD_Client_ID(ctx), TableName, trxName); int next_id = DB.getSQLValue(trxName, "SELECT CurrentNext FROM AD_Sequence WHERE Name=? AND IsActive='Y' AND IsTableID='Y' AND IsAutoSequence='Y'", TableName);
if (next_id == -1) if (next_id == -1)
{ {
MSequence seq = new MSequence (ctx, 0, trxName); MSequence seq = new MSequence (ctx, 0, trxName);
@ -701,7 +502,7 @@ public class MSequence extends X_AD_Sequence
seq.saveEx(); seq.saveEx();
next_id = INIT_NO; next_id = INIT_NO;
} }
if (! CConnection.get().getDatabase().createSequence(TableName+"_SQ", 1, 0 , 99999999, next_id, trxName)) if (! CConnection.get().getDatabase().createSequence(TableName+"_SQ", 1, INIT_NO, Integer.MAX_VALUE, next_id, trxName))
return false; return false;
return true; return true;
@ -881,7 +682,9 @@ public class MSequence extends X_AD_Sequence
public int getNextID() public int getNextID()
{ {
int retValue = getCurrentNext(); int retValue = getCurrentNext();
if (! (MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false) && isTableID())) {
setCurrentNext(retValue + getIncrementNo()); setCurrentNext(retValue + getIncrementNo());
}
return retValue; return retValue;
} // getNextNo } // getNextNo
@ -932,7 +735,7 @@ public class MSequence extends X_AD_Sequence
+ " WHERE " + tableName + "_ID < " + INIT_NO; + " WHERE " + tableName + "_ID < " + INIT_NO;
int maxTableSysID = DB.getSQLValue(null, sql); int maxTableSysID = DB.getSQLValue(null, sql);
if (maxTableSysID <= 0) if (maxTableSysID <= 0)
maxTableSysID = INIT_SYS_NO - 1; maxTableSysID = INIT_SYS_NO;
int currentNextSysValue = getCurrentNextSys(); int currentNextSysValue = getCurrentNextSys();
if (currentNextSysValue < maxTableSysID){ if (currentNextSysValue < maxTableSysID){
setCurrentNextSys(maxTableSysID); setCurrentNextSys(maxTableSysID);
@ -964,8 +767,10 @@ public class MSequence extends X_AD_Sequence
@Override @Override
public void setCurrentNext(int CurrentNext) { public void setCurrentNext(int CurrentNext) {
if (MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false) && isTableID()){ if (MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false) && isTableID()){
while (DB.getNextID(getAD_Client_ID(),getName(),get_TrxName()) < (CurrentNext-1)) { while (true) {
// do nothing - the while is incrementing the sequence int id = DB.getNextID(getAD_Client_ID(),getName(),get_TrxName());
if (id < 0 || id >= (CurrentNext-1))
break;
} }
}else { }else {
super.setCurrentNext(CurrentNext); super.setCurrentNext(CurrentNext);
@ -1376,10 +1181,7 @@ public class MSequence extends X_AD_Sequence
cym = sdf.format(d); cym = sdf.format(d);
} }
if (orgLevelSeq) { if (orgLevelSeq) {
String orgColumn = seq.getOrgColumn(); org = (Integer)tab.getValue(seq.getOrgColumn());
Object orgObj = tab.getValue(orgColumn);
if (orgObj != null)
org = (Integer)orgObj;
} }
String sql = "SELECT CurrentNext FROM AD_Sequence_No WHERE AD_Sequence_ID=? AND CalendarYearMonth=? AND AD_Org_ID=?"; String sql = "SELECT CurrentNext FROM AD_Sequence_No WHERE AD_Sequence_ID=? AND CalendarYearMonth=? AND AD_Org_ID=?";
currentNext = DB.getSQLValue(null, sql, AD_Sequence_ID, cym, org); currentNext = DB.getSQLValue(null, sql, AD_Sequence_ID, cym, org);

View File

@ -41,6 +41,7 @@ import org.adempiere.exceptions.DBException;
import org.compiere.Adempiere; import org.compiere.Adempiere;
import org.compiere.dbPort.Convert; import org.compiere.dbPort.Convert;
import org.compiere.dbPort.Convert_Oracle; import org.compiere.dbPort.Convert_Oracle;
import org.compiere.model.MSysConfig;
import org.compiere.model.PO; import org.compiere.model.PO;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.DB; import org.compiere.util.DB;
@ -1158,13 +1159,35 @@ public class DB_Oracle implements AdempiereDatabase
public boolean createSequence(String name , int increment , int minvalue , int maxvalue ,int start , String trxName) public boolean createSequence(String name , int increment , int minvalue , int maxvalue ,int start , String trxName)
{ {
int no = DB.executeUpdate("DROP SEQUENCE "+name.toUpperCase(), trxName); // Check if Sequence exists
StringBuilder msgDB = new StringBuilder("CREATE SEQUENCE ").append(name.toUpperCase()) final int cnt = DB.getSQLValueEx(trxName, "SELECT COUNT(*) FROM USER_SEQUENCES WHERE UPPER(sequence_name)=?", name.toUpperCase());
.append(" MINVALUE ").append(minvalue) final int no;
.append(" MAXVALUE ").append(maxvalue) if (start < minvalue)
.append(" START WITH ").append(start) start = minvalue;
.append(" INCREMENT BY ").append(increment).append(" CACHE 20"); //
no = DB.executeUpdateEx(msgDB.toString(), trxName); // New Sequence
if (cnt == 0)
{
no = DB.executeUpdate("CREATE SEQUENCE "+name.toUpperCase()
+ " MINVALUE " + minvalue
+ " MAXVALUE " + maxvalue
+ " START WITH " + start
+ " INCREMENT BY " + increment
+ " CACHE 20", trxName);
}
//
// Already existing sequence => ALTER
else
{
no = DB.executeUpdate("ALTER SEQUENCE "+name.toUpperCase()
+ " INCREMENT BY " + increment
// + " MINVALUE " + minvalue // ORA-04007
+ " MAXVALUE " + maxvalue
+ " CACHE 20", trxName);
while (DB.getSQLValue(trxName, "SELECT " + name.toUpperCase() + ".NEXTVAL FROM DUAL") < start) {
// do nothing - the while is incrementing the sequence
}
}
if(no == -1 ) if(no == -1 )
return false; return false;
else else

View File

@ -854,25 +854,27 @@ public class DB_PostgreSQL implements AdempiereDatabase
// Check if Sequence exists // Check if Sequence exists
final int cnt = DB.getSQLValueEx(trxName, "SELECT COUNT(*) FROM pg_class WHERE UPPER(relname)=? AND relkind='S'", name.toUpperCase()); final int cnt = DB.getSQLValueEx(trxName, "SELECT COUNT(*) FROM pg_class WHERE UPPER(relname)=? AND relkind='S'", name.toUpperCase());
final int no; final int no;
if (start < minvalue)
start = minvalue;
// //
// New Sequence // New Sequence
if (cnt == 0) if (cnt == 0)
{ {
no = DB.executeUpdate("CREATE SEQUENCE "+name.toUpperCase() no = DB.executeUpdate("CREATE SEQUENCE "+name.toUpperCase()
+ " INCREMENT " + increment + " INCREMENT BY " + increment
+ " MINVALUE " + minvalue + " MINVALUE " + minvalue
+ " MAXVALUE " + maxvalue + " MAXVALUE " + maxvalue
+ " START " + start , trxName); + " START WITH " + start, trxName);
} }
// //
// Already existing sequence => ALTER // Already existing sequence => ALTER
else else
{ {
no = DB.executeUpdate("ALTER SEQUENCE "+name.toUpperCase() no = DB.executeUpdate("ALTER SEQUENCE "+name.toUpperCase()
+ " INCREMENT " + increment + " INCREMENT BY " + increment
+ " MINVALUE " + minvalue + " MINVALUE " + minvalue
+ " MAXVALUE " + maxvalue + " MAXVALUE " + maxvalue
+ " RESTART " + start , trxName); + " RESTART WITH " + start, trxName);
} }
if(no == -1 ) if(no == -1 )
return false; return false;

View File

@ -80,32 +80,6 @@ public class Convert_PostgreSQL extends Convert_SQL92 {
/** Vector to save previous values of quoted strings **/ /** Vector to save previous values of quoted strings **/
Vector<String> retVars = new Vector<String>(); Vector<String> retVars = new Vector<String>();
//Validate Next ID Function and use Native Sequence if the functionality is active
int found_next_fuction = sqlStatement.toUpperCase().indexOf("NEXTIDFUNC(");
if(found_next_fuction<=0)
found_next_fuction = sqlStatement.toUpperCase().indexOf("NEXTID(");
if(found_next_fuction > 0)
{
boolean SYSTEM_NATIVE_SEQUENCE = MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false);
boolean adempiereSys = Ini.isPropertyBool(Ini.P_ADEMPIERESYS);
if(SYSTEM_NATIVE_SEQUENCE && !adempiereSys)
{
String function_before = sqlStatement.substring(0,found_next_fuction);
String function_start = sqlStatement.substring(found_next_fuction);
String function_after = function_start.substring(function_start.indexOf(")") + 1);
String sequence = function_start.substring(function_start.indexOf("(") + 1, function_start.indexOf(","));
int separator = function_start.indexOf("'") + 1;
String next = function_start.substring(separator);
String system = next.substring(0,next.indexOf("'"));
if (system.equals("N"))
{
String seq_name = DB.getSQLValueString(null, "SELECT Name FROM AD_Sequence WHERE AD_Sequence_ID=" + sequence);
sqlStatement = function_before + " nextval('"+seq_name+ "_seq') " + function_after;
}
}
}
String statement = replaceQuotedStrings(sqlStatement, retVars); String statement = replaceQuotedStrings(sqlStatement, retVars);
statement = convertWithConvertMap(statement); statement = convertWithConvertMap(statement);
statement = statement.replace(DB_PostgreSQL.NATIVE_MARKER, ""); statement = statement.replace(DB_PostgreSQL.NATIVE_MARKER, "");