- remove debug log blocks
- add Row interface
- change savepoint to use table number instead of name?
+- don't use columnimpl for creating tables
+ - clean up columnimpl/tableimpl constructors
+- add updateCurrentRow(Map), add updateRow(Row)
import java.sql.SQLException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
/**
* Builder style class for constructing a Column.
*
*/
public class ColumnBuilder {
+ private static final Log LOG = LogFactory.getLog(ColumnBuilder.class);
+
/** name of the new column */
private String _name;
/** the type of the new column */
private DataType _type;
/** optional length for the new column */
- private Integer _length;
+ private Short _length;
/** optional precision for the new column */
- private Integer _precision;
+ private Byte _precision;
/** optional scale for the new column */
- private Integer _scale;
+ private Byte _scale;
/** whether or not the column is auto-number */
private boolean _autoNumber;
/** whether or not the column allows compressed unicode */
- private Boolean _compressedUnicode;
+ private boolean _compressedUnicode;
+ /** whether or not the column is a hyperlink (memo only) */
+ private boolean _hyperlink;
+ /** 0-based column number */
+ private short _columnNumber;
+ /** the collating sort order for a text field */
+ private ColumnImpl.SortOrder _sortOrder;
+
public ColumnBuilder(String name) {
this(name, null);
_type = type;
}
+ public String getName() {
+ return _name;
+ }
+
/**
* Sets the type for the new column.
*/
return this;
}
+ public DataType getType() {
+ return _type;
+ }
+
/**
* Sets the type for the new column based on the given SQL type.
*/
* Sets the precision for the new column.
*/
public ColumnBuilder setPrecision(int newPrecision) {
- _precision = newPrecision;
+ _precision = (byte)newPrecision;
return this;
}
+ public byte getPrecision() {
+ return ((_precision != null) ? _precision :
+ (byte)(_type.getHasScalePrecision() ? _type.getDefaultPrecision() : 0));
+ }
+
/**
* Sets the scale for the new column.
*/
public ColumnBuilder setScale(int newScale) {
- _scale = newScale;
+ _scale = (byte)newScale;
return this;
}
+ public byte getScale() {
+ return ((_scale != null) ? _scale :
+ (byte)(_type.getHasScalePrecision() ? _type.getDefaultScale() : 0));
+ }
+
/**
* Sets the length (in bytes) for the new column.
*/
public ColumnBuilder setLength(int length) {
- _length = length;
+ _length = (short)length;
return this;
}
+ public short getLength() {
+ return ((_length != null) ? _length :
+ (short)(!_type.isVariableLength() ? _type.getFixedSize() :
+ (!_type.isLongValue() ? _type.getDefaultSize() : 0)));
+ }
+
/**
* Sets the length (in type specific units) for the new column.
*/
return this;
}
+ public boolean isAutoNumber() {
+ return _autoNumber;
+ }
+
/**
* Sets whether of not the new column allows unicode compression.
*/
return this;
}
+ public boolean isCompressedUnicode() {
+ return _compressedUnicode;
+ }
+
+ /**
+ * Sets whether of not the new column allows unicode compression.
+ */
+ public ColumnBuilder setHyperlink(boolean hyperlink) {
+ _hyperlink = hyperlink;
+ return this;
+ }
+
+ public boolean isHyperlink() {
+ return _hyperlink;
+ }
+
/**
* Sets all attributes except name from the given Column template.
*/
- public ColumnBuilder setFromColumn(ColumnImpl template) {
+ public ColumnBuilder setFromColumn(Column template) {
DataType type = template.getType();
setType(type);
setLength(template.getLength());
setPrecision(template.getPrecision());
}
setCompressedUnicode(template.isCompressedUnicode());
+ setHyperlink(template.isHyperlink());
return this;
}
/**
- * Escapes the new column's name using {@link Database#escapeIdentifier}.
+ * Sets all attributes except name from the given Column template.
+ */
+ public ColumnBuilder setFromColumn(ColumnBuilder template) {
+ DataType type = template.getType();
+ setType(type);
+ setLength(template.getLength());
+ setAutoNumber(template.isAutoNumber());
+ if(type.getHasScalePrecision()) {
+ setScale(template.getScale());
+ setPrecision(template.getPrecision());
+ }
+ setCompressedUnicode(template.isCompressedUnicode());
+ setHyperlink(template.isHyperlink());
+
+ return this;
+ }
+
+ /**
+ * Escapes the new column's name using {@link DatabaseImpl#escapeIdentifier}.
*/
public ColumnBuilder escapeName()
{
return this;
}
+ short getColumnNumber() {
+ return _columnNumber;
+ }
+
+ void setColumnNumber(short newColumnNumber) {
+ _columnNumber = newColumnNumber;
+ }
+
+ ColumnImpl.SortOrder getTextSortOrder() {
+ return _sortOrder;
+ }
+
+ void setTextSortOrder(ColumnImpl.SortOrder newTextSortOrder) {
+ _sortOrder = newTextSortOrder;
+ }
+
/**
- * Creates a new Column with the currently configured attributes.
+ * Checks that this column definition is valid.
+ *
+ * @throws IllegalArgumentException if this column definition is invalid.
+ * @usage _advanced_method_
*/
- public ColumnImpl toColumn() {
- ColumnImpl col = new ColumnImpl();
- col.setName(_name);
- col.setType(_type);
- if(_length != null) {
- col.setLength(_length.shortValue());
+ public void validate(JetFormat format) {
+ if(getType() == null) {
+ throw new IllegalArgumentException("must have type");
+ }
+ DatabaseImpl.validateIdentifierName(
+ getName(), format.MAX_COLUMN_NAME_LENGTH, "column");
+
+ if(getType().isUnsupported()) {
+ throw new IllegalArgumentException(
+ "Cannot create column with unsupported type " + getType());
+ }
+ if(!format.isSupportedDataType(getType())) {
+ throw new IllegalArgumentException(
+ "Database format " + format + " does not support type " + getType());
}
- if(_precision != null) {
- col.setPrecision(_precision.byteValue());
+
+ if(!getType().isVariableLength()) {
+ if(getLength() != getType().getFixedSize()) {
+ if(getLength() < getType().getFixedSize()) {
+ throw new IllegalArgumentException("invalid fixed length size");
+ }
+ LOG.warn("Column length " + getLength() +
+ " longer than expected fixed size " +
+ getType().getFixedSize());
+ }
+ } else if(!getType().isLongValue()) {
+ if(!getType().isValidSize(getLength())) {
+ throw new IllegalArgumentException("var length out of range");
+ }
+ }
+
+ if(getType().getHasScalePrecision()) {
+ if(!getType().isValidScale(getScale())) {
+ throw new IllegalArgumentException(
+ "Scale must be from " + getType().getMinScale() + " to " +
+ getType().getMaxScale() + " inclusive");
+ }
+ if(!getType().isValidPrecision(getPrecision())) {
+ throw new IllegalArgumentException(
+ "Precision must be from " + getType().getMinPrecision() + " to " +
+ getType().getMaxPrecision() + " inclusive");
+ }
}
- if(_scale != null) {
- col.setScale(_scale.byteValue());
+
+ if(isAutoNumber()) {
+ if(!getType().mayBeAutoNumber()) {
+ throw new IllegalArgumentException(
+ "Auto number column must be long integer or guid");
+ }
}
- if(_autoNumber) {
- col.setAutoNumber(true);
+
+ if(isCompressedUnicode()) {
+ if(!getType().isTextual()) {
+ throw new IllegalArgumentException(
+ "Only textual columns allow unicode compression (text/memo)");
+ }
}
- if(_compressedUnicode != null) {
- col.setCompressedUnicode(_compressedUnicode);
+
+ if(isHyperlink()) {
+ if(getType() != DataType.MEMO) {
+ throw new IllegalArgumentException(
+ "Only memo columns can be hyperlinks");
+ }
}
- return col;
+ }
+
+ /**
+ * Creates a new Column with the currently configured attributes.
+ */
+ public ColumnBuilder toColumn() {
+ // for backwards compat w/ old code
+ return this;
}
}
/** properties for this column, if any */
private PropertyMap _props;
- /**
- * @usage _general_method_
- */
- public ColumnImpl() {
- this(null);
- }
-
/**
* @usage _advanced_method_
*/
- public ColumnImpl(JetFormat format) {
- _table = null;
- }
-
- /**
- * Only used by unit tests
- */
- ColumnImpl(boolean testing, TableImpl table) {
- if(!testing) {
- throw new IllegalArgumentException();
- }
+ ColumnImpl(TableImpl table) {
_table = table;
}
{
_table = table;
_displayIndex = displayIndex;
- if (LOG.isDebugEnabled()) {
- LOG.debug("Column def block:\n" + ByteUtil.toHexString(buffer, offset, 25));
- }
byte colType = buffer.get(offset + getFormat().OFFSET_COLUMN_TYPE);
_columnNumber = buffer.getShort(offset + getFormat().OFFSET_COLUMN_NUMBER);
return _type.getSQLType();
}
- /**
- * @usage _general_method_
- */
- public void setSQLType(int type) throws SQLException {
- setSQLType(type, 0);
- }
-
- /**
- * @usage _general_method_
- */
- public void setSQLType(int type, int lengthInUnits) throws SQLException {
- setType(DataType.fromSQLType(type, lengthInUnits));
- }
-
public boolean isCompressedUnicode() {
return _textInfo._compressedUnicode;
}
}
}
- /**
- * Checks that this column definition is valid.
- *
- * @throws IllegalArgumentException if this column definition is invalid.
- * @usage _advanced_method_
- */
- public void validate(JetFormat format) {
- if(getType() == null) {
- throw new IllegalArgumentException("must have type");
- }
- DatabaseImpl.validateIdentifierName(getName(), format.MAX_COLUMN_NAME_LENGTH,
- "column");
-
- if(getType().isUnsupported()) {
- throw new IllegalArgumentException(
- "Cannot create column with unsupported type " + getType());
- }
- if(!format.isSupportedDataType(getType())) {
- throw new IllegalArgumentException(
- "Database format " + format + " does not support type " + getType());
- }
-
- if(isVariableLength() != getType().isVariableLength()) {
- throw new IllegalArgumentException("invalid variable length setting");
- }
-
- if(!isVariableLength()) {
- if(getLength() != getType().getFixedSize()) {
- if(getLength() < getType().getFixedSize()) {
- throw new IllegalArgumentException("invalid fixed length size");
- }
- LOG.warn("Column length " + getLength() +
- " longer than expected fixed size " +
- getType().getFixedSize());
- }
- } else if(!getType().isLongValue()) {
- if(!getType().isValidSize(getLength())) {
- throw new IllegalArgumentException("var length out of range");
- }
- }
-
- if(getType().getHasScalePrecision()) {
- if(!getType().isValidScale(getScale())) {
- throw new IllegalArgumentException(
- "Scale must be from " + getType().getMinScale() + " to " +
- getType().getMaxScale() + " inclusive");
- }
- if(!getType().isValidPrecision(getPrecision())) {
- throw new IllegalArgumentException(
- "Precision must be from " + getType().getMinPrecision() + " to " +
- getType().getMaxPrecision() + " inclusive");
- }
- }
-
- if(isAutoNumber()) {
- if(!getType().mayBeAutoNumber()) {
- throw new IllegalArgumentException(
- "Auto number column must be long integer or guid");
- }
- }
-
- if(isCompressedUnicode()) {
- if(!getType().isTextual()) {
- throw new IllegalArgumentException(
- "Only textual columns allow unicode compression (text/memo)");
- }
- }
-
- if(isHyperlink()) {
- if(getType() != DataType.MEMO) {
- throw new IllegalArgumentException(
- "Only memo columns can be hyperlinks");
- }
- }
- }
-
public Object setRowValue(Object[] rowArray, Object value) {
rowArray[_columnIndex] = value;
return value;
/**
* Constructs a byte containing the flags for this column.
*/
- private byte getColumnBitFlags() {
+ private static byte getColumnBitFlags(ColumnBuilder col) {
byte flags = UNKNOWN_FLAG_MASK;
- if(!isVariableLength()) {
+ if(!col.getType().isVariableLength()) {
flags |= FIXED_LEN_FLAG_MASK;
}
- if(isAutoNumber()) {
- flags |= getAutoNumberGenerator().getColumnFlags();
+ if(col.isAutoNumber()) {
+ byte autoNumFlags = 0;
+ switch(col.getType()) {
+ case LONG:
+ case COMPLEX_TYPE:
+ autoNumFlags = AUTO_NUMBER_FLAG_MASK;
+ break;
+ case GUID:
+ autoNumFlags = AUTO_NUMBER_GUID_FLAG_MASK;
+ break;
+ default:
+ // unknown autonum type
+ }
+ flags |= autoNumFlags;
}
- if(isHyperlink()) {
+ if(col.isHyperlink()) {
flags |= HYPERLINK_FLAG_MASK;
}
return flags;
* @return The number of variable length columns found in the list
* @usage _advanced_method_
*/
- public static short countVariableLength(List<ColumnImpl> columns) {
+ public static short countVariableLength(List<ColumnBuilder> columns) {
short rtn = 0;
- for (ColumnImpl col : columns) {
- if (col.isVariableLength()) {
+ for (ColumnBuilder col : columns) {
+ if (col.getType().isVariableLength()) {
rtn++;
}
}
* found in the list
* @usage _advanced_method_
*/
- public static short countNonLongVariableLength(List<ColumnImpl> columns) {
+ public static short countNonLongVariableLength(List<ColumnBuilder> columns) {
short rtn = 0;
- for (ColumnImpl col : columns) {
- if (col.isVariableLength() && !col.getType().isLongValue()) {
+ for (ColumnBuilder col : columns) {
+ if (col.getType().isVariableLength() && !col.getType().isLongValue()) {
rtn++;
}
}
protected static void writeDefinitions(TableCreator creator, ByteBuffer buffer)
throws IOException
{
- List<ColumnImpl> columns = creator.getColumns();
+ List<ColumnBuilder> columns = creator.getColumns();
short columnNumber = (short) 0;
short fixedOffset = (short) 0;
short variableOffset = (short) 0;
// variable length values so that we have a better chance of fitting it
// all (because "long variable" values can go in separate pages)
short longVariableOffset = countNonLongVariableLength(columns);
- for (ColumnImpl col : columns) {
+ for (ColumnBuilder col : columns) {
// record this for later use when writing indexes
col.setColumnNumber(columnNumber);
buffer.put(col.getType().getValue());
buffer.putInt(TableImpl.MAGIC_TABLE_NUMBER); //constant magic number
buffer.putShort(columnNumber); //Column Number
- if (col.isVariableLength()) {
+ if (col.getType().isVariableLength()) {
if(!col.getType().isLongValue()) {
buffer.putShort(variableOffset++);
} else {
}
buffer.putShort((short) 0); //Unknown
}
- buffer.put(col.getColumnBitFlags()); // misc col flags
+ buffer.put(getColumnBitFlags(col)); // misc col flags
if (col.isCompressedUnicode()) { //Compressed
buffer.put((byte) 1);
} else {
}
buffer.putInt(0); //Unknown, but always 0.
//Offset for fixed length columns
- if (col.isVariableLength()) {
+ if (col.getType().isVariableLength()) {
buffer.putShort((short) 0);
} else {
buffer.putShort(fixedOffset);
buffer.putShort((short)0x0000); // unused
}
columnNumber++;
- if (LOG.isDebugEnabled()) {
- LOG.debug("Creating new column def block\n" + ByteUtil.toHexString(
- buffer, position, creator.getFormat().SIZE_COLUMN_DEF_BLOCK));
- }
}
- for (ColumnImpl col : columns) {
+ for (ColumnBuilder col : columns) {
TableImpl.writeName(buffer, col.getName(), creator.getCharset());
}
}
*/
public abstract Object getNext(Object prevRowValue);
- /**
- * Returns the flags used when writing this column.
- */
- public abstract int getColumnFlags();
-
/**
* Returns the type of values generated by this generator.
*/
return getTable().getNextLongAutoNumber();
}
- @Override
- public int getColumnFlags() {
- return AUTO_NUMBER_FLAG_MASK;
- }
-
@Override
public DataType getType() {
return DataType.LONG;
return _lastAutoNumber;
}
- @Override
- public int getColumnFlags() {
- return AUTO_NUMBER_GUID_FLAG_MASK;
- }
-
@Override
public DataType getType() {
return DataType.GUID;
return new ComplexValueForeignKey(ColumnImpl.this, nextComplexAutoNum);
}
- @Override
- public int getColumnFlags() {
- return AUTO_NUMBER_FLAG_MASK;
- }
-
@Override
public DataType getType() {
return DataType.COMPLEX_TYPE;
throw new UnsupportedOperationException();
}
- @Override
- public int getColumnFlags() {
- throw new UnsupportedOperationException();
- }
-
@Override
public DataType getType() {
return _genType;
* @param columns List of Columns in the table
* @usage _general_method_
*/
- public void createTable(String name, List<ColumnImpl> columns)
+ public void createTable(String name, List<ColumnBuilder> columns)
throws IOException
{
createTable(name, columns, null);
* @param indexes List of IndexBuilders describing indexes for the table
* @usage _general_method_
*/
- public void createTable(String name, List<ColumnImpl> columns,
+ public void createTable(String name, List<ColumnBuilder> columns,
List<IndexBuilder> indexes)
throws IOException
{
*/
public interface ExportFilter {
+ /**
+ * Called before any calls {@link #filterColumns} and {@link #filterRow} for
+ * a single export operation. Allows the given instance to return a
+ * per-call instance which can maintain state.
+ *
+ * @return the ExportFilter instance to use for the rest of the export
+ * operation
+ */
+ public ExportFilter init();
+
/**
* The columns that should be used to create the exported file.
*
* modified and returned
* @return the columns to use when creating the export file
*/
- public List<ColumnImpl> filterColumns(List<ColumnImpl> columns) throws IOException;
+ public List<ColumnImpl> filterColumns(List<ColumnImpl> columns)
+ throws IOException;
/**
* The desired values for the row.
"(?:" + Pattern.quote(delimiter) + ")|(?:" +
Pattern.quote("" + quote) + ")|(?:[\n\r])");
+ // allow filter to setup per-call state
+ filter = filter.init();
+
List<ColumnImpl> origCols = cursor.getTable().getColumns();
List<ColumnImpl> columns = new ArrayList<ColumnImpl>(origCols);
columns = filter.filterColumns(columns);
*/
public interface ImportFilter {
+ /**
+ * Called before any calls {@link #filterColumns} and {@link #filterRow} for
+ * a single import operation. Allows the given instance to return a
+ * per-call instance which can maintain state.
+ *
+ * @return the ImportFilter instance to use for the rest of the import
+ * operation
+ */
+ public ImportFilter init();
+
/**
* The columns that should be used to create the imported table.
* @param destColumns the columns as determined by the import code, may be
* JDBC source
* @return the columns to use when creating the import table
*/
- public List<ColumnImpl> filterColumns(List<ColumnImpl> destColumns,
- ResultSetMetaData srcColumns)
+ public List<ColumnBuilder> filterColumns(List<ColumnBuilder> destColumns,
+ ResultSetMetaData srcColumns)
throws SQLException, IOException;
/**
*
* @return a List of Columns
*/
- public static List<ColumnImpl> toColumns(ResultSetMetaData md)
+ public static List<ColumnBuilder> toColumns(ResultSetMetaData md)
throws SQLException
{
- List<ColumnImpl> columns = new LinkedList<ColumnImpl>();
+ List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>();
for (int i = 1; i <= md.getColumnCount(); i++) {
- ColumnImpl column = new ColumnImpl();
- column.setName(DatabaseImpl.escapeIdentifier(md.getColumnName(i)));
+ ColumnBuilder column = new ColumnBuilder(md.getColumnName(i)).escapeName();
int lengthInUnits = md.getColumnDisplaySize(i);
column.setSQLType(md.getColumnType(i), lengthInUnits);
DataType type = column.getType();
{
ResultSetMetaData md = source.getMetaData();
+ // allow filter to setup per-call state
+ filter = filter.init();
+
name = DatabaseImpl.escapeIdentifier(name);
Table table = null;
if(!useExistingTable || ((table = db.getTable(name)) == null)) {
- List<ColumnImpl> columns = toColumns(md);
+ List<ColumnBuilder> columns = toColumns(md);
table = createUniqueTable(db, name, columns, md, filter);
}
Pattern delimPat = Pattern.compile(delim);
+ // allow filter to setup per-call state
+ filter = filter.init();
+
try {
name = DatabaseImpl.escapeIdentifier(name);
Table table = null;
if(!useExistingTable || ((table = db.getTable(name)) == null)) {
- List<ColumnImpl> columns = new LinkedList<ColumnImpl>();
+ List<ColumnBuilder> columns = new LinkedList<ColumnBuilder>();
Object[] columnNames = splitLine(line, delimPat, quote, in, 0);
for (int i = 0; i < columnNames.length; i++) {
* Returns a new table with a unique name and the given table definition.
*/
private static Table createUniqueTable(DatabaseImpl db, String name,
- List<ColumnImpl> columns,
+ List<ColumnBuilder> columns,
ResultSetMetaData md,
ImportFilter filter)
throws IOException, SQLException
flags = idxCol.getFlags();
// find actual table column number
- for(ColumnImpl col : creator.getColumns()) {
+ for(ColumnBuilder col : creator.getColumns()) {
if(col.getName().equalsIgnoreCase(idxCol.getName())) {
columnNumber = col.getColumnNumber();
break;
throws IOException
{
validatePageNumber(pageNumber);
- if (LOG.isDebugEnabled()) {
- LOG.debug("Reading in page " + Integer.toHexString(pageNumber));
- }
buffer.clear();
int bytesRead = _channel.read(
buffer, (long) pageNumber * (long) getFormat().PAGE_SIZE);
*/
private class PropColumn extends ColumnImpl
{
+ private PropColumn() {
+ super(null);
+ }
+
@Override
public DatabaseImpl getDatabase() {
return _database;
public SimpleExportFilter() {
}
+ public ExportFilter init() {
+ return this;
+ }
+
public List<ColumnImpl> filterColumns(List<ColumnImpl> columns) throws IOException {
return columns;
}
public SimpleImportFilter() {
}
+
+ public ImportFilter init() {
+ return this;
+ }
- public List<ColumnImpl> filterColumns(List<ColumnImpl> destColumns,
- ResultSetMetaData srcColumns)
+ public List<ColumnBuilder> filterColumns(List<ColumnBuilder> destColumns,
+ ResultSetMetaData srcColumns)
throws SQLException, IOException
{
return destColumns;
/** name of the new table */
private String _name;
/** columns for the new table */
- private List<ColumnImpl> _columns = new ArrayList<ColumnImpl>();
+ private List<ColumnBuilder> _columns = new ArrayList<ColumnBuilder>();
/** indexes for the new table */
private List<IndexBuilder> _indexes = new ArrayList<IndexBuilder>();
/** whether or not table/column/index names are automatically escaped */
/**
* Adds a Column to the new table.
*/
- public TableBuilder addColumn(ColumnImpl column) {
+ public TableBuilder addColumn(ColumnBuilder column) {
if(_escapeIdentifiers) {
- column.setName(DatabaseImpl.escapeIdentifier(column.getName()));
+ column.escapeName();
}
_columns.add(column);
return this;
}
- /**
- * Adds a Column to the new table.
- */
- public TableBuilder addColumn(ColumnBuilder columnBuilder) {
- return addColumn(columnBuilder.toColumn());
- }
-
/**
* Adds an IndexBuilder to the new table.
*/
import java.io.IOException;
import java.nio.charset.Charset;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
{
private final DatabaseImpl _database;
private final String _name;
- private final List<ColumnImpl> _columns;
+ private final List<ColumnBuilder> _columns;
private final List<IndexBuilder> _indexes;
private final Map<IndexBuilder,IndexState> _indexStates =
new HashMap<IndexBuilder,IndexState>();
private int _indexCount;
private int _logicalIndexCount;
- public TableCreator(DatabaseImpl database, String name, List<ColumnImpl> columns,
+ public TableCreator(DatabaseImpl database, String name, List<ColumnBuilder> columns,
List<IndexBuilder> indexes) {
_database = database;
_name = name;
return _umapPageNumber;
}
- public List<ColumnImpl> getColumns() {
+ public List<ColumnBuilder> getColumns() {
return _columns;
}
Set<String> colNames = new HashSet<String>();
// next, validate the column definitions
- for(ColumnImpl column : _columns) {
+ for(ColumnBuilder column : _columns) {
// FIXME for now, we can't create complex columns
if(column.getType() == DataType.COMPLEX_TYPE) {
}
}
- List<ColumnImpl> autoCols = TableImpl.getAutoNumberColumns(_columns);
+ List<ColumnBuilder> autoCols = getAutoNumberColumns();
if(autoCols.size() > 1) {
// for most autonumber types, we can only have one of each type
Set<DataType> autoTypes = EnumSet.noneOf(DataType.class);
- for(ColumnImpl c : autoCols) {
+ for(ColumnBuilder c : autoCols) {
if(!c.getType().isMultipleAutoNumberAllowed() &&
!autoTypes.add(c.getType())) {
throw new IllegalArgumentException(
}
}
+ private List<ColumnBuilder> getAutoNumberColumns()
+ {
+ List<ColumnBuilder> autoCols = new ArrayList<ColumnBuilder>(1);
+ for(ColumnBuilder c : _columns) {
+ if(c.isAutoNumber()) {
+ autoCols.add(c);
+ }
+ }
+ return autoCols;
+ }
+
/**
* Maintains additional state used during index creation.
* @usage _advanced_class_
/** owning database */
private final DatabaseImpl _database;
/** additional table flags from the catalog entry */
- private int _flags;
+ private final int _flags;
/** Type of the table (either TYPE_SYSTEM or TYPE_USER) */
private byte _tableType;
/** Number of actual indexes on the table */
/** max Number of variable columns in the table */
private short _maxVarColumnCount;
/** List of columns in this table, ordered by column number */
- private List<ColumnImpl> _columns = new ArrayList<ColumnImpl>();
+ 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 */
_name = null;
setColumns(columns);
_fkEnforcer = null;
+ _flags = 0;
}
/**
* Only called by unit tests
*/
private void setColumns(List<ColumnImpl> columns) {
- _columns = columns;
+ _columns.addAll(columns);
int colIdx = 0;
int varLenIdx = 0;
int fixedOffset = 0;
// total up the amount of space used by the column and index names (2
// bytes per char + 2 bytes for the length)
- for(ColumnImpl col : creator.getColumns()) {
+ for(ColumnBuilder col : creator.getColumns()) {
int nameByteLen = (col.getName().length() *
JetFormat.TEXT_FIELD_UNIT_SIZE);
totalTableDefSize += nameByteLen + 2;
TableCreator creator, ByteBuffer buffer, int totalTableDefSize)
throws IOException
{
- List<ColumnImpl> columns = creator.getColumns();
+ List<ColumnBuilder> columns = creator.getColumns();
//Start writing the tdef
writeTablePageHeader(buffer);
ByteUtil.put3ByteInt(buffer, creator.getUmapPageNumber()); //Usage map page number
buffer.put((byte) 1); //Free map row number
ByteUtil.put3ByteInt(buffer, creator.getUmapPageNumber()); //Free map page number
- if (LOG.isDebugEnabled()) {
- int position = buffer.position();
- buffer.rewind();
- LOG.debug("Creating new table def block:\n" + ByteUtil.toHexString(
- buffer, creator.getFormat().SIZE_TDEF_HEADER));
- buffer.position(position);
- }
}
/**
*/
private void readTableDefinition(ByteBuffer tableBuffer) throws IOException
{
- if (LOG.isDebugEnabled()) {
- tableBuffer.rewind();
- LOG.debug("Table def block:\n" + ByteUtil.toHexString(tableBuffer,
- getFormat().SIZE_TDEF_HEADER));
- }
_rowCount = tableBuffer.getInt(getFormat().OFFSET_NUM_ROWS);
_lastLongAutoNumber = tableBuffer.getInt(getFormat().OFFSET_NEXT_AUTO_NUMBER);
if(getFormat().OFFSET_NEXT_COMPLEX_AUTO_NUMBER >= 0) {
* @return Page number of the new page
*/
private ByteBuffer newDataPage() throws IOException {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Creating new data page");
- }
ByteBuffer dataPage = _addRowBufferH.setNewPage(getPageChannel());
dataPage.put(PageTypes.DATA); //Page type
dataPage.put((byte) 1); //Unknown
nullMask.write(buffer); //Null mask
buffer.flip();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Creating new data block:\n" + ByteUtil.toHexString(buffer, buffer.limit()));
- }
return buffer;
}
_rowStart = rowStart;
_tableBuffer.position(_rowStart + getFormat().OFFSET_USAGE_MAP_START);
_startOffset = _tableBuffer.position();
- if (LOG.isDebugEnabled()) {
- LOG.debug("Usage map block:\n" + ByteUtil.toHexString(_tableBuffer, _rowStart,
- tableBuffer.limit() - _rowStart));
- }
}
public DatabaseImpl getDatabase() {