You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2009/02/08 12:40:53 UTC
svn commit: r742064 - in
/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db:
DBColumn.java DBDatabase.java DBDatabaseDriver.java DBRowSet.java
DBSQLScript.java mysql/DBDatabaseDriverMySQL.java
sqlserver/DBDatabaseDriverMSSQL.java
Author: doebele
Date: Sun Feb 8 11:40:52 2009
New Revision: 742064
URL: http://svn.apache.org/viewvc?rev=742064&view=rev
Log:
EMPIREDB-34
Modified:
incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBColumn.java
incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabase.java
incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabaseDriver.java
incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBRowSet.java
incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBSQLScript.java
incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
Modified: incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBColumn.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBColumn.java?rev=742064&r1=742063&r2=742064&view=diff
==============================================================================
--- incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBColumn.java (original)
+++ incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBColumn.java Sun Feb 8 11:40:52 2009
@@ -45,6 +45,8 @@
// Predefined column attributes
public static final String DBCOLATTR_MANDATORY = "mandatory";
public static final String DBCOLATTR_READONLY = "readonly";
+ public static final String DBCOLATTR_MINVALUE = "minValue";
+ public static final String DBCOLATTR_MAXVALUE = "maxValue";
// basic data
protected final DBRowSet rowset;
Modified: incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabase.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabase.java?rev=742064&r1=742063&r2=742064&view=diff
==============================================================================
--- incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabase.java (original)
+++ incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabase.java Sun Feb 8 11:40:52 2009
@@ -948,7 +948,7 @@
* @param conn a valid connection to the database.
* @return the row count for insert, update or delete or 0 for SQL statements that return nothing
*/
- public int executeSQL(String sqlCmd, Object[] sqlParams, Connection conn)
+ public int executeSQL(String sqlCmd, Object[] sqlParams, Connection conn, DBDatabaseDriver.DBSetGenKeys setGenKeys)
{
try
{
@@ -960,7 +960,7 @@
log.info("Executing: " + sqlCmd);
// execute SQL
long start = System.currentTimeMillis();
- int affected = driver.executeSQL(sqlCmd, sqlParams, conn);
+ int affected = driver.executeSQL(sqlCmd, sqlParams, conn, setGenKeys);
// Log
if (log.isInfoEnabled())
log.info("executeSQL affected " + String.valueOf(affected) + " Records / " + (System.currentTimeMillis() - start) + "ms");
@@ -980,6 +980,11 @@
}
}
+ public final int executeSQL(String sqlCmd, Object[] sqlParams, Connection conn)
+ {
+ return executeSQL(sqlCmd, sqlParams, conn, null);
+ }
+
/**
* Executes an update, insert or delete SQL-Statement.<BR>
* We recommend to use a DBCommand object in order to build the sqlCmd.<BR>
Modified: incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabaseDriver.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabaseDriver.java?rev=742064&r1=742063&r2=742064&view=diff
==============================================================================
--- incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabaseDriver.java (original)
+++ incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBDatabaseDriver.java Sun Feb 8 11:40:52 2009
@@ -115,8 +115,18 @@
"select", "udpate", "insert", "alter", "delete" };
protected final Set<String> reservedSQLKeywords;
+ /**
+ * This interface is used to set the auto generated keys when executing insert statements.
+ */
+ public interface DBSetGenKeys
+ {
+ void set(Object value);
+ }
- // DBSeqTable
+ /**
+ * This class is used to emulate sequences by using a sequence table.
+ * It is used with the executeSQL function and only required for insert statements
+ */
public static class DBSeqTable extends DBTable
{
public DBColumn C_SEQNAME;
@@ -319,20 +329,6 @@
public abstract Object getNextSequenceValue(DBDatabase db, String SeqName, int minValue, Connection conn);
/**
- * Returns the value of an AutoIncrement field for the last inserted record.<BR>
- * This function is only used for databases that do not support sequences.<BR>
- * Hence getNextSequenceValue() must return 'null'
- * @param db the database
- * @param conn a valid database connection
- * @return the id of the last inserted record null if this feature is not supported
- */
- public Object getPostInsertAutoIncValue(DBDatabase db, Connection conn)
- {
- error(Errors.NotSupported);
- return null;
- }
-
- /**
* Prepares an sql statement by setting the supplied objects as parameters.
*
* @param pstmt the prepared statement
@@ -414,26 +410,41 @@
* @param sqlCmd the SQL-Command
* @param sqlParams array of sql command parameters used for prepared statements (Optional).
* @param conn a valid connection to the database.
+ * @param seqValue allows to set the auto generated key of a record (INSERT statements only)
* @return the row count for insert, update or delete or 0 for SQL statements that return nothing
*/
- public int executeSQL(String sqlCmd, Object[] sqlParams, Connection conn)
+ public int executeSQL(String sqlCmd, Object[] sqlParams, Connection conn, DBSetGenKeys genKeys)
throws SQLException
{ // Execute the Statement
Statement stmt = null;
try
{
+ int count = 0;
+ int retGenKeys = (genKeys!=null) ? Statement.RETURN_GENERATED_KEYS
+ : Statement.NO_GENERATED_KEYS;
if (sqlParams!=null)
- {
- PreparedStatement pstmt = conn.prepareStatement(sqlCmd);
- stmt = pstmt;
+ { // Use a prepared statement
+ PreparedStatement pstmt = conn.prepareStatement(sqlCmd, retGenKeys);
prepareStatement(pstmt, sqlParams);
- return pstmt.executeUpdate();
+ count = pstmt.executeUpdate();
}
else
{ // Execute a simple statement
stmt = conn.createStatement();
- return stmt.executeUpdate(sqlCmd);
+ count = stmt.executeUpdate(sqlCmd, retGenKeys);
+ }
+ // Retrieve any auto-generated keys
+ if (genKeys!=null)
+ { // Return Keys
+ ResultSet rs = stmt.getGeneratedKeys();
+ try {
+ while(rs.next())
+ genKeys.set(rs.getObject(1));
+ } finally {
+ rs.close();
+ }
}
+ return count;
} finally
{ // Close
close(stmt);
Modified: incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBRowSet.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBRowSet.java?rev=742064&r1=742063&r2=742064&view=diff
==============================================================================
--- incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBRowSet.java (original)
+++ incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBRowSet.java Sun Feb 8 11:40:52 2009
@@ -47,6 +47,25 @@
*/
public abstract class DBRowSet extends DBExpr
{
+ /**
+ * This class is used to set the auto generated key of a record if the database does not support sequences.
+ * It is used with the executeSQL function and only required for insert statements
+ */
+ private static class DBSetGenKey implements DBDatabaseDriver.DBSetGenKeys
+ {
+ private Object[] fields;
+ private int index;
+ public DBSetGenKey(Object[] fields, int index)
+ {
+ this.fields = fields;
+ this.index = index;
+ }
+ public void set(Object value)
+ {
+ fields[index]=value;
+ }
+ }
+
// Logger
@SuppressWarnings("hiding")
protected static Log log = LogFactory.getLog(DBRowSet.class);
@@ -559,13 +578,13 @@
// Get the new Timestamp
String name = getName();
Timestamp timestamp = (timestampColumn!=null) ? db.getUpdateTimestamp(conn) : null;
+ DBDatabaseDriver.DBSetGenKeys setGenKey = null;
// Get the fields and the flags
Object[] fields = rec.getFields();
// Build SQL-Statement
DBCommand cmd = db.createCommand();
String sql = null;
int setCount = 0;
- int autoIncFieldIndex = -1; // for post insert auto increment processing
switch (rec.getState())
{
case DBRecord.REC_MODIFIED:
@@ -622,7 +641,7 @@
{ // Set Autoinc value if not already done
if (db.getDriver().isSupported(DBDriverFeature.SEQUENCES)==false)
{ // Post Dectect Autoinc Value
- autoIncFieldIndex = i;
+ setGenKey = new DBSetGenKey(fields, i);
continue;
}
// Get Next Sequence value
@@ -663,7 +682,7 @@
return success();
}
// Perform action
- int affected = db.executeSQL(sql, cmd.getCmdParams(), conn);
+ int affected = db.executeSQL(sql, cmd.getCmdParams(), conn, setGenKey);
if (affected < 0)
{ // Update Failed
return error(db);
@@ -676,13 +695,6 @@
{ // Multiple Records affected
return error(DBErrors.RecordUpdateInvalid, name);
}
- // Post Insert Autoincrement processing
- if (autoIncFieldIndex>=0 && fields[autoIncFieldIndex]==null)
- { // Driver must supply the value
- fields[autoIncFieldIndex]=db.getDriver().getPostInsertAutoIncValue(db, conn);
- if (fields[autoIncFieldIndex]==null)
- return error(db.getDriver());
- }
// Correct Timestamp
if (timestampColumn != null)
{ // Set the correct Timestamp
Modified: incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBSQLScript.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBSQLScript.java?rev=742064&r1=742063&r2=742064&view=diff
==============================================================================
--- incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBSQLScript.java (original)
+++ incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/DBSQLScript.java Sun Feb 8 11:40:52 2009
@@ -110,7 +110,7 @@
try {
// Execute Statement
log.debug("Executing: " + stmt);
- driver.executeSQL(stmt, null, conn);
+ driver.executeSQL(stmt, null, conn, null);
} catch(SQLException e) {
// SQLException
log.error(e.toString(), e);
Modified: incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java?rev=742064&r1=742063&r2=742064&view=diff
==============================================================================
--- incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java (original)
+++ incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/mysql/DBDatabaseDriverMySQL.java Sun Feb 8 11:40:52 2009
@@ -148,7 +148,7 @@
try
{ // Set Database
if (StringUtils.isValid(databaseName))
- executeSQL("USE " + databaseName, null, conn);
+ executeSQL("USE " + databaseName, null, conn, null);
// Sequence Table
if (useSequenceTable && db.getTable(sequenceTableName)==null)
new DBSeqTable(sequenceTableName, db);
@@ -292,7 +292,7 @@
*/
@Override
public Object getNextSequenceValue(DBDatabase db, String seqName, int minValue, Connection conn)
- { //Use Oracle Sequences
+ {
if (useSequenceTable)
{ // Use a sequence Table to generate Sequences
DBTable t = db.getTable(sequenceTableName);
@@ -303,12 +303,6 @@
return null;
}
}
-
- @Override
- public Object getPostInsertAutoIncValue(DBDatabase db, Connection conn)
- {
- return db.querySingleInt("SELECT LAST_INSERT_ID()", conn);
- }
/**
* @see DBDatabaseDriver#getDDLScript(DBCmdType, DBObject, DBSQLScript)
Modified: incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java
URL: http://svn.apache.org/viewvc/incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java?rev=742064&r1=742063&r2=742064&view=diff
==============================================================================
--- incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java (original)
+++ incubator/empire-db/trunk/core/Empire-db/src/org/apache/empire/db/sqlserver/DBDatabaseDriverMSSQL.java Sun Feb 8 11:40:52 2009
@@ -24,6 +24,7 @@
import java.util.Iterator;
import org.apache.empire.commons.Errors;
+import org.apache.empire.commons.ObjectUtils;
import org.apache.empire.commons.StringUtils;
import org.apache.empire.data.DataType;
import org.apache.empire.db.DBCmdType;
@@ -66,6 +67,9 @@
private String databaseName = null;
private String objectOwner = "dbo";
private String sequenceTableName = "Sequences";
+ // Sequence treatment
+ // When set to 'false' (default) MySQL's autoincrement feature is used.
+ private boolean useSequenceTable = false;
/**
* Constructor for the MSSQL database driver.<br>
@@ -96,6 +100,26 @@
}
/**
+ * returns whether a sequence table is used for record identiy management.<br>
+ * Default is false. In this case the AutoIncrement feature of MySQL is used.
+ * @return true if a sequence table is used instead of identity columns.
+ */
+ public boolean isUseSequenceTable()
+ {
+ return useSequenceTable;
+ }
+
+ /**
+ * If set to true a special table is used for sequence number generation.<br>
+ * Otherwise the AutoIncrement feature of MySQL is used identiy fields.
+ * @param useSequenceTable true to use a sequence table or false otherwise.
+ */
+ public void setUseSequenceTable(boolean useSequenceTable)
+ {
+ this.useSequenceTable = useSequenceTable;
+ }
+
+ /**
* returns the name of the sequence table
* @return the name of the table used for sequence number generation
*/
@@ -125,11 +149,11 @@
try
{ // Set Database
if (StringUtils.isValid(databaseName))
- executeSQL("USE " + databaseName, null, conn);
+ executeSQL("USE " + databaseName, null, conn, null);
// Set Dateformat
- executeSQL("SET DATEFORMAT ymd", null, conn);
+ executeSQL("SET DATEFORMAT ymd", null, conn, null);
// Sequence Table
- if (db.getTable(sequenceTableName)==null)
+ if (useSequenceTable && db.getTable(sequenceTableName)==null)
new DBSeqTable(sequenceTableName, db);
// Check Schema
String schema = db.getSchema();
@@ -171,7 +195,7 @@
switch (type)
{ // return support info
case CREATE_SCHEMA: return true;
- case SEQUENCES: return true;
+ case SEQUENCES: return useSequenceTable;
}
return false;
}
@@ -282,9 +306,16 @@
*/
@Override
public Object getNextSequenceValue(DBDatabase db, String seqName, int minValue, Connection conn)
- { //Use Oracle Sequences
- DBTable t = db.getTable(sequenceTableName);
- return ((DBSeqTable)t).getNextValue(seqName, minValue, conn);
+ {
+ if (useSequenceTable)
+ { // Use a sequence Table to generate Sequences
+ DBTable t = db.getTable(sequenceTableName);
+ return ((DBSeqTable)t).getNextValue(seqName, minValue, conn);
+ }
+ else
+ { // Post Detection
+ return null;
+ }
}
/**
@@ -511,6 +542,14 @@
break;
case AUTOINC:
sql.append("[int]");
+ if (useSequenceTable==false)
+ { // Make this column the identity column
+ int minValue = ObjectUtils.getInteger(c.getAttribute(DBColumn.DBCOLATTR_MINVALUE), 1);
+ sql.append(" IDENTITY(");
+ sql.append(String.valueOf(minValue));
+ sql.append(", 1) NOT NULL");
+ return true;
+ }
break;
case TEXT:
{ // Check fixed or variable length