summaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/guiSQLiteStudio/dialogs/indexdialog.h
blob: dd68137fa8bb7d1dc48b25a50525a63256b313bd (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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#ifndef INDEXDIALOG_H
#define INDEXDIALOG_H

#include "db/db.h"
#include "guiSQLiteStudio_global.h"
#include "parser/ast/sqlitecreateindex.h"
#include "common/strhash.h"
#include <QDialog>
#include <QStringListModel>

namespace Ui {
    class IndexDialog;
}

class QGridLayout;
class QSignalMapper;
class QCheckBox;
class QComboBox;
class QTableWidget;

class GUI_API_EXPORT IndexDialog : public QDialog
{
        Q_OBJECT

    public:
        IndexDialog(Db* db, QWidget *parent = 0);
        IndexDialog(Db* db, const QString& index, QWidget *parent = 0);
        ~IndexDialog();

        void setTable(const QString& value);

    protected:
        void changeEvent(QEvent *e);

    private:
        class Column
        {
            public:
                /**
                 * @brief Constructor for a real column in the table
                 */
                Column(const QString& name, QTableWidget* table);

                /**
                 * @brief Constructor for an expression column
                 */
                Column(SqliteExpr* expr, QTableWidget* table);
                ~Column();

                void assignToNewRow(int row);
                void prepareForNewRow();
                QCheckBox* getCheck() const;
                void setCheck(QCheckBox* cb);
                QWidget* getCheckParent() const;
                void setCheckParent(QWidget* w);
                QComboBox* getSort() const;
                void setSort(QComboBox* cb);
                QComboBox* getCollation() const;
                void setCollation(QComboBox* cb);

                /**
                 * @brief Gets name of a real column in the table
                 * @return Name of table's column, or null string if it's expression column.
                 */
                QString getName() const;

                /**
                 * @brief Gets expression of an expression column.
                 * @return Either the expression, or null if this is a real table column.
                 *
                 * If an expression assigned to the column is a collate expression,
                 * this method will extract inner expression and return that.
                 *
                 * This is done this way, because after parsing SqliteOrderBy,
                 * the whole expression (including outer COLLATE expression) is passed
                 * to the column, whereas COLLATE is used for dropdowns, not for actual expression.
                 */
                SqliteExpr* getExpr() const;

                void setExpr(SqliteExpr* expr);

                /**
                 * @brief Tells whether this is an expression column or real table column.
                 * @return true if it's expression column, or false if it's real table.
                 */
                bool isExpr() const;
                QString getKey() const;

            private:
                QWidget* defineContainer(QWidget* w);

                QWidget* column1Contrainer = nullptr;
                QWidget* column2Contrainer = nullptr;
                QWidget* column3Contrainer = nullptr;
                QWidget* checkParent = nullptr;
                QCheckBox* check = nullptr;
                QComboBox* sort = nullptr;
                QComboBox* collation = nullptr;
                QTableWidget* table = nullptr;
                QString name;
                SqliteExpr* expr = nullptr;
        };

        static QString buildKey(SqliteExpr* expr);

        void init();
        void readIndex();
        void readCollations();
        void buildColumn(const QString& name, int row);
        Column* buildColumn(SqliteOrderBy* orderBy, int row);
        Column* buildColumn(SqliteExpr* expr, int row);
        void buildColumn(Column* column, int row);
        void applyColumnValues();
        void applyIndex();
        SqliteOrderBy* addIndexedColumn(const QString& name);
        SqliteOrderBy* addIndexedColumn(SqliteExpr* expr);
        void addCollation(SqliteOrderBy* col, const QString& name);
        void rebuildCreateIndex();
        void queryDuplicates();
        void clearColumns();
        void rebuildColumnsByNewOrder();
        QString getKey(SqliteOrderBy* col) const;
        QStringList getExistingColumnExprs(const QString& exceptThis = QString()) const;
        QStringList getTableColumns() const;
        void preReject();
        QString getOriginalDdl() const;

        bool existingIndex = false;
        Db* db = nullptr;
        QString table;
        QString index;
        SqliteCreateIndexPtr createIndex;
        SqliteCreateIndexPtr originalCreateIndex;
        QStringList tableColumns;
        QSignalMapper* columnStateSignalMapping = nullptr;
        QStringListModel collations;
        StrHash<Column*> columns;
        QList<Column*> columnsByRow;
        int totalColumns = 0;
        bool preRejected = false;
        Ui::IndexDialog *ui = nullptr;

    private slots:
        void updateValidation();
        void buildColumns();
        void updateTable(const QString& value);
        void updateColumnState(const QString& columnKey);
        void updatePartialConditionState();
        void updateDdl();
        void tabChanged(int tab);
        void moveColumnUp();
        void moveColumnDown();
        void updateToolBarButtons(const QModelIndex& idx = QModelIndex());
        void addExprColumn();
        void editExprColumn(int row = -1);
        void delExprColumn();

    public slots:
        void accept();
        int exec();
};

#endif // INDEXDIALOG_H