/**
* @author 郑小康
*
* 1.检验实体是否为空
*
* 2.检验视图实体是否为空
*
* 3.获取数据库连接
*
* 4.根据对应的ModelEntity来创建表 其中modelEntities是关系表的集合
*
* */
public String createTable(ModelEntity entity, Map<String, ModelEntity> modelEntities, boolean addFks) {
if (entity == null) {
return "ModelEntity was null and is required to create a table ModelEntity是空,不能创建表";
}
if (entity instanceof ModelViewEntity) {
return "ERROR: Cannot create table for a view entity 不能为视图实体创建表";
}
Connection connection = null;
Statement stmt = null;
try {
connection = getConnection();
} catch (SQLException e) {
String errMsg = "在建表过程中Unable to establish a connection with the database for helperName [" + this.helperInfo.getHelperFullName() + "]... Error was: " + e.toString();
Debug.logError(e, errMsg, module);
return errMsg;
} catch (GenericEntityException e) {
String errMsg = "在建表过程中 Unable to establish a connection with the database for helperName [" + this.helperInfo.getHelperFullName() + "]... Error was: " + e.toString();
Debug.logError(e, errMsg, module);
return errMsg;
}
StringBuilder sqlBuf = new StringBuilder("CREATE TABLE ");
sqlBuf.append(entity.getTableName(this.datasourceInfo));
sqlBuf.append(" (");
Iterator<ModelField> fieldIter = entity.getFieldsIterator();
while (fieldIter.hasNext()) {
ModelField field = fieldIter.next();
ModelFieldType type = modelFieldTypeReader.getModelFieldType(field.getType());
if (type == null) {
return "Field type [" + type + "] not found for field [" + field.getName() + "] of entity [" + entity.getEntityName() + "], not creating table.";
}
sqlBuf.append(field.getColName());
sqlBuf.append(" ");
sqlBuf.append(type.getSqlType());
if ("String".equals(type.getJavaType()) || "java.lang.String".equals(type.getJavaType())) {
// if there is a characterSet, add the CHARACTER SET arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCharacterSet())) {
sqlBuf.append(" CHARACTER SET ");
sqlBuf.append(this.datasourceInfo.getCharacterSet());
}
// if there is a collate, add the COLLATE arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCollate())) {
sqlBuf.append(" COLLATE ");
sqlBuf.append(this.datasourceInfo.getCollate());
}
}
if (field.getIsNotNull() || field.getIsPk()) {
if (this.datasourceInfo.getAlwaysUseConstraintKeyword()) {
sqlBuf.append(" CONSTRAINT NOT NULL, ");
} else {
sqlBuf.append(" NOT NULL, ");
}
} else {
sqlBuf.append(", ");
}
}
String pkName = makePkConstraintName(entity, this.datasourceInfo.getConstraintNameClipLength());
if (this.datasourceInfo.getUsePkConstraintNames()) {
sqlBuf.append("CONSTRAINT ");
sqlBuf.append(pkName);
}
sqlBuf.append(" PRIMARY KEY (");
entity.colNameString(entity.getPkFieldsUnmodifiable(), sqlBuf, "");
sqlBuf.append(")");
if (addFks) {
// NOTE: This is kind of a bad idea anyway since ordering table creations is crazy, if not impossible
// go through the relationships to see if any foreign keys need to be added
Iterator<ModelRelation> relationsIter = entity.getRelationsIterator();
while (relationsIter.hasNext()) {
ModelRelation modelRelation = relationsIter.next();
if ("one".equals(modelRelation.getType())) {
ModelEntity relModelEntity = modelEntities.get(modelRelation.getRelEntityName());
if (relModelEntity == null) {
Debug.logError("Error adding foreign key: ModelEntity was null for related entity name " + modelRelation.getRelEntityName(), module);
continue;
}
if (relModelEntity instanceof ModelViewEntity) {
Debug.logError("Error adding foreign key: related entity is a view entity for related entity name " + modelRelation.getRelEntityName(), module);
continue;
}
String fkConstraintClause = makeFkConstraintClause(entity, modelRelation, relModelEntity, this.datasourceInfo.getConstraintNameClipLength(), this.datasourceInfo.getFkStyle(), this.datasourceInfo.getUseFkInitiallyDeferred());
if (UtilValidate.isNotEmpty(fkConstraintClause)) {
sqlBuf.append(", ");
sqlBuf.append(fkConstraintClause);
} else {
continue;
}
}
}
}
sqlBuf.append(")");
// if there is a tableType, add the TYPE arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getTableType())) {
// jaz:20101229 - This appears to be only used by mysql and now mysql has
// deprecated (and in 5.5.x removed) the use of the TYPE keyword. This is
// changed to ENGINE which is supported starting at 4.1
sqlBuf.append(" ENGINE ");
//sqlBuf.append(" TYPE ");
sqlBuf.append(this.datasourceInfo.getTableType());
}
// if there is a characterSet, add the CHARACTER SET arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCharacterSet())) {
sqlBuf.append(" CHARACTER SET ");
sqlBuf.append(this.datasourceInfo.getCharacterSet());
}
// if there is a collate, add the COLLATE arg here
if (UtilValidate.isNotEmpty(this.datasourceInfo.getCollate())) {
sqlBuf.append(" COLLATE ");
sqlBuf.append(this.datasourceInfo.getCollate());
}
if (Debug.verboseOn()) Debug.logVerbose("[createTable] sql=" + sqlBuf.toString(), module);
try {
stmt = connection.createStatement();
stmt.executeUpdate(sqlBuf.toString());
} catch (SQLException e) {
return "SQL Exception while executing the following:\n" + sqlBuf.toString() + "\nError was: " + e.toString();
} finally {
try {
if (stmt != null) stmt.close();
} catch (SQLException e) {
Debug.logError(e, module);
}
try {
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
Debug.logError(e, module);
}
}
return null;
}