/** * Copyright (C) 2009-2013 FoundationDB, LLC * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.foundationdb.server.store; import java.util.Collection; import java.util.Iterator; import java.util.Set; import com.foundationdb.ais.AISCloner; import com.foundationdb.ais.model.AkibanInformationSchema; import com.foundationdb.ais.model.Index; import com.foundationdb.ais.model.Routine; import com.foundationdb.ais.model.Sequence; import com.foundationdb.ais.model.SQLJJar; import com.foundationdb.ais.model.Table; import com.foundationdb.ais.model.TableName; import com.foundationdb.ais.model.View; import com.foundationdb.ais.util.ChangedTableDescription; import com.foundationdb.qp.virtualadapter.VirtualScanFactory; import com.foundationdb.server.error.NoSuchSchemaException; import com.foundationdb.server.service.security.SecurityService; import com.foundationdb.server.service.session.Session; import com.foundationdb.server.store.TableChanges.ChangeSet; import com.foundationdb.server.store.format.StorageFormatRegistry; import com.foundationdb.server.types.common.types.TypesTranslator; import com.foundationdb.server.types.service.TypesRegistry; import com.persistit.Key; public interface SchemaManager { /** Flags indicating behavior regarding contained objects in DROP calls **/ static enum DropBehavior { /** Reject if there are contained objects **/ RESTRICT, /** Allow and also drop contained objects **/ CASCADE } interface OnlineChangeState { AkibanInformationSchema getAIS(); Collection<ChangeSet> getChangeSets(); } /** * <p> * Create a new table in the {@link TableName#INFORMATION_SCHEMA} * schema. This table will be be populated and accessed through the normal * {@link Store} methods. * </p> * <p> * As this table contains rows that will go to disk, a caller specified * version will also be stored to facilitate upgrades. If this table * already exists (i.e. created on a previous start-up), the version must * match or an exception will be thrown. Upgrade and/or conversion must be * handled by the caller. * </p> * * @param newTable New table to create. * @param version Version of the table being created. * * @return Name of the table that was created. */ TableName registerStoredInformationSchemaTable(Table newTable, int version); /** * Create a new table in the {@link TableName#INFORMATION_SCHEMA} * schema. This table will be be populated on demand and accessed through * the given {@link VirtualScanFactory}. * * @param newTable New table to create. * @param factory Factory to service this table. * * @return Name of the table that was created. */ TableName registerVirtualTable(Table newTable, VirtualScanFactory factory); /** * Delete the definition of a table in the {@link TableName#INFORMATION_SCHEMA} * schema. The table must exist and be a virtual table. * * @param tableName Table to delete. */ void unRegisterVirtualTable(TableName tableName); /** Mark the {@code hKey} has already been handled with respect to online DDL. */ void addOnlineHandledHKey(Session session, int tableID, Key hKey); /** * Get an iterator that returns all hKeys added from {@link #addOnlineHandledHKey} in order. * Start from {@code hKey} if not null, otherwise the beginning. */ Iterator<byte[]> getOnlineHandledHKeyIterator(Session session, int tableID, Key hKey); /** {@code true} if {@code tableID} is undergoing an online change in *another* session. */ boolean isOnlineActive(Session session, int tableID); /** Get all AIS and ChangeSets for active online sessions. */ Collection<OnlineChangeState> getOnlineChangeStates(Session session); /** * Mark {@code session} as performing online DDL so future SchemaManager calls do not not modify the primary schema. * Must be paired with {@link #finishOnline(Session)} or {@link #discardOnline(Session)}. */ void startOnline(Session session); /** Mark the online session associated with {@code tableID} with an error. */ void setOnlineDMLError(Session session, int tableID, String message); /** Return the error message for a concurrent DML violation or {@code null} if none has occurred. */ String getOnlineDMLError(Session session); /** Get current AIS for an in-progress online DDL. */ AkibanInformationSchema getOnlineAIS(Session session); /** Add change information for an in-progress online DDL. */ void addOnlineChangeSet(Session session, ChangeSet changeSet); /** Get current changes for an in-progress online DDL. */ Collection<ChangeSet> getOnlineChangeSets(Session session); /** Move definition changes since the last {@link #startOnline(Session)} call to the primary schema. */ void finishOnline(Session session); /** Discard definition changes since the last {@link #startOnline(Session)} call. */ void discardOnline(Session session); /** * Create a new table in the SchemaManager. * @param session Session to operate under * @param newTable New table to add * @return The name of the table that was created. */ TableName createTableDefinition(Session session, Table newTable); /** * Rename an existing table. * @param session Session * @param currentName Current name of table * @param newName Desired name of table */ void renameTable(Session session, TableName currentName, TableName newName); /** Add table or group indexes to existing table(s). Empty or null <code>indexes</code> not allowed. **/ void createIndexes(Session session, Collection<? extends Index> indexesToCreate, boolean keepStorage); /** * Modifying the existing schema definitions by adding indexes. Both Table and Group indexes are * supported through this interface. * @param session Session to operate under. * @param indexes List of indexes to drop. */ void dropIndexes(Session session, Collection<? extends Index> indexes); /** * Delete the definition of the table with the given name. Throws * NoSuchTableException if the table does not exist. * @param session The session to operate under. * @param schemaName The name of the schema the table is in. * @param tableName The name of the table. * @param dropBehavior How to handle child tables. */ void dropTableDefinition(Session session, String schemaName, String tableName, DropBehavior dropBehavior); /** * Delete the definition for an entire schema, and everything inside that schema, plus the sequences provided. * * @throws NoSuchSchemaException if the schema does not exist */ void dropSchema(Session session, String schemaName); /** Drops all non-system schemas from the ais. **/ void dropNonSystemSchemas(Session session); /** Change definitions of existing tables. */ void alterTableDefinitions(Session session, Collection<ChangedTableDescription> alteredTables); /** ALTER the definition of the given Sequence */ void alterSequence(Session session, TableName sequenceName, Sequence newDefinition); /** * Return the AIS for {@code session}, which will include any <i>non-online</i> changes for the current transaction. * Also see {@link #getOnlineAIS(Session)}. */ AkibanInformationSchema getAis(Session session); /** Add the given view to the current AIS. */ void createView(Session session, View view); /** Drop the given view from the current AIS. */ void dropView(Session session, TableName viewName); /** Add the Sequence to the current AIS */ void createSequence(Session session, Sequence sequence); /** Drop the given sequence from the current AIS. */ void dropSequence(Session session, Sequence sequence); /** Add the Routine to the current AIS */ void createRoutine(Session session, Routine routine, boolean replaceExisting); /** Drop the given routine from the current AIS. */ void dropRoutine(Session session, TableName routineName); /** Add an SQL/J jar to the current AIS. */ void createSQLJJar(Session session, SQLJJar sqljJar); /** Update an SQL/J jar in the current AIS. */ void replaceSQLJJar(Session session, SQLJJar sqljJar); /** Drop the given SQL/J jar from the current AIS. */ void dropSQLJJar(Session session, TableName jarName); /** Add the Routine to live AIS */ void registerSystemRoutine(Routine routine); /** Drop a system routine from the live AIS. */ void unRegisterSystemRoutine(TableName routineName); /** Add the SQL/J jar to live AIS */ void registerSystemSQLJJar(SQLJJar sqljJar); /** Drop a system SQL/J jar from the live AIS. */ void unRegisterSystemSQLJJar(TableName jarName); /** Get all known/allocated tree names */ Set<String> getTreeNames(Session session); /** Get oldest AIS generation still in memory */ long getOldestActiveAISGeneration(); /** Get AIS generations still in memory */ Set<Long> getActiveAISGenerations(); /** Return {@code true} if {@code tableID} has changed *concurrent* to this session's transaction. */ boolean hasTableChanged(Session session, int tableID); /** Link up to security service. */ void setSecurityService(SecurityService securityService); /** The types registry. */ TypesRegistry getTypesRegistry(); /** The types translator. */ TypesTranslator getTypesTranslator(); /** The store-specific format registry. */ StorageFormatRegistry getStorageFormatRegistry(); /** An <code>AISCloner</code> for merging. */ AISCloner getAISCloner(); /** Throw an error if there are unsupported indexes. */ void checkAllowedIndexes(Collection<? extends Index> indexes); }