That is a concern I have with Fan (being too esoteric) as well. Also, the smaller community around it concerns me as well because it would be more likely to die at some point.
For reference, below is the type of class (pre-cleanup) that would be a candidate for conversion. As you can see, there is a lot of logic around the sql to run for a particular database and based on the parameters passed in, but in the end it just outputs a string. Once you get beyond code like this, each platform is different (jdbc vs ado.net etc.) and I think it makes sense to do a fork/copy/conversion of the java codebase to C# for all that. My hope is that it would be isolated and straightforward enough that it would be fine to expect people to code it in a non-standard language (python, ruby, fan) and it would feel more like a dsl than something tacked on. If the goal is to increase the chances of getting patches, the last thing I want to do is come up with code that scares people away.
public class CreateTableGenerator implements SqlGenerator {
public int getSpecializationLevel() {
return SPECIALIZATION_LEVEL_DEFAULT;
}
public boolean isValidGenerator(CreateTableStatement statement, Database database) {
return true;
}
public GeneratorValidationErrors validate(CreateTableStatement createTableStatement, Database database) {
return new GeneratorValidationErrors();
}
public Sql[] generateSql(CreateTableStatement statement, Database database) {
StringBuffer buffer = new StringBuffer();
buffer.append(“CREATE TABLE “).append(database.escapeTableName(statement.getSchemaName(), statement.getTableName())).append(” “);
buffer.append(”(”);
Iterator columnIterator = statement.getColumns().iterator();
while (columnIterator.hasNext()) {
String column = columnIterator.next();
boolean isAutoIncrement = statement.getAutoIncrementColumns().contains(column);
buffer.append(database.escapeColumnName(statement.getSchemaName(), statement.getTableName(), column));
buffer.append(" ").append(database.getColumnType(statement.getColumnTypes().get(column), isAutoIncrement));
if ((database instanceof SQLiteDatabase) &&
(statement.getPrimaryKeyConstraint()!=null) &&
(statement.getPrimaryKeyConstraint().getColumns().size()==1) &&
(statement.getPrimaryKeyConstraint().getColumns().contains(column)) &&
isAutoIncrement) {
String pkName = StringUtils.trimToNull(statement.getPrimaryKeyConstraint().getConstraintName());
if (pkName == null) {
pkName = database.generatePrimaryKeyName(statement.getTableName());
}
buffer.append(" CONSTRAINT “);
buffer.append(database.escapeConstraintName(pkName));
buffer.append(” PRIMARY KEY AUTOINCREMENT");
}
if (statement.getDefaultValue(column) != null) {
if (database instanceof MSSQLDatabase) {
buffer.append(" CONSTRAINT “).append(((MSSQLDatabase) database).generateDefaultConstraintName(statement.getTableName(), column));
}
buffer.append(” DEFAULT ");
buffer.append(statement.getDefaultValue(column));
}
if (isAutoIncrement &&
(database.getAutoIncrementClause()!=null) &&
(!database.getAutoIncrementClause().equals(""))) {
if (database.supportsAutoIncrement()) {
buffer.append(" “).append(database.getAutoIncrementClause()).append(” “);
} else {
LogFactory.getLogger().log(Level.WARNING, database.getProductName()+” does not support autoincrement columns as request for "+(database.escapeTableName(statement.getSchemaName(), statement.getTableName())));
}
}
if (statement.getNotNullColumns().contains(column)) {
buffer.append(" NOT NULL");
} else {
if (database instanceof SybaseDatabase || database instanceof SybaseASADatabase) {
buffer.append(" NULL");
}
}
if ((database instanceof InformixDatabase) &&
(statement.getPrimaryKeyConstraint()!=null) &&
(statement.getPrimaryKeyConstraint().getColumns().size()==1) &&
(statement.getPrimaryKeyConstraint().getColumns().contains(column))) {
buffer.append(" PRIMARY KEY");
}
if (columnIterator.hasNext()) {
buffer.append(", ");
}
}
buffer.append(",");
// TODO informixdb
if (!( (database instanceof SQLiteDatabase) &&
(statement.getPrimaryKeyConstraint()!=null) &&
(statement.getPrimaryKeyConstraint().getColumns().size()==1) &&
statement.getAutoIncrementColumns().contains(statement.getPrimaryKeyConstraint().getColumns().get(0)) ) &&
!((database instanceof InformixDatabase) &&
(statement.getPrimaryKeyConstraint()!=null) &&
(statement.getPrimaryKeyConstraint().getColumns().size()==1)
)) {
// …skip this code block for sqlite if a single column primary key
// with an autoincrement constraint exists.
// This constraint is added after the column type.
if (statement.getPrimaryKeyConstraint() != null && statement.getPrimaryKeyConstraint().getColumns().size() > 0) {
if (!(database instanceof InformixDatabase)) {
String pkName = StringUtils.trimToNull(statement.getPrimaryKeyConstraint().getConstraintName());
if (pkName == null) {
pkName = database.generatePrimaryKeyName(statement.getTableName());
}
buffer.append(" CONSTRAINT ");
buffer.append(database.escapeConstraintName(pkName));
}
buffer.append(" PRIMARY KEY (");
buffer.append(database.escapeColumnNameList(StringUtils.join(statement.getPrimaryKeyConstraint().getColumns(), ", ")));
buffer.append(")");
buffer.append(",");
}
}
for (ForeignKeyConstraint fkConstraint : statement.getForeignKeyConstraints()) {
if (!(database instanceof InformixDatabase)) {
buffer.append(" CONSTRAINT “);
buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));
}
buffer.append(” FOREIGN KEY (")
.append(database.escapeColumnName(statement.getSchemaName(), statement.getTableName(), fkConstraint.getColumn()))
.append(") REFERENCES ")
.append(fkConstraint.getReferences());
if (fkConstraint.isDeleteCascade()) {
buffer.append(" ON DELETE CASCADE");
}
if ((database instanceof InformixDatabase)) {
buffer.append(" CONSTRAINT ");
buffer.append(database.escapeConstraintName(fkConstraint.getForeignKeyName()));
}
if (fkConstraint.isInitiallyDeferred()) {
buffer.append(" INITIALLY DEFERRED");
}
if (fkConstraint.isDeferrable()) {
buffer.append(" DEFERRABLE");
}
buffer.append(",");
}
for (UniqueConstraint uniqueConstraint : statement.getUniqueConstraints()) {
if (uniqueConstraint.getConstraintName() != null && !constraintNameAfterUnique(database)) {
buffer.append(" CONSTRAINT “);
buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
}
buffer.append(” UNIQUE (");
buffer.append(database.escapeColumnNameList(StringUtils.join(uniqueConstraint.getColumns(), “, “)));
buffer.append(”)”);
if (uniqueConstraint.getConstraintName() != null && constraintNameAfterUnique(database)) {
buffer.append(" CONSTRAINT “);
buffer.append(database.escapeConstraintName(uniqueConstraint.getConstraintName()));
}
buffer.append(”,");
}
// if (constraints != null && constraints.getCheck() != null) {
// buffer.append(constraints.getCheck()).append(" ");
// }
// }
String sql = buffer.toString().replaceFirst(",\s*$", “”) + “)”;
// if (StringUtils.trimToNull(tablespace) != null && database.supportsTablespaces()) {
// if (database instanceof MSSQLDatabase) {
// buffer.append(" ON “).append(tablespace);
// } else if (database instanceof DB2Database) {
// buffer.append(” IN “).append(tablespace);
// } else {
// buffer.append(” TABLESPACE ").append(tablespace);
// }
// }
if (statement.getTablespace() != null && database.supportsTablespaces()) {
if (database instanceof MSSQLDatabase || database instanceof SybaseASADatabase) {
sql += " ON " + statement.getTablespace();
} else if (database instanceof DB2Database || database instanceof InformixDatabase) {
sql += " IN " + statement.getTablespace();
} else {
sql += " TABLESPACE " + statement.getTablespace();
}
}
return new Sql[] {
new UnparsedSql(sql)
};
}
private boolean constraintNameAfterUnique(Database database) {
return database instanceof InformixDatabase;
}
}