String tableName = alterTableDef.getTableName();
String newTableName = alterTableDef.getNewTableName();
ISqlJetColumnDef newColumnDef = alterTableDef.getNewColumnDef();
if (null == tableName) {
throw new SqlJetException(SqlJetErrorCode.MISUSE, "Table name isn't defined");
}
if (null == newTableName && null == newColumnDef) {
throw new SqlJetException(SqlJetErrorCode.MISUSE, "Not defined any altering");
}
boolean renameTable = false;
if (null != newTableName) {
renameTable = true;
} else {
newTableName = tableName;
}
if (renameTable && tableDefs.containsKey(newTableName)) {
throw new SqlJetException(SqlJetErrorCode.MISUSE,
String.format("Table \"%s\" already exists", newTableName));
}
final SqlJetTableDef tableDef = (SqlJetTableDef) tableDefs.get(tableName);
if (null == tableDef) {
throw new SqlJetException(SqlJetErrorCode.MISUSE, String.format("Table \"%s\" not found", tableName));
}
List<ISqlJetColumnDef> columns = tableDef.getColumns();
if (null != newColumnDef) {
final String fieldName = newColumnDef.getName();
if (tableDef.getColumn(fieldName) != null) {
throw new SqlJetException(SqlJetErrorCode.MISUSE, String.format(
"Field \"%s\" already exists in table \"%s\"", fieldName, tableName));
}
final List<ISqlJetColumnConstraint> constraints = newColumnDef.getConstraints();
if (null != constraints && 0 != constraints.size()) {
boolean notNull = false;
boolean defaultValue = false;
for (final ISqlJetColumnConstraint constraint : constraints) {
if (constraint instanceof ISqlJetColumnNotNull) {
notNull = true;
} else if (constraint instanceof ISqlJetColumnDefault) {
defaultValue = true;
} else {
throw new SqlJetException(SqlJetErrorCode.MISUSE, String.format("Invalid constraint: %s",
constraint.toString()));
}
}
if (notNull && !defaultValue) {
throw new SqlJetException(SqlJetErrorCode.MISUSE, "NOT NULL requires to have DEFAULT value");
}
}
columns = new ArrayList<ISqlJetColumnDef>(columns);
columns.add(newColumnDef);
}
final int page = tableDef.getPage();
final long rowId = tableDef.getRowId();
final SqlJetTableDef alterDef = new SqlJetTableDef(newTableName, null, tableDef.isTemporary(), false, columns,
tableDef.getConstraints(), page, rowId);
final ISqlJetBtreeSchemaTable schemaTable = openSchemaTable(true);
try {
schemaTable.lock();
try {
if (!schemaTable.goToRow(rowId)) {
throw new SqlJetException(SqlJetErrorCode.CORRUPT);
}
final String typeField = schemaTable.getTypeField();
final String nameField = schemaTable.getNameField();
final String tableField = schemaTable.getTableField();
final int pageField = schemaTable.getPageField();
if (null == typeField || !TABLE_TYPE.equals(typeField)) {
throw new SqlJetException(SqlJetErrorCode.CORRUPT);
}
if (null == nameField || !tableName.equals(nameField)) {
throw new SqlJetException(SqlJetErrorCode.CORRUPT);
}
if (null == tableField || !tableName.equals(tableField)) {
throw new SqlJetException(SqlJetErrorCode.CORRUPT);
}
if (0 == pageField || pageField != page) {
throw new SqlJetException(SqlJetErrorCode.CORRUPT);
}
final String alteredSql = getTableAlteredSql(schemaTable.getSqlField(), alterTableDef);
db.getOptions().changeSchemaVersion();