/** * 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 java.util.Map; import com.foundationdb.server.rowdata.RowData; import com.foundationdb.server.rowdata.RowDef; import com.foundationdb.server.api.dml.ColumnSelector; /** * <p>A map-like interface for defining rows. This interface does not specify any inherent binding to a row definition; * that binding (including any errors that arise from it) should happen when the row is used.</p> * * <p>Rows should be able to accept <tt>null</tt> values, which should be distinct from unset values. So the following * are <strong>not</strong> equivalent: * <pre> {1: 'foo', 2: null } * {1: 'foo' }</pre> * </p> * * <p>Note: Although this interface primarily defines a ColumnId -> Object mapping, it is not, and should not be, * related to the <tt>Map</tt> interface. This is because the <tt>Map</tt> interface specifies a <tt>hashCode</tt> * and <tt>equals</tt> implementation which are not compatible with this class; in particular, this class's equality * and hash should take its TableId into consideration.</p> */ public abstract class NewRow { protected RowDef rowDef; /** * Gets the RowDef for the row. * @return the RowDef */ public final RowDef getRowDef() { return rowDef; } /** * Puts a value into the row. Optional operation. * @param index the column to insert into * @param object the object to insert * @return the previous object at the specified index, or null if there was one * @throws UnsupportedOperationException if not supported */ public abstract Object put(int index, Object object); /** * Gets the table ID to which this row belongs * @return the table ID */ public abstract int getTableId(); /** * Gets the value at the specified index, which is a 0-indexed column position offset. * @param columnId the column to get * @return the value at the specified index, or null if there is none * @throws UnsupportedOperationException if not supported */ public abstract Object get(int columnId); /** * Whether a value is defined in this column. This is the equivalent of Map.containsKey. * @param columnId the column to request * @return whether a value is defined for the given column */ public abstract boolean hasValue(int columnId); /** * Removes a value from the row, if it existed. Returns back the old value * @param columnId the column whose value we should remove * @return the old value, or null if there wasn't one */ public abstract Object remove(int columnId); /** * Returns a modifiable map view of the fields. The modifying the NewRow will update the Map, and updating * the Map will modify the NewRow. The Map must support all optional operations. * @return the fields that have been set * @throws UnsupportedOperationException if not supported */ public abstract Map<Integer,Object> getFields(); /** * Converts this row to a newly allocated RowData * @return the data represented by this row, encoded as a RowData * @throws NullPointerException if rowDef is required but null */ public abstract RowData toRowData(); /** * Returns a ColumnSelector where {@linkplain ColumnSelector#includesColumn(int)} returns true for fields * that have been set, as opposed to testing for NULL. * @return the ColumnSelector */ public abstract ColumnSelector getActiveColumns(); /** * Returns whether or not the column at the given position is null or unset. * @param columnId the column whose value to test * @return true if null or unset, false otherwise */ public abstract boolean isColumnNull(int columnId); /** * <p>Compares the specified object with this NewRow. Returns <tt>true</tt> if the given object is also a * <tt>NewRow</tt>, defines the same (ColumnId, Object) mapping and corresponds to the same TableId.</p> * * <p>Note that TableIds can only be used in equality and hashcode if they're resolved. That restriction * propagates to implementations of this class.</p> * @param o the object to compare to * @return if the given object is equal to this NewRow */ @Override public abstract boolean equals(Object o); /** * <p>Returns the hash code for this NewRow. The hash code is defined as sum of the NewRow's tableId hash code and * the hash code for the <tt>Map</tt> returned by {@linkplain #getFields}.</p> * * <p>Note that TableIds can only be used in equality and hashcode if they're resolved. That restriction * propagates to implementations of this class.</p> * @return the hash code for this NewRow */ @Override public abstract int hashCode(); protected NewRow(RowDef rowDef) { this.rowDef = rowDef; } }