IDEMPIERE-422 Complete Native Sequence feature

This commit is contained in:
Juan David Arboleda 2012-10-05 11:22:33 -05:00
parent ae5622f7de
commit 7874f573e4
8 changed files with 385 additions and 94 deletions

View File

@ -24,8 +24,13 @@ BEGIN
END;
*
************************************************************************/
AS
As
Isnativeseqon NVARCHAR2(1);
Tablename Nvarchar2(60);
sqlcmd VARCHAR2(200);
BEGIN
IF (p_System = 'Y') THEN
SELECT CurrentNextSys
INTO o_NextID
@ -37,15 +42,42 @@ BEGIN
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;
Update Ad_Sequence
Set Currentnext = Currentnext + Incrementno
Where Ad_Sequence_Id=P_Ad_Sequence_Id;
--
END IF;
END IF;
--
EXCEPTION

View File

@ -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
@ -21,7 +21,9 @@ CREATE OR REPLACE FUNCTION nextid(
* select * from nextid((select ad_sequence_id from ad_sequence where name = 'Test')::Integer, 'Y'::Varchar);
*
************************************************************************/
DECLARE
Isnativeseqon VARCHAR(1);
tablename VARCHAR(60);
BEGIN
IF (p_System = 'Y') THEN
RAISE NOTICE 'system';
@ -34,6 +36,26 @@ BEGIN
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;
--
EXECUTE 'SELECT nextval('''||tablename||'_sq'''||')' INTO o_NextID;
--
ELSE
SELECT CurrentNext
INTO o_NextID
FROM AD_Sequence
@ -43,6 +65,7 @@ BEGIN
SET CurrentNext = CurrentNext + IncrementNo
WHERE AD_Sequence_ID=p_AD_Sequence_ID;
END IF;
END IF;
--
EXCEPTION
WHEN OTHERS THEN

View File

@ -0,0 +1,89 @@
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;
/
SELECT register_migration_script('921_IDEMPIERE-422_NativeSequence.sql') FROM dual;

View File

@ -0,0 +1,78 @@
CREATE OR REPLACE FUNCTION nextid(
p_AD_Sequence_ID IN INTEGER,
p_System IN VARCHAR,
o_NextID OUT INTEGER
)
RETURNS INTEGER AS $body$
/*************************************************************************
* The contents of this file are subject to the Compiere License. You may
* obtain a copy of the License at http://www.compiere.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: Compiere ERP+CRM
* Copyright (C) 1999-2005 Jorg Janke, ComPiere, Inc. All Rights Reserved.
*
* converted to postgreSQL by Karsten Thiemann (Schaeffer AG),
* kthiemann@adempiere.org
*************************************************************************
***
* Title: Get Next ID - no Commit
* Description: Returns the next id of the sequence.
* Test:
* select * from nextid((select ad_sequence_id from ad_sequence where name = 'Test')::Integer, 'Y'::Varchar);
*
************************************************************************/
DECLARE
Isnativeseqon VARCHAR(1);
tablename VARCHAR(60);
BEGIN
IF (p_System = 'Y') THEN
RAISE NOTICE 'system';
SELECT CurrentNextSys
INTO o_NextID
FROM AD_Sequence
WHERE AD_Sequence_ID=p_AD_Sequence_ID;
--
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;
--
EXECUTE 'SELECT nextval('''||tablename||'_sq'''||')' INTO o_NextID;
--
ELSE
SELECT CurrentNext
INTO o_NextID
FROM AD_Sequence
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;
--
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE '%',SQLERRM;
END;
$body$ LANGUAGE plpgsql;
SELECT register_migration_script('921_IDEMPIERE-422_NativeSequence.sql') FROM dual
;

View File

@ -7,7 +7,9 @@ DECLARE
currentnextsys NUMBER (10);
currentnext NUMBER (10);
currentseqsys NUMBER (10);
currentseq NUMBER (10);
Currentseq Number (10);
Isnativeseqon Varchar2(1);
sqlcmd VARCHAR2(200);
BEGIN
DBMS_OUTPUT.PUT_LINE ('Start');
@ -38,7 +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;
IF currentnextsys IS NULL
THEN
@ -76,16 +88,26 @@ BEGIN
INTO currentnext
FROM DUAL;
If Isnativeseqon ='Y' Then
Cmdseq :=
'SELECT '||R.Tablename||'_SQ.Nextval as currentnext,
currentnextsys
FROM AD_Sequence '
|| 'WHERE Name = '''
|| r.Tablename
|| ''' AND istableid = ''Y''';
ELSE
cmdseq :=
'SELECT currentnext, currentnextsys FROM AD_Sequence '
|| 'WHERE Name = '''
|| r.tablename
|| ''' AND istableid = ''Y''';
END IF;
EXECUTE IMMEDIATE cmdseq
INTO currentseq, currentseqsys;
IF currentnextsys <> currentseqsys OR currentnext <> currentseq
IF currentnextsys <> currentseqsys OR (currentnext <> currentseq AND Isnativeseqon ='N')
THEN
DBMS_OUTPUT.PUT_LINE ( r.tablename
|| ' sys='
@ -108,8 +130,16 @@ BEGIN
DBMS_OUTPUT.PUT_LINE (cmdupd);
EXECUTE IMMEDIATE cmdupd;
END IF;
End If;
If Currentseq < Currentnext And Isnativeseqon ='Y' Then
Sqlcmd := 'SELECT '||R.Tablename||'_SQ.Nextval FROM DUAL';
DBMS_OUTPUT.PUT_LINE (Sqlcmd);
While Not Currentseq >= (currentnext-1) Loop
Execute Immediate Sqlcmd
Into currentseq;
End Loop;
END IF;
<<next_iteration>>
NULL;
END LOOP;

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
DECLARE
cmdsys VARCHAR (1000);
@ -11,6 +11,7 @@ DECLARE
currentseq NUMERIC (10);
ok BOOLEAN;
r RECORD;
isnativeseqon VARCHAR (1);
BEGIN
FOR r IN (SELECT tablename
@ -41,6 +42,17 @@ 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;
IF currentnextsys IS NULL
THEN
currentnextsys := 0;
@ -72,15 +84,25 @@ BEGIN
ELSE coalesce (currentnext + 1, 1000000)
END ;
IF isnativeseqon ='Y' THEN
cmdseq :=
'SELECT nextval('''||trim(r.tablename)||'_sq'''||') as currentnext,
currentnextsys
FROM AD_Sequence '
|| 'WHERE Name = '''
|| r.tablename
|| ''' AND istableid = ''Y''';
ELSE
cmdseq :=
'SELECT currentnext, currentnextsys FROM AD_Sequence '
|| 'WHERE Name = '''
|| r.tablename
|| ''' AND istableid = ''Y''';
END IF;
EXECUTE cmdseq INTO currentseq, currentseqsys;
IF currentnextsys <> currentseqsys OR currentnext <> currentseq
IF currentnextsys <> currentseqsys OR (currentnext <> currentseq AND isnativeseqon ='N')
THEN
cmdupd :=
'update ad_sequence set currentnextsys = '
@ -93,8 +115,14 @@ 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;
END LOOP;
END;
$func$ LANGUAGE plpgsql;

View File

@ -202,38 +202,24 @@ public class SequenceCheck extends SvrProcess
+ "ORDER BY Name";
int counter = 0;
PreparedStatement pstmt = null;
ResultSet rs = null;
String trxName = null;
if (sp != null)
trxName = sp.get_TrxName();
try
{
pstmt = DB.prepareStatement(sql, trxName);
ResultSet rs = pstmt.executeQuery();
rs = pstmt.executeQuery();
while (rs.next())
{
MSequence seq = new MSequence (ctx, rs, trxName);
int old = seq.getCurrentNext();
int oldSys = seq.getCurrentNextSys();
if (seq.validateTableIDValue())
{
if (seq.getCurrentNext() != old)
{
StringBuilder msg = new StringBuilder(seq.getName()).append(" ID ")
.append(old).append(" -> ").append(seq.getCurrentNext());
String tableValidation= seq.validateTableIDValue();
if (tableValidation!=null){
if (sp != null)
sp.addLog(0, null, null, msg.toString());
sp.addLog(0, null, null, tableValidation);
else
s_log.fine(msg.toString());
}
if (seq.getCurrentNextSys() != oldSys)
{
StringBuilder msg = new StringBuilder(seq.getName()).append(" Sys ")
.append(oldSys).append(" -> ").append(seq.getCurrentNextSys());
if (sp != null)
sp.addLog(0, null, null, msg.toString());
else
s_log.fine(msg.toString());
}
s_log.fine(tableValidation);
if (seq.save())
counter++;
else
@ -249,16 +235,10 @@ public class SequenceCheck extends SvrProcess
catch (Exception e)
{
s_log.log(Level.SEVERE, sql, e);
}
try
}finally
{
if (pstmt != null)
pstmt.close();
pstmt = null;
}
catch (Exception e)
{
pstmt = null;
DB.close(rs, pstmt);
rs = null; pstmt = null;
}
s_log.fine("#" + counter);
} // checkTableID

View File

@ -63,6 +63,7 @@ public class MSequence extends X_AD_Sequence
private static final String NoYearNorMonth = "-";
@Deprecated
public static int getNextID (int AD_Client_ID, String TableName)
{
return getNextID(AD_Client_ID, TableName, null);
@ -75,6 +76,11 @@ 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)
{
@ -693,7 +699,7 @@ public class MSequence extends X_AD_Sequence
seq.setDescription("Table " + TableName);
seq.setIsTableID(tableID);
seq.saveEx();
next_id = seq.getCurrentNext();
next_id = INIT_NO;
}
if (! CConnection.get().getDatabase().createSequence(TableName+"_SQ", 1, 0 , 99999999, next_id, trxName))
return false;
@ -883,10 +889,10 @@ public class MSequence extends X_AD_Sequence
* Validate Table Sequence Values
* @return true if updated
*/
public boolean validateTableIDValue()
public String validateTableIDValue()
{
if (!isTableID())
return false;
return null;
String tableName = getName();
int AD_Column_ID = DB.getSQLValue(null, "SELECT MAX(c.AD_Column_ID) "
+ "FROM AD_Table t"
@ -894,13 +900,14 @@ public class MSequence extends X_AD_Sequence
+ "WHERE t.TableName='" + tableName + "'"
+ " AND c.ColumnName='" + tableName + "_ID'");
if (AD_Column_ID <= 0)
return false;
return null;
//
MSystem system = MSystem.get(getCtx());
int IDRangeEnd = 0;
if (system.getIDRangeEnd() != null)
IDRangeEnd = system.getIDRangeEnd().intValue();
boolean change = false;
String changeMsg = null;
String info = null;
// Current Next
@ -911,11 +918,13 @@ public class MSequence extends X_AD_Sequence
if (maxTableID < INIT_NO)
maxTableID = INIT_NO - 1;
maxTableID++; // Next
if (getCurrentNext() < maxTableID)
int currentNextValue = getCurrentNext();
if (currentNextValue < maxTableID)
{
setCurrentNext(maxTableID);
info = "CurrentNext=" + maxTableID;
change = true;
changeMsg = getName() + " ID " + currentNextValue + " -> " + maxTableID;
}
// Get Max System_ID used in Table
@ -924,22 +933,44 @@ public class MSequence extends X_AD_Sequence
int maxTableSysID = DB.getSQLValue(null, sql);
if (maxTableSysID <= 0)
maxTableSysID = INIT_SYS_NO - 1;
maxTableSysID++; // Next
if (getCurrentNextSys() < maxTableSysID)
{
int currentNextSysValue = getCurrentNextSys();
if (currentNextSysValue < maxTableSysID){
setCurrentNextSys(maxTableSysID);
if (info == null)
info = "CurrentNextSys=" + maxTableSysID;
else
info += " - CurrentNextSys=" + maxTableSysID;
change = true;
if (changeMsg == null)
changeMsg = getName() + " Sys " + currentNextSysValue + " -> " + maxTableSysID;
else
changeMsg += " - " +getName() + " Sys " + currentNextSysValue + " -> " + maxTableSysID;
}
if (info != null)
log.fine(getName() + " - " + info);
return change;
return changeMsg;
} // validate
@Override
public int getCurrentNext() {
if (MSysConfig.getBooleanValue(MSysConfig.SYSTEM_NATIVE_SEQUENCE,false) && isTableID()){
return DB.getNextID (getAD_Client_ID(),getName(),get_TrxName());
}else {
return super.getCurrentNext();
}
}
@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
}
}else {
super.setCurrentNext(CurrentNext);
}
}
/**************************************************************************
* Test
* @param args ignored