public void updateRecord()

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();        
    }