예제 #1
0
  private void readShema(ISqlJetBtreeSchemaTable table) throws SqlJetException {
    for (table.first(); !table.eof(); table.next()) {
      final String type = table.getTypeField();
      if (null == type) {
        continue;
      }
      final String name = table.getNameField();
      if (null == name) {
        continue;
      }
      final int page = table.getPageField();

      if (TABLE_TYPE.equals(type)) {
        String sql = table.getSqlField();
        // System.err.println(sql);
        final CommonTree ast = (CommonTree) parseTable(sql).getTree();
        if (!isCreateVirtualTable(ast)) {
          final SqlJetTableDef tableDef = new SqlJetTableDef(ast, page);
          if (!name.equals(tableDef.getName())) {
            throw new SqlJetException(SqlJetErrorCode.CORRUPT);
          }
          tableDef.setRowId(table.getRowId());
          tableDefs.put(name, tableDef);
        } else {
          final SqlJetVirtualTableDef virtualTableDef = new SqlJetVirtualTableDef(ast, page);
          if (!name.equals(virtualTableDef.getTableName())) {
            throw new SqlJetException(SqlJetErrorCode.CORRUPT);
          }
          virtualTableDef.setRowId(table.getRowId());
          virtualTableDefs.put(name, virtualTableDef);
        }
      } else if (INDEX_TYPE.equals(type)) {
        final String tableName = table.getTableField();
        final String sql = table.getSqlField();
        if (null != sql) {
          // System.err.println(sql);
          final CommonTree ast = (CommonTree) parseIndex(sql).getTree();
          final SqlJetIndexDef indexDef = new SqlJetIndexDef(ast, page);
          if (!name.equals(indexDef.getName())) {
            throw new SqlJetException(SqlJetErrorCode.CORRUPT);
          }
          if (!tableName.equals(indexDef.getTableName())) {
            throw new SqlJetException(SqlJetErrorCode.CORRUPT);
          }
          indexDef.setRowId(table.getRowId());
          indexDefs.put(name, indexDef);
        } else {
          SqlJetBaseIndexDef indexDef = new SqlJetBaseIndexDef(name, tableName, page);
          indexDef.setRowId(table.getRowId());
          indexDefs.put(name, indexDef);
        }
      }
    }
    bindIndexes();
  }
예제 #2
0
  public SqlJetViewDef(String sql, CommonTree ast) {
    CommonTree optionsNode = (CommonTree) ast.getChild(0);

    sqlStatement = sql;
    temporary = SqlJetTableDef.hasOption(optionsNode, "temporary");
    ifNotExists = SqlJetTableDef.hasOption(optionsNode, "exists");

    CommonTree nameNode = (CommonTree) ast.getChild(1);
    name = nameNode.getText();
    databaseName = nameNode.getChildCount() > 0 ? nameNode.getChild(0).getText() : null;
  }
예제 #3
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));
        }
      }
    }
  }
예제 #4
0
  private void dropTableSafe(String tableName) throws SqlJetException {

    if (null == tableName || "".equals(tableName))
      throw new SqlJetException(SqlJetErrorCode.MISUSE, "Table name must be not empty");

    if (!tableDefs.containsKey(tableName))
      throw new SqlJetException(SqlJetErrorCode.MISUSE, "Table not found: " + tableName);
    final SqlJetTableDef tableDef = (SqlJetTableDef) tableDefs.get(tableName);

    dropTableIndexes(tableDef);

    final ISqlJetBtreeSchemaTable schemaTable = openSchemaTable(true);

    try {

      schemaTable.lock();

      try {

        db.getOptions().changeSchemaVersion();

        if (!schemaTable.goToRow(tableDef.getRowId())
            || !TABLE_TYPE.equals(schemaTable.getTypeField()))
          throw new SqlJetException(SqlJetErrorCode.CORRUPT);
        final String n = schemaTable.getNameField();
        if (null == n || !tableName.equals(n)) throw new SqlJetException(SqlJetErrorCode.CORRUPT);
        schemaTable.delete();

      } finally {
        schemaTable.unlock();
      }

    } finally {
      schemaTable.close();
    }

    final int page = tableDef.getPage();
    final int moved = btree.dropTable(page);
    if (moved != 0) {
      movePage(page, moved);
    }

    tableDefs.remove(tableName);
  }
예제 #5
0
 /**
  * @param schemaTable
  * @param tableDef
  * @throws SqlJetException
  */
 private void dropTableIndexes(SqlJetTableDef tableDef) throws SqlJetException {
   final String tableName = tableDef.getName();
   final Iterator<Map.Entry<String, ISqlJetIndexDef>> iterator = indexDefs.entrySet().iterator();
   while (iterator.hasNext()) {
     final Map.Entry<String, ISqlJetIndexDef> indexDefEntry = iterator.next();
     final String indexName = indexDefEntry.getKey();
     final ISqlJetIndexDef indexDef = indexDefEntry.getValue();
     if (indexDef.getTableName().equals(tableName)) {
       if (doDropIndex(indexName, true, false)) {
         iterator.remove();
       }
     }
   }
 }
예제 #6
0
  /**
   * @param page
   * @param moved
   * @throws SqlJetException
   */
  private void movePage(final int page, final int moved) throws SqlJetException {
    final ISqlJetBtreeSchemaTable schemaTable = openSchemaTable(true);
    try {
      schemaTable.lock();
      try {
        for (schemaTable.first(); !schemaTable.eof(); schemaTable.next()) {
          final long pageField = schemaTable.getPageField();
          if (pageField == moved) {
            final String nameField = schemaTable.getNameField();
            schemaTable.updateRecord(
                schemaTable.getRowId(),
                schemaTable.getTypeField(),
                nameField,
                schemaTable.getTableField(),
                page,
                schemaTable.getSqlField());
            final ISqlJetIndexDef index = getIndex(nameField);
            if (index != null) {
              if (index instanceof SqlJetBaseIndexDef) {
                ((SqlJetBaseIndexDef) index).setPage(page);
              }
            } else {
              final ISqlJetTableDef table = getTable(nameField);
              if (table != null) {
                if (table instanceof SqlJetTableDef) {
                  ((SqlJetTableDef) table).setPage(page);
                }
              }
            }
            return;
          }
        }
      } finally {
        schemaTable.unlock();
      }

    } finally {
      schemaTable.close();
    }
  }
예제 #7
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();
    }
  }
예제 #8
0
  private ISqlJetTableDef createTableSafe(String sql, boolean internal) throws SqlJetException {

    final RuleReturnScope parseTable = parseTable(sql);
    final CommonTree ast = (CommonTree) parseTable.getTree();

    if (isCreateVirtualTable(ast)) {
      throw new SqlJetException(SqlJetErrorCode.ERROR);
    }

    final SqlJetTableDef tableDef = new SqlJetTableDef(ast, 0);
    if (null == tableDef.getName()) throw new SqlJetException(SqlJetErrorCode.ERROR);
    final String tableName = tableDef.getName();
    if ("".equals(tableName)) throw new SqlJetException(SqlJetErrorCode.ERROR);

    if (!internal) {
      checkNameReserved(tableName);
    }

    if (tableDefs.containsKey(tableName)) {
      if (tableDef.isKeepExisting()) {
        return tableDefs.get(tableName);
      } else {
        throw new SqlJetException(
            SqlJetErrorCode.ERROR, "Table \"" + tableName + "\" exists already");
      }
    }

    checkNameConflict(SqlJetSchemaObjectType.TABLE, tableName);
    checkFieldNamesRepeatsConflict(tableDef.getName(), tableDef.getColumns());

    final List<ISqlJetColumnDef> columns = tableDef.getColumns();
    if (null == columns || 0 == columns.size()) throw new SqlJetException(SqlJetErrorCode.ERROR);

    final String createTableSql = getCreateTableSql(parseTable);

    final ISqlJetBtreeSchemaTable schemaTable = openSchemaTable(true);

    try {

      schemaTable.lock();

      try {

        db.getOptions().changeSchemaVersion();

        final int page = btree.createTable(BTREE_CREATE_TABLE_FLAGS);
        final long rowId =
            schemaTable.insertRecord(TABLE_TYPE, tableName, tableName, page, createTableSql);

        addConstraints(schemaTable, tableDef);

        tableDef.setPage(page);
        tableDef.setRowId(rowId);
        tableDefs.put(tableName, tableDef);
        return tableDef;

      } finally {
        schemaTable.unlock();
      }

    } finally {
      schemaTable.close();
    }
  }