/** owning table */
private final TableImpl _table;
/** Whether or not the column is of variable length */
- private boolean _variableLength;
+ private final boolean _variableLength;
/** Whether or not the column is an autonumber column */
- private boolean _autoNumber;
+ private final boolean _autoNumber;
/** Data type */
- private DataType _type;
+ private final DataType _type;
/** Maximum column length */
- private short _columnLength;
+ private final short _columnLength;
/** 0-based column number */
- private short _columnNumber;
+ private final short _columnNumber;
/** index of the data for this column within a list of row data */
private int _columnIndex;
/** display index of the data for this column */
- private int _displayIndex;
+ private final int _displayIndex;
/** Column name */
private String _name;
/** the offset of the fixed data in the row */
- private int _fixedDataOffset;
+ private final int _fixedDataOffset;
/** the index of the variable length data in the var len offset table */
- private int _varLenTableIndex;
+ private final int _varLenTableIndex;
/** information specific to numeric columns */
private NumericInfo _numericInfo = DEFAULT_NUMERIC_INFO;
/** information specific to text columns */
private TextInfo _textInfo = DEFAULT_TEXT_INFO;
/** the auto number generator for this column (if autonumber column) */
- private AutoNumberGenerator _autoNumberGenerator;
+ private final AutoNumberGenerator _autoNumberGenerator;
/** additional information specific to complex columns */
private ComplexColumnInfo<? extends ComplexValue> _complexInfo;
/** properties for this column, if any */
/**
* @usage _advanced_method_
*/
- ColumnImpl(TableImpl table) {
+ protected ColumnImpl(TableImpl table, DataType type, int colNumber,
+ int fixedOffset, int varLenIndex) {
_table = table;
+ _type = type;
+
+ if(!_type.isVariableLength()) {
+ _columnLength = (short)type.getFixedSize();
+ } else {
+ _columnLength = (short)type.getMaxSize();
+ }
+ _variableLength = type.isVariableLength();
+ if(type.getHasScalePrecision()) {
+ modifyNumericInfo();
+ _numericInfo._scale = (byte)type.getDefaultScale();
+ _numericInfo._precision =(byte)type.getDefaultPrecision();
+ }
+ _autoNumber = false;
+ _autoNumberGenerator = null;
+ _columnNumber = (short)colNumber;
+ _displayIndex = 0;
+ _fixedDataOffset = fixedOffset;
+ _varLenTableIndex = varLenIndex;
}
/**
* @param offset Offset in the buffer at which the column definition starts
* @usage _advanced_method_
*/
- public ColumnImpl(TableImpl table, ByteBuffer buffer, int offset, int displayIndex)
+ public ColumnImpl(TableImpl table, ByteBuffer buffer, int offset,
+ int displayIndex)
throws IOException
{
_table = table;
byte flags = buffer.get(offset + getFormat().OFFSET_COLUMN_FLAGS);
_variableLength = ((flags & FIXED_LEN_FLAG_MASK) == 0);
- _autoNumber = ((flags & (AUTO_NUMBER_FLAG_MASK | AUTO_NUMBER_GUID_FLAG_MASK)) != 0);
+ _autoNumber = ((flags & (AUTO_NUMBER_FLAG_MASK | AUTO_NUMBER_GUID_FLAG_MASK))
+ != 0);
+ DataType type = null;
try {
- _type = DataType.fromByte(colType);
+ type = DataType.fromByte(colType);
} catch(IOException e) {
LOG.warn("Unsupported column type " + colType);
- _type = (_variableLength ? DataType.UNSUPPORTED_VARLEN :
- DataType.UNSUPPORTED_FIXEDLEN);
+ type = (_variableLength ? DataType.UNSUPPORTED_VARLEN :
+ DataType.UNSUPPORTED_FIXEDLEN);
setUnknownDataType(colType);
}
+ _type = type;
if (_type.getHasScalePrecision()) {
modifyNumericInfo();
}
}
- setAutoNumberGenerator();
+ _autoNumberGenerator = createAutoNumberGenerator();
if(_variableLength) {
_varLenTableIndex = buffer.getShort(offset + getFormat().OFFSET_COLUMN_VARIABLE_TABLE_INDEX);
+ _fixedDataOffset = 0;
} else {
_fixedDataOffset = buffer.getShort(offset + getFormat().OFFSET_COLUMN_FIXED_DATA_OFFSET);
+ _varLenTableIndex = 0;
}
// load complex info
/**
* @usage _advanced_method_
*/
- public void setName(String name) {
+ void setName(String name) {
_name = name;
}
public boolean isVariableLength() {
return _variableLength;
}
-
- /**
- * @usage _advanced_method_
- */
- public void setVariableLength(boolean variableLength) {
- _variableLength = variableLength;
- }
public boolean isAutoNumber() {
return _autoNumber;
}
- /**
- * @usage _general_method_
- */
- public void setAutoNumber(boolean autoNumber) {
- _autoNumber = autoNumber;
- setAutoNumberGenerator();
- }
-
/**
* @usage _advanced_method_
*/
return _columnNumber;
}
- /**
- * @usage _advanced_method_
- */
- public void setColumnNumber(short newColumnNumber) {
- _columnNumber = newColumnNumber;
- }
-
public int getColumnIndex() {
return _columnIndex;
}
return _displayIndex;
}
- /**
- * Also sets the length and the variable length flag, inferred from the
- * type. For types with scale/precision, sets the scale and precision to
- * default values.
- * @usage _general_method_
- */
- public void setType(DataType type) {
- _type = type;
- if(!type.isVariableLength()) {
- setLength((short)type.getFixedSize());
- } else if(!type.isLongValue()) {
- setLength((short)type.getDefaultSize());
- }
- setVariableLength(type.isVariableLength());
- if(type.getHasScalePrecision()) {
- setScale((byte)type.getDefaultScale());
- setPrecision((byte)type.getDefaultPrecision());
- }
- }
-
public DataType getType() {
return _type;
}
return _textInfo._compressedUnicode;
}
- /**
- * @usage _general_method_
- */
- public void setCompressedUnicode(boolean newCompessedUnicode) {
- modifyTextInfo();
- _textInfo._compressedUnicode = newCompessedUnicode;
- }
-
public byte getPrecision() {
return _numericInfo._precision;
}
- /**
- * @usage _general_method_
- */
- public void setPrecision(byte newPrecision) {
- modifyNumericInfo();
- _numericInfo._precision = newPrecision;
- }
-
public byte getScale() {
return _numericInfo._scale;
}
- /**
- * @usage _general_method_
- */
- public void setScale(byte newScale) {
- modifyNumericInfo();
- _numericInfo._scale = newScale;
- }
-
/**
* @usage _intermediate_method_
*/
public short getTextCodePage() {
return _textInfo._codePage;
}
-
- /**
- * @usage _general_method_
- */
- public void setLength(short length) {
- _columnLength = length;
- }
public short getLength() {
return _columnLength;
}
- /**
- * @usage _general_method_
- */
- public void setLengthInUnits(short unitLength) {
- setLength((short)getType().fromUnitSize(unitLength));
- }
-
public short getLengthInUnits() {
return (short)getType().toUnitSize(getLength());
}
-
- /**
- * @usage _advanced_method_
- */
- public void setVarLenTableIndex(int idx) {
- _varLenTableIndex = idx;
- }
/**
* @usage _advanced_method_
public int getVarLenTableIndex() {
return _varLenTableIndex;
}
-
- /**
- * @usage _advanced_method_
- */
- public void setFixedDataOffset(int newOffset) {
- _fixedDataOffset = newOffset;
- }
/**
* @usage _advanced_method_
public boolean isHyperlink() {
return _textInfo._hyperlink;
}
-
- /**
- * @usage _general_method_
- */
- public void setHyperlink(boolean hyperlink) {
- modifyTextInfo();
- _textInfo._hyperlink = hyperlink;
- }
public ComplexColumnInfo<? extends ComplexValue> getComplexInfo() {
return _complexInfo;
return _numericInfo._scale;
}
- private void setAutoNumberGenerator()
- {
+ private AutoNumberGenerator createAutoNumberGenerator() {
if(!_autoNumber || (_type == null)) {
- _autoNumberGenerator = null;
- return;
- }
-
- if((_autoNumberGenerator != null) &&
- (_autoNumberGenerator.getType() == _type)) {
- // keep existing
- return;
+ return null;
}
switch(_type) {
case LONG:
- _autoNumberGenerator = new LongAutoNumberGenerator();
- break;
+ return new LongAutoNumberGenerator();
case GUID:
- _autoNumberGenerator = new GuidAutoNumberGenerator();
- break;
+ return new GuidAutoNumberGenerator();
case COMPLEX_TYPE:
- _autoNumberGenerator = new ComplexTypeAutoNumberGenerator();
- break;
+ return new ComplexTypeAutoNumberGenerator();
default:
LOG.warn("Unknown auto number column type " + _type);
- _autoNumberGenerator = new UnsupportedAutoNumberGenerator(_type);
+ return new UnsupportedAutoNumberGenerator(_type);
}
}
return _name;
}
- public void setName(String name) {
+ void setName(String name) {
_name = name;
}
// create column with ability to read/write the given data type
col = ((colType == DataType.BOOLEAN) ?
- new BooleanPropColumn() : new PropColumn());
- col.setType(colType);
- if(col.isVariableLength()) {
- col.setLength((short)colType.getMaxSize());
- }
+ new BooleanPropColumn() : new PropColumn(colType));
}
return col;
*/
private class PropColumn extends ColumnImpl
{
- private PropColumn() {
- super(null);
+ private PropColumn(DataType type) {
+ super(null, type, 0, 0, 0);
}
@Override
*/
private final class BooleanPropColumn extends PropColumn
{
+ private BooleanPropColumn() {
+ super(DataType.BOOLEAN);
+ }
+
@Override
public Object read(byte[] data) throws IOException {
return ((data[0] != 0) ? Boolean.TRUE : Boolean.FALSE);
/** additional table flags from the catalog entry */
private final int _flags;
/** Type of the table (either TYPE_SYSTEM or TYPE_USER) */
- private byte _tableType;
+ private final byte _tableType;
/** Number of actual indexes on the table */
- private int _indexCount;
+ private final int _indexCount;
/** Number of logical indexes for the table */
- private int _logicalIndexCount;
- /** Number of rows in the table */
- private int _rowCount;
- /** last long auto number for the table */
- private int _lastLongAutoNumber;
- /** last complex type auto number for the table */
- private int _lastComplexTypeAutoNumber;
+ private final int _logicalIndexCount;
/** page number of the definition of this table */
private final int _tableDefPageNumber;
/** max Number of columns in the table (includes previous deletions) */
- private short _maxColumnCount;
+ private final short _maxColumnCount;
/** max Number of variable columns in the table */
- private short _maxVarColumnCount;
+ private final short _maxVarColumnCount;
/** List of columns in this table, ordered by column number */
private final List<ColumnImpl> _columns = new ArrayList<ColumnImpl>();
/** List of variable length columns in this table, ordered by offset */
private final List<ColumnImpl> _varColumns = new ArrayList<ColumnImpl>();
/** List of autonumber columns in this table, ordered by column number */
- private List<ColumnImpl> _autoNumColumns;
+ private final List<ColumnImpl> _autoNumColumns = new ArrayList<ColumnImpl>(1);
/** List of indexes on this table (multiple logical indexes may be backed by
the same index data) */
private final List<IndexImpl> _indexes = new ArrayList<IndexImpl>();
/** Table name as stored in Database */
private final String _name;
/** Usage map of pages that this table owns */
- private UsageMap _ownedPages;
+ private final UsageMap _ownedPages;
/** Usage map of pages that this table owns with free space on them */
- private UsageMap _freeSpacePages;
+ private final UsageMap _freeSpacePages;
+ /** Number of rows in the table */
+ private int _rowCount;
+ /** last long auto number for the table */
+ private int _lastLongAutoNumber;
+ /** last complex type auto number for the table */
+ private int _lastComplexTypeAutoNumber;
/** modification count for the table, keeps row-states up-to-date */
private int _modCount;
/** page buffer used to update data pages when adding rows */
/**
* Only used by unit tests
-
+ * @usage _advanced_method_
*/
TableImpl(boolean testing, List<ColumnImpl> columns) throws IOException {
if(!testing) {
_database = null;
_tableDefPageNumber = PageChannel.INVALID_PAGE_NUMBER;
_name = null;
- setColumns(columns);
+
+ _columns.addAll(columns);
+ for(ColumnImpl col : _columns) {
+ if(col.getType().isVariableLength()) {
+ _varColumns.add(col);
+ }
+ }
+ _maxColumnCount = (short)_columns.size();
+ _maxVarColumnCount = (short)_varColumns.size();
+ getAutoNumberColumns();
+
_fkEnforcer = null;
_flags = 0;
+ _tableType = TYPE_USER;
+ _indexCount = 0;
+ _logicalIndexCount = 0;
+ _ownedPages = null;
+ _freeSpacePages = null;
}
/**
_tableDefPageNumber = pageNumber;
_name = name;
_flags = flags;
- readTableDefinition(loadCompleteTableDefinitionBuffer(tableBuffer));
+
+ // read table definition
+ tableBuffer = loadCompleteTableDefinitionBuffer(tableBuffer);
+ _rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS);
+ _lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER);
+ if(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) {
+ _lastComplexTypeAutoNumber = tableBuffer.getInt(
+ getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER);
+ }
+ _tableType = tableBuffer.get(getFormat().OFFSET_TABLE_TYPE);
+ _maxColumnCount = tableBuffer.getShort(getFormat().OFFSET_MAX_COLS);
+ _maxVarColumnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_VAR_COLS);
+ short columnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_COLS);
+ _logicalIndexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEX_SLOTS);
+ _indexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEXES);
+
+ int rowNum = ByteUtil.getUnsignedByte(
+ tableBuffer, getFormat().OFFSET_OWNED_PAGES);
+ int pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_OWNED_PAGES + 1);
+ _ownedPages = UsageMap.read(getDatabase(), pageNum, rowNum, false);
+ rowNum = ByteUtil.getUnsignedByte(
+ tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES);
+ pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES + 1);
+ _freeSpacePages = UsageMap.read(getDatabase(), pageNum, rowNum, false);
+
+ for (int i = 0; i < _indexCount; i++) {
+ _indexDatas.add(IndexData.create(this, tableBuffer, i, getFormat()));
+ }
+
+ readColumnDefinitions(tableBuffer, columnCount);
+
+ readIndexDefinitions(tableBuffer);
+
+ // re-sort columns if necessary
+ if(getDatabase().getColumnOrder() != ColumnOrder.DATA) {
+ Collections.sort(_columns, DISPLAY_ORDER_COMPARATOR);
+ }
+
+ for(ColumnImpl col : _columns) {
+ // some columns need to do extra work after the table is completely
+ // loaded
+ col.postTableLoadInit();
+ }
+
_fkEnforcer = new FKEnforcer(this);
}
throw new IllegalArgumentException("Column with name " + name +
" does not exist in this table");
}
-
- /**
- * Only called by unit tests
- */
- private void setColumns(List<ColumnImpl> columns) {
- _columns.addAll(columns);
- int colIdx = 0;
- int varLenIdx = 0;
- int fixedOffset = 0;
- for(ColumnImpl col : _columns) {
- col.setColumnNumber((short)colIdx);
- col.setColumnIndex(colIdx++);
- if(col.isVariableLength()) {
- col.setVarLenTableIndex(varLenIdx++);
- _varColumns.add(col);
- } else {
- col.setFixedDataOffset(fixedOffset);
- fixedOffset += col.getType().getFixedSize();
- }
- }
- _maxColumnCount = (short)_columns.size();
- _maxVarColumnCount = (short)_varColumns.size();
- _autoNumColumns = getAutoNumberColumns(columns);
- }
public PropertyMap getProperties() throws IOException {
if(_props == null) {
return tableBuffer;
}
- /**
- * Read the table definition
- */
- private void readTableDefinition(ByteBuffer tableBuffer) throws IOException
+ private void readColumnDefinitions(ByteBuffer tableBuffer, short columnCount)
+ throws IOException
{
- _rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS);
- _lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER);
- if(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) {
- _lastComplexTypeAutoNumber = tableBuffer.getInt(
- getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER);
- }
- _tableType = tableBuffer.get(getFormat().OFFSET_TABLE_TYPE);
- _maxColumnCount = tableBuffer.getShort(getFormat().OFFSET_MAX_COLS);
- _maxVarColumnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_VAR_COLS);
- short columnCount = tableBuffer.getShort(getFormat().OFFSET_NUM_COLS);
- _logicalIndexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEX_SLOTS);
- _indexCount = tableBuffer.getInt(getFormat().OFFSET_NUM_INDEXES);
-
- int rowNum = ByteUtil.getUnsignedByte(
- tableBuffer, getFormat().OFFSET_OWNED_PAGES);
- int pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_OWNED_PAGES + 1);
- _ownedPages = UsageMap.read(getDatabase(), pageNum, rowNum, false);
- rowNum = ByteUtil.getUnsignedByte(
- tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES);
- pageNum = ByteUtil.get3ByteInt(tableBuffer, getFormat().OFFSET_FREE_SPACE_PAGES + 1);
- _freeSpacePages = UsageMap.read(getDatabase(), pageNum, rowNum, false);
-
- for (int i = 0; i < _indexCount; i++) {
- _indexDatas.add(IndexData.create(this, tableBuffer, i, getFormat()));
- }
-
int colOffset = getFormat().OFFSET_INDEX_DEF_BLOCK +
_indexCount * getFormat().SIZE_INDEX_DEFINITION;
int dispIndex = 0;
column.setName(readName(tableBuffer));
}
Collections.sort(_columns);
- _autoNumColumns = getAutoNumberColumns(_columns);
+ getAutoNumberColumns();
// setup the data index for the columns
int colIdx = 0;
// sort variable length columns based on their index into the variable
// length offset table, because we will write the columns in this order
Collections.sort(_varColumns, VAR_LEN_COLUMN_COMPARATOR);
+ }
+ private void readIndexDefinitions(ByteBuffer tableBuffer) throws IOException
+ {
// read index column information
for (int i = 0; i < _indexCount; i++) {
IndexData idxData = _indexDatas.get(i);
}
Collections.sort(_indexes);
-
- // re-sort columns if necessary
- if(getDatabase().getColumnOrder() != ColumnOrder.DATA) {
- Collections.sort(_columns, DISPLAY_ORDER_COMPARATOR);
- }
-
- for(ColumnImpl col : _columns) {
- // some columns need to do extra work after the table is completely
- // loaded
- col.postTableLoadInit();
- }
}
/**
return rowSize + format.SIZE_ROW_LOCATION;
}
- /**
- * @return the "AutoNumber" columns in the given collection of columns.
- * @usage _advanced_method_
- */
- public static List<ColumnImpl> getAutoNumberColumns(
- Collection<ColumnImpl> columns)
- {
- List<ColumnImpl> autoCols = new ArrayList<ColumnImpl>(1);
- for(ColumnImpl c : columns) {
+ private void getAutoNumberColumns() {
+ for(ColumnImpl c : _columns) {
if(c.isAutoNumber()) {
- autoCols.add(c);
+ _autoNumColumns.add(c);
}
}
- return (!autoCols.isEmpty() ? autoCols : Collections.<ColumnImpl>emptyList());
}
/**
private final PageChannel _pageChannel = new PageChannel(true);
private List<Column> _columns = new ArrayList<Column>();
private Table _testTable;
+ private int _varLenIdx;
+ private int _fixedOffset;
+
public TableTest(String name) {
super(name);
return _testTable;
}
- private Column newTestColumn() {
- return new Column(true, null) {
+ private Column newTestColumn(DataType type) {
+
+ int nextColIdx = _columns.size();
+ int nextVarLenIdx = 0;
+ int nextFixedOff = 0;
+
+ if(type.isVariableLength()) {
+ nextVarLenIdx = _varLenIdx++;
+ } else {
+ nextFixedOff = _fixedOffset;
+ _fixedOffset += type.getFixedSize();
+ }
+
+ return new Column(null, type, nextColIdx, nextFixedOff, nextVarLenIdx) {
@Override
public Table getTable() {
return _testTable;