aboutsummaryrefslogtreecommitdiffstats
path: root/SQLiteStudio3/coreSQLiteStudio/completionhelper.h
diff options
context:
space:
mode:
authorLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
committerLibravatarUnit 193 <unit193@ubuntu.com>2014-12-06 17:33:25 -0500
commit7167ce41b61d2ba2cdb526777a4233eb84a3b66a (patch)
treea35c14143716e1f2c98f808c81f89426045a946f /SQLiteStudio3/coreSQLiteStudio/completionhelper.h
Imported Upstream version 2.99.6upstream/2.99.6
Diffstat (limited to 'SQLiteStudio3/coreSQLiteStudio/completionhelper.h')
-rw-r--r--SQLiteStudio3/coreSQLiteStudio/completionhelper.h264
1 files changed, 264 insertions, 0 deletions
diff --git a/SQLiteStudio3/coreSQLiteStudio/completionhelper.h b/SQLiteStudio3/coreSQLiteStudio/completionhelper.h
new file mode 100644
index 0000000..63b7225
--- /dev/null
+++ b/SQLiteStudio3/coreSQLiteStudio/completionhelper.h
@@ -0,0 +1,264 @@
+#ifndef COMPLETIONHELPER_H
+#define COMPLETIONHELPER_H
+
+#include "expectedtoken.h"
+#include "schemaresolver.h"
+#include "selectresolver.h"
+#include "dialect.h"
+#include "completioncomparer.h"
+#include "parser/ast/sqliteselect.h"
+#include "parser/token.h"
+#include "db/db.h"
+#include "common/strhash.h"
+#include "common/table.h"
+#include <QObject>
+#include <QSet>
+
+class DbAttacher;
+
+class API_EXPORT CompletionHelper : public QObject
+{
+ friend class CompletionComparer;
+
+ public:
+ struct API_EXPORT Results
+ {
+ QList<ExpectedTokenPtr> filtered();
+
+ QList<ExpectedTokenPtr> expectedTokens;
+ QString partialToken;
+ bool wrappedToken = false;
+ };
+
+ CompletionHelper(const QString& sql, Db* db);
+ CompletionHelper(const QString& sql, quint32 cursorPos, Db* db);
+ ~CompletionHelper();
+
+ static void applyFilter(QList<ExpectedTokenPtr> &results, const QString &filter);
+ static void init();
+
+ Results getExpectedTokens();
+
+ DbAttacher* getDbAttacher() const;
+ void setDbAttacher(DbAttacher* value);
+
+ static bool enableLemonDebug;
+
+ QString getCreateTriggerTable() const;
+ void setCreateTriggerTable(const QString& value);
+
+ private:
+ enum class Context
+ {
+ NONE,
+ SELECT_RESULT_COLUMN,
+ SELECT_FROM,
+ SELECT_WHERE,
+ SELECT_GROUP_BY,
+ SELECT_HAVING,
+ SELECT_ORDER_BY,
+ SELECT_LIMIT,
+ UPDATE_COLUMN,
+ UPDATE_WHERE,
+ DELETE_WHERE,
+ CREATE_TABLE,
+ CREATE_TRIGGER,
+ EXPR
+ };
+
+ QList<ExpectedTokenPtr> getExpectedTokens(TokenPtr token);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString& value);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString& value,
+ int priority);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString& value,
+ const QString& contextInfo);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString& value,
+ const QString& contextInfo, int priority);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString &value,
+ const QString &contextInfo, const QString &label);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString &value,
+ const QString &contextInfo, const QString &label,
+ int priority);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString &value,
+ const QString &contextInfo, const QString &label,
+ const QString &prefix);
+ ExpectedTokenPtr getExpectedToken(ExpectedToken::Type type, const QString &value,
+ const QString &contextInfo, const QString &label,
+ const QString &prefix, int priority);
+ bool validatePreviousIdForGetObjects(QString* dbName = nullptr);
+ QList<ExpectedTokenPtr> getTables();
+ QList<ExpectedTokenPtr> getIndexes();
+ QList<ExpectedTokenPtr> getTriggers();
+ QList<ExpectedTokenPtr> getViews();
+ QList<ExpectedTokenPtr> getDatabases();
+ QList<ExpectedTokenPtr> getObjects(ExpectedToken::Type type);
+ QList<ExpectedTokenPtr> getObjects(ExpectedToken::Type type, const QString& database);
+ QList<ExpectedTokenPtr> getColumns();
+ QList<ExpectedTokenPtr> getColumnsNoPrefix();
+ QList<ExpectedTokenPtr> getColumnsNoPrefix(const QString &column, const QStringList &tables);
+ QList<ExpectedTokenPtr> getColumns(const QString& prefixTable);
+ QList<ExpectedTokenPtr> getColumns(const QString& prefixDb, const QString& prefixTable);
+ QList<ExpectedTokenPtr> getFavoredColumns(const QList<ExpectedTokenPtr>& resultsSoFar);
+
+ QList<ExpectedTokenPtr> getPragmas(Dialect dialect);
+ QList<ExpectedTokenPtr> getFunctions(Db* db);
+ QList<ExpectedTokenPtr> getCollations();
+ TokenPtr getPreviousDbOrTable(const TokenList& parsedTokens);
+ void attachDatabases();
+ void detachDatabases();
+ QString translateDatabase(const QString& dbName);
+ QString translateDatabaseBack(const QString& dbName);
+ void collectOtherDatabases();
+ QString removeStartedToken(const QString& adjustedSql, QString &finalFilter, bool& wrappedFilter);
+ void filterContextKeywords(QList<ExpectedTokenPtr> &results, const TokenList& tokens);
+ void filterOtherId(QList<ExpectedTokenPtr> &results, const TokenList& tokens);
+ void filterDuplicates(QList<ExpectedTokenPtr> &results);
+ bool isFilterType(Token::Type type);
+ void parseFullSql();
+ void sort(QList<ExpectedTokenPtr> &results);
+ void extractPreviousIdTokens(const TokenList& parsedTokens);
+ void extractQueryAdditionalInfo();
+ void extractSelectAvailableColumnsAndTables();
+ bool extractSelectCore();
+ SqliteSelect::Core* extractSelectCore(SqliteQueryPtr query);
+ void extractTableAliasMap();
+ void extractCreateTableColumns();
+ void detectSelectContext();
+ bool isInUpdateColumn();
+ bool isInUpdateWhere();
+ bool isInDeleteWhere();
+ bool isInCreateTable();
+ bool isInCreateTrigger();
+ bool isIn(SqliteQueryType queryType, const QString& tokenMapKey, const QString &prefixKeyword);
+ bool isInExpr();
+ bool testQueryToken(int tokenPosition, Token::Type type, const QString& value, Qt::CaseSensitivity cs = Qt::CaseInsensitive);
+ bool cursorAfterTokenMaps(SqliteStatement* stmt, const QStringList& mapNames);
+ bool cursorBeforeTokenMaps(SqliteStatement* stmt, const QStringList& mapNames);
+
+ template <class T>
+ bool cursorFitsInCollection(const QList<T*>& collection)
+ {
+ if (collection.size() == 0)
+ return false;
+
+ T* firstStmt = collection.first();
+ T* lastStmt = collection.last();
+
+ int startIdx = -1;
+ int endIdx = -1;
+ if (firstStmt && firstStmt->tokens.size() > 0)
+ startIdx = firstStmt->tokens.first()->start;
+
+ if (lastStmt && lastStmt->tokens.size() > 0)
+ endIdx = lastStmt->tokens.last()->end;
+
+ if (startIdx < 0 || endIdx < 0)
+ return false;
+
+ return (cursorPosition >= startIdx && cursorPosition <= endIdx);
+ }
+
+ template <class T>
+ bool cursorFitsInStatement(T* stmt)
+ {
+ if (!stmt || stmt->tokens.size() == 0)
+ return false;
+
+ int startIdx = stmt->tokens.first()->start;
+ int endIdx = stmt->tokens.last()->end;
+
+ return (cursorPosition >= startIdx && cursorPosition <= endIdx);
+ }
+
+
+ Context context = Context::NONE;
+ Db* db = nullptr;
+ qint64 cursorPosition;
+ QString fullSql;
+ TokenPtr previousId;
+ TokenPtr twoIdsBack;
+ TokenList queryTokens;
+ SqliteQueryPtr parsedQuery;
+ SqliteQueryPtr originalParsedQuery;
+ SchemaResolver* schemaResolver = nullptr;
+ SelectResolver* selectResolver = nullptr;
+ DbAttacher* dbAttacher = nullptr;
+ QString createTriggerTable;
+
+ /**
+ * @brief tableToAlias
+ * This map maps real table name to its alias. Every table can be typed multiple times
+ * with different aliases, therefore this map has a list on the right side.
+ */
+ QHash<QString,QStringList> tableToAlias;
+
+ /**
+ * @brief aliasToTable
+ * Maps table alias to table's real name.
+ */
+ //QHash<QString,QString> aliasToTable;
+ StrHash<Table> aliasToTable;
+
+ /**
+ * @brief currentSelectCore
+ * The SqliteSelect::Core object that contains current cursor position.
+ */
+ SqliteSelect::Core* currentSelectCore = nullptr;
+
+ /**
+ * @brief originalCurrentSelectCore
+ *
+ * The same as currentSelectCore, but relates to originalParsedQuery, not just parsedQuery.
+ */
+ SqliteSelect::Core* originalCurrentSelectCore = nullptr;
+
+ /**
+ * @brief selectAvailableColumns
+ * Available columns are columns that can be selected basing on what tables are mentioned in FROM clause.
+ */
+ QList<SelectResolver::Column> selectAvailableColumns;
+
+ /**
+ * @brief selectAvailableTables
+ * Availble tables are tables mentioned in FROM clause.
+ */
+ QSet<SelectResolver::Table> selectAvailableTables;
+
+ /**
+ * @brief parentSelectCores
+ * List of all parent select core objects in order: from direct parent, to the oldest parent.
+ */
+ QList<SqliteSelect::Core*> parentSelectCores;
+
+ /**
+ * @brief parentSelectAvailableColumns
+ * List of all columns available in all tables mentioned in all parent select cores.
+ */
+ QList<SelectResolver::Column> parentSelectAvailableColumns;
+
+ /**
+ * @brief parentSelectAvailableTables
+ * Same as parentSelectAvailableColumns, but for tables in FROM clauses.
+ */
+ QSet<SelectResolver::Table> parentSelectAvailableTables;
+
+ /**
+ * @brief favoredColumnNames
+ * For some contexts there are favored column names, like for example CREATE TABLE
+ * will favour column names specified so far in its definition.
+ * Such columns will be added to completion results even they weren't result
+ * of regular computation.
+ */
+ QStringList favoredColumnNames;
+
+ /**
+ * @brief Context databases to look for objects in.
+ *
+ * If the query uses some other databases (not the currentone), then user might be interested
+ * also in objects from those databases. This list contains those databases.
+ */
+ QStringList otherDatabasesToLookupFor;
+};
+
+#endif // COMPLETIONHELPER_H