/**
* Copyright (C) 2009-2013 FoundationDB, LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.foundationdb.server.api.dml.scan;
import com.foundationdb.server.rowdata.RowData;
import com.foundationdb.server.rowdata.RowDataExtractor;
import com.foundationdb.server.rowdata.RowDef;
import com.foundationdb.server.api.dml.ColumnSelector;
import java.util.Map;
public final class LegacyRowWrapper extends NewRow
{
// Updates are handled by creating a NiceRow from the RowData and applying updates to the NiceRow.
// When this happens, rowData is set to null, and is regenerated lazily. If newRow is null, then
// rowData is current.
private RowData rowData;
private NiceRow niceRow;
// For when a LegacyRowWrapper is being reused, e.g. WriteRowRequest.
public LegacyRowWrapper()
{
this(null, null);
}
public LegacyRowWrapper(RowDef rowDef)
{
this(rowDef, null);
}
public LegacyRowWrapper(RowDef rowDef, RowData rowData)
{
super(rowDef);
setRowData(rowData);
}
public void setRowData(RowData rowData)
{
assert
rowData == null || rowDef == null || rowData.getRowDefId() == rowDef.getRowDefId()
: String.format("rowData: %s, rowDef: %s", rowData, rowDef);
this.rowData = rowData;
this.niceRow = null;
this.extractor = null;
}
@Override
public Object put(int index, Object object)
{
return niceRow().put(index, object);
}
@Override
public int getTableId()
{
assert rowData != null || niceRow != null;
return niceRow != null ? niceRow.getTableId() : rowData.getRowDefId();
}
@Override
public Object get(int columnId)
{
Object object;
if (rowData == null && niceRow == null) {
throw new IllegalArgumentException("Row state has not been set");
} else {
object =
niceRow != null
? niceRow.get(columnId)
: extractor().get(rowDef.getFieldDef(columnId));
}
return object;
}
@Override
public boolean hasValue(int columnId)
{
throw new UnsupportedOperationException();
}
@Override
public Object remove(int columnId)
{
throw new UnsupportedOperationException();
}
@Override
public Map<Integer, Object> getFields()
{
return niceRow().getFields();
}
@Override
public RowData toRowData()
{
if (rowData == null && niceRow != null) {
rowData = niceRow.toRowData();
extractor = null;
niceRow = null;
}
return rowData;
}
@Override
public ColumnSelector getActiveColumns() {
return niceRow().getActiveColumns();
}
@Override
public boolean isColumnNull(int columnId) {
return toRowData().isNull(columnId);
}
@Override
public boolean equals(Object o)
{
boolean eq;
if (o == null) {
eq = false;
} else if (this == o) {
eq = true;
} else if (o instanceof LegacyRowWrapper) {
LegacyRowWrapper that = (LegacyRowWrapper) o;
eq = this.niceRow().equals(that.niceRow());
} else if (o instanceof NiceRow) {
NiceRow that = (NiceRow) o;
eq = this.niceRow().equals(that);
} else {
eq = false;
}
return eq;
}
@Override
public int hashCode()
{
return niceRow().hashCode();
}
@Override
public String toString()
{
// newRow().toString() would be simpler, but there's a side-effect: If rowData != null, then
// the rowData is converted to a NiceRow and rowData is set to null.
return
rowData == null && niceRow == null ? "null" :
rowData == null ? niceRow.toString() :
rowData.toString(rowDef);
}
public NiceRow niceRow()
{
if (niceRow == null) {
niceRow = (NiceRow) NiceRow.fromRowData(rowData, rowDef);
rowData = null;
extractor = null;
}
return niceRow;
}
// Allows a LegacyRowWrapper to be used for a RowData acting as a container of rows of any type.
public void setRowDef(RowDef rowDef)
{
this.rowDef = rowDef;
niceRow = null;
}
private RowDataExtractor extractor()
{
if (extractor == null) {
extractor = new RowDataExtractor(rowData, rowDef);
}
return extractor;
}
private RowDataExtractor extractor;
}