2016-03-19 01:18:49 +00:00
# pragma once
2019-03-11 14:01:45 +00:00
# include <Core/Types.h>
# include <Parsers/IAST_fwd.h>
2019-05-17 14:34:25 +00:00
# include <Storages/IStorage_fwd.h>
2019-10-21 14:20:42 +00:00
# include <Dictionaries/IDictionary.h>
2019-08-27 20:43:08 +00:00
# include <Common/Exception.h>
2019-03-11 14:01:45 +00:00
# include <ctime>
# include <functional>
# include <memory>
2016-12-12 07:24:56 +00:00
2016-03-19 01:18:49 +00:00
namespace DB
{
2016-12-12 07:24:56 +00:00
class Context ;
2017-01-23 18:05:07 +00:00
struct Settings ;
2019-08-27 20:43:08 +00:00
struct ConstraintsDescription ;
class ColumnsDescription ;
struct IndicesDescription ;
struct TableStructureWriteLockHolder ;
2019-10-16 14:59:52 +00:00
using Dictionaries = std : : set < String > ;
2019-08-27 20:43:08 +00:00
namespace ErrorCodes
{
extern const int NOT_IMPLEMENTED ;
2019-11-01 12:47:55 +00:00
extern const int CANNOT_GET_CREATE_TABLE_QUERY ;
extern const int CANNOT_GET_CREATE_TABLE_QUERY ;
extern const int CANNOT_GET_CREATE_DICTIONARY_QUERY ;
2019-08-27 20:43:08 +00:00
}
2016-12-12 07:24:56 +00:00
2019-10-10 17:33:01 +00:00
class IDatabaseTablesIterator
2016-03-19 01:18:49 +00:00
{
public :
2017-04-01 07:20:54 +00:00
virtual void next ( ) = 0 ;
virtual bool isValid ( ) const = 0 ;
2016-03-19 01:18:49 +00:00
2017-04-01 07:20:54 +00:00
virtual const String & name ( ) const = 0 ;
2019-09-26 07:16:31 +00:00
virtual const StoragePtr & table ( ) const = 0 ;
2016-03-19 01:18:49 +00:00
2019-10-10 17:33:01 +00:00
virtual ~ IDatabaseTablesIterator ( ) = default ;
} ;
/// Copies list of tables and iterates through such snapshot.
class DatabaseTablesSnapshotIterator : public IDatabaseTablesIterator
{
private :
Tables tables ;
Tables : : iterator it ;
public :
DatabaseTablesSnapshotIterator ( Tables & tables_ ) : tables ( tables_ ) , it ( tables . begin ( ) ) { }
DatabaseTablesSnapshotIterator ( Tables & & tables_ ) : tables ( tables_ ) , it ( tables . begin ( ) ) { }
void next ( ) { + + it ; }
bool isValid ( ) const { return it ! = tables . end ( ) ; }
const String & name ( ) const { return it - > first ; }
const StoragePtr & table ( ) const { return it - > second ; }
2016-03-19 01:18:49 +00:00
} ;
2019-10-10 17:33:01 +00:00
/// Copies list of dictionaries and iterates through such snapshot.
class DatabaseDictionariesSnapshotIterator
{
private :
Dictionaries dictionaries ;
Dictionaries : : iterator it ;
public :
2019-10-11 15:41:52 +00:00
DatabaseDictionariesSnapshotIterator ( ) = default ;
2019-10-10 17:33:01 +00:00
DatabaseDictionariesSnapshotIterator ( Dictionaries & dictionaries_ ) : dictionaries ( dictionaries_ ) , it ( dictionaries . begin ( ) ) { }
DatabaseDictionariesSnapshotIterator ( Dictionaries & & dictionaries_ ) : dictionaries ( dictionaries_ ) , it ( dictionaries . begin ( ) ) { }
void next ( ) { + + it ; }
2019-10-11 15:41:52 +00:00
bool isValid ( ) const { return ! dictionaries . empty ( ) & & it ! = dictionaries . end ( ) ; }
2019-10-10 17:33:01 +00:00
2019-10-16 14:59:52 +00:00
const String & name ( ) const { return * it ; }
2016-03-19 01:18:49 +00:00
} ;
2019-10-10 17:33:01 +00:00
using DatabaseTablesIteratorPtr = std : : unique_ptr < IDatabaseTablesIterator > ;
using DatabaseDictionariesIteratorPtr = std : : unique_ptr < DatabaseDictionariesSnapshotIterator > ;
2016-03-19 01:18:49 +00:00
2017-01-23 18:05:07 +00:00
/** Database engine.
* It is responsible for :
2019-10-10 17:33:01 +00:00
* - initialization of set of known tables and dictionaries ;
2017-01-23 18:05:07 +00:00
* - checking existence of a table and getting a table object ;
* - retrieving a list of all tables ;
* - creating and dropping tables ;
* - renaming tables and moving between databases with same engine .
2016-03-19 01:18:49 +00:00
*/
class IDatabase : public std : : enable_shared_from_this < IDatabase >
{
public :
2019-11-01 12:47:55 +00:00
IDatabase ( ) = delete ;
IDatabase ( String database_name_ ) : database_name ( std : : move ( database_name_ ) ) { }
2017-04-01 07:20:54 +00:00
/// Get name of database engine.
virtual String getEngineName ( ) const = 0 ;
2016-03-19 01:18:49 +00:00
2019-07-19 14:22:57 +00:00
/// Load a set of existing tables.
2017-04-17 11:56:55 +00:00
/// You can call only once, right after the object is created.
2019-11-01 12:47:55 +00:00
virtual void loadStoredObjects ( Context & /*context*/ , bool /*has_force_restore_data_flag*/ ) { }
2016-06-10 20:46:58 +00:00
2017-04-17 11:56:55 +00:00
/// Check the existence of the table.
2017-09-11 12:39:01 +00:00
virtual bool isTableExist (
const Context & context ,
const String & name ) const = 0 ;
2016-03-19 01:18:49 +00:00
2019-10-10 17:33:01 +00:00
/// Check the existence of the dictionary
virtual bool isDictionaryExist (
2019-11-01 12:47:55 +00:00
const Context & /*context*/ ,
const String & /*name*/ ) const
{
return false ;
}
2019-10-10 17:33:01 +00:00
2017-04-17 11:56:55 +00:00
/// Get the table for work. Return nullptr if there is no table.
2017-09-11 12:39:01 +00:00
virtual StoragePtr tryGetTable (
const Context & context ,
2018-01-30 17:47:04 +00:00
const String & name ) const = 0 ;
2016-03-19 01:18:49 +00:00
2019-06-02 12:11:01 +00:00
using FilterByNameFunction = std : : function < bool ( const String & ) > ;
2017-04-17 11:56:55 +00:00
/// Get an iterator that allows you to pass through all the tables.
/// It is possible to have "hidden" tables that are not visible when passing through, but are visible if you get them by name using the functions above.
2019-10-10 17:33:01 +00:00
virtual DatabaseTablesIteratorPtr getTablesIterator ( const Context & context , const FilterByNameFunction & filter_by_table_name = { } ) = 0 ;
/// Get an iterator to pass through all the dictionaries.
virtual DatabaseDictionariesIteratorPtr getDictionariesIterator ( const Context & context , const FilterByNameFunction & filter_by_dictionary_name = { } ) = 0 ;
2016-03-19 01:18:49 +00:00
2019-10-17 13:05:12 +00:00
/// Get an iterator to pass through all the tables and dictionary tables.
virtual DatabaseTablesIteratorPtr getTablesWithDictionaryTablesIterator ( const Context & context , const FilterByNameFunction & filter_by_name = { } )
{
return getTablesIterator ( context , filter_by_name ) ;
}
2016-03-19 01:18:49 +00:00
2017-04-17 11:56:55 +00:00
/// Is the database empty.
2017-09-11 12:39:01 +00:00
virtual bool empty ( const Context & context ) const = 0 ;
2016-03-19 01:18:49 +00:00
2017-04-17 11:56:55 +00:00
/// Add the table to the database. Record its presence in the metadata.
2017-04-01 07:20:54 +00:00
virtual void createTable (
2019-11-01 12:47:55 +00:00
const Context & /*context*/ ,
const String & /*name*/ ,
const StoragePtr & /*table*/ ,
const ASTPtr & /*query*/ )
{
throw Exception ( " There is no CREATE TABLE query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2016-03-19 01:18:49 +00:00
2019-10-10 17:33:01 +00:00
/// Add the dictionary to the database. Record its presence in the metadata.
virtual void createDictionary (
2019-11-01 12:47:55 +00:00
const Context & /*context*/ ,
const String & /*dictionary_name*/ ,
const ASTPtr & /*query*/ )
{
throw Exception ( " There is no CREATE DICTIONARY query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2019-10-10 17:33:01 +00:00
2018-11-28 13:40:24 +00:00
/// Delete the table from the database. Delete the metadata.
2017-09-11 12:39:01 +00:00
virtual void removeTable (
2019-11-01 12:47:55 +00:00
const Context & /*context*/ ,
const String & /*name*/ )
{
throw Exception ( " There is no DROP TABLE query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2016-03-19 01:18:49 +00:00
2019-10-10 17:33:01 +00:00
/// Delete the dictionary from the database. Delete the metadata.
virtual void removeDictionary (
2019-11-01 12:47:55 +00:00
const Context & /*context*/ ,
const String & /*dictionary_name*/ )
{
throw Exception ( " There is no DROP DICTIONARY query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2019-10-10 17:33:01 +00:00
2017-04-17 11:56:55 +00:00
/// Add a table to the database, but do not add it to the metadata. The database may not support this method.
2019-11-01 12:47:55 +00:00
virtual void attachTable ( const String & /*name*/ , const StoragePtr & /*table*/ )
{
throw Exception ( " There is no ATTACH TABLE query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2016-03-19 01:18:49 +00:00
2019-10-10 17:33:01 +00:00
/// Add dictionary to the database, but do not add it to the metadata. The database may not support this method.
2019-10-21 17:09:41 +00:00
/// load is false when we starting up and lazy_load is true, so we don't want to load dictionaries synchronously.
2019-11-01 12:47:55 +00:00
virtual void attachDictionary ( const String & /*name*/ , const Context & /*context*/ , [[maybe_unused]] bool reload = true )
{
throw Exception ( " There is no ATTACH DICTIONARY query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2019-10-10 17:33:01 +00:00
2017-04-17 11:56:55 +00:00
/// Forget about the table without deleting it, and return it. The database may not support this method.
2019-11-01 12:47:55 +00:00
virtual StoragePtr detachTable ( const String & /*name*/ )
{
throw Exception ( " There is no DETACH TABLE query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2016-03-19 01:18:49 +00:00
2019-10-10 17:33:01 +00:00
/// Forget about the dictionary without deleting it, and return it. The database may not support this method.
2019-11-01 12:47:55 +00:00
virtual void detachDictionary ( const String & /*name*/ , const Context & /*context*/ , [[maybe_unused]] bool reload = true )
{
throw Exception ( " There is no DETACH DICTIONARY query for Database " + getEngineName ( ) , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2019-10-10 17:33:01 +00:00
2017-04-17 11:56:55 +00:00
/// Rename the table and possibly move the table to another database.
2017-04-01 07:20:54 +00:00
virtual void renameTable (
2019-08-27 20:43:08 +00:00
const Context & /*context*/ ,
const String & /*name*/ ,
IDatabase & /*to_database*/ ,
const String & /*to_name*/ ,
TableStructureWriteLockHolder & )
{
throw Exception ( getEngineName ( ) + " : renameTable() is not supported " , ErrorCodes : : NOT_IMPLEMENTED ) ;
}
2016-09-02 13:04:11 +00:00
2017-09-17 18:49:43 +00:00
using ASTModifier = std : : function < void ( IAST & ) > ;
2016-05-13 21:08:19 +00:00
2017-04-17 11:56:55 +00:00
/// Change the table structure in metadata.
/// You must call under the TableStructureLock of the corresponding table . If engine_modifier is empty, then engine does not change.
2017-04-01 07:20:54 +00:00
virtual void alterTable (
2019-08-27 20:43:08 +00:00
const Context & /*context*/ ,
const String & /*name*/ ,
const ColumnsDescription & /*columns*/ ,
const IndicesDescription & /*indices*/ ,
const ConstraintsDescription & /*constraints*/ ,
const ASTModifier & /*engine_modifier*/ )
{
2019-10-23 13:46:38 +00:00
throw Exception ( getEngineName ( ) + " : alterTable() is not supported " , ErrorCodes : : NOT_IMPLEMENTED ) ;
2019-08-27 20:43:08 +00:00
}
2016-05-13 21:08:19 +00:00
2017-09-11 12:39:01 +00:00
/// Returns time of table's metadata change, 0 if there is no corresponding metadata file.
2019-11-01 12:47:55 +00:00
virtual time_t getObjectMetadataModificationTime ( const Context & /*context*/ , const String & /*name*/ )
{
return static_cast < time_t > ( 0 ) ;
}
2017-09-11 12:39:01 +00:00
2017-04-17 11:56:55 +00:00
/// Get the CREATE TABLE query for the table. It can also provide information for detached tables for which there is metadata.
2019-11-01 12:47:55 +00:00
ASTPtr tryGetCreateTableQuery ( const Context & context , const String & name ) const noexcept
{
return getCreateTableQueryImpl ( context , name , false ) ;
}
2016-03-19 01:18:49 +00:00
2019-11-01 12:47:55 +00:00
ASTPtr getCreateTableQuery ( const Context & context , const String & name ) const
2018-03-23 19:56:24 +00:00
{
2019-11-01 12:47:55 +00:00
return getCreateTableQueryImpl ( context , name , true ) ;
2018-03-23 19:56:24 +00:00
}
2018-03-14 19:56:44 +00:00
2019-10-10 17:33:01 +00:00
/// Get the CREATE DICTIONARY query for the dictionary. Returns nullptr if dictionary doesn't exists.
2019-11-01 12:47:55 +00:00
ASTPtr tryGetCreateDictionaryQuery ( const Context & context , const String & name ) const noexcept
{
return getCreateDictionaryQueryImpl ( context , name , false ) ;
}
2019-10-10 17:33:01 +00:00
2019-11-01 12:47:55 +00:00
ASTPtr getCreateDictionaryQuery ( const Context & context , const String & name ) const
2019-10-10 17:33:01 +00:00
{
2019-11-01 12:47:55 +00:00
return getCreateDictionaryQueryImpl ( context , name , true ) ;
2019-10-10 17:33:01 +00:00
}
2018-03-13 13:28:32 +00:00
/// Get the CREATE DATABASE query for current database.
virtual ASTPtr getCreateDatabaseQuery ( const Context & context ) const = 0 ;
2016-03-19 01:18:49 +00:00
2018-05-21 03:01:38 +00:00
/// Get name of database.
2019-11-01 12:47:55 +00:00
String getDatabaseName ( ) const { return database_name ; }
2017-11-03 19:53:10 +00:00
/// Returns path for persistent data storage if the database supports it, empty string otherwise
2018-02-21 19:26:59 +00:00
virtual String getDataPath ( ) const { return { } ; }
/// Returns metadata path if the database supports it, empty string otherwise
virtual String getMetadataPath ( ) const { return { } ; }
/// Returns metadata path of a concrete table if the database supports it, empty string otherwise
2019-10-10 17:33:01 +00:00
virtual String getObjectMetadataPath ( const String & /*table_name*/ ) const { return { } ; }
2017-11-03 19:53:10 +00:00
2017-04-17 11:56:55 +00:00
/// Ask all tables to complete the background threads they are using and delete all table objects.
2017-04-01 07:20:54 +00:00
virtual void shutdown ( ) = 0 ;
2016-03-19 01:18:49 +00:00
2018-06-09 15:48:22 +00:00
/// Delete data and metadata stored inside the database, if exists.
2019-10-25 19:07:47 +00:00
virtual void drop ( const Context & /*context*/ ) { }
2016-03-28 11:19:14 +00:00
2017-04-01 07:20:54 +00:00
virtual ~ IDatabase ( ) { }
2019-11-01 12:47:55 +00:00
protected :
virtual ASTPtr getCreateTableQueryImpl ( const Context & /*context*/ , const String & /*name*/ , bool throw_on_error ) const
{
if ( throw_on_error )
throw Exception ( " There is no SHOW CREATE TABLE query for Database " + getEngineName ( ) , ErrorCodes : : CANNOT_GET_CREATE_TABLE_QUERY ) ;
return nullptr ;
}
virtual ASTPtr getCreateDictionaryQueryImpl ( const Context & /*context*/ , const String & /*name*/ , bool throw_on_error ) const
{
if ( throw_on_error )
throw Exception ( " There is no SHOW CREATE DICTIONARY query for Database " + getEngineName ( ) , ErrorCodes : : CANNOT_GET_CREATE_DICTIONARY_QUERY ) ;
return nullptr ;
}
String database_name ;
2016-03-19 01:18:49 +00:00
} ;
using DatabasePtr = std : : shared_ptr < IDatabase > ;
using Databases = std : : map < String , DatabasePtr > ;
}