Let's make (git) history!
这个提交包含在:
26
database/categorydao.cpp
普通文件
26
database/categorydao.cpp
普通文件
@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "categorydao.h"
|
||||
|
||||
CategoryDao::CategoryDao()
|
||||
{
|
||||
|
||||
}
|
21
database/categorydao.h
普通文件
21
database/categorydao.h
普通文件
@ -0,0 +1,21 @@
|
||||
#ifndef CATEGORYDAO_H
|
||||
#define CATEGORYDAO_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include "queryoption.h"
|
||||
#include "../category.h"
|
||||
|
||||
class CategoryDao
|
||||
{
|
||||
public:
|
||||
CategoryDao();
|
||||
virtual void save(const Category &c) = 0;
|
||||
virtual std::vector<std::string> fetchList(QueryOption o) = 0;
|
||||
virtual std::optional<Category> find(std::string name) = 0;
|
||||
virtual void deleteCategory(std::string name) = 0;
|
||||
virtual std::vector<std::string> fetchMembers(std::string name, QueryOption o) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // CATEGORYDAO_H
|
118
database/categorydaosqlite.cpp
普通文件
118
database/categorydaosqlite.cpp
普通文件
@ -0,0 +1,118 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "categorydaosqlite.h"
|
||||
#include "sqlitequeryoption.h"
|
||||
CategoryDaoSqlite::CategoryDaoSqlite()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::optional<Category> CategoryDaoSqlite::find(std::string name)
|
||||
{
|
||||
try {
|
||||
Category result;
|
||||
*db << "SELECT id, name FROM category WHERE name = ?" << name >> std::tie(result.id, result.name);
|
||||
return result;
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
|
||||
void CategoryDaoSqlite::save(const Category &c)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
*db << "INSERT OR IGNORE INTO category (id, name) VALUES (SELECT id FROM category WHERE lower(name) = lower(?), lower(?)" <<c.name << c.name;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
|
||||
void CategoryDaoSqlite::deleteCategory(std::string name)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
*db << "BEGIN";
|
||||
*db << "DELETE FROM categorymember WHERE catid = (SELECT id FROM category WHERE name = ?)" << name;
|
||||
*db << "DELETE FROM category WHERE name = ?" << name;
|
||||
*db << "COMMIT;";
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> CategoryDaoSqlite::fetchList(QueryOption o)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
try
|
||||
{
|
||||
auto queryoption = SqliteQueryOption(o).setPrependWhere(true).setOrderByColumn("name").build();
|
||||
*db << "SELECT name FROM category " + queryoption >> [&](std::string n) { result.push_back(n);};
|
||||
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
catch(const sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
std::vector<std::string> CategoryDaoSqlite::fetchMembers(std::string name, QueryOption o)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
SqliteQueryOption queryOption { o };
|
||||
std::string queryoptions = queryOption.setOrderByColumn("name").setVisibleColumnName("page.visible").setPrependWhere(false).build();
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
auto query = *db << "SELECT page.name AS name FROM categorymember INNER JOIN page ON page.id = categorymember.page WHERE category = (SELECT id FROM category WHERE name = ? ) AND " + queryoptions << name;
|
||||
query >> [&](std::string p) { result.push_back(p);};
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
18
database/categorydaosqlite.h
普通文件
18
database/categorydaosqlite.h
普通文件
@ -0,0 +1,18 @@
|
||||
#ifndef CATEGORYDAOSQLITE_H
|
||||
#define CATEGORYDAOSQLITE_H
|
||||
|
||||
#include "categorydao.h"
|
||||
#include "sqlitedao.h"
|
||||
class CategoryDaoSqlite : public CategoryDao, protected SqliteDao
|
||||
{
|
||||
public:
|
||||
CategoryDaoSqlite();
|
||||
std::vector<std::string> fetchList(QueryOption o) override;
|
||||
std::vector<std::string> fetchMembers(std::string name, QueryOption o) override;
|
||||
void save(const Category &c) override;
|
||||
void deleteCategory(std::string name) override;
|
||||
std::optional<Category> find(std::string name) override;
|
||||
using SqliteDao::SqliteDao;
|
||||
};
|
||||
|
||||
#endif // CATEGORYDAOSQLITE_H
|
32
database/database.h
普通文件
32
database/database.h
普通文件
@ -0,0 +1,32 @@
|
||||
#ifndef DATABASE_H
|
||||
#define DATABASE_H
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include "../user.h"
|
||||
#include "../request.h"
|
||||
#include "../response.h"
|
||||
#include "pagedao.h"
|
||||
#include "revisiondao.h"
|
||||
#include "sessiondao.h"
|
||||
#include "userdao.h"
|
||||
#include "categorydao.h"
|
||||
class Database
|
||||
{
|
||||
private:
|
||||
std::string connnectionstring;
|
||||
public:
|
||||
Database() { }
|
||||
Database(std::string connstring) { this->connnectionstring = connstring; }
|
||||
|
||||
virtual void beginTransaction() = 0;
|
||||
virtual void rollbackTransaction() = 0;
|
||||
virtual void commitTransaction() = 0;
|
||||
virtual std::unique_ptr<PageDao> createPageDao() const = 0;
|
||||
virtual std::unique_ptr<RevisionDao> createRevisionDao() const = 0;
|
||||
virtual std::unique_ptr<SessionDao> createSessionDao() const = 0;
|
||||
virtual std::unique_ptr<UserDao> createUserDao() const = 0;
|
||||
virtual std::unique_ptr<CategoryDao> createCategoryDao() const = 0;
|
||||
virtual ~Database() { }
|
||||
};
|
||||
|
||||
#endif
|
26
database/databasefactory.cpp
普通文件
26
database/databasefactory.cpp
普通文件
@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "databasefactory.h"
|
||||
#include "sqlite.h"
|
||||
std::unique_ptr<Database> createDatabase(const Config &o)
|
||||
{
|
||||
return std::make_unique<Sqlite>(o.connectionstring);
|
||||
}
|
7
database/databasefactory.h
普通文件
7
database/databasefactory.h
普通文件
@ -0,0 +1,7 @@
|
||||
#ifndef DATABASEFACTORY_H
|
||||
#define DATABASEFACTORY_H
|
||||
#include "../config.h"
|
||||
#include "database.h"
|
||||
|
||||
std::unique_ptr<Database> createDatabase(const Config &o);
|
||||
#endif // DATABASEFACTORY_H
|
16
database/exceptions.h
普通文件
16
database/exceptions.h
普通文件
@ -0,0 +1,16 @@
|
||||
#ifndef EXCEPTIONS_H
|
||||
#define EXCEPTIONS_H
|
||||
#include <stdexcept>
|
||||
|
||||
|
||||
class DatabaseException : public std::runtime_error
|
||||
{
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
class DatabaseQueryException : public DatabaseException
|
||||
{
|
||||
using DatabaseException::DatabaseException;
|
||||
};
|
||||
|
||||
#endif // EXCEPTIONS_H
|
1047
database/hdr/sqlite_modern_cpp.h
普通文件
1047
database/hdr/sqlite_modern_cpp.h
普通文件
文件差异内容过多而无法显示
加载差异
@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace sqlite {
|
||||
|
||||
class sqlite_exception: public std::runtime_error {
|
||||
public:
|
||||
sqlite_exception(const char* msg, std::string sql, int code = -1): runtime_error(msg), code(code), sql(sql) {}
|
||||
sqlite_exception(int code, std::string sql): runtime_error(sqlite3_errstr(code)), code(code), sql(sql) {}
|
||||
int get_code() const {return code & 0xFF;}
|
||||
int get_extended_code() const {return code;}
|
||||
std::string get_sql() const {return sql;}
|
||||
private:
|
||||
int code;
|
||||
std::string sql;
|
||||
};
|
||||
|
||||
namespace errors {
|
||||
//One more or less trivial derived error class for each SQLITE error.
|
||||
//Note the following are not errors so have no classes:
|
||||
//SQLITE_OK, SQLITE_NOTICE, SQLITE_WARNING, SQLITE_ROW, SQLITE_DONE
|
||||
//
|
||||
//Note these names are exact matches to the names of the SQLITE error codes.
|
||||
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
|
||||
class name: public sqlite_exception { using sqlite_exception::sqlite_exception; };\
|
||||
derived
|
||||
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE,SUB,base,sub) \
|
||||
class base ## _ ## sub: public base { using base::base; };
|
||||
#include "lists/error_codes.h"
|
||||
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
|
||||
#undef SQLITE_MODERN_CPP_ERROR_CODE
|
||||
|
||||
//Some additional errors are here for the C++ interface
|
||||
class more_rows: public sqlite_exception { using sqlite_exception::sqlite_exception; };
|
||||
class no_rows: public sqlite_exception { using sqlite_exception::sqlite_exception; };
|
||||
class more_statements: public sqlite_exception { using sqlite_exception::sqlite_exception; }; // Prepared statements can only contain one statement
|
||||
class invalid_utf16: public sqlite_exception { using sqlite_exception::sqlite_exception; };
|
||||
|
||||
static void throw_sqlite_error(const int& error_code, const std::string &sql = "") {
|
||||
switch(error_code & 0xFF) {
|
||||
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
|
||||
case SQLITE_ ## NAME: switch(error_code) { \
|
||||
derived \
|
||||
default: throw name(error_code, sql); \
|
||||
}
|
||||
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE,SUB,base,sub) \
|
||||
case SQLITE_ ## BASE ## _ ## SUB: throw base ## _ ## sub(error_code, sql);
|
||||
#include "lists/error_codes.h"
|
||||
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
|
||||
#undef SQLITE_MODERN_CPP_ERROR_CODE
|
||||
default: throw sqlite_exception(error_code, sql);
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace exceptions = errors;
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
#if SQLITE_VERSION_NUMBER < 3010000
|
||||
#define SQLITE_IOERR_VNODE (SQLITE_IOERR | (27<<8))
|
||||
#define SQLITE_IOERR_AUTH (SQLITE_IOERR | (28<<8))
|
||||
#define SQLITE_AUTH_USER (SQLITE_AUTH | (1<<8))
|
||||
#endif
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(ERROR,error,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(INTERNAL,internal,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(PERM,perm,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(ABORT,abort,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(ABORT,ROLLBACK,abort,rollback)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(BUSY,busy,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BUSY,RECOVERY,busy,recovery)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BUSY,SNAPSHOT,busy,snapshot)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(LOCKED,locked,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(LOCKED,SHAREDCACHE,locked,sharedcache)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(NOMEM,nomem,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(READONLY,readonly,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(INTERRUPT,interrupt,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(IOERR,ioerr,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,READ,ioerr,read)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHORT_READ,ioerr,short_read)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,WRITE,ioerr,write)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,FSYNC,ioerr,fsync)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DIR_FSYNC,ioerr,dir_fsync)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,TRUNCATE,ioerr,truncate)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,FSTAT,ioerr,fstat)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,UNLOCK,ioerr,unlock)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,RDLOCK,ioerr,rdlock)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DELETE,ioerr,delete)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,BLOCKED,ioerr,blocked)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,NOMEM,ioerr,nomem)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,ACCESS,ioerr,access)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,CHECKRESERVEDLOCK,ioerr,checkreservedlock)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,LOCK,ioerr,lock)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,CLOSE,ioerr,close)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DIR_CLOSE,ioerr,dir_close)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMOPEN,ioerr,shmopen)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMSIZE,ioerr,shmsize)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMLOCK,ioerr,shmlock)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SHMMAP,ioerr,shmmap)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,SEEK,ioerr,seek)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,DELETE_NOENT,ioerr,delete_noent)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,MMAP,ioerr,mmap)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,GETTEMPPATH,ioerr,gettemppath)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,CONVPATH,ioerr,convpath)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,VNODE,ioerr,vnode)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(IOERR,AUTH,ioerr,auth)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(CORRUPT,corrupt,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CORRUPT,VTAB,corrupt,vtab)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(NOTFOUND,notfound,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(FULL,full,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(CANTOPEN,cantopen,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,NOTEMPDIR,cantopen,notempdir)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,ISDIR,cantopen,isdir)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,FULLPATH,cantopen,fullpath)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CANTOPEN,CONVPATH,cantopen,convpath)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(PROTOCOL,protocol,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(EMPTY,empty,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(SCHEMA,schema,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(TOOBIG,toobig,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(CONSTRAINT,constraint,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,CHECK,constraint,check)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,COMMITHOOK,constraint,commithook)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,FOREIGNKEY,constraint,foreignkey)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,FUNCTION,constraint,function)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,NOTNULL,constraint,notnull)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,PRIMARYKEY,constraint,primarykey)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,TRIGGER,constraint,trigger)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,UNIQUE,constraint,unique)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,VTAB,constraint,vtab)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(CONSTRAINT,ROWID,constraint,rowid)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(MISMATCH,mismatch,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(MISUSE,misuse,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(NOLFS,nolfs,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(AUTH,auth,
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(FORMAT,format,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(RANGE,range,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(NOTADB,notadb,)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(NOTICE,notice,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(NOTICE,RECOVER_WAL,notice,recover_wal)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(NOTICE,RECOVER_ROLLBACK,notice,recover_rollback)
|
||||
)
|
||||
SQLITE_MODERN_CPP_ERROR_CODE(WARNING,warning,
|
||||
SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(WARNING,AUTOINDEX,warning,autoindex)
|
||||
)
|
101
database/hdr/sqlite_modern_cpp/log.h
普通文件
101
database/hdr/sqlite_modern_cpp/log.h
普通文件
@ -0,0 +1,101 @@
|
||||
#include "errors.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <utility>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
namespace sqlite {
|
||||
namespace detail {
|
||||
template<class>
|
||||
using void_t = void;
|
||||
template<class T, class = void>
|
||||
struct is_callable : std::false_type {};
|
||||
template<class Functor, class ...Arguments>
|
||||
struct is_callable<Functor(Arguments...), void_t<decltype(std::declval<Functor>()(std::declval<Arguments>()...))>> : std::true_type {};
|
||||
template<class Functor, class ...Functors>
|
||||
class FunctorOverload: public Functor, public FunctorOverload<Functors...> {
|
||||
public:
|
||||
template<class Functor1, class ...Remaining>
|
||||
FunctorOverload(Functor1 &&functor, Remaining &&... remaining):
|
||||
Functor(std::forward<Functor1>(functor)),
|
||||
FunctorOverload<Functors...>(std::forward<Remaining>(remaining)...) {}
|
||||
using Functor::operator();
|
||||
using FunctorOverload<Functors...>::operator();
|
||||
};
|
||||
template<class Functor>
|
||||
class FunctorOverload<Functor>: public Functor {
|
||||
public:
|
||||
template<class Functor1>
|
||||
FunctorOverload(Functor1 &&functor):
|
||||
Functor(std::forward<Functor1>(functor)) {}
|
||||
using Functor::operator();
|
||||
};
|
||||
template<class Functor>
|
||||
class WrapIntoFunctor: public Functor {
|
||||
public:
|
||||
template<class Functor1>
|
||||
WrapIntoFunctor(Functor1 &&functor):
|
||||
Functor(std::forward<Functor1>(functor)) {}
|
||||
using Functor::operator();
|
||||
};
|
||||
template<class ReturnType, class ...Arguments>
|
||||
class WrapIntoFunctor<ReturnType(*)(Arguments...)> {
|
||||
ReturnType(*ptr)(Arguments...);
|
||||
public:
|
||||
WrapIntoFunctor(ReturnType(*ptr)(Arguments...)): ptr(ptr) {}
|
||||
ReturnType operator()(Arguments... arguments) { return (*ptr)(std::forward<Arguments>(arguments)...); }
|
||||
};
|
||||
inline void store_error_log_data_pointer(std::shared_ptr<void> ptr) {
|
||||
static std::shared_ptr<void> stored;
|
||||
stored = std::move(ptr);
|
||||
}
|
||||
template<class T>
|
||||
std::shared_ptr<typename std::decay<T>::type> make_shared_inferred(T &&t) {
|
||||
return std::make_shared<typename std::decay<T>::type>(std::forward<T>(t));
|
||||
}
|
||||
}
|
||||
template<class Handler>
|
||||
typename std::enable_if<!detail::is_callable<Handler(const sqlite_exception&)>::value>::type
|
||||
error_log(Handler &&handler);
|
||||
template<class Handler>
|
||||
typename std::enable_if<detail::is_callable<Handler(const sqlite_exception&)>::value>::type
|
||||
error_log(Handler &&handler);
|
||||
template<class ...Handler>
|
||||
typename std::enable_if<sizeof...(Handler)>=2>::type
|
||||
error_log(Handler &&...handler) {
|
||||
return error_log(detail::FunctorOverload<detail::WrapIntoFunctor<typename std::decay<Handler>::type>...>(std::forward<Handler>(handler)...));
|
||||
}
|
||||
template<class Handler>
|
||||
typename std::enable_if<!detail::is_callable<Handler(const sqlite_exception&)>::value>::type
|
||||
error_log(Handler &&handler) {
|
||||
return error_log(std::forward<Handler>(handler), [](const sqlite_exception&) {});
|
||||
}
|
||||
template<class Handler>
|
||||
typename std::enable_if<detail::is_callable<Handler(const sqlite_exception&)>::value>::type
|
||||
error_log(Handler &&handler) {
|
||||
auto ptr = detail::make_shared_inferred([handler = std::forward<Handler>(handler)](int error_code, const char *errstr) mutable {
|
||||
switch(error_code & 0xFF) {
|
||||
#define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \
|
||||
case SQLITE_ ## NAME: switch(error_code) { \
|
||||
derived \
|
||||
default: handler(errors::name(errstr, "", error_code)); \
|
||||
};break;
|
||||
#define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE,SUB,base,sub) \
|
||||
case SQLITE_ ## BASE ## _ ## SUB: \
|
||||
handler(errors::base ## _ ## sub(errstr, "", error_code)); \
|
||||
break;
|
||||
#include "lists/error_codes.h"
|
||||
#undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED
|
||||
#undef SQLITE_MODERN_CPP_ERROR_CODE
|
||||
default: handler(sqlite_exception(errstr, "", error_code)); \
|
||||
}
|
||||
});
|
||||
|
||||
sqlite3_config(SQLITE_CONFIG_LOG, (void(*)(void*,int,const char*))[](void *functor, int error_code, const char *errstr) {
|
||||
(*static_cast<decltype(ptr.get())>(functor))(error_code, errstr);
|
||||
}, ptr.get());
|
||||
detail::store_error_log_data_pointer(std::move(ptr));
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef SQLITE_HAS_CODEC
|
||||
#define SQLITE_HAS_CODEC
|
||||
#endif
|
||||
|
||||
#include "../sqlite_modern_cpp.h"
|
||||
|
||||
namespace sqlite {
|
||||
struct sqlcipher_config : public sqlite_config {
|
||||
std::string key;
|
||||
};
|
||||
|
||||
class sqlcipher_database : public database {
|
||||
public:
|
||||
sqlcipher_database(std::string db, const sqlcipher_config &config): database(db, config) {
|
||||
set_key(config.key);
|
||||
}
|
||||
|
||||
sqlcipher_database(std::u16string db, const sqlcipher_config &config): database(db, config) {
|
||||
set_key(config.key);
|
||||
}
|
||||
|
||||
void set_key(const std::string &key) {
|
||||
if(auto ret = sqlite3_key(_db.get(), key.data(), key.size()))
|
||||
errors::throw_sqlite_error(ret);
|
||||
}
|
||||
|
||||
void set_key(const std::string &key, const std::string &db_name) {
|
||||
if(auto ret = sqlite3_key_v2(_db.get(), db_name.c_str(), key.data(), key.size()))
|
||||
errors::throw_sqlite_error(ret);
|
||||
}
|
||||
|
||||
void rekey(const std::string &new_key) {
|
||||
if(auto ret = sqlite3_rekey(_db.get(), new_key.data(), new_key.size()))
|
||||
errors::throw_sqlite_error(ret);
|
||||
}
|
||||
|
||||
void rekey(const std::string &new_key, const std::string &db_name) {
|
||||
if(auto ret = sqlite3_rekey_v2(_db.get(), db_name.c_str(), new_key.data(), new_key.size()))
|
||||
errors::throw_sqlite_error(ret);
|
||||
}
|
||||
};
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
#pragma once
|
||||
|
||||
#include <tuple>
|
||||
#include<type_traits>
|
||||
|
||||
namespace sqlite {
|
||||
namespace utility {
|
||||
|
||||
template<typename> struct function_traits;
|
||||
|
||||
template <typename Function>
|
||||
struct function_traits : public function_traits<
|
||||
decltype(&std::remove_reference<Function>::type::operator())
|
||||
> { };
|
||||
|
||||
template <
|
||||
typename ClassType,
|
||||
typename ReturnType,
|
||||
typename... Arguments
|
||||
>
|
||||
struct function_traits<
|
||||
ReturnType(ClassType::*)(Arguments...) const
|
||||
> : function_traits<ReturnType(*)(Arguments...)> { };
|
||||
|
||||
/* support the non-const operator ()
|
||||
* this will work with user defined functors */
|
||||
template <
|
||||
typename ClassType,
|
||||
typename ReturnType,
|
||||
typename... Arguments
|
||||
>
|
||||
struct function_traits<
|
||||
ReturnType(ClassType::*)(Arguments...)
|
||||
> : function_traits<ReturnType(*)(Arguments...)> { };
|
||||
|
||||
template <
|
||||
typename ReturnType,
|
||||
typename... Arguments
|
||||
>
|
||||
struct function_traits<
|
||||
ReturnType(*)(Arguments...)
|
||||
> {
|
||||
typedef ReturnType result_type;
|
||||
|
||||
template <std::size_t Index>
|
||||
using argument = typename std::tuple_element<
|
||||
Index,
|
||||
std::tuple<Arguments...>
|
||||
>::type;
|
||||
|
||||
static const std::size_t arity = sizeof...(Arguments);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
|
||||
namespace sqlite {
|
||||
namespace utility {
|
||||
#ifdef __cpp_lib_uncaught_exceptions
|
||||
class UncaughtExceptionDetector {
|
||||
public:
|
||||
operator bool() {
|
||||
return count != std::uncaught_exceptions();
|
||||
}
|
||||
private:
|
||||
int count = std::uncaught_exceptions();
|
||||
};
|
||||
#else
|
||||
class UncaughtExceptionDetector {
|
||||
public:
|
||||
operator bool() {
|
||||
return std::uncaught_exception();
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../errors.h"
|
||||
|
||||
namespace sqlite {
|
||||
namespace utility {
|
||||
inline std::string utf16_to_utf8(const std::u16string &input) {
|
||||
struct : std::codecvt<char16_t, char, std::mbstate_t> {
|
||||
} codecvt;
|
||||
std::mbstate_t state{};
|
||||
std::string result((std::max)(input.size() * 3 / 2, std::size_t(4)), '\0');
|
||||
const char16_t *remaining_input = input.data();
|
||||
std::size_t produced_output = 0;
|
||||
while(true) {
|
||||
char *used_output;
|
||||
switch(codecvt.out(state, remaining_input, &input[input.size()],
|
||||
remaining_input, &result[produced_output],
|
||||
&result[result.size() - 1] + 1, used_output)) {
|
||||
case std::codecvt_base::ok:
|
||||
result.resize(used_output - result.data());
|
||||
return result;
|
||||
case std::codecvt_base::noconv:
|
||||
// This should be unreachable
|
||||
case std::codecvt_base::error:
|
||||
throw errors::invalid_utf16("Invalid UTF-16 input", "");
|
||||
case std::codecvt_base::partial:
|
||||
if(used_output == result.data() + produced_output)
|
||||
throw errors::invalid_utf16("Unexpected end of input", "");
|
||||
produced_output = used_output - result.data();
|
||||
result.resize(
|
||||
result.size()
|
||||
+ (std::max)((&input[input.size()] - remaining_input) * 3 / 2,
|
||||
std::ptrdiff_t(4)));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace utility
|
||||
} // namespace sqlite
|
@ -0,0 +1,201 @@
|
||||
#pragma once
|
||||
|
||||
#include "../errors.h"
|
||||
#include <sqlite3.h>
|
||||
#include <optional>
|
||||
#include <variant>
|
||||
|
||||
namespace sqlite::utility {
|
||||
template<typename ...Options>
|
||||
struct VariantFirstNullable {
|
||||
using type = void;
|
||||
};
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstNullable<T, Options...> {
|
||||
using type = typename VariantFirstNullable<Options...>::type;
|
||||
};
|
||||
#ifdef MODERN_SQLITE_STD_OPTIONAL_SUPPORT
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstNullable<std::optional<T>, Options...> {
|
||||
using type = std::optional<T>;
|
||||
};
|
||||
#endif
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstNullable<std::unique_ptr<T>, Options...> {
|
||||
using type = std::unique_ptr<T>;
|
||||
};
|
||||
template<typename ...Options>
|
||||
struct VariantFirstNullable<std::nullptr_t, Options...> {
|
||||
using type = std::nullptr_t;
|
||||
};
|
||||
template<typename Callback, typename ...Options>
|
||||
inline void variant_select_null(Callback&&callback) {
|
||||
if constexpr(std::is_same_v<typename VariantFirstNullable<Options...>::type, void>) {
|
||||
throw errors::mismatch("NULL is unsupported by this variant.", "", SQLITE_MISMATCH);
|
||||
} else {
|
||||
std::forward<Callback>(callback)(typename VariantFirstNullable<Options...>::type());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Options>
|
||||
struct VariantFirstIntegerable {
|
||||
using type = void;
|
||||
};
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstIntegerable<T, Options...> {
|
||||
using type = typename VariantFirstIntegerable<Options...>::type;
|
||||
};
|
||||
#ifdef MODERN_SQLITE_STD_OPTIONAL_SUPPORT
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstIntegerable<std::optional<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstIntegerable<T, Options...>::type, T>, std::optional<T>, typename VariantFirstIntegerable<Options...>::type>;
|
||||
};
|
||||
#endif
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstIntegerable<std::enable_if_t<std::is_same_v<typename VariantFirstIntegerable<T, Options...>::type, T>>, std::unique_ptr<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstIntegerable<T, Options...>::type, T>, std::unique_ptr<T>, typename VariantFirstIntegerable<Options...>::type>;
|
||||
};
|
||||
template<typename ...Options>
|
||||
struct VariantFirstIntegerable<int, Options...> {
|
||||
using type = int;
|
||||
};
|
||||
template<typename ...Options>
|
||||
struct VariantFirstIntegerable<sqlite_int64, Options...> {
|
||||
using type = sqlite_int64;
|
||||
};
|
||||
template<typename Callback, typename ...Options>
|
||||
inline auto variant_select_integer(Callback&&callback) {
|
||||
if constexpr(std::is_same_v<typename VariantFirstIntegerable<Options...>::type, void>) {
|
||||
throw errors::mismatch("Integer is unsupported by this variant.", "", SQLITE_MISMATCH);
|
||||
} else {
|
||||
std::forward<Callback>(callback)(typename VariantFirstIntegerable<Options...>::type());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Options>
|
||||
struct VariantFirstFloatable {
|
||||
using type = void;
|
||||
};
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstFloatable<T, Options...> {
|
||||
using type = typename VariantFirstFloatable<Options...>::type;
|
||||
};
|
||||
#ifdef MODERN_SQLITE_STD_OPTIONAL_SUPPORT
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstFloatable<std::optional<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstFloatable<T, Options...>::type, T>, std::optional<T>, typename VariantFirstFloatable<Options...>::type>;
|
||||
};
|
||||
#endif
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstFloatable<std::unique_ptr<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstFloatable<T, Options...>::type, T>, std::unique_ptr<T>, typename VariantFirstFloatable<Options...>::type>;
|
||||
};
|
||||
template<typename ...Options>
|
||||
struct VariantFirstFloatable<float, Options...> {
|
||||
using type = float;
|
||||
};
|
||||
template<typename ...Options>
|
||||
struct VariantFirstFloatable<double, Options...> {
|
||||
using type = double;
|
||||
};
|
||||
template<typename Callback, typename ...Options>
|
||||
inline auto variant_select_float(Callback&&callback) {
|
||||
if constexpr(std::is_same_v<typename VariantFirstFloatable<Options...>::type, void>) {
|
||||
throw errors::mismatch("Real is unsupported by this variant.", "", SQLITE_MISMATCH);
|
||||
} else {
|
||||
std::forward<Callback>(callback)(typename VariantFirstFloatable<Options...>::type());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Options>
|
||||
struct VariantFirstTextable {
|
||||
using type = void;
|
||||
};
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstTextable<T, Options...> {
|
||||
using type = typename VariantFirstTextable<void, Options...>::type;
|
||||
};
|
||||
#ifdef MODERN_SQLITE_STD_OPTIONAL_SUPPORT
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstTextable<std::optional<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstTextable<T, Options...>::type, T>, std::optional<T>, typename VariantFirstTextable<Options...>::type>;
|
||||
};
|
||||
#endif
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstTextable<std::unique_ptr<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstTextable<T, Options...>::type, T>, std::unique_ptr<T>, typename VariantFirstTextable<Options...>::type>;
|
||||
};
|
||||
template<typename ...Options>
|
||||
struct VariantFirstTextable<std::string, Options...> {
|
||||
using type = std::string;
|
||||
};
|
||||
template<typename ...Options>
|
||||
struct VariantFirstTextable<std::u16string, Options...> {
|
||||
using type = std::u16string;
|
||||
};
|
||||
template<typename Callback, typename ...Options>
|
||||
inline void variant_select_text(Callback&&callback) {
|
||||
if constexpr(std::is_same_v<typename VariantFirstTextable<Options...>::type, void>) {
|
||||
throw errors::mismatch("Text is unsupported by this variant.", "", SQLITE_MISMATCH);
|
||||
} else {
|
||||
std::forward<Callback>(callback)(typename VariantFirstTextable<Options...>::type());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Options>
|
||||
struct VariantFirstBlobable {
|
||||
using type = void;
|
||||
};
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstBlobable<T, Options...> {
|
||||
using type = typename VariantFirstBlobable<Options...>::type;
|
||||
};
|
||||
#ifdef MODERN_SQLITE_STD_OPTIONAL_SUPPORT
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstBlobable<std::optional<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstBlobable<T, Options...>::type, T>, std::optional<T>, typename VariantFirstBlobable<Options...>::type>;
|
||||
};
|
||||
#endif
|
||||
template<typename T, typename ...Options>
|
||||
struct VariantFirstBlobable<std::unique_ptr<T>, Options...> {
|
||||
using type = std::conditional_t<std::is_same_v<typename VariantFirstBlobable<T, Options...>::type, T>, std::unique_ptr<T>, typename VariantFirstBlobable<Options...>::type>;
|
||||
};
|
||||
template<typename T, typename A, typename ...Options>
|
||||
struct VariantFirstBlobable<std::enable_if_t<std::is_pod_v<T>>, std::vector<T, A>, Options...> {
|
||||
using type = std::vector<T, A>;
|
||||
};
|
||||
template<typename Callback, typename ...Options>
|
||||
inline auto variant_select_blob(Callback&&callback) {
|
||||
if constexpr(std::is_same_v<typename VariantFirstBlobable<Options...>::type, void>) {
|
||||
throw errors::mismatch("Blob is unsupported by this variant.", "", SQLITE_MISMATCH);
|
||||
} else {
|
||||
std::forward<Callback>(callback)(typename VariantFirstBlobable<Options...>::type());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename ...Options>
|
||||
inline auto variant_select(int type) {
|
||||
return [type](auto &&callback) {
|
||||
using Callback = decltype(callback);
|
||||
switch(type) {
|
||||
case SQLITE_NULL:
|
||||
variant_select_null<Callback, Options...>(std::forward<Callback>(callback));
|
||||
break;
|
||||
case SQLITE_INTEGER:
|
||||
variant_select_integer<Callback, Options...>(std::forward<Callback>(callback));
|
||||
break;
|
||||
case SQLITE_FLOAT:
|
||||
variant_select_float<Callback, Options...>(std::forward<Callback>(callback));
|
||||
break;
|
||||
case SQLITE_TEXT:
|
||||
variant_select_text<Callback, Options...>(std::forward<Callback>(callback));
|
||||
break;
|
||||
case SQLITE_BLOB:
|
||||
variant_select_blob<Callback, Options...>(std::forward<Callback>(callback));
|
||||
break;
|
||||
default:;
|
||||
/* assert(false); */
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
26
database/pagedao.cpp
普通文件
26
database/pagedao.cpp
普通文件
@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "pagedao.h"
|
||||
|
||||
PageDao::PageDao()
|
||||
{
|
||||
|
||||
}
|
28
database/pagedao.h
普通文件
28
database/pagedao.h
普通文件
@ -0,0 +1,28 @@
|
||||
#ifndef PAGEDAO_H
|
||||
#define PAGEDAO_H
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include "queryoption.h"
|
||||
#include "../page.h"
|
||||
#include "../searchresult.h"
|
||||
class PageDao
|
||||
{
|
||||
public:
|
||||
PageDao();
|
||||
virtual bool exists(std::string page) const = 0;
|
||||
virtual bool exists(int id) const = 0;
|
||||
virtual std::optional<Page> find(std::string name) = 0;
|
||||
virtual std::optional<Page> find(int id) = 0;
|
||||
virtual std::vector<std::string> getPageList(QueryOption option) = 0;
|
||||
virtual std::vector<std::string> fetchCategories(std::string pagename, QueryOption option) = 0;
|
||||
virtual void deletePage(std::string page) = 0;
|
||||
virtual void save(const Page &page) = 0;
|
||||
//TODO: this may not be the correct place for this.
|
||||
virtual void setCategories(std::string pagename, const std::vector<std::string> &catnames) = 0;
|
||||
virtual std::vector<SearchResult> search(std::string query, QueryOption option) = 0;
|
||||
|
||||
virtual ~PageDao() { }
|
||||
};
|
||||
|
||||
#endif // PAGEDAO_H
|
201
database/pagedaosqlite.cpp
普通文件
201
database/pagedaosqlite.cpp
普通文件
@ -0,0 +1,201 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include <sqlite_modern_cpp/errors.h>
|
||||
#include "pagedaosqlite.h"
|
||||
#include "exceptions.h"
|
||||
#include "sqlitequeryoption.h"
|
||||
#include "../logger.h"
|
||||
|
||||
/* TODO: copied from C version mostly, review whether access to table other than page is ok */
|
||||
|
||||
bool PageDaoSqlite::exists(int id) const
|
||||
{
|
||||
auto binder = *db << "SELECT 1 from page WHERE id = ?" << id ;
|
||||
return execBool(binder);
|
||||
}
|
||||
|
||||
bool PageDaoSqlite::exists(std::string name) const
|
||||
{
|
||||
auto binder = *db << "SELECT 1 FROM page WHERE name = ?" << name;
|
||||
return execBool(binder);
|
||||
}
|
||||
|
||||
std::optional<Page> PageDaoSqlite::find(std::string name)
|
||||
{
|
||||
int pageid = fetchPageId(name);
|
||||
return find(pageid);
|
||||
}
|
||||
|
||||
std::optional<Page> PageDaoSqlite::find(int id)
|
||||
{
|
||||
Page result;
|
||||
try
|
||||
{
|
||||
auto ps = *db << "SELECT name, lastrevision, visible FROM page WHERE id = ?";
|
||||
|
||||
ps << id >> std::tie(result.name, result.current_revision, result.listed);
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return { };
|
||||
}
|
||||
catch(sqlite::sqlite_exception& e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void PageDaoSqlite::deletePage(std::string page)
|
||||
{
|
||||
int pageId = this->fetchPageId(page);
|
||||
//TODO on delete cascade is better most certainly
|
||||
try
|
||||
{
|
||||
*db << "BEGIN;";
|
||||
*db << "DELETE FROM revision WHERE page = ?;" << pageId;
|
||||
*db << "DELETE FROM categorymember WHERE page = ?;" << pageId;
|
||||
*db << "DELETE FROM permissions WHERE page = ?;" << pageId;
|
||||
*db << "DELETE FROM page WHERE id =?;" << pageId;
|
||||
*db << "COMMIT;";
|
||||
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PageDaoSqlite::save(const Page &page)
|
||||
{
|
||||
try
|
||||
{
|
||||
*db << "INSERT INTO page (name, lastrevision, visible) VALUES(?, ?, ?)" << page.name << page.current_revision << page.listed;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
std::vector<std::string> PageDaoSqlite::getPageList(QueryOption option)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
std::string queryOption = SqliteQueryOption(option).setOrderByColumn("lower(name)").setVisibleColumnName("visible").setPrependWhere(true).build();
|
||||
std::string query = "SELECT name FROM page " + queryOption;
|
||||
|
||||
*db << query >> [&](std::string name)
|
||||
{
|
||||
result.push_back(name);
|
||||
};
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> PageDaoSqlite::fetchCategories(std::string pagename, QueryOption option)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
try
|
||||
{
|
||||
auto query = *db << "SELECT name FROM categorymember INNNER JOIN category ON category = category.id WHERE page = (SELECT id FROM page WHERE name = ?)" << pagename;
|
||||
query << " AND " << SqliteQueryOption(option).setPrependWhere(false).setOrderByColumn("name").build();
|
||||
query >> [&](std::string pagename) { result.push_back(pagename);};
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<SearchResult> PageDaoSqlite::search(std::string name, QueryOption option)
|
||||
{
|
||||
|
||||
std::vector<SearchResult> result;
|
||||
try
|
||||
{
|
||||
std::string qo = SqliteQueryOption(option).setPrependWhere(false).setOrderByColumn("rank").build();
|
||||
//TODO: what is passed here, simple gets thrown to the MATCH operator without escaping or anything and this is suboptimal
|
||||
auto query = *db << "SELECT page.name FROM search INNER JOIN page ON search.page = page.id WHERE search MATCH ? " << name;
|
||||
query >> [&](std::string pagename) {
|
||||
SearchResult sresult;
|
||||
sresult.pagename = pagename;
|
||||
sresult.query = name;
|
||||
result.push_back(sresult);
|
||||
};
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PageDaoSqlite::setCategories(std::string pagename, const std::vector<std::string> &catnames)
|
||||
{
|
||||
try
|
||||
{
|
||||
int pageid = fetchPageId(pagename);
|
||||
*db << "savepoint setcategories;";
|
||||
*db << "DELETE FROM categorymember WHERE page = ?" << pageid;
|
||||
for(const std::string &cat : catnames)
|
||||
{
|
||||
*db << "INSERT OR IGNORE INTO category (id, name) VALUES( (SELECT id FROM category WHERE lower(name) = lower(?)), lower(?))" << cat << cat;
|
||||
*db << "INSERT INTO categorymember (category, page) VALUES ( (SELECT ID FROM category WHERE lower(name) = lower(?)), ?)" << cat << pageid;
|
||||
|
||||
}
|
||||
*db << "release setcategories;";
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PageDaoSqlite::fetchPageId(std::string pagename)
|
||||
{
|
||||
auto binder = *db << "SELECT id FROM page WHERE name = ?" << pagename;
|
||||
return execInt(binder);
|
||||
}
|
28
database/pagedaosqlite.h
普通文件
28
database/pagedaosqlite.h
普通文件
@ -0,0 +1,28 @@
|
||||
#ifndef PAGEDAOSQLITE_H
|
||||
#define PAGEDAOSQLITE_H
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <sqlite3.h>
|
||||
#include "../page.h"
|
||||
#include "pagedao.h"
|
||||
#include "sqlitedao.h"
|
||||
class PageDaoSqlite : public PageDao, protected SqliteDao
|
||||
{
|
||||
public:
|
||||
PageDaoSqlite() { }
|
||||
void deletePage(std::string page) override;
|
||||
bool exists(int id) const override;
|
||||
bool exists(std::string name) const override;
|
||||
void save(const Page &page) override;
|
||||
std::optional<Page> find(std::string name) override;
|
||||
std::optional<Page> find(int id) override;
|
||||
std::vector<std::string> getPageList(QueryOption option) override;
|
||||
std::vector<std::string> fetchCategories(std::string pagename, QueryOption option) override;
|
||||
using SqliteDao::SqliteDao;
|
||||
int fetchPageId(std::string pagename);
|
||||
std::vector<SearchResult> search(std::string query, QueryOption option) override;
|
||||
void setCategories(std::string pagename, const std::vector<std::string> &catnames) override;
|
||||
|
||||
};
|
||||
|
||||
#endif // PAGEDAOSQLITE_H
|
26
database/permissionsdao.cpp
普通文件
26
database/permissionsdao.cpp
普通文件
@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "permissionsdao.h"
|
||||
|
||||
PermissionsDao::PermissionsDao()
|
||||
{
|
||||
|
||||
}
|
12
database/permissionsdao.h
普通文件
12
database/permissionsdao.h
普通文件
@ -0,0 +1,12 @@
|
||||
#ifndef PERMISSIONSDAO_H
|
||||
#define PERMISSIONSDAO_H
|
||||
#include "../permissions.h"
|
||||
#include "../user.h"
|
||||
class PermissionsDao
|
||||
{
|
||||
public:
|
||||
PermissionsDao();
|
||||
virtual Permissions find(std::string pagename, std::string username) = 0;
|
||||
};
|
||||
|
||||
#endif // PERMISSIONSDAO_H
|
@ -0,0 +1,32 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "permissionsdaosqlite.h"
|
||||
|
||||
PermissionsDaoSqlite::PermissionsDaoSqlite()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
Permissions PermissionsDaoSqlite::find(std::string pagename, std::string username)
|
||||
{
|
||||
/* auto query = *db << "SELECT COALESCE( (SELECT permissions FROM permissions WHERE page = ? AND userid = ?), (SELECT permissions FROM user WHERE ID = ?))";
|
||||
exec*/
|
||||
}
|
15
database/permissionsdaosqlite.h
普通文件
15
database/permissionsdaosqlite.h
普通文件
@ -0,0 +1,15 @@
|
||||
#ifndef PERMISSIONSDAOSQLITE_H
|
||||
#define PERMISSIONSDAOSQLITE_H
|
||||
#include "permissionsdao.h"
|
||||
#include "sqlitedao.h"
|
||||
|
||||
class PermissionsDaoSqlite : public PermissionsDao, protected SqliteDao
|
||||
{
|
||||
public:
|
||||
PermissionsDaoSqlite();
|
||||
|
||||
Permissions find(std::string pagename, std::string username) override;
|
||||
using SqliteDao::SqliteDao;
|
||||
};
|
||||
|
||||
#endif // PERMISSIONSDAOSQLITE_H
|
22
database/queryoption.cpp
普通文件
22
database/queryoption.cpp
普通文件
@ -0,0 +1,22 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "queryoption.h"
|
||||
|
19
database/queryoption.h
普通文件
19
database/queryoption.h
普通文件
@ -0,0 +1,19 @@
|
||||
#ifndef QUERYOPTION_H
|
||||
#define QUERYOPTION_H
|
||||
|
||||
enum SORT_ORDER
|
||||
{
|
||||
ASCENDING=0,
|
||||
DESCENDING
|
||||
};
|
||||
|
||||
class QueryOption
|
||||
{
|
||||
public:
|
||||
unsigned int offset = 0;
|
||||
unsigned int limit = 0;
|
||||
SORT_ORDER order = ASCENDING;
|
||||
bool includeInvisible = true;
|
||||
};
|
||||
|
||||
#endif // QUERYOPTION_H
|
22
database/revisiondao.cpp
普通文件
22
database/revisiondao.cpp
普通文件
@ -0,0 +1,22 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "revisiondao.h"
|
||||
|
22
database/revisiondao.h
普通文件
22
database/revisiondao.h
普通文件
@ -0,0 +1,22 @@
|
||||
#ifndef REVISIONDAO_H
|
||||
#define REVISIONDAO_H
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
#include "../revision.h"
|
||||
#include "queryoption.h"
|
||||
class RevisionDao
|
||||
{
|
||||
public:
|
||||
virtual void save(const Revision &revision) = 0;
|
||||
virtual std::vector<Revision> getAllRevisions(QueryOption &options) = 0;
|
||||
virtual std::vector<Revision> getAllRevisionsForPage(std::string pagename, QueryOption &option) = 0;
|
||||
virtual std::optional<Revision> getCurrentForPage(std::string pagename) = 0;
|
||||
virtual std::optional<Revision> getRevisionForPage(std::string pagnename, unsigned int revision) = 0;
|
||||
virtual unsigned int countTotalRevisions() = 0;
|
||||
virtual unsigned int countTotalRevisions(std::string pagename) = 0;
|
||||
|
||||
virtual ~RevisionDao() { }
|
||||
|
||||
};
|
||||
|
||||
#endif // REVISIONDAO_H
|
168
database/revisiondaosqlite.cpp
普通文件
168
database/revisiondaosqlite.cpp
普通文件
@ -0,0 +1,168 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "revisiondaosqlite.h"
|
||||
#include "exceptions.h"
|
||||
#include "sqlitequeryoption.h"
|
||||
#include "../utils.h"
|
||||
RevisionDaoSqlite::RevisionDaoSqlite()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RevisionDaoSqlite::save(const Revision &revision)
|
||||
{
|
||||
try
|
||||
{
|
||||
*db << "savepoint revisionsubmit;";
|
||||
*db << "INSERT INTO revision(author, comment, content, creationtime, page, revisionid) VALUES((SELECT id FROM user WHERE username = ?), ?, ?, DATETIME(), (SELECT id FROM page WHERE name = ?), (SELECT lastrevision+1 FROM page WHERE id = (SELECT id FROM page WHERE name = ?)));" <<
|
||||
revision.author << revision.comment << revision.content << revision.page << revision.page;
|
||||
*db << "UPDATE page SET lastrevision=lastrevision+1 WHERE name = ?; " << revision.page;
|
||||
*db << "release revisionsubmit;";
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::vector<Revision> RevisionDaoSqlite::getAllRevisions(QueryOption &options)
|
||||
{
|
||||
std::vector<Revision> result;
|
||||
|
||||
try
|
||||
{
|
||||
SqliteQueryOption queryOption { options };
|
||||
std::string queryOptionSql = queryOption.setPrependWhere(true).setOrderByColumn("id").build();
|
||||
|
||||
auto query = *db << "SELECT author, comment, content, strftime('%s',creationtime), (SELECT name FROM page WHERE page.id = page ), revisionid FROM revision " + queryOptionSql;
|
||||
query >> [&](std::string author, std::string comment, std::string content, time_t creationtime, std::string page, unsigned int revisionid)
|
||||
{
|
||||
Revision r;
|
||||
r.author = author;
|
||||
r.comment = comment;
|
||||
r.content = content;
|
||||
r.timestamp = creationtime;
|
||||
r.page = page;
|
||||
r.revision = revisionid;
|
||||
result.push_back(r);
|
||||
};
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<Revision> RevisionDaoSqlite::getAllRevisionsForPage(std::string pagename, QueryOption &option)
|
||||
{
|
||||
std::vector<Revision> result;
|
||||
|
||||
try
|
||||
{
|
||||
SqliteQueryOption queryOption { option };
|
||||
std::string queryOptionSql = queryOption.setPrependWhere(false).setOrderByColumn("id").build();
|
||||
|
||||
auto query = *db << "SELECT (SELECT username FROM user WHERE id = author), comment, content, strftime('%s',creationtime), (SELECT name FROM page WHERE page.id = page ), revisionid FROM revision WHERE page = (SELECT id FROM page WHERE name = ?) " + queryOptionSql << pagename;
|
||||
|
||||
query >> [&](std::string author, std::string comment, std::string content, time_t creationtime, std::string page, unsigned int revisionid)
|
||||
{
|
||||
Revision r;
|
||||
r.author = author;
|
||||
r.comment = comment;
|
||||
r.content = content;
|
||||
r.timestamp = creationtime;
|
||||
r.page = page;
|
||||
r.revision = revisionid;
|
||||
result.push_back(r);
|
||||
};
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
std::optional<Revision> RevisionDaoSqlite::getCurrentForPage(std::string pagename)
|
||||
{
|
||||
Revision result;
|
||||
try
|
||||
{
|
||||
auto query = *db << "SELECT (SELECT username FROM user WHERE id = author), comment, content, strftime('%s',creationtime), page, revisionid FROM revision WHERE page = (SELECT id FROM page WHERE name = ? ) AND revisionid = (SELECT lastrevision FROM page WHERE name = ?)";
|
||||
query << pagename << pagename;
|
||||
query >> std::tie(result.author, result.comment, result.content, result.timestamp, result.page, result.revision);
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return { };
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::optional<Revision> RevisionDaoSqlite::getRevisionForPage(std::string pagename, unsigned int revision)
|
||||
{
|
||||
Revision result;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
auto query = *db << "SELECT (SELECT username FROM user WHERE id = author), comment, content, strftime('%s',creationtime), page, revisionid FROM revision WHERE page = (SELECT id FROM page WHERE name = ? ) AND revisionid = ?";
|
||||
query << pagename << revision;
|
||||
query >> std::tie(result.author, result.comment, result.content, result.timestamp, result.page, result.revision);
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
return { };
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
unsigned int RevisionDaoSqlite::countTotalRevisions()
|
||||
{
|
||||
auto query = *db << "SELECT COUNT(ROWID) FROM revision";
|
||||
return static_cast<unsigned int>(execInt(query));
|
||||
}
|
||||
|
||||
unsigned int RevisionDaoSqlite::countTotalRevisions(std::string page)
|
||||
{
|
||||
auto query = *db << "SELECT COUNT(ROWID) FROM revision WHERE page = (SELECT id FROM page WHERE name = ?)" << page;
|
||||
return static_cast<unsigned int>(execInt(query));
|
||||
}
|
||||
|
23
database/revisiondaosqlite.h
普通文件
23
database/revisiondaosqlite.h
普通文件
@ -0,0 +1,23 @@
|
||||
#ifndef REVISIONDAOSQLITE_H
|
||||
#define REVISIONDAOSQLITE_H
|
||||
#include <sqlite3.h>
|
||||
#include "revisiondao.h"
|
||||
#include "sqlitedao.h"
|
||||
|
||||
class RevisionDaoSqlite : public RevisionDao, protected SqliteDao
|
||||
{
|
||||
public:
|
||||
RevisionDaoSqlite();
|
||||
void save(const Revision &revision) override;
|
||||
std::vector<Revision> getAllRevisions(QueryOption &options) override;
|
||||
std::vector<Revision> getAllRevisionsForPage(std::string pagename, QueryOption &option) override;
|
||||
std::optional<Revision> getCurrentForPage(std::string pagename) override;
|
||||
std::optional<Revision> getRevisionForPage(std::string pagnename, unsigned int revision) override;
|
||||
unsigned int countTotalRevisions() override;
|
||||
unsigned int countTotalRevisions(std::string pagename) override;
|
||||
using SqliteDao::SqliteDao;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // REVISIONDAOSQLITE_H
|
26
database/sessiondao.cpp
普通文件
26
database/sessiondao.cpp
普通文件
@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "sessiondao.h"
|
||||
|
||||
SessionDao::SessionDao()
|
||||
{
|
||||
|
||||
}
|
16
database/sessiondao.h
普通文件
16
database/sessiondao.h
普通文件
@ -0,0 +1,16 @@
|
||||
#ifndef SESSIONDAO_H
|
||||
#define SESSIONDAO_H
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include "../session.h"
|
||||
class SessionDao
|
||||
{
|
||||
public:
|
||||
SessionDao();
|
||||
virtual void save(const Session &session) = 0;
|
||||
virtual std::optional<Session> find(std::string token) = 0;
|
||||
virtual void deleteSession(std::string token) = 0;
|
||||
virtual ~SessionDao() { }
|
||||
};
|
||||
|
||||
#endif // SESSIONDAO_H
|
97
database/sessiondaosqlite.cpp
普通文件
97
database/sessiondaosqlite.cpp
普通文件
@ -0,0 +1,97 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "sessiondaosqlite.h"
|
||||
#include "userdaosqlite.h"
|
||||
|
||||
void SessionDaoSqlite::save(const Session &session)
|
||||
{
|
||||
try
|
||||
{
|
||||
//TODO: we do not store creationtime
|
||||
auto q = *db << "INSERT OR REPLACE INTO session(id, token, csrf_token, creationtime, userid) VALUES((SELECT id FROM session WHERE token = ?), ?, ?, DATETIME(), (SELECT id FROM user WHERE username = ?))";
|
||||
q << session.token << session.token << session.csrf_token << session.user.login;
|
||||
q.execute();
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
|
||||
void SessionDaoSqlite::deleteSession(std::string token)
|
||||
{
|
||||
try
|
||||
{
|
||||
auto stmt = *db << "DELETE FROM session WHERE token = ?" << token;
|
||||
stmt.execute();
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
std::optional<Session> SessionDaoSqlite::find(std::string token)
|
||||
{
|
||||
Session result;
|
||||
|
||||
try
|
||||
{
|
||||
std::string username;
|
||||
auto q = *db << "SELECT userid, token, csrf_token, strftime('%s', creationtime) FROM session WHERE token = ?" << token;
|
||||
int userid;
|
||||
q >> std::tie(userid, result.token, result.csrf_token, result.creation_time);
|
||||
|
||||
if(userid > -1)
|
||||
{
|
||||
UserDaoSqlite userDao { this-> db };
|
||||
auto u = userDao.find(userid);
|
||||
if(u)
|
||||
{
|
||||
result.user = *u;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::error() << "Session for non existent user";
|
||||
throw DatabaseQueryException("Session for non existent user");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.user = User::Anonymous();
|
||||
}
|
||||
result.loggedIn = userid != -1;
|
||||
|
||||
}
|
||||
catch(const sqlite::exceptions::no_rows &e)
|
||||
{
|
||||
return { };
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
20
database/sessiondaosqlite.h
普通文件
20
database/sessiondaosqlite.h
普通文件
@ -0,0 +1,20 @@
|
||||
#ifndef SESSIONDAOSQLITE_H
|
||||
#define SESSIONDAOSQLITE_H
|
||||
#include "sessiondao.h"
|
||||
#include "../session.h"
|
||||
#include "sqlitedao.h"
|
||||
|
||||
|
||||
class SessionDaoSqlite : public SessionDao, protected SqliteDao
|
||||
{
|
||||
public:
|
||||
SessionDaoSqlite();
|
||||
void save(const Session &session) override;
|
||||
std::optional<Session> find(std::string token) override;
|
||||
void deleteSession(std::string token) override;
|
||||
using SqliteDao::SqliteDao;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // SESSIONDAOSQLITE_H
|
91
database/sqlite.cpp
普通文件
91
database/sqlite.cpp
普通文件
@ -0,0 +1,91 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "sqlite.h"
|
||||
#include "../logger.h"
|
||||
#include "pagedaosqlite.h"
|
||||
#include "revisiondaosqlite.h"
|
||||
#include "sessiondaosqlite.h"
|
||||
#include "userdaosqlite.h"
|
||||
#include "categorydaosqlite.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
Sqlite::Sqlite(std::string path) : Database(path)
|
||||
{
|
||||
this->db = std::make_shared<sqlite::database>(path);
|
||||
|
||||
*db << "PRAGMA journal_mode=WAL;";
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
std::unique_ptr<RevisionDao> Sqlite::createRevisionDao() const
|
||||
{
|
||||
return create<RevisionDaoSqlite>();
|
||||
}
|
||||
|
||||
std::unique_ptr<PageDao> Sqlite::createPageDao() const
|
||||
{
|
||||
return create<PageDaoSqlite>();
|
||||
}
|
||||
|
||||
std::unique_ptr<UserDao> Sqlite::createUserDao() const
|
||||
{
|
||||
return create<UserDaoSqlite>();
|
||||
}
|
||||
|
||||
|
||||
std::unique_ptr<SessionDao> Sqlite::createSessionDao() const
|
||||
{
|
||||
return create<SessionDaoSqlite>();
|
||||
}
|
||||
|
||||
std::unique_ptr<CategoryDao> Sqlite::createCategoryDao() const
|
||||
{
|
||||
return create<CategoryDaoSqlite>();
|
||||
}
|
||||
void Sqlite::beginTransaction()
|
||||
{
|
||||
if(!inTransaction)
|
||||
{
|
||||
*db << "begin;";
|
||||
inTransaction = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Sqlite::rollbackTransaction()
|
||||
{
|
||||
if(inTransaction)
|
||||
{
|
||||
*db << "rollback;";
|
||||
inTransaction = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Sqlite::commitTransaction()
|
||||
{
|
||||
if(inTransaction)
|
||||
{
|
||||
*db << "commit;";
|
||||
inTransaction = false;
|
||||
}
|
||||
}
|
31
database/sqlite.h
普通文件
31
database/sqlite.h
普通文件
@ -0,0 +1,31 @@
|
||||
#ifndef SQLITE_H
|
||||
#define SQLITE_H
|
||||
#include <string>
|
||||
#include <sqlite3.h>
|
||||
#include <sqlite_modern_cpp.h>
|
||||
#include "database.h"
|
||||
|
||||
class Sqlite : public Database
|
||||
{
|
||||
private:
|
||||
bool inTransaction = false;
|
||||
std::shared_ptr<sqlite::database> db;
|
||||
|
||||
template<class T> std::unique_ptr<T> create() const
|
||||
{
|
||||
return std::make_unique<T>(db);
|
||||
}
|
||||
public:
|
||||
Sqlite(std::string path);
|
||||
std::unique_ptr<PageDao> createPageDao() const;
|
||||
std::unique_ptr<RevisionDao> createRevisionDao() const;
|
||||
std::unique_ptr<UserDao> createUserDao() const;
|
||||
std::unique_ptr<SessionDao> createSessionDao() const;
|
||||
std::unique_ptr<CategoryDao> createCategoryDao() const;
|
||||
void beginTransaction();
|
||||
void commitTransaction();
|
||||
void rollbackTransaction();
|
||||
|
||||
};
|
||||
|
||||
#endif // SQLITE_H
|
52
database/sqlitedao.cpp
普通文件
52
database/sqlitedao.cpp
普通文件
@ -0,0 +1,52 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "sqlitedao.h"
|
||||
|
||||
|
||||
bool SqliteDao::execBool(sqlite::database_binder &binder) const
|
||||
{
|
||||
bool result;
|
||||
try
|
||||
{
|
||||
bool result;
|
||||
binder >> result;
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception& e)
|
||||
{
|
||||
//TODO: well, we may want to check whether rows have found or not and thus log this here
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int SqliteDao::execInt(sqlite::database_binder &binder) const
|
||||
{
|
||||
try
|
||||
{
|
||||
int result;
|
||||
binder >> result;
|
||||
return result;
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
36
database/sqlitedao.h
普通文件
36
database/sqlitedao.h
普通文件
@ -0,0 +1,36 @@
|
||||
#ifndef SQLITEDAO_H
|
||||
#define SQLITEDAO_H
|
||||
#include <string_view>
|
||||
#include <sqlite3.h>
|
||||
#include <stdarg.h>
|
||||
#include <sqlite_modern_cpp.h>
|
||||
#include <sqlite_modern_cpp/errors.h>
|
||||
#include "queryoption.h"
|
||||
#include "exceptions.h"
|
||||
#include "../logger.h"
|
||||
|
||||
class SqliteDao
|
||||
{
|
||||
protected:
|
||||
std::shared_ptr<sqlite::database> db;
|
||||
public:
|
||||
SqliteDao() { }
|
||||
|
||||
SqliteDao(std::shared_ptr<sqlite::database> db) { this->db = db; }
|
||||
void setDb(std::shared_ptr<sqlite::database> db) { this->db = db; }
|
||||
|
||||
inline void throwFrom(const sqlite::sqlite_exception &e) const
|
||||
{
|
||||
std::string msg = "Sqlite Error: " + std::to_string(e.get_code()) + " SQL: " + e.get_sql();
|
||||
Logger::error() << msg << " Extended code: " << e.get_extended_code();
|
||||
throw DatabaseQueryException(msg);
|
||||
}
|
||||
|
||||
bool execBool(sqlite::database_binder &binder) const;
|
||||
int execInt(sqlite::database_binder &binder) const;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // SQLITEDAO_H
|
66
database/sqlitequeryoption.cpp
普通文件
66
database/sqlitequeryoption.cpp
普通文件
@ -0,0 +1,66 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "sqlitequeryoption.h"
|
||||
|
||||
|
||||
SqliteQueryOption::SqliteQueryOption(const QueryOption &o) { this->o = o; }
|
||||
|
||||
SqliteQueryOption &SqliteQueryOption::setOrderByColumn(std::string name)
|
||||
{
|
||||
this->orderByColumnName = name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SqliteQueryOption &SqliteQueryOption::setVisibleColumnName(std::string name)
|
||||
{
|
||||
this->visibleColumnName = name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SqliteQueryOption &SqliteQueryOption::setPrependWhere(bool b) { this->prependWhere = b; return *this; }
|
||||
|
||||
std::string SqliteQueryOption::build()
|
||||
{
|
||||
std::string result;
|
||||
if(!o.includeInvisible && ! this->visibleColumnName.empty())
|
||||
{
|
||||
if(this->prependWhere)
|
||||
{
|
||||
result += "WHERE ";
|
||||
}
|
||||
result += this->visibleColumnName + " = 1";
|
||||
}
|
||||
|
||||
result += " ORDER BY " + orderByColumnName;
|
||||
if(o.order == ASCENDING)
|
||||
{
|
||||
result += " ASC";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += " DESC";
|
||||
}
|
||||
//TODO: limits for offset?
|
||||
if(o.limit > 0 )
|
||||
result += " LIMIT " + std::to_string(o.limit) + " OFFSET " + std::to_string(o.offset);
|
||||
|
||||
return result;
|
||||
}
|
26
database/sqlitequeryoption.h
普通文件
26
database/sqlitequeryoption.h
普通文件
@ -0,0 +1,26 @@
|
||||
#ifndef SQLITEQUERYOPTION_H
|
||||
#define SQLITEQUERYOPTION_H
|
||||
#include <string>
|
||||
#include "queryoption.h"
|
||||
|
||||
class SqliteQueryOption
|
||||
{
|
||||
private:
|
||||
QueryOption o;
|
||||
std::string visibleColumnName;
|
||||
std::string orderByColumnName;
|
||||
|
||||
bool prependWhere;
|
||||
public:
|
||||
SqliteQueryOption(const QueryOption &o);
|
||||
|
||||
SqliteQueryOption &setOrderByColumn(std::string name);
|
||||
|
||||
SqliteQueryOption &setVisibleColumnName(std::string name);
|
||||
|
||||
SqliteQueryOption &setPrependWhere(bool b);
|
||||
|
||||
std::string build();
|
||||
};
|
||||
|
||||
#endif // SQLITEQUERYOPTION_H
|
26
database/userdao.cpp
普通文件
26
database/userdao.cpp
普通文件
@ -0,0 +1,26 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include "userdao.h"
|
||||
|
||||
UserDao::UserDao()
|
||||
{
|
||||
|
||||
}
|
20
database/userdao.h
普通文件
20
database/userdao.h
普通文件
@ -0,0 +1,20 @@
|
||||
#ifndef USERDAO_H
|
||||
#define USERDAO_H
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include "../user.h"
|
||||
class UserDao
|
||||
{
|
||||
public:
|
||||
UserDao();
|
||||
virtual bool exists(std::string username) = 0;
|
||||
virtual std::optional<User> find(std::string username) = 0;
|
||||
virtual std::optional<User> find(int id) = 0;
|
||||
virtual void deleteUser(std::string username) = 0;
|
||||
virtual void save(const User &u) = 0;
|
||||
virtual ~UserDao() { };
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // USERDAO_H
|
93
database/userdaosqlite.cpp
普通文件
93
database/userdaosqlite.cpp
普通文件
@ -0,0 +1,93 @@
|
||||
/* Copyright (c) 2018 Albert S.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
#include <sqlite3.h>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <cstring>
|
||||
#include "userdaosqlite.h"
|
||||
|
||||
UserDaoSqlite::UserDaoSqlite()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool UserDaoSqlite::exists(std::string username)
|
||||
{
|
||||
auto prep = *db << "SELECT 1 FROM user WHERE username = ?" << username;
|
||||
return execBool(prep);
|
||||
}
|
||||
|
||||
std::optional<User> UserDaoSqlite::find(std::string username)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
User user;
|
||||
auto stmt = *db << "SELECT username, password, salt, permissions FROM user WHERE username = ?" << username;
|
||||
|
||||
int perms = 0;
|
||||
stmt >> std::tie(user.login, user.password, user.salt, perms);
|
||||
user.permissions = Permissions { perms };
|
||||
|
||||
return std::move(user);
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return { };
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<User> UserDaoSqlite::find(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
User user;
|
||||
auto stmt = *db << "SELECT username, password, salt, permissions FROM user WHERE id = ?" << id;
|
||||
|
||||
int perms = 0;
|
||||
stmt >> std::tie(user.login, user.password, user.salt, perms);
|
||||
user.permissions = Permissions { perms };
|
||||
|
||||
return std::move(user);
|
||||
}
|
||||
catch(const sqlite::errors::no_rows &e)
|
||||
{
|
||||
return { };
|
||||
}
|
||||
catch(sqlite::sqlite_exception &e)
|
||||
{
|
||||
throwFrom(e);
|
||||
}
|
||||
}
|
||||
|
||||
void UserDaoSqlite::deleteUser(std::string username)
|
||||
{
|
||||
//What to do with the contributions of the user?
|
||||
}
|
||||
|
||||
void UserDaoSqlite::save(const User &u)
|
||||
{
|
||||
|
||||
}
|
22
database/userdaosqlite.h
普通文件
22
database/userdaosqlite.h
普通文件
@ -0,0 +1,22 @@
|
||||
#ifndef USERDAOSQLITE_H
|
||||
#define USERDAOSQLITE_H
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include "userdao.h"
|
||||
#include "sqlitedao.h"
|
||||
|
||||
class UserDaoSqlite : public UserDao, protected SqliteDao
|
||||
{
|
||||
public:
|
||||
bool exists(std::string username);
|
||||
std::optional<User> find(std::string username);
|
||||
std::optional<User> find(int id);
|
||||
|
||||
void deleteUser(std::string username);
|
||||
void save(const User &u);
|
||||
using SqliteDao::SqliteDao;
|
||||
UserDaoSqlite();
|
||||
};
|
||||
|
||||
#endif // USERDAOSQLITE_H
|
在新工单中引用
屏蔽一个用户