Commit c9887805 authored by Camilo Higuita's avatar Camilo Higuita

initial work on the db schema and dbactions and add mauikit as submodule

parent 38686125
......@@ -10,9 +10,13 @@ DEFINES += QT_DEPRECATED_WARNINGS
include(mauikit/mauikit.pri)
SOURCES += \
main.cpp
main.cpp \
src/db/db.cpp \
src/db/dbactions.cpp \
src/buho.cpp
RESOURCES += qml.qrc
RESOURCES += \
qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
......@@ -40,3 +44,13 @@ linux:unix:!android {
message("Unknown configuration")
}
DISTFILES += \
src/db/script.sql \
src/utils/owl.js
HEADERS += \
src/db/db.h \
src/db/dbactions.h \
src/buho.h \
src/utils/owl.h
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickStyle>
#include <QQmlContext>
#ifdef STATIC_KIRIGAMI
#include "3rdparty/kirigami/src/kirigamiplugin.h"
......@@ -14,6 +16,7 @@
#endif
#include "mauikit/src/mauikit.h"
#include "src/buho.h"
int main(int argc, char *argv[])
{
......@@ -23,7 +26,6 @@ int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QIcon::setThemeName("Luv");
QQuickStyle::setStyle("material");
#else
QApplication app(argc, argv);
#endif
......@@ -36,7 +38,12 @@ int main(int argc, char *argv[])
MauiKit::getInstance().registerTypes();
#endif
Buho owl;
QQmlApplicationEngine engine;
auto context = engine.rootContext();
context->setContextProperty("owl", &owl);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
......
......@@ -3,6 +3,8 @@ import QtQuick.Controls 2.2
import org.kde.kirigami 2.0 as Kirigami
import org.kde.maui 1.0 as Maui
import "src/widgets"
Maui.ApplicationWindow
{
id: root
......@@ -10,7 +12,6 @@ Maui.ApplicationWindow
headBar.middleContent: Row
{
anchors.centerIn: parent
spacing: space.medium
Maui.ToolButton
{
......@@ -39,16 +40,19 @@ Maui.ApplicationWindow
{
id: addButton
iconName: "list-add"
anchors.centerIn: parent
model: ListModel
{
ListElement {iconName: "document-new"}
ListElement {iconName: "link"}
ListElement {iconName: "draw-text"}
ListElement {iconName: "link"}
ListElement {iconName: "view-list-details"}
ListElement {iconName: "document-new"; mid: "page"}
ListElement {iconName: "link"; mid: "link"}
ListElement {iconName: "draw-text"; mid: "note"}
ListElement {iconName: "view-list-details"; mid: "todo"}
}
onItemClicked:
{
if(item.mid === "note")
newNoteDialog.open()
}
}
......@@ -62,4 +66,12 @@ Maui.ApplicationWindow
iconName: "archive-remove"
}
/***** COMPONENTS *****/
NewNoteDialog
{
id: newNoteDialog
}
}
mauikit @ d6ce8b86
Subproject commit 188a8b9e78cea9b94fdfb567f0215adb97f1de45
Subproject commit d6ce8b868cb3be4ba44ef46591de6ee89788a2a2
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>src/db/script.sql</file>
<file>src/widgets/NewNoteDialog.qml</file>
</qresource>
</RCC>
#include "buho.h"
Buho::Buho(QObject *parent) : DBActions(parent)
{
this->setFolders();
}
void Buho::setFolders()
{
QDir notes_path(OWL::NotesPath);
if (!notes_path.exists())
notes_path.mkpath(".");
QDir links_path(OWL::LinksPath);
if (!links_path.exists())
links_path.mkpath(".");
QDir books_path(OWL::BooksPath);
if (!books_path.exists())
books_path.mkpath(".");
}
#ifndef BUHO_H
#define BUHO_H
#include <QObject>
#include "db/dbactions.h"
class Buho : public DBActions
{
Q_OBJECT
public:
explicit Buho(QObject *parent = nullptr);
private:
void setFolders();
signals:
public slots:
};
#endif // BUHO_H
/***
Pix Copyright (C) 2018 Camilo Higuita
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "db.h"
#include <QUuid>
#include <QString>
#include <QStringList>
#include <QSqlQuery>
DB::DB(QObject *parent) : QObject(parent)
{
QDir collectionDBPath_dir(OWL::CollectionDBPath);
if (!collectionDBPath_dir.exists())
collectionDBPath_dir.mkpath(".");
this->name = QUuid::createUuid().toString();
if(!OWL::fileExists(OWL::CollectionDBPath + OWL::DBName))
{
this->openDB(this->name);
qDebug()<<"Collection doesn't exists, trying to create it" << OWL::CollectionDBPath + OWL::DBName;
this->prepareCollectionDB();
}else this->openDB(this->name);
}
DB::~DB()
{
this->m_db.close();
}
void DB::openDB(const QString &name)
{
if(!QSqlDatabase::contains(name))
{
this->m_db = QSqlDatabase::addDatabase(QStringLiteral("QSQLITE"), name);
this->m_db.setDatabaseName(OWL::CollectionDBPath + OWL::DBName);
}
if (!this->m_db.isOpen())
{
if(!this->m_db.open())
qDebug()<<"ERROR OPENING DB"<<this->m_db.lastError().text()<<m_db.connectionName();
}
auto query = this->getQuery("PRAGMA synchronous=OFF");
query.exec();
}
void DB::prepareCollectionDB() const
{
QSqlQuery query(this->m_db);
QFile file(":/src/db/script.sql");
if (!file.exists())
{
QString log = QStringLiteral("Fatal error on build database. The file '");
log.append(file.fileName() + QStringLiteral("' for database and tables creation query cannot be not found!"));
qDebug()<<log;
return;
}
if (!file.open(QIODevice::ReadOnly))
{
qDebug()<<QStringLiteral("Fatal error on try to create database! The file with sql queries for database creation cannot be opened!");
return;
}
bool hasText;
QString line;
QByteArray readLine;
QString cleanedLine;
QStringList strings;
while (!file.atEnd())
{
hasText = false;
line = "";
readLine = "";
cleanedLine = "";
strings.clear();
while (!hasText)
{
readLine = file.readLine();
cleanedLine = readLine.trimmed();
strings = cleanedLine.split("--");
cleanedLine = strings.at(0);
if (!cleanedLine.startsWith("--") && !cleanedLine.startsWith("DROP") && !cleanedLine.isEmpty())
line += cleanedLine;
if (cleanedLine.endsWith(";"))
break;
if (cleanedLine.startsWith("COMMIT"))
hasText = true;
}
if (!line.isEmpty())
{
if (!query.exec(line))
{
qDebug()<<"exec failed"<<query.lastQuery()<<query.lastError();
}
} else qDebug()<<"exec wrong"<<query.lastError();
}
file.close();
}
bool DB::checkExistance(const QString &tableName, const QString &searchId, const QString &search)
{
auto queryStr = QString("SELECT %1 FROM %2 WHERE %3 = \"%4\"").arg(searchId, tableName, searchId, search);
auto query = this->getQuery(queryStr);
if (query.exec())
{
if (query.next()) return true;
}else qDebug()<<query.lastError().text();
return false;
}
QSqlQuery DB::getQuery(const QString &queryTxt)
{
QSqlQuery query(queryTxt, this->m_db);
return query;
}
bool DB::insert(const QString &tableName, const QVariantMap &insertData)
{
if (tableName.isEmpty())
{
qDebug()<<QStringLiteral("Fatal error on insert! The table name is empty!");
return false;
} else if (insertData.isEmpty())
{
qDebug()<<QStringLiteral("Fatal error on insert! The insertData is empty!");
return false;
}
QStringList strValues;
QStringList fields = insertData.keys();
QVariantList values = insertData.values();
int totalFields = fields.size();
for (int i = 0; i < totalFields; ++i)
strValues.append("?");
QString sqlQueryString = "INSERT INTO " + tableName + " (" + QString(fields.join(",")) + ") VALUES(" + QString(strValues.join(",")) + ")";
QSqlQuery query(this->m_db);
query.prepare(sqlQueryString);
int k = 0;
foreach (const QVariant &value, values)
query.bindValue(k++, value);
return query.exec();
}
bool DB::update(const QString &tableName, const OWL::DB &updateData, const QVariantMap &where)
{
if (tableName.isEmpty())
{
qDebug()<<QStringLiteral("Fatal error on insert! The table name is empty!");
return false;
} else if (updateData.isEmpty())
{
qDebug()<<QStringLiteral("Fatal error on insert! The insertData is empty!");
return false;
}
QStringList set;
for (auto key : updateData.keys())
set.append(OWL::KEYMAP[key]+" = '"+updateData[key]+"'");
QStringList condition;
for (auto key : where.keys())
condition.append(key+" = '"+where[key].toString()+"'");
QString sqlQueryString = "UPDATE " + tableName + " SET " + QString(set.join(",")) + " WHERE " + QString(condition.join(",")) ;
auto query = this->getQuery(sqlQueryString);
qDebug()<<sqlQueryString;
return query.exec();
}
bool DB::update(const QString &table, const QString &column, const QVariant &newValue, const QVariant &op, const QString &id)
{
auto queryStr = QString("UPDATE %1 SET %2 = \"%3\" WHERE %4 = \"%5\"").arg(table, column, newValue.toString().replace("\"","\"\""), op.toString(), id);
auto query = this->getQuery(queryStr);
return query.exec();
}
bool DB::remove(const QString &tableName, const OWL::DB &removeData)
{
if (tableName.isEmpty())
{
qDebug()<<QStringLiteral("Fatal error on removing! The table name is empty!");
return false;
} else if (removeData.isEmpty())
{
qDebug()<<QStringLiteral("Fatal error on insert! The removeData is empty!");
return false;
}
QString strValues;
auto i = 0;
for (auto key : removeData.keys())
{
strValues.append(QString("%1 = \"%2\"").arg(OWL::KEYMAP[key], removeData[key]));
i++;
if(removeData.keys().size() > 1 && i<removeData.keys().size())
strValues.append(" AND ");
}
QString sqlQueryString = "DELETE FROM " + tableName + " WHERE " + strValues;
qDebug()<< sqlQueryString;
return this->getQuery(sqlQueryString).exec();
}
/***
Pix Copyright (C) 2018 Camilo Higuita
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef DB_H
#define DB_H
#include <QObject>
#include <QString>
#include <QStringList>
#include <QList>
#include <QSqlDatabase>
#include <QDebug>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
#include <QSqlDriver>
#include <QFileInfo>
#include <QDir>
#include <QVariantMap>
#include "../utils/owl.h"
class DB : public QObject
{
Q_OBJECT
private:
QString name;
QSqlDatabase m_db;
public:
explicit DB(QObject *parent = nullptr);
~ DB();
void openDB(const QString &name);
/*basic public actions*/
void prepareCollectionDB() const;
/* utils*/
Q_INVOKABLE bool checkExistance(const QString &tableName, const QString &searchId, const QString &search);
protected:
QSqlQuery getQuery(const QString &queryTxt);
bool insert(const QString &tableName, const QVariantMap &insertData);
bool update(const QString &tableName, const OWL::DB &updateData, const QVariantMap &where);
bool update(const QString &table, const QString &column, const QVariant &newValue, const QVariant &op, const QString &id);
bool remove(const QString &tableName, const OWL::DB &removeData);
signals:
public slots:
};
#endif // DB_H
/***
Buho Copyright (C) 2018 Camilo Higuita
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#include "dbactions.h"
#include <QJsonDocument>
#include <QVariantMap>
#include <QUuid>
#include <QDateTime>
DBActions::DBActions(QObject *parent) : DB(parent)
{
qDebug() << "Getting collectionDB info from: " << OWL::CollectionDBPath;
qDebug()<< "Starting DBActions";
}
DBActions::~DBActions() {}
OWL::DB_LIST DBActions::getDBData(const QString &queryTxt)
{
OWL::DB_LIST mapList;
auto query = this->getQuery(queryTxt);
if(query.exec())
{
while(query.next())
{
OWL::DB data;
for(auto key : OWL::KEYMAP.keys())
if(query.record().indexOf(OWL::KEYMAP[key])>-1)
data.insert(key, query.value(OWL::KEYMAP[key]).toString());
mapList<< data;
}
}else qDebug()<< query.lastError()<< query.lastQuery();
return mapList;
}
QVariantList DBActions::get(const QString &queryTxt)
{
QVariantList mapList;
auto query = this->getQuery(queryTxt);
if(query.exec())
{
while(query.next())
{
QVariantMap data;
for(auto key : OWL::KEYMAP.keys())
if(query.record().indexOf(OWL::KEYMAP[key])>-1)
data[OWL::KEYMAP[key]] = query.value(OWL::KEYMAP[key]).toString();
mapList<< data;
}
}else qDebug()<< query.lastError()<< query.lastQuery();
return mapList;
}
bool DBActions::insertNote(const QString &title, const QString &body, const QString &color, const QString &tags)
{
QVariantMap json_note =
{
{OWL::SLANG[OWL::W::TITLE], title},
{OWL::SLANG[OWL::W::BODY], body}
};
auto json = QJsonDocument::fromVariant(json_note);
auto note_url = OWL::NotesPath+title+QUuid::createUuid().toString();
OWL::saveJson(json, note_url);
QVariantMap note_map =
{
{OWL::KEYMAP[OWL::KEY::URL], note_url},
{OWL::KEYMAP[OWL::KEY::COLOR], color},
{OWL::KEYMAP[OWL::KEY::ADD_DATE], QDateTime::currentDateTime()}
};
if(!tags.isEmpty())
{
for(auto tag : tags.split(","))
{
this->insert(OWL::TABLEMAP[OWL::TABLE::TAGS], {{OWL::KEYMAP[OWL::KEY::TAG], tag}});
this->insert(OWL::TABLEMAP[OWL::TABLE::NOTES_TAGS],
{
{OWL::KEYMAP[OWL::KEY::TAG], tag},
{OWL::KEYMAP[OWL::KEY::URL], note_url}
});
}
}
return this->insert(OWL::TABLEMAP[OWL::TABLE::NOTES], note_map);
}
bool DBActions::execQuery(const QString &queryTxt)
{
auto query = this->getQuery(queryTxt);
return query.exec();
}
/***
Buho Copyright (C) 2018 Camilo Higuita
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
***/
#ifndef DBACTIONS_H
#define DBACTIONS_H
#include <QObject>
#include "db.h"
class DBActions : public DB
{
Q_OBJECT
public:
explicit DBActions(QObject *parent = nullptr);
~DBActions();
Q_INVOKABLE QVariantList get(const QString &queryTxt);
/*main actions*/
Q_INVOKABLE bool insertNote(const QString &title, const QString &body, const QString &color = QString(), const QString &tags = QString());
protected:
OWL::DB_LIST getDBData(const QString &queryTxt);
bool execQuery(const QString &queryTxt);
signals:
void tagAdded(QString tag);
};
#endif // DBACTIONS_H
CREATE TABLE IF NOT EXISTS NOTES (
url TEXT PRIMARY KEY,
color TEXT,
addDate DATE
);
CREATE TABLE IF NOT EXISTS TAGS (
tag TEXT PRIMARY KEY
);
CREATE TABLE IF NOT EXISTS BOOKS (
url TEXT PRIMARY KEY,
title TEXT NOT NULL,
fav INTEGER NOT NULL,
addDate DATE
);
CREATE TABLE IF NOT EXISTS NOTES_TAGS (
tag TEXT NOT NULL,
url TEXT NOT NULL,
PRIMARY KEY (tag, url),
FOREIGN KEY(tag) REFERENCES TAGS(tag),
FOREIGN KEY(url) REFERENCES NOTES(url)
);
#ifndef OWL_H
#define OWL_H
#include <QString>
#include <QDebug>
#include <QStandardPaths>
#include <QFileInfo>
#include <QImage>
#include <QTime>
#include <QSettings>
#include <QDirIterator>
#include <QVariantList>
#include <QJsonDocument>
#include <QJsonObject>
namespace OWL
{
Q_NAMESPACE
enum class W : uint8_t
{
TITLE,
BODY,
IMAGE,
VIDEO,
LINK,
TAG,
AUTHOR,
DATE
};
static const QMap<W, QString> SLANG =
{
{W::TITLE, "title"},
{W::BODY, "body"},
{W::IMAGE, "image"},
{W::VIDEO, "video"},
{W::LINK, "link"},
{W::TAG, "tag"},
{W::AUTHOR, "author"},
{W::DATE, "date"}
};
enum class TABLE : uint8_t
{
NOTES,
NOTES_TAGS,
TAGS,
BOOKS,
PAGES,
BOOKS_PAGES,
LINKS,
LINKS_TAGS,
PAGES_TAGS,
NONE
};
static const QMap<TABLE,QString> TABLEMAP =
{
{TABLE::NOTES,"notes"},
{TABLE::NOTES_TAGS,"notes_tags"},
{TABLE::TAGS,"tags"},
{TABLE::BOOKS,"books"},
{TABLE::PAGES,"pages"},
{TABLE::BOOKS_PAGES,"books_pages"},