예제 #1
0
  /**
   * @param schemaTable
   * @param tableDef
   * @throws SqlJetException
   */
  private void addConstraints(ISqlJetBtreeSchemaTable schemaTable, final SqlJetTableDef tableDef)
      throws SqlJetException {

    final String tableName = tableDef.getName();
    final List<ISqlJetColumnDef> columns = tableDef.getColumns();
    int i = 0;

    for (final ISqlJetColumnDef column : columns) {
      final List<ISqlJetColumnConstraint> constraints = column.getConstraints();
      if (null == constraints) continue;
      for (final ISqlJetColumnConstraint constraint : constraints) {
        if (constraint instanceof ISqlJetColumnPrimaryKey) {
          final ISqlJetColumnPrimaryKey pk = (ISqlJetColumnPrimaryKey) constraint;
          if (!column.hasExactlyIntegerType()) {
            if (pk.isAutoincremented()) {
              throw new SqlJetException(
                  SqlJetErrorCode.ERROR,
                  "AUTOINCREMENT is allowed only for INTEGER PRIMARY KEY fields");
            }
            createAutoIndex(schemaTable, tableName, generateAutoIndexName(tableName, ++i));
          } else if (pk.isAutoincremented()) {
            checkSequenceTable();
          }
        } else if (constraint instanceof ISqlJetColumnUnique) {
          createAutoIndex(schemaTable, tableName, generateAutoIndexName(tableName, ++i));
        }
      }
    }

    final List<ISqlJetTableConstraint> constraints = tableDef.getConstraints();
    if (null != constraints) {
      for (final ISqlJetTableConstraint constraint : constraints) {
        if (constraint instanceof ISqlJetTablePrimaryKey) {
          boolean b = false;
          final ISqlJetTablePrimaryKey pk = (ISqlJetTablePrimaryKey) constraint;
          if (pk.getColumns().size() == 1) {
            final String n = pk.getColumns().get(0);
            final ISqlJetColumnDef c = tableDef.getColumn(n);
            b = c != null && c.hasExactlyIntegerType();
          }
          if (!b) {
            createAutoIndex(schemaTable, tableName, generateAutoIndexName(tableName, ++i));
          }
        } else if (constraint instanceof ISqlJetTableUnique) {
          createAutoIndex(schemaTable, tableName, generateAutoIndexName(tableName, ++i));
        }
      }
    }
  }
예제 #2
0
  /**
   * @param tableName
   * @param newTableName
   * @param newColumnDef
   * @return
   * @throws SqlJetException
   */
  private ISqlJetTableDef alterTableSafe(final SqlJetAlterTableDef alterTableDef)
      throws SqlJetException {

    assert (null != alterTableDef);
    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();

        schemaTable.insertRecord(TABLE_TYPE, newTableName, newTableName, page, alteredSql);

        if (renameTable && !tableName.equals(newTableName)) {
          renameTablesIndices(
              schemaTable, tableName, newTableName, getAlterTableName(alterTableDef));
        }

        tableDefs.remove(tableName);
        tableDefs.put(newTableName, alterDef);

        return alterDef;

      } finally {
        schemaTable.unlock();
      }
    } finally {
      schemaTable.close();
    }
  }