in empire-db/src/main/java/org/apache/empire/db/DBRowSet.java [1031:1185]
public <R extends DBRecordBase> void updateRecord(R record)
{
// check updateable
if (isUpdateable()==false)
throw new NotSupportedException(this, "updateRecord");
// Check Arguments
checkParamRecord(record, true);
// the connection
DBContext context = record.getContext();
Connection conn = context.getConnection();
// Get the new Timestamp
String name = getName();
Timestamp timestamp = (timestampColumn!=null) ? context.getDbms().getUpdateTimestamp(conn) : null;
DBMSHandler.DBSetGenKeys setGenKey = null;
// Get the fields and the flags
Object[] fields = record.getFields();
// Build SQL-Statement
DBCommand cmd = createRecordCommand(context);
String sql = null;
int setCount = 0;
// Perform action
DBColumn[] keyColumns = getKeyColumns();
DBRecordBase.State recordState = record.getState();
if (recordState==DBRecordBase.State.New)
{ // Insert Record
for (int i = 0; i < columns.size(); i++)
{ // search for the column
Object value = fields[i];
DBTableColumn col = (DBTableColumn) columns.get(i);
if (timestampColumn == col)
{ // Make sure the update timestamp column is set
if (timestamp!=null)
cmd.set(col.to(timestamp));
continue;
}
boolean empty = (value==ObjectUtils.NO_VALUE || ObjectUtils.isEmpty(value));
if (empty && col.isAutoGenerated())
{ // Check for AutoInc data type
if (col.getDataType()==DataType.AUTOINC &&
db.getDbms().isSupported(DBMSFeature.SEQUENCES)==false)
{ // Obtain value via JDBC Statement.RETURN_GENERATED_KEYS
setGenKey = new DBSetRecordKey(fields, i);
continue;
}
// get the auto-generated field value
fields[i] = value = col.getRecordDefaultValue(conn);
empty = ObjectUtils.isEmpty(value);
}
// Add the value to the command
if (empty==false)
{ // *** unnecessary check removed 2.5.0 ***
// if (col.isAutoGenerated()==false && rec.isValidateFieldValues())
// col.validate(value);
// Insert a field
cmd.set(col.to(value));
setCount++;
}
else if (ObjectUtils.contains(keyColumns, col))
{ // All primary key fields must be supplied
throw new FieldNotNullException(col);
}
else if (col.isRequired())
{ // Error Column is required!
throw new FieldNotNullException(col);
}
}
sql = cmd.getInsert();
}
else if (recordState==DBRecordBase.State.Modified)
{ // Update Record
if (keyColumns == null)
{ // Requires a primary key
log.error("updateRecord: " + name + " no primary key defined!");
throw new NoPrimaryKeyException(this);
}
for (int i = 0; i < columns.size(); i++)
{ // search for the column
Object value = fields[i];
// check for NO_VALUE
if (value==ObjectUtils.NO_VALUE)
{ // Timestamp?
if (timestampColumn == columns.get(i))
log.info("Record has no value for timestamp column. Concurrent changes will not be detected.");
// next
continue;
}
boolean modified = record.wasModified(i);
boolean empty = ObjectUtils.isEmpty(value);
DBTableColumn col = (DBTableColumn) columns.get(i);
if (ObjectUtils.contains(keyColumns, col))
{ // Check for Modification
if (modified == true)
{ // Requires a primary key
log.warn("updateRecord: " + name + " primary has been modified!");
}
// set pk constraint
cmd.where(col.is(value));
}
else if (timestampColumn == col)
{ // Check the update-timestamp
if (empty==false)
{ // set timestamp constraint
cmd.where(col.is(value));
}
// set new timestamp
if (timestamp!=null)
cmd.set(col.to(timestamp));
}
else if (modified)
{ // Update a field
if (col.isReadOnly())
log.warn("updateRecord: Read-only column '" + col.getName() + " has been modified!");
// Set the column
cmd.set(col.to(value));
setCount++;
}
}
// Get the SQL statement
sql = cmd.getUpdate();
}
else
{ // Not modified
log.info("updateRecord: " + name + " record has not been modified! ");
return;
}
if (setCount == 0)
{ // Nothing to update
log.info("updateRecord: " + name + " nothing to update or insert!");
return;
}
// Perform action
DBUtils utils = context.getUtils();
int affected = utils.executeSQL(sql, cmd.getParamValues(), setGenKey);
if (affected < 0)
{ // Update Failed
throw new UnexpectedReturnValueException(affected, "db.executeSQL()");
}
else if (affected == 0)
{ // Record not found
throw new RecordUpdateFailedException(this, record.getKey());
}
else if (affected > 1)
{ // Multiple Records affected
throw new RecordUpdateAmbiguousException(this, record.getKey());
}
// Correct Timestamp
if (timestampColumn!=null && timestamp!=null)
{ // Set the correct Timestamp
int i = record.getFieldIndex(timestampColumn);
if (i >= 0)
fields[i] = timestamp;
}
// Change State
record.updateComplete();
}