package org.jooq.impl;
import static java.util.Arrays.asList;
import static org.jooq.conf.SettingsTools.updatablePrimaryKeys;
import static org.jooq.impl.Tools.EMPTY_FIELD;
import static org.jooq.impl.Tools.converterOrFail;
import static org.jooq.impl.Tools.embeddedFields;
import static org.jooq.impl.Tools.indexFail;
import static org.jooq.impl.Tools.indexOrFail;
import static org.jooq.impl.Tools.resetChangedOnNotNull;
import static org.jooq.impl.Tools.settings;
import static org.jooq.impl.Tools.ThreadGuard.Guard.RECORD_TOSTRING;
import java.io.Writer;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import org.jooq.Attachable;
import org.jooq.CSVFormat;
import org.jooq.ChartFormat;
import org.jooq.Converter;
import org.jooq.DataType;
import org.jooq.EmbeddableRecord;
import org.jooq.Field;
import org.jooq.JSONFormat;
import org.jooq.Name;
import org.jooq.Record;
import org.jooq.Record1;
import org.jooq.Record10;
import org.jooq.Record11;
import org.jooq.Record12;
import org.jooq.Record13;
import org.jooq.Record14;
import org.jooq.Record15;
import org.jooq.Record16;
import org.jooq.Record17;
import org.jooq.Record18;
import org.jooq.Record19;
import org.jooq.Record2;
import org.jooq.Record20;
import org.jooq.Record21;
import org.jooq.Record22;
import org.jooq.Record3;
import org.jooq.Record4;
import org.jooq.Record5;
import org.jooq.Record6;
import org.jooq.Record7;
import org.jooq.Record8;
import org.jooq.Record9;
import org.jooq.RecordMapper;
import org.jooq.Result;
import org.jooq.TXTFormat;
import org.jooq.Table;
import org.jooq.UniqueKey;
import org.jooq.XMLFormat;
import org.jooq.exception.IOException;
import org.jooq.exception.InvalidResultException;
import org.jooq.exception.MappingException;
import org.jooq.impl.Tools.ThreadGuard;
import org.jooq.impl.Tools.ThreadGuard.GuardedOperation;
import org.jooq.tools.Convert;
import org.jooq.tools.JooqLogger;
import org.jooq.tools.StringUtils;
import org.w3c.dom.Document;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
@SuppressWarnings({ "rawtypes", "unchecked" })
abstract class AbstractRecord extends AbstractStore implements Record {
private static final long serialVersionUID = -6052512608911220404L;
private static final JooqLogger log = JooqLogger.getLogger(AbstractRecord.class);
final AbstractRow fields;
final Object[] values;
final Object[] originals;
final BitSet changed;
boolean fetched;
@Deprecated
AbstractRecord(Collection<? extends Field<?>> fields) {
this(Tools.row0(fields.toArray(EMPTY_FIELD)));
}
@Deprecated
AbstractRecord(Field<?>... fields) {
this(Tools.row0(fields));
}
AbstractRecord(AbstractRow fields) {
int size = fields.size();
this.fields = fields;
this.values = new Object[size];
this.originals = new Object[size];
this.changed = new BitSet(size);
}
@Override
final List<Attachable> getAttachables() {
List<Attachable> result = null;
int size = size();
for (int i = 0; i < size; i++) {
if (values[i] instanceof Attachable) {
if (result == null)
result = new ArrayList<>();
result.add((Attachable) values[i]);
}
}
return result == null ? Collections.<Attachable>emptyList() : result;
}
@Override
public final <T> Field<T> field(Field<T> field) {
return fields.field(field);
}
@Override
public final Field<?> field(String name) {
return fields.field(name);
}
@Override
public final Field<?> field(Name name) {
return fields.field(name);
}
@Override
public final Field<?> field(int index) {
return index >= 0 && index < fields.size() ? fields.field(index) : null;
}
@Override
public final Field<?>[] fields() {
return fields.fields();
}
@Override
public final Field<?>[] fields(Field<?>... f) {
return fields.fields(f);
}
@Override
public final Field<?>[] fields(String... fieldNames) {
return fields.fields(fieldNames);
}
@Override
public final Field<?>[] fields(Name... fieldNames) {
return fields.fields(fieldNames);
}
@Override
public final Field<?>[] fields(int... fieldIndexes) {
return fields.fields(fieldIndexes);
}
@Override
public final int indexOf(Field<?> field) {
return fields.indexOf(field);
}
@Override
public final int indexOf(String fieldName) {
return fields.indexOf(fieldName);
}
@Override
public final int indexOf(Name fieldName) {
return fields.indexOf(fieldName);
}
@Override
public final int size() {
return fields.size();
}
@Override
public final <T> T get(Field<T> field) {
int index = fields.indexOf(field);
if (index >= 0)
return (T) get(index);
else if (Tools.nonReplacingEmbeddable(field))
return (T) Tools
.newRecord(fetched, ((EmbeddableTableField<?, ?>) field).recordType)
.operate(new TransferRecordState<Record>(embeddedFields(field)));
else
throw Tools.indexFail(fields, field);
}
@Override
public final <T> T get(Field<?> field, Class<? extends T> type) {
return (T) converterOrFail(this, field.getType(), (Class) type).from(get(field));
}
@Override
public final <T, U> U get(Field<T> field, Converter<? super T, ? extends U> converter) {
return converter.from(get(field));
}
@Override
public final Object get(int index) {
return values[safeIndex(index)];
}
@Override
public final <T> T get(int index, Class<? extends T> type) {
return (T) converterOrFail(this, field(safeIndex(index)).getType(), (Class) type).from(get(index));
}
@Override
public final <U> U get(int index, Converter<?, ? extends U> converter) {
return Convert.convert(get(index), converter);
}
@Override
public final Object get(String fieldName) {
return get(indexOrFail(fields, fieldName));
}
@Override
public final <T> T get(String fieldName, Class<? extends T> type) {
return get(indexOrFail(fields, fieldName), type);
}
@Override
public final <U> U get(String fieldName, Converter<?, ? extends U> converter) {
return Convert.convert(get(fieldName), converter);
}
@Override
public final Object get(Name fieldName) {
return get(indexOrFail(fields, fieldName));
}
@Override
public final <T> T get(Name fieldName, Class<? extends T> type) {
return get(indexOrFail(fields, fieldName), type);
}
@Override
public final <U> U get(Name fieldName, Converter<?, ? extends U> converter) {
return Convert.convert(get(fieldName), converter);
}
@Deprecated
protected final void setValue(int index, Object value) {
set(index, value);
}
protected final void set(int index, Object value) {
set(index, field(index), value);
}
@Override
public final <T> void set(Field<T> field, T value) {
int index = fields.indexOf(field);
if (index >= 0)
set(index, field, value);
else if (Tools.nonReplacingEmbeddable(field)) {
Field<?>[] f = embeddedFields(field);
Object[] v = value instanceof EmbeddableRecord
? ((EmbeddableRecord) value).intoArray()
: new Object[f.length];
for (int i = 0; i < f.length; i++)
set(indexOrFail(fields, f[i]), f[i], v[i]);
}
else
throw indexFail(fields, field);
}
final void set(int index, Field<?> field, Object value) {
UniqueKey<?> key = getPrimaryKey();
if (key == null || !key.getFields().contains(field)) {
changed.set(index);
}
else if (changed.get(index)) {
changed.set(index);
}
else if (updatablePrimaryKeys(settings(this))) {
changed.set(index);
}
else if (originals[index] == null) {
changed.set(index);
}
else {
changed.set(index, changed.get(index) || !StringUtils.equals(values[index], value));
if (changed.get(index)) {
changed(true);
}
}
values[index] = value;
}
@Override
public final <T, U> void set(Field<T> field, U value, Converter<? extends T, ? super U> converter) {
set(field, converter.to(value));
}
@Override
public <T> Record with(Field<T> field, T value) {
set(field, value);
return this;
}
@Override
public <T, U> Record with(Field<T> field, U value, Converter<? extends T, ? super U> converter) {
set(field, value, converter);
return this;
}
final void setValues(Field<?>[] fields, AbstractRecord record) {
fetched = record.fetched;
for (Field<?> field : fields) {
int targetIndex = indexOrFail(this.fields, field);
int sourceIndex = indexOrFail(record.fields, field);
values[targetIndex] = record.get(sourceIndex);
originals[targetIndex] = record.original(sourceIndex);
changed.set(targetIndex, record.changed(sourceIndex));
}
}
final void intern0(int fieldIndex) {
safeIndex(fieldIndex);
if (field(fieldIndex).getType() == String.class) {
values[fieldIndex] = intern((String) values[fieldIndex]);
originals[fieldIndex] = intern((String) originals[fieldIndex]);
}
}
final int safeIndex(int index) {
if (index >= 0 && index < values.length)
return index;
throw new IllegalArgumentException("No field at index " + index + " in Record type " + fields);
}
final String intern(String string) {
return string == null ? null : string.intern();
}
UniqueKey<?> getPrimaryKey() {
return null;
}
@Override
public Record original() {
return Tools.newRecord(fetched, (Class<AbstractRecord>) getClass(), fields, configuration())
.operate(new RecordOperation<AbstractRecord, RuntimeException>() {
@Override
public AbstractRecord operate(AbstractRecord record) throws RuntimeException {
for (int i = 0; i < originals.length; i++) {
record.values[i] = originals[i];
record.originals[i] = originals[i];
}
return record;
}
});
}
@Override
public final <T> T original(Field<T> field) {
return (T) original(indexOrFail(fields, field));
}
@Override
public final Object original(int fieldIndex) {
return originals[safeIndex(fieldIndex)];
}
@Override
public final Object original(String fieldName) {
return original(indexOrFail(fields, fieldName));
}
@Override
public final Object original(Name fieldName) {
return original(indexOrFail(fields, fieldName));
}
@Override
public final boolean changed() {
return !changed.isEmpty();
}
@Override
public final boolean changed(Field<?> field) {
return changed(indexOrFail(fields, field));
}
@Override
public final boolean changed(int fieldIndex) {
return changed.get(safeIndex(fieldIndex));
}
@Override
public final boolean changed(String fieldName) {
return changed(indexOrFail(fields, fieldName));
}
@Override
public final boolean changed(Name fieldName) {
return changed(indexOrFail(fields, fieldName));
}
@Override
public final void changed(boolean c) {
changed.set(0, values.length, c);
if (!c) {
System.arraycopy(values, 0, originals, 0, values.length);
}
}
@Override
public final void changed(Field<?> field, boolean c) {
changed(indexOrFail(fields, field), c);
}
@Override
public final void changed(int fieldIndex, boolean c) {
safeIndex(fieldIndex);
changed.set(fieldIndex, c);
if (!c)
originals[fieldIndex] = values[fieldIndex];
}
@Override
public final void changed(String fieldName, boolean c) {
changed(indexOrFail(fields, fieldName), c);
}
@Override
public final void changed(Name fieldName, boolean c) {
changed(indexOrFail(fields, fieldName), c);
}
@Override
public final void reset() {
changed.clear();
System.arraycopy(originals, 0, values, 0, originals.length);
}
@Override
public final void reset(Field<?> field) {
reset(indexOrFail(fields, field));
}
@Override
public final void reset(int fieldIndex) {
safeIndex(fieldIndex);
changed.clear(fieldIndex);
values[fieldIndex] = originals[fieldIndex];
}
@Override
public final void reset(String fieldName) {
reset(indexOrFail(fields, fieldName));
}
@Override
public final void reset(Name fieldName) {
reset(indexOrFail(fields, fieldName));
}
@Override
public final Object[] intoArray() {
return into(Object[].class);
}
@Override
public final List<Object> intoList() {
return Arrays.asList(intoArray());
}
@Override
public final Stream<Object> intoStream() {
return into(Stream.class);
}
@Override
public final Map<String, Object> intoMap() {
Map<String, Object> map = new LinkedHashMap<>();
int size = fields.size();
for (int i = 0; i < size; i++) {
Field<?> field = fields.field(i);
if (map.put(field.getName(), get(i)) != null) {
throw new InvalidResultException("Field " + field.getName() + " is not unique in Record : " + this);
}
}
return map;
}
@Override
public final Record into(Field<?>... f) {
return Tools.newRecord(fetched, Record.class, Tools.row0(f), configuration()).operate(new TransferRecordState<Record>(f));
}
@Override
public final <T1> Record1<T1> into(Field<T1> field1) {
return (Record1) into(new Field[] { field1 });
}
@Override
public final <T1, T2> Record2<T1, T2> into(Field<T1> field1, Field<T2> field2) {
return (Record2) into(new Field[] { field1, field2 });
}
@Override
public final <T1, T2, T3> Record3<T1, T2, T3> into(Field<T1> field1, Field<T2> field2, Field<T3> field3) {
return (Record3) into(new Field[] { field1, field2, field3 });
}
@Override
public final <T1, T2, T3, T4> Record4<T1, T2, T3, T4> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4) {
return (Record4) into(new Field[] { field1, field2, field3, field4 });
}
@Override
public final <T1, T2, T3, T4, T5> Record5<T1, T2, T3, T4, T5> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5) {
return (Record5) into(new Field[] { field1, field2, field3, field4, field5 });
}
@Override
public final <T1, T2, T3, T4, T5, T6> Record6<T1, T2, T3, T4, T5, T6> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6) {
return (Record6) into(new Field[] { field1, field2, field3, field4, field5, field6 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7> Record7<T1, T2, T3, T4, T5, T6, T7> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7) {
return (Record7) into(new Field[] { field1, field2, field3, field4, field5, field6, field7 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8> Record8<T1, T2, T3, T4, T5, T6, T7, T8> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8) {
return (Record8) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9> Record9<T1, T2, T3, T4, T5, T6, T7, T8, T9> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9) {
return (Record9) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Record10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10) {
return (Record10) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Record11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11) {
return (Record11) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Record12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12) {
return (Record12) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Record13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13) {
return (Record13) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Record14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14) {
return (Record14) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> Record15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15) {
return (Record15) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> Record16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15, Field<T16> field16) {
return (Record16) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> Record17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15, Field<T16> field16, Field<T17> field17) {
return (Record17) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> Record18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15, Field<T16> field16, Field<T17> field17, Field<T18> field18) {
return (Record18) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> Record19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15, Field<T16> field16, Field<T17> field17, Field<T18> field18, Field<T19> field19) {
return (Record19) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> Record20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15, Field<T16> field16, Field<T17> field17, Field<T18> field18, Field<T19> field19, Field<T20> field20) {
return (Record20) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> Record21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15, Field<T16> field16, Field<T17> field17, Field<T18> field18, Field<T19> field19, Field<T20> field20, Field<T21> field21) {
return (Record21) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20, field21 });
}
@Override
public final <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> Record22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> into(Field<T1> field1, Field<T2> field2, Field<T3> field3, Field<T4> field4, Field<T5> field5, Field<T6> field6, Field<T7> field7, Field<T8> field8, Field<T9> field9, Field<T10> field10, Field<T11> field11, Field<T12> field12, Field<T13> field13, Field<T14> field14, Field<T15> field15, Field<T16> field16, Field<T17> field17, Field<T18> field18, Field<T19> field19, Field<T20> field20, Field<T21> field21, Field<T22> field22) {
return (Record22) into(new Field[] { field1, field2, field3, field4, field5, field6, field7, field8, field9, field10, field11, field12, field13, field14, field15, field16, field17, field18, field19, field20, field21, field22 });
}
@Override
public final <E> E into(Class<? extends E> type) {
return (E) Tools.configuration(this).recordMapperProvider().provide((Fields) fields.fields, type).map(this);
}
@Override
public <E> E into(E object) {
if (object == null)
throw new NullPointerException("Cannot copy Record into null");
Class<E> type = (Class<E>) object.getClass();
try {
return new DefaultRecordMapper<Record, E>((Fields) fields.fields, type, object, configuration()).map(this);
}
catch (MappingException e) {
throw e;
}
catch (Exception e) {
throw new MappingException("An error ocurred when mapping record to " + type, e);
}
}
@Override
public final <R extends Record> R into(Table<R> table) {
return Tools.newRecord(fetched, table, configuration()).operate(new TransferRecordState<R>(table.fields()));
}
final <R extends Record> R intoRecord(Class<R> type) {
return Tools.newRecord(fetched, type, fields, configuration()).operate(new TransferRecordState<R>(null));
}
private class TransferRecordState<R extends Record> implements RecordOperation<R, MappingException> {
private final Field<?>[] targetFields;
TransferRecordState(Field<?>[] targetFields) {
this.targetFields = targetFields;
}
@Override
public R operate(R target) throws MappingException {
AbstractRecord source = AbstractRecord.this;
try {
if (target instanceof AbstractRecord) {
AbstractRecord t = (AbstractRecord) target;
for (int targetIndex = 0; targetIndex < (targetFields != null ? targetFields.length : t.size()); targetIndex++) {
Field<?> targetField = (targetFields != null ? targetFields[targetIndex] : t.field(targetIndex));
int sourceIndex = fields.indexOf(targetField);
if (sourceIndex >= 0) {
DataType<?> targetType = targetField.getDataType();
t.values[targetIndex] = targetType.convert(values[sourceIndex]);
t.originals[targetIndex] = targetType.convert(originals[sourceIndex]);
t.changed.set(targetIndex, changed.get(sourceIndex));
}
}
}
else {
for (Field<?> targetField : target.fields()) {
Field<?> sourceField = field(targetField);
if (sourceField != null) {
Tools.setValue(target, targetField, source, sourceField);
}
}
}
return target;
}
catch (Exception e) {
throw new MappingException("An error ocurred when mapping record to " + target, e);
}
}
}
@Override
public final ResultSet intoResultSet() {
return asResult().intoResultSet();
}
@Override
public final <E> E map(RecordMapper<Record, E> mapper) {
return mapper.map(this);
}
private final void from0(Object source, Fields f) {
if (source == null) return;
from(Tools.configuration(this).recordUnmapperProvider().provide(source.getClass(), f).unmap(prepareArrayForUnmap(source, f)));
resetChangedOnNotNull(this);
}
private final Object prepareArrayForUnmap(Object source, Fields f) {
if (source instanceof Object[]) {
Object[] array = (Object[]) source;
if (array.length != f.size()) {
Object[] result = new Object[f.size()];
for (int i = 0; i < result.length; i++) {
int index = fields.indexOf(f.field(i));
result[i] = index >= 0 && index < array.length ? array[index] : null;
}
return result;
}
else
return source;
}
else
return source;
}
@Override
public final void from(Object source) {
from0(source, fields.fields);
}
@Override
public final void from(Object source, Field<?>... f) {
from0(source, new Fields(f));
}
@Override
public final void from(Object source, String... fieldNames) {
from(source, fields(fieldNames));
}
@Override
public final void from(Object source, Name... fieldNames) {
from(source, fields(fieldNames));
}
@Override
public final void from(Object source, int... fieldIndexes) {
from(source, fields(fieldIndexes));
}
@Override
public final void fromMap(Map<String, ?> map) {
from(map, fields());
}
@Override
public final void fromMap(Map<String, ?> map, Field<?>... f) {
from0(map, new Fields(f));
}
@Override
public final void fromMap(Map<String, ?> map, String... fieldNames) {
fromMap(map, fields(fieldNames));
}
@Override
public final void fromMap(Map<String, ?> map, Name... fieldNames) {
fromMap(map, fields(fieldNames));
}
@Override
public final void fromMap(Map<String, ?> map, int... fieldIndexes) {
fromMap(map, fields(fieldIndexes));
}
@Override
public final void fromArray(Object... array) {
fromArray(array, fields());
}
@Override
public final void fromArray(Object[] array, Field<?>... f) {
from0(array, new Fields(f));
}
@Override
public final void fromArray(Object[] array, String... fieldNames) {
fromArray(array, fields(fieldNames));
}
@Override
public final void fromArray(Object[] array, Name... fieldNames) {
fromArray(array, fields(fieldNames));
}
@Override
public final void fromArray(Object[] array, int... fieldIndexes) {
fromArray(array, fields(fieldIndexes));
}
protected final void from(Record source) {
for (Field<?> field : fields.fields.fields) {
Field<?> sourceField = source.field(field);
if (sourceField != null && source.changed(sourceField))
Tools.setValue(this, field, source, sourceField);
}
}
@Override
public final void format(Writer writer, TXTFormat format) {
asResult().format(writer, format);
}
@Override
public final void formatCSV(Writer writer, CSVFormat format) {
asResult().formatCSV(writer, format);
}
@Override
public final void formatJSON(Writer writer, JSONFormat format) {
if (format == null)
format = JSONFormat.DEFAULT_FOR_RECORDS;
if (format.header())
log.debug("JSONFormat.header currently not supported for Record.formatJSON()");
try {
switch (format.recordFormat()) {
case ARRAY:
AbstractCursor.formatJSONArray0(this, fields, format, 0, writer);
break;
case OBJECT:
AbstractCursor.formatJSONMap0(this, fields, format, 0, writer);
break;
default:
throw new IllegalArgumentException("Format not supported: " + format);
}
}
catch (java.io.IOException e) {
throw new IOException("Exception while writing JSON", e);
}
}
@Override
public final void formatXML(Writer writer, XMLFormat format) {
if (format == null)
format = XMLFormat.DEFAULT_FOR_RECORDS;
if (format.header())
log.debug("XMLFormat.header currently not supported for Record.formatXML()");
try {
AbstractCursor.formatXMLRecord(writer, format, 0, this, fields);
}
catch (java.io.IOException e) {
throw new IOException("Exception while writing XML", e);
}
}
@Override
public final void formatHTML(Writer writer) {
Result<AbstractRecord> result = asResult();
result.formatHTML(writer);
}
@Override
public final void formatChart(Writer writer, ChartFormat format) {
Result<AbstractRecord> result = asResult();
result.formatChart(writer, format);
}
@Override
public final void formatInsert(Writer writer) {
formatInsert(writer, null, fields.fields.fields);
}
@Override
public final void formatInsert(Writer writer, Table<?> table, Field<?>... f) {
Result<AbstractRecord> result = asResult();
result.formatInsert(writer, table, f);
}
@Override
public final Document intoXML(XMLFormat format) {
Result<AbstractRecord> result = asResult();
return result.intoXML(format);
}
@Override
public final <H extends ContentHandler> H intoXML(H handler, XMLFormat format) throws SAXException {
Result<AbstractRecord> result = asResult();
return result.intoXML(handler, format);
}
@Override
public String toString() {
return ThreadGuard.run(RECORD_TOSTRING, new GuardedOperation<String>() {
@Override
public String unguarded() {
return asResult().toString();
}
@Override
public String guarded() {
return valuesRow().toString();
}
});
}
@Override
public int compareTo(Record that) {
if (that == this)
return 0;
if (that == null)
throw new NullPointerException();
if (size() != that.size())
throw new ClassCastException(String.format("Trying to compare incomparable records (wrong degree):\n%s\n%s", this, that));
Class<?>[] thisTypes = this.fieldsRow().types();
Class<?>[] thatTypes = that.fieldsRow().types();
if (!asList(thisTypes).equals(asList(thatTypes)))
throw new ClassCastException(String.format("Trying to compare incomparable records (type mismatch):\n%s\n%s", this, that));
for (int i = 0; i < size(); i++) {
final Object thisValue = get(i);
final Object thatValue = that.get(i);
if (thisValue == null && thatValue == null)
continue;
else if (thisValue == null)
return 1;
else if (thatValue == null)
return -1;
else if (thisValue.getClass().isArray() && thatValue.getClass().isArray()) {
if (thisValue.getClass() == byte[].class) {
int compare = compare((byte[]) thisValue, (byte[]) thatValue);
if (compare != 0)
return compare;
}
else if (!thisValue.getClass().getComponentType().isPrimitive()) {
int compare = compare((Object[]) thisValue, (Object[]) thatValue);
if (compare != 0)
return compare;
}
else
throw new ClassCastException(String.format("Unsupported data type in natural ordering: %s", thisValue.getClass()));
}
else {
int compare = compare0(thisValue, thatValue);
if (compare != 0)
return compare;
}
}
return 0;
}
final int compare(byte[] array1, byte[] array2) {
int length = Math.min(array1.length, array2.length);
for (int i = 0; i < length; i++) {
int v1 = (array1[i] & 0xff);
int v2 = (array2[i] & 0xff);
if (v1 != v2)
return v1 < v2 ? -1 : 1;
}
return array1.length - array2.length;
}
final int compare(Object[] array1, Object[] array2) {
int length = Math.min(array1.length, array2.length);
for (int i = 0; i < length; i++) {
int compare = compare0(array1[i], array2[i]);
if (compare != 0)
return compare;
}
return array1.length - array2.length;
}
final int compare0(Object object1, Object object2) {
return object1 == object2
? 0
: object1 == null
? -1
: object2 == null
? 1
: object1.hashCode() - object2.hashCode();
}
@Override
public final <T> T getValue(Field<T> field) {
return get(field);
}
@Override
@Deprecated
public final <T> T getValue(Field<T> field, T defaultValue) {
T result = getValue(field);
return result != null ? result : defaultValue;
}
@Override
public final <T> T getValue(Field<?> field, Class<? extends T> type) {
return get(field, type);
}
@Override
@Deprecated
public final <T> T getValue(Field<?> field, Class<? extends T> type, T defaultValue) {
final T result = get(field, type);
return result == null ? defaultValue : result;
}
@Override
public final <T, U> U getValue(Field<T> field, Converter<? super T, ? extends U> converter) {
return get(field, converter);
}
@Override
@Deprecated
public final <T, U> U getValue(Field<T> field, Converter<? super T, ? extends U> converter, U defaultValue) {
final U result = get(field, converter);
return result == null ? defaultValue : result;
}
@Override
public final Object getValue(int index) {
return get(index);
}
@Override
@Deprecated
public final Object getValue(int index, Object defaultValue) {
final Object result = get(index);
return result == null ? defaultValue : result;
}
@Override
public final <T> T getValue(int index, Class<? extends T> type) {
return get(index, type);
}
@Override
@Deprecated
public final <T> T getValue(int index, Class<? extends T> type, T defaultValue) {
final T result = get(index, type);
return result == null ? defaultValue : result;
}
@Override
public final <U> U getValue(int index, Converter<?, ? extends U> converter) {
return get(index, converter);
}
@Override
@Deprecated
public final <U> U getValue(int index, Converter<?, ? extends U> converter, U defaultValue) {
final U result = get(index, converter);
return result == null ? defaultValue : result;
}
@Override
public final Object getValue(String fieldName) {
return get(fieldName);
}
@Override
@Deprecated
public final Object getValue(String fieldName, Object defaultValue) {
return getValue(indexOrFail(fields, fieldName), defaultValue);
}
@Override
public final <T> T getValue(String fieldName, Class<? extends T> type) {
return get(fieldName, type);
}
@Override
@Deprecated
public final <T> T getValue(String fieldName, Class<? extends T> type, T defaultValue) {
final T result = get(fieldName, type);
return result == null ? defaultValue : result;
}
@Override
public final <U> U getValue(String fieldName, Converter<?, ? extends U> converter) {
return get(fieldName, converter);
}
@Override
@Deprecated
public final <U> U getValue(String fieldName, Converter<?, ? extends U> converter, U defaultValue) {
final U result = get(fieldName, converter);
return result == null ? defaultValue : result;
}
@Override
public final Object getValue(Name fieldName) {
return get(fieldName);
}
@Override
public final <T> T getValue(Name fieldName, Class<? extends T> type) {
return get(fieldName, type);
}
@Override
public final <U> U getValue(Name fieldName, Converter<?, ? extends U> converter) {
return get(fieldName, converter);
}
@Override
public final <T> void setValue(Field<T> field, T value) {
set(field, value);
}
@Override
public final <T, U> void setValue(Field<T> field, U value, Converter<? extends T, ? super U> converter) {
set(field, value, converter);
}
final Result<AbstractRecord> asResult() {
Result<AbstractRecord> result = new ResultImpl<>(configuration(), fields);
result.add(this);
return result;
}
}