예제 #1
0
  @Override
  protected void loadUniqueKeys(DefaultRelations relations) throws SQLException {
    for (Record record : fetchKeys(false)) {
      SchemaDefinition schema = getSchema(record.get(Statistics.TABLE_SCHEMA));
      String constraintName = record.get(Statistics.INDEX_NAME);
      String tableName = record.get(Statistics.TABLE_NAME);
      String columnName = record.get(Statistics.COLUMN_NAME);

      String key = getKeyName(tableName, constraintName);
      TableDefinition table = getTable(schema, tableName);

      if (table != null) {
        relations.addUniqueKey(key, table.getColumn(columnName));
      }
    }
  }
예제 #2
0
  @Override
  protected List<TableDefinition> getTables0() throws SQLException {
    List<TableDefinition> result = new ArrayList<TableDefinition>();

    for (Record record :
        create()
            .select(Tables.TABLE_SCHEMA, Tables.TABLE_NAME, Tables.TABLE_COMMENT)
            .from(TABLES)
            .where(Tables.TABLE_SCHEMA.in(getInputSchemata()))
            .orderBy(Tables.TABLE_SCHEMA, Tables.TABLE_NAME)
            .fetch()) {

      SchemaDefinition schema = getSchema(record.get(Tables.TABLE_SCHEMA));
      String name = record.get(Tables.TABLE_NAME);
      String comment = record.get(Tables.TABLE_COMMENT);

      MySQLTableDefinition table = new MySQLTableDefinition(schema, name, comment);
      result.add(table);
    }

    return result;
  }
예제 #3
0
  @Override
  protected void init0() throws SQLException {
    for (Record record :
        create()
            .select(
                FunctionColumns.COLUMN_NAME,
                FunctionColumns.TYPE_NAME,
                FunctionColumns.PRECISION,
                FunctionColumns.SCALE,
                FunctionColumns.POS,
                FunctionColumns.NULLABLE,
                FunctionColumns.COLUMN_DEFAULT)
            .from(FUNCTION_COLUMNS)
            .where(FunctionColumns.ALIAS_SCHEMA.equal(getSchema().getName()))
            .and(FunctionColumns.ALIAS_NAME.equal(getName()))

            // [#4193] recent versions of H2 produce a row for the function
            // return value at position 0
            .and(FunctionColumns.POS.gt(0))
            .orderBy(FunctionColumns.POS.asc())
            .fetch()) {

      String paramName = record.get(FunctionColumns.COLUMN_NAME);
      String typeName = record.get(FunctionColumns.TYPE_NAME);
      Integer precision = record.get(FunctionColumns.PRECISION);
      Short scale = record.get(FunctionColumns.SCALE);
      int position = record.get(FunctionColumns.POS);
      boolean nullable = record.get(FunctionColumns.NULLABLE, boolean.class);
      String defaultValue = record.get(FunctionColumns.COLUMN_DEFAULT);

      // VERY special case for H2 alias/function parameters. The first parameter
      // may be a java.sql.Connection object and in such cases it should NEVER be used.
      // It is only used internally by H2 to provide a connection to the current database.
      if (position == 0 && H2DataType.OTHER.getTypeName().equalsIgnoreCase(typeName)) {
        continue;
      }

      DataTypeDefinition type =
          new DefaultDataTypeDefinition(
              getDatabase(),
              getSchema(),
              typeName,
              precision,
              precision,
              scale,
              nullable,
              defaultValue);

      ParameterDefinition parameter =
          new DefaultParameterDefinition(this, paramName, position, type);
      addParameter(InOutDefinition.IN, parameter);
    }
  }
예제 #4
0
  @Override
  protected List<RoutineDefinition> getRoutines0() throws SQLException {
    List<RoutineDefinition> result = new ArrayList<RoutineDefinition>();

    try {
      create(true).fetchCount(PROC);
    } catch (DataAccessException e) {
      log.warn(
          "Table unavailable",
          "The `mysql`.`proc` table is unavailable. Stored procedures cannot be loaded. Check if you have sufficient grants");
      return result;
    }

    Result<Record6<String, String, String, byte[], byte[], ProcType>> records =
        create()
            .select(Proc.DB, Proc.NAME, Proc.COMMENT, Proc.PARAM_LIST, Proc.RETURNS, Proc.TYPE)
            .from(PROC)
            .where(DB.in(getInputSchemata()))
            .orderBy(DB, Proc.NAME)
            .fetch();

    Map<Record, Result<Record6<String, String, String, byte[], byte[], ProcType>>> groups =
        records.intoGroups(new Field[] {Proc.DB, Proc.NAME});

    // [#1908] This indirection is necessary as MySQL allows for overloading
    // procedures and functions with the same signature.
    for (Entry<Record, Result<Record6<String, String, String, byte[], byte[], ProcType>>> entry :
        groups.entrySet()) {
      Result<?> overloads = entry.getValue();

      for (int i = 0; i < overloads.size(); i++) {
        Record record = overloads.get(i);

        SchemaDefinition schema = getSchema(record.get(DB));
        String name = record.get(Proc.NAME);
        String comment = record.get(Proc.COMMENT);
        String params = new String(record.get(Proc.PARAM_LIST));
        String returns = new String(record.get(Proc.RETURNS));
        ProcType type = record.get(Proc.TYPE);

        if (overloads.size() > 1) {
          result.add(
              new MySQLRoutineDefinition(
                  schema, name, comment, params, returns, type, "_" + type.name()));
        } else {
          result.add(
              new MySQLRoutineDefinition(schema, name, comment, params, returns, type, null));
        }
      }
    }

    return result;
  }
예제 #5
0
  @Override
  protected void loadForeignKeys(DefaultRelations relations) throws SQLException {
    for (Record record :
        create()
            .select(
                ReferentialConstraints.CONSTRAINT_SCHEMA,
                ReferentialConstraints.CONSTRAINT_NAME,
                ReferentialConstraints.TABLE_NAME,
                ReferentialConstraints.REFERENCED_TABLE_NAME,
                ReferentialConstraints.UNIQUE_CONSTRAINT_NAME,
                ReferentialConstraints.UNIQUE_CONSTRAINT_SCHEMA,
                KeyColumnUsage.COLUMN_NAME)
            .from(REFERENTIAL_CONSTRAINTS)
            .join(KEY_COLUMN_USAGE)
            .on(ReferentialConstraints.CONSTRAINT_SCHEMA.equal(KeyColumnUsage.CONSTRAINT_SCHEMA))
            .and(ReferentialConstraints.CONSTRAINT_NAME.equal(KeyColumnUsage.CONSTRAINT_NAME))
            .where(ReferentialConstraints.CONSTRAINT_SCHEMA.in(getInputSchemata()))
            .orderBy(
                KeyColumnUsage.CONSTRAINT_SCHEMA.asc(),
                KeyColumnUsage.CONSTRAINT_NAME.asc(),
                KeyColumnUsage.ORDINAL_POSITION.asc())
            .fetch()) {

      SchemaDefinition foreignKeySchema =
          getSchema(record.get(ReferentialConstraints.CONSTRAINT_SCHEMA));
      SchemaDefinition uniqueKeySchema =
          getSchema(record.get(ReferentialConstraints.UNIQUE_CONSTRAINT_SCHEMA));

      String foreignKey = record.get(ReferentialConstraints.CONSTRAINT_NAME);
      String foreignKeyColumn = record.get(KeyColumnUsage.COLUMN_NAME);
      String foreignKeyTableName = record.get(ReferentialConstraints.TABLE_NAME);
      String referencedKey = record.get(ReferentialConstraints.UNIQUE_CONSTRAINT_NAME);
      String referencedTableName = record.get(ReferentialConstraints.REFERENCED_TABLE_NAME);

      TableDefinition foreignKeyTable = getTable(foreignKeySchema, foreignKeyTableName);

      if (foreignKeyTable != null) {
        ColumnDefinition column = foreignKeyTable.getColumn(foreignKeyColumn);

        String key = getKeyName(referencedTableName, referencedKey);
        relations.addForeignKey(foreignKey, key, column, uniqueKeySchema);
      }
    }
  }
예제 #6
0
  @Override
  protected List<EnumDefinition> getEnums0() throws SQLException {
    List<EnumDefinition> result = new ArrayList<EnumDefinition>();

    Result<Record5<String, String, String, String, String>> records =
        create()
            .select(
                Columns.TABLE_SCHEMA,
                Columns.COLUMN_COMMENT,
                Columns.TABLE_NAME,
                Columns.COLUMN_NAME,
                Columns.COLUMN_TYPE)
            .from(COLUMNS)
            .where(
                Columns.COLUMN_TYPE
                    .like("enum(%)")
                    .and(Columns.TABLE_SCHEMA.in(getInputSchemata())))
            .orderBy(
                Columns.TABLE_SCHEMA.asc(), Columns.TABLE_NAME.asc(), Columns.COLUMN_NAME.asc())
            .fetch();

    for (Record record : records) {
      SchemaDefinition schema = getSchema(record.get(Columns.TABLE_SCHEMA));

      String comment = record.get(Columns.COLUMN_COMMENT);
      String table = record.get(Columns.TABLE_NAME);
      String column = record.get(Columns.COLUMN_NAME);
      String name = table + "_" + column;
      String columnType = record.get(Columns.COLUMN_TYPE);

      // [#1237] Don't generate enum classes for columns in MySQL tables
      // that are excluded from code generation
      TableDefinition tableDefinition = getTable(schema, table);
      if (tableDefinition != null) {
        ColumnDefinition columnDefinition = tableDefinition.getColumn(column);

        if (columnDefinition != null) {

          // [#1137] Avoid generating enum classes for enum types that
          // are explicitly forced to another type
          if (getConfiguredForcedType(columnDefinition, columnDefinition.getType()) == null) {
            DefaultEnumDefinition definition = new DefaultEnumDefinition(schema, name, comment);

            CSVReader reader =
                new CSVReader(
                    new StringReader(columnType.replaceAll("(^enum\\()|(\\)$)", "")),
                    ',' // Separator
                    ,
                    '\'' // Quote character
                    ,
                    true // Strict quotes
                    );

            for (String string : reader.next()) {
              definition.addLiteral(string);
            }

            result.add(definition);
          }
        }
      }
    }

    return result;
  }