示例#1
0
 /**
  * @param schemaTable
  * @param generateAutoIndexName
  * @throws SqlJetException
  */
 private SqlJetBaseIndexDef createAutoIndex(
     ISqlJetBtreeSchemaTable schemaTable, String tableName, String autoIndexName)
     throws SqlJetException {
   final int page = btree.createTable(BTREE_CREATE_INDEX_FLAGS);
   final SqlJetBaseIndexDef indexDef = new SqlJetBaseIndexDef(autoIndexName, tableName, page);
   indexDef.setRowId(schemaTable.insertRecord(INDEX_TYPE, autoIndexName, tableName, page, null));
   indexDefs.put(autoIndexName, indexDef);
   return indexDef;
 }
示例#2
0
  private ISqlJetVirtualTableDef createVirtualTableSafe(String sql, int page)
      throws SqlJetException {

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

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

    final SqlJetVirtualTableDef tableDef = new SqlJetVirtualTableDef(ast, 0);
    if (null == tableDef.getTableName()) throw new SqlJetException(SqlJetErrorCode.ERROR);
    final String tableName = tableDef.getTableName();
    if ("".equals(tableName)) {
      throw new SqlJetException(SqlJetErrorCode.ERROR);
    }

    checkNameReserved(tableName);
    checkFieldNamesRepeatsConflict(tableDef.getTableName(), tableDef.getModuleColumns());

    if (virtualTableDefs.containsKey(tableName)) {
      throw new SqlJetException(
          SqlJetErrorCode.ERROR, "Virtual table \"" + tableName + "\" exists already");
    }

    checkNameConflict(SqlJetSchemaObjectType.VIRTUAL_TABLE, tableName);

    final ISqlJetBtreeSchemaTable schemaTable = openSchemaTable(true);
    final String createVirtualTableSQL = getCreateVirtualTableSql(parseTable);

    try {

      schemaTable.lock();

      try {

        db.getOptions().changeSchemaVersion();

        final long rowId =
            schemaTable.insertRecord(TABLE_TYPE, tableName, tableName, page, createVirtualTableSQL);

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

      } finally {
        schemaTable.unlock();
      }

    } finally {
      schemaTable.close();
    }
  }
示例#3
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();
    }
  }
示例#4
0
  private ISqlJetIndexDef createIndexSafe(String sql) throws SqlJetException {

    final ParserRuleReturnScope parseIndex = parseIndex(sql);
    final CommonTree ast = (CommonTree) parseIndex.getTree();

    final SqlJetIndexDef indexDef = new SqlJetIndexDef(ast, 0);

    if (null == indexDef.getName()) throw new SqlJetException(SqlJetErrorCode.ERROR);
    final String indexName = indexDef.getName();
    if ("".equals(indexName)) throw new SqlJetException(SqlJetErrorCode.ERROR);

    checkNameReserved(indexName);

    if (indexDefs.containsKey(indexName)) {
      if (indexDef.isKeepExisting()) {
        return indexDefs.get(indexName);
      } else {
        throw new SqlJetException(
            SqlJetErrorCode.ERROR, "Index \"" + indexName + "\" exists already");
      }
    }

    checkNameConflict(SqlJetSchemaObjectType.INDEX, indexName);

    if (null == indexDef.getTableName()) throw new SqlJetException(SqlJetErrorCode.ERROR);
    final String tableName = indexDef.getTableName();
    if ("".equals(tableName)) throw new SqlJetException(SqlJetErrorCode.ERROR);

    final List<ISqlJetIndexedColumn> columns = indexDef.getColumns();
    if (null == columns) throw new SqlJetException(SqlJetErrorCode.ERROR);

    final ISqlJetTableDef tableDef = getTable(tableName);
    if (null == tableDef) throw new SqlJetException(SqlJetErrorCode.ERROR);

    for (final ISqlJetIndexedColumn column : columns) {
      if (null == column.getName()) throw new SqlJetException(SqlJetErrorCode.ERROR);
      final String columnName = column.getName();
      if ("".equals(columnName)) throw new SqlJetException(SqlJetErrorCode.ERROR);
      if (null == tableDef.getColumn(columnName))
        throw new SqlJetException(
            SqlJetErrorCode.ERROR,
            "Column \"" + columnName + "\" not found in table \"" + tableName + "\"");
    }

    final ISqlJetBtreeSchemaTable schemaTable = openSchemaTable(true);
    final String createIndexSQL =
        indexDef.isUnique() ? getCreateIndexUniqueSql(parseIndex) : getCreateIndexSql(parseIndex);

    try {

      schemaTable.lock();

      try {

        db.getOptions().changeSchemaVersion();

        final int page = btree.createTable(BTREE_CREATE_INDEX_FLAGS);

        final long rowId =
            schemaTable.insertRecord(INDEX_TYPE, indexName, tableName, page, createIndexSQL);

        indexDef.setPage(page);
        indexDef.setRowId(rowId);
        indexDef.bindColumns(tableDef);
        indexDefs.put(indexName, indexDef);

        final SqlJetBtreeIndexTable indexTable =
            new SqlJetBtreeIndexTable(btree, indexDef.getName(), true);
        try {
          indexTable.reindex(this);
        } finally {
          indexTable.close();
        }
        return indexDef;

      } finally {
        schemaTable.unlock();
      }

    } finally {
      schemaTable.close();
    }
  }
示例#5
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();
    }
  }
示例#6
0
  /**
   * @param schemaTable
   * @param newTableName
   * @param tableName
   * @param string
   * @throws SqlJetException
   */
  private void renameTablesIndices(
      final ISqlJetBtreeSchemaTable schemaTable,
      String tableName,
      String newTableName,
      String alterTableName)
      throws SqlJetException {

    final Set<ISqlJetIndexDef> indexes = getIndexes(tableName);
    if (null == indexes || 0 == indexes.size()) {
      return;
    }

    int i = 0;
    for (final ISqlJetIndexDef index : indexes) {
      if (index instanceof SqlJetBaseIndexDef) {

        final SqlJetBaseIndexDef indexDef = (SqlJetBaseIndexDef) index;
        final String indexName = indexDef.getName();
        final long rowId = indexDef.getRowId();
        final int page = indexDef.getPage();

        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 || !INDEX_TYPE.equals(typeField)) {
          throw new SqlJetException(SqlJetErrorCode.CORRUPT);
        }
        if (null == nameField || !indexName.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);
        }

        indexDef.setTableName(newTableName);

        String newIndexName = indexName;
        String alteredIndexSql = null;

        if (index.isImplicit()) {
          newIndexName = generateAutoIndexName(tableName, ++i);
          indexDef.setName(newIndexName);
          indexDefs.remove(indexName);
          indexDefs.put(newIndexName, indexDef);
        } else {
          alteredIndexSql = getAlteredIndexSql(schemaTable.getSqlField(), alterTableName);
        }

        schemaTable.insertRecord(INDEX_TYPE, newIndexName, newTableName, page, alteredIndexSql);

      } else {
        throw new SqlJetException(SqlJetErrorCode.INTERNAL);
      }
    }
  }