From 595fda5ef4a42addbf1bce354a2c9016d58d83ec Mon Sep 17 00:00:00 2001 From: Carlos Ruiz Date: Fri, 5 Oct 2012 19:03:57 -0500 Subject: [PATCH] IDEMPIERE-422 Complete Native Sequence feature / peer review and tests --- db/ddlutils/oracle/procedures/nextID.sql | 158 ++++++------ db/ddlutils/postgresql/functions/nextID.sql | 15 +- .../921_IDEMPIERE-422_NativeSequence.sql | 50 ++-- .../921_IDEMPIERE-422_NativeSequence.sql | 26 +- .../oracle/03_update_sequences.sql | 19 +- .../postgresql/03_update_sequences.sql | 22 +- .../org/compiere/process/SequenceCheck.java | 17 +- .../src/org/compiere/model/MSequence.java | 228 ++---------------- .../src/org/compiere/db/DB_Oracle.java | 37 ++- .../src/org/compiere/db/DB_PostgreSQL.java | 10 +- .../compiere/dbPort/Convert_PostgreSQL.java | 26 -- 11 files changed, 181 insertions(+), 427 deletions(-) diff --git a/db/ddlutils/oracle/procedures/nextID.sql b/db/ddlutils/oracle/procedures/nextID.sql index eda4003eff..c241509cdb 100644 --- a/db/ddlutils/oracle/procedures/nextID.sql +++ b/db/ddlutils/oracle/procedures/nextID.sql @@ -1,87 +1,71 @@ -CREATE OR REPLACE PROCEDURE nextID -( - p_AD_Sequence_ID IN NUMBER, - p_System IN CHAR, - o_NextID OUT NUMBER -) -/************************************************************************* - * The contents of this file are subject to the Adempiere License. You may - * obtain a copy of the License at http://www.adempiere.org/license.html - * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either - * express or implied. See the License for details. Code: Adempiere ERP+CRM - * Copyright (C) 1999-2005 Jorg Janke, ComPiere, Inc. All Rights Reserved. - ************************************************************************* - * $Id: nextID.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ - *** - * Title: Get Next ID - no Commit - * Description: - * Test via -DECLARE - v_NextID NUMBER; -BEGIN - nextID(2, 'Y', v_NextID); - DBMS_OUTPUT.PUT_LINE(v_NextID); -END; - * - ************************************************************************/ -As -Isnativeseqon NVARCHAR2(1); -Tablename Nvarchar2(60); -sqlcmd VARCHAR2(200); -BEGIN - - - IF (p_System = 'Y') THEN - SELECT CurrentNextSys - INTO o_NextID - FROM AD_Sequence - WHERE AD_Sequence_ID=p_AD_Sequence_ID - FOR UPDATE OF CurrentNextSys; - -- - UPDATE AD_Sequence - SET CurrentNextSys = CurrentNextSys + IncrementNo - WHERE AD_Sequence_ID=p_AD_Sequence_ID; - ELSE - - BEGIN - 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 - - Select Name - INTO tablename - From Ad_Sequence - Where Ad_Sequence_Id=P_Ad_Sequence_Id - And Istableid = 'Y'; - -- - Sqlcmd := 'SELECT '||Tablename||'_SQ.Nextval FROM DUAL'; - -- - Execute Immediate Sqlcmd Into O_Nextid; - -- - ELSE - - SELECT CurrentNext - INTO o_NextID - FROM AD_Sequence - WHERE AD_Sequence_ID=p_AD_Sequence_ID - FOR UPDATE OF CurrentNext; - -- - Update Ad_Sequence - Set Currentnext = Currentnext + Incrementno - Where Ad_Sequence_Id=P_Ad_Sequence_Id; - -- - END IF; - END IF; - -- -EXCEPTION - WHEN OTHERS THEN - DBMS_OUTPUT.PUT_LINE(SQLERRM); -END nextID; -/ +CREATE OR REPLACE PROCEDURE nextID +( + p_AD_Sequence_ID IN NUMBER, + p_System IN CHAR, + o_NextID OUT NUMBER +) +/************************************************************************* + * The contents of this file are subject to the Adempiere License. You may + * obtain a copy of the License at http://www.adempiere.org/license.html + * Software is on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either + * express or implied. See the License for details. Code: Adempiere ERP+CRM + * Copyright (C) 1999-2005 Jorg Janke, ComPiere, Inc. All Rights Reserved. + ************************************************************************* + * $Id: nextID.sql,v 1.1 2006/04/21 17:51:58 jjanke Exp $ + *** + * Title: Get Next ID - no Commit + * Description: + * Test via + * + ************************************************************************/ +AS +Isnativeseqon NVARCHAR2(1); +Tablename Nvarchar2(60); +sqlcmd VARCHAR2(200); +BEGIN + + + IF (p_System = 'Y') THEN + SELECT CurrentNextSys + INTO o_NextID + FROM AD_Sequence + WHERE AD_Sequence_ID=p_AD_Sequence_ID + FOR UPDATE OF CurrentNextSys; + -- + UPDATE AD_Sequence + SET CurrentNextSys = CurrentNextSys + IncrementNo + WHERE AD_Sequence_ID=p_AD_Sequence_ID; + ELSE + + Isnativeseqon := get_Sysconfig('SYSTEM_NATIVE_SEQUENCE','N',0,0); + IF Isnativeseqon = 'Y' THEN + + SELECT Name + INTO tablename + FROM Ad_Sequence + WHERE Ad_Sequence_Id=P_Ad_Sequence_Id; + -- + Sqlcmd := 'SELECT '||Tablename||'_SQ.Nextval FROM DUAL'; + -- + Execute Immediate Sqlcmd Into O_Nextid; + -- + ELSE + + SELECT CurrentNext + INTO o_NextID + FROM AD_Sequence + WHERE AD_Sequence_ID=p_AD_Sequence_ID + FOR UPDATE OF CurrentNext; + -- + UPDATE Ad_Sequence + SET Currentnext = Currentnext + Incrementno + WHERE Ad_Sequence_Id=P_Ad_Sequence_Id; + -- + END IF; + END IF; + -- +EXCEPTION + WHEN OTHERS THEN + DBMS_OUTPUT.PUT_LINE(SQLERRM); +END nextID; +/ diff --git a/db/ddlutils/postgresql/functions/nextID.sql b/db/ddlutils/postgresql/functions/nextID.sql index a916ba4d2b..2785d1c8d8 100644 --- a/db/ddlutils/postgresql/functions/nextID.sql +++ b/db/ddlutils/postgresql/functions/nextID.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION nextid( +CREATE OR REPLACE FUNCTION nextid( p_AD_Sequence_ID IN INTEGER, p_System IN VARCHAR, o_NextID OUT INTEGER @@ -37,16 +37,7 @@ BEGIN WHERE AD_Sequence_ID=p_AD_Sequence_ID; ELSE - 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 Isnativeseqon = 'Y' THEN SELECT Name INTO tablename @@ -74,5 +65,3 @@ END; $body$ LANGUAGE plpgsql; - - diff --git a/migration/360lts-release/oracle/921_IDEMPIERE-422_NativeSequence.sql b/migration/360lts-release/oracle/921_IDEMPIERE-422_NativeSequence.sql index 01f75cab6e..22ad2f3649 100644 --- a/migration/360lts-release/oracle/921_IDEMPIERE-422_NativeSequence.sql +++ b/migration/360lts-release/oracle/921_IDEMPIERE-422_NativeSequence.sql @@ -1,6 +1,6 @@ CREATE OR REPLACE PROCEDURE nextID ( - p_AD_Sequence_ID IN NUMBER, + p_AD_Sequence_ID IN NUMBER, p_System IN CHAR, o_NextID OUT NUMBER ) @@ -16,15 +16,9 @@ CREATE OR REPLACE PROCEDURE nextID * Title: Get Next ID - no Commit * Description: * Test via -DECLARE - v_NextID NUMBER; -BEGIN - nextID(2, 'Y', v_NextID); - DBMS_OUTPUT.PUT_LINE(v_NextID); -END; * ************************************************************************/ -As +AS Isnativeseqon NVARCHAR2(1); Tablename Nvarchar2(60); sqlcmd VARCHAR2(200); @@ -43,23 +37,13 @@ BEGIN WHERE AD_Sequence_ID=p_AD_Sequence_ID; ELSE - 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 Isnativeseqon = 'Y' THEN - Select Name + SELECT Name INTO tablename - From Ad_Sequence - Where Ad_Sequence_Id=P_Ad_Sequence_Id - And Istableid = 'Y'; + FROM Ad_Sequence + WHERE Ad_Sequence_Id=P_Ad_Sequence_Id; -- Sqlcmd := 'SELECT '||Tablename||'_SQ.Nextval FROM DUAL'; -- @@ -73,9 +57,9 @@ BEGIN WHERE AD_Sequence_ID=p_AD_Sequence_ID FOR UPDATE OF CurrentNext; -- - Update Ad_Sequence - Set Currentnext = Currentnext + Incrementno - Where Ad_Sequence_Id=P_Ad_Sequence_Id; + UPDATE Ad_Sequence + SET Currentnext = Currentnext + Incrementno + WHERE Ad_Sequence_Id=P_Ad_Sequence_Id; -- END IF; END IF; @@ -85,5 +69,19 @@ EXCEPTION DBMS_OUTPUT.PUT_LINE(SQLERRM); 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 +; diff --git a/migration/360lts-release/postgresql/921_IDEMPIERE-422_NativeSequence.sql b/migration/360lts-release/postgresql/921_IDEMPIERE-422_NativeSequence.sql index 2a47b95d44..d833929616 100644 --- a/migration/360lts-release/postgresql/921_IDEMPIERE-422_NativeSequence.sql +++ b/migration/360lts-release/postgresql/921_IDEMPIERE-422_NativeSequence.sql @@ -1,4 +1,4 @@ -CREATE OR REPLACE FUNCTION nextid( +CREATE OR REPLACE FUNCTION nextid( p_AD_Sequence_ID IN INTEGER, p_System IN VARCHAR, o_NextID OUT INTEGER @@ -37,16 +37,7 @@ BEGIN WHERE AD_Sequence_ID=p_AD_Sequence_ID; ELSE - 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 Isnativeseqon = 'Y' THEN SELECT Name INTO tablename @@ -71,8 +62,21 @@ EXCEPTION WHEN OTHERS THEN RAISE NOTICE '%',SQLERRM; END; + $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 ; diff --git a/migration/processes_post_migration/oracle/03_update_sequences.sql b/migration/processes_post_migration/oracle/03_update_sequences.sql index 4ba7274544..061710f3d9 100644 --- a/migration/processes_post_migration/oracle/03_update_sequences.sql +++ b/migration/processes_post_migration/oracle/03_update_sequences.sql @@ -40,26 +40,17 @@ BEGIN DBMS_OUTPUT.PUT_LINE ('Table not found'); DBMS_OUTPUT.PUT_LINE (cmdsys); 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 THEN currentnextsys := 0; END IF; - SELECT DECODE (SIGN (currentnextsys - 50000), - -1, 50000, - NVL (currentnextsys + 1, 50000) + SELECT DECODE (SIGN (currentnextsys - 200000), + -1, 200000, + NVL (currentnextsys + 1, 200000) ) INTO currentnextsys FROM DUAL; diff --git a/migration/processes_post_migration/postgresql/03_update_sequences.sql b/migration/processes_post_migration/postgresql/03_update_sequences.sql index 4380cea0de..490cdae5fd 100644 --- a/migration/processes_post_migration/postgresql/03_update_sequences.sql +++ b/migration/processes_post_migration/postgresql/03_update_sequences.sql @@ -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 DECLARE cmdsys VARCHAR (1000); @@ -42,25 +42,15 @@ BEGIN END; IF ok THEN - - 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 THEN currentnextsys := 0; END IF; - SELECT INTO currentnextsys CASE SIGN (currentnextsys - 50000) - WHEN -1 THEN 50000 - ELSE coalesce (currentnextsys + 1, 50000) + SELECT INTO currentnextsys CASE SIGN (currentnextsys - 200000) + WHEN -1 THEN 200000 + ELSE coalesce (currentnextsys + 1, 200000) END; cmdnosys := @@ -116,10 +106,8 @@ BEGIN EXECUTE cmdupd; END IF; IF currentseq < currentnext AND isnativeseqon ='Y' THEN - --RAISE NOTICE 'currentseq % ,currentnext %',currentseq,currentnext; WHILE NOT currentseq >= (currentnext-1) LOOP EXECUTE 'SELECT nextval('''||trim(r.tablename)||'_sq'''||')' INTO currentseq; - --RAISE NOTICE 'currentseq % ,currentnext %',currentseq,currentnext; END LOOP; END IF; END IF; diff --git a/org.adempiere.base.process/src/org/compiere/process/SequenceCheck.java b/org.adempiere.base.process/src/org/compiere/process/SequenceCheck.java index a73dc0d99a..6083b14f84 100644 --- a/org.adempiere.base.process/src/org/compiere/process/SequenceCheck.java +++ b/org.adempiere.base.process/src/org/compiere/process/SequenceCheck.java @@ -117,7 +117,6 @@ public class SequenceCheck extends SvrProcess } else { - rs.close(); throw new Exception ("Error creating Table Sequence for " + tableName); } } @@ -213,8 +212,12 @@ public class SequenceCheck extends SvrProcess while (rs.next()) { MSequence seq = new MSequence (ctx, rs, trxName); - String tableValidation= seq.validateTableIDValue(); - if (tableValidation!=null){ + /* 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(); + if (tableValidation != null) { if (sp != null) sp.addLog(0, null, null, tableValidation); else @@ -225,17 +228,13 @@ public class SequenceCheck extends SvrProcess else 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) { s_log.log(Level.SEVERE, sql, e); - }finally + } + finally { DB.close(rs, pstmt); rs = null; pstmt = null; diff --git a/org.adempiere.base/src/org/compiere/model/MSequence.java b/org.adempiere.base/src/org/compiere/model/MSequence.java index 75c62d7201..51786e8a19 100644 --- a/org.adempiere.base/src/org/compiere/model/MSequence.java +++ b/org.adempiere.base/src/org/compiere/model/MSequence.java @@ -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 */ private static final Level LOGLEVEL = Level.ALL; @@ -62,12 +62,6 @@ public class MSequence extends X_AD_Sequence private static final int QUERY_TIME_OUT = 30; private static final String NoYearNorMonth = "-"; - - @Deprecated - public static int getNextID (int AD_Client_ID, String TableName) - { - return getNextID(AD_Client_ID, TableName, null); - } /** * @@ -76,207 +70,14 @@ public class MSequence extends X_AD_Sequence * @param TableName table name * @param trxName deprecated. * @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) { if (TableName == null || TableName.length() == 0) throw new IllegalArgumentException("TableName missing"); - int retValue = -1; - - // 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; + MSequence seq = MSequence.get (Env.getCtx(), TableName, trxName, true); + return seq.getNextID(); } // getNextID /************************************************************************** @@ -690,7 +491,7 @@ public class MSequence extends X_AD_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) { MSequence seq = new MSequence (ctx, 0, trxName); @@ -701,7 +502,7 @@ public class MSequence extends X_AD_Sequence seq.saveEx(); 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 true; @@ -881,7 +682,9 @@ public class MSequence extends X_AD_Sequence public int getNextID() { int retValue = getCurrentNext(); - setCurrentNext(retValue + getIncrementNo()); + if (! (MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false) && isTableID())) { + setCurrentNext(retValue + getIncrementNo()); + } return retValue; } // getNextNo @@ -932,7 +735,7 @@ public class MSequence extends X_AD_Sequence + " WHERE " + tableName + "_ID < " + INIT_NO; int maxTableSysID = DB.getSQLValue(null, sql); if (maxTableSysID <= 0) - maxTableSysID = INIT_SYS_NO - 1; + maxTableSysID = INIT_SYS_NO; int currentNextSysValue = getCurrentNextSys(); if (currentNextSysValue < maxTableSysID){ setCurrentNextSys(maxTableSysID); @@ -956,7 +759,7 @@ public class MSequence extends X_AD_Sequence public int getCurrentNext() { if (MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false) && isTableID()){ return DB.getNextID (getAD_Client_ID(),getName(),get_TrxName()); - }else { + } else { return super.getCurrentNext(); } } @@ -964,8 +767,10 @@ public class MSequence extends X_AD_Sequence @Override public void setCurrentNext(int CurrentNext) { if (MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false) && isTableID()){ - while (DB.getNextID(getAD_Client_ID(),getName(),get_TrxName()) < (CurrentNext-1)) { - // do nothing - the while is incrementing the sequence + while (true) { + int id = DB.getNextID(getAD_Client_ID(),getName(),get_TrxName()); + if (id < 0 || id >= (CurrentNext-1)) + break; } }else { super.setCurrentNext(CurrentNext); @@ -1376,10 +1181,7 @@ public class MSequence extends X_AD_Sequence cym = sdf.format(d); } if (orgLevelSeq) { - String orgColumn = seq.getOrgColumn(); - Object orgObj = tab.getValue(orgColumn); - if (orgObj != null) - org = (Integer)orgObj; + org = (Integer)tab.getValue(seq.getOrgColumn()); } 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); diff --git a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java index 49dffd9315..047a2bd53f 100644 --- a/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java +++ b/org.compiere.db.oracle.provider/src/org/compiere/db/DB_Oracle.java @@ -41,6 +41,7 @@ import org.adempiere.exceptions.DBException; import org.compiere.Adempiere; import org.compiere.dbPort.Convert; import org.compiere.dbPort.Convert_Oracle; +import org.compiere.model.MSysConfig; import org.compiere.model.PO; import org.compiere.util.CLogger; 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) { - int no = DB.executeUpdate("DROP SEQUENCE "+name.toUpperCase(), trxName); - StringBuilder msgDB = new StringBuilder("CREATE SEQUENCE ").append(name.toUpperCase()) - .append(" MINVALUE ").append(minvalue) - .append(" MAXVALUE ").append(maxvalue) - .append(" START WITH ").append(start) - .append(" INCREMENT BY ").append(increment).append(" CACHE 20"); - no = DB.executeUpdateEx(msgDB.toString(), trxName); + // Check if Sequence exists + final int cnt = DB.getSQLValueEx(trxName, "SELECT COUNT(*) FROM USER_SEQUENCES WHERE UPPER(sequence_name)=?", name.toUpperCase()); + final int no; + if (start < minvalue) + start = minvalue; + // + // 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 ) return false; else diff --git a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java index 0dbc1eaa99..b8979f13b1 100755 --- a/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java +++ b/org.compiere.db.postgresql.provider/src/org/compiere/db/DB_PostgreSQL.java @@ -854,25 +854,27 @@ public class DB_PostgreSQL implements AdempiereDatabase // 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 no; + if (start < minvalue) + start = minvalue; // // New Sequence if (cnt == 0) { no = DB.executeUpdate("CREATE SEQUENCE "+name.toUpperCase() - + " INCREMENT " + increment + + " INCREMENT BY " + increment + " MINVALUE " + minvalue + " MAXVALUE " + maxvalue - + " START " + start , trxName); + + " START WITH " + start, trxName); } // // Already existing sequence => ALTER else { no = DB.executeUpdate("ALTER SEQUENCE "+name.toUpperCase() - + " INCREMENT " + increment + + " INCREMENT BY " + increment + " MINVALUE " + minvalue + " MAXVALUE " + maxvalue - + " RESTART " + start , trxName); + + " RESTART WITH " + start, trxName); } if(no == -1 ) return false; diff --git a/org.compiere.db.postgresql.provider/src/org/compiere/dbPort/Convert_PostgreSQL.java b/org.compiere.db.postgresql.provider/src/org/compiere/dbPort/Convert_PostgreSQL.java index cc4aad2d1b..fb4c0d8249 100644 --- a/org.compiere.db.postgresql.provider/src/org/compiere/dbPort/Convert_PostgreSQL.java +++ b/org.compiere.db.postgresql.provider/src/org/compiere/dbPort/Convert_PostgreSQL.java @@ -80,32 +80,6 @@ public class Convert_PostgreSQL extends Convert_SQL92 { /** Vector to save previous values of quoted strings **/ Vector retVars = new Vector(); - //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); statement = convertWithConvertMap(statement); statement = statement.replace(DB_PostgreSQL.NATIVE_MARKER, "");