Beispiel #1
0
  /**
   * Validates a column against the model's field definition. Checks for existence, supported type,
   * type mapping, default value, defined lengths, primary key, autoincrement.
   */
  private void validate(
      List<ValidationRemark> remarks, FieldDefinition fieldDef, boolean throwError) {
    // unknown field
    if (!columns.containsKey(fieldDef.columnName.toLowerCase())) {
      // unknown column mapping
      remarks.add(error(table, fieldDef, "Does not exist in database!").throwError(throwError));
      return;
    }
    ColumnInspector col = columns.get(fieldDef.columnName.toLowerCase());
    Class<?> fieldClass = fieldDef.field.getType();
    Class<?> jdbcClass = ModelUtils.getClassForSqlType(col.type, dateTimeClass);

    // supported type check
    // iciql maps to VARCHAR for unsupported types.
    if (fieldDef.dataType.equals("VARCHAR") && (fieldClass != String.class)) {
      remarks.add(
          error(
                  table,
                  fieldDef,
                  "iciql does not currently implement support for " + fieldClass.getName())
              .throwError(throwError));
    }
    // number types
    if (!fieldClass.equals(jdbcClass)) {
      if (Number.class.isAssignableFrom(fieldClass)) {
        remarks.add(
            warn(
                table,
                col,
                format(
                    "Precision mismatch: ModelObject={0}, ColumnObject={1}",
                    fieldClass.getSimpleName(), jdbcClass.getSimpleName())));
      } else {
        if (!Date.class.isAssignableFrom(jdbcClass)) {
          remarks.add(
              warn(
                  table,
                  col,
                  format(
                      "Object Mismatch: ModelObject={0}, ColumnObject={1}",
                      fieldClass.getSimpleName(), jdbcClass.getSimpleName())));
        }
      }
    }

    // string types
    if (fieldClass == String.class) {
      if ((fieldDef.length != col.size) && (col.size < Integer.MAX_VALUE)) {
        remarks.add(
            warn(
                table,
                col,
                format(
                    "{0}.length={1}, ColumnMaxLength={2}",
                    IQColumn.class.getSimpleName(), fieldDef.length, col.size)));
      }
      if (fieldDef.length > 0 && !fieldDef.trim) {
        remarks.add(
            consider(
                table,
                col,
                format(
                    "{0}.trim=true will prevent IciqlExceptions on"
                        + " INSERT or UPDATE, but will clip data!",
                    IQColumn.class.getSimpleName())));
      }
    }

    // numeric autoIncrement
    if (fieldDef.isAutoIncrement != col.isAutoIncrement) {
      remarks.add(
          warn(
              table,
              col,
              format(
                  "{0}.autoIncrement={1}" + " while Column autoIncrement={2}",
                  IQColumn.class.getSimpleName(), fieldDef.isAutoIncrement, col.isAutoIncrement)));
    }
    // default value
    if (!col.isAutoIncrement && !col.isPrimaryKey) {
      String defaultValue = null;
      if (fieldDef.defaultValue != null && fieldDef.defaultValue instanceof String) {
        defaultValue = fieldDef.defaultValue.toString();
      }
      // check Model.defaultValue format
      if (!ModelUtils.isProperlyFormattedDefaultValue(defaultValue)) {
        remarks.add(
            error(
                    table,
                    col,
                    format(
                        "{0}.defaultValue=\"{1}\"" + " is improperly formatted!",
                        IQColumn.class.getSimpleName(), defaultValue))
                .throwError(throwError));
        // next field
        return;
      }
      // compare Model.defaultValue to Column.defaultValue
      if (isNullOrEmpty(defaultValue) && !isNullOrEmpty(col.defaultValue)) {
        // Model.defaultValue is NULL, Column.defaultValue is NOT NULL
        remarks.add(
            warn(
                table,
                col,
                format(
                    "{0}.defaultValue=\"\"" + " while column default=\"{1}\"",
                    IQColumn.class.getSimpleName(), col.defaultValue)));
      } else if (!isNullOrEmpty(defaultValue) && isNullOrEmpty(col.defaultValue)) {
        // Column.defaultValue is NULL, Model.defaultValue is NOT NULL
        remarks.add(
            warn(
                table,
                col,
                format(
                    "{0}.defaultValue=\"{1}\"" + " while column default=\"\"",
                    IQColumn.class.getSimpleName(), defaultValue)));
      } else if (!isNullOrEmpty(defaultValue) && !isNullOrEmpty(col.defaultValue)) {
        if (!defaultValue.equals(col.defaultValue)) {
          // Model.defaultValue != Column.defaultValue
          remarks.add(
              warn(
                  table,
                  col,
                  format(
                      "{0}.defaultValue=\"{1}\"" + " while column default=\"{2}\"",
                      IQColumn.class.getSimpleName(), defaultValue, col.defaultValue)));
        }
      }

      // sanity check Model.defaultValue literal value
      if (!ModelUtils.isValidDefaultValue(fieldDef.field.getType(), defaultValue)) {
        remarks.add(
            error(
                table,
                col,
                format(
                    "{0}.defaultValue=\"{1}\" is invalid!",
                    IQColumn.class.getSimpleName(), defaultValue)));
      }
    }
  }
  TableDefinition<T> createTableIfRequired(Db db) {
    if (!createTableIfRequired) {
      // skip table and index creation
      // but still check for upgrades
      db.upgradeTable(this);
      return this;
    }
    SQLDialect dialect = db.getDialect();
    SQLStatement stat = new SQLStatement(db);
    StatementBuilder buff;
    if (memoryTable && dialect.supportsMemoryTables()) {
      buff = new StatementBuilder("CREATE MEMORY TABLE IF NOT EXISTS ");
    } else {
      buff = new StatementBuilder("CREATE TABLE IF NOT EXISTS ");
    }

    buff.append(dialect.getTableName(schemaName, tableName)).append('(');

    for (FieldDefinition field : fields) {
      buff.appendExceptFirst(", ");
      buff.append(field.columnName).append(' ').append(field.dataType);
      if (field.maxLength > 0) {
        buff.append('(').append(field.maxLength).append(')');
      }

      if (field.isAutoIncrement) {
        buff.append(" AUTO_INCREMENT");
      }

      if (!field.allowNull) {
        buff.append(" NOT NULL");
      }

      // default values
      if (!field.isAutoIncrement && !field.isPrimaryKey) {
        String dv = field.defaultValue;
        if (!StringUtils.isNullOrEmpty(dv)) {
          if (ModelUtils.isProperlyFormattedDefaultValue(dv)
              && ModelUtils.isValidDefaultValue(field.field.getType(), dv)) {
            buff.append(" DEFAULT " + dv);
          }
        }
      }
    }

    // primary key
    if (primaryKeyColumnNames != null && primaryKeyColumnNames.size() > 0) {
      buff.append(", PRIMARY KEY(");
      buff.resetCount();
      for (String n : primaryKeyColumnNames) {
        buff.appendExceptFirst(", ");
        buff.append(n);
      }
      buff.append(')');
    }
    buff.append(')');
    stat.setSQL(buff.toString());
    StatementLogger.create(stat.getSQL());
    stat.executeUpdate();

    // create indexes
    for (IndexDefinition index : indexes) {
      String sql = db.getDialect().getCreateIndex(schemaName, tableName, index);
      stat.setSQL(sql);
      StatementLogger.create(stat.getSQL());
      stat.executeUpdate();
    }

    // tables are created using IF NOT EXISTS
    // but we may still need to upgrade
    db.upgradeTable(this);
    return this;
  }