Implemented connection pool properties file support. Added convert statement cache for PostgreSQL. Enhance connection pool ability to survive under heavy load.
This commit is contained in:
parent
af5cd44af8
commit
ed6f264381
|
@ -287,4 +287,10 @@
|
||||||
version="0.0.0"
|
version="0.0.0"
|
||||||
unpack="false"/>
|
unpack="false"/>
|
||||||
|
|
||||||
|
<plugin
|
||||||
|
id="org.adempiere.install"
|
||||||
|
download-size="0"
|
||||||
|
install-size="0"
|
||||||
|
version="0.0.0"/>
|
||||||
|
|
||||||
</feature>
|
</feature>
|
||||||
|
|
|
@ -21,8 +21,8 @@
|
||||||
<stringAttribute key="pde.version" value="3.3"/>
|
<stringAttribute key="pde.version" value="3.3"/>
|
||||||
<stringAttribute key="product" value="org.adempiere.ui.swing.client_product"/>
|
<stringAttribute key="product" value="org.adempiere.ui.swing.client_product"/>
|
||||||
<stringAttribute key="productFile" value="/org.adempiere.ui.swing-feature/swingclient.product"/>
|
<stringAttribute key="productFile" value="/org.adempiere.ui.swing-feature/swingclient.product"/>
|
||||||
<stringAttribute key="selected_target_plugins" value="org.eclipse.osgi.services@default:default,org.eclipse.equinox.util@default:default,org.eclipse.equinox.p2.ql@default:default,com.springsource.javax.mail@default:default,com.springsource.org.apache.activemq@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false,org.apache.commons.httpclient@default:default,com.springsource.org.apache.xmlcommons@default:default,org.eclipse.ecf.provider.filetransfer.httpclient@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.http.registry@default:default,com.springsource.org.apache.xerces@default:false,org.eclipse.equinox.p2.metadata.repository@default:default,com.springsource.org.apache.xml.resolver@default:default,org.eclipse.core.jobs@default:default,javax.xml@default:default,org.eclipse.osgi@-1:true,com.springsource.org.apache.poi@default:default,com.springsource.org.junit@default:default,org.eclipse.ecf.provider.filetransfer@default:default,org.sat4j.core@default:default,org.eclipse.equinox.simpleconfigurator@1:true,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.launcher.gtk.linux.x86@default:false,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.p2.garbagecollector@default:default,org.restlet.ext.net@default:true,org.eclipse.core.runtime@default:true,com.springsource.javax.jms@default:default,com.springsource.javax.xml.rpc@default:default,com.springsource.javax.el@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,com.springsource.net.sf.cglib@default:default,org.eclipse.ecf.filetransfer@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.eclipse.equinox.p2.engine@default:default,org.apache.commons.codec@default:default,com.springsource.javax.ejb@default:default,org.restlet@default:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.security@default:default,org.eclipse.equinox.p2.director@default:default,com.springsource.org.apache.xml.serializer@default:default,org.eclipse.ecf.provider.filetransfer.httpclient.ssl@default:false,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.apache.ant@default:default,com.springsource.org.apache.commons.collections@default:default,org.apache.commons.logging@default:default,org.eclipse.equinox.launcher@default:default,com.springsource.org.apache.commons.logging@default:default,org.sat4j.pb@default:default,org.eclipse.ecf.ssl@default:false,org.eclipse.ecf.identity@default:default,org.eclipse.ecf@default:default,com.springsource.org.apache.commons.net@default:default,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.p2.console@default:default,com.springsource.javax.servlet@default:default,com.springsource.javax.activation@default:default,org.eclipse.equinox.app@default:default,com.springsource.org.apache.kahadb@default:default,com.springsource.javax.xml.soap@default:default,org.eclipse.equinox.p2.core@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,com.springsource.javax.management.j2ee@default:default"/>
|
<stringAttribute key="selected_target_plugins" value="org.restlet@default:true,org.eclipse.core.contenttype@default:default,org.eclipse.equinox.frameworkadmin@default:default,org.apache.commons.codec@default:default,com.springsource.javax.servlet@default:default,org.eclipse.ecf.identity@default:default,org.eclipse.equinox.p2.touchpoint.natives@default:default,org.apache.commons.httpclient@default:default,com.springsource.javax.mail@default:default,org.eclipse.ecf.provider.filetransfer@default:default,com.springsource.org.junit@default:default,org.sat4j.core@default:default,com.springsource.org.apache.poi@default:default,com.springsource.org.apache.xerces@default:false,com.springsource.org.apache.xmlcommons@default:default,org.eclipse.osgi.services@default:default,com.springsource.javax.activation@default:default,org.eclipse.ecf.provider.filetransfer.ssl@default:false,org.eclipse.ecf.provider.filetransfer.httpclient@default:default,org.eclipse.ecf@default:default,com.springsource.javax.xml.rpc@default:default,org.eclipse.equinox.p2.director@default:default,org.eclipse.equinox.registry@default:default,com.springsource.org.apache.activemq@default:default,org.eclipse.equinox.p2.metadata@default:default,org.eclipse.core.runtime@default:true,com.springsource.org.apache.commons.logging@default:default,org.eclipse.equinox.simpleconfigurator.manipulator@default:default,org.eclipse.core.jobs@default:default,com.springsource.org.apache.kahadb@default:default,com.springsource.javax.ejb@default:default,com.springsource.org.apache.xml.resolver@default:default,org.eclipse.equinox.p2.engine@default:default,org.eclipse.equinox.launcher@default:default,org.eclipse.ecf.ssl@default:false,org.restlet.ext.net@default:true,org.eclipse.equinox.p2.garbagecollector@default:default,org.eclipse.equinox.p2.metadata.repository@default:default,com.springsource.org.apache.xml.serializer@default:default,org.eclipse.osgi@-1:true,org.eclipse.ecf.filetransfer@default:default,org.eclipse.equinox.preferences@default:default,com.springsource.net.sf.cglib@default:default,org.eclipse.equinox.p2.ql@default:default,org.eclipse.equinox.p2.jarprocessor@default:default,org.eclipse.equinox.security@default:default,com.springsource.javax.el@default:default,org.apache.commons.logging@default:default,com.springsource.org.apache.commons.net@default:default,org.eclipse.equinox.p2.artifact.repository@default:default,javax.xml@default:default,org.eclipse.equinox.app@default:default,com.springsource.javax.management.j2ee@default:default,org.eclipse.equinox.p2.console@default:default,com.springsource.org.apache.commons.collections@default:default,org.sat4j.pb@default:default,com.springsource.javax.jms@default:default,org.eclipse.equinox.http.registry@default:default,org.eclipse.ecf.provider.filetransfer.httpclient.ssl@default:false,org.eclipse.equinox.common@2:true,com.springsource.javax.xml.soap@default:default,org.apache.ant@default:default,org.eclipse.equinox.util@default:default,org.eclipse.equinox.p2.touchpoint.eclipse@default:default,org.eclipse.equinox.launcher.gtk.linux.x86@default:false,org.eclipse.equinox.frameworkadmin.equinox@default:default,org.eclipse.equinox.p2.repository@default:default,org.eclipse.equinox.simpleconfigurator@1:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.p2.core@default:default"/>
|
||||||
<stringAttribute key="selected_workspace_plugins" value="org.adempiere.base@default:default,org.adempiere.extend@default:false,org.adempiere.ui@default:default,org.adempiere.report.jasper.swing@default:default,org.adempiere.plugin.utils@default:default,org.adempiere.report.jasper@default:default,org.adempiere.report.jasper.library@default:default,org.adempiere.pipo@default:default,org.apache.ecs@default:default,org.adempiere.replication@default:default,org.adempiere.payment.processor@default:default,org.adempiere.base.callout@default:default,org.adempiere.pipo.handlers@default:default,org.compiere.db.oracle.provider@default:default,org.adempiere.ui.swing@default:default,org.compiere.db.postgresql.provider@default:default,org.adempiere.base.process@default:default"/>
|
<stringAttribute key="selected_workspace_plugins" value="org.adempiere.report.jasper.library@default:default,org.adempiere.replication@default:default,org.apache.ecs@default:default,org.adempiere.plugin.utils@default:default,org.adempiere.ui@default:default,org.adempiere.pipo.handlers@default:default,org.compiere.db.postgresql.provider@default:default,org.adempiere.report.jasper.swing@default:default,org.compiere.db.oracle.provider@default:default,org.adempiere.ui.swing@default:default,org.adempiere.extend@default:false,org.adempiere.install@default:default,org.adempiere.base.process@default:default,org.adempiere.payment.processor@default:default,org.adempiere.pipo@default:default,org.adempiere.report.jasper@default:default,org.adempiere.base@default:default,org.adempiere.base.callout@default:default"/>
|
||||||
<booleanAttribute key="show_selected_only" value="false"/>
|
<booleanAttribute key="show_selected_only" value="false"/>
|
||||||
<booleanAttribute key="tracing" value="false"/>
|
<booleanAttribute key="tracing" value="false"/>
|
||||||
<booleanAttribute key="useCustomFeatures" value="false"/>
|
<booleanAttribute key="useCustomFeatures" value="false"/>
|
||||||
|
|
|
@ -10,4 +10,7 @@ Bundle-ClassPath: .,
|
||||||
ojdbc6.jar,
|
ojdbc6.jar,
|
||||||
c3p0-0.9.1.2.jar,
|
c3p0-0.9.1.2.jar,
|
||||||
c3p0-oracle-thin-extras-0.9.1.2.jar
|
c3p0-oracle-thin-extras-0.9.1.2.jar
|
||||||
|
Import-Package: org.osgi.framework
|
||||||
|
Bundle-ActivationPolicy: lazy
|
||||||
|
Bundle-Activator: org.adempiere.db.oracle.OracleBundleActivator
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#timeout
|
||||||
|
IdleConnectionTestPeriod=1200
|
||||||
|
AcquireRetryAttempts=2
|
||||||
|
MaxIdleTimeExcessConnections=1200
|
||||||
|
MaxIdleTime=1200
|
||||||
|
#UnreturnedConnectionTimeout=1800
|
||||||
|
|
||||||
|
#size
|
||||||
|
MaxPoolSize=15
|
||||||
|
InitialPoolSize=1
|
||||||
|
MinPoolSize=1
|
||||||
|
|
||||||
|
#flag
|
||||||
|
TestConnectionOnCheckin=false
|
||||||
|
TestConnectionOnCheckout=false
|
||||||
|
#CheckoutTimeout=60;
|
|
@ -0,0 +1,16 @@
|
||||||
|
#timeout
|
||||||
|
IdleConnectionTestPeriod=1200
|
||||||
|
AcquireRetryAttempts=2
|
||||||
|
MaxIdleTimeExcessConnections=1200
|
||||||
|
MaxIdleTime=1200
|
||||||
|
#UnreturnedConnectionTimeout=1800
|
||||||
|
|
||||||
|
#size
|
||||||
|
MaxPoolSize=150
|
||||||
|
InitialPoolSize=10
|
||||||
|
MinPoolSize=5
|
||||||
|
|
||||||
|
#flag
|
||||||
|
TestConnectionOnCheckin=false
|
||||||
|
TestConnectionOnCheckout=false
|
||||||
|
#CheckoutTimeout=60;
|
|
@ -0,0 +1,38 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2010 Heng Sin Low *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.adempiere.db.oracle;
|
||||||
|
|
||||||
|
import org.osgi.framework.BundleActivator;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class OracleBundleActivator implements BundleActivator {
|
||||||
|
|
||||||
|
public static BundleContext bundleContext = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(BundleContext context) throws Exception {
|
||||||
|
bundleContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(BundleContext context) throws Exception {
|
||||||
|
bundleContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,7 +16,9 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.compiere.db;
|
package org.compiere.db;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URL;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.Driver;
|
import java.sql.Driver;
|
||||||
|
@ -25,12 +27,15 @@ import java.sql.PreparedStatement;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import oracle.jdbc.OracleDriver;
|
import oracle.jdbc.OracleDriver;
|
||||||
|
|
||||||
|
import org.adempiere.db.oracle.OracleBundleActivator;
|
||||||
import org.adempiere.exceptions.DBException;
|
import org.adempiere.exceptions.DBException;
|
||||||
import org.compiere.Adempiere;
|
import org.compiere.Adempiere;
|
||||||
import org.compiere.dbPort.Convert;
|
import org.compiere.dbPort.Convert;
|
||||||
|
@ -40,6 +45,7 @@ import org.compiere.util.DB;
|
||||||
import org.compiere.util.DisplayType;
|
import org.compiere.util.DisplayType;
|
||||||
import org.compiere.util.Ini;
|
import org.compiere.util.Ini;
|
||||||
import org.compiere.util.Language;
|
import org.compiere.util.Language;
|
||||||
|
import org.compiere.util.Trx;
|
||||||
import org.compiere.util.Util;
|
import org.compiere.util.Util;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
||||||
|
@ -52,11 +58,12 @@ import com.mchange.v2.c3p0.ComboPooledDataSource;
|
||||||
* ---
|
* ---
|
||||||
* Modifications: Refactoring. Replaced Oracle Cache Manager with C3P0
|
* Modifications: Refactoring. Replaced Oracle Cache Manager with C3P0
|
||||||
* connection pooling framework for better and more efficient connnection handling
|
* connection pooling framework for better and more efficient connnection handling
|
||||||
*
|
*
|
||||||
* @author Ashley Ramdass (Posterita)
|
* @author Ashley Ramdass (Posterita)
|
||||||
*/
|
*/
|
||||||
public class DB_Oracle implements AdempiereDatabase
|
public class DB_Oracle implements AdempiereDatabase
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Oracle Database
|
* Oracle Database
|
||||||
*/
|
*/
|
||||||
|
@ -97,8 +104,6 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
/** Connection String */
|
/** Connection String */
|
||||||
private String m_connectionURL;
|
private String m_connectionURL;
|
||||||
|
|
||||||
/** Statement Cache (50) */
|
|
||||||
private static final String MAX_STATEMENTS = "200";
|
|
||||||
/** Data Source */
|
/** Data Source */
|
||||||
private ComboPooledDataSource m_ds = null;
|
private ComboPooledDataSource m_ds = null;
|
||||||
|
|
||||||
|
@ -113,6 +118,7 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
|
|
||||||
private static int m_maxbusyconnections = 0;
|
private static int m_maxbusyconnections = 0;
|
||||||
|
|
||||||
|
private Random rand = new Random();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Database Name
|
* Get Database Name
|
||||||
|
@ -333,6 +339,7 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
|
sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
|
||||||
sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
|
sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
|
||||||
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
|
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
|
||||||
|
sb.append(" , # Active Transactions: ").append(Trx.getActiveTransactions().length);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{}
|
{}
|
||||||
|
@ -546,6 +553,24 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
if (m_ds != null)
|
if (m_ds != null)
|
||||||
return m_ds;
|
return m_ds;
|
||||||
|
|
||||||
|
URL url = Ini.isClient()
|
||||||
|
? OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.properties")
|
||||||
|
: OracleBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.properties");
|
||||||
|
Properties poolProperties = new Properties();
|
||||||
|
try {
|
||||||
|
poolProperties.load(url.openStream());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new DBException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idleConnectionTestPeriod = getIntProperty(poolProperties, "IdleConnectionTestPeriod", 1200);
|
||||||
|
int acquireRetryAttempts = getIntProperty(poolProperties, "AcquireRetryAttempts", 2);
|
||||||
|
int maxIdleTimeExcessConnections = getIntProperty(poolProperties, "MaxIdleTimeExcessConnections", 1200);
|
||||||
|
int maxIdleTime = getIntProperty(poolProperties, "MaxIdleTime", 1200);
|
||||||
|
int unreturnedConnectionTimeout = getIntProperty(poolProperties, "UnreturnedConnectionTimeout", 0);
|
||||||
|
boolean testConnectionOnCheckin = getBooleanProperty(poolProperties, "TestConnectionOnCheckin", false);
|
||||||
|
boolean testConnectionOnCheckout = getBooleanProperty(poolProperties, "TestConnectionOnCheckout", false);
|
||||||
|
int checkoutTimeout = getIntProperty(poolProperties, "CheckoutTimeout", 0);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
|
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
|
||||||
|
@ -558,34 +583,42 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
cpds.setUser(connection.getDbUid());
|
cpds.setUser(connection.getDbUid());
|
||||||
cpds.setPassword(connection.getDbPwd());
|
cpds.setPassword(connection.getDbPwd());
|
||||||
cpds.setPreferredTestQuery(DEFAULT_CONN_TEST_SQL);
|
cpds.setPreferredTestQuery(DEFAULT_CONN_TEST_SQL);
|
||||||
cpds.setIdleConnectionTestPeriod(1200);
|
cpds.setIdleConnectionTestPeriod(idleConnectionTestPeriod);
|
||||||
cpds.setAcquireRetryAttempts(2);
|
cpds.setAcquireRetryAttempts(acquireRetryAttempts);
|
||||||
//cpds.setTestConnectionOnCheckin(true);
|
cpds.setTestConnectionOnCheckin(testConnectionOnCheckin);
|
||||||
//cpds.setTestConnectionOnCheckout(true);
|
cpds.setTestConnectionOnCheckout(testConnectionOnCheckout);
|
||||||
//cpds.setCheckoutTimeout(60);
|
if (checkoutTimeout > 0)
|
||||||
|
cpds.setCheckoutTimeout(checkoutTimeout);
|
||||||
|
|
||||||
|
cpds.setMaxIdleTimeExcessConnections(maxIdleTimeExcessConnections);
|
||||||
|
cpds.setMaxIdleTime(maxIdleTime);
|
||||||
if (Ini.isClient())
|
if (Ini.isClient())
|
||||||
{
|
{
|
||||||
cpds.setInitialPoolSize(1);
|
int maxPoolSize = getIntProperty(poolProperties, "MaxPoolSize", 15);
|
||||||
cpds.setMinPoolSize(1);
|
int initialPoolSize = getIntProperty(poolProperties, "InitialPoolSize", 1);
|
||||||
cpds.setMaxPoolSize(15);
|
int minPoolSize = getIntProperty(poolProperties, "MinPoolSize", 1);
|
||||||
cpds.setMaxIdleTimeExcessConnections(1200);
|
cpds.setInitialPoolSize(initialPoolSize);
|
||||||
cpds.setMaxIdleTime(900);
|
cpds.setMinPoolSize(minPoolSize);
|
||||||
m_maxbusyconnections = 10;
|
cpds.setMaxPoolSize(maxPoolSize);
|
||||||
|
m_maxbusyconnections = (int) (maxPoolSize * 0.9);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cpds.setInitialPoolSize(10);
|
int maxPoolSize = getIntProperty(poolProperties, "MaxPoolSize", 400);
|
||||||
cpds.setMinPoolSize(5);
|
int initialPoolSize = getIntProperty(poolProperties, "InitialPoolSize", 10);
|
||||||
cpds.setMaxPoolSize(150);
|
int minPoolSize = getIntProperty(poolProperties, "MinPoolSize", 5);
|
||||||
cpds.setMaxIdleTimeExcessConnections(1200);
|
cpds.setInitialPoolSize(initialPoolSize);
|
||||||
cpds.setMaxIdleTime(1200);
|
cpds.setMinPoolSize(minPoolSize);
|
||||||
m_maxbusyconnections = 120;
|
cpds.setMaxPoolSize(maxPoolSize);
|
||||||
|
m_maxbusyconnections = (int) (maxPoolSize * 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
//the following sometimes kill active connection!
|
if (unreturnedConnectionTimeout > 0)
|
||||||
//cpds.setUnreturnedConnectionTimeout(1200);
|
{
|
||||||
//cpds.setDebugUnreturnedConnectionStackTraces(true);
|
//the following sometimes kill active connection!
|
||||||
|
cpds.setUnreturnedConnectionTimeout(1200);
|
||||||
|
cpds.setDebugUnreturnedConnectionStackTraces(true);
|
||||||
|
}
|
||||||
|
|
||||||
m_ds = cpds;
|
m_ds = cpds;
|
||||||
}
|
}
|
||||||
|
@ -600,7 +633,6 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
return m_ds;
|
return m_ds;
|
||||||
} // getDataSource
|
} // getDataSource
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Cached Connection
|
* Get Cached Connection
|
||||||
* @param connection info
|
* @param connection info
|
||||||
|
@ -623,14 +655,27 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
//
|
//
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
conn = (Connection)m_ds.getConnection();
|
int numConnections = m_ds.getNumBusyConnections();
|
||||||
|
if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
|
||||||
|
{
|
||||||
|
//system is under heavy load, wait between 20 to 40 seconds
|
||||||
|
int randomNum = rand.nextInt(40 - 20 + 1) + 20;
|
||||||
|
Thread.sleep(randomNum * 1000);
|
||||||
|
}
|
||||||
|
conn = m_ds.getConnection();
|
||||||
|
if (conn == null) {
|
||||||
|
//try again after 10 to 30 seconds
|
||||||
|
int randomNum = rand.nextInt(30 - 10 + 1) + 10;
|
||||||
|
Thread.sleep(randomNum * 1000);
|
||||||
|
conn = m_ds.getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
if (conn != null)
|
if (conn != null)
|
||||||
{
|
{
|
||||||
if (conn.getTransactionIsolation() != transactionIsolation)
|
if (conn.getTransactionIsolation() != transactionIsolation)
|
||||||
conn.setTransactionIsolation(transactionIsolation);
|
conn.setTransactionIsolation(transactionIsolation);
|
||||||
if (conn.getAutoCommit() != autoCommit)
|
if (conn.getAutoCommit() != autoCommit)
|
||||||
conn.setAutoCommit(autoCommit);
|
conn.setAutoCommit(autoCommit);
|
||||||
// conn.setDefaultRowPrefetch(20); // 10 default - reduces round trips
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -668,18 +713,29 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
|
boolean trace = "true".equalsIgnoreCase(System.getProperty("org.adempiere.db.traceStatus"));
|
||||||
int numConnections = m_ds.getNumBusyConnections();
|
int numConnections = m_ds.getNumBusyConnections();
|
||||||
if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
|
if (numConnections > 1)
|
||||||
{
|
{
|
||||||
log.warning(getStatus());
|
if (trace)
|
||||||
//hengsin: make a best effort to reclaim leak connection
|
{
|
||||||
Runtime.getRuntime().runFinalization();
|
log.warning(getStatus());
|
||||||
}
|
}
|
||||||
|
if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
|
||||||
|
{
|
||||||
|
if (!trace)
|
||||||
|
log.warning(getStatus());
|
||||||
|
//hengsin: make a best effort to reclaim leak connection
|
||||||
|
Runtime.getRuntime().runFinalization();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//don't use log.severe here as it will try to access db again
|
||||||
|
System.err.println("Failed to acquire new connection. Status=" + getStatus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
if (exception != null)
|
if (exception != null)
|
||||||
throw exception;
|
throw exception;
|
||||||
|
@ -1090,25 +1146,25 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
return m_sequence_id;
|
return m_sequence_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
int no = DB.executeUpdate("DROP SEQUENCE "+name.toUpperCase(), trxName);
|
||||||
no = DB.executeUpdateEx("CREATE SEQUENCE "+name.toUpperCase()
|
no = DB.executeUpdateEx("CREATE SEQUENCE "+name.toUpperCase()
|
||||||
+ " MINVALUE " + minvalue
|
+ " MINVALUE " + minvalue
|
||||||
+ " MAXVALUE " + maxvalue
|
+ " MAXVALUE " + maxvalue
|
||||||
+ " START WITH " + start
|
+ " START WITH " + start
|
||||||
+ " INCREMENT BY " + increment +" CACHE 20", trxName)
|
+ " INCREMENT BY " + increment +" CACHE 20", trxName)
|
||||||
;
|
;
|
||||||
if(no == -1 )
|
if(no == -1 )
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isQueryTimeoutSupported() {
|
public boolean isQueryTimeoutSupported() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String addPagingSQL(String sql, int start, int end) {
|
public String addPagingSQL(String sql, int start, int end) {
|
||||||
//not supported, too many corner case that doesn't work using rownum. to investigate later
|
//not supported, too many corner case that doesn't work using rownum. to investigate later
|
||||||
return sql;
|
return sql;
|
||||||
|
@ -1118,4 +1174,29 @@ public class DB_Oracle implements AdempiereDatabase
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getIntProperty(Properties properties, String key, int defaultValue)
|
||||||
|
{
|
||||||
|
int i = defaultValue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String s = properties.getProperty(key);
|
||||||
|
if (s != null && s.trim().length() > 0)
|
||||||
|
i = Integer.parseInt(s);
|
||||||
|
}
|
||||||
|
catch (Exception e) {}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getBooleanProperty(Properties properties, String key, boolean defaultValue)
|
||||||
|
{
|
||||||
|
boolean b = defaultValue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String s = properties.getProperty(key);
|
||||||
|
if (s != null && s.trim().length() > 0)
|
||||||
|
b = Boolean.valueOf(s);
|
||||||
|
}
|
||||||
|
catch (Exception e) {}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
} // DB_Oracle
|
} // DB_Oracle
|
||||||
|
|
|
@ -10,4 +10,7 @@ Bundle-ClassPath: .,
|
||||||
Require-Bundle: org.adempiere.base;bundle-version="1.0.0",
|
Require-Bundle: org.adempiere.base;bundle-version="1.0.0",
|
||||||
org.adempiere.install;bundle-version="1.0.0"
|
org.adempiere.install;bundle-version="1.0.0"
|
||||||
Import-Package: junit.framework;version="3.8.2",
|
Import-Package: junit.framework;version="3.8.2",
|
||||||
org.junit;version="4.8.1"
|
org.junit;version="4.8.1",
|
||||||
|
org.osgi.framework
|
||||||
|
Bundle-ActivationPolicy: lazy
|
||||||
|
Bundle-Activator: org.adempiere.db.postgresql.PostgreSQLBundleActivator
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#timeout
|
||||||
|
IdleConnectionTestPeriod=1200
|
||||||
|
AcquireRetryAttempts=2
|
||||||
|
MaxIdleTimeExcessConnections=1200
|
||||||
|
MaxIdleTime=1200
|
||||||
|
#UnreturnedConnectionTimeout=1800
|
||||||
|
|
||||||
|
#size
|
||||||
|
MaxPoolSize=15
|
||||||
|
InitialPoolSize=1
|
||||||
|
MinPoolSize=1
|
||||||
|
|
||||||
|
#flag
|
||||||
|
TestConnectionOnCheckin=false
|
||||||
|
TestConnectionOnCheckout=false
|
||||||
|
#CheckoutTimeout=60;
|
|
@ -0,0 +1,16 @@
|
||||||
|
#timeout
|
||||||
|
IdleConnectionTestPeriod=1200
|
||||||
|
AcquireRetryAttempts=2
|
||||||
|
MaxIdleTimeExcessConnections=1200
|
||||||
|
MaxIdleTime=1200
|
||||||
|
#UnreturnedConnectionTimeout=1800
|
||||||
|
|
||||||
|
#size
|
||||||
|
MaxPoolSize=150
|
||||||
|
InitialPoolSize=10
|
||||||
|
MinPoolSize=5
|
||||||
|
|
||||||
|
#flag
|
||||||
|
TestConnectionOnCheckin=false
|
||||||
|
TestConnectionOnCheckout=false
|
||||||
|
#CheckoutTimeout=60;
|
|
@ -0,0 +1,38 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* Product: Adempiere ERP & CRM Smart Business Solution *
|
||||||
|
* Copyright (C) 2010 Heng Sin Low *
|
||||||
|
* This program is free software; you can redistribute it and/or modify it *
|
||||||
|
* under the terms version 2 of the GNU General Public License as published *
|
||||||
|
* by the Free Software Foundation. This program is distributed in the hope *
|
||||||
|
* that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
|
||||||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||||
|
* See the GNU General Public License for more details. *
|
||||||
|
* You should have received a copy of the GNU General Public License along *
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
|
||||||
|
*****************************************************************************/
|
||||||
|
package org.adempiere.db.postgresql;
|
||||||
|
|
||||||
|
import org.osgi.framework.BundleActivator;
|
||||||
|
import org.osgi.framework.BundleContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author hengsin
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PostgreSQLBundleActivator implements BundleActivator {
|
||||||
|
|
||||||
|
public static BundleContext bundleContext = null;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start(BundleContext context) throws Exception {
|
||||||
|
bundleContext = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop(BundleContext context) throws Exception {
|
||||||
|
bundleContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -18,38 +18,46 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
package org.compiere.db;
|
package org.compiere.db;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URL;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.Random;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.sql.ConnectionPoolDataSource;
|
import javax.sql.ConnectionPoolDataSource;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import javax.sql.RowSet;
|
import javax.sql.RowSet;
|
||||||
|
|
||||||
|
import org.adempiere.db.postgresql.PostgreSQLBundleActivator;
|
||||||
|
import org.adempiere.exceptions.DBException;
|
||||||
import org.compiere.dbPort.Convert;
|
import org.compiere.dbPort.Convert;
|
||||||
import org.compiere.dbPort.Convert_PostgreSQL;
|
import org.compiere.dbPort.Convert_PostgreSQL;
|
||||||
|
import org.compiere.util.CCache;
|
||||||
import org.compiere.util.CLogger;
|
import org.compiere.util.CLogger;
|
||||||
import org.compiere.util.DB;
|
import org.compiere.util.DB;
|
||||||
import org.compiere.util.DisplayType;
|
import org.compiere.util.DisplayType;
|
||||||
import org.compiere.util.Ini;
|
import org.compiere.util.Ini;
|
||||||
|
import org.compiere.util.Trx;
|
||||||
|
|
||||||
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
import com.mchange.v2.c3p0.ComboPooledDataSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PostgreSQL Database Port
|
* PostgreSQL Database Port
|
||||||
*
|
*
|
||||||
* @author @author Jorg Janke, Victor P<EFBFBD>rez
|
* @author @author Jorg Janke, Victor P<EFBFBD>rez
|
||||||
* @version $Id: DB_PostgreSQL.java,v 1.23 2005/03/11 20:29:01 jjanke Exp $
|
* @version $Id: DB_PostgreSQL.java,v 1.23 2005/03/11 20:29:01 jjanke Exp $
|
||||||
* ---
|
* ---
|
||||||
* Modifications: removed static references to database connection and instead always
|
* Modifications: removed static references to database connection and instead always
|
||||||
* get a new connection from database pool manager which manages all connections
|
* get a new connection from database pool manager which manages all connections
|
||||||
* set rw/ro properties for the connection accordingly.
|
* set rw/ro properties for the connection accordingly.
|
||||||
* @author Ashley Ramdass (Posterita)
|
* @author Ashley Ramdass (Posterita)
|
||||||
*/
|
*/
|
||||||
public class DB_PostgreSQL implements AdempiereDatabase
|
public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
{
|
{
|
||||||
|
@ -67,13 +75,13 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
|
|
||||||
/** Driver */
|
/** Driver */
|
||||||
private org.postgresql.Driver s_driver = null;
|
private org.postgresql.Driver s_driver = null;
|
||||||
|
|
||||||
/** Driver class */
|
/** Driver class */
|
||||||
public static final String DRIVER = "org.postgresql.Driver";
|
public static final String DRIVER = "org.postgresql.Driver";
|
||||||
|
|
||||||
/** Default Port */
|
/** Default Port */
|
||||||
public static final int DEFAULT_PORT = 5432;
|
public static final int DEFAULT_PORT = 5432;
|
||||||
|
|
||||||
/** Data Source */
|
/** Data Source */
|
||||||
private ComboPooledDataSource m_ds = null;
|
private ComboPooledDataSource m_ds = null;
|
||||||
|
|
||||||
|
@ -83,19 +91,24 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
private String m_connection;
|
private String m_connection;
|
||||||
/** Cached Database Name */
|
/** Cached Database Name */
|
||||||
private String m_dbName = null;
|
private String m_dbName = null;
|
||||||
|
|
||||||
private String m_userName = null;
|
@SuppressWarnings("unused")
|
||||||
|
private String m_userName = null;
|
||||||
|
|
||||||
/** Connection String */
|
/** Connection String */
|
||||||
private String m_connectionURL;
|
private String m_connectionURL;
|
||||||
|
|
||||||
/** Logger */
|
/** Logger */
|
||||||
private static CLogger log = CLogger.getCLogger (DB_PostgreSQL.class);
|
private static CLogger log = CLogger.getCLogger (DB_PostgreSQL.class);
|
||||||
|
|
||||||
private static int m_maxbusyconnections = 0;
|
private static int m_maxbusyconnections = 0;
|
||||||
|
|
||||||
public static final String NATIVE_MARKER = "NATIVE_"+Database.DB_POSTGRESQL+"_KEYWORK";
|
public static final String NATIVE_MARKER = "NATIVE_"+Database.DB_POSTGRESQL+"_KEYWORK";
|
||||||
|
|
||||||
|
private CCache<String, String> convertCache = new CCache<String, String>("SQLConvertCache", 100, 0);
|
||||||
|
|
||||||
|
private Random rand = new Random();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Database Name
|
* Get Database Name
|
||||||
* @return database short name
|
* @return database short name
|
||||||
|
@ -180,7 +193,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
public String getConnectionURL (String dbHost, int dbPort, String dbName,
|
public String getConnectionURL (String dbHost, int dbPort, String dbName,
|
||||||
String userName)
|
String userName)
|
||||||
{
|
{
|
||||||
return "jdbc:postgresql://"
|
return "jdbc:postgresql://"
|
||||||
+ dbHost + ":" + dbPort + "/" + dbName;
|
+ dbHost + ":" + dbPort + "/" + dbName;
|
||||||
} // getConnectionURL
|
} // getConnectionURL
|
||||||
|
|
||||||
|
@ -196,7 +209,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
m_connectionURL = connectionURL;
|
m_connectionURL = connectionURL;
|
||||||
return m_connectionURL;
|
return m_connectionURL;
|
||||||
} // getConnectionURL
|
} // getConnectionURL
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get JDBC Catalog
|
* Get JDBC Catalog
|
||||||
* @return catalog (database name)
|
* @return catalog (database name)
|
||||||
|
@ -208,7 +221,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
// log.severe("Database Name not set (yet) - call getConnectionURL first");
|
// log.severe("Database Name not set (yet) - call getConnectionURL first");
|
||||||
return null;
|
return null;
|
||||||
} // getCatalog
|
} // getCatalog
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get JDBC Schema
|
* Get JDBC Schema
|
||||||
* @return schema (dbo)
|
* @return schema (dbo)
|
||||||
|
@ -271,6 +284,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
|
sb.append(" , # Busy Connections: ").append(m_ds.getNumBusyConnections());
|
||||||
sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
|
sb.append(" , # Idle Connections: ").append(m_ds.getNumIdleConnections());
|
||||||
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
|
sb.append(" , # Orphaned Connections: ").append(m_ds.getNumUnclosedOrphanedConnections());
|
||||||
|
sb.append(" , # Active Transactions: ").append(Trx.getActiveTransactions().length);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{}
|
{}
|
||||||
|
@ -286,23 +300,19 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
*/
|
*/
|
||||||
public String convertStatement (String oraStatement)
|
public String convertStatement (String oraStatement)
|
||||||
{
|
{
|
||||||
|
String cache = convertCache.get(oraStatement);
|
||||||
|
if (cache != null) {
|
||||||
|
Convert.logMigrationScript(oraStatement, cache);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
String retValue[] = m_convert.convert(oraStatement);
|
String retValue[] = m_convert.convert(oraStatement);
|
||||||
|
|
||||||
//begin vpj-cd e-evolution 03/14/2005
|
//begin vpj-cd e-evolution 03/14/2005
|
||||||
if (retValue.length == 0 )
|
if (retValue == null || retValue.length == 0 )
|
||||||
return oraStatement;
|
return oraStatement;
|
||||||
//end vpj-cd e-evolution 03/14/2005
|
//end vpj-cd e-evolution 03/14/2005
|
||||||
|
|
||||||
if (retValue == null)
|
|
||||||
//begin vpj-cd 24/06/2005 e-evolution
|
|
||||||
{
|
|
||||||
log.log(Level.SEVERE,("DB_PostgreSQL.convertStatement - Not Converted (" + oraStatement + ") - "
|
|
||||||
+ m_convert.getConversionError()));
|
|
||||||
throw new IllegalArgumentException
|
|
||||||
("DB_PostgreSQL.convertStatement - Not Converted (" + oraStatement + ") - "
|
|
||||||
+ m_convert.getConversionError());
|
|
||||||
}
|
|
||||||
// end vpj-cd 24/06/2005 e-evolution
|
|
||||||
if (retValue.length != 1)
|
if (retValue.length != 1)
|
||||||
//begin vpj-cd 24/06/2005 e-evolution
|
//begin vpj-cd 24/06/2005 e-evolution
|
||||||
{
|
{
|
||||||
|
@ -313,6 +323,9 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
+ " (" + oraStatement + ") - " + m_convert.getConversionError());
|
+ " (" + oraStatement + ") - " + m_convert.getConversionError());
|
||||||
}
|
}
|
||||||
//end vpj-cd 24/06/2005 e-evolution
|
//end vpj-cd 24/06/2005 e-evolution
|
||||||
|
|
||||||
|
convertCache.put(oraStatement, retValue[0]);
|
||||||
|
|
||||||
// Diagnostics (show changed, but not if AD_Error
|
// Diagnostics (show changed, but not if AD_Error
|
||||||
if (log.isLoggable(Level.FINE))
|
if (log.isLoggable(Level.FINE))
|
||||||
{
|
{
|
||||||
|
@ -328,7 +341,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
return retValue[0];
|
return retValue[0];
|
||||||
} // convertStatement
|
} // convertStatement
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Name of System User
|
* Get Name of System User
|
||||||
* @return e.g. sa, system
|
* @return e.g. sa, system
|
||||||
|
@ -348,7 +361,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
return "template1";
|
return "template1";
|
||||||
} // getSystemDatabase
|
} // getSystemDatabase
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create SQL TO Date String from Timestamp
|
* Create SQL TO Date String from Timestamp
|
||||||
*
|
*
|
||||||
|
@ -409,7 +422,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
if (displayType == DisplayType.Amount)
|
if (displayType == DisplayType.Amount)
|
||||||
retValue.append(" AS TEXT");
|
retValue.append(" AS TEXT");
|
||||||
else
|
else
|
||||||
retValue.append(" AS TEXT");
|
retValue.append(" AS TEXT");
|
||||||
//if (!Language.isDecimalPoint(AD_Language)) // reversed
|
//if (!Language.isDecimalPoint(AD_Language)) // reversed
|
||||||
//retValue.append(",'NLS_NUMERIC_CHARACTERS='',.'''");
|
//retValue.append(",'NLS_NUMERIC_CHARACTERS='',.'''");
|
||||||
}
|
}
|
||||||
|
@ -450,7 +463,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
return result.toString();
|
return result.toString();
|
||||||
} // TO_NUMBER
|
} // TO_NUMBER
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get SQL Commands
|
* Get SQL Commands
|
||||||
* @param cmdType CMD_*
|
* @param cmdType CMD_*
|
||||||
|
@ -461,7 +474,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
if (CMD_CREATE_USER == cmdType)
|
if (CMD_CREATE_USER == cmdType)
|
||||||
return new String[]
|
return new String[]
|
||||||
{
|
{
|
||||||
"CREATE USER adempiere;",
|
"CREATE USER adempiere;",
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
if (CMD_CREATE_DATABASE == cmdType)
|
if (CMD_CREATE_DATABASE == cmdType)
|
||||||
|
@ -482,7 +495,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
return null;
|
return null;
|
||||||
} // getCommands
|
} // getCommands
|
||||||
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* Get RowSet
|
* Get RowSet
|
||||||
* @param rs ResultSet
|
* @param rs ResultSet
|
||||||
|
@ -493,8 +506,8 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("PostgreSQL does not support RowSets");
|
throw new UnsupportedOperationException("PostgreSQL does not support RowSets");
|
||||||
} // getRowSet
|
} // getRowSet
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Cached Connection
|
* Get Cached Connection
|
||||||
* @param connection connection
|
* @param connection connection
|
||||||
|
@ -507,31 +520,91 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
boolean autoCommit, int transactionIsolation)
|
boolean autoCommit, int transactionIsolation)
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (m_ds == null)
|
Connection conn = null;
|
||||||
getDataSource(connection);
|
Exception exception = null;
|
||||||
//
|
try
|
||||||
Connection conn = m_ds.getConnection();
|
{
|
||||||
if (conn != null) {
|
if (m_ds == null)
|
||||||
//
|
getDataSource(connection);
|
||||||
conn.setAutoCommit(autoCommit);
|
|
||||||
conn.setTransactionIsolation(transactionIsolation);
|
//
|
||||||
|
try
|
||||||
try
|
{
|
||||||
{
|
int numConnections = m_ds.getNumBusyConnections();
|
||||||
int numConnections = m_ds.getNumBusyConnections();
|
if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
|
||||||
if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
|
{
|
||||||
{
|
//system is under heavy load, wait between 20 to 40 seconds
|
||||||
log.warning(getStatus());
|
int randomNum = rand.nextInt(40 - 20 + 1) + 20;
|
||||||
//hengsin: make a best effort to reclaim leak connection
|
Thread.sleep(randomNum * 1000);
|
||||||
Runtime.getRuntime().runFinalization();
|
}
|
||||||
}
|
conn = m_ds.getConnection();
|
||||||
}
|
if (conn == null) {
|
||||||
catch (Exception ex)
|
//try again after 10 to 30 seconds
|
||||||
{}
|
int randomNum = rand.nextInt(30 - 10 + 1) + 10;
|
||||||
}
|
Thread.sleep(randomNum * 1000);
|
||||||
return conn;
|
conn = m_ds.getConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn != null)
|
||||||
|
{
|
||||||
|
if (conn.getTransactionIsolation() != transactionIsolation)
|
||||||
|
conn.setTransactionIsolation(transactionIsolation);
|
||||||
|
if (conn.getAutoCommit() != autoCommit)
|
||||||
|
conn.setAutoCommit(autoCommit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
exception = e;
|
||||||
|
conn = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (conn == null && exception != null)
|
||||||
|
{
|
||||||
|
//log might cause infinite loop since it will try to acquire database connection again
|
||||||
|
/*
|
||||||
|
log.log(Level.SEVERE, exception.toString());
|
||||||
|
log.fine(toString()); */
|
||||||
|
System.err.println(exception.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
exception = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (conn != null) {
|
||||||
|
boolean trace = "true".equalsIgnoreCase(System.getProperty("org.adempiere.db.traceStatus"));
|
||||||
|
int numConnections = m_ds.getNumBusyConnections();
|
||||||
|
if (numConnections > 1)
|
||||||
|
{
|
||||||
|
if (trace)
|
||||||
|
{
|
||||||
|
log.warning(getStatus());
|
||||||
|
}
|
||||||
|
if(numConnections >= m_maxbusyconnections && m_maxbusyconnections > 0)
|
||||||
|
{
|
||||||
|
if (!trace)
|
||||||
|
log.warning(getStatus());
|
||||||
|
//hengsin: make a best effort to reclaim leak connection
|
||||||
|
Runtime.getRuntime().runFinalization();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//don't use log.severe here as it will try to access db again
|
||||||
|
System.err.println("Failed to acquire new connection. Status=" + getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
if (exception != null)
|
||||||
|
throw exception;
|
||||||
|
return conn;
|
||||||
} // getCachedConnection
|
} // getCachedConnection
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create DataSource (Client)
|
* Create DataSource (Client)
|
||||||
|
@ -542,7 +615,26 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
{
|
{
|
||||||
if (m_ds != null)
|
if (m_ds != null)
|
||||||
return m_ds;
|
return m_ds;
|
||||||
|
|
||||||
|
URL url = Ini.isClient()
|
||||||
|
? PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/client.properties")
|
||||||
|
: PostgreSQLBundleActivator.bundleContext.getBundle().getEntry("META-INF/pool/server.properties");
|
||||||
|
Properties poolProperties = new Properties();
|
||||||
|
try {
|
||||||
|
poolProperties.load(url.openStream());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new DBException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
int idleConnectionTestPeriod = getIntProperty(poolProperties, "IdleConnectionTestPeriod", 1200);
|
||||||
|
int acquireRetryAttempts = getIntProperty(poolProperties, "AcquireRetryAttempts", 2);
|
||||||
|
int maxIdleTimeExcessConnections = getIntProperty(poolProperties, "MaxIdleTimeExcessConnections", 1200);
|
||||||
|
int maxIdleTime = getIntProperty(poolProperties, "MaxIdleTime", 1200);
|
||||||
|
int unreturnedConnectionTimeout = getIntProperty(poolProperties, "UnreturnedConnectionTimeout", 0);
|
||||||
|
boolean testConnectionOnCheckin = getBooleanProperty(poolProperties, "TestConnectionOnCheckin", false);
|
||||||
|
boolean testConnectionOnCheckout = getBooleanProperty(poolProperties, "TestConnectionOnCheckout", false);
|
||||||
|
int checkoutTimeout = getIntProperty(poolProperties, "CheckoutTimeout", 0);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
|
System.setProperty("com.mchange.v2.log.MLog", "com.mchange.v2.log.FallbackMLog");
|
||||||
|
@ -555,34 +647,44 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
cpds.setUser(connection.getDbUid());
|
cpds.setUser(connection.getDbUid());
|
||||||
cpds.setPassword(connection.getDbPwd());
|
cpds.setPassword(connection.getDbPwd());
|
||||||
cpds.setPreferredTestQuery(DEFAULT_CONN_TEST_SQL);
|
cpds.setPreferredTestQuery(DEFAULT_CONN_TEST_SQL);
|
||||||
cpds.setIdleConnectionTestPeriod(1200);
|
cpds.setIdleConnectionTestPeriod(idleConnectionTestPeriod);
|
||||||
//cpds.setTestConnectionOnCheckin(true);
|
cpds.setMaxIdleTimeExcessConnections(maxIdleTimeExcessConnections);
|
||||||
//cpds.setTestConnectionOnCheckout(true);
|
cpds.setMaxIdleTime(maxIdleTime);
|
||||||
cpds.setAcquireRetryAttempts(2);
|
cpds.setTestConnectionOnCheckin(testConnectionOnCheckin);
|
||||||
//cpds.setCheckoutTimeout(60);
|
cpds.setTestConnectionOnCheckout(testConnectionOnCheckout);
|
||||||
|
cpds.setAcquireRetryAttempts(acquireRetryAttempts);
|
||||||
|
if (checkoutTimeout > 0)
|
||||||
|
cpds.setCheckoutTimeout(checkoutTimeout);
|
||||||
|
|
||||||
if (Ini.isClient())
|
if (Ini.isClient())
|
||||||
{
|
{
|
||||||
cpds.setInitialPoolSize(1);
|
int maxPoolSize = getIntProperty(poolProperties, "MaxPoolSize", 15);
|
||||||
cpds.setMinPoolSize(1);
|
int initialPoolSize = getIntProperty(poolProperties, "InitialPoolSize", 1);
|
||||||
cpds.setMaxPoolSize(15);
|
int minPoolSize = getIntProperty(poolProperties, "MinPoolSize", 1);
|
||||||
cpds.setMaxIdleTimeExcessConnections(1200);
|
cpds.setInitialPoolSize(initialPoolSize);
|
||||||
cpds.setMaxIdleTime(900);
|
cpds.setMinPoolSize(minPoolSize);
|
||||||
m_maxbusyconnections = 10;
|
cpds.setMaxPoolSize(maxPoolSize);
|
||||||
|
|
||||||
|
m_maxbusyconnections = (int) (maxPoolSize * 0.9);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cpds.setInitialPoolSize(10);
|
int maxPoolSize = getIntProperty(poolProperties, "MaxPoolSize", 400);
|
||||||
cpds.setMinPoolSize(5);
|
int initialPoolSize = getIntProperty(poolProperties, "InitialPoolSize", 10);
|
||||||
cpds.setMaxPoolSize(150);
|
int minPoolSize = getIntProperty(poolProperties, "MinPoolSize", 5);
|
||||||
cpds.setMaxIdleTimeExcessConnections(1200);
|
cpds.setInitialPoolSize(initialPoolSize);
|
||||||
cpds.setMaxIdleTime(1200);
|
cpds.setInitialPoolSize(initialPoolSize);
|
||||||
m_maxbusyconnections = 120;
|
cpds.setMinPoolSize(minPoolSize);
|
||||||
|
cpds.setMaxPoolSize(maxPoolSize);
|
||||||
|
m_maxbusyconnections = (int) (maxPoolSize * 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
//the following sometimes kill active connection!
|
if (unreturnedConnectionTimeout > 0)
|
||||||
//cpds.setUnreturnedConnectionTimeout(1200);
|
{
|
||||||
//cpds.setDebugUnreturnedConnectionStackTraces(true);
|
//the following sometimes kill active connection!
|
||||||
|
cpds.setUnreturnedConnectionTimeout(1200);
|
||||||
|
cpds.setDebugUnreturnedConnectionStackTraces(true);
|
||||||
|
}
|
||||||
|
|
||||||
m_ds = cpds;
|
m_ds = cpds;
|
||||||
}
|
}
|
||||||
|
@ -591,7 +693,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
m_ds = null;
|
m_ds = null;
|
||||||
log.log(Level.SEVERE, "Could not initialise C3P0 Datasource", ex);
|
log.log(Level.SEVERE, "Could not initialise C3P0 Datasource", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_ds;
|
return m_ds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +706,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException("Not supported/implemented");
|
throw new UnsupportedOperationException("Not supported/implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Connection from Driver
|
* Get Connection from Driver
|
||||||
* @param connection info
|
* @param connection info
|
||||||
|
@ -613,7 +715,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
public Connection getDriverConnection (CConnection connection) throws SQLException
|
public Connection getDriverConnection (CConnection connection) throws SQLException
|
||||||
{
|
{
|
||||||
getDriver();
|
getDriver();
|
||||||
return DriverManager.getConnection (getConnectionURL (connection),
|
return DriverManager.getConnection (getConnectionURL (connection),
|
||||||
connection.getDbUid(), connection.getDbPwd());
|
connection.getDbUid(), connection.getDbPwd());
|
||||||
} // getDriverConnection
|
} // getDriverConnection
|
||||||
|
|
||||||
|
@ -625,7 +727,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
* @return connection
|
* @return connection
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
public Connection getDriverConnection (String dbUrl, String dbUid, String dbPwd)
|
public Connection getDriverConnection (String dbUrl, String dbUid, String dbPwd)
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
getDriver();
|
getDriver();
|
||||||
|
@ -638,9 +740,9 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
*/
|
*/
|
||||||
public void close()
|
public void close()
|
||||||
{
|
{
|
||||||
|
|
||||||
log.config(toString());
|
log.config(toString());
|
||||||
|
|
||||||
if (m_ds != null)
|
if (m_ds != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -651,11 +753,11 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
{
|
{
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_ds = null;
|
m_ds = null;
|
||||||
} // close
|
} // close
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check and generate an alternative SQL
|
* Check and generate an alternative SQL
|
||||||
* @reExNo number of re-execution
|
* @reExNo number of re-execution
|
||||||
|
@ -667,7 +769,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
{
|
{
|
||||||
return null; //do not do re-execution of alternative SQL
|
return null; //do not do re-execution of alternative SQL
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get constraint type associated with the index
|
* Get constraint type associated with the index
|
||||||
* @tableName table name
|
* @tableName table name
|
||||||
|
@ -675,7 +777,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
* @return String[0] = 0: do not know, 1: Primary Key 2: Foreign Key
|
* @return String[0] = 0: do not know, 1: Primary Key 2: Foreign Key
|
||||||
* String[1] - String[n] = Constraint Name
|
* String[1] - String[n] = Constraint Name
|
||||||
*/
|
*/
|
||||||
public String getConstraintType(Connection conn, String tableName, String IXName)
|
public String getConstraintType(Connection conn, String tableName, String IXName)
|
||||||
{
|
{
|
||||||
if (IXName == null || IXName.length()==0)
|
if (IXName == null || IXName.length()==0)
|
||||||
return "0";
|
return "0";
|
||||||
|
@ -685,8 +787,8 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
return "0";
|
return "0";
|
||||||
//jz temp, modify later from user.constraints
|
//jz temp, modify later from user.constraints
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if DBMS support the sql statement
|
* Check if DBMS support the sql statement
|
||||||
* @sql SQL statement
|
* @sql SQL statement
|
||||||
* @return true: yes
|
* @return true: yes
|
||||||
|
@ -696,7 +798,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
return true;
|
return true;
|
||||||
//jz temp, modify later
|
//jz temp, modify later
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump table lock info to console for current transaction
|
* Dump table lock info to console for current transaction
|
||||||
* @param conn
|
* @param conn
|
||||||
|
@ -710,7 +812,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
ResultSet rs = stmt.executeQuery(sql);
|
ResultSet rs = stmt.executeQuery(sql);
|
||||||
int cnt = rs.getMetaData().getColumnCount();
|
int cnt = rs.getMetaData().getColumnCount();
|
||||||
System.out.println();
|
System.out.println();
|
||||||
while (rs.next())
|
while (rs.next())
|
||||||
{
|
{
|
||||||
for(int i = 0; i < cnt; i++)
|
for(int i = 0; i < cnt; i++)
|
||||||
{
|
{
|
||||||
|
@ -723,7 +825,7 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
}
|
}
|
||||||
System.out.println();
|
System.out.println();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
try{
|
try{
|
||||||
if (stmt != null)
|
if (stmt != null)
|
||||||
|
@ -731,50 +833,14 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Test
|
|
||||||
* @param args ignored
|
|
||||||
*/
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
DB_PostgreSQL postgresql = new DB_PostgreSQL();
|
|
||||||
//
|
|
||||||
String databaseName = "adempiere";
|
|
||||||
String uid = "adempiere";
|
|
||||||
String pwd = "adempiere";
|
|
||||||
String jdbcURL = postgresql.getConnectionURL("vpj", DEFAULT_PORT, databaseName, uid);
|
|
||||||
System.out.println(jdbcURL);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
postgresql.getDriver();
|
|
||||||
Connection conn = DriverManager.getConnection (jdbcURL, uid, pwd);
|
|
||||||
|
|
||||||
//CachedRowSetImpl crs = null;
|
|
||||||
//crs = new CachedRowSetImpl();
|
|
||||||
//crs.setSyncProvider("com.sun.rowset.providers.RIOptimisticProvider");
|
|
||||||
//crs.setConcurrency(ResultSet.CONCUR_READ_ONLY);
|
|
||||||
//crs.setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
|
|
||||||
//crs.setCommand("SELECT * FROM AD_Client");
|
|
||||||
//
|
|
||||||
//crs.execute(conn);
|
|
||||||
//
|
|
||||||
conn.close();
|
|
||||||
conn = null;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
} // main
|
|
||||||
|
|
||||||
public int getNextID(String name) {
|
public int getNextID(String name) {
|
||||||
|
|
||||||
int m_sequence_id = DB.getSQLValue(null, "SELECT nextval('"+name.toLowerCase()+"')");
|
int m_sequence_id = DB.getSQLValue(null, "SELECT nextval('"+name.toLowerCase()+"')");
|
||||||
return m_sequence_id;
|
return m_sequence_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
// 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());
|
||||||
|
@ -784,9 +850,9 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
if (cnt == 0)
|
if (cnt == 0)
|
||||||
{
|
{
|
||||||
no = DB.executeUpdate("CREATE SEQUENCE "+name.toUpperCase()
|
no = DB.executeUpdate("CREATE SEQUENCE "+name.toUpperCase()
|
||||||
+ " INCREMENT " + increment
|
+ " INCREMENT " + increment
|
||||||
+ " MINVALUE " + minvalue
|
+ " MINVALUE " + minvalue
|
||||||
+ " MAXVALUE " + maxvalue
|
+ " MAXVALUE " + maxvalue
|
||||||
+ " START " + start , trxName);
|
+ " START " + start , trxName);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
|
@ -794,14 +860,14 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
no = DB.executeUpdate("ALTER SEQUENCE "+name.toUpperCase()
|
no = DB.executeUpdate("ALTER SEQUENCE "+name.toUpperCase()
|
||||||
+ " INCREMENT " + increment
|
+ " INCREMENT " + increment
|
||||||
+ " MINVALUE " + minvalue
|
+ " MINVALUE " + minvalue
|
||||||
+ " MAXVALUE " + maxvalue
|
+ " MAXVALUE " + maxvalue
|
||||||
+ " RESTART " + start , trxName);
|
+ " RESTART " + start , trxName);
|
||||||
}
|
}
|
||||||
if(no == -1 )
|
if(no == -1 )
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,4 +890,30 @@ public class DB_PostgreSQL implements AdempiereDatabase
|
||||||
public boolean isPagingSupported() {
|
public boolean isPagingSupported() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getIntProperty(Properties properties, String key, int defaultValue)
|
||||||
|
{
|
||||||
|
int i = defaultValue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String s = properties.getProperty(key);
|
||||||
|
if (s != null && s.trim().length() > 0)
|
||||||
|
i = Integer.parseInt(s);
|
||||||
|
}
|
||||||
|
catch (Exception e) {}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean getBooleanProperty(Properties properties, String key, boolean defaultValue)
|
||||||
|
{
|
||||||
|
boolean b = defaultValue;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String s = properties.getProperty(key);
|
||||||
|
if (s != null && s.trim().length() > 0)
|
||||||
|
b = Boolean.valueOf(s);
|
||||||
|
}
|
||||||
|
catch (Exception e) {}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
} // DB_PostgreSQL
|
} // DB_PostgreSQL
|
||||||
|
|
Loading…
Reference in New Issue