get header-only library dependencies using git submodules
This commit is contained in:
父節點
5df89f0491
當前提交
8595978560
6
.gitmodules
vendored
Normal file
6
.gitmodules
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
[submodule "submodules/sqlitemoderncpp"]
|
||||
path = submodules/sqlitemoderncpp
|
||||
url = https://github.com/SqliteModernCpp/sqlite_modern_cpp
|
||||
[submodule "submodules/cpp-httplib"]
|
||||
path = submodules/cpp-httplib
|
||||
url = https://github.com/yhirose/cpp-httplib
|
4
Makefile
4
Makefile
@ -43,7 +43,7 @@ GTEST_OBJECTS=$(filter-out qswiki.o, $(WIKIOBJECTS))
|
||||
release: CXXFLAGS=$(RELEASE_CXXFLAGS)
|
||||
release: qswiki
|
||||
qswiki: $(WIKIOBJECTS)
|
||||
$(CXX) $(WIKIOBJECTS) ${LDFLAGS} -I database/hdr -o qswiki
|
||||
$(CXX) $(WIKIOBJECTS) ${LDFLAGS} -I submodules/sqlitemoderncpp/hdr -I submodules/cpp-httplib -o qswiki
|
||||
|
||||
test: $(TESTOBJECTS)
|
||||
$(CXX) $(TESTOBJECTS) ${LDFLAGS} -o test
|
||||
@ -52,7 +52,7 @@ gtest: $(GTESTS_TESTDIR)/*.cpp $(GTEST_OBJECTS)
|
||||
$(CXX) -o gtest $(GTESTS_TESTDIR)/*.cpp $(GTEST_OBJECTS) $(GTEST_CXXFLAGS) $(GTEST_DIR)/src/gtest_main.cc $(GTEST_DIR)/src/gtest-all.cc $(GTEST_LDFLAGS)
|
||||
|
||||
%.o:%.cpp
|
||||
$(CXX) ${CXXFLAGS} ${LDFLAGS} -I database/hdr -c -o $@ $<
|
||||
$(CXX) ${CXXFLAGS} ${LDFLAGS} -I submodules/sqlitemoderncpp/hdr -I submodules/cpp-httplib -c -o $@ $<
|
||||
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(DEPENDS)
|
||||
|
檔案差異因為檔案過大而無法顯示
載入差異
@ -1,100 +0,0 @@
|
||||
#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 errors
|
||||
namespace exceptions = errors;
|
||||
} // namespace sqlite
|
@ -1,90 +0,0 @@
|
||||
#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))
|
@ -1,124 +0,0 @@
|
||||
#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));
|
||||
}
|
||||
} // namespace detail
|
||||
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));
|
||||
}
|
||||
} // namespace sqlite
|
@ -1,53 +0,0 @@
|
||||
#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);
|
||||
}
|
||||
};
|
||||
} // namespace sqlite
|
@ -1,40 +0,0 @@
|
||||
#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);
|
||||
};
|
||||
|
||||
} // namespace utility
|
||||
} // namespace sqlite
|
@ -1,34 +0,0 @@
|
||||
#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
|
||||
} // namespace utility
|
||||
} // namespace sqlite
|
@ -1,45 +0,0 @@
|
||||
#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
|
@ -1,230 +0,0 @@
|
||||
#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); */
|
||||
}
|
||||
};
|
||||
}
|
||||
} // namespace sqlite::utility
|
@ -1,6 +1,6 @@
|
||||
#ifndef HTTPGATEWAY_H
|
||||
#define HTTPGATEWAY_H
|
||||
#include "httplib.h"
|
||||
#include <httplib.h>
|
||||
#include "gatewayinterface.h"
|
||||
#include "../requestworker.h"
|
||||
#include "../request.h"
|
||||
|
4431
gateway/httplib.h
4431
gateway/httplib.h
檔案差異因為檔案過大而無法顯示
載入差異
1
submodules/cpp-httplib
Submodule
1
submodules/cpp-httplib
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit dc6a72a0fd2f02c89b7ea900dac050ccfa0136ea
|
1
submodules/sqlitemoderncpp
Submodule
1
submodules/sqlitemoderncpp
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 39d119190fbaeb95eb43b6da78176ca25a80f06f
|
載入中…
新增問題並參考
Block a user