Big cleanup

This commit is contained in:
eelke 2022-05-26 08:25:31 +02:00
parent d3080a08bb
commit 8b671090a0
55 changed files with 214 additions and 3967 deletions

View file

@ -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());

View file

@ -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;

View file

@ -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"
//}

View file

@ -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 {

View file

@ -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"

View file

@ -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";

View file

@ -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);
}
}

View file

@ -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( );
//};

View file

@ -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;
}

View file

@ -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

View file

@ -1,5 +0,0 @@
#include "SqlAstNode.h"
using namespace SqlAst;
Node::Node() = default;

View file

@ -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

View file

@ -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;
}
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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
//}

View file

@ -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

View file

@ -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