aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/dbattacher.h
blob: 0e849a553233fecacf512051ff17d3fd28ebe448 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#ifndef DBATTACHER_H
#define DBATTACHER_H

#include "parser/ast/sqlitequery.h"
#include "common/bistrhash.h"
#include "common/strhash.h"
#include <QList>

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<SqliteQueryPtr>& 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