/** * @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; }
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(); } }
/** * @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(); } }
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(); } }
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(); } }
/** * @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); } } }