@Override final UniqueKey<R> getPrimaryKey() { return getTable().getPrimaryKey(); }
@Override final UniqueKey<R> getPrimaryKey() { return getTable().getPrimaryKey(); }
@SuppressWarnings("deprecation") private final void addConditionForVersionAndTimestamp(org.jooq.ConditionProvider query) { TableField<R, ?> v = getTable().getRecordVersion(); TableField<R, ?> t = getTable().getRecordTimestamp(); if (v != null) Utils.addCondition(query, this, v); if (t != null) Utils.addCondition(query, this, t); }
@SuppressWarnings("deprecation") private final void addConditionForVersionAndTimestamp(org.jooq.ConditionProvider query) { TableField<R, ?> v = getTable().getRecordVersion(); TableField<R, ?> t = getTable().getRecordTimestamp(); if (v != null) Tools.addCondition(query, this, v); if (t != null) Tools.addCondition(query, this, t); }
private final Collection<Field<?>> getReturning() { Collection<Field<?>> result = new LinkedHashSet<Field<?>>(); Identity<R, ?> identity = getTable().getIdentity(); if (identity != null) { result.add(identity.getField()); } result.addAll(getPrimaryKey().getFields()); return result; }
/** * Set an updated timestamp value to a store query */ private final Timestamp addRecordTimestamp(StoreQuery<?> store) { Timestamp result = null; if (isTimestampOrVersionAvailable()) { TableField<R, ? extends java.util.Date> timestamp = getTable().getRecordTimestamp(); if (timestamp != null) { // Use Timestamp locally, to provide maximum precision result = new Timestamp(System.currentTimeMillis()); addValue(store, timestamp, result); } } return result; }
/** * Set an updated version value to a store query */ private final BigInteger addRecordVersion(StoreQuery<?> store) { BigInteger result = null; if (isTimestampOrVersionAvailable()) { TableField<R, ? extends Number> version = getTable().getRecordVersion(); if (version != null) { Number value = getValue(version); // Use BigInteger locally to avoid arithmetic overflows if (value == null) { result = BigInteger.ONE; } else { result = new BigInteger(value.toString()).add(BigInteger.ONE); } addValue(store, version, result); } } return result; }
@Override public final R copy() { return Utils.newRecord(getTable(), configuration()) .operate(new RecordOperation<R, RuntimeException>() { @Override public R operate(R copy) throws RuntimeException { // Copy all fields. This marks them all as isChanged, which is important List<TableField<R, ?>> key = getPrimaryKey().getFields(); for (Field<?> field : fields.fields.fields) { // Don't copy key values if (!key.contains(field)) { setValue(copy, field); } } return copy; } /** * Extracted method to ensure generic type safety. */ private final <T> void setValue(Record record, Field<T> field) { record.setValue(field, getValue(field)); } }); }
@Override public final R copy() { // [#3359] The "fetched" flag must be set to false to enforce INSERT statements on // subsequent store() calls - when Settings.updatablePrimaryKeys is set. return Tools.newRecord(false, getTable(), configuration()) .operate(new RecordOperation<R, RuntimeException>() { @Override public R operate(R copy) throws RuntimeException { // Copy all fields. This marks them all as isChanged, which is important List<TableField<R, ?>> key = getPrimaryKey().getFields(); for (Field<?> field : fields.fields.fields) { // Don't copy key values if (!key.contains(field)) { setValue(copy, field); } } return copy; } /** * Extracted method to ensure generic type safety. */ private final <T> void setValue(Record record, Field<T> field) { record.set(field, get(field)); } }); }
/** * Set a generated version and timestamp value onto this record after * successfully storing the record. */ private final void setRecordVersionAndTimestamp(BigInteger version, Timestamp timestamp) { if (version != null) { TableField<R, ?> field = getTable().getRecordVersion(); setValue(field, new Value<Object>(field.getDataType().convert(version))); } if (timestamp != null) { TableField<R, ?> field = getTable().getRecordTimestamp(); setValue(field, new Value<Object>(field.getDataType().convert(timestamp))); } } }
/** * Perform an additional SELECT .. FOR UPDATE to check if the underlying * database record has been changed compared to this record. */ private final void checkIfChanged(TableField<R, ?>[] keys) { SelectQuery<R> select = create().selectQuery(getTable()); Utils.addConditions(select, this, keys); // [#1547] MS Access and SQLite doesn't support FOR UPDATE. CUBRID and SQL Server // can simulate it, though! if (!asList(SQLITE).contains(create().configuration().dialect().family())) { select.setForUpdate(true); } R record = select.fetchOne(); if (record == null) { throw new DataChangedException("Database record no longer exists"); } for (Field<?> field : fields.fields.fields) { Value<?> thisValue = getValue0(field); Value<?> thatValue = ((AbstractRecord) record).getValue0(field); Object thisObject = thisValue.getOriginal(); Object thatObject = thatValue.getOriginal(); if (!StringUtils.equals(thisObject, thatObject)) { throw new DataChangedException("Database record has been changed"); } } }
/** * Perform an additional SELECT .. FOR UPDATE to check if the underlying * database record has been changed compared to this record. */ private final void checkIfChanged(TableField<R, ?>[] keys) { SelectQuery<R> select = create().selectQuery(getTable()); Tools.addConditions(select, this, keys); // [#1547] MS Access and SQLite doesn't support FOR UPDATE. CUBRID and SQL Server // can emulate it, though! if (!NO_SUPPORT_FOR_UPDATE.contains(create().configuration().dialect().family())) select.setForUpdate(true); R record = select.fetchOne(); if (record == null) throw new DataChangedException("Database record no longer exists"); for (Field<?> field : fields.fields.fields) { Object thisObject = original(field); Object thatObject = record.original(field); if (!StringUtils.equals(thisObject, thatObject)) throw new DataChangedException("Database record has been changed"); } }
private final int storeInsert0() { DSLContext create = create(); InsertQuery<R> insert = create.insertQuery(getTable()); addChangedValues(insert);
private final int delete0() { TableField<R, ?>[] keys = getPrimaryKey().getFieldsArray(); try { DeleteQuery<R> delete1 = create().deleteQuery(getTable()); Utils.addConditions(delete1, this, keys); if (isExecuteWithOptimisticLocking()) { // [#1596] Add additional conditions for version and/or timestamp columns if (isTimestampOrVersionAvailable()) { addConditionForVersionAndTimestamp(delete1); } // [#1547] Try fetching the Record again first, and compare this // Record's original values with the ones in the database else { checkIfChanged(keys); } } int result = delete1.execute(); checkIfChanged(result, null, null); return result; } // [#673] If store() is called after delete(), a new INSERT should // be executed and the record should be recreated finally { changed(true); } }
@Override public final void refresh(final Field<?>... refreshFields) { SelectQuery<Record> select = create().selectQuery(); select.addSelect(refreshFields); select.addFrom(getTable()); Tools.addConditions(select, this, getPrimaryKey().getFieldsArray()); if (select.execute() == 1) { final AbstractRecord source = (AbstractRecord) select.getResult().get(0); delegate(configuration(), (Record) this, REFRESH) .operate(new RecordOperation<Record, RuntimeException>() { @Override public Record operate(Record record) throws RuntimeException { setValues(refreshFields, source); return record; } }); } else { throw new NoDataFoundException("Exactly one row expected for refresh. Record does not exist in database."); } }
@Override public final void refresh(final Field<?>... f) { SelectQuery<Record> select = create().selectQuery(); select.addSelect(f); select.addFrom(getTable()); Utils.addConditions(select, this, getPrimaryKey().getFieldsArray()); if (select.execute() == 1) { final AbstractRecord source = (AbstractRecord) select.getResult().get(0); delegate(configuration(), (Record) this, REFRESH) .operate(new RecordOperation<Record, RuntimeException>() { @Override public Record operate(Record record) throws RuntimeException { setValues(f, source); return record; } }); } else { throw new InvalidResultException("Exactly one row expected for refresh. Record does not exist in database."); } }
private final int delete0() { TableField<R, ?>[] keys = getPrimaryKey().getFieldsArray(); try { DeleteQuery<R> delete1 = create().deleteQuery(getTable()); Tools.addConditions(delete1, this, keys); if (isExecuteWithOptimisticLocking()) { // [#1596] Add additional conditions for version and/or timestamp columns if (isTimestampOrVersionAvailable()) { addConditionForVersionAndTimestamp(delete1); } // [#1547] Try fetching the Record again first, and compare this // Record's original values with the ones in the database // [#5384] Do this only if the exclusion flag for unversioned records is off else if (isExecuteWithOptimisticLockingIncludeUnversioned()) { checkIfChanged(keys); } } int result = delete1.execute(); checkIfChanged(result, null, null); return result; } // [#673] [#3363] If store() is called after delete(), a new INSERT should // be executed and the record should be recreated finally { changed(true); fetched = false; } }
private final int storeUpdate0(TableField<R, ?>[] keys) { UpdateQuery<R> update = create().updateQuery(getTable()); addChangedValues(update); Utils.addConditions(update, this, keys); // Don't store records if no value was set by client code if (!update.isExecutable()) return 0; // [#1596] Set timestamp and/or version columns to appropriate values BigInteger version = addRecordVersion(update); Timestamp timestamp = addRecordTimestamp(update); if (isExecuteWithOptimisticLocking()) { // [#1596] Add additional conditions for version and/or timestamp columns if (isTimestampOrVersionAvailable()) { addConditionForVersionAndTimestamp(update); } // [#1547] Try fetching the Record again first, and compare this // Record's original values with the ones in the database else { checkIfChanged(keys); } } // [#1596] Check if the record was really changed in the database int result = update.execute(); checkIfChanged(result, version, timestamp); if (result > 0) { changed(false); } return result; }
private final int storeUpdate0(Field<?>[] storeFields, TableField<R, ?>[] keys) { UpdateQuery<R> update = create().updateQuery(getTable()); addChangedValues(storeFields, update); Tools.addConditions(update, this, keys);