#ifndef DBATTACHER_H #define DBATTACHER_H #include "parser/ast/sqlitequery.h" #include "common/bistrhash.h" #include "common/strhash.h" #include class Db; /** * @brief Transparent attaching of databases used in the query. * * Scans query (or queries) for names of databases registered in DbManager. * If a database is recognized, it's automatically attached and the mapping * of its database name to its attach name is created for later information. * * The attacher looks for database names only at those spots in the query, * where the database name is valid by SQLite syntax (this is accomplished * with SqliteStatement::getContextDatabaseTokens()). */ class API_EXPORT DbAttacher { public: /** * @brief Default destructor. */ virtual ~DbAttacher(); /** * @brief Scans for databases in given query and attaches them. * @param query Query string to be executed. * @return true on success, or false on failure. * * The method can fail if any of databases used in the query could * not be attached (the ATTACH statement caused error). * * To get query with database names replaced with attach names use getQuery(). */ virtual bool attachDatabases(const QString& query) = 0; /** * Be aware that database names in queries are replaced with attach names in SqliteStatement::tokens, * thus modified query can be achived with SqliteStatement::detokenize(). This also means * that the input queries will contain modified token list. * * @overload */ virtual bool attachDatabases(const QList& queries) = 0; /** * @overload */ virtual bool attachDatabases(SqliteQueryPtr query) = 0; /** * @brief Detaches all databases attached by the attacher. */ virtual void detachDatabases() = 0; /** * @brief Provides mapping of database names to their attach names. * @return Database name to attach name mapping. * * The returned map is bi-directional, so you can easly translate database name to attach name * and vice versa. Left values of the map are database names (as registered in DbManager) * and right values are attach names assigned to them. */ virtual BiStrHash getDbNameToAttach() const = 0; /** * @brief Provides query string updated with attach names. * @return Query string. */ virtual QString getQuery() const = 0; /** * @brief Tells if "main" database name was used in the query and was ommited. * @return true when "main" db token was in the query, or false otherwise. * * The "main" database will not be attached and this getter tells wheter such situation occured. * This is to assert situation when user has database on the list which name is actually "main". * Table window always uses "main." prefix when reading data and this caused attacher to step in, * which then caused some execution error. */ virtual bool getMainDbNameUsed() const = 0; }; /** * @brief Abstract factory for DbAttacher objects. * * The abstract factory is accessed from SQLiteStudio class in order to produce DbAttacher instances. * The default DbAttacherFactory implementation (DbAttacherFactoryImpl) produces default DbAttacher instances * (DbAttacherImpl), but it can be replaced with other factory to produce other attachers, just like unit tests * in this project do. */ class API_EXPORT DbAttacherFactory { public: virtual ~DbAttacherFactory(); /** * @brief Produces single attacher instance. * @param db Database to produce attacher for. * @return Attacher instance. Factory doesn't own it, you have to delete it when you're done. */ virtual DbAttacher* create(Db* db) = 0; }; #endif // DBATTACHER_H