Big cleanup
This commit is contained in:
parent
d3080a08bb
commit
8b671090a0
55 changed files with 214 additions and 3967 deletions
|
|
@ -36,28 +36,6 @@ BackupFormatModel::BackupFormatModel(QObject *parent)
|
|||
|
||||
}
|
||||
|
||||
//QVariant BackupFormatModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||
//{
|
||||
// QVariant result;
|
||||
|
||||
// if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
|
||||
// switch (section) {
|
||||
// case Column::Short:
|
||||
// result = tr("Short");
|
||||
// break;
|
||||
// case Column::Long:
|
||||
// result = tr("Long");
|
||||
// break;
|
||||
// case Column::Description:
|
||||
// result = tr("Description");
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
// return result;
|
||||
//}
|
||||
|
||||
|
||||
int BackupFormatModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
int size = static_cast<int>(g_BackupFormats.size());
|
||||
|
|
|
|||
|
|
@ -13,10 +13,6 @@ public:
|
|||
|
||||
explicit BackupFormatModel(QObject *parent);
|
||||
|
||||
// Header:
|
||||
// QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
|
||||
|
||||
// Basic functionality:
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
|
|
|
|||
|
|
@ -113,23 +113,6 @@ int ExplainTreeModelItem::childCount() const
|
|||
return static_cast<int>(m_childItems.size());
|
||||
}
|
||||
|
||||
//int ExplainTreeModelItem::columnCount() const
|
||||
//{
|
||||
// return 6;
|
||||
//}
|
||||
|
||||
//QVariant ExplainTreeModelItem::data(int column) const
|
||||
//{
|
||||
// QVariant r;
|
||||
// if (column == 0) {
|
||||
// r = nodeType;
|
||||
// }
|
||||
// else if (column == 1) {
|
||||
|
||||
// }
|
||||
// return r;
|
||||
//}
|
||||
|
||||
int ExplainTreeModelItem::row() const
|
||||
{
|
||||
int idx = 0;
|
||||
|
|
@ -151,166 +134,6 @@ ExplainTreeModelItemPtr ExplainTreeModelItem::parent()
|
|||
return p;
|
||||
}
|
||||
|
||||
//void ExplainTreeModelItem::setNodeType(QString nt)
|
||||
//{
|
||||
// m_nodeType = std::move(nt);
|
||||
//}
|
||||
|
||||
//const QString& ExplainTreeModelItem::nodeType() const
|
||||
//{
|
||||
// return m_nodeType;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setParallelAware(bool aware)
|
||||
//{
|
||||
// m_parallelAware = aware;
|
||||
//}
|
||||
|
||||
//bool ExplainTreeModelItem::getParallelAware() const
|
||||
//{
|
||||
// return m_parallelAware;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setStrategy(QString strat)
|
||||
//{
|
||||
// m_strategy = std::move(strat);
|
||||
//}
|
||||
|
||||
//const QString& ExplainTreeModelItem::strategy() const
|
||||
//{
|
||||
// return m_strategy;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setJoinType(QString jointype)
|
||||
//{
|
||||
// m_joinType = jointype;
|
||||
//}
|
||||
|
||||
//QString ExplainTreeModelItem::joinType() const
|
||||
//{
|
||||
// return m_joinType;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setStartupCost(float cost)
|
||||
//{
|
||||
// m_startupCost = cost;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setTotalCost(float cost)
|
||||
//{
|
||||
// m_totalCost = cost;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setEstimatedRows(long long estimated)
|
||||
//{
|
||||
// m_estimatedRows = estimated;
|
||||
//}
|
||||
|
||||
//long long ExplainTreeModelItem::estimatedRows() const
|
||||
//{
|
||||
// return m_estimatedRows;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setPlanWidth(int width)
|
||||
//{
|
||||
// m_planWidth = width;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setActualStartupTime(float timems)
|
||||
//{
|
||||
// m_actualStartupTime = timems;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setActualTotalTime(float timems)
|
||||
//{
|
||||
// m_actualTotalTime = timems;
|
||||
//}
|
||||
|
||||
//float ExplainTreeModelItem::actualTotalTime() const
|
||||
//{
|
||||
// return m_actualTotalTime;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setActualRows(long long rowcount)
|
||||
//{
|
||||
// m_actualRows = rowcount;
|
||||
//}
|
||||
|
||||
//long long ExplainTreeModelItem::actualRows() const
|
||||
//{
|
||||
// return m_actualRows;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setActualLoops(int loopcount)
|
||||
//{
|
||||
// m_actualLoops = loopcount;
|
||||
//}
|
||||
|
||||
//int ExplainTreeModelItem::actualLoops() const
|
||||
//{
|
||||
// return m_actualLoops;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setRelationName(QString n)
|
||||
//{
|
||||
// m_relationName = std::move(n);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setAlias(QString a)
|
||||
//{
|
||||
// m_alias = std::move(a);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setScanDirection(QString dir)
|
||||
//{
|
||||
// m_scanDirection = std::move(dir);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setIndexName(QString idxname)
|
||||
//{
|
||||
// m_indexName = std::move(idxname);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setIndexCondition(QString idxcond)
|
||||
//{
|
||||
// m_indexCondition = std::move(idxcond);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setIndexRecheck(QString idxrecheck)
|
||||
//{
|
||||
// m_indexRecheck = std::move(idxrecheck);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setFilter(QString filter)
|
||||
//{
|
||||
// m_filter = std::move(filter);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setHashCondition(QString condition)
|
||||
//{
|
||||
// m_hashCondition = std::move(condition);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setSortKey(QString key)
|
||||
//{
|
||||
// m_sortKey = std::move(key);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setSortMethod(QString method)
|
||||
//{
|
||||
// m_sortMethod = std::move(method);
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setSortSpaceUsed(int space)
|
||||
//{
|
||||
// m_sortSpaceUsed = space;
|
||||
//}
|
||||
|
||||
//void ExplainTreeModelItem::setSortSpaceType(QString type)
|
||||
//{
|
||||
// m_sortSpaceType = std::move(type);
|
||||
//}
|
||||
|
||||
float ExplainTreeModelItem::exclusiveTime() const
|
||||
{
|
||||
float tt = inclusiveTime();
|
||||
|
|
@ -389,29 +212,3 @@ QString ExplainTreeModelItem::detailString() const
|
|||
|
||||
return s.trimmed();
|
||||
}
|
||||
|
||||
//"Sort Key": ["pg_attribute.attname"],
|
||||
//"Sort Method": "quicksort",
|
||||
//"Sort Space Used": 1426,
|
||||
//"Sort Space Type": "Memory",
|
||||
|
||||
|
||||
//{
|
||||
// "Node Type": "Index Scan",
|
||||
// "Parent Relationship": "Inner",
|
||||
// "Scan Direction": "Forward",
|
||||
// "Index Name": "pg_type_oid_index",
|
||||
// "Relation Name": "pg_type",
|
||||
// "Alias": "pg_type",
|
||||
// "Startup Cost": 0.15,
|
||||
// "Total Cost": 0.18,
|
||||
// "Plan Rows": 1,
|
||||
// "Plan Width": 758,
|
||||
// "Actual Startup Time": 0.003,
|
||||
// "Actual Total Time": 0.004,
|
||||
// "Actual Rows": 1,
|
||||
// "Actual Loops": 100,
|
||||
// "Index Cond": "(oid = pg_attribute.atttypid)",
|
||||
// "Rows Removed by Index Recheck": 0
|
||||
// "Filter": "actief"
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -60,54 +60,17 @@ public:
|
|||
|
||||
ExplainTreeModelItemPtr child(int row);
|
||||
int childCount() const;
|
||||
// int columnCount() const;
|
||||
// QVariant data(int column) const;
|
||||
int row() const;
|
||||
void setParent(const ItemPtr &parent);
|
||||
ItemPtr parent();
|
||||
|
||||
|
||||
// void setNodeType(QString nt);
|
||||
// const QString& nodeType() const;
|
||||
// void setParallelAware(bool aware);
|
||||
// bool getParallelAware() const;
|
||||
// void setStrategy(QString strat);
|
||||
// const QString& strategy() const;
|
||||
// void setJoinType(QString jointype);
|
||||
// QString joinType() const;
|
||||
// void setStartupCost(float cost);
|
||||
// void setTotalCost(float cost);
|
||||
// void setEstimatedRows(long long estimated);
|
||||
// long long estimatedRows() const;
|
||||
// void setPlanWidth(int width);
|
||||
// void setActualStartupTime(float timems);
|
||||
// void setActualTotalTime(float timems);
|
||||
// float actualTotalTime() const;
|
||||
// void setActualRows(long long rowcount);
|
||||
// long long actualRows() const;
|
||||
// void setActualLoops(int loopcount);
|
||||
// int actualLoops() const;
|
||||
|
||||
// void setRelationName(QString n);
|
||||
// void setAlias(QString a);
|
||||
// void setScanDirection(QString dir);
|
||||
// void setIndexName(QString idxname);
|
||||
// void setIndexCondition(QString idxcond);
|
||||
// void setIndexRecheck(QString idxrecheck);
|
||||
// void setFilter(QString filter);
|
||||
// void setHashCondition(QString condition);
|
||||
// void setSortKey(QString key);
|
||||
// void setSortMethod(QString method);
|
||||
// void setSortSpaceUsed(int space);
|
||||
// void setSortSpaceType(QString type);
|
||||
|
||||
/** ActualTotalTime minus the actual total time of it's children */
|
||||
float exclusiveTime() const;
|
||||
float inclusiveTime() const;
|
||||
float estimateError() const;
|
||||
QString detailString() const;
|
||||
|
||||
//private:
|
||||
std::vector<ItemPtr> m_childItems;
|
||||
std::weak_ptr<ExplainTreeModelItem> m_parentItem;
|
||||
|
||||
|
|
@ -143,9 +106,6 @@ public:
|
|||
TempBlocks tempBlocks;
|
||||
IoTimes ioTimes;
|
||||
|
||||
// "Triggers": [
|
||||
// ],
|
||||
|
||||
};
|
||||
|
||||
class ExplainRoot {
|
||||
|
|
|
|||
|
|
@ -198,14 +198,11 @@ void PasswordManager::initializeNewPskStore(QSqlDatabase &db)
|
|||
" salt TEXT \n"
|
||||
");");
|
||||
if (!create_tbl.exec()) {
|
||||
// auto sql_error = create_tbl.lastError();
|
||||
// throw std::runtime_error("create table failed");
|
||||
auto err = create_tbl.lastError();
|
||||
throw SqlException(err);
|
||||
}
|
||||
}
|
||||
|
||||
// db->create_table(
|
||||
QSqlQuery create_tbl(db);
|
||||
create_tbl.prepare(
|
||||
"CREATE TABLE IF NOT EXISTS " + m_secretHashTableName + "( \n"
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ public:
|
|||
|
||||
std::string encrypt(const std::string &id, const std::string &passwd);
|
||||
std::string decrypt(const std::string &id, const std::string_view &encpwd);
|
||||
// void remove(const std::string &id);
|
||||
|
||||
private:
|
||||
QString m_passwordTableName = "psk_passwd";
|
||||
QString m_secretAlgoTableName = "psk_masterkey_algo";
|
||||
|
|
|
|||
|
|
@ -1,64 +0,0 @@
|
|||
#include "QueuedBackgroundTask.h"
|
||||
#include "ScopeGuard.h"
|
||||
|
||||
//void QueuedBackgroundTask::requestPause()
|
||||
//{}
|
||||
|
||||
QueuedBackgroundTask::QueuedBackgroundTask(CompletionFunction on_completion)
|
||||
: m_completionFunction(std::move(on_completion))
|
||||
{
|
||||
setAutoDelete(false);
|
||||
}
|
||||
|
||||
QueuedBackgroundTask::~QueuedBackgroundTask()
|
||||
{
|
||||
cancel();
|
||||
wait();
|
||||
}
|
||||
|
||||
void QueuedBackgroundTask::cancel()
|
||||
{
|
||||
QMutexLocker lock(&stateMutex);
|
||||
if (!m_finished)
|
||||
m_canceled = true;
|
||||
}
|
||||
|
||||
void QueuedBackgroundTask::wait()
|
||||
{
|
||||
QMutexLocker lock(&stateMutex);
|
||||
if (!m_finished)
|
||||
finished.wait(&stateMutex);
|
||||
}
|
||||
|
||||
bool QueuedBackgroundTask::hasException() const
|
||||
{
|
||||
return doRunException != nullptr;
|
||||
}
|
||||
|
||||
void QueuedBackgroundTask::rethrow()
|
||||
{
|
||||
std::rethrow_exception(doRunException);
|
||||
}
|
||||
|
||||
void QueuedBackgroundTask::run()
|
||||
{
|
||||
SCOPE_EXIT {
|
||||
m_finished = true;
|
||||
QMutexLocker lock(&stateMutex);
|
||||
finished.notify_all();
|
||||
};
|
||||
QMutexLocker lock(&stateMutex);
|
||||
m_started = true;
|
||||
if (!m_canceled) {
|
||||
lock.unlock();
|
||||
try {
|
||||
doRun();
|
||||
}
|
||||
catch (...) {
|
||||
doRunException = std::current_exception();
|
||||
}
|
||||
|
||||
if (!m_canceled && m_completionFunction)
|
||||
m_completionFunction(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <QRunnable>
|
||||
//#include <QVector>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
|
||||
/** Base class for an object that can be queued for execution in the background.
|
||||
*
|
||||
* It is meaned for long running processes the end user might want to abort,
|
||||
* pause and check progress on.
|
||||
*/
|
||||
class QueuedBackgroundTask: public QRunnable {
|
||||
public:
|
||||
using CompletionFunction = std::function<void(QRunnable *)>;
|
||||
|
||||
explicit QueuedBackgroundTask(CompletionFunction on_completion);
|
||||
virtual ~QueuedBackgroundTask();
|
||||
|
||||
void cancel();
|
||||
void wait();
|
||||
bool hasException() const;
|
||||
void rethrow();
|
||||
|
||||
protected:
|
||||
|
||||
bool m_canceled = false;
|
||||
bool m_started = false;
|
||||
bool m_finished = false;
|
||||
std::exception_ptr doRunException = nullptr;
|
||||
CompletionFunction m_completionFunction = nullptr;
|
||||
|
||||
QMutex stateMutex;
|
||||
QWaitCondition finished;
|
||||
|
||||
virtual void run() override;
|
||||
|
||||
virtual void doRun() = 0;
|
||||
|
||||
// /** Task should exit it's run method but remember it's state, it might be resumed later.
|
||||
// */
|
||||
// void requestPause();
|
||||
|
||||
// /** Request to stop running and forget progress
|
||||
// */
|
||||
// void requestAbort();
|
||||
|
||||
// QString getProgressInfo();
|
||||
};
|
||||
|
||||
//class BackgroundTaskInfo {
|
||||
//public:
|
||||
//};
|
||||
|
||||
///** Manages objects of type QueuedBackgroundTask
|
||||
// *
|
||||
// * The basic operation of this queue is hand everything directly of to the default
|
||||
// * threadpool and that will decide when to run each task. But extra functions are
|
||||
// * provided to control tasks to allow the program to have a UI for controlling the tasks
|
||||
// */
|
||||
//class BackgroundTaskQueue {
|
||||
|
||||
//public:
|
||||
|
||||
// /** Returns a list of tasks in the queue and their progress.
|
||||
// *
|
||||
// * When building a UI to show realtime activity then make sure to first register the update events
|
||||
// * then get the snapshot. After that you can use the events to update the contents of the UI.
|
||||
// */
|
||||
// QVector<BackgroundTaskInfo> getTaskInfoSnapshort();
|
||||
|
||||
// void pauseTask( );
|
||||
|
||||
// /** Resume a paused task
|
||||
// */
|
||||
// void resumeTask( );
|
||||
|
||||
// void abortTask( );
|
||||
|
||||
//};
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
#include "SqlAstExpression.h"
|
||||
|
||||
using namespace SqlAst;
|
||||
|
||||
|
||||
std::shared_ptr<SqlAst::Expression> parseExpression(SqlParser &parser)
|
||||
{
|
||||
// get token, what is it?
|
||||
// number
|
||||
// symbol
|
||||
// left parenthesis
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef SQLASTEXPRESSION_H
|
||||
#define SQLASTEXPRESSION_H
|
||||
|
||||
#include "SqlAstNode.h"
|
||||
|
||||
class SqlParser;
|
||||
|
||||
namespace SqlAst {
|
||||
|
||||
/// Base class for parts of expressions like calculations, comparisons, function calls etc...
|
||||
class Expression: public Node {
|
||||
|
||||
};
|
||||
|
||||
std::shared_ptr<SqlAst::Expression> parseExpression(SqlParser &parser);
|
||||
|
||||
}
|
||||
|
||||
#endif // SQLASTEXPRESSION_H
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
#include "SqlAstNode.h"
|
||||
|
||||
using namespace SqlAst;
|
||||
|
||||
Node::Node() = default;
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
#ifndef SQLASTNODE_H
|
||||
#define SQLASTNODE_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace SqlAst {
|
||||
|
||||
class Node {
|
||||
public:
|
||||
Node();
|
||||
//virtual Node* Clone() const = 0;
|
||||
};
|
||||
|
||||
class DDLNode: public Node {
|
||||
|
||||
};
|
||||
|
||||
class CreateTable: public Node {
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Is there a benefit for having a common base for crud operations???
|
||||
class CrudNode: public Node {
|
||||
|
||||
};
|
||||
|
||||
|
||||
class Insert: public CrudNode {
|
||||
|
||||
};
|
||||
|
||||
/** Class for representing an identifier.
|
||||
*
|
||||
* This can still be multiple things like:
|
||||
* - name of alias, schema, table and or column
|
||||
* - name of function
|
||||
* - predefined symbol like LOCAL_TIME
|
||||
*
|
||||
* During parsing this cannot always be determined as an alias might be involved that hasn't been parsed yet
|
||||
* so we put a Identifier in the AST a follow up pass could determine what it actually as and act appropriatly
|
||||
*
|
||||
* An identifier can consist of following fields
|
||||
* - [[schema.]table.]column
|
||||
* - [alias.]column
|
||||
* - [schema.]table.function (for function taking a row of type table)
|
||||
* - alias.function (for function taking a row of type table)
|
||||
* - schema.function
|
||||
* - sql symbol like CURRENT_DATE
|
||||
*/
|
||||
class Identifier: public Node {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // SQLASTNODE_H
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
#include "SqlAstSelect.h"
|
||||
#include "SqlAstSelectList.h"
|
||||
#include "SqlParser.h"
|
||||
|
||||
namespace SqlAst {
|
||||
|
||||
|
||||
std::shared_ptr<SqlAst::Select> parseSelect(SqlParser &parser)
|
||||
{
|
||||
auto ast_select = std::make_shared<SqlAst::Select>();
|
||||
// parse select list of expression + aliasses, required
|
||||
// auto select_list = parseSelectList(parser);
|
||||
// ast_select->setSelectList(select_list);
|
||||
|
||||
// parse optional from list
|
||||
|
||||
return ast_select;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef SQLASTSELECT_H
|
||||
#define SQLASTSELECT_H
|
||||
|
||||
#include "SqlAstNode.h"
|
||||
//#include "SqlAstSelectList.h"
|
||||
#include <memory>
|
||||
|
||||
class SqlParser;
|
||||
|
||||
namespace SqlAst {
|
||||
|
||||
class SelectList;
|
||||
class From;
|
||||
class Where;
|
||||
class GroupBy;
|
||||
class Having;
|
||||
class OrderBy;
|
||||
|
||||
class Select: public CrudNode {
|
||||
public:
|
||||
|
||||
void setSelectList(std::shared_ptr<SelectList> list) { select = list; }
|
||||
auto getSelectList() const { return select; }
|
||||
void setFrom(std::shared_ptr<From> f) { from = f; }
|
||||
|
||||
private:
|
||||
std::shared_ptr<SelectList> select;
|
||||
std::shared_ptr<From> from;
|
||||
std::shared_ptr<Where> where;
|
||||
std::shared_ptr<GroupBy> groupBy;
|
||||
std::shared_ptr<Having> having;
|
||||
std::shared_ptr<OrderBy> orderBy;
|
||||
};
|
||||
|
||||
std::shared_ptr<SqlAst::Select> parseSelect(SqlParser &parser);
|
||||
|
||||
}
|
||||
|
||||
#endif // SQLASTSELECT_H
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
#include "SqlAstSelectList.h"
|
||||
#include "SqlAstSelectListEntry.h"
|
||||
#include "SqlParser.h"
|
||||
|
||||
using namespace SqlAst;
|
||||
|
||||
std::shared_ptr<SqlAst::SelectList> parseSelectList(SqlParser &parser)
|
||||
{
|
||||
// parse select element
|
||||
// whats next?
|
||||
// comma -> parse an element
|
||||
// something else return and let caller figure it out
|
||||
auto ast_select_list = std::make_shared<SelectList>();
|
||||
while (1) {
|
||||
auto ast_select_elem = parseSelectListEntry(parser);
|
||||
if (ast_select_elem) {
|
||||
ast_select_list->add(ast_select_elem);
|
||||
}
|
||||
else {
|
||||
// todo error
|
||||
}
|
||||
if (!parser.expectToken(BasicTokenType::Comma)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ast_select_list;
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef SQLASTSELECTLIST_H
|
||||
#define SQLASTSELECTLIST_H
|
||||
|
||||
#include "SqlAstNode.h"
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class SqlParser;
|
||||
|
||||
namespace SqlAst {
|
||||
|
||||
class SelectListEntry;
|
||||
|
||||
class SelectList: public Node {
|
||||
public:
|
||||
using EntrySPtr = std::shared_ptr<SelectListEntry>;
|
||||
|
||||
void add(EntrySPtr entry)
|
||||
{
|
||||
entryList.push_back(entry);
|
||||
}
|
||||
|
||||
private:
|
||||
using EntryList = std::vector<EntrySPtr>;
|
||||
|
||||
EntryList entryList;
|
||||
};
|
||||
|
||||
std::shared_ptr<SqlAst::SelectList> parseSelectList(SqlParser &parser);
|
||||
|
||||
}
|
||||
|
||||
#endif // SQLASTSELECTLIST_H
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#include "SqlAstSelectListEntry.h"
|
||||
#include "SqlAstExpression.h"
|
||||
#include "SqlParser.h"
|
||||
|
||||
using namespace SqlAst;
|
||||
|
||||
std::shared_ptr<SelectListEntry> parseSelectListEntry(SqlParser &parser)
|
||||
{
|
||||
|
||||
// parse expression
|
||||
auto ast_expr = parseExpression(parser);
|
||||
|
||||
if (parser.consumeOptionalKeyword(Keyword::As)) {
|
||||
// alias required!
|
||||
auto token = parser.expectSymbol();
|
||||
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
// optional alias
|
||||
|
||||
}
|
||||
// can come three groups of things:
|
||||
// - AS keyword, alias should follow, followed by comma
|
||||
// - a symbol ie an alias followed by comma
|
||||
// - something else ie comma, FROM or INTO or... is something one of the callers should figure out as long as we have valid
|
||||
// selectElem we are happy
|
||||
|
||||
|
||||
auto ast = std::make_shared<SelectListEntry>();
|
||||
|
||||
return ast;
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef SQLASTSELECTLISTENTRY_H
|
||||
#define SQLASTSELECTLISTENTRY_H
|
||||
|
||||
#include "SqlAstNode.h"
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
class SqlParser;
|
||||
|
||||
namespace SqlAst {
|
||||
|
||||
class Expression;
|
||||
|
||||
class SelectListEntry: public Node {
|
||||
public:
|
||||
void setExpression(std::shared_ptr<Expression> expr) { this->expression = expr; }
|
||||
void setAlias(QString a) { this->alias = alias; }
|
||||
private:
|
||||
std::shared_ptr<Expression> expression;
|
||||
QString alias;
|
||||
};
|
||||
|
||||
std::shared_ptr<SqlAst::SelectListEntry> parseSelectListEntry(SqlParser &parser);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif // SQLASTSELECTLISTENTRY_H
|
||||
|
|
@ -79,147 +79,119 @@ bool SqlLexer::nextBasicToken(int &startpos, int &length, BasicTokenType &tokent
|
|||
while (true) {
|
||||
startpos = m_pos;
|
||||
QChar c = nextChar();
|
||||
// if (LexerState::Null == m_state) {
|
||||
if (c == '\n') {
|
||||
if (m_returnWhitespace) {
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::NewLine;
|
||||
out = "\n";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (c.isSpace()) {
|
||||
// Just skip whitespace
|
||||
if (m_returnWhitespace) {
|
||||
for (;;) {
|
||||
c = peekChar();
|
||||
if (c != QChar::Null && c.isSpace() && c != '\n')
|
||||
nextChar();
|
||||
else
|
||||
break;
|
||||
}
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::WhiteSpace;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (c == '-' && peekChar() == '-') { // two dashes, start of comment
|
||||
// Loop till end of line or end of block
|
||||
c = nextChar();
|
||||
for (;;) {
|
||||
c = peekChar();
|
||||
if (c != QChar::Null && c != '\n')
|
||||
nextChar();
|
||||
else
|
||||
break;
|
||||
}
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Comment;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
else if (c == ':') {
|
||||
c = peekChar();
|
||||
if (c == ':') {
|
||||
nextChar();
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Cast;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (isSelf(c)) {
|
||||
length = m_pos - startpos;
|
||||
if (c == ',')
|
||||
tokentype = BasicTokenType::Comma;
|
||||
else
|
||||
tokentype = BasicTokenType::Self;
|
||||
|
||||
out = m_block.mid(startpos, length);
|
||||
if (c == '\n') {
|
||||
if (m_returnWhitespace) {
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::NewLine;
|
||||
out = "\n";
|
||||
return true;
|
||||
}
|
||||
else if (isOperatorChar(c)) {
|
||||
while (true) {
|
||||
QChar c = peekChar();
|
||||
if (isOperatorChar(c)) {
|
||||
nextChar();
|
||||
}
|
||||
else {
|
||||
// unexpected end, pretend nothings wrong
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Operator;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '\'') {
|
||||
// Single quoted string so it's an SQL text literal
|
||||
if (parseSingleQuotedString(startpos, length, tokentype)) {
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (c == '"') {
|
||||
// Double quoted identifier
|
||||
if (parseDoubleQuotedIdentifier(startpos, length, tokentype)) {
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// else if (c == '/' && peekChar() == '*') {
|
||||
// nextChar();
|
||||
// m_state = LexerState::InBlockComment;
|
||||
// }
|
||||
else if (c == QChar::Null) {
|
||||
length = 0;
|
||||
tokentype = BasicTokenType::End;
|
||||
return true;
|
||||
}
|
||||
else if (c == '$') {
|
||||
return parseDollarQuote(startpos, length, tokentype, out);
|
||||
}
|
||||
else {
|
||||
// Undetermined symbol
|
||||
for (;;) {
|
||||
c = peekChar();
|
||||
if (c.isLetterOrNumber() || c == '_')
|
||||
nextChar();
|
||||
else
|
||||
break;
|
||||
}
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Symbol;
|
||||
}
|
||||
else if (c.isSpace()) {
|
||||
// Just skip whitespace
|
||||
if (m_returnWhitespace) {
|
||||
for (;;) {
|
||||
c = peekChar();
|
||||
if (c != QChar::Null && c.isSpace() && c != '\n')
|
||||
nextChar();
|
||||
else
|
||||
break;
|
||||
}
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::WhiteSpace;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
// }
|
||||
// else if (LexerState::InBlockComment == m_state) {
|
||||
// if (c == QChar::Null) {
|
||||
// // eof current buffer, we need to return state so
|
||||
// if (m_pos == startpos) {
|
||||
// break;
|
||||
// }
|
||||
// else {
|
||||
// length = m_pos - startpos;
|
||||
// tokentype = BasicTokenType::OpenBlockComment;
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// else if (c == '*') {
|
||||
// nextChar();
|
||||
// if (peekChar() == '/') {
|
||||
// nextChar();
|
||||
// length = m_pos - startpos;
|
||||
// tokentype = BasicTokenType::BlockComment;
|
||||
// m_state = LexerState::Null;
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
else if (c == '-' && peekChar() == '-') { // two dashes, start of comment
|
||||
// Loop till end of line or end of block
|
||||
c = nextChar();
|
||||
for (;;) {
|
||||
c = peekChar();
|
||||
if (c != QChar::Null && c != '\n')
|
||||
nextChar();
|
||||
else
|
||||
break;
|
||||
}
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Comment;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
else if (c == ':') {
|
||||
c = peekChar();
|
||||
if (c == ':') {
|
||||
nextChar();
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Cast;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (isSelf(c)) {
|
||||
length = m_pos - startpos;
|
||||
if (c == ',')
|
||||
tokentype = BasicTokenType::Comma;
|
||||
else
|
||||
tokentype = BasicTokenType::Self;
|
||||
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
else if (isOperatorChar(c)) {
|
||||
while (true) {
|
||||
QChar c = peekChar();
|
||||
if (isOperatorChar(c)) {
|
||||
nextChar();
|
||||
}
|
||||
else {
|
||||
// unexpected end, pretend nothings wrong
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Operator;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == '\'') {
|
||||
// Single quoted string so it's an SQL text literal
|
||||
if (parseSingleQuotedString(startpos, length, tokentype)) {
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (c == '"') {
|
||||
// Double quoted identifier
|
||||
if (parseDoubleQuotedIdentifier(startpos, length, tokentype)) {
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (c == QChar::Null) {
|
||||
length = 0;
|
||||
tokentype = BasicTokenType::End;
|
||||
return true;
|
||||
}
|
||||
else if (c == '$') {
|
||||
return parseDollarQuote(startpos, length, tokentype, out);
|
||||
}
|
||||
else {
|
||||
// Undetermined symbol
|
||||
for (;;) {
|
||||
c = peekChar();
|
||||
if (c.isLetterOrNumber() || c == '_')
|
||||
nextChar();
|
||||
else
|
||||
break;
|
||||
}
|
||||
length = m_pos - startpos;
|
||||
tokentype = BasicTokenType::Symbol;
|
||||
out = m_block.mid(startpos, length);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -298,11 +270,9 @@ bool SqlLexer::parseDollarQuote(int startpos, int &length, BasicTokenType &token
|
|||
}
|
||||
|
||||
if (c.isLetter()) {
|
||||
// is this a dollar quote?
|
||||
while (true) {
|
||||
c = nextChar();
|
||||
if (c == '$') {
|
||||
// Found valid dollar quote
|
||||
tokentype = BasicTokenType::DollarQuote;
|
||||
length = m_pos - startpos;
|
||||
out = m_block.mid(startpos, length);
|
||||
|
|
@ -310,7 +280,6 @@ bool SqlLexer::parseDollarQuote(int startpos, int &length, BasicTokenType &token
|
|||
}
|
||||
|
||||
if (!c.isLetter()) {
|
||||
// ERROR, unallowed character
|
||||
tokentype = BasicTokenType::None;
|
||||
length = m_pos - startpos;
|
||||
out = m_block.mid(startpos, length);
|
||||
|
|
|
|||
|
|
@ -1,81 +0,0 @@
|
|||
#include "SqlParser.h"
|
||||
#include "SqlAstSelect.h"
|
||||
#include <stdexcept>
|
||||
#include <unordered_map>
|
||||
|
||||
using namespace SqlAst;
|
||||
|
||||
Keyword isKeyword(const QString &symbol)
|
||||
{
|
||||
static std::unordered_map<std::string, Keyword> lookup_map = {
|
||||
{ "as", Keyword::As },
|
||||
{ "by", Keyword::By },
|
||||
{ "delete", Keyword::Delete },
|
||||
{ "from", Keyword::From },
|
||||
{ "group", Keyword::Group },
|
||||
{ "insert", Keyword::Insert },
|
||||
{ "order", Keyword::Order },
|
||||
{ "select", Keyword::Select },
|
||||
{ "update", Keyword::Update },
|
||||
{ "where", Keyword::Where }
|
||||
};
|
||||
|
||||
auto res = lookup_map.find(symbol.toLower().toUtf8().data());
|
||||
if (res != lookup_map.end())
|
||||
return res->second;
|
||||
|
||||
return Keyword::NotAKeyword;
|
||||
}
|
||||
|
||||
|
||||
SqlParser::SqlParser(SqlLexer &lexer)
|
||||
: lexer(lexer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<SqlAst::Node> SqlParser::parse()
|
||||
{
|
||||
// Basic algo:
|
||||
// LOOP
|
||||
// GET token
|
||||
// IF NOT try_reduce(token)
|
||||
// THEN SHIFT
|
||||
// END LOOP
|
||||
std::shared_ptr<SqlAst::Node> result;
|
||||
while (true) {
|
||||
SqlToken token = lexer.nextBasicToken();
|
||||
if (token.ok) {
|
||||
if (token.tokenType == BasicTokenType::Symbol) {
|
||||
Keyword kw = isKeyword(token.out);
|
||||
switch (kw) {
|
||||
case Keyword::Select:
|
||||
parseSelect(*this);
|
||||
break;
|
||||
|
||||
case Keyword::NotAKeyword:
|
||||
default:
|
||||
// unexpected
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (token.tokenType == BasicTokenType::End) {
|
||||
// Are we at the top level?
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// error during lexical analysis, need to recover
|
||||
throw std::runtime_error("Unrecognized input");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//bool try_reduce(SqkToken token)
|
||||
//{
|
||||
// // what state are we in? what are we expecting
|
||||
|
||||
//}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
#ifndef SQLPARSER_H
|
||||
#define SQLPARSER_H
|
||||
|
||||
#include "SqlLexer.h"
|
||||
#include "SqlAstNode.h"
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
enum class Keyword {
|
||||
NotAKeyword,
|
||||
As,
|
||||
By,
|
||||
Delete,
|
||||
From,
|
||||
Group,
|
||||
Insert,
|
||||
Order,
|
||||
Select,
|
||||
Update,
|
||||
Where,
|
||||
|
||||
};
|
||||
|
||||
namespace SqlAst {
|
||||
|
||||
class Node;
|
||||
class Select;
|
||||
class SelectList;
|
||||
|
||||
}
|
||||
// The parsing works by calling functions that know either a global part
|
||||
// or a smaller specific part and is thus recursive. At certain points a function parsing something specific
|
||||
// will reach a point where it is in a valid terminal state and it encounters something that cannot be a continuation
|
||||
// of what it is parsing and thus returns succesfully or it is in a non terminal state and encounters something unexpected
|
||||
// In both cases it will return hoping that one of the functions above can continue (and recover from the error if needed)
|
||||
|
||||
class SqlParser
|
||||
{
|
||||
public:
|
||||
explicit SqlParser(SqlLexer &lexer);
|
||||
|
||||
std::shared_ptr<SqlAst::Node> parse();
|
||||
|
||||
/** Checks to see if the next token is the expected keyword.
|
||||
*
|
||||
* If it is the token is consumed and the function returns true.
|
||||
* Otherwise false is returned
|
||||
*/
|
||||
std::optional<SqlToken> expectKeyword(Keyword kw);
|
||||
std::optional<SqlToken> expectSymbol();
|
||||
std::optional<SqlToken> expectToken(BasicTokenType tt);
|
||||
|
||||
/** If the next token is Keyword kw consume it otherwise do nothing.
|
||||
* In some cases the return value is unimportant as the keyword is completely optional
|
||||
* in other cases the optional keywords presence might force the next token to be something specific
|
||||
*
|
||||
* \return true if the token was found
|
||||
*/
|
||||
bool consumeOptionalKeyword(Keyword kw);
|
||||
private:
|
||||
|
||||
//using TokenStack = std::stack<SqlToken>;
|
||||
|
||||
//TokenStack tokenStack;
|
||||
|
||||
SqlLexer &lexer;
|
||||
|
||||
//bool try_reduce(SqkToken token);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // SQLPARSER_H
|
||||
|
|
@ -26,15 +26,8 @@ SOURCES += my_boost_assert_handler.cpp \
|
|||
PasswordManager.cpp \
|
||||
CsvWriter.cpp \
|
||||
BackupFormatModel.cpp \
|
||||
QueuedBackgroundTask.cpp \
|
||||
ExplainTreeModelItem.cpp \
|
||||
jsoncpp.cpp \
|
||||
SqlParser.cpp \
|
||||
SqlAstNode.cpp \
|
||||
SqlAstSelectList.cpp \
|
||||
SqlAstSelectListEntry.cpp \
|
||||
SqlAstSelect.cpp \
|
||||
SqlAstExpression.cpp
|
||||
jsoncpp.cpp
|
||||
|
||||
HEADERS += PasswordManager.h \
|
||||
KeyStrengthener.h \
|
||||
|
|
@ -42,16 +35,9 @@ HEADERS += PasswordManager.h \
|
|||
ScopeGuard.h \
|
||||
CsvWriter.h \
|
||||
BackupFormatModel.h \
|
||||
QueuedBackgroundTask.h \
|
||||
Expected.h \
|
||||
ExplainTreeModelItem.h \
|
||||
json/json.h \
|
||||
SqlParser.h \
|
||||
SqlAstNode.h \
|
||||
SqlAstSelectList.h \
|
||||
SqlAstSelectListEntry.h \
|
||||
SqlAstSelect.h \
|
||||
SqlAstExpression.h \
|
||||
std_utils.h \
|
||||
IntegerRange.h
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue