mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-07 03:13:33 +00:00
d/j2: Some work on the SQL editors (#2771)
This commit is contained in:
parent
25e7c9bc5d
commit
10934f6746
@ -175,16 +175,17 @@ add_subdirectory(third-party/replxx EXCLUDE_FROM_ALL)
|
||||
# SQLite - Jak 2/3's built in editor
|
||||
add_definitions(-DHAVE_USLEEP=1)
|
||||
add_definitions(-DSQLITE_THREADSAFE=1)
|
||||
add_definitions(-DSQLITE_ENABLE_JSON1)
|
||||
add_definitions(-DSQLITE_ENABLE_RTREE)
|
||||
include_directories(third-party/SQLiteCpp/include)
|
||||
add_subdirectory(third-party/SQLiteCpp)
|
||||
string(REPLACE " ${THIRDPARTY_IGNORED_WARNINGS} " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
add_subdirectory(third-party/sqlite3)
|
||||
|
||||
# build tree-sitter parser
|
||||
include_directories(third-party/tree-sitter/tree-sitter/lib/include)
|
||||
include_directories(third-party/tree-sitter/tree-sitter-opengoal/include)
|
||||
add_subdirectory(third-party/tree-sitter EXCLUDE_FROM_ALL)
|
||||
|
||||
string(REPLACE " ${THIRDPARTY_IGNORED_WARNINGS} " "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
# build common library
|
||||
add_subdirectory(common)
|
||||
|
||||
|
@ -55,6 +55,7 @@ add_library(common
|
||||
serialization/subtitles/subtitles_ser.cpp
|
||||
serialization/subtitles2/subtitles2_deser.cpp
|
||||
serialization/subtitles2/subtitles2_ser.cpp
|
||||
sqlite/sqlite.cpp
|
||||
type_system/defenum.cpp
|
||||
type_system/deftype.cpp
|
||||
type_system/state.cpp
|
||||
@ -82,10 +83,9 @@ add_library(common
|
||||
util/term_util.cpp
|
||||
util/Timer.cpp
|
||||
util/unicode_util.cpp
|
||||
versions/versions.cpp
|
||||
)
|
||||
versions/versions.cpp)
|
||||
|
||||
target_link_libraries(common fmt lzokay replxx libzstd_static tree-sitter)
|
||||
target_link_libraries(common fmt lzokay replxx libzstd_static tree-sitter sqlite3)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(common wsock32 ws2_32 windowsapp)
|
||||
|
55
common/sqlite/sqlite.cpp
Normal file
55
common/sqlite/sqlite.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "sqlite.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
bool sqlite::SQLiteDatabase::open_db(const std::string& path) {
|
||||
if (is_open()) {
|
||||
return true;
|
||||
}
|
||||
sqlite3* db;
|
||||
|
||||
// NOTE - this opens with SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
|
||||
const auto status_code = sqlite3_open(path.data(), &db);
|
||||
if (status_code) {
|
||||
lg::error("Unable to open SQLite database: {}", sqlite3_errmsg(db));
|
||||
sqlite3_close(db);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Otherwise, track it
|
||||
m_db = std::shared_ptr<sqlite3>(db, SQLite3DatabaseDeleter());
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO - allow passing in a `std::function<int(void*, int, char**, char**)>` to format the results
|
||||
// for now we do something that works in general (converts to vectors)
|
||||
|
||||
sqlite::GenericResponse sqlite::SQLiteDatabase::run_query(const std::string& sql) {
|
||||
GenericResponse resp;
|
||||
if (!is_open()) {
|
||||
return resp;
|
||||
}
|
||||
|
||||
char* errMsg = 0;
|
||||
|
||||
const auto rc = sqlite3_exec(
|
||||
m_db.value().get(), sql.data(),
|
||||
[](void* data, int argc, char** argv, char** azColName) {
|
||||
GenericResponse* resp = static_cast<GenericResponse*>(data);
|
||||
std::vector<std::string> row = {};
|
||||
for (int i = 0; i < argc; i++) {
|
||||
row.push_back(argv[i] ? argv[i] : "NULL");
|
||||
}
|
||||
resp->rows.push_back(row);
|
||||
return 0;
|
||||
},
|
||||
&resp, &errMsg);
|
||||
|
||||
if (rc != SQLITE_OK) {
|
||||
fprintf(stderr, "SQL error: %s\n", errMsg);
|
||||
sqlite3_free(errMsg);
|
||||
// TODO - store error on response
|
||||
return resp;
|
||||
}
|
||||
return resp;
|
||||
}
|
36
common/sqlite/sqlite.h
Normal file
36
common/sqlite/sqlite.h
Normal file
@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "third-party/sqlite3/sqlite3.h"
|
||||
|
||||
// Just a simple wrapper around the raw C types from sqlite3
|
||||
// takes care of all the relevant memory freeing and such for you (hopefully)
|
||||
namespace sqlite {
|
||||
struct SQLite3DatabaseDeleter {
|
||||
void operator()(sqlite3* db) const {
|
||||
if (db) {
|
||||
sqlite3_close(db);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct GenericResponse {
|
||||
std::vector<std::vector<std::string>> rows;
|
||||
};
|
||||
|
||||
class SQLiteDatabase {
|
||||
public:
|
||||
SQLiteDatabase() = default;
|
||||
bool is_open() const { return m_db.has_value(); }
|
||||
bool open_db(const std::string& path);
|
||||
GenericResponse run_query(const std::string& sql);
|
||||
|
||||
private:
|
||||
std::optional<std::shared_ptr<sqlite3>> m_db;
|
||||
};
|
||||
|
||||
} // namespace sqlite
|
@ -105,6 +105,7 @@
|
||||
|
||||
(declare-type sql-result basic)
|
||||
(define-extern sql-query (function string sql-result))
|
||||
(define-extern *collapse-quote* symbol)
|
||||
|
||||
(define-extern loading-level kheap)
|
||||
(define-extern dma-sync (function pointer int int int))
|
||||
@ -31660,7 +31661,7 @@
|
||||
:flag-assert #xd00000030
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0) ;; added to avoid re-definition errors (even though nothing was being re-defined)
|
||||
(editable-region-method-9 (_type_ editable-array int int) none 9)
|
||||
(editable-region-method-9 (_type_ editable-array int int) symbol 9)
|
||||
(editable-region-method-10 (_type_ int) symbol 10)
|
||||
(editable-region-method-11 (_type_ vector int) none 11)
|
||||
(editable-region-method-12 (_type_) editable-filter 12)
|
||||
@ -32116,7 +32117,7 @@
|
||||
:size-assert #x41c
|
||||
:flag-assert #x150000041c
|
||||
(:methods
|
||||
(new (symbol type int symbol) _type_ 0)
|
||||
(new (symbol type string) _type_ 0)
|
||||
(init-from-sql!
|
||||
"Query the database and initialize the [[mysql-nav-graph]] and all it's related components"
|
||||
(_type_ string string) symbol 9)
|
||||
@ -32248,11 +32249,11 @@
|
||||
(nav-graph-editor-method-45 (_type_) none 45)
|
||||
(nav-graph-editor-method-46 (_type_) pad-buttons 46)
|
||||
(nav-graph-editor-method-47 (_type_) none 47)
|
||||
(nav-graph-editor-method-48 "TODO - enum / com-type" (_type_ uint32) nav-graph-command 48)
|
||||
(nav-graph-editor-method-48 "TODO - enum / com-type" (_type_ uint) nav-graph-command 48)
|
||||
(nav-graph-editor-method-49 (_type_) nav-graph-command 49)
|
||||
(nav-graph-editor-method-50 (_type_) none 50)
|
||||
(nav-graph-editor-method-51 (_type_) none 51)
|
||||
(nav-graph-editor-method-52 (_type_) none 52)
|
||||
(nav-graph-editor-method-52 (_type_) uint 52)
|
||||
(nav-graph-editor-method-53 (_type_ int int) none 53)
|
||||
(nav-graph-editor-method-54 (_type_ int) none 54)
|
||||
(nav-graph-editor-method-55 (_type_ int) none 55)
|
||||
@ -32268,7 +32269,7 @@
|
||||
)
|
||||
|
||||
(define-extern *nav-graph-editor* (pointer nav-graph-editor))
|
||||
(define-extern nav-graph-editor-init-by-other (function int none :behavior nav-graph-editor))
|
||||
(define-extern nav-graph-editor-init-by-other (function string none :behavior nav-graph-editor))
|
||||
(define-extern run-nav-graph-editor (function symbol (pointer process)))
|
||||
(define-extern get-nav-graph-editor (function nav-graph-editor))
|
||||
(define-extern exit-nav-graph-editor (function none))
|
||||
@ -36060,6 +36061,9 @@
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype hover-nav-bsp-node (structure)
|
||||
@ -36072,6 +36076,7 @@
|
||||
:size-assert #x1c
|
||||
:flag-assert #xb0000001c
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
(hover-nav-bsp-node-method-9 (_type_) none 9)
|
||||
(hover-nav-bsp-node-method-10 (_type_ int) none 10)
|
||||
)
|
||||
@ -36087,11 +36092,11 @@
|
||||
|
||||
(define-extern probe-for-clear-collision? (function vector vector symbol))
|
||||
(define-extern hover-nav-graph-process-points (function none))
|
||||
(define-extern hover-nav-graph-output (function none))
|
||||
(define-extern hover-nav-graph-output (function symbol))
|
||||
(define-extern *axes-table* (array vector))
|
||||
(define-extern *hover-bsp* hover-nav-bsp)
|
||||
(define-extern hover-nav-graph-output-bsp (function hover-nav-bsp))
|
||||
(define-extern hover-nav-network-build-bsp (function hover-nav-bsp-node none))
|
||||
(define-extern hover-nav-network-build-bsp (function (array hover-nav-bsp-point) hover-nav-bsp))
|
||||
(define-extern hover-nav-bsp-output (function hover-nav-bsp none))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
@ -96,7 +96,6 @@
|
||||
// CFG failed
|
||||
"draw-inline-array-instance-shrub",
|
||||
|
||||
"(method 9 editable-region)", // condition branch assert hit
|
||||
"test-to-from-spr",
|
||||
"test-from-spr",
|
||||
"test-to-spr",
|
||||
@ -527,7 +526,11 @@
|
||||
"(anon-function 56 hal2-course)": [4, 5],
|
||||
"(anon-function 58 hal2-course)": [74],
|
||||
"(method 142 gun-buoy)": [0, 2],
|
||||
"generic-merc-execute-all": [7, 15]
|
||||
"generic-merc-execute-all": [7, 15],
|
||||
"(method 9 editable-region)": [
|
||||
1, 2, 3, 4, 5, 10, 11, 15, 16, 17, 18, 21, 24, 25, 30, 31, 35, 36, 37, 38,
|
||||
39, 41, 42, 44, 45, 47, 48, 49, 51, 52, 53, 54
|
||||
]
|
||||
},
|
||||
|
||||
// Sometimes the game might use format strings that are fetched dynamically,
|
||||
|
@ -2233,5 +2233,10 @@
|
||||
[112, ["array", "collide-shape", 32]]
|
||||
],
|
||||
"(code impact gun-dark-shot)": [[160, ["array", "collide-shape", 16]]],
|
||||
"texture-anim-layer-draw": [[16, "matrix"], [80, "matrix"], [144, "matrix"], [208, "matrix"]]
|
||||
"texture-anim-layer-draw": [
|
||||
[16, "matrix"],
|
||||
[80, "matrix"],
|
||||
[144, "matrix"],
|
||||
[208, "matrix"]
|
||||
]
|
||||
}
|
||||
|
@ -1942,7 +1942,9 @@
|
||||
],
|
||||
"(method 29 editable-face)": [
|
||||
[318, "a0", "(array editable-point)"],
|
||||
[234, "a1", "editable-point"]
|
||||
[234, "a1", "editable-point"],
|
||||
[206, "v0", "(array editable-point)"],
|
||||
[241, "f0", "float"]
|
||||
],
|
||||
"(method 27 editable-face)": [
|
||||
[9, "t9", "(function editable-face editable-array editable)"],
|
||||
@ -10391,9 +10393,7 @@
|
||||
[42, "t3", "(pointer uint128)"],
|
||||
[44, "t2", "(pointer uint128)"]
|
||||
],
|
||||
"texture-anim-layer-draw": [
|
||||
[[4, 162], "s4", "(pointer uint128)"]
|
||||
],
|
||||
"texture-anim-layer-draw": [[[4, 162], "s4", "(pointer uint128)"]],
|
||||
"move-rg-to-ba-texture-anim-layer-func": [
|
||||
[[305, 313], "a0", "dma-packet"],
|
||||
[[315, 322], "a0", "gs-gif-tag"],
|
||||
@ -10491,6 +10491,6 @@
|
||||
[[239, 245], "a0", "dma-packet"],
|
||||
[[248, 254], "a0", "gs-gif-tag"],
|
||||
[259, "v1", "(pointer gs-reg64)"]
|
||||
]
|
||||
|
||||
],
|
||||
"hover-nav-graph-output": [[[25, 30], "s2", "vector"]]
|
||||
}
|
||||
|
@ -4273,19 +4273,28 @@
|
||||
},
|
||||
"update-texture-anim": {
|
||||
"args": ["bucket", "anim-array"],
|
||||
"vars": {"s3-0": "dma-buf", "s2-0": "anim-idx", "s1-0": "anim", "v1-11": "dest-tex", "s0-0": "tex-width", "sv-16": "tex-height",
|
||||
"sv-32": "fbp-for-tex", "sv-48": "layer-idx", "t0-6": "layer"}
|
||||
"vars": {
|
||||
"s3-0": "dma-buf",
|
||||
"s2-0": "anim-idx",
|
||||
"s1-0": "anim",
|
||||
"v1-11": "dest-tex",
|
||||
"s0-0": "tex-width",
|
||||
"sv-16": "tex-height",
|
||||
"sv-32": "fbp-for-tex",
|
||||
"sv-48": "layer-idx",
|
||||
"t0-6": "layer"
|
||||
}
|
||||
},
|
||||
"no-alpha-texture-anim-layer-func": {
|
||||
"args": ["dma-buf", "fbp-to-draw", "width", "height", "layer", "time"]
|
||||
},
|
||||
"dest-texture-init": {
|
||||
"args": ["tex-anim"],
|
||||
"vars": {"v1-1":"dest-tex", "a0-2": "size", "a1-1": "dest"}
|
||||
"vars": { "v1-1": "dest-tex", "a0-2": "size", "a1-1": "dest" }
|
||||
},
|
||||
"src-texture-init": {
|
||||
"args": ["layer"],
|
||||
"vars": {"v1-1": "tex", "a0-2":"size", "a1-1":"addr"}
|
||||
"vars": { "v1-1": "tex", "a0-2": "size", "a1-1": "addr" }
|
||||
},
|
||||
"copy-alpha-texture-anim-layer-func": {
|
||||
"args": ["dma-buf", "fbp-to-draw", "width", "height", "layer", "time"]
|
||||
@ -4301,7 +4310,13 @@
|
||||
},
|
||||
"src-texture-init-mt8": {
|
||||
"args": ["layer"],
|
||||
"vars" : {"v1-1": "tex", "a0-2": "width", "a1-1": "height", "a2-0": "dest", "a3-0":"clutdest"}
|
||||
"vars": {
|
||||
"v1-1": "tex",
|
||||
"a0-2": "width",
|
||||
"a1-1": "height",
|
||||
"a2-0": "dest",
|
||||
"a3-0": "clutdest"
|
||||
}
|
||||
},
|
||||
"noise-texture-anim-layer-func": {
|
||||
"args": ["dma-buf", "fbp-to-draw", "width", "height", "layer", "time"]
|
||||
|
@ -225,7 +225,7 @@ add_subdirectory(sound)
|
||||
# we build the runtime as a static library.
|
||||
add_library(runtime STATIC ${RUNTIME_SOURCE} "../third-party/glad/src/glad.c")
|
||||
|
||||
target_link_libraries(runtime common fmt SDL2::SDL2 imgui discord-rpc sound stb_image libco SQLiteCpp)
|
||||
target_link_libraries(runtime common fmt SDL2::SDL2 imgui discord-rpc sound stb_image libco)
|
||||
if(WIN32)
|
||||
target_link_libraries(runtime mman)
|
||||
else()
|
||||
|
@ -154,16 +154,32 @@ int sql_query_sync(Ptr<String> string_in) {
|
||||
|
||||
kdebugheap->top.offset -= 0x4000; // not sure what it's used for...
|
||||
|
||||
// TODO - query the database!
|
||||
const auto& result = run_sql_query(query_str);
|
||||
// TODO - check for errors
|
||||
|
||||
auto sym = find_symbol_from_c("sql-result");
|
||||
if (sym.offset) {
|
||||
Ptr<Type> type = Ptr<Type>(sym->value());
|
||||
auto new_result_ptr = call_method_of_type_arg2(intern_from_c("debug").offset, type,
|
||||
GOAL_NEW_METHOD, type.offset, 1);
|
||||
|
||||
// TODO - can their sql-result type not return multiple rows and the data is just the columns?
|
||||
// or do they make assumptions and iterate the data like a 2d flattened array
|
||||
SQLResult* new_result = Ptr<SQLResult>(new_result_ptr).c();
|
||||
new_result->len = 1;
|
||||
new_result->data[0] = Ptr<String>(make_debug_string_from_c("test"));
|
||||
|
||||
int num_values = 0;
|
||||
for (const auto& row : result.rows) {
|
||||
num_values += row.size();
|
||||
for (const auto& val : row) {
|
||||
new_result->data[0] = Ptr<String>(make_debug_string_from_c(val.data()));
|
||||
}
|
||||
}
|
||||
new_result->len = num_values;
|
||||
|
||||
// TODO - possible values here (when to set them?)
|
||||
// 'error = the default, fairly obvious
|
||||
// 'select = the result of a select
|
||||
new_result->error = intern_from_c("select").offset;
|
||||
|
||||
kdebugheap->top.offset += 0x4000;
|
||||
|
||||
|
@ -443,12 +443,22 @@ u32 MouseGetData(u32 _mouse) {
|
||||
mouse->valid = offset_of_s7() + jak2_symbols::FIX_SYM_TRUE;
|
||||
mouse->cursor = offset_of_s7() + jak2_symbols::FIX_SYM_TRUE;
|
||||
mouse->status = 1;
|
||||
// Contrary to the name, this is a 16bitfield
|
||||
// where:
|
||||
// 0 = left button
|
||||
// 1 = right button
|
||||
// 2 = middle button
|
||||
mouse->button0 = 0;
|
||||
|
||||
s32 xpos = 0;
|
||||
s32 ypos = 0;
|
||||
if (Display::GetMainDisplay()) {
|
||||
std::tie(xpos, ypos) = Display::GetMainDisplay()->get_input_manager()->get_mouse_pos();
|
||||
const auto mouse_button_status =
|
||||
Display::GetMainDisplay()->get_input_manager()->get_mouse_button_status();
|
||||
mouse->button0 |= (mouse_button_status.left ? 1 : 0);
|
||||
mouse->button0 |= (mouse_button_status.right ? 2 : 0);
|
||||
mouse->button0 |= (mouse_button_status.middle ? 4 : 0);
|
||||
}
|
||||
|
||||
// NOTE - ignoring speed and setting position directly
|
||||
@ -801,90 +811,40 @@ void InitMachineScheme() {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<SQLite::Database> sql_db = std::nullopt;
|
||||
sqlite::SQLiteDatabase sql_db;
|
||||
|
||||
void initialize_sql_db() {
|
||||
// If the DB has already been initialized, no-op
|
||||
if (sql_db) {
|
||||
if (sql_db.is_open()) {
|
||||
return;
|
||||
}
|
||||
// In the original environment, they relied on a database already being setup with the correct
|
||||
// schema We are using an embedded SQLite database, which isn't already setup, so we have to do
|
||||
// that here!
|
||||
|
||||
// TODO - eventually tie this to .sql files instead of hard-coding the strings here, usually a
|
||||
// nicer editing experience
|
||||
|
||||
fs::path db_path = file_util::get_user_misc_dir(g_game_version) / "jak2-editor.db";
|
||||
file_util::create_dir_if_needed_for_file(db_path);
|
||||
|
||||
try {
|
||||
sql_db = SQLite::Database(db_path.string(), SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
SQLite::Transaction tx(sql_db.value());
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'level_info' ( 'level_info_id' INTEGER, 'name' TEXT, "
|
||||
"'translate_x' REAL, 'translate_y' REAL, 'translate_z' REAL, 'last_update' TEXT, "
|
||||
"'sample_point_update' TEXT, PRIMARY KEY('level_info_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'light' ( 'light_id' INTEGER, 'name' TEXT, 'level_name' TEXT, "
|
||||
"'pos_x' REAL, 'pos_y' REAL, 'pos_z' REAL, 'r' REAL, 'dir_x' REAL, 'dir_y' REAL, 'dir_z' "
|
||||
"REAL, 'color0_r' REAL, 'color0_g' REAL, 'color0_b' REAL, 'color0_a' REAL, 'decay_start' "
|
||||
"REAL, 'ambient_point_ratio' REAL, 'brightness' REAL, PRIMARY KEY('light_id' "
|
||||
"AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'nav_edge' ( 'nav_edge_id' INTEGER NOT NULL, 'nav_graph_id' "
|
||||
"INTEGER NOT NULL, 'nav_node_id_1' INTEGER, 'nav_node_id_2' INTEGER, 'directionality' "
|
||||
"TEXT, 'speed_limit' NUMERIC, 'density' NUMERIC, 'traffic_edge_flag' NUMERIC, "
|
||||
"'nav_clock_mask' NUMERIC, 'nav_clock_type' TEXT, 'width' NUMERIC, 'minimap_edge_flag' "
|
||||
"NUMERIC, FOREIGN KEY('nav_node_id_2') REFERENCES 'nav_node'('nav_node_id'), FOREIGN "
|
||||
"KEY('nav_graph_id') REFERENCES 'nav_graph'('nav_graph_id'), FOREIGN KEY('nav_node_id_1') "
|
||||
"REFERENCES 'nav_node'('nav_node_id'), PRIMARY KEY('nav_edge_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'nav_graph' ( 'nav_graph_id' INTEGER, 'name' TEXT, PRIMARY "
|
||||
"KEY('nav_graph_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'nav_mesh' ( 'nav_mesh_id' INTEGER, PRIMARY KEY('nav_mesh_id' "
|
||||
"AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'nav_node' ( 'nav_node_id' INTEGER NOT NULL, 'nav_graph_id' "
|
||||
"INTEGER NOT NULL, 'nav_mesh_id' INTEGER NOT NULL, 'x' REAL, 'y' REAL, 'z' REAL, "
|
||||
"'level_name' TEXT, 'angle' REAL, 'radius' REAL, 'nav_node_flag' NUMERIC, FOREIGN "
|
||||
"KEY('nav_mesh_id') REFERENCES 'nav_mesh'('nav_mesh_id'), FOREIGN KEY('nav_graph_id') "
|
||||
"REFERENCES 'nav_graph'('nav_graph_id'), PRIMARY KEY('nav_node_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'nav_visible_nodes' ( 'nav_node_id' INTEGER NOT NULL, "
|
||||
"'nav_graph_id' INTEGER NOT NULL, 'nav_edge_id' INTEGER NOT NULL, FOREIGN "
|
||||
"KEY('nav_edge_id') REFERENCES 'nav_mesh'('nav_mesh_id'), FOREIGN KEY('nav_graph_id') "
|
||||
"REFERENCES 'nav_graph'('nav_graph_id'), PRIMARY KEY('nav_node_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'race_path' ( 'race_path_id' INTEGER, 'race' TEXT, 'path' "
|
||||
"INTEGER, PRIMARY KEY('race_path_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'region' ( 'region_id' INTEGER NOT NULL, 'level_name' TEXT, "
|
||||
"'flags' NUMERIC, 'tree' TEXT, 'on_enter' TEXT, 'on_exit' TEXT, 'on_inside' TEXT, PRIMARY "
|
||||
"KEY('region_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'region_face' ( 'region_face_id' INTEGER NOT NULL, 'region_id' "
|
||||
"INTEGER NOT NULL, 'idx' INTEGER, 'kind' TEXT, 'radius' REAL, FOREIGN KEY('region_id') "
|
||||
"REFERENCES 'region'('region_id'), PRIMARY KEY('region_face_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'region_point' ( 'region_point_id' INTEGER, 'region_face_id' "
|
||||
"INTEGER NOT NULL, 'idx' INTEGER, 'x' REAL, 'y' REAL, 'z' REAL, FOREIGN "
|
||||
"KEY('region_face_id') REFERENCES 'region_face'('region_face_id'), PRIMARY "
|
||||
"KEY('region_point_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'region_sphere' ( 'region_sphere_id' INTEGER, 'region_id' "
|
||||
"INTEGER, 'x' REAL, 'y' REAL, 'z' REAL, 'r' REAL, FOREIGN KEY('region_id') REFERENCES "
|
||||
"'region'('region_id'), PRIMARY KEY('region_sphere_id' AUTOINCREMENT) );");
|
||||
sql_db->exec(
|
||||
"CREATE TABLE IF NOT EXISTS 'sample_point' ( 'sample_point_id' INTEGER, 'level_info_id' "
|
||||
"INTEGER NOT NULL, 'source' TEXT, 'x' REAL, 'y' REAL, 'z' REAL, FOREIGN "
|
||||
"KEY('level_info_id') REFERENCES 'level_info'('level_info_id'), PRIMARY "
|
||||
"KEY('sample_point_id' AUTOINCREMENT) );");
|
||||
tx.commit();
|
||||
} catch (std::exception& e) {
|
||||
lg::error("[SQL] Error creating SQLite DB - {}", e.what());
|
||||
// Attempt to open the database
|
||||
const auto opened = sql_db.open_db(db_path.string());
|
||||
|
||||
fs::path schema_file =
|
||||
file_util::get_jak_project_dir() / "goal_src" / "jak2" / "tools" / "editable-schema.sql";
|
||||
if (!file_util::file_exists(schema_file.string())) {
|
||||
lg::error("Unable to locate SQL Schema file at {}", schema_file.string());
|
||||
return;
|
||||
}
|
||||
|
||||
const auto success = sql_db.run_query(file_util::read_text_file(schema_file));
|
||||
// TODO - error check
|
||||
}
|
||||
|
||||
sqlite::GenericResponse run_sql_query(const std::string& query) {
|
||||
if (!sql_db.is_open()) {
|
||||
// TODO - error
|
||||
return sqlite::GenericResponse();
|
||||
}
|
||||
return sql_db.run_query(query);
|
||||
}
|
||||
|
||||
} // namespace jak2
|
||||
|
@ -3,8 +3,7 @@
|
||||
#include <optional>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
#include "SQLiteCpp/SQLiteCpp.h"
|
||||
#include "common/sqlite/sqlite.h"
|
||||
|
||||
namespace jak2 {
|
||||
void InitParms(int argc, const char* const* argv);
|
||||
@ -13,8 +12,9 @@ int InitMachine();
|
||||
int ShutdownMachine();
|
||||
void InitMachineScheme();
|
||||
|
||||
extern std::optional<SQLite::Database> sql_db;
|
||||
extern sqlite::SQLiteDatabase sql_db;
|
||||
void initialize_sql_db();
|
||||
sqlite::GenericResponse run_sql_query(const std::string& query);
|
||||
|
||||
struct MouseInfo {
|
||||
// ((active symbol :offset-assert 4)
|
||||
|
@ -30,10 +30,30 @@ void MouseDevice::process_event(const SDL_Event& event,
|
||||
} else if (event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) {
|
||||
// Mouse Button Events
|
||||
// https://wiki.libsdl.org/SDL2/SDL_MouseButtonEvent
|
||||
const auto button_event = event.button;
|
||||
// Always update the internal button tracker, this is for GOAL reasons.
|
||||
switch (button_event.button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
m_button_status.left = event.type == SDL_MOUSEBUTTONDOWN;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
m_button_status.right = event.type == SDL_MOUSEBUTTONDOWN;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
m_button_status.middle = event.type == SDL_MOUSEBUTTONDOWN;
|
||||
break;
|
||||
case SDL_BUTTON_X1:
|
||||
m_button_status.mouse4 = event.type == SDL_MOUSEBUTTONDOWN;
|
||||
break;
|
||||
case SDL_BUTTON_X2:
|
||||
m_button_status.mouse5 = event.type == SDL_MOUSEBUTTONDOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ignore_inputs) {
|
||||
return;
|
||||
}
|
||||
const auto button_event = event.button;
|
||||
|
||||
auto& binds = m_settings->mouse_binds;
|
||||
|
||||
// Binding re-assignment
|
||||
|
@ -4,6 +4,14 @@
|
||||
|
||||
class MouseDevice : public InputDevice {
|
||||
public:
|
||||
struct MouseButtonStatus {
|
||||
bool left;
|
||||
bool right;
|
||||
bool middle;
|
||||
bool mouse4;
|
||||
bool mouse5;
|
||||
};
|
||||
|
||||
MouseDevice(){};
|
||||
MouseDevice(std::shared_ptr<game_settings::InputSettings> settings);
|
||||
~MouseDevice() {}
|
||||
@ -21,11 +29,13 @@ class MouseDevice : public InputDevice {
|
||||
void enable_camera_control(const bool enable);
|
||||
void enable_movement_control(const bool enable) { m_control_movement = enable; }
|
||||
std::pair<int, int> get_mouse_pos() const { return {m_xcoord, m_ycoord}; }
|
||||
MouseButtonStatus get_mouse_button_status() const { return m_button_status; }
|
||||
void set_camera_sens(const float xsens, const float ysens);
|
||||
|
||||
private:
|
||||
int m_xcoord = 0;
|
||||
int m_ycoord = 0;
|
||||
MouseButtonStatus m_button_status;
|
||||
|
||||
bool m_control_camera = false;
|
||||
bool m_control_movement = false;
|
||||
|
@ -54,6 +54,9 @@ class InputManager {
|
||||
|
||||
std::optional<std::shared_ptr<PadData>> get_current_data(const int port) const;
|
||||
std::pair<int, int> get_mouse_pos() const { return m_mouse.get_mouse_pos(); }
|
||||
MouseDevice::MouseButtonStatus get_mouse_button_status() const {
|
||||
return m_mouse.get_mouse_button_status();
|
||||
}
|
||||
|
||||
// These functions can be called from the EE and interact with SDL directly
|
||||
// These should be enqueued in the event that for example, you try to set
|
||||
|
@ -380,7 +380,7 @@
|
||||
:flag-assert #xd00000030
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
(editable-region-method-9 (_type_ editable-array int int) none 9)
|
||||
(editable-region-method-9 (_type_ editable-array int int) symbol 9)
|
||||
(editable-region-method-10 (_type_ int) symbol 10)
|
||||
(editable-region-method-11 (_type_ vector int) none 11)
|
||||
(editable-region-method-12 (_type_) editable-filter 12)
|
||||
|
@ -1447,7 +1447,7 @@
|
||||
)
|
||||
(when #t
|
||||
(format *stdcon* "~0K")
|
||||
(format *stdcon* "~16S~16S~16S~%" "Left button" "Middle button" "Right button")
|
||||
(format *stdcon* "~%~%~16S~16S~16S~%" "Left button" "Middle button" "Right button")
|
||||
(format
|
||||
*stdcon*
|
||||
"~16S~16S~16S~%"
|
||||
|
@ -112,7 +112,194 @@
|
||||
#f
|
||||
)
|
||||
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
(defmethod editable-region-method-9 editable-region ((obj editable-region) (arg0 editable-array) (arg1 int) (arg2 int))
|
||||
(local-vars (v0-0 symbol) (v1-5 object) (v1-28 object))
|
||||
(set! v0-0
|
||||
(when (-> obj changed)
|
||||
(format 0 "NOTICE: saving ~A~%" obj)
|
||||
(let ((s5-0 *collapse-quote*))
|
||||
(set! *collapse-quote* #f)
|
||||
(let ((v1-1 (-> obj tree)))
|
||||
(b! (!= v1-1 'entity) cfg-3 :delay (nop!))
|
||||
(b! #t cfg-78 :delay (nop!))
|
||||
(label cfg-3)
|
||||
(b! (!= v1-1 'light) cfg-17 :delay (nop!))
|
||||
(let ((s3-0 (-> arg0 length))
|
||||
(s2-0 0)
|
||||
)
|
||||
(let ((s1-0 (-> arg0 data s2-0)))
|
||||
(b! #t cfg-15 :delay (nop!))
|
||||
(label cfg-5)
|
||||
(b! (not s1-0) cfg-10 :likely-delay (set! v1-5 s1-0))
|
||||
(set! v1-5 (and (= (-> s1-0 region) obj) (not (logtest? (-> s1-0 flags) (editable-flag no-save)))))
|
||||
(label cfg-10)
|
||||
(b! (not v1-5) cfg-14 :delay (empty-form))
|
||||
(b! (editable-method-22 s1-0 arg0 1 0) cfg-14 :delay (empty-form))
|
||||
(format 0 "ERROR: sql: insert error for ~A~%" s1-0)
|
||||
(return #f)
|
||||
(label cfg-14)
|
||||
(+! s2-0 1)
|
||||
(set! s1-0 (-> arg0 data s2-0))
|
||||
)
|
||||
(label cfg-15)
|
||||
(b! (< s2-0 s3-0) cfg-5)
|
||||
)
|
||||
(b! #t cfg-78 :delay (nop!))
|
||||
(label cfg-17)
|
||||
(b! (!= v1-1 'sample) cfg-37 :delay (nop!))
|
||||
)
|
||||
(let ((s3-1 (clear *temp-string*)))
|
||||
(format s3-1 "delete from sample_point where level_info_id=~D and source='manual'" (-> arg0 level-info-id))
|
||||
(let ((a2-5 (sql-query s3-1)))
|
||||
(let ((v1-18 'modify))
|
||||
(b! (= (-> a2-5 error) v1-18) cfg-21 :delay (empty-form))
|
||||
)
|
||||
(format 0 "ERROR: sql: modify error ~A for ~A~%" a2-5 obj)
|
||||
)
|
||||
(return #t)
|
||||
(label cfg-21)
|
||||
(format
|
||||
(clear s3-1)
|
||||
"update level_info set last_update=last_update, sample_point_update=NULL where level_info_id=~D"
|
||||
(-> arg0 level-info-id)
|
||||
)
|
||||
(let ((a2-7 (sql-query s3-1)))
|
||||
(let ((v1-22 'modify))
|
||||
(b! (= (-> a2-7 error) v1-22) cfg-24 :delay (empty-form))
|
||||
)
|
||||
(format 0 "ERROR: sql: modify error ~A for ~A~%" a2-7 obj)
|
||||
)
|
||||
)
|
||||
(return #t)
|
||||
(label cfg-24)
|
||||
(let ((s3-2 (-> arg0 length))
|
||||
(s2-2 0)
|
||||
)
|
||||
(let ((s1-1 (-> arg0 data s2-2)))
|
||||
(b! #t cfg-35 :delay (nop!))
|
||||
(label cfg-25)
|
||||
(b! (not s1-1) cfg-30 :likely-delay (set! v1-28 s1-1))
|
||||
(set! v1-28 (and (= (-> s1-1 region) obj) (not (logtest? (-> s1-1 flags) (editable-flag no-save)))))
|
||||
(label cfg-30)
|
||||
(b! (not v1-28) cfg-34 :delay (empty-form))
|
||||
(b! (editable-method-22 s1-1 arg0 1 0) cfg-34 :delay (empty-form))
|
||||
(format 0 "ERROR: sql: insert error for ~A~%" s1-1)
|
||||
(return #f)
|
||||
(label cfg-34)
|
||||
(+! s2-2 1)
|
||||
(set! s1-1 (-> arg0 data s2-2))
|
||||
)
|
||||
(label cfg-35)
|
||||
(b! (< s2-2 s3-2) cfg-25)
|
||||
)
|
||||
(b! #t cfg-78 :delay (nop!))
|
||||
(label cfg-37)
|
||||
(b! (nonzero? (-> obj id)) cfg-53 :delay (nop!))
|
||||
(let ((s3-3 (clear *temp-string*)))
|
||||
(format s3-3 "insert into region set level_name='~S',tree='~S'" (-> obj level) (-> obj tree))
|
||||
(let ((a2-11 (-> obj on-enter)))
|
||||
(b! (not a2-11) cfg-40 :delay (nop!))
|
||||
(format s3-3 ",on_enter='~S'" a2-11)
|
||||
)
|
||||
(b! #t cfg-41 :delay (nop!))
|
||||
(label cfg-40)
|
||||
(format s3-3 ",on_enter=''")
|
||||
(label cfg-41)
|
||||
(let ((a2-12 (-> obj on-exit)))
|
||||
(b! (not a2-12) cfg-43 :delay (nop!))
|
||||
(format s3-3 ",on_exit='~S'" a2-12)
|
||||
)
|
||||
(b! #t cfg-44 :delay (nop!))
|
||||
(label cfg-43)
|
||||
(format s3-3 ",on_exit=''")
|
||||
(label cfg-44)
|
||||
(let ((a2-13 (-> obj on-inside)))
|
||||
(b! (not a2-13) cfg-46 :delay (nop!))
|
||||
(format s3-3 ",on_inside='~S'" a2-13)
|
||||
)
|
||||
(b! #t cfg-47 :delay (nop!))
|
||||
(label cfg-46)
|
||||
(format s3-3 ",on_inside=''")
|
||||
(label cfg-47)
|
||||
(let ((s3-4 (sql-query s3-3)))
|
||||
(let ((v1-48 'modify))
|
||||
(b! (!= (-> s3-4 error) v1-48) cfg-51 :delay (empty-form))
|
||||
)
|
||||
(let ((v1-50 (sql-query "select LAST_INSERT_ID()")))
|
||||
(let ((a0-36 'select))
|
||||
(b! (!= (-> v1-50 error) a0-36) cfg-51 :delay (empty-form))
|
||||
)
|
||||
(set! (-> obj id) (the-as uint (string->int (-> v1-50 data 0))))
|
||||
)
|
||||
(b! #t cfg-65 :delay (nop!))
|
||||
(the-as none 0)
|
||||
(label cfg-51)
|
||||
(format 0 "ERROR: sql: insert error ~A for ~A~%" s3-4 obj)
|
||||
)
|
||||
)
|
||||
(set! v0-0 #f)
|
||||
(b! #t cfg-79 :delay (nop!))
|
||||
(the-as none 0)
|
||||
(b! #t cfg-65 :delay (nop!))
|
||||
(label cfg-53)
|
||||
(let ((s3-5 (clear *temp-string*)))
|
||||
(format s3-5 "update region set level_name='~S',tree='~S'" (-> obj level) (-> obj tree))
|
||||
(let ((a2-16 (-> obj on-enter)))
|
||||
(b! (not a2-16) cfg-55 :delay (nop!))
|
||||
(format s3-5 ",on_enter='~S'" a2-16)
|
||||
)
|
||||
(b! #t cfg-56 :delay (nop!))
|
||||
(label cfg-55)
|
||||
(format s3-5 ",on_enter=NULL")
|
||||
(label cfg-56)
|
||||
(let ((a2-17 (-> obj on-exit)))
|
||||
(if a2-17
|
||||
(format s3-5 ",on_exit='~S'" a2-17)
|
||||
(format s3-5 ",on_exit=NULL")
|
||||
)
|
||||
)
|
||||
(let ((a2-18 (-> obj on-inside)))
|
||||
(if a2-18
|
||||
(format s3-5 ",on_inside='~S'" a2-18)
|
||||
(format s3-5 ",on_inside=NULL")
|
||||
)
|
||||
)
|
||||
(format s3-5 " where region_id=~D" (-> obj id))
|
||||
(let ((a2-20 (sql-query s3-5)))
|
||||
(when (!= (-> a2-20 error) 'modify)
|
||||
(format 0 "ERROR: sql: update error ~A for ~A~%" a2-20 obj)
|
||||
(return #f)
|
||||
)
|
||||
)
|
||||
)
|
||||
(label cfg-65)
|
||||
(editable-region-method-10 obj 1)
|
||||
(let* ((s3-6 (-> arg0 length))
|
||||
(s2-3 0)
|
||||
(s1-2 (-> arg0 data s2-3))
|
||||
)
|
||||
(while (< s2-3 s3-6)
|
||||
(when (and s1-2 (= (-> s1-2 region) obj) (not (logtest? (-> s1-2 flags) (editable-flag no-save))))
|
||||
(when (not (editable-method-22 s1-2 arg0 1 0))
|
||||
(format 0 "ERROR: sql: insert error for ~A~%" s1-2)
|
||||
(return #f)
|
||||
)
|
||||
)
|
||||
(+! s2-3 1)
|
||||
(set! s1-2 (-> arg0 data s2-3))
|
||||
)
|
||||
)
|
||||
(label cfg-78)
|
||||
(set! (-> obj changed) #f)
|
||||
(set! v0-0 #t)
|
||||
(set! *collapse-quote* s5-0)
|
||||
)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
(label cfg-79)
|
||||
v0-0
|
||||
)
|
||||
|
||||
(defmethod editable-region-method-11 editable-region ((obj editable-region) (arg0 vector) (arg1 int))
|
||||
(local-vars (sv-32 vector2h))
|
||||
@ -120,7 +307,7 @@
|
||||
(add-debug-x #t (bucket-id debug-no-zbuf1) arg0 (new 'static 'rgba :r #xff :g #xff :a #x80))
|
||||
(let ((s3-0 add-debug-text-3d)
|
||||
(s2-0 #t)
|
||||
(s1-0 (bucket-id debug-no-zbuf1))
|
||||
(s1-0 318)
|
||||
)
|
||||
(format (clear *temp-string*) "region-~D~%" (-> obj id))
|
||||
(s3-0 s2-0 (the-as bucket-id s1-0) *temp-string* arg0 (font-color white) sv-32)
|
||||
@ -131,7 +318,7 @@
|
||||
(when s4-1
|
||||
(let ((s3-1 add-debug-text-3d)
|
||||
(s2-1 #t)
|
||||
(s1-1 (bucket-id debug-no-zbuf1))
|
||||
(s1-1 318)
|
||||
)
|
||||
(format (clear *temp-string*) "(on-enter ~S)" s4-1)
|
||||
(s3-1 s2-1 (the-as bucket-id s1-1) *temp-string* arg0 (font-color white) sv-32)
|
||||
@ -1152,7 +1339,167 @@
|
||||
-1.0
|
||||
)
|
||||
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
;; WARN: Return type mismatch int vs symbol.
|
||||
(defmethod editable-method-29 editable-face ((obj editable-face) (arg0 editable-filter))
|
||||
(local-vars
|
||||
(sv-208 (inline-array vector))
|
||||
(sv-216 int)
|
||||
(sv-288 (array editable-point))
|
||||
(sv-292 int)
|
||||
(sv-296 int)
|
||||
(sv-368 matrix)
|
||||
(sv-372 editable-point)
|
||||
(sv-376 float)
|
||||
(sv-380 symbol)
|
||||
(sv-400 float)
|
||||
)
|
||||
(if (or (logtest? arg0 (editable-filter water-command)) (logtest? (-> obj flags) (editable-flag mark)))
|
||||
(return (the-as symbol #f))
|
||||
)
|
||||
(logior! (-> obj flags) (editable-flag mark))
|
||||
(let ((s5-0 (new 'stack-no-clear 'inline-array 'vector 6)))
|
||||
(dotimes (v1-7 6)
|
||||
(set! (-> s5-0 v1-7 quad) (the-as uint128 0))
|
||||
)
|
||||
(let ((s4-0 (editable-face-method-30 obj s5-0)))
|
||||
(when (and (>= s4-0 4) (>= (-> obj length) 3))
|
||||
(let ((v1-14 0))
|
||||
(dotimes (a0-7 s4-0)
|
||||
(if (logtest? (-> obj vertex a0-7 flags) (editable-flag selected))
|
||||
(+! v1-14 1)
|
||||
)
|
||||
)
|
||||
(cond
|
||||
((= v1-14 s4-0)
|
||||
(set! arg0 (logior arg0 (editable-filter load)))
|
||||
)
|
||||
((= v1-14 2)
|
||||
(let ((v1-15 (new 'stack-no-clear 'inline-array 'vector 6)))
|
||||
(dotimes (a0-12 6)
|
||||
(set! (-> v1-15 a0-12 quad) (the-as uint128 0))
|
||||
)
|
||||
(set! sv-208 v1-15)
|
||||
)
|
||||
(set! sv-216 0)
|
||||
(dotimes (s2-2 s4-0)
|
||||
(when (not (logtest? (-> obj vertex s2-2 flags) (editable-flag selected)))
|
||||
(set! (-> sv-208 sv-216 quad) (-> (edit-get-trans (-> obj vertex s2-2)) quad))
|
||||
(set! sv-216 (+ sv-216 1))
|
||||
)
|
||||
)
|
||||
(dotimes (s2-3 s4-0)
|
||||
(when (logtest? (-> obj vertex s2-3 flags) (editable-flag selected))
|
||||
(set! (-> sv-208 sv-216 quad) (-> (edit-get-trans (-> obj vertex s2-3)) quad))
|
||||
(set! sv-216 (+ sv-216 1))
|
||||
)
|
||||
)
|
||||
(normal-of-plane (-> obj normal) (-> sv-208 0) (-> sv-208 1) (-> sv-208 2))
|
||||
(set! (-> obj center quad) (-> (edit-get-trans obj) quad))
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (not (logtest? arg0 (editable-filter load)))
|
||||
(when (= (-> obj normal w) 0.0)
|
||||
(editable-face-method-31 obj (-> obj normal))
|
||||
(set! (-> obj center quad) (-> (edit-get-trans obj) quad))
|
||||
)
|
||||
(let ((s3-2 0)
|
||||
(s2-5 (-> obj normal))
|
||||
(s1-2 (-> obj center))
|
||||
)
|
||||
(while (< s3-2 s4-0)
|
||||
(when (logtest? (-> obj vertex s3-2 flags) (editable-flag selected))
|
||||
(let* ((a1-14 (vector-! (new 'stack-no-clear 'vector) (-> s5-0 s3-2) s1-2))
|
||||
(f0-2 (vector-dot a1-14 s2-5))
|
||||
)
|
||||
(edit-coord!
|
||||
(-> obj vertex s3-2)
|
||||
(vector+float*! a1-14 (-> s5-0 s3-2) s2-5 (- f0-2))
|
||||
(editable-flag x y z no-plane-snap)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s3-2 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! sv-288
|
||||
(the-as
|
||||
(array editable-point)
|
||||
((method-of-type array new)
|
||||
(the-as symbol (new 'stack-no-clear 'array 'editable-point 6))
|
||||
array
|
||||
editable-point
|
||||
6
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! sv-292 (+ (-> obj length) -1))
|
||||
(set! sv-296 1)
|
||||
(editable-face-method-31 obj (-> obj normal))
|
||||
(dotimes (v1-85 sv-292)
|
||||
(set! (-> sv-288 v1-85) (-> obj vertex (+ v1-85 1)))
|
||||
)
|
||||
(set! sv-368 (new-stack-matrix0))
|
||||
(set! sv-372 (the-as editable-point #f))
|
||||
(set! sv-376 (the-as float 0.0))
|
||||
(set! sv-380 #t)
|
||||
(vector-normalize!
|
||||
(vector-! (-> sv-368 vector 2) (edit-get-trans obj) (edit-get-trans (-> obj vertex 0)))
|
||||
1.0
|
||||
)
|
||||
(vector-normalize! (editable-face-method-31 obj (-> sv-368 vector 1)) 1.0)
|
||||
(vector-normalize!
|
||||
(vector-cross! (the-as vector (-> sv-368 vector)) (-> sv-368 vector 2) (-> sv-368 vector 1))
|
||||
1.0
|
||||
)
|
||||
(set! (-> sv-368 trans quad) (-> (edit-get-trans (-> obj vertex 0)) quad))
|
||||
(set! (-> sv-368 trans w) 1.0)
|
||||
(matrix-4x4-inverse! sv-368 sv-368)
|
||||
(while (< sv-296 (-> obj length))
|
||||
(set! sv-372 (the-as editable-point #f))
|
||||
(dotimes (s5-4 sv-292)
|
||||
(when (-> sv-288 s5-4)
|
||||
(let* ((a1-27 (edit-get-trans (-> sv-288 s5-4)))
|
||||
(a0-48 (vector-matrix*! (new 'stack-no-clear 'vector) a1-27 sv-368))
|
||||
)
|
||||
(set! sv-400 (vector-y-angle a0-48))
|
||||
)
|
||||
(cond
|
||||
(sv-380
|
||||
(when (or (not sv-372) (< sv-376 sv-400))
|
||||
(set! sv-372 (-> sv-288 s5-4))
|
||||
(set! sv-376 sv-400)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(when (or (not sv-372) (< sv-400 sv-376))
|
||||
(set! sv-372 (-> sv-288 s5-4))
|
||||
(set! sv-376 sv-400)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> obj vertex sv-296) sv-372)
|
||||
(dotimes (v1-137 sv-292)
|
||||
(if (= sv-372 (-> sv-288 v1-137))
|
||||
(set! (-> sv-288 v1-137) #f)
|
||||
)
|
||||
)
|
||||
(set! sv-296 (+ sv-296 1))
|
||||
(set! sv-380 (not sv-380))
|
||||
)
|
||||
(if (< (vector-dot (-> obj normal) (editable-face-method-31 obj (new 'stack-no-clear 'vector))) 0.0)
|
||||
(logxor! (-> obj flags) (editable-flag orient))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(editable-face-method-31 obj (-> obj normal))
|
||||
(set! (-> obj center quad) (-> (edit-get-trans obj) quad))
|
||||
(the-as symbol 0)
|
||||
)
|
||||
|
||||
(defmethod editable-method-10 editable-face ((obj editable-face))
|
||||
(local-vars (sv-112 int))
|
||||
@ -1351,7 +1698,7 @@
|
||||
)
|
||||
(when (< 0.0 (-> gp-0 z))
|
||||
(reverse-transform-point! gp-0 (edit-get-trans (-> obj vertex 0)) s5-0 arg0)
|
||||
(let ((s3-1 (the-as object (new 'stack-no-clear 'inline-array 'vector 4))))
|
||||
(let ((s3-1 (the-as object (new 'stack-no-clear 'matrix))))
|
||||
(dotimes (v1-6 4)
|
||||
(set! (-> (the-as (inline-array vector) s3-1) v1-6 quad) (the-as uint128 0))
|
||||
)
|
||||
|
@ -217,7 +217,7 @@
|
||||
:size-assert #x41c
|
||||
:flag-assert #x150000041c
|
||||
(:methods
|
||||
(new (symbol type int symbol) _type_ 0)
|
||||
(new (symbol type string) _type_ 0)
|
||||
(init-from-sql! (_type_ string string) symbol 9)
|
||||
(exec-sql! (_type_) symbol 10)
|
||||
(indexof-nav-node (_type_ int) int 11)
|
||||
@ -235,7 +235,7 @@
|
||||
|
||||
|
||||
;; WARN: Return type mismatch object vs mysql-nav-graph.
|
||||
(defmethod new mysql-nav-graph ((allocation symbol) (type-to-make type) (arg0 int) (arg1 symbol))
|
||||
(defmethod new mysql-nav-graph ((allocation symbol) (type-to-make type) (arg0 string))
|
||||
(let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
|
||||
(if (zero? gp-0)
|
||||
(return (the-as mysql-nav-graph 0))
|
||||
@ -248,6 +248,7 @@
|
||||
(set! (-> gp-0 visnode-array length) 0)
|
||||
(let ((s4-0 (clear *temp-string*)))
|
||||
(format *temp-string* "select nav_graph_id from nav_graph where name='~S'" arg0)
|
||||
(format 0 "HERE B~%")
|
||||
(let ((a2-6 (sql-query s4-0)))
|
||||
(when (!= (-> a2-6 error) 'select)
|
||||
(format 0 "ERROR: sql: select error ~A for ~A~%" a2-6 gp-0)
|
||||
@ -757,6 +758,7 @@ returns `-1` if none is found"
|
||||
(set! (-> obj visnode-array length) 0)
|
||||
(let ((s3-0 (clear *temp-string*)))
|
||||
(format s3-0 "select nav_graph_id from nav_graph where name='~S'" arg0)
|
||||
(format 0 "HERE A~%")
|
||||
(let ((a2-2 (sql-query s3-0)))
|
||||
(when (!= (-> a2-2 error) 'select)
|
||||
(format 0 "ERROR: sql: select error ~A for ~A~%" a2-2 obj)
|
||||
@ -1200,4 +1202,3 @@ returns `-1` if none is found"
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -614,6 +614,8 @@
|
||||
|
||||
;; the result that the C Kernel will send us.
|
||||
(define *sql-result* (the-as sql-result #f))
|
||||
;; TODO - no idea what this is, but some sort of symbol set on the C side as well.
|
||||
(define-extern *collapse-quote* symbol)
|
||||
|
||||
(defmacro defbehavior (name process-type bindings &rest body)
|
||||
"define a new behavior. This is simply a function where self is bound to the process register,
|
||||
|
@ -7,3 +7,556 @@
|
||||
|
||||
;; DECOMP BEGINS
|
||||
|
||||
;; this file is debug only
|
||||
(declare-file (debug))
|
||||
|
||||
(defun probe-for-clear-collision? ((arg0 vector) (arg1 vector))
|
||||
(let ((s5-0 (new 'stack-no-clear 'collide-query)))
|
||||
(set! (-> s5-0 start-pos quad) (-> arg0 quad))
|
||||
(vector-! (-> s5-0 move-dist) arg1 arg0)
|
||||
(let ((v1-2 s5-0))
|
||||
(set! (-> v1-2 radius) 4096.0)
|
||||
(set! (-> v1-2 collide-with) (collide-spec backgnd))
|
||||
(set! (-> v1-2 ignore-process0) #f)
|
||||
(set! (-> v1-2 ignore-process1) #f)
|
||||
(set! (-> v1-2 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
|
||||
(set! (-> v1-2 action-mask) (collide-action solid))
|
||||
)
|
||||
(when (< (fill-and-probe-using-line-sphere *collide-cache* s5-0) 0.0)
|
||||
(let ((s4-0 (new 'stack-no-clear 'vector)))
|
||||
(set! (-> s4-0 quad) (-> arg0 quad))
|
||||
(let* ((f0-2 (vector-vector-distance s4-0 arg1))
|
||||
(s3-1 (+ (the int (* 0.000008138021 f0-2)) 1))
|
||||
(s2-0 (vector-normalize-copy! (new 'stack-no-clear 'vector) (-> s5-0 move-dist) 110592.0))
|
||||
)
|
||||
(dotimes (s1-0 s3-1)
|
||||
(set! (-> s5-0 start-pos quad) (-> s4-0 quad))
|
||||
(vector-! (-> s5-0 move-dist) arg1 s4-0)
|
||||
(if (< 122880.0 (vector-length (-> s5-0 move-dist)))
|
||||
(vector-normalize! (-> s5-0 move-dist) 122880.0)
|
||||
)
|
||||
(let ((v1-15 s5-0))
|
||||
(set! (-> v1-15 radius) 12288.0)
|
||||
(set! (-> v1-15 collide-with) (collide-spec backgnd))
|
||||
(set! (-> v1-15 ignore-process0) #f)
|
||||
(set! (-> v1-15 ignore-process1) #f)
|
||||
(set! (-> v1-15 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
|
||||
(set! (-> v1-15 action-mask) (collide-action solid))
|
||||
)
|
||||
(if (>= (fill-and-probe-using-line-sphere *collide-cache* s5-0) 0.0)
|
||||
(return #f)
|
||||
)
|
||||
(vector+! s4-0 s4-0 s2-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
#t
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun hover-nav-graph-process-points ()
|
||||
(local-vars (v1-10 symbol))
|
||||
(let ((v1-0 (get-nav-graph-editor)))
|
||||
(when v1-0
|
||||
(let* ((gp-0 (-> v1-0 nav-graph))
|
||||
(s5-0 (-> gp-0 node-array length))
|
||||
)
|
||||
(dotimes (s4-0 s5-0)
|
||||
(let ((s3-0 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s4-0))))
|
||||
(when (< s4-0 (+ s5-0 -1))
|
||||
(let ((s2-0 (+ s4-0 1)))
|
||||
(while (< s2-0 s5-0)
|
||||
(let ((s1-0 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s2-0))))
|
||||
(dotimes (v1-8 (-> gp-0 edge-array length))
|
||||
(let* ((a1-1 (-> gp-0 edge-array data v1-8))
|
||||
(a0-8 (-> a1-1 runtime-node-id-1))
|
||||
(a1-2 (-> a1-1 runtime-node-id-2))
|
||||
)
|
||||
(when (or (and (= s4-0 a0-8) (= s2-0 a1-2)) (and (= s4-0 a1-2) (= s2-0 a0-8)))
|
||||
(set! v1-10 #t)
|
||||
(goto cfg-19)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! v1-10 #f)
|
||||
(label cfg-19)
|
||||
(when (not v1-10)
|
||||
(when (and (< (vector-vector-distance (the-as vector s3-0) (the-as vector s1-0)) 122880.0)
|
||||
(probe-for-clear-collision? (the-as vector s3-0) (the-as vector s1-0))
|
||||
(probe-for-clear-collision? (the-as vector s1-0) (the-as vector s3-0))
|
||||
)
|
||||
(let ((v1-17 (alloc-new-edge! gp-0)))
|
||||
(when (!= v1-17 -1)
|
||||
(let ((v1-20 (-> gp-0 edge-array data v1-17)))
|
||||
(set! (-> v1-20 runtime-node-id-1) s4-0)
|
||||
(set! (-> v1-20 runtime-node-id-2) s2-0)
|
||||
(set! (-> v1-20 directionality) (nav-directionality bi_directional))
|
||||
(set! (-> v1-20 speed_limit) 122880.0)
|
||||
(set! (-> v1-20 density) 1.0)
|
||||
(set! (-> v1-20 traffic_edge_flag) 0)
|
||||
(set! (-> v1-20 nav_clock_mask) (nav-clock-mask))
|
||||
(set! (-> v1-20 nav_clock_type) (nav-clock-type no-clock))
|
||||
(set! (-> v1-20 width) 0.0)
|
||||
(set! (-> v1-20 minimap_edge_flag) (nav-minimap-edge-flag))
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s2-0 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun hover-nav-graph-output ()
|
||||
(local-vars
|
||||
(sv-16 int)
|
||||
(sv-32 (function _varargs_ object))
|
||||
(sv-48 symbol)
|
||||
(sv-64 string)
|
||||
(sv-80 int)
|
||||
(sv-96 (function _varargs_ object))
|
||||
(sv-112 symbol)
|
||||
(sv-128 string)
|
||||
)
|
||||
(let ((v1-0 (get-nav-graph-editor)))
|
||||
(when v1-0
|
||||
(let* ((gp-0 (-> v1-0 nav-graph))
|
||||
(s5-0 (-> gp-0 node-array length))
|
||||
(s4-0 0)
|
||||
)
|
||||
(dotimes (s3-0 s5-0)
|
||||
(when (nonzero? (-> gp-0 node-array data s3-0 nav_node_id))
|
||||
(let ((s2-0 (the-as object (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s3-0)))))
|
||||
(format
|
||||
#t
|
||||
"(~d (~m ~m ~m) ("
|
||||
s4-0
|
||||
(-> (the-as vector s2-0) x)
|
||||
(-> (the-as vector s2-0) y)
|
||||
(-> (the-as vector s2-0) z)
|
||||
)
|
||||
(dotimes (s1-0 (-> gp-0 edge-array length))
|
||||
(let* ((v1-11 (-> gp-0 edge-array data s1-0))
|
||||
(s0-0 (-> v1-11 runtime-node-id-1))
|
||||
)
|
||||
(set! sv-16 (-> v1-11 runtime-node-id-2))
|
||||
(when (= s3-0 s0-0)
|
||||
(let ((a1-2 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 sv-16))))
|
||||
(set! sv-32 format)
|
||||
(set! sv-48 #t)
|
||||
(set! sv-64 "(~d ~m) ")
|
||||
(set! sv-80 sv-16)
|
||||
(let ((a3-1 (vector-vector-distance (the-as vector s2-0) (the-as vector a1-2))))
|
||||
(sv-32 sv-48 sv-64 sv-80 a3-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (= s3-0 sv-16)
|
||||
(let ((a1-4 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s0-0))))
|
||||
(set! sv-96 format)
|
||||
(set! sv-112 #t)
|
||||
(set! sv-128 "(~d ~m) ")
|
||||
(let ((a3-2 (vector-vector-distance (the-as vector s2-0) (the-as vector a1-4))))
|
||||
(sv-96 sv-112 sv-128 s0-0 a3-2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(format #t "))~%")
|
||||
(+! s4-0 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
#f
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(define *axes-table* (new 'static 'boxed-array :type vector
|
||||
(new 'static 'vector :x 1.0 :w 1.0)
|
||||
(new 'static 'vector :y 1.0 :w 1.0)
|
||||
(new 'static 'vector :z 1.0 :w 1.0)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype hover-nav-bsp-point (list-node)
|
||||
((index int32 :offset-assert 8)
|
||||
(pos vector :inline :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; WARN: Return type mismatch structure vs hover-nav-bsp-point.
|
||||
(defmethod new hover-nav-bsp-point ((allocation symbol) (type-to-make type))
|
||||
(let ((t9-0 (method-of-type structure new))
|
||||
(v1-1 type-to-make)
|
||||
)
|
||||
(-> type-to-make size)
|
||||
(let ((v0-0 (t9-0 allocation v1-1)))
|
||||
(set! (-> (the-as hover-nav-bsp-point v0-0) next) #f)
|
||||
(set! (-> (the-as hover-nav-bsp-point v0-0) prev) #f)
|
||||
(the-as hover-nav-bsp-point v0-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype hover-nav-bsp-node (structure)
|
||||
((split-plane vector :inline :offset-assert 0)
|
||||
(point-list hover-nav-bsp-point :offset-assert 16)
|
||||
(left hover-nav-bsp-node :offset-assert 20)
|
||||
(right hover-nav-bsp-node :offset-assert 24)
|
||||
)
|
||||
:method-count-assert 11
|
||||
:size-assert #x1c
|
||||
:flag-assert #xb0000001c
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
(hover-nav-bsp-node-method-9 (_type_) none 9)
|
||||
(hover-nav-bsp-node-method-10 (_type_ int) none 10)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; WARN: Return type mismatch structure vs hover-nav-bsp-node.
|
||||
(defmethod new hover-nav-bsp-node ((allocation symbol) (type-to-make type))
|
||||
(let ((t9-0 (method-of-type structure new))
|
||||
(v1-1 type-to-make)
|
||||
)
|
||||
(-> type-to-make size)
|
||||
(let ((v0-0 (t9-0 allocation v1-1)))
|
||||
(set! (-> (the-as hover-nav-bsp-node v0-0) point-list) #f)
|
||||
(set! (-> (the-as hover-nav-bsp-node v0-0) left) #f)
|
||||
(set! (-> (the-as hover-nav-bsp-node v0-0) right) #f)
|
||||
(the-as hover-nav-bsp-node v0-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype hover-nav-bsp (structure)
|
||||
((root hover-nav-bsp-node :offset-assert 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
|
||||
(defmethod hover-nav-bsp-node-method-9 hover-nav-bsp-node ((obj hover-nav-bsp-node))
|
||||
(let ((v1-0 (-> obj split-plane)))
|
||||
(format #t "((~,,1f ~,,1f ~,,1f ~m)~% " (-> v1-0 x) (-> v1-0 y) (-> v1-0 z) (-> v1-0 w))
|
||||
)
|
||||
(let ((v1-2 (the-as list-node (-> obj point-list))))
|
||||
(while v1-2
|
||||
(let ((s5-0 (-> v1-2 next)))
|
||||
(format
|
||||
#t
|
||||
"(~d (~m ~m ~m)) "
|
||||
(-> (the-as hover-nav-bsp-point v1-2) index)
|
||||
(-> (the-as hover-nav-bsp-point v1-2) pos x)
|
||||
(-> (the-as hover-nav-bsp-point v1-2) pos y)
|
||||
(-> (the-as hover-nav-bsp-point v1-2) pos z)
|
||||
)
|
||||
(set! v1-2 s5-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (-> obj left)
|
||||
(hover-nav-bsp-node-method-9 (-> obj left))
|
||||
)
|
||||
(if (-> obj right)
|
||||
(hover-nav-bsp-node-method-9 (-> obj right))
|
||||
)
|
||||
(format #t ")~%")
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
(defmethod hover-nav-bsp-node-method-10 hover-nav-bsp-node ((obj hover-nav-bsp-node) (arg0 int))
|
||||
(when (-> obj point-list)
|
||||
(format 0 "build-bsp: ")
|
||||
(let ((s4-0 (new 'stack-no-clear 'vector))
|
||||
(s3-0 0)
|
||||
)
|
||||
(let ((v1-2 (the-as list-node (-> obj point-list))))
|
||||
(while v1-2
|
||||
(set! v1-2 (-> v1-2 next))
|
||||
(+! s3-0 1)
|
||||
)
|
||||
)
|
||||
(format 0 "count ~d ~%" s3-0)
|
||||
(when (< 1 s3-0)
|
||||
(vector-reset! s4-0)
|
||||
(let ((f0-1 (/ 1.0 (the float s3-0)))
|
||||
(a2-1 (the-as list-node (-> obj point-list)))
|
||||
)
|
||||
(while a2-1
|
||||
(let ((v1-9 (-> a2-1 next)))
|
||||
(vector+float*! s4-0 s4-0 (the-as vector (+ (the-as uint a2-1) 16)) f0-1)
|
||||
(set! a2-1 v1-9)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> obj split-plane quad) (-> *axes-table* arg0 quad))
|
||||
(set! (-> obj split-plane w) (- (vector-dot s4-0 (-> obj split-plane))))
|
||||
(let ((s3-1 (the-as list-node (-> obj point-list))))
|
||||
(while s3-1
|
||||
(let ((s4-1 (-> s3-1 next)))
|
||||
(let ((f0-7 (- (vector-dot (the-as vector (+ (the-as uint s3-1) 16)) (-> obj split-plane)))))
|
||||
(cond
|
||||
((= f0-7 (-> obj split-plane w))
|
||||
)
|
||||
((< f0-7 (-> obj split-plane w))
|
||||
(if (not (-> obj left))
|
||||
(set! (-> obj left) (new 'global 'hover-nav-bsp-node))
|
||||
)
|
||||
(let ((v1-21 s3-1))
|
||||
(let ((a0-12 (&-> obj point-list)))
|
||||
(if (= (-> a0-12 0) v1-21)
|
||||
(set! (-> a0-12 0) (the-as hover-nav-bsp-point (-> v1-21 next)))
|
||||
)
|
||||
)
|
||||
(if (-> v1-21 prev)
|
||||
(set! (-> v1-21 prev next) (-> v1-21 next))
|
||||
)
|
||||
(if (-> v1-21 next)
|
||||
(set! (-> v1-21 next prev) (-> v1-21 prev))
|
||||
)
|
||||
(set! (-> v1-21 prev) #f)
|
||||
(set! (-> v1-21 next) #f)
|
||||
)
|
||||
(let ((a0-19 (-> obj left point-list))
|
||||
(v1-25 (&-> (-> obj left) point-list))
|
||||
)
|
||||
(when (zero? s3-1)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= s3-1 a0-19) (= s3-1 v1-25))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a0-19) (!= (-> a0-19 prev) s3-1)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a0-19
|
||||
(set! (-> s3-1 next) a0-19)
|
||||
(set! (-> s3-1 prev) (-> a0-19 prev))
|
||||
(if (-> s3-1 prev)
|
||||
(set! (-> s3-1 prev next) s3-1)
|
||||
)
|
||||
(if (-> s3-1 next)
|
||||
(set! (-> s3-1 next prev) s3-1)
|
||||
)
|
||||
)
|
||||
(if (or (not a0-19) (= a0-19 (-> v1-25 0)))
|
||||
(set! (-> v1-25 0) (the-as hover-nav-bsp-point s3-1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(if (not (-> obj right))
|
||||
(set! (-> obj right) (new 'global 'hover-nav-bsp-node))
|
||||
)
|
||||
(let ((v1-30 s3-1))
|
||||
(let ((a0-22 (&-> obj point-list)))
|
||||
(if (= (-> a0-22 0) v1-30)
|
||||
(set! (-> a0-22 0) (the-as hover-nav-bsp-point (-> v1-30 next)))
|
||||
)
|
||||
)
|
||||
(if (-> v1-30 prev)
|
||||
(set! (-> v1-30 prev next) (-> v1-30 next))
|
||||
)
|
||||
(if (-> v1-30 next)
|
||||
(set! (-> v1-30 next prev) (-> v1-30 prev))
|
||||
)
|
||||
(set! (-> v1-30 prev) #f)
|
||||
(set! (-> v1-30 next) #f)
|
||||
)
|
||||
(let ((v1-32 s3-1)
|
||||
(a1-40 (-> obj right point-list))
|
||||
(a0-31 (&-> (-> obj right) point-list))
|
||||
)
|
||||
(when (zero? v1-32)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= v1-32 a1-40) (= v1-32 a0-31))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a1-40) (!= (-> a1-40 prev) v1-32)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a1-40
|
||||
(set! (-> v1-32 next) a1-40)
|
||||
(set! (-> v1-32 prev) (-> a1-40 prev))
|
||||
(if (-> v1-32 prev)
|
||||
(set! (-> v1-32 prev next) v1-32)
|
||||
)
|
||||
(if (-> v1-32 next)
|
||||
(set! (-> v1-32 next prev) v1-32)
|
||||
)
|
||||
)
|
||||
(if (or (not a1-40) (= a1-40 (-> a0-31 0)))
|
||||
(set! (-> a0-31 0) (the-as hover-nav-bsp-point v1-32))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! s3-1 s4-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (-> obj left)
|
||||
(hover-nav-bsp-node-method-10 (-> obj left) (mod (+ arg0 1) 3))
|
||||
)
|
||||
(if (-> obj right)
|
||||
(hover-nav-bsp-node-method-10 (-> obj right) (mod (+ arg0 1) 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
(define *hover-bsp* (the-as hover-nav-bsp #f))
|
||||
|
||||
(defun hover-nav-graph-output-bsp ()
|
||||
(let ((v1-0 (get-nav-graph-editor)))
|
||||
(when v1-0
|
||||
(let ((s5-0 (-> v1-0 nav-graph))
|
||||
(gp-0 (new 'global 'hover-nav-bsp))
|
||||
)
|
||||
(let ((s4-0 (-> s5-0 node-array length))
|
||||
(s3-0 0)
|
||||
)
|
||||
(set! (-> gp-0 root) (new 'global 'hover-nav-bsp-node))
|
||||
(dotimes (s2-0 s4-0)
|
||||
(when (nonzero? (-> s5-0 node-array data s2-0 nav_node_id))
|
||||
(let ((v1-9 (new 'global 'hover-nav-bsp-point)))
|
||||
(set! (-> v1-9 index) s3-0)
|
||||
(set! (-> v1-9 pos quad)
|
||||
(-> (the-as (pointer uint128) (+ (the-as uint (-> s5-0 node-array data 0 position)) (* 80 s2-0))))
|
||||
)
|
||||
(let ((a1-7 (-> gp-0 root point-list))
|
||||
(a0-8 (&-> (-> gp-0 root) point-list))
|
||||
)
|
||||
(when (zero? v1-9)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= v1-9 a1-7) (= v1-9 a0-8))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a1-7) (!= (-> a1-7 prev) v1-9)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a1-7
|
||||
(set! (-> v1-9 next) a1-7)
|
||||
(set! (-> v1-9 prev) (-> a1-7 prev))
|
||||
(if (-> v1-9 prev)
|
||||
(set! (-> v1-9 prev next) v1-9)
|
||||
)
|
||||
(if (-> v1-9 next)
|
||||
(set! (-> v1-9 next prev) v1-9)
|
||||
)
|
||||
)
|
||||
(if (or (not a1-7) (= a1-7 (-> a0-8 0)))
|
||||
(set! (-> a0-8 0) v1-9)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s3-0 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(hover-nav-bsp-node-method-10 (-> gp-0 root) 0)
|
||||
(set! *hover-bsp* gp-0)
|
||||
gp-0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun hover-nav-network-build-bsp ((arg0 (array hover-nav-bsp-point)))
|
||||
(let ((gp-0 (new 'global 'hover-nav-bsp)))
|
||||
(let ((s4-0 (-> arg0 length))
|
||||
(s3-0 0)
|
||||
)
|
||||
(set! (-> gp-0 root) (new 'global 'hover-nav-bsp-node))
|
||||
(dotimes (s2-0 s4-0)
|
||||
(let ((v1-3 (new 'global 'hover-nav-bsp-point)))
|
||||
(set! (-> v1-3 index) (the-as int (-> arg0 s2-0 next)))
|
||||
(set! (-> v1-3 pos quad) (-> arg0 s2-0 pos quad))
|
||||
(let ((a1-8 (-> gp-0 root point-list))
|
||||
(a0-11 (&-> (-> gp-0 root) point-list))
|
||||
)
|
||||
(when (zero? v1-3)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= v1-3 a1-8) (= v1-3 a0-11))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a1-8) (!= (-> a1-8 prev) v1-3)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a1-8
|
||||
(set! (-> v1-3 next) a1-8)
|
||||
(set! (-> v1-3 prev) (-> a1-8 prev))
|
||||
(if (-> v1-3 prev)
|
||||
(set! (-> v1-3 prev next) v1-3)
|
||||
)
|
||||
(if (-> v1-3 next)
|
||||
(set! (-> v1-3 next prev) v1-3)
|
||||
)
|
||||
)
|
||||
(if (or (not a1-8) (= a1-8 (-> a0-11 0)))
|
||||
(set! (-> a0-11 0) v1-3)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s3-0 1)
|
||||
)
|
||||
)
|
||||
(hover-nav-bsp-node-method-10 (-> gp-0 root) 0)
|
||||
(set! *hover-bsp* gp-0)
|
||||
gp-0
|
||||
)
|
||||
)
|
||||
|
||||
;; WARN: Return type mismatch object vs none.
|
||||
(defun hover-nav-bsp-output ((arg0 hover-nav-bsp))
|
||||
(format #t "(")
|
||||
(hover-nav-bsp-node-method-9 (-> arg0 root))
|
||||
(format #t ")~%")
|
||||
(none)
|
||||
)
|
||||
|
@ -65,6 +65,6 @@ endif ()
|
||||
add_executable(goalc main.cpp)
|
||||
add_executable(goalc-simple simple_main.cpp)
|
||||
|
||||
target_link_libraries(goalc common Zydis compiler sqlite3 SQLiteCpp)
|
||||
target_link_libraries(goalc-simple common Zydis compiler sqlite3 SQLiteCpp)
|
||||
target_link_libraries(goalc common Zydis compiler)
|
||||
target_link_libraries(goalc-simple common Zydis compiler)
|
||||
|
||||
|
2
test/decompiler/reference/jak2/engine/debug/editable-h_REF.gc
generated
vendored
2
test/decompiler/reference/jak2/engine/debug/editable-h_REF.gc
generated
vendored
@ -261,7 +261,7 @@
|
||||
:flag-assert #xd00000030
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
(editable-region-method-9 (_type_ editable-array int int) none 9)
|
||||
(editable-region-method-9 (_type_ editable-array int int) symbol 9)
|
||||
(editable-region-method-10 (_type_ int) symbol 10)
|
||||
(editable-region-method-11 (_type_ vector int) none 11)
|
||||
(editable-region-method-12 (_type_) editable-filter 12)
|
||||
|
408
test/decompiler/reference/jak2/engine/debug/editable_REF.gc
generated
vendored
408
test/decompiler/reference/jak2/engine/debug/editable_REF.gc
generated
vendored
@ -111,7 +111,194 @@
|
||||
)
|
||||
|
||||
;; definition for method 9 of type editable-region
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
(defmethod editable-region-method-9 editable-region ((obj editable-region) (arg0 editable-array) (arg1 int) (arg2 int))
|
||||
(local-vars (v0-0 symbol) (v1-5 object) (v1-28 object))
|
||||
(set! v0-0
|
||||
(when (-> obj changed)
|
||||
(format 0 "NOTICE: saving ~A~%" obj)
|
||||
(let ((s5-0 *collapse-quote*))
|
||||
(set! *collapse-quote* #f)
|
||||
(let ((v1-1 (-> obj tree)))
|
||||
(b! (!= v1-1 'entity) cfg-3 :delay (nop!))
|
||||
(b! #t cfg-78 :delay (nop!))
|
||||
(label cfg-3)
|
||||
(b! (!= v1-1 'light) cfg-17 :delay (nop!))
|
||||
(let ((s3-0 (-> arg0 length))
|
||||
(s2-0 0)
|
||||
)
|
||||
(let ((s1-0 (-> arg0 data s2-0)))
|
||||
(b! #t cfg-15 :delay (nop!))
|
||||
(label cfg-5)
|
||||
(b! (not s1-0) cfg-10 :likely-delay (set! v1-5 s1-0))
|
||||
(set! v1-5 (and (= (-> s1-0 region) obj) (not (logtest? (-> s1-0 flags) (editable-flag no-save)))))
|
||||
(label cfg-10)
|
||||
(b! (not v1-5) cfg-14 :delay (empty-form))
|
||||
(b! (editable-method-22 s1-0 arg0 1 0) cfg-14 :delay (empty-form))
|
||||
(format 0 "ERROR: sql: insert error for ~A~%" s1-0)
|
||||
(return #f)
|
||||
(label cfg-14)
|
||||
(+! s2-0 1)
|
||||
(set! s1-0 (-> arg0 data s2-0))
|
||||
)
|
||||
(label cfg-15)
|
||||
(b! (< s2-0 s3-0) cfg-5)
|
||||
)
|
||||
(b! #t cfg-78 :delay (nop!))
|
||||
(label cfg-17)
|
||||
(b! (!= v1-1 'sample) cfg-37 :delay (nop!))
|
||||
)
|
||||
(let ((s3-1 (clear *temp-string*)))
|
||||
(format s3-1 "delete from sample_point where level_info_id=~D and source='manual'" (-> arg0 level-info-id))
|
||||
(let ((a2-5 (sql-query s3-1)))
|
||||
(let ((v1-18 'modify))
|
||||
(b! (= (-> a2-5 error) v1-18) cfg-21 :delay (empty-form))
|
||||
)
|
||||
(format 0 "ERROR: sql: modify error ~A for ~A~%" a2-5 obj)
|
||||
)
|
||||
(return #t)
|
||||
(label cfg-21)
|
||||
(format
|
||||
(clear s3-1)
|
||||
"update level_info set last_update=last_update, sample_point_update=NULL where level_info_id=~D"
|
||||
(-> arg0 level-info-id)
|
||||
)
|
||||
(let ((a2-7 (sql-query s3-1)))
|
||||
(let ((v1-22 'modify))
|
||||
(b! (= (-> a2-7 error) v1-22) cfg-24 :delay (empty-form))
|
||||
)
|
||||
(format 0 "ERROR: sql: modify error ~A for ~A~%" a2-7 obj)
|
||||
)
|
||||
)
|
||||
(return #t)
|
||||
(label cfg-24)
|
||||
(let ((s3-2 (-> arg0 length))
|
||||
(s2-2 0)
|
||||
)
|
||||
(let ((s1-1 (-> arg0 data s2-2)))
|
||||
(b! #t cfg-35 :delay (nop!))
|
||||
(label cfg-25)
|
||||
(b! (not s1-1) cfg-30 :likely-delay (set! v1-28 s1-1))
|
||||
(set! v1-28 (and (= (-> s1-1 region) obj) (not (logtest? (-> s1-1 flags) (editable-flag no-save)))))
|
||||
(label cfg-30)
|
||||
(b! (not v1-28) cfg-34 :delay (empty-form))
|
||||
(b! (editable-method-22 s1-1 arg0 1 0) cfg-34 :delay (empty-form))
|
||||
(format 0 "ERROR: sql: insert error for ~A~%" s1-1)
|
||||
(return #f)
|
||||
(label cfg-34)
|
||||
(+! s2-2 1)
|
||||
(set! s1-1 (-> arg0 data s2-2))
|
||||
)
|
||||
(label cfg-35)
|
||||
(b! (< s2-2 s3-2) cfg-25)
|
||||
)
|
||||
(b! #t cfg-78 :delay (nop!))
|
||||
(label cfg-37)
|
||||
(b! (nonzero? (-> obj id)) cfg-53 :delay (nop!))
|
||||
(let ((s3-3 (clear *temp-string*)))
|
||||
(format s3-3 "insert into region set level_name='~S',tree='~S'" (-> obj level) (-> obj tree))
|
||||
(let ((a2-11 (-> obj on-enter)))
|
||||
(b! (not a2-11) cfg-40 :delay (nop!))
|
||||
(format s3-3 ",on_enter='~S'" a2-11)
|
||||
)
|
||||
(b! #t cfg-41 :delay (nop!))
|
||||
(label cfg-40)
|
||||
(format s3-3 ",on_enter=''")
|
||||
(label cfg-41)
|
||||
(let ((a2-12 (-> obj on-exit)))
|
||||
(b! (not a2-12) cfg-43 :delay (nop!))
|
||||
(format s3-3 ",on_exit='~S'" a2-12)
|
||||
)
|
||||
(b! #t cfg-44 :delay (nop!))
|
||||
(label cfg-43)
|
||||
(format s3-3 ",on_exit=''")
|
||||
(label cfg-44)
|
||||
(let ((a2-13 (-> obj on-inside)))
|
||||
(b! (not a2-13) cfg-46 :delay (nop!))
|
||||
(format s3-3 ",on_inside='~S'" a2-13)
|
||||
)
|
||||
(b! #t cfg-47 :delay (nop!))
|
||||
(label cfg-46)
|
||||
(format s3-3 ",on_inside=''")
|
||||
(label cfg-47)
|
||||
(let ((s3-4 (sql-query s3-3)))
|
||||
(let ((v1-48 'modify))
|
||||
(b! (!= (-> s3-4 error) v1-48) cfg-51 :delay (empty-form))
|
||||
)
|
||||
(let ((v1-50 (sql-query "select LAST_INSERT_ID()")))
|
||||
(let ((a0-36 'select))
|
||||
(b! (!= (-> v1-50 error) a0-36) cfg-51 :delay (empty-form))
|
||||
)
|
||||
(set! (-> obj id) (the-as uint (string->int (-> v1-50 data 0))))
|
||||
)
|
||||
(b! #t cfg-65 :delay (nop!))
|
||||
(the-as none 0)
|
||||
(label cfg-51)
|
||||
(format 0 "ERROR: sql: insert error ~A for ~A~%" s3-4 obj)
|
||||
)
|
||||
)
|
||||
(set! v0-0 #f)
|
||||
(b! #t cfg-79 :delay (nop!))
|
||||
(the-as none 0)
|
||||
(b! #t cfg-65 :delay (nop!))
|
||||
(label cfg-53)
|
||||
(let ((s3-5 (clear *temp-string*)))
|
||||
(format s3-5 "update region set level_name='~S',tree='~S'" (-> obj level) (-> obj tree))
|
||||
(let ((a2-16 (-> obj on-enter)))
|
||||
(b! (not a2-16) cfg-55 :delay (nop!))
|
||||
(format s3-5 ",on_enter='~S'" a2-16)
|
||||
)
|
||||
(b! #t cfg-56 :delay (nop!))
|
||||
(label cfg-55)
|
||||
(format s3-5 ",on_enter=NULL")
|
||||
(label cfg-56)
|
||||
(let ((a2-17 (-> obj on-exit)))
|
||||
(if a2-17
|
||||
(format s3-5 ",on_exit='~S'" a2-17)
|
||||
(format s3-5 ",on_exit=NULL")
|
||||
)
|
||||
)
|
||||
(let ((a2-18 (-> obj on-inside)))
|
||||
(if a2-18
|
||||
(format s3-5 ",on_inside='~S'" a2-18)
|
||||
(format s3-5 ",on_inside=NULL")
|
||||
)
|
||||
)
|
||||
(format s3-5 " where region_id=~D" (-> obj id))
|
||||
(let ((a2-20 (sql-query s3-5)))
|
||||
(when (!= (-> a2-20 error) 'modify)
|
||||
(format 0 "ERROR: sql: update error ~A for ~A~%" a2-20 obj)
|
||||
(return #f)
|
||||
)
|
||||
)
|
||||
)
|
||||
(label cfg-65)
|
||||
(editable-region-method-10 obj 1)
|
||||
(let* ((s3-6 (-> arg0 length))
|
||||
(s2-3 0)
|
||||
(s1-2 (-> arg0 data s2-3))
|
||||
)
|
||||
(while (< s2-3 s3-6)
|
||||
(when (and s1-2 (= (-> s1-2 region) obj) (not (logtest? (-> s1-2 flags) (editable-flag no-save))))
|
||||
(when (not (editable-method-22 s1-2 arg0 1 0))
|
||||
(format 0 "ERROR: sql: insert error for ~A~%" s1-2)
|
||||
(return #f)
|
||||
)
|
||||
)
|
||||
(+! s2-3 1)
|
||||
(set! s1-2 (-> arg0 data s2-3))
|
||||
)
|
||||
)
|
||||
(label cfg-78)
|
||||
(set! (-> obj changed) #f)
|
||||
(set! v0-0 #t)
|
||||
(set! *collapse-quote* s5-0)
|
||||
)
|
||||
v0-0
|
||||
)
|
||||
)
|
||||
(label cfg-79)
|
||||
v0-0
|
||||
)
|
||||
|
||||
;; definition for method 11 of type editable-region
|
||||
;; WARN: Return type mismatch int vs none.
|
||||
@ -1238,7 +1425,224 @@
|
||||
)
|
||||
|
||||
;; definition for method 29 of type editable-face
|
||||
;; ERROR: function was not converted to expressions. Cannot decompile.
|
||||
;; INFO: Used lq/sq
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 376 signed mismatch
|
||||
;; WARN: Stack slot offset 400 signed mismatch
|
||||
;; WARN: Stack slot offset 292 signed mismatch
|
||||
;; WARN: Return type mismatch int vs symbol.
|
||||
(defmethod editable-method-29 editable-face ((obj editable-face) (arg0 editable-filter))
|
||||
(local-vars
|
||||
(sv-208 (inline-array vector))
|
||||
(sv-216 int)
|
||||
(sv-288 (array editable-point))
|
||||
(sv-292 int)
|
||||
(sv-296 int)
|
||||
(sv-368 matrix)
|
||||
(sv-372 editable-point)
|
||||
(sv-376 float)
|
||||
(sv-380 symbol)
|
||||
(sv-400 float)
|
||||
)
|
||||
(if (or (logtest? arg0 (editable-filter water-command)) (logtest? (-> obj flags) (editable-flag mark)))
|
||||
(return (the-as symbol #f))
|
||||
)
|
||||
(logior! (-> obj flags) (editable-flag mark))
|
||||
(let ((s5-0 (new 'stack-no-clear 'inline-array 'vector 6)))
|
||||
(dotimes (v1-7 6)
|
||||
(set! (-> s5-0 v1-7 quad) (the-as uint128 0))
|
||||
)
|
||||
(let ((s4-0 (editable-face-method-30 obj s5-0)))
|
||||
(when (and (>= s4-0 4) (>= (-> obj length) 3))
|
||||
(let ((v1-14 0))
|
||||
(dotimes (a0-7 s4-0)
|
||||
(if (logtest? (-> obj vertex a0-7 flags) (editable-flag selected))
|
||||
(+! v1-14 1)
|
||||
)
|
||||
)
|
||||
(cond
|
||||
((= v1-14 s4-0)
|
||||
(set! arg0 (logior arg0 (editable-filter load)))
|
||||
)
|
||||
((= v1-14 2)
|
||||
(let ((v1-15 (new 'stack-no-clear 'inline-array 'vector 6)))
|
||||
(dotimes (a0-12 6)
|
||||
(set! (-> v1-15 a0-12 quad) (the-as uint128 0))
|
||||
)
|
||||
(set! sv-208 v1-15)
|
||||
)
|
||||
(set! sv-216 0)
|
||||
(dotimes (s2-2 s4-0)
|
||||
(when (not (logtest? (-> obj vertex s2-2 flags) (editable-flag selected)))
|
||||
(set! (-> sv-208 sv-216 quad) (-> (edit-get-trans (-> obj vertex s2-2)) quad))
|
||||
(set! sv-216 (+ sv-216 1))
|
||||
)
|
||||
)
|
||||
(dotimes (s2-3 s4-0)
|
||||
(when (logtest? (-> obj vertex s2-3 flags) (editable-flag selected))
|
||||
(set! (-> sv-208 sv-216 quad) (-> (edit-get-trans (-> obj vertex s2-3)) quad))
|
||||
(set! sv-216 (+ sv-216 1))
|
||||
)
|
||||
)
|
||||
(normal-of-plane (-> obj normal) (-> sv-208 0) (-> sv-208 1) (-> sv-208 2))
|
||||
(set! (-> obj center quad) (-> (edit-get-trans obj) quad))
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (not (logtest? arg0 (editable-filter load)))
|
||||
(when (= (-> obj normal w) 0.0)
|
||||
(editable-face-method-31 obj (-> obj normal))
|
||||
(set! (-> obj center quad) (-> (edit-get-trans obj) quad))
|
||||
)
|
||||
(let ((s3-2 0)
|
||||
(s2-5 (-> obj normal))
|
||||
(s1-2 (-> obj center))
|
||||
)
|
||||
(while (< s3-2 s4-0)
|
||||
(when (logtest? (-> obj vertex s3-2 flags) (editable-flag selected))
|
||||
(let* ((a1-14 (vector-! (new 'stack-no-clear 'vector) (-> s5-0 s3-2) s1-2))
|
||||
(f0-2 (vector-dot a1-14 s2-5))
|
||||
)
|
||||
(edit-coord!
|
||||
(-> obj vertex s3-2)
|
||||
(vector+float*! a1-14 (-> s5-0 s3-2) s2-5 (- f0-2))
|
||||
(editable-flag x y z no-plane-snap)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s3-2 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! sv-288
|
||||
(the-as
|
||||
(array editable-point)
|
||||
((method-of-type array new)
|
||||
(the-as symbol (new 'stack-no-clear 'array 'editable-point 6))
|
||||
array
|
||||
editable-point
|
||||
6
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! sv-292 (+ (-> obj length) -1))
|
||||
(set! sv-296 1)
|
||||
(editable-face-method-31 obj (-> obj normal))
|
||||
(dotimes (v1-85 sv-292)
|
||||
(set! (-> sv-288 v1-85) (-> obj vertex (+ v1-85 1)))
|
||||
)
|
||||
(set! sv-368 (new-stack-matrix0))
|
||||
(set! sv-372 (the-as editable-point #f))
|
||||
(set! sv-376 (the-as float 0.0))
|
||||
(set! sv-380 #t)
|
||||
(vector-normalize!
|
||||
(vector-! (-> sv-368 vector 2) (edit-get-trans obj) (edit-get-trans (-> obj vertex 0)))
|
||||
1.0
|
||||
)
|
||||
(vector-normalize! (editable-face-method-31 obj (-> sv-368 vector 1)) 1.0)
|
||||
(vector-normalize!
|
||||
(vector-cross! (the-as vector (-> sv-368 vector)) (-> sv-368 vector 2) (-> sv-368 vector 1))
|
||||
1.0
|
||||
)
|
||||
(set! (-> sv-368 trans quad) (-> (edit-get-trans (-> obj vertex 0)) quad))
|
||||
(set! (-> sv-368 trans w) 1.0)
|
||||
(matrix-4x4-inverse! sv-368 sv-368)
|
||||
(while (< sv-296 (-> obj length))
|
||||
(set! sv-372 (the-as editable-point #f))
|
||||
(dotimes (s5-4 sv-292)
|
||||
(when (-> sv-288 s5-4)
|
||||
(let* ((a1-27 (edit-get-trans (-> sv-288 s5-4)))
|
||||
(a0-48 (vector-matrix*! (new 'stack-no-clear 'vector) a1-27 sv-368))
|
||||
)
|
||||
(set! sv-400 (vector-y-angle a0-48))
|
||||
)
|
||||
(cond
|
||||
(sv-380
|
||||
(when (or (not sv-372) (< sv-376 sv-400))
|
||||
(set! sv-372 (-> sv-288 s5-4))
|
||||
(set! sv-376 sv-400)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(when (or (not sv-372) (< sv-400 sv-376))
|
||||
(set! sv-372 (-> sv-288 s5-4))
|
||||
(set! sv-376 sv-400)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> obj vertex sv-296) sv-372)
|
||||
(dotimes (v1-137 sv-292)
|
||||
(if (= sv-372 (-> sv-288 v1-137))
|
||||
(set! (-> sv-288 v1-137) #f)
|
||||
)
|
||||
)
|
||||
(set! sv-296 (+ sv-296 1))
|
||||
(set! sv-380 (not sv-380))
|
||||
)
|
||||
(if (< (vector-dot (-> obj normal) (editable-face-method-31 obj (new 'stack-no-clear 'vector))) 0.0)
|
||||
(logxor! (-> obj flags) (editable-flag orient))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(editable-face-method-31 obj (-> obj normal))
|
||||
(set! (-> obj center quad) (-> (edit-get-trans obj) quad))
|
||||
(the-as symbol 0)
|
||||
)
|
||||
|
||||
;; definition for method 10 of type editable-face
|
||||
;; INFO: Used lq/sq
|
||||
|
4
test/decompiler/reference/jak2/engine/debug/nav/mysql-nav-graph_REF.gc
generated
vendored
4
test/decompiler/reference/jak2/engine/debug/nav/mysql-nav-graph_REF.gc
generated
vendored
@ -271,7 +271,7 @@
|
||||
:size-assert #x41c
|
||||
:flag-assert #x150000041c
|
||||
(:methods
|
||||
(new (symbol type int symbol) _type_ 0)
|
||||
(new (symbol type string) _type_ 0)
|
||||
(init-from-sql! (_type_ string string) symbol 9)
|
||||
(exec-sql! (_type_) symbol 10)
|
||||
(indexof-nav-node (_type_ int) int 11)
|
||||
@ -307,7 +307,7 @@
|
||||
|
||||
;; definition for method 0 of type mysql-nav-graph
|
||||
;; WARN: Return type mismatch object vs mysql-nav-graph.
|
||||
(defmethod new mysql-nav-graph ((allocation symbol) (type-to-make type) (arg0 int) (arg1 symbol))
|
||||
(defmethod new mysql-nav-graph ((allocation symbol) (type-to-make type) (arg0 string))
|
||||
(let ((gp-0 (object-new allocation type-to-make (the-as int (-> type-to-make size)))))
|
||||
(if (zero? gp-0)
|
||||
(return (the-as mysql-nav-graph 0))
|
||||
|
2530
test/decompiler/reference/jak2/engine/debug/nav/nav-graph-editor_REF.gc
generated
vendored
Normal file
2530
test/decompiler/reference/jak2/engine/debug/nav/nav-graph-editor_REF.gc
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
618
test/decompiler/reference/jak2/levels/common/enemy/hover/hover-nav-edit_REF.gc
generated
vendored
Normal file
618
test/decompiler/reference/jak2/levels/common/enemy/hover/hover-nav-edit_REF.gc
generated
vendored
Normal file
@ -0,0 +1,618 @@
|
||||
;;-*-Lisp-*-
|
||||
(in-package goal)
|
||||
|
||||
;; this file is debug only
|
||||
(declare-file (debug))
|
||||
|
||||
;; definition for function probe-for-clear-collision?
|
||||
;; INFO: Used lq/sq
|
||||
(defun probe-for-clear-collision? ((arg0 vector) (arg1 vector))
|
||||
(let ((s5-0 (new 'stack-no-clear 'collide-query)))
|
||||
(set! (-> s5-0 start-pos quad) (-> arg0 quad))
|
||||
(vector-! (-> s5-0 move-dist) arg1 arg0)
|
||||
(let ((v1-2 s5-0))
|
||||
(set! (-> v1-2 radius) 4096.0)
|
||||
(set! (-> v1-2 collide-with) (collide-spec backgnd))
|
||||
(set! (-> v1-2 ignore-process0) #f)
|
||||
(set! (-> v1-2 ignore-process1) #f)
|
||||
(set! (-> v1-2 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
|
||||
(set! (-> v1-2 action-mask) (collide-action solid))
|
||||
)
|
||||
(when (< (fill-and-probe-using-line-sphere *collide-cache* s5-0) 0.0)
|
||||
(let ((s4-0 (new 'stack-no-clear 'vector)))
|
||||
(set! (-> s4-0 quad) (-> arg0 quad))
|
||||
(let* ((f0-2 (vector-vector-distance s4-0 arg1))
|
||||
(s3-1 (+ (the int (* 0.000008138021 f0-2)) 1))
|
||||
(s2-0 (vector-normalize-copy! (new 'stack-no-clear 'vector) (-> s5-0 move-dist) 110592.0))
|
||||
)
|
||||
(dotimes (s1-0 s3-1)
|
||||
(set! (-> s5-0 start-pos quad) (-> s4-0 quad))
|
||||
(vector-! (-> s5-0 move-dist) arg1 s4-0)
|
||||
(if (< 122880.0 (vector-length (-> s5-0 move-dist)))
|
||||
(vector-normalize! (-> s5-0 move-dist) 122880.0)
|
||||
)
|
||||
(let ((v1-15 s5-0))
|
||||
(set! (-> v1-15 radius) 12288.0)
|
||||
(set! (-> v1-15 collide-with) (collide-spec backgnd))
|
||||
(set! (-> v1-15 ignore-process0) #f)
|
||||
(set! (-> v1-15 ignore-process1) #f)
|
||||
(set! (-> v1-15 ignore-pat) (new 'static 'pat-surface :noentity #x1 :nojak #x1 :probe #x1 :noendlessfall #x1))
|
||||
(set! (-> v1-15 action-mask) (collide-action solid))
|
||||
)
|
||||
(if (>= (fill-and-probe-using-line-sphere *collide-cache* s5-0) 0.0)
|
||||
(return #f)
|
||||
)
|
||||
(vector+! s4-0 s4-0 s2-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
#t
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for function hover-nav-graph-process-points
|
||||
;; WARN: Return type mismatch int vs none.
|
||||
(defun hover-nav-graph-process-points ()
|
||||
(local-vars (v1-10 symbol))
|
||||
(let ((v1-0 (get-nav-graph-editor)))
|
||||
(when v1-0
|
||||
(let* ((gp-0 (-> v1-0 nav-graph))
|
||||
(s5-0 (-> gp-0 node-array length))
|
||||
)
|
||||
(dotimes (s4-0 s5-0)
|
||||
(let ((s3-0 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s4-0))))
|
||||
(when (< s4-0 (+ s5-0 -1))
|
||||
(let ((s2-0 (+ s4-0 1)))
|
||||
(while (< s2-0 s5-0)
|
||||
(let ((s1-0 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s2-0))))
|
||||
(dotimes (v1-8 (-> gp-0 edge-array length))
|
||||
(let* ((a1-1 (-> gp-0 edge-array data v1-8))
|
||||
(a0-8 (-> a1-1 runtime-node-id-1))
|
||||
(a1-2 (-> a1-1 runtime-node-id-2))
|
||||
)
|
||||
(when (or (and (= s4-0 a0-8) (= s2-0 a1-2)) (and (= s4-0 a1-2) (= s2-0 a0-8)))
|
||||
(set! v1-10 #t)
|
||||
(goto cfg-19)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! v1-10 #f)
|
||||
(label cfg-19)
|
||||
(when (not v1-10)
|
||||
(when (and (< (vector-vector-distance (the-as vector s3-0) (the-as vector s1-0)) 122880.0)
|
||||
(probe-for-clear-collision? (the-as vector s3-0) (the-as vector s1-0))
|
||||
(probe-for-clear-collision? (the-as vector s1-0) (the-as vector s3-0))
|
||||
)
|
||||
(let ((v1-17 (alloc-new-edge! gp-0)))
|
||||
(when (!= v1-17 -1)
|
||||
(let ((v1-20 (-> gp-0 edge-array data v1-17)))
|
||||
(set! (-> v1-20 runtime-node-id-1) s4-0)
|
||||
(set! (-> v1-20 runtime-node-id-2) s2-0)
|
||||
(set! (-> v1-20 directionality) (nav-directionality bi_directional))
|
||||
(set! (-> v1-20 speed_limit) 122880.0)
|
||||
(set! (-> v1-20 density) 1.0)
|
||||
(set! (-> v1-20 traffic_edge_flag) 0)
|
||||
(set! (-> v1-20 nav_clock_mask) (nav-clock-mask))
|
||||
(set! (-> v1-20 nav_clock_type) (nav-clock-type no-clock))
|
||||
(set! (-> v1-20 width) 0.0)
|
||||
(set! (-> v1-20 minimap_edge_flag) (nav-minimap-edge-flag))
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s2-0 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for function hover-nav-graph-output
|
||||
;; INFO: Used lq/sq
|
||||
(defun hover-nav-graph-output ()
|
||||
(local-vars
|
||||
(sv-16 int)
|
||||
(sv-32 (function _varargs_ object))
|
||||
(sv-48 symbol)
|
||||
(sv-64 string)
|
||||
(sv-80 int)
|
||||
(sv-96 (function _varargs_ object))
|
||||
(sv-112 symbol)
|
||||
(sv-128 string)
|
||||
)
|
||||
(let ((v1-0 (get-nav-graph-editor)))
|
||||
(when v1-0
|
||||
(let* ((gp-0 (-> v1-0 nav-graph))
|
||||
(s5-0 (-> gp-0 node-array length))
|
||||
(s4-0 0)
|
||||
)
|
||||
(dotimes (s3-0 s5-0)
|
||||
(when (nonzero? (-> gp-0 node-array data s3-0 nav_node_id))
|
||||
(let ((s2-0 (the-as object (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s3-0)))))
|
||||
(format
|
||||
#t
|
||||
"(~d (~m ~m ~m) ("
|
||||
s4-0
|
||||
(-> (the-as vector s2-0) x)
|
||||
(-> (the-as vector s2-0) y)
|
||||
(-> (the-as vector s2-0) z)
|
||||
)
|
||||
(dotimes (s1-0 (-> gp-0 edge-array length))
|
||||
(let* ((v1-11 (-> gp-0 edge-array data s1-0))
|
||||
(s0-0 (-> v1-11 runtime-node-id-1))
|
||||
)
|
||||
(set! sv-16 (-> v1-11 runtime-node-id-2))
|
||||
(when (= s3-0 s0-0)
|
||||
(let ((a1-2 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 sv-16))))
|
||||
(set! sv-32 format)
|
||||
(set! sv-48 #t)
|
||||
(set! sv-64 "(~d ~m) ")
|
||||
(set! sv-80 sv-16)
|
||||
(let ((a3-1 (vector-vector-distance (the-as vector s2-0) (the-as vector a1-2))))
|
||||
(sv-32 sv-48 sv-64 sv-80 a3-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(when (= s3-0 sv-16)
|
||||
(let ((a1-4 (+ (the-as uint (-> gp-0 node-array data 0 position)) (* 80 s0-0))))
|
||||
(set! sv-96 format)
|
||||
(set! sv-112 #t)
|
||||
(set! sv-128 "(~d ~m) ")
|
||||
(let ((a3-2 (vector-vector-distance (the-as vector s2-0) (the-as vector a1-4))))
|
||||
(sv-96 sv-112 sv-128 s0-0 a3-2)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(format #t "))~%")
|
||||
(+! s4-0 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
#f
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for symbol *axes-table*, type (array vector)
|
||||
(define *axes-table* (new 'static 'boxed-array :type vector
|
||||
(new 'static 'vector :x 1.0 :w 1.0)
|
||||
(new 'static 'vector :y 1.0 :w 1.0)
|
||||
(new 'static 'vector :z 1.0 :w 1.0)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition of type hover-nav-bsp-point
|
||||
(deftype hover-nav-bsp-point (list-node)
|
||||
((index int32 :offset-assert 8)
|
||||
(pos vector :inline :offset-assert 16)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x20
|
||||
:flag-assert #x900000020
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 3 of type hover-nav-bsp-point
|
||||
(defmethod inspect hover-nav-bsp-point ((obj hover-nav-bsp-point))
|
||||
(when (not obj)
|
||||
(set! obj obj)
|
||||
(goto cfg-4)
|
||||
)
|
||||
(format #t "[~8x] ~A~%" obj 'hover-nav-bsp-point)
|
||||
(format #t "~1Tnext: #<list-node @ #x~X>~%" (-> obj next))
|
||||
(format #t "~1Tprev: #<list-node @ #x~X>~%" (-> obj prev))
|
||||
(format #t "~1Tindex: ~D~%" (-> obj index))
|
||||
(format #t "~1Tpos: #<vector @ #x~X>~%" (-> obj pos))
|
||||
(label cfg-4)
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for method 0 of type hover-nav-bsp-point
|
||||
;; WARN: Return type mismatch structure vs hover-nav-bsp-point.
|
||||
(defmethod new hover-nav-bsp-point ((allocation symbol) (type-to-make type))
|
||||
(let ((t9-0 (method-of-type structure new))
|
||||
(v1-1 type-to-make)
|
||||
)
|
||||
(-> type-to-make size)
|
||||
(let ((v0-0 (t9-0 allocation v1-1)))
|
||||
(set! (-> (the-as hover-nav-bsp-point v0-0) next) #f)
|
||||
(set! (-> (the-as hover-nav-bsp-point v0-0) prev) #f)
|
||||
(the-as hover-nav-bsp-point v0-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition of type hover-nav-bsp-node
|
||||
(deftype hover-nav-bsp-node (structure)
|
||||
((split-plane vector :inline :offset-assert 0)
|
||||
(point-list hover-nav-bsp-point :offset-assert 16)
|
||||
(left hover-nav-bsp-node :offset-assert 20)
|
||||
(right hover-nav-bsp-node :offset-assert 24)
|
||||
)
|
||||
:method-count-assert 11
|
||||
:size-assert #x1c
|
||||
:flag-assert #xb0000001c
|
||||
(:methods
|
||||
(new (symbol type) _type_ 0)
|
||||
(hover-nav-bsp-node-method-9 (_type_) none 9)
|
||||
(hover-nav-bsp-node-method-10 (_type_ int) none 10)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for method 3 of type hover-nav-bsp-node
|
||||
(defmethod inspect hover-nav-bsp-node ((obj hover-nav-bsp-node))
|
||||
(when (not obj)
|
||||
(set! obj obj)
|
||||
(goto cfg-4)
|
||||
)
|
||||
(format #t "[~8x] ~A~%" obj 'hover-nav-bsp-node)
|
||||
(format #t "~1Tsplit-plane: #<vector @ #x~X>~%" (-> obj split-plane))
|
||||
(format #t "~1Tpoint-list: #<hover-nav-bsp-point @ #x~X>~%" (-> obj point-list))
|
||||
(format #t "~1Tleft: #<hover-nav-bsp-node @ #x~X>~%" (-> obj left))
|
||||
(format #t "~1Tright: #<hover-nav-bsp-node @ #x~X>~%" (-> obj right))
|
||||
(label cfg-4)
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for method 0 of type hover-nav-bsp-node
|
||||
;; WARN: Return type mismatch structure vs hover-nav-bsp-node.
|
||||
(defmethod new hover-nav-bsp-node ((allocation symbol) (type-to-make type))
|
||||
(let ((t9-0 (method-of-type structure new))
|
||||
(v1-1 type-to-make)
|
||||
)
|
||||
(-> type-to-make size)
|
||||
(let ((v0-0 (t9-0 allocation v1-1)))
|
||||
(set! (-> (the-as hover-nav-bsp-node v0-0) point-list) #f)
|
||||
(set! (-> (the-as hover-nav-bsp-node v0-0) left) #f)
|
||||
(set! (-> (the-as hover-nav-bsp-node v0-0) right) #f)
|
||||
(the-as hover-nav-bsp-node v0-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition of type hover-nav-bsp
|
||||
(deftype hover-nav-bsp (structure)
|
||||
((root hover-nav-bsp-node :offset-assert 0)
|
||||
)
|
||||
:method-count-assert 9
|
||||
:size-assert #x4
|
||||
:flag-assert #x900000004
|
||||
)
|
||||
|
||||
;; definition for method 3 of type hover-nav-bsp
|
||||
(defmethod inspect hover-nav-bsp ((obj hover-nav-bsp))
|
||||
(when (not obj)
|
||||
(set! obj obj)
|
||||
(goto cfg-4)
|
||||
)
|
||||
(format #t "[~8x] ~A~%" obj 'hover-nav-bsp)
|
||||
(format #t "~1Troot: #<hover-nav-bsp-node @ #x~X>~%" (-> obj root))
|
||||
(label cfg-4)
|
||||
obj
|
||||
)
|
||||
|
||||
;; definition for method 9 of type hover-nav-bsp-node
|
||||
;; WARN: Return type mismatch int vs none.
|
||||
(defmethod hover-nav-bsp-node-method-9 hover-nav-bsp-node ((obj hover-nav-bsp-node))
|
||||
(let ((v1-0 (-> obj split-plane)))
|
||||
(format #t "((~,,1f ~,,1f ~,,1f ~m)~% " (-> v1-0 x) (-> v1-0 y) (-> v1-0 z) (-> v1-0 w))
|
||||
)
|
||||
(let ((v1-2 (the-as list-node (-> obj point-list))))
|
||||
(while v1-2
|
||||
(let ((s5-0 (-> v1-2 next)))
|
||||
(format
|
||||
#t
|
||||
"(~d (~m ~m ~m)) "
|
||||
(-> (the-as hover-nav-bsp-point v1-2) index)
|
||||
(-> (the-as hover-nav-bsp-point v1-2) pos x)
|
||||
(-> (the-as hover-nav-bsp-point v1-2) pos y)
|
||||
(-> (the-as hover-nav-bsp-point v1-2) pos z)
|
||||
)
|
||||
(set! v1-2 s5-0)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (-> obj left)
|
||||
(hover-nav-bsp-node-method-9 (-> obj left))
|
||||
)
|
||||
(if (-> obj right)
|
||||
(hover-nav-bsp-node-method-9 (-> obj right))
|
||||
)
|
||||
(format #t ")~%")
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for method 10 of type hover-nav-bsp-node
|
||||
;; INFO: Used lq/sq
|
||||
;; WARN: Return type mismatch int vs none.
|
||||
(defmethod hover-nav-bsp-node-method-10 hover-nav-bsp-node ((obj hover-nav-bsp-node) (arg0 int))
|
||||
(when (-> obj point-list)
|
||||
(format 0 "build-bsp: ")
|
||||
(let ((s4-0 (new 'stack-no-clear 'vector))
|
||||
(s3-0 0)
|
||||
)
|
||||
(let ((v1-2 (the-as list-node (-> obj point-list))))
|
||||
(while v1-2
|
||||
(set! v1-2 (-> v1-2 next))
|
||||
(+! s3-0 1)
|
||||
)
|
||||
)
|
||||
(format 0 "count ~d ~%" s3-0)
|
||||
(when (< 1 s3-0)
|
||||
(vector-reset! s4-0)
|
||||
(let ((f0-1 (/ 1.0 (the float s3-0)))
|
||||
(a2-1 (the-as list-node (-> obj point-list)))
|
||||
)
|
||||
(while a2-1
|
||||
(let ((v1-9 (-> a2-1 next)))
|
||||
(vector+float*! s4-0 s4-0 (the-as vector (+ (the-as uint a2-1) 16)) f0-1)
|
||||
(set! a2-1 v1-9)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! (-> obj split-plane quad) (-> *axes-table* arg0 quad))
|
||||
(set! (-> obj split-plane w) (- (vector-dot s4-0 (-> obj split-plane))))
|
||||
(let ((s3-1 (the-as list-node (-> obj point-list))))
|
||||
(while s3-1
|
||||
(let ((s4-1 (-> s3-1 next)))
|
||||
(let ((f0-7 (- (vector-dot (the-as vector (+ (the-as uint s3-1) 16)) (-> obj split-plane)))))
|
||||
(cond
|
||||
((= f0-7 (-> obj split-plane w))
|
||||
)
|
||||
((< f0-7 (-> obj split-plane w))
|
||||
(if (not (-> obj left))
|
||||
(set! (-> obj left) (new 'global 'hover-nav-bsp-node))
|
||||
)
|
||||
(let ((v1-21 s3-1))
|
||||
(let ((a0-12 (&-> obj point-list)))
|
||||
(if (= (-> a0-12 0) v1-21)
|
||||
(set! (-> a0-12 0) (the-as hover-nav-bsp-point (-> v1-21 next)))
|
||||
)
|
||||
)
|
||||
(if (-> v1-21 prev)
|
||||
(set! (-> v1-21 prev next) (-> v1-21 next))
|
||||
)
|
||||
(if (-> v1-21 next)
|
||||
(set! (-> v1-21 next prev) (-> v1-21 prev))
|
||||
)
|
||||
(set! (-> v1-21 prev) #f)
|
||||
(set! (-> v1-21 next) #f)
|
||||
)
|
||||
(let ((a0-19 (-> obj left point-list))
|
||||
(v1-25 (&-> (-> obj left) point-list))
|
||||
)
|
||||
(when (zero? s3-1)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= s3-1 a0-19) (= s3-1 v1-25))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a0-19) (!= (-> a0-19 prev) s3-1)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a0-19
|
||||
(set! (-> s3-1 next) a0-19)
|
||||
(set! (-> s3-1 prev) (-> a0-19 prev))
|
||||
(if (-> s3-1 prev)
|
||||
(set! (-> s3-1 prev next) s3-1)
|
||||
)
|
||||
(if (-> s3-1 next)
|
||||
(set! (-> s3-1 next prev) s3-1)
|
||||
)
|
||||
)
|
||||
(if (or (not a0-19) (= a0-19 (-> v1-25 0)))
|
||||
(set! (-> v1-25 0) (the-as hover-nav-bsp-point s3-1))
|
||||
)
|
||||
)
|
||||
)
|
||||
(else
|
||||
(if (not (-> obj right))
|
||||
(set! (-> obj right) (new 'global 'hover-nav-bsp-node))
|
||||
)
|
||||
(let ((v1-30 s3-1))
|
||||
(let ((a0-22 (&-> obj point-list)))
|
||||
(if (= (-> a0-22 0) v1-30)
|
||||
(set! (-> a0-22 0) (the-as hover-nav-bsp-point (-> v1-30 next)))
|
||||
)
|
||||
)
|
||||
(if (-> v1-30 prev)
|
||||
(set! (-> v1-30 prev next) (-> v1-30 next))
|
||||
)
|
||||
(if (-> v1-30 next)
|
||||
(set! (-> v1-30 next prev) (-> v1-30 prev))
|
||||
)
|
||||
(set! (-> v1-30 prev) #f)
|
||||
(set! (-> v1-30 next) #f)
|
||||
)
|
||||
(let ((v1-32 s3-1)
|
||||
(a1-40 (-> obj right point-list))
|
||||
(a0-31 (&-> (-> obj right) point-list))
|
||||
)
|
||||
(when (zero? v1-32)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= v1-32 a1-40) (= v1-32 a0-31))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a1-40) (!= (-> a1-40 prev) v1-32)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a1-40
|
||||
(set! (-> v1-32 next) a1-40)
|
||||
(set! (-> v1-32 prev) (-> a1-40 prev))
|
||||
(if (-> v1-32 prev)
|
||||
(set! (-> v1-32 prev next) v1-32)
|
||||
)
|
||||
(if (-> v1-32 next)
|
||||
(set! (-> v1-32 next prev) v1-32)
|
||||
)
|
||||
)
|
||||
(if (or (not a1-40) (= a1-40 (-> a0-31 0)))
|
||||
(set! (-> a0-31 0) (the-as hover-nav-bsp-point v1-32))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(set! s3-1 s4-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(if (-> obj left)
|
||||
(hover-nav-bsp-node-method-10 (-> obj left) (mod (+ arg0 1) 3))
|
||||
)
|
||||
(if (-> obj right)
|
||||
(hover-nav-bsp-node-method-10 (-> obj right) (mod (+ arg0 1) 3))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
0
|
||||
(none)
|
||||
)
|
||||
|
||||
;; definition for symbol *hover-bsp*, type hover-nav-bsp
|
||||
(define *hover-bsp* (the-as hover-nav-bsp #f))
|
||||
|
||||
;; definition for function hover-nav-graph-output-bsp
|
||||
;; INFO: Used lq/sq
|
||||
(defun hover-nav-graph-output-bsp ()
|
||||
(let ((v1-0 (get-nav-graph-editor)))
|
||||
(when v1-0
|
||||
(let ((s5-0 (-> v1-0 nav-graph))
|
||||
(gp-0 (new 'global 'hover-nav-bsp))
|
||||
)
|
||||
(let ((s4-0 (-> s5-0 node-array length))
|
||||
(s3-0 0)
|
||||
)
|
||||
(set! (-> gp-0 root) (new 'global 'hover-nav-bsp-node))
|
||||
(dotimes (s2-0 s4-0)
|
||||
(when (nonzero? (-> s5-0 node-array data s2-0 nav_node_id))
|
||||
(let ((v1-9 (new 'global 'hover-nav-bsp-point)))
|
||||
(set! (-> v1-9 index) s3-0)
|
||||
(set! (-> v1-9 pos quad)
|
||||
(-> (the-as (pointer uint128) (+ (the-as uint (-> s5-0 node-array data 0 position)) (* 80 s2-0))))
|
||||
)
|
||||
(let ((a1-7 (-> gp-0 root point-list))
|
||||
(a0-8 (&-> (-> gp-0 root) point-list))
|
||||
)
|
||||
(when (zero? v1-9)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= v1-9 a1-7) (= v1-9 a0-8))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a1-7) (!= (-> a1-7 prev) v1-9)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a1-7
|
||||
(set! (-> v1-9 next) a1-7)
|
||||
(set! (-> v1-9 prev) (-> a1-7 prev))
|
||||
(if (-> v1-9 prev)
|
||||
(set! (-> v1-9 prev next) v1-9)
|
||||
)
|
||||
(if (-> v1-9 next)
|
||||
(set! (-> v1-9 next prev) v1-9)
|
||||
)
|
||||
)
|
||||
(if (or (not a1-7) (= a1-7 (-> a0-8 0)))
|
||||
(set! (-> a0-8 0) v1-9)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s3-0 1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(hover-nav-bsp-node-method-10 (-> gp-0 root) 0)
|
||||
(set! *hover-bsp* gp-0)
|
||||
gp-0
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for function hover-nav-network-build-bsp
|
||||
;; INFO: Used lq/sq
|
||||
(defun hover-nav-network-build-bsp ((arg0 (array hover-nav-bsp-point)))
|
||||
(let ((gp-0 (new 'global 'hover-nav-bsp)))
|
||||
(let ((s4-0 (-> arg0 length))
|
||||
(s3-0 0)
|
||||
)
|
||||
(set! (-> gp-0 root) (new 'global 'hover-nav-bsp-node))
|
||||
(dotimes (s2-0 s4-0)
|
||||
(let ((v1-3 (new 'global 'hover-nav-bsp-point)))
|
||||
(set! (-> v1-3 index) (the-as int (-> arg0 s2-0 next)))
|
||||
(set! (-> v1-3 pos quad) (-> arg0 s2-0 pos quad))
|
||||
(let ((a1-8 (-> gp-0 root point-list))
|
||||
(a0-11 (&-> (-> gp-0 root) point-list))
|
||||
)
|
||||
(when (zero? v1-3)
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (or (= v1-3 a1-8) (= v1-3 a0-11))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when (not (or (not a1-8) (!= (-> a1-8 prev) v1-3)))
|
||||
(break!)
|
||||
0
|
||||
)
|
||||
(when a1-8
|
||||
(set! (-> v1-3 next) a1-8)
|
||||
(set! (-> v1-3 prev) (-> a1-8 prev))
|
||||
(if (-> v1-3 prev)
|
||||
(set! (-> v1-3 prev next) v1-3)
|
||||
)
|
||||
(if (-> v1-3 next)
|
||||
(set! (-> v1-3 next prev) v1-3)
|
||||
)
|
||||
)
|
||||
(if (or (not a1-8) (= a1-8 (-> a0-11 0)))
|
||||
(set! (-> a0-11 0) v1-3)
|
||||
)
|
||||
)
|
||||
)
|
||||
(+! s3-0 1)
|
||||
)
|
||||
)
|
||||
(hover-nav-bsp-node-method-10 (-> gp-0 root) 0)
|
||||
(set! *hover-bsp* gp-0)
|
||||
gp-0
|
||||
)
|
||||
)
|
||||
|
||||
;; definition for function hover-nav-bsp-output
|
||||
;; WARN: Return type mismatch object vs none.
|
||||
(defun hover-nav-bsp-output ((arg0 hover-nav-bsp))
|
||||
(format #t "(")
|
||||
(hover-nav-bsp-node-method-9 (-> arg0 root))
|
||||
(format #t ")~%")
|
||||
(none)
|
||||
)
|
538
third-party/SQLiteCpp/.cproject
generated
vendored
538
third-party/SQLiteCpp/.cproject
generated
vendored
@ -1,538 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.debug.1034724773">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.debug.1034724773" moduleId="org.eclipse.cdt.core.settings" name="Debug">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.debug.1034724773" name="Debug" parent="cdt.managedbuild.config.gnu.exe.debug">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.debug.1034724773." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.debug.898681687" name="Linux GCC" nonInternalBuilderId="cdt.managedbuild.target.gnu.builder.exe.debug" superClass="cdt.managedbuild.toolchain.gnu.exe.debug">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.debug.25715897" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.debug"/>
|
||||
<builder buildPath="${ProjDirPath}/build" id="cdt.managedbuild.target.gnu.builder.exe.debug.1103730408" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.836634439" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool command="g++" id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1817615032" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug">
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.750523151" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.1248186067" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1310903331" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.796464367" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
|
||||
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.1202477623" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.debug.option.debugging.level.280470620" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1655653012" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.1058275134" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1061662206" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug">
|
||||
<option id="gnu.cpp.link.option.libs.1966761747" name="Libraries (-l)" superClass="gnu.cpp.link.option.libs" valueType="libs">
|
||||
<listOptionValue builtIn="false" value="pthread"/>
|
||||
<listOptionValue builtIn="false" value="dl"/>
|
||||
</option>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1636986986" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.258570404" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.1571334436" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
|
||||
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen">
|
||||
<path value=""/>
|
||||
</doc-comment-owner>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="cdt.managedbuild.config.gnu.exe.release.326780594">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="cdt.managedbuild.config.gnu.exe.release.326780594" moduleId="org.eclipse.cdt.core.settings" name="Release">
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.326780594" name="Release" parent="cdt.managedbuild.config.gnu.exe.release">
|
||||
<folderInfo id="cdt.managedbuild.config.gnu.exe.release.326780594." name="/" resourcePath="">
|
||||
<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1521127462" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
|
||||
<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.1294814790" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
|
||||
<builder arguments="BUILD=Release" buildPath="${ProjDirPath}" command="make" id="cdt.managedbuild.target.gnu.builder.exe.release.1733496537" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="cdt.managedbuild.target.gnu.builder.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.archiver.base.446006787" name="GCC Archiver" superClass="cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.2105828055" name="GCC C++ Compiler" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.exe.release">
|
||||
<option id="gnu.cpp.compiler.exe.release.option.optimization.level.1921346334" name="Optimization Level" superClass="gnu.cpp.compiler.exe.release.option.optimization.level" value="gnu.cpp.compiler.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="gnu.cpp.compiler.exe.release.option.debugging.level.1660521780" name="Debug Level" superClass="gnu.cpp.compiler.exe.release.option.debugging.level" value="gnu.cpp.compiler.debugging.level.none" valueType="enumerated"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.compiler.input.1064866729" superClass="cdt.managedbuild.tool.gnu.cpp.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.release.1329805514" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.release">
|
||||
<option defaultValue="gnu.c.optimization.level.most" id="gnu.c.compiler.exe.release.option.optimization.level.2130170048" name="Optimization Level" superClass="gnu.c.compiler.exe.release.option.optimization.level" valueType="enumerated"/>
|
||||
<option id="gnu.c.compiler.exe.release.option.debugging.level.1028604453" name="Debug Level" superClass="gnu.c.compiler.exe.release.option.debugging.level" value="gnu.c.debugging.level.none" valueType="enumerated"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.1173224902" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.c.linker.exe.release.1484631410" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.release"/>
|
||||
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.release.1493084285" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.release">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.cpp.linker.input.1398815353" superClass="cdt.managedbuild.tool.gnu.cpp.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="cdt.managedbuild.tool.gnu.assembler.exe.release.1362356526" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.release">
|
||||
<inputType id="cdt.managedbuild.tool.gnu.assembler.input.831278578" superClass="cdt.managedbuild.tool.gnu.assembler.input"/>
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings">
|
||||
<doc-comment-owner id="org.eclipse.cdt.ui.doxygen">
|
||||
<path value=""/>
|
||||
</doc-comment-owner>
|
||||
</storageModule>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="SQLiteC++.cdt.managedbuild.target.gnu.exe.2007535171" name="Executable" projectType="cdt.managedbuild.target.gnu.exe"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="refreshScope" versionNumber="2">
|
||||
<configuration configurationName="Release">
|
||||
<resource resourceType="PROJECT" workspacePath="/SQLiteCpp"/>
|
||||
</configuration>
|
||||
<configuration configurationName="Debug">
|
||||
<resource resourceType="PROJECT" workspacePath="/SQLiteCpp"/>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.326780594;cdt.managedbuild.config.gnu.exe.release.326780594.;cdt.managedbuild.tool.gnu.c.compiler.exe.release.1329805514;cdt.managedbuild.tool.gnu.c.compiler.input.1173224902">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1034724773;cdt.managedbuild.config.gnu.exe.debug.1034724773.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.debug.1817615032;cdt.managedbuild.tool.gnu.cpp.compiler.input.1310903331">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.release.326780594;cdt.managedbuild.config.gnu.exe.release.326780594.;cdt.managedbuild.tool.gnu.cpp.compiler.exe.release.2105828055;cdt.managedbuild.tool.gnu.cpp.compiler.input.1064866729">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="cdt.managedbuild.config.gnu.exe.debug.1034724773;cdt.managedbuild.config.gnu.exe.debug.1034724773.;cdt.managedbuild.tool.gnu.c.compiler.exe.debug.796464367;cdt.managedbuild.tool.gnu.c.compiler.input.1655653012">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC"/>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="makefileGenerator">
|
||||
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/${specs_file}"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'g++ -E -P -v -dD "${plugin_state_location}/specs.cpp"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
|
||||
<buildOutputProvider>
|
||||
<openAction enabled="true" filePath=""/>
|
||||
<parser enabled="true"/>
|
||||
</buildOutputProvider>
|
||||
<scannerInfoProvider id="specsFile">
|
||||
<runAction arguments="-c 'gcc -E -P -v -dD "${plugin_state_location}/specs.c"'" command="sh" useDefault="true"/>
|
||||
<parser enabled="true"/>
|
||||
</scannerInfoProvider>
|
||||
</profile>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
</cproject>
|
14
third-party/SQLiteCpp/.editorconfig
generated
vendored
14
third-party/SQLiteCpp/.editorconfig
generated
vendored
@ -1,14 +0,0 @@
|
||||
root = true
|
||||
|
||||
# 4 space indentation
|
||||
[*]
|
||||
charset = utf-8
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
end_of_line = lf
|
||||
|
||||
# 2 space indentation for CI configuration
|
||||
[*.yml]
|
||||
indent_style = space
|
||||
indent_size = 2
|
7
third-party/SQLiteCpp/.gitbugtraq
generated
vendored
7
third-party/SQLiteCpp/.gitbugtraq
generated
vendored
@ -1,7 +0,0 @@
|
||||
# .gitbugtraq for Git GUIs (SmartGit/TortoiseGit) to show links to the Github issue tracker.
|
||||
# Instead of the repository root directory, it could be added as an additional section to $GIT_DIR/config.
|
||||
# (note that '\' need to be escaped).
|
||||
[bugtraq]
|
||||
url = https://github.com/SRombauts/SQLiteCpp/issues/%BUGID%
|
||||
loglinkregex = "#\\d+"
|
||||
logregex = \\d+
|
54
third-party/SQLiteCpp/.github/workflows/build.yml
generated
vendored
54
third-party/SQLiteCpp/.github/workflows/build.yml
generated
vendored
@ -1,54 +0,0 @@
|
||||
name: build
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
name: "Windows Latest MSVC",
|
||||
os: windows-latest,
|
||||
build_type: "Debug", cc: "cl", cxx: "cl",
|
||||
}
|
||||
# TODO: this is not working, since CMake is using generator for latest Visual Studio
|
||||
#- {
|
||||
# name: "Windows Latest MinGW",
|
||||
# os: windows-latest,
|
||||
# build_type: "Debug", cc: "gcc", cxx: "g++"
|
||||
# }
|
||||
- {
|
||||
name: "Ubuntu Latest GCC",
|
||||
os: ubuntu-latest,
|
||||
build_type: "Debug", cc: "gcc", cxx: "g++"
|
||||
}
|
||||
- {
|
||||
name: "macOS Latest Clang",
|
||||
os: macos-latest,
|
||||
build_type: "Debug", cc: "clang", cxx: "clang++"
|
||||
}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: submodule
|
||||
run: git submodule update --init --recursive
|
||||
- name: configure
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
set(ENV{CC} ${{matrix.config.cc}})
|
||||
set(ENV{CXX} ${{matrix.config.cxx}})
|
||||
- name: generate
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_RUN_CPPCHECK=OFF -DSQLITECPP_RUN_CPPLINT=OFF ..
|
||||
- name: build
|
||||
run: cmake --build build --config ${{matrix.config.build_type}}
|
||||
- name: test
|
||||
run: |
|
||||
cd build
|
||||
ctest --verbose --output-on-failure
|
43
third-party/SQLiteCpp/.github/workflows/subdir_example.yml
generated
vendored
43
third-party/SQLiteCpp/.github/workflows/subdir_example.yml
generated
vendored
@ -1,43 +0,0 @@
|
||||
name: subdir_example
|
||||
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.config.name }}
|
||||
runs-on: ${{ matrix.config.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
config:
|
||||
- {
|
||||
name: "Windows Latest MSVC",
|
||||
os: windows-latest,
|
||||
build_type: "Debug", cc: "cl", cxx: "cl",
|
||||
}
|
||||
- {
|
||||
name: "Ubuntu Latest GCC",
|
||||
os: ubuntu-latest,
|
||||
build_type: "Debug", cc: "gcc", cxx: "g++"
|
||||
}
|
||||
- {
|
||||
name: "macOS Latest Clang",
|
||||
os: macos-latest,
|
||||
build_type: "Debug", cc: "clang", cxx: "clang++"
|
||||
}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: configure
|
||||
shell: cmake -P {0}
|
||||
run: |
|
||||
set(ENV{CC} ${{matrix.config.cc}})
|
||||
set(ENV{CXX} ${{matrix.config.cxx}})
|
||||
- name: generate
|
||||
run: |
|
||||
cd examples/example2
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=${{matrix.config.build_type}} ..
|
||||
- name: build
|
||||
run: cmake --build examples/example2/build --config ${{matrix.config.build_type}}
|
29
third-party/SQLiteCpp/.gitignore
generated
vendored
29
third-party/SQLiteCpp/.gitignore
generated
vendored
@ -1,29 +0,0 @@
|
||||
Debug
|
||||
Release
|
||||
build
|
||||
*.a
|
||||
|
||||
.vs/
|
||||
.vscode/
|
||||
/SQLiteCpp.sln
|
||||
*.ncb
|
||||
*.suo
|
||||
*.user
|
||||
*sdf
|
||||
*.vc*
|
||||
*~
|
||||
doc
|
||||
core
|
||||
*ipch
|
||||
.settings/
|
||||
|
||||
CMakeCache.txt
|
||||
CMakeFiles
|
||||
*.dir
|
||||
Testing
|
||||
Win32
|
||||
|
||||
SQLiteCpp_example1
|
||||
SQLiteCpp_tests
|
||||
|
||||
!FindSQLiteCpp.cmake
|
3
third-party/SQLiteCpp/.gitmodules
generated
vendored
3
third-party/SQLiteCpp/.gitmodules
generated
vendored
@ -1,3 +0,0 @@
|
||||
[submodule "googletest"]
|
||||
path = googletest
|
||||
url = https://github.com/google/googletest.git
|
85
third-party/SQLiteCpp/.project
generated
vendored
85
third-party/SQLiteCpp/.project
generated
vendored
@ -1,85 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>SQLiteC++</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.python.pydev.PyDevBuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
<dictionary>
|
||||
<key>?name?</key>
|
||||
<value></value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.append_environment</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildArguments</key>
|
||||
<value>-j</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.buildCommand</key>
|
||||
<value>make</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
|
||||
<value>clean</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.contents</key>
|
||||
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
|
||||
<value>false</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
|
||||
<value>all</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.stopOnError</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
<dictionary>
|
||||
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
|
||||
<value>true</value>
|
||||
</dictionary>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>org.eclipse.cdt.core.ccnature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
<nature>org.python.pydev.pythonNature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
136
third-party/SQLiteCpp/.travis.yml
generated
vendored
136
third-party/SQLiteCpp/.travis.yml
generated
vendored
@ -1,136 +0,0 @@
|
||||
# Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
|
||||
language: cpp
|
||||
|
||||
# Use Linux unless specified otherwise
|
||||
os: linux
|
||||
|
||||
cache:
|
||||
apt: true
|
||||
|
||||
env:
|
||||
global:
|
||||
- BUILD_TYPE=Debug
|
||||
- ASAN=ON
|
||||
- INTERNAL_SQLITE=ON
|
||||
- VALGRIND=OFF
|
||||
|
||||
# Build variants (should test a reasonable number of combination of CMake options)
|
||||
jobs:
|
||||
include:
|
||||
|
||||
##########################################################################
|
||||
# GCC on Linux
|
||||
##########################################################################
|
||||
|
||||
# Coverity static code analysis
|
||||
- dist: bionic
|
||||
env:
|
||||
- COVERITY_SCAN_PROJECT_NAME=SRombauts/SQLiteCpp
|
||||
- COVERITY_SCAN_BRANCH_PATTERN=master
|
||||
- COVERITY_SCAN_NOTIFICATION_EMAIL=sebastien.rombauts@gmail.com
|
||||
- COVERITY_SCAN_BUILD_COMMAND_PREPEND="cmake ."
|
||||
- COVERITY_SCAN_BUILD_COMMAND="make -j8"
|
||||
# Encrypted COVERITY_SCAN_TOKEN, created via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "Qm4d8NEDPBtYZCYav46uPEvDCtaRsjLXlkVS+C+WCJAPcwXCGkrr96wEi7RWcq2xD86QCh0XiqaPT+xdUmlohOYIovRhaaBmZ1lwIJ4GsG/ZR6xoFr3DYsZ3o4GyXk2vNXNxEl82AC+Xs6e6gkLOV9XRkBcjpVIvoIXgNlKWeGY="
|
||||
|
||||
# GCC 7.4.0 Debug build with GCov for coverage build
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
- GCOV=ON
|
||||
- COVERALLS=true
|
||||
|
||||
# GCC 7.4.0 Debug build with Valgrind instead of Address Sanitizer
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
- ASAN=OFF
|
||||
- VALGRIND=true
|
||||
|
||||
# GCC 7.4.0 Release build
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
- BUILD_TYPE=Release
|
||||
|
||||
# GCC 7.4.0 test linking with libsqlite3-dev package
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
- INTERNAL_SQLITE=OFF
|
||||
|
||||
# GCC 5.4.0
|
||||
- dist: xenial
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
|
||||
# GCC 4.8.4
|
||||
- dist: trusty
|
||||
env:
|
||||
- cc=gcc cxx=g++
|
||||
|
||||
##########################################################################
|
||||
# Clang on Linux
|
||||
##########################################################################
|
||||
|
||||
# Clang 7.0.0
|
||||
- dist: bionic
|
||||
env:
|
||||
- cc=clang cxx=clang++
|
||||
|
||||
# Clang 7.0.0
|
||||
- dist: xenial
|
||||
env:
|
||||
- cc=clang cxx=clang++
|
||||
|
||||
# Clang 5.0.0
|
||||
- dist: trusty
|
||||
env:
|
||||
- cc=clang cxx=clang++
|
||||
|
||||
##########################################################################
|
||||
# Clang on OSX
|
||||
##########################################################################
|
||||
|
||||
# Latest XCode - AppleClang 9.1.0
|
||||
- os: osx
|
||||
env:
|
||||
- cc=clang cxx=clang++
|
||||
|
||||
# XCode 8.3 - AppleClang 8.1.0
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
env:
|
||||
- cc=clang cxx=clang++
|
||||
|
||||
before_install:
|
||||
# Coverity: don't use addons.coverity_scan since it run on every job of the build matrix, which waste resources and exhausts quotas
|
||||
# Note: the job dedicated to Coverity need to only run the shell script and then exit (to not try to build and run unit tests etc.)
|
||||
- if [[ -n "$COVERITY_SCAN_PROJECT_NAME" ]] ; then curl -s https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh | bash ; exit 0 ; fi
|
||||
|
||||
- if [[ "$INTERNAL_SQLITE" == "OFF" ]]; then sudo apt-get install libsqlite3-dev ; fi
|
||||
- if [[ "$VALGRIND" == "true" ]]; then sudo apt-get install valgrind ; fi
|
||||
- if [[ "$COVERALLS" == "true" ]]; then pip install --user cpp-coveralls ; fi
|
||||
|
||||
# Set the compiler environment variables properly
|
||||
- export CC=${cc}
|
||||
- export CXX=${cxx}
|
||||
|
||||
# scripts to run before build
|
||||
before_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSQLITECPP_INTERNAL_SQLITE=$INTERNAL_SQLITE -DSQLITECPP_USE_ASAN=$ASAN -DSQLITECPP_USE_GCOV=$GCOV -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
|
||||
# build examples, and run tests (ie make & make test)
|
||||
script:
|
||||
- cmake --build .
|
||||
- export ASAN_OPTIONS=verbosity=1:debug=1
|
||||
- ctest --verbose --output-on-failure
|
||||
- if [[ "$VALGRIND" == "true" ]]; then valgrind --leak-check=full --error-exitcode=1 ./SQLiteCpp_example1 ; fi
|
||||
- if [[ "$VALGRIND" == "true" ]]; then valgrind --leak-check=full --error-exitcode=1 ./SQLiteCpp_tests ; fi
|
||||
|
||||
# generate and publish GCov coveralls results
|
||||
after_success:
|
||||
- if [[ "$COVERALLS" == "true" ]]; then coveralls --root .. -e examples -e googletest -e sqlite3 -e tests -E ".*feature_tests.*" -E ".*CompilerId.*" --gcov-options '\-lp' ; fi
|
217
third-party/SQLiteCpp/CHANGELOG.md
generated
vendored
217
third-party/SQLiteCpp/CHANGELOG.md
generated
vendored
@ -1,217 +0,0 @@
|
||||
2012 Mar 30
|
||||
- Start of a new thin C++ SQLite wrapper
|
||||
|
||||
2012 Apr 2
|
||||
- The wrapper is functional
|
||||
- Added documentation and examples
|
||||
- Publication on GitHub
|
||||
|
||||
Version 0.1.0 - 2012 Apr 4
|
||||
- Added a Database::exec() method to execute simple SQL statement
|
||||
- Added a version number like in sqlite3.h, starting with 0.1.0
|
||||
|
||||
Version 0.2.0 - 2012 Apr 11
|
||||
- Added getLastInsertId() and setBusyTimout()
|
||||
- Added bind() by name methods
|
||||
|
||||
Version 0.3.0 - 2012 Apr 16
|
||||
- Added an easy wrapper Database::execAngGet()
|
||||
|
||||
Version 0.4.0 - 2012 Apr 23
|
||||
- Added a Database::tableExists() easy to use function
|
||||
|
||||
Dec 10 2012
|
||||
- Added a Statement::exec() method to execute a one-step query with no expected result
|
||||
|
||||
Version 0.5.0 - 2013 March 9
|
||||
- Added assert() on errors on destructors
|
||||
- Added getBytes()
|
||||
- Added getBlob(), getType() and isInteger/isFloat/isText/isBlob/isNull
|
||||
- Added bind() for binary blob data
|
||||
|
||||
Version 0.5.1 - 2013 April 7
|
||||
- Added Column::getName()
|
||||
|
||||
Version 0.6.0 - 2013 November 22
|
||||
- Renamed Column::getName() to Column::getOriginName()
|
||||
- Added Column::getName()
|
||||
|
||||
Version 0.7.0 - 2014 January 9
|
||||
- Added Database::createFunction()
|
||||
- Added std::string version of existing APIs
|
||||
- Improved CMake with more build options and Doxygen auto-detection
|
||||
|
||||
Version 0.8.0 - 2014 February 26
|
||||
- Database constructor support opening a database with a custom VFS (default to NULL)
|
||||
- Changed Column::getText() to return empty string "" by default instead of NULL pointer (to handle std::string conversion)
|
||||
|
||||
Version 1.0.0 - 2015 May 3
|
||||
- Public headers file moved to include/ dir
|
||||
- Added support to biicode in CMakeLists.txt
|
||||
- Added Unit Tests
|
||||
- Added aBusyTimeoutMs parameter to Database() constructors
|
||||
- Added Database::getTotalChanges()
|
||||
- Added Database::getErrorCode()
|
||||
- Added Statement::clearBindings()
|
||||
- Added Statement::getColumn(aName)
|
||||
- Added Statement::getErrorCode()
|
||||
- Added Statement::getColumnName(aIndex)
|
||||
- Added Statement::getColumnOriginName(aIndex)
|
||||
|
||||
Version 1.1.0 - 2015 May 18
|
||||
- Fixed valgrind error on Database destructor
|
||||
- Added Database::loadExtension
|
||||
|
||||
Version 1.2.0 - 2015 September 9
|
||||
- Fixed build with GCC 5.1.0
|
||||
- Fixed MSVC release build warning
|
||||
- Fixed CppDepends warnings
|
||||
- Updated documentation on installation
|
||||
- Added Database::getHandle()
|
||||
|
||||
Version 1.3.0 - 2015 November 1
|
||||
- Fixed build with Visual Studio 2015
|
||||
- Further improvements to README
|
||||
- Added Backup class
|
||||
|
||||
Version 1.3.1 - 2016 February 10
|
||||
- Switch Linux/Mac build to the provided SQLite3 C library
|
||||
- Update SQLite3 from 3.8.8.3 to latest 3.10.2 (2016-01-20)
|
||||
- Remove warnings
|
||||
- Remove biicode support (defunct service, servers will shutdown the 16th of February 2016)
|
||||
|
||||
Version 2.0.0 - 2016 July 25
|
||||
- Update SQLite3 from 3.10.2 to latest 3.13 (2016-05-18)
|
||||
- Move #include <sqlite3.h> from headers to .cpp files only using forward declarations
|
||||
- Add Database::VERSION to reach SQLITE_VERSION without including sqlite3.h in application code
|
||||
- Add getLibVersion() and getLibVersionNumber() to get runtime version of the library
|
||||
- Better exception messages when Statements fail PR #84
|
||||
- Variadic templates for bind() (C++14) PR #85
|
||||
- Add Statement::bindNoCopy() methods for strings, using SQLITE_STATIC to avoid internal copy by SQLite3 PR #86
|
||||
- Add Statement::bind() overload for uint32_t, and Column::getUint() and cast operator to uint32_t PR #86
|
||||
- Use the new SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION from SQLite 3.13 for security reason
|
||||
- Rename Backup::remainingPageCount()/totalPageCount() to Backup::getRemainingPageCount()/getTotalPageCount()
|
||||
- Remove Column::errmsg() method : use Database or Statement equivalents
|
||||
- More unit tests, with code coverage status on the GitHub page
|
||||
- Do not force MSVC to use static runtime if unit-tests are not build
|
||||
|
||||
Version 2.1.0 - 2017 July 18
|
||||
- Update SQLite3 from 3.13 to latest 3.19.3 (2017-06-08)
|
||||
- Fixed Incompatibility in 3.19.0 (to use older SQLite version set the CMake variable SQLITE_USE_LEGACY_STRUCT) #125
|
||||
- Fixed link error (inline in cpp) and compiler warnings (unused variable...) #96
|
||||
- Added ability to open encrypted databases (using SQLCipher, eg. libsqlcipher-dev) #107
|
||||
- Added convenience functions for constructing objects from a row #114
|
||||
- Added CMake install step #118
|
||||
- Fix warnings #119
|
||||
- Make cpplint.py Python-3 compatible #120
|
||||
- Link libssp when targeted #100
|
||||
- Removed redundant const #102
|
||||
|
||||
Version 2.2.0 - 2017 Sept 19
|
||||
- Update SQLite3 from 3.19.3 to latest 3.20.1 (2017-08-24) #143
|
||||
- Added tryExecuteStep and tryReset #142
|
||||
- Removed virtual keywords from destructors #140
|
||||
- Removed misplaced noexcept keyword #139
|
||||
- Improved Exception class C++ conformance #138
|
||||
- Fix warnings #134
|
||||
- Deprecated Statement::isOk() to Statement::hasRow()
|
||||
|
||||
Version 2.3.0 - 2019 March 3
|
||||
- Update SQLite3 from 3.20.1 to latest 3.27.2 (2019-02-25) #183 #187
|
||||
- Add Statement binding for long int values #147
|
||||
- Allows long int for bind when used with name #148
|
||||
- More cmake instructions for Linux #151
|
||||
- Add comparison with sqlite_orm #141
|
||||
- Fix Statement::bind truncates long integer to 32 bits on x86_64 Linux #155
|
||||
- Add a move constructor to Database #157
|
||||
- Added tests for all MSVC compilers available on AppVeyor (2013, 2015, 2017) #169
|
||||
- Update VariadicBind.h #172
|
||||
- Better CMake compatibility #170
|
||||
- Add implicit cast operator to char and short types #179 #180
|
||||
|
||||
Version 2.4.0 - 2019 August 25
|
||||
- Update SQLite3 from 3.27.2 to 3.29.0 (2019-07-10) #217
|
||||
- #191 CMake Warning line 299
|
||||
- #190 Implement move constructors
|
||||
- #192 Add wrapper for bind parameter count
|
||||
- #197 Add tuple_bind and execute_many (requested by #24)
|
||||
- #199 Fix #156 misleading error message in exception from Statement::exec
|
||||
- #201 Add Statement::getExpandedSQL() to get the SQL text of prepared statement with bound parameters expanded
|
||||
- #211 Implement Database::backup()
|
||||
- #215 Disable implicit fallthrough warning when building internal sqlite3
|
||||
- #216 Set PROJECT_VERSION to fix CMP0048 Policy warnings
|
||||
|
||||
Version 2.5.0 - 2019 December 31
|
||||
- Update SQLite3 from 3.29.0 to 3.30.1 (2019-10-10)
|
||||
- 100% Unit Test coverage
|
||||
- #212 fix sqlite3 compile properties (jzt)
|
||||
- #219 Disable cast-function-type warning when building internal sqlite (zxey)
|
||||
- #230 Fixed installation on other than Ubuntu GNU/Linux distributions (xvitaly)
|
||||
- #228 use transitive compile definitions via cmake (BioDataAnalysis/emmenlau)
|
||||
- #232 Added support of packaged GTest for running unit tests (xvitaly)
|
||||
- #231 Added SOVERSION field for shared library (xvitaly)
|
||||
- #229 Explicitly find and link against system sqlite library (xvitaly)
|
||||
- #235 Added support for cmake dependencies and version information (BioDataAnalysis/emmenlau)
|
||||
- #249 Added SQLite header parsing functionality and associated tests (patrick--)
|
||||
|
||||
- #251 Added example for getHeaderInfo()
|
||||
|
||||
Version 3.0.0 - 2020 January 31
|
||||
- C++11 is now required
|
||||
- CMake 3.1 minimum
|
||||
- Visual Studio 2015 minimum
|
||||
- Update Googletest to latest release 1.10
|
||||
- Add Github Actions continuous integration solution
|
||||
- Add Valgrind memcheck tool to Travis CI
|
||||
- Remove Statement::isOk() deprecated in 2.2.0 when renamed to Statement::hasRow()
|
||||
- Replace Database::backup() "C" implementation by calling the Backup class
|
||||
- #252 Run Valgrind memcheck on Travis CI
|
||||
- #253 Keep inline functions for GCov code coverage
|
||||
- #254 Re-enable Coverity static analysis
|
||||
- #256 Fix linking with system library (libsqlite3)
|
||||
- #242 Added a `getIndex` method and used it (KOLANICH)
|
||||
- #257 Improve Statement unit tests coverage (bind by name with a std::string)
|
||||
- #234 support for external sqlite3 (BioDataAnalysis/emmenlau)
|
||||
- #243 adding a pure attribute to getIndex() (KOLANICH)
|
||||
|
||||
Version 3.1.0 - 2020 August 11
|
||||
- Update SQLite3 from 3.30.1 to 3.32.3 (2020-06-18)
|
||||
- #274 Install both cmake files into same lib directory from tcraigtyler
|
||||
- #275 Add a method on Statement to get the declared type of a column. from daniel-schmidt
|
||||
- #284 Add SQLITE_OPEN_FULLMUTEX flag from rwrx
|
||||
- #286 Add CMake option to toggle stack protection from chrisdalke
|
||||
- #287 Fixed installation on other than Ubuntu distributions from xvitaly
|
||||
- #288 Allow building of sqlite JSON1 extension when building internal sqlite library from zxey
|
||||
|
||||
Version 3.1.1 - 2020 August 19
|
||||
- #292 Fix compilation if using SQLITE_HAS_CODEC from sum01
|
||||
- #293 Remove FindSQLiteCpp.cmake from sum01
|
||||
|
||||
Version 3.2.0 - 2022 Septembre 18
|
||||
- #300 #316 #362 #368 Updated SQLite3 from 3.32.3 to 3.39.3 (2022-09-05)
|
||||
- #236 Disable explicit setting of MSVC runtime from BioDataAnalysis/emmenlau
|
||||
- #308 Fix build warning due to string truncation from stauffer-garmin
|
||||
- #311 Add Database::tryExec() from kcowolf
|
||||
- #313 [CMake] Add SQLITECPP_INCLUDE_SCRIPT option from past-due
|
||||
- #314 Add Database constructor for filesystem::path (#296) from ptrks
|
||||
- #295 Compile internal SQLite library with -ffunction-sections from smichaku
|
||||
- #299 Added Savepoint support from catalogm
|
||||
- #333 Added Database and Statement getChanges()
|
||||
- #305 Add other constants that work with sqlite3_open_v2 from LuAPi/more-flags
|
||||
- #333 Added Database and Statement method getChanges() from SRombauts/get-changes
|
||||
- #334 fix link for HAS_CODEC from linux-fan-dave/master
|
||||
- #338 fix load extension from paulo-coutinho/fix-load-extension
|
||||
- #335 from jagerman/older-macos-avoid-std-filesystem
|
||||
- #337 Add catkin configuration from ardabbour/master
|
||||
- #339 Allow specifying transaction behaviors DEFERRED, IMMEDIATE, and EXCLUSIVE from jjenkins278/transaction_behavior
|
||||
- #340 add HTML keywords and properly link up the links in docs/README.md from phoebe-leong/patch-1
|
||||
- #341 Install the package.xml file from ardabbour/patch-1
|
||||
- #352 add basic meson support from ninjaoflight/meson-support
|
||||
- #349 Refactoring of Statement and Column classes from Kacperos155/refactoring-Statement&Column
|
||||
- #359 Fix compilation issues earlier than iOS 13
|
||||
- #354 Windows improved support (meson) from ninjaoflight/windows-migration
|
||||
- #361 Fix Statement unit test using long from SRombauts/fix-statement-unit-tests-long-long-type
|
||||
- #346 Add compatible definition for std::experimental::filesystem from guoh27/master
|
||||
- #364 Removal of remaining long APIs from SRombauts/convert-remaining-long-types
|
||||
- #366 Add vcpkg installation instructions from FrankXie05/vcpkg-instructions
|
||||
- #360 Small improvements and code cleaning from Kacperos155/small_improvements
|
449
third-party/SQLiteCpp/CMakeLists.txt
generated
vendored
449
third-party/SQLiteCpp/CMakeLists.txt
generated
vendored
@ -1,449 +0,0 @@
|
||||
# Main CMake file for compiling the library itself, examples and tests.
|
||||
#
|
||||
# Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
#
|
||||
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
# or copy at http://opensource.org/licenses/MIT)
|
||||
cmake_minimum_required(VERSION 3.1) # for "CMAKE_CXX_STANDARD" version
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # custom CMake modules like FindSQLiteCpp
|
||||
project(SQLiteCpp VERSION 3.2.0)
|
||||
|
||||
# SQLiteC++ 3.x requires C++11 features
|
||||
if (NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
elseif (CMAKE_CXX_STANDARD LESS 11)
|
||||
message(WARNING "CMAKE_CXX_STANDARD has been set to '${CMAKE_CXX_STANDARD}' which is lower than the minimum required standard (c++11).")
|
||||
endif ()
|
||||
message(STATUS "Using c++ standard c++${CMAKE_CXX_STANDARD}")
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
message (STATUS "CMake version: ${CMAKE_VERSION}")
|
||||
message (STATUS "Project version: ${PROJECT_VERSION}")
|
||||
|
||||
option(SQLITECPP_BUILD_TESTS "Build and run tests." OFF)
|
||||
|
||||
# Define useful variables to handle OS differences:
|
||||
if (WIN32)
|
||||
set(DEV_NULL "NUL")
|
||||
else (WIN32) # UNIX
|
||||
set(DEV_NULL "/dev/null")
|
||||
endif (WIN32)
|
||||
|
||||
# then Compiler/IDE differences:
|
||||
if (MSVC)
|
||||
set(CPPLINT_ARG_OUTPUT "--output=vs7")
|
||||
set(CPPCHECK_ARG_TEMPLATE "--template=vs")
|
||||
# disable Visual Studio warnings for fopen() used in the example
|
||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
||||
# Flags for linking with multithread static C++ runtime, required by internal googletest
|
||||
option(SQLITECPP_USE_STATIC_RUNTIME "Use MSVC static runtime (default for internal googletest)." ${SQLITECPP_BUILD_TESTS})
|
||||
if (SQLITECPP_USE_STATIC_RUNTIME)
|
||||
message(STATUS "Linking against multithread static C++ runtime")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
|
||||
endif (SQLITECPP_USE_STATIC_RUNTIME)
|
||||
# MSVC versions prior to 2015 are not supported anymore by SQLiteC++ 3.x
|
||||
if (MSVC_VERSION LESS 1900) # OR MSVC_TOOLSET_VERSION LESS 140)
|
||||
message(ERROR "Visual Studio prior to 2015 is not supported anymore.")
|
||||
endif (MSVC_VERSION LESS 1900)
|
||||
else (MSVC)
|
||||
set(CPPLINT_ARG_OUTPUT "--output=eclipse")
|
||||
set(CPPCHECK_ARG_TEMPLATE "--template=gcc")
|
||||
# Useful compile flags and extra warnings
|
||||
# Stack protection is not supported on MinGW-W64 on Windows, allow this flag to be turned off.
|
||||
option(SQLITECPP_USE_STACK_PROTECTION "USE Stack Protection hardening." ON)
|
||||
if (SQLITECPP_USE_STACK_PROTECTION)
|
||||
message (STATUS "Using Stack Protection hardening")
|
||||
add_compile_options(-fstack-protector)
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -Wswitch-enum -Wshadow -Wno-long-long") # C++ only, don't bother with sqlite3
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
# GCC flags
|
||||
option(SQLITECPP_USE_GCOV "USE GCov instrumentation." OFF)
|
||||
if (SQLITECPP_USE_GCOV)
|
||||
message (STATUS "Using GCov instrumentation")
|
||||
add_compile_options (-coverage)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -coverage")
|
||||
endif ()
|
||||
endif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
endif (MSVC)
|
||||
# and then common variables
|
||||
set(CPPLINT_ARG_VERBOSE "--verbose=3")
|
||||
set(CPPLINT_ARG_LINELENGTH "--linelength=120")
|
||||
|
||||
# Print CXX compiler information
|
||||
message (STATUS "CMAKE_CXX_COMPILER '${CMAKE_CXX_COMPILER}' '${CMAKE_CXX_COMPILER_ID}' '${CMAKE_CXX_COMPILER_VERSION}'")
|
||||
|
||||
# Print CXX FLAGS
|
||||
message (STATUS "CMAKE_CXX_FLAGS '${CMAKE_CXX_FLAGS}'")
|
||||
if (MSVC)
|
||||
message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'")
|
||||
message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'")
|
||||
message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'")
|
||||
message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'")
|
||||
else (NOT MSVC)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||
message (STATUS "CMAKE_CXX_FLAGS_DEBUG '${CMAKE_CXX_FLAGS_DEBUG}'")
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
|
||||
message (STATUS "CMAKE_CXX_FLAGS_RELWITHDEBINFO '${CMAKE_CXX_FLAGS_RELWITHDEBINFO}'")
|
||||
elseif (CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
|
||||
message (STATUS "CMAKE_CXX_FLAGS_MINSIZEREL '${CMAKE_CXX_FLAGS_MINSIZEREL}'")
|
||||
else ()
|
||||
message (STATUS "CMAKE_CXX_FLAGS_RELEASE '${CMAKE_CXX_FLAGS_RELEASE}'")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
## Build the C++ Wrapper ##
|
||||
|
||||
# adding a new file require explicitly modifying the CMakeLists.txt
|
||||
# so that CMake knows that it should rebuild the project (it is best practice)
|
||||
|
||||
# list of sources files of the library
|
||||
set(SQLITECPP_SRC
|
||||
${PROJECT_SOURCE_DIR}/src/Backup.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/Column.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/Database.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/Exception.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/Savepoint.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/Statement.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/Transaction.cpp
|
||||
)
|
||||
source_group(src FILES ${SQLITECPP_SRC})
|
||||
|
||||
# list of header files of the library
|
||||
set(SQLITECPP_INC
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/SQLiteCpp.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Assertion.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Backup.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Column.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Database.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Exception.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Savepoint.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Statement.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/Transaction.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/VariadicBind.h
|
||||
${PROJECT_SOURCE_DIR}/include/SQLiteCpp/ExecuteMany.h
|
||||
)
|
||||
source_group(include FILES ${SQLITECPP_INC})
|
||||
|
||||
# list of test files of the library
|
||||
set(SQLITECPP_TESTS
|
||||
tests/Column_test.cpp
|
||||
tests/Database_test.cpp
|
||||
tests/Savepoint_test.cpp
|
||||
tests/Statement_test.cpp
|
||||
tests/Backup_test.cpp
|
||||
tests/Transaction_test.cpp
|
||||
tests/VariadicBind_test.cpp
|
||||
tests/Exception_test.cpp
|
||||
tests/ExecuteMany_test.cpp
|
||||
)
|
||||
source_group(tests FILES ${SQLITECPP_TESTS})
|
||||
|
||||
# list of example files of the library
|
||||
set(SQLITECPP_EXAMPLES
|
||||
examples/example1/main.cpp
|
||||
)
|
||||
source_group(example1 FILES ${SQLITECPP_EXAMPLES})
|
||||
|
||||
# list of doc files of the library
|
||||
set(SQLITECPP_DOC
|
||||
README.md
|
||||
LICENSE.txt
|
||||
CHANGELOG.md
|
||||
TODO.txt
|
||||
)
|
||||
source_group(doc FILES ${SQLITECPP_DOC})
|
||||
|
||||
option(SQLITECPP_INCLUDE_SCRIPT "Include config & script files." ON)
|
||||
if (SQLITECPP_INCLUDE_SCRIPT)
|
||||
# list of config & script files of the library
|
||||
set(SQLITECPP_SCRIPT
|
||||
.editorconfig
|
||||
.gitbugtraq
|
||||
.github/workflows/build.yml
|
||||
.github/workflows/subdir_example.yml
|
||||
.gitignore
|
||||
.gitmodules
|
||||
.travis.yml
|
||||
appveyor.yml
|
||||
build.bat
|
||||
build.sh
|
||||
cpplint.py
|
||||
Doxyfile
|
||||
cmake/FindSQLite3.cmake
|
||||
cmake/SQLiteCppConfig.cmake.in
|
||||
)
|
||||
source_group(scripts FILES ${SQLITECPP_SCRIPT})
|
||||
endif()
|
||||
|
||||
# add sources of the wrapper as a "SQLiteCpp" static library
|
||||
add_library(SQLiteCpp STATIC ${SQLITECPP_SRC} ${SQLITECPP_INC} ${SQLITECPP_DOC} ${SQLITECPP_SCRIPT})
|
||||
|
||||
# Options relative to SQLite and SQLiteC++ functions
|
||||
|
||||
option(SQLITE_ENABLE_COLUMN_METADATA "Enable Column::getColumnOriginName(). Require support from sqlite3 library." ON)
|
||||
if (SQLITE_ENABLE_COLUMN_METADATA)
|
||||
# Enable the use of SQLite column metadata and Column::getColumnOriginName() method,
|
||||
# Require that the sqlite3 library is also compiled with this flag (default under Debian/Ubuntu, but not on Mac OS X).
|
||||
target_compile_definitions(SQLiteCpp PUBLIC SQLITE_ENABLE_COLUMN_METADATA)
|
||||
endif (SQLITE_ENABLE_COLUMN_METADATA)
|
||||
|
||||
option(SQLITE_ENABLE_ASSERT_HANDLER "Enable the user definition of a assertion_failed() handler." OFF)
|
||||
if (SQLITE_ENABLE_ASSERT_HANDLER)
|
||||
# Enable the user definition of a assertion_failed() handler (default to false, easier to handler for beginners).
|
||||
target_compile_definitions(SQLiteCpp PUBLIC SQLITECPP_ENABLE_ASSERT_HANDLER)
|
||||
endif (SQLITE_ENABLE_ASSERT_HANDLER)
|
||||
|
||||
option(SQLITE_HAS_CODEC "Enable database encryption API. Not available in the public release of SQLite." OFF)
|
||||
if (SQLITE_HAS_CODEC)
|
||||
# Enable database encryption API. Requires implementations of sqlite3_key & sqlite3_key_v2.
|
||||
# Eg. SQLCipher (libsqlcipher-dev) is an SQLite extension that provides 256 bit AES encryption of database files.
|
||||
target_compile_definitions(SQLiteCpp PUBLIC SQLITE_HAS_CODEC)
|
||||
endif (SQLITE_HAS_CODEC)
|
||||
|
||||
option(SQLITE_USE_LEGACY_STRUCT "Fallback to forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)" OFF)
|
||||
if (SQLITE_USE_LEGACY_STRUCT)
|
||||
# Force forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)
|
||||
target_compile_definitions(SQLiteCpp PUBLIC SQLITE_USE_LEGACY_STRUCT)
|
||||
endif (SQLITE_USE_LEGACY_STRUCT)
|
||||
|
||||
option(SQLITE_OMIT_LOAD_EXTENSION "Enable omit load extension" OFF)
|
||||
if (SQLITE_OMIT_LOAD_EXTENSION)
|
||||
# Enable the user definition of load_extension().
|
||||
target_compile_definitions(SQLiteCpp PUBLIC SQLITE_OMIT_LOAD_EXTENSION)
|
||||
endif (SQLITE_OMIT_LOAD_EXTENSION)
|
||||
|
||||
if (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
|
||||
set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
endif (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
|
||||
|
||||
option(SQLITECPP_USE_ASAN "Use Address Sanitizer." OFF)
|
||||
if (SQLITECPP_USE_ASAN)
|
||||
if ((CMAKE_CXX_COMPILER_VERSION GREATER_EQUAL 6) OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang"))
|
||||
message (STATUS "Using Address Sanitizer")
|
||||
set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fsanitize=address -fno-omit-frame-pointer")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
|
||||
endif ()
|
||||
endif ()
|
||||
endif (SQLITECPP_USE_ASAN)
|
||||
|
||||
if (SQLITECPP_USE_GCOV)
|
||||
# Prevent the compiler from removing the unused inline functions so that they get tracked as "non-covered"
|
||||
set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-fkeep-inline-functions -fkeep-static-functions")
|
||||
endif ()
|
||||
|
||||
## Build provided copy of SQLite3 C library ##
|
||||
|
||||
option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON)
|
||||
if (SQLITECPP_INTERNAL_SQLITE)
|
||||
message(STATUS "Compile sqlite3 from source in subdirectory")
|
||||
option(SQLITE_ENABLE_JSON1 "Enable JSON1 extension when building internal sqlite3 library." ON)
|
||||
# build the SQLite3 C library (for ease of use/compatibility) versus Linux sqlite3-dev package
|
||||
add_subdirectory(sqlite3)
|
||||
target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3)
|
||||
else (SQLITECPP_INTERNAL_SQLITE)
|
||||
# When using the SQLite codec, we need to link against the sqlcipher lib & include <sqlcipher/sqlite3.h>
|
||||
# So this gets the lib & header, and links/includes everything
|
||||
if(SQLITE_HAS_CODEC)
|
||||
# Make PkgConfig optional since Windows doesn't usually have it installed.
|
||||
find_package(PkgConfig QUIET)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
# IMPORTED_TARGET was added in 3.6.3
|
||||
if(CMAKE_VERSION VERSION_LESS 3.6.3)
|
||||
pkg_check_modules(sqlcipher REQUIRED sqlcipher)
|
||||
# Only used in Database.cpp so PRIVATE to hide from end-user
|
||||
# Since we can't use IMPORTED_TARGET on this older Cmake version, manually link libs & includes
|
||||
target_link_libraries(SQLiteCpp PRIVATE ${sqlcipher_LIBRARIES})
|
||||
target_include_directories(SQLiteCpp PRIVATE ${sqlcipher_INCLUDE_DIRS})
|
||||
else()
|
||||
pkg_check_modules(sqlcipher REQUIRED IMPORTED_TARGET sqlcipher)
|
||||
# Only used in Database.cpp so PRIVATE to hide from end-user
|
||||
target_link_libraries(SQLiteCpp PRIVATE PkgConfig::sqlcipher)
|
||||
endif()
|
||||
else()
|
||||
# Since we aren't using pkgconf here, find it manually
|
||||
find_library(sqlcipher_LIBRARY "sqlcipher")
|
||||
find_path(sqlcipher_INCLUDE_DIR "sqlcipher/sqlite3.h"
|
||||
PATH_SUFFIXES
|
||||
"include"
|
||||
"includes"
|
||||
)
|
||||
# Hides it from the GUI
|
||||
mark_as_advanced(sqlcipher_LIBRARY sqlcipher_INCLUDE_DIR)
|
||||
if(NOT sqlcipher_INCLUDE_DIR)
|
||||
message(FATAL_ERROR "${PROJECT_NAME} requires the \"<sqlcipher/sqlite3.h>\" header to use the codec functionality but it wasn't found.")
|
||||
elseif(NOT sqlcipher_LIBRARY)
|
||||
message(FATAL_ERROR "${PROJECT_NAME} requires the sqlcipher library to use the codec functionality but it wasn't found.")
|
||||
endif()
|
||||
# Only used in Database.cpp so PRIVATE to hide from end-user
|
||||
target_include_directories(SQLiteCpp PRIVATE "${sqlcipher_INCLUDE_DIR}/sqlcipher")
|
||||
target_link_libraries(SQLiteCpp PRIVATE ${sqlcipher_LIBRARY})
|
||||
endif()
|
||||
else()
|
||||
find_package (SQLite3 REQUIRED)
|
||||
message(STATUS "Link to sqlite3 system library")
|
||||
target_link_libraries(SQLiteCpp PUBLIC SQLite::SQLite3)
|
||||
if(SQLite3_VERSION VERSION_LESS "3.19")
|
||||
set_target_properties(SQLiteCpp PROPERTIES COMPILE_FLAGS "-DSQLITECPP_HAS_MEM_STRUCT")
|
||||
endif()
|
||||
endif()
|
||||
endif (SQLITECPP_INTERNAL_SQLITE)
|
||||
|
||||
# Link target with pthread and dl for Unix
|
||||
if (UNIX)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(SQLiteCpp PUBLIC Threads::Threads ${CMAKE_DL_LIBS})
|
||||
endif (UNIX)
|
||||
|
||||
# Set includes for target and transitive downstream targets
|
||||
|
||||
target_include_directories(SQLiteCpp
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include/>)
|
||||
|
||||
# Allow the library to be installed via "make install" and found with "find_package"
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS SQLiteCpp
|
||||
EXPORT ${PROJECT_NAME}Targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT libraries)
|
||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT headers FILES_MATCHING REGEX ".*\\.(hpp|h)$")
|
||||
install(EXPORT ${PROJECT_NAME}Targets DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||
install(FILES ${PROJECT_SOURCE_DIR}/package.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME})
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(
|
||||
cmake/${PROJECT_NAME}ConfigVersion.cmake
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY AnyNewerVersion)
|
||||
configure_package_config_file(
|
||||
cmake/${PROJECT_NAME}Config.cmake.in
|
||||
cmake/${PROJECT_NAME}Config.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||
install(FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake
|
||||
${CMAKE_CURRENT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
|
||||
|
||||
# Optional additional targets:
|
||||
|
||||
option(SQLITECPP_RUN_CPPLINT "Run cpplint.py tool for Google C++ StyleGuide." OFF)
|
||||
if (SQLITECPP_RUN_CPPLINT)
|
||||
find_package(PythonInterp)
|
||||
if (PYTHONINTERP_FOUND)
|
||||
# add a cpplint target to the "all" target
|
||||
add_custom_target(SQLiteCpp_cpplint
|
||||
ALL
|
||||
COMMAND ${PYTHON_EXECUTABLE} ${PROJECT_SOURCE_DIR}/cpplint.py ${CPPLINT_ARG_OUTPUT} ${CPPLINT_ARG_VERBOSE} ${CPPLINT_ARG_LINELENGTH} ${SQLITECPP_SRC} ${SQLITECPP_INC}
|
||||
)
|
||||
endif (PYTHONINTERP_FOUND)
|
||||
else (SQLITECPP_RUN_CPPLINT)
|
||||
message(STATUS "SQLITECPP_RUN_CPPLINT OFF")
|
||||
endif (SQLITECPP_RUN_CPPLINT)
|
||||
|
||||
option(SQLITECPP_RUN_CPPCHECK "Run cppcheck C++ static analysis tool." OFF)
|
||||
if (SQLITECPP_RUN_CPPCHECK)
|
||||
find_program(CPPCHECK_EXECUTABLE NAMES cppcheck)
|
||||
if (CPPCHECK_EXECUTABLE)
|
||||
# add a cppcheck target to the "all" target
|
||||
add_custom_target(SQLiteCpp_cppcheck
|
||||
ALL
|
||||
COMMAND ${CPPCHECK_EXECUTABLE} -j 8 cppcheck --enable=style --quiet ${CPPCHECK_ARG_TEMPLATE} ${PROJECT_SOURCE_DIR}/src
|
||||
)
|
||||
execute_process(COMMAND "${CPPCHECK_EXECUTABLE}" --version OUTPUT_VARIABLE CPPCHECK_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
message(STATUS "Found Cppcheck: ${CPPCHECK_EXECUTABLE} ${CPPCHECK_VERSION}")
|
||||
else (CPPCHECK_EXECUTABLE)
|
||||
message(STATUS "Could NOT find cppcheck")
|
||||
endif (CPPCHECK_EXECUTABLE)
|
||||
else (SQLITECPP_RUN_CPPCHECK)
|
||||
message(STATUS "SQLITECPP_RUN_CPPCHECK OFF")
|
||||
endif (SQLITECPP_RUN_CPPCHECK)
|
||||
|
||||
option(SQLITECPP_RUN_DOXYGEN "Run Doxygen C++ documentation tool." OFF)
|
||||
if (SQLITECPP_RUN_DOXYGEN)
|
||||
find_package(Doxygen)
|
||||
if (DOXYGEN_FOUND)
|
||||
# add a Doxygen target to the "all" target
|
||||
add_custom_target(SQLiteCpp_doxygen
|
||||
ALL
|
||||
COMMAND doxygen Doxyfile > ${DEV_NULL}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||
)
|
||||
endif (DOXYGEN_FOUND)
|
||||
else (SQLITECPP_RUN_DOXYGEN)
|
||||
message(STATUS "SQLITECPP_RUN_DOXYGEN OFF")
|
||||
endif (SQLITECPP_RUN_DOXYGEN)
|
||||
|
||||
option(SQLITECPP_BUILD_EXAMPLES "Build examples." OFF)
|
||||
if (SQLITECPP_BUILD_EXAMPLES)
|
||||
# add the basic example executable
|
||||
add_executable(SQLiteCpp_example1 ${SQLITECPP_EXAMPLES})
|
||||
target_link_libraries(SQLiteCpp_example1 SQLiteCpp)
|
||||
if (MSYS OR MINGW)
|
||||
target_link_libraries(SQLiteCpp_example1 ssp)
|
||||
endif ()
|
||||
else (SQLITECPP_BUILD_EXAMPLES)
|
||||
message(STATUS "SQLITECPP_BUILD_EXAMPLES OFF")
|
||||
endif (SQLITECPP_BUILD_EXAMPLES)
|
||||
|
||||
if (SQLITECPP_BUILD_TESTS)
|
||||
# add the unit test executable
|
||||
add_executable(SQLiteCpp_tests ${SQLITECPP_TESTS})
|
||||
target_link_libraries(SQLiteCpp_tests SQLiteCpp)
|
||||
|
||||
find_package(GTest)
|
||||
if (GTEST_FOUND)
|
||||
message(STATUS "Link to GTest system library")
|
||||
target_link_libraries(SQLiteCpp_tests GTest::GTest GTest::Main)
|
||||
else (GTEST_FOUND)
|
||||
message(STATUS "Compile googletest from source in submodule")
|
||||
# deactivate some warnings for compiling the googletest library
|
||||
if (NOT MSVC)
|
||||
add_compile_options(-Wno-switch-enum)
|
||||
endif (NOT MSVC)
|
||||
|
||||
# add the subdirectory containing the CMakeLists.txt for the googletest library
|
||||
if (NOT EXISTS "${PROJECT_SOURCE_DIR}/googletest/CMakeLists.txt")
|
||||
message(FATAL_ERROR "Missing 'googletest' submodule! Either use 'git submodule init' and 'git submodule update' to get googletest according to the README, or deactivate unit tests with -DSQLITECPP_BUILD_TESTS=OFF")
|
||||
endif ()
|
||||
add_subdirectory(googletest)
|
||||
include_directories("${PROJECT_SOURCE_DIR}/googletest/googletest/include")
|
||||
|
||||
# Add definitions to keep googletest from making the compilation fail
|
||||
if (MSVC)
|
||||
if (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919) # OR MSVC_TOOLSET_VERSION EQUAL 141)
|
||||
target_compile_definitions(gtest PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
|
||||
target_compile_definitions(gtest_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
|
||||
target_compile_definitions(gmock PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
|
||||
target_compile_definitions(gmock_main PUBLIC _SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING)
|
||||
endif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS_EQUAL 1919)
|
||||
endif (MSVC)
|
||||
|
||||
target_link_libraries(SQLiteCpp_tests gtest_main)
|
||||
endif (GTEST_FOUND)
|
||||
|
||||
# add a "test" target:
|
||||
enable_testing()
|
||||
|
||||
# does the tests pass?
|
||||
add_test(UnitTests SQLiteCpp_tests)
|
||||
|
||||
if (SQLITECPP_BUILD_EXAMPLES)
|
||||
# does the example1 runs successfully?
|
||||
add_test(Example1Run SQLiteCpp_example1)
|
||||
endif (SQLITECPP_BUILD_EXAMPLES)
|
||||
else (SQLITECPP_BUILD_TESTS)
|
||||
message(STATUS "SQLITECPP_BUILD_TESTS OFF")
|
||||
endif (SQLITECPP_BUILD_TESTS)
|
||||
|
||||
# API version for SQLiteCpp shared library.
|
||||
set_property(TARGET SQLiteCpp PROPERTY SOVERSION 0)
|
2304
third-party/SQLiteCpp/Doxyfile
generated
vendored
2304
third-party/SQLiteCpp/Doxyfile
generated
vendored
File diff suppressed because it is too large
Load Diff
20
third-party/SQLiteCpp/LICENSE.txt
generated
vendored
20
third-party/SQLiteCpp/LICENSE.txt
generated
vendored
@ -1,20 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
|
||||
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.
|
359
third-party/SQLiteCpp/README.md
generated
vendored
359
third-party/SQLiteCpp/README.md
generated
vendored
@ -1,359 +0,0 @@
|
||||
SQLiteC++
|
||||
---------
|
||||
|
||||
[![release](https://img.shields.io/github/release/SRombauts/SQLiteCpp.svg)](https://github.com/SRombauts/SQLiteCpp/releases)
|
||||
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/SRombauts/SQLiteCpp/blob/master/LICENSE.txt)
|
||||
[![Travis CI Linux Build Status](https://travis-ci.org/SRombauts/SQLiteCpp.svg?branch=master)](https://travis-ci.org/SRombauts/SQLiteCpp "Travis CI Linux Build Status")
|
||||
[![AppVeyor Windows Build status](https://ci.appveyor.com/api/projects/status/github/SRombauts/SQLiteCpp?svg=true)](https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp "AppVeyor Windows Build status")
|
||||
[![GitHub Actions Build status](https://github.com/SRombauts/SQLiteCpp/workflows/build/badge.svg)](https://github.com/SRombauts/SQLiteCpp/actions "GitHhub Actions Build status")
|
||||
[![Coveralls](https://img.shields.io/coveralls/SRombauts/SQLiteCpp.svg)](https://coveralls.io/github/SRombauts/SQLiteCpp "Coveralls test coverage")
|
||||
[![Coverity](https://img.shields.io/coverity/scan/14508.svg)](https://scan.coverity.com/projects/srombauts-sqlitecpp "Coverity Scan Build Status")
|
||||
[![Join the chat at https://gitter.im/SRombauts/SQLiteCpp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/SRombauts/SQLiteCpp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
SQLiteC++ (SQLiteCpp) is a lean and easy to use C++ SQLite3 wrapper.
|
||||
|
||||
<!--Keywords: sqlite, sqlite3, C, library, wrapper C++-->
|
||||
<meta name="keywords" content="sqlite, sqlite3, C, library, wrapper C++">
|
||||
|
||||
## About SQLiteC++:
|
||||
|
||||
SQLiteC++ offers an encapsulation around the native C APIs of SQLite,
|
||||
with a few intuitive and well documented C++ classes.
|
||||
|
||||
### License:
|
||||
|
||||
Copyright (c) 2012-2022 Sébastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
<a href="https://www.paypal.me/SRombauts" title="Pay Me a Beer! Donate with PayPal :)"><img src="https://www.paypalobjects.com/webstatic/paypalme/images/pp_logo_small.png" width="118"></a>
|
||||
|
||||
Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
or copy at http://opensource.org/licenses/MIT)
|
||||
|
||||
#### Note on redistribution of SQLite source files
|
||||
|
||||
As stated by the MIT License, you are welcome to reuse, modify, and redistribute the SQLiteCpp source code
|
||||
the way you want it to, be it a git submodule, a subdirectory, or a selection of some source files.
|
||||
|
||||
I would love a mention in your README, a web link to the SQLite repository, and a mention of the author,
|
||||
but none of those are mandatory.
|
||||
|
||||
### About SQLite underlying library:
|
||||
|
||||
SQLite is a library that implements a serverless transactional SQL database engine.
|
||||
It is the most widely deployed SQL database engine in the world.
|
||||
All of the code and documentation in SQLite has been dedicated to the public domain by the authors.
|
||||
[http://www.sqlite.org/about.html](http://www.sqlite.org/about.html)
|
||||
|
||||
### The goals of SQLiteC++ are:
|
||||
|
||||
- to offer the best of the existing simple C++ SQLite wrappers
|
||||
- to be elegantly written with good C++11 design, STL, exceptions and RAII idiom
|
||||
- to keep dependencies to a minimum (C++11 STL and SQLite3)
|
||||
- to be portable
|
||||
- to be light and fast
|
||||
- to be thread-safe only as much as SQLite "Multi-thread" mode (see below)
|
||||
- to have a good unit test coverage
|
||||
- to use API names sticking with those of the SQLite library
|
||||
- to be well documented with Doxygen tags, and with some good examples
|
||||
- to be well maintained
|
||||
- to use a permissive MIT license, similar to BSD or Boost, for proprietary/commercial usage
|
||||
|
||||
It is designed using the Resource Acquisition Is Initialization (RAII) idiom
|
||||
(see [http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)),
|
||||
and throwing exceptions in case of SQLite errors (except in destructors,
|
||||
where assert() are used instead).
|
||||
Each SQLiteC++ object must be constructed with a valid SQLite database connection,
|
||||
and then is always valid until destroyed.
|
||||
|
||||
### Supported platforms:
|
||||
|
||||
Now requires a C++11 compiler. Use branch [sqlitecpp-2.x](https://github.com/SRombauts/SQLiteCpp/tree/sqlitecpp-2.x) for latest pre-C++11 developments.
|
||||
|
||||
Developments and tests are done under the following OSs:
|
||||
- Ubuntu 14.04, 16.04 and 18.04 (Travis CI and Github Actions)
|
||||
- Windows 10, and Windows Server 2012 R2, Windows Server 2016, Windows Server 2022 (AppVeyor and Github Actions)
|
||||
- MacOS 10.11 and 11.7 (Travis CI and Github Actions)
|
||||
- Valgrind memcheck tool
|
||||
|
||||
And the following IDEs/Compilers
|
||||
- GCC 4.8.4, 5.3.0, 7.1.1 and latest eg 9.4 (C++11, C++14, C++17)
|
||||
- Clang 5 and 7 (Travis CI)
|
||||
- AppleClang 8, 9 and 13 (Travis CI and Github Actions)
|
||||
- Xcode 8 & 9 (Travis CI)
|
||||
- Visual Studio Community/Entreprise 2022, 2019, 2017, and 2015 (AppVeyor and Github Actions)
|
||||
|
||||
### Dependencies
|
||||
|
||||
- a modern C++11 STL implementation with GCC, Clang, or Visual Studio 2015
|
||||
- exception support (the class Exception inherits from std::runtime_error)
|
||||
- the SQLite library (3.7.15 minimum from 2012-12-12) either by linking to it dynamically or statically (install the libsqlite3-dev package under Debian/Ubuntu/Mint Linux),
|
||||
or by adding its source file in your project code base (source code provided in src/sqlite3 for Windows),
|
||||
with the `SQLITE_ENABLE_COLUMN_METADATA` macro defined (see http://www.sqlite.org/compile.html#enable_column_metadata).
|
||||
|
||||
## Getting started
|
||||
### Installation
|
||||
|
||||
To use this wrapper, you need to add the SQLiteC++ source files from the src/ directory
|
||||
in your project code base, and compile/link against the sqlite library.
|
||||
|
||||
The easiest way to do this is to add the wrapper as a library.
|
||||
The "CMakeLists.txt" file defining the static library is provided in the root directory,
|
||||
so you simply have to add_subdirectory(SQLiteCpp) to you main CMakeLists.txt
|
||||
and link to the "SQLiteCpp" wrapper library.
|
||||
|
||||
Example for Linux:
|
||||
```cmake
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp)
|
||||
|
||||
add_executable(main src/main.cpp)
|
||||
target_link_libraries(main
|
||||
SQLiteCpp
|
||||
sqlite3
|
||||
pthread
|
||||
dl
|
||||
)
|
||||
```
|
||||
Thus this SQLiteCpp repository can be directly used as a Git submodule.
|
||||
See the [SQLiteCpp_Example](https://github.com/SRombauts/SQLiteCpp_Example) side repository for a standalone "from scratch" example.
|
||||
|
||||
Under Debian/Ubuntu/Mint Linux, you can install the libsqlite3-dev package if you don't want to use the embedded sqlite3 library.
|
||||
|
||||
### Building example and unit-tests:
|
||||
|
||||
Use git to clone the repository. Then init and update submodule "googletest".
|
||||
|
||||
```Shell
|
||||
git clone https://github.com/SRombauts/SQLiteCpp.git
|
||||
cd SQLiteCpp
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
### Installing SQLiteCpp (vcpkg)
|
||||
|
||||
Alternatively, you can build and install SQLiteCpp using [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
|
||||
|
||||
```bash or powershell
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install sqlitecpp
|
||||
```
|
||||
|
||||
The SQLiteCpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
|
||||
#### Using SQLiteCpp on a system-wide installation
|
||||
|
||||
If you installed this package to your system, a `SQLiteCppConfig.cmake` file will be generated & installed to your system.
|
||||
This file lets you link against the SQLiteCpp library for use in your Cmake project.
|
||||
|
||||
Here's an example of using this in your CMakeLists.txt
|
||||
```cmake
|
||||
# You can optionally define a minimum version in this call
|
||||
find_package(SQLiteCpp REQUIRED)
|
||||
# For this example, lets say you created an target with add_executable (or add_library) called "my_target"
|
||||
# You can optionally declare PUBLIC or PRIVATE linkage here, depending on your needs.
|
||||
target_link_libraries(my_target PRIVATE SQLiteCpp)
|
||||
```
|
||||
|
||||
#### CMake and tests
|
||||
A CMake configuration file is also provided for multi-platform support and testing.
|
||||
|
||||
Typical generic build for MS Visual Studio under Windows (from [build.bat](build.bat)):
|
||||
|
||||
```Batchfile
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake .. # cmake .. -G "Visual Studio 16 2019" # for Visual Studio 2019
|
||||
@REM Generate a Visual Studio solution for latest version found
|
||||
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
|
||||
@REM Build default configuration (ie 'Debug')
|
||||
cmake --build .
|
||||
|
||||
@REM Build and run tests
|
||||
ctest --output-on-failure
|
||||
```
|
||||
|
||||
Generating the Linux Makefile, building in Debug and executing the tests (from [build.sh](build.sh)):
|
||||
|
||||
```Shell
|
||||
mkdir Debug
|
||||
cd Debug
|
||||
|
||||
# Generate a Makefile for GCC (or Clang, depanding on CC/CXX envvar)
|
||||
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
|
||||
# Build (ie 'make')
|
||||
cmake --build .
|
||||
|
||||
# Build and run unit-tests (ie 'make test')
|
||||
ctest --output-on-failure
|
||||
```
|
||||
|
||||
#### CMake options
|
||||
|
||||
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/SRombauts/SQLiteCpp/blob/master/CMakeLists.txt) file.
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
Under Linux, if you get multiple linker errors like "undefined reference to sqlite3_xxx",
|
||||
it's that you lack the "sqlite3" library: install the libsqlite3-dev package.
|
||||
|
||||
If you get a single linker error "Column.cpp: undefined reference to sqlite3_column_origin_name",
|
||||
it's that your "sqlite3" library was not compiled with
|
||||
the `SQLITE_ENABLE_COLUMN_METADATA` macro defined (see [http://www.sqlite.org/compile.html#enable_column_metadata](http://www.sqlite.org/compile.html#enable_column_metadata)).
|
||||
You can:
|
||||
- either recompile the sqlite3 library provided by your distribution yourself (seek help online)
|
||||
- or turn off the `option(SQLITE_ENABLE_COLUMN_METADATA "Enable Column::getColumnOriginName(). Require support from sqlite3 library." ON)` in [CMakeFiles.txt](CMakeFiles.txt) (or other build system scripts)
|
||||
- or turn on the `option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON)` in [CMakeFiles.txt](CMakeFiles.txt)
|
||||
|
||||
### Continuous Integration
|
||||
|
||||
This project is continuously tested under Ubuntu Linux with the gcc and clang compilers
|
||||
using the Travis CI community service with the above CMake building and testing procedure.
|
||||
It is also tested in the same way under Windows Server 2012 R2 with Visual Studio 2013 compiler
|
||||
using the AppVeyor continuous integration service.
|
||||
|
||||
Detailed results can be seen online:
|
||||
- [https://travis-ci.org/SRombauts/SQLiteCpp](https://travis-ci.org/SRombauts/SQLiteCpp)
|
||||
- [https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp](https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp)
|
||||
|
||||
### Thread-safety
|
||||
|
||||
SQLite supports three modes of thread safety, as describe in "SQLite And Multiple Threads":
|
||||
see [http://www.sqlite.org/threadsafe.html](http://www.sqlite.org/threadsafe.html)
|
||||
|
||||
This SQLiteC++ wrapper does no add any locks (no mutexes) nor any other thread-safety mechanism
|
||||
above the SQLite library itself, by design, for lightness and speed.
|
||||
|
||||
Thus, SQLiteC++ naturally supports the "Multi Thread" mode of SQLite:
|
||||
"In this mode, SQLite can be safely used by multiple threads
|
||||
provided that no single database connection is used simultaneously in two or more threads."
|
||||
|
||||
But SQLiteC++ does not support the fully thread-safe "Serialized" mode of SQLite,
|
||||
because of the way it shares the underlying SQLite precompiled statement
|
||||
in a custom shared pointer (See the inner class "Statement::Ptr").
|
||||
|
||||
### Valgrind memcheck
|
||||
|
||||
Run valgrind to search for memory leaks in your application, the SQLiteCpp wrapper, or the sqlite3 library.
|
||||
Execute the following command under Unix like OS (Linux, MacOS or WSL2/Ubuntu under Windows Subsystem for Linux):
|
||||
|
||||
```Shell
|
||||
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose build/SQLiteCpp_example1
|
||||
```
|
||||
|
||||
or uncoment the line at the end of [build.sh](build.sh)
|
||||
|
||||
## Examples
|
||||
### The first sample demonstrates how to query a database and get results:
|
||||
|
||||
```C++
|
||||
try
|
||||
{
|
||||
// Open a database file
|
||||
SQLite::Database db("example.db3");
|
||||
|
||||
// Compile a SQL query, containing one parameter (index 1)
|
||||
SQLite::Statement query(db, "SELECT * FROM test WHERE size > ?");
|
||||
|
||||
// Bind the integer value 6 to the first parameter of the SQL query
|
||||
query.bind(1, 6);
|
||||
|
||||
// Loop to execute the query step by step, to get rows of result
|
||||
while (query.executeStep())
|
||||
{
|
||||
// Demonstrate how to get some typed column value
|
||||
int id = query.getColumn(0);
|
||||
const char* value = query.getColumn(1);
|
||||
int size = query.getColumn(2);
|
||||
|
||||
std::cout << "row: " << id << ", " << value << ", " << size << std::endl;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "exception: " << e.what() << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
### The second sample shows how to manage a transaction:
|
||||
|
||||
```C++
|
||||
try
|
||||
{
|
||||
SQLite::Database db("transaction.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
|
||||
|
||||
// Commit transaction
|
||||
transaction.commit();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "exception: " << e.what() << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
### How to handle assertion in SQLiteC++:
|
||||
Exceptions shall not be used in destructors, so SQLiteC++ uses SQLITECPP_ASSERT() to check for errors in destructors.
|
||||
If you don't want assert() to be called, you have to enable and define an assert handler as shown below,
|
||||
and by setting the flag SQLITECPP_ENABLE_ASSERT_HANDLER when compiling the lib.
|
||||
|
||||
```C++
|
||||
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
namespace SQLite
|
||||
{
|
||||
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
|
||||
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
|
||||
{
|
||||
// Print a message to the standard error output stream, and abort the program.
|
||||
std::cerr << apFile << ":" << apLine << ":" << " error: assertion failed (" << apExpr << ") in " << apFunc << "() with message \"" << apMsg << "\"\n";
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
## How to contribute
|
||||
### GitHub website
|
||||
The most efficient way to help and contribute to this wrapper project is to
|
||||
use the tools provided by GitHub:
|
||||
- please fill bug reports and feature requests here: [https://github.com/SRombauts/SQLiteCpp/issues](https://github.com/SRombauts/SQLiteCpp/issues)
|
||||
- fork the repository, make some small changes and submit them with pull-request
|
||||
|
||||
### Contact
|
||||
You can also email me directly, I will try to answer questions and requests whenever I get the time for it.
|
||||
|
||||
### Coding Style Guidelines
|
||||
The source code use the CamelCase naming style variant where:
|
||||
- type names (class, struct, typedef, enums...) begin with a capital letter
|
||||
- files (.cpp/.h) are named like the class they contain
|
||||
- function and variable names begin with a lower case letter
|
||||
- member variables begin with a 'm', function arguments begin with a 'a', booleans with a 'b', pointers with a 'p'
|
||||
- each file, class, method and member variable is documented using Doxygen tags
|
||||
- braces on their own line
|
||||
See also [http://www.appinf.com/download/CppCodingStyleGuide.pdf](http://www.appinf.com/download/CppCodingStyleGuide.pdf) for good guidelines
|
||||
|
||||
## See also - Some other simple C++ SQLite wrappers:
|
||||
|
||||
See bellow a short comparison of other wrappers done at the time of writing:
|
||||
- [sqdbcpp](http://code.google.com/p/sqdbcpp/): RAII design, simple, no dependencies, UTF-8/UTF-16, new BSD license
|
||||
- [sqlite3cc](http://ed.am/dev/sqlite3cc): uses boost, modern design, LPGPL
|
||||
- [sqlite3pp](https://github.com/iwongu/sqlite3pp): modern design inspired by boost, MIT License
|
||||
- [SQLite++](http://sqlitepp.berlios.de/): uses boost build system, Boost License 1.0
|
||||
- [CppSQLite](http://www.codeproject.com/Articles/6343/CppSQLite-C-Wrapper-for-SQLite/): famous Code Project but old design, BSD License
|
||||
- [easySQLite](http://code.google.com/p/easysqlite/): manages table as structured objects, complex
|
||||
- [sqlite_modern_cpp](https://github.com/keramer/sqlite_modern_cpp): modern C++11, all in one file, MIT license
|
||||
- [sqlite_orm](https://github.com/fnc12/sqlite_orm): modern C++14, header only all in one file, no raw string queries, BSD-3 license
|
25
third-party/SQLiteCpp/TODO.txt
generated
vendored
25
third-party/SQLiteCpp/TODO.txt
generated
vendored
@ -1,25 +0,0 @@
|
||||
Add a Tutorial for SQLite newbies
|
||||
Add a real example in the form of a small interactive console application
|
||||
|
||||
Improve Github Wiki pages with the FAQ: Installation, Examples, Tutorial, How to contribute
|
||||
Publish the Doxygen Documentation in the Github Pages (gh-pages branch)
|
||||
|
||||
Missing features in v2.0.0:
|
||||
- #34: Better type for getColumn
|
||||
|
||||
Missing documentation in v2.0.0:
|
||||
- explain the non-copyable property for RAII design
|
||||
- comment on returning error code instead of exception that shall not be thrown when expected (!?)
|
||||
|
||||
Missing unit tests in v2.0.0:
|
||||
- Load Extension (not practicable, and easy to verify by code review)
|
||||
|
||||
Advanced missing features:
|
||||
- Add optional usage of experimental sqlite3_trace() function to enable statistics
|
||||
- Aggregate ?
|
||||
|
||||
- support for different transaction mode ? NO: too specific
|
||||
- operator<< binding ? NO: redundant with bind()
|
||||
- ATTACH Database ? NO: can already be done by "ATTACH" Statement
|
||||
|
||||
Post an article to CodeProject: Is there a license issue ?
|
1
third-party/SQLiteCpp/_config.yml
generated
vendored
1
third-party/SQLiteCpp/_config.yml
generated
vendored
@ -1 +0,0 @@
|
||||
theme: jekyll-theme-slate
|
46
third-party/SQLiteCpp/appveyor.yml
generated
vendored
46
third-party/SQLiteCpp/appveyor.yml
generated
vendored
@ -1,46 +0,0 @@
|
||||
# Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
|
||||
# build format
|
||||
version: "{build}"
|
||||
|
||||
# scripts that run after cloning repository
|
||||
install:
|
||||
- git submodule update --init --recursive
|
||||
|
||||
image:
|
||||
- Visual Studio 2022
|
||||
- Visual Studio 2019
|
||||
- Visual Studio 2017
|
||||
- Visual Studio 2015
|
||||
|
||||
# configurations to add to build matrix
|
||||
# TODO: MinGW Makefiles and MSYS Makefiles
|
||||
configuration:
|
||||
- Debug
|
||||
- Release
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- arch: Win32
|
||||
- arch: x64
|
||||
|
||||
init:
|
||||
- echo %APPVEYOR_BUILD_WORKER_IMAGE% - %configuration% - %arch%
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" (set vs=Visual Studio 15 2017)
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" (set vs=Visual Studio 14 2015)
|
||||
- if "%arch%"=="x64" (set generator="%vs% Win64") else (set generator="%vs%")
|
||||
# CMake uses a different grammar for Visual Studio 2019, with -A to specify architecture:
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2019" (set generator="Visual Studio 16 2019" -A %arch%)
|
||||
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2022" (set generator="Visual Studio 17 2022" -A %arch%)
|
||||
- echo %generator%
|
||||
|
||||
# scripts to run before build
|
||||
before_build:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_VERBOSE_MAKEFILE=ON -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_RUN_CPPCHECK=OFF .. -G %generator%
|
||||
|
||||
# build examples, and run tests (ie make & make test)
|
||||
build_script:
|
||||
- cmake --build . --config %configuration%
|
||||
- ctest --output-on-failure
|
26
third-party/SQLiteCpp/build.bat
generated
vendored
26
third-party/SQLiteCpp/build.bat
generated
vendored
@ -1,26 +0,0 @@
|
||||
@REM Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
@REM
|
||||
@REM Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
@REM or copy at http://opensource.org/licenses/MIT)
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
@REM Generate a Visual Studio solution for latest version found
|
||||
REM -DPYTHON_EXECUTABLE=D:\workspace\Corvus\UnrealEngine\Engine\Binaries\ThirdParty\Python\Win64\python.exe
|
||||
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON -DSQLITECPP_RUN_CPPLINT=OFF ..
|
||||
@if ERRORLEVEL 1 goto onError
|
||||
|
||||
@REM Build default configuration (ie 'Debug')
|
||||
cmake --build .
|
||||
@if ERRORLEVEL 1 goto onError
|
||||
|
||||
@REM Build and run tests
|
||||
ctest --output-on-failure
|
||||
@if ERRORLEVEL 1 goto onError
|
||||
|
||||
goto onSuccess
|
||||
|
||||
:onError
|
||||
@echo An error occured!
|
||||
:onSuccess
|
||||
cd ..
|
25
third-party/SQLiteCpp/build.sh
generated
vendored
25
third-party/SQLiteCpp/build.sh
generated
vendored
@ -1,25 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2012-2020 Sébastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
#
|
||||
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
# or copy at http://opensource.org/licenses/MIT)
|
||||
|
||||
# exit on first error
|
||||
set -e
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
# Generate a Makefile for GCC (or Clang, depanding on CC/CXX envvar)
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug -DSQLITECPP_USE_ASAN=ON -DSQLITECPP_USE_GCOV=OFF -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
|
||||
# Build (ie 'make')
|
||||
cmake --build .
|
||||
|
||||
# Build and run unit-tests (ie 'make test')
|
||||
ctest --output-on-failure
|
||||
|
||||
# And with Valgrind
|
||||
echo "Note: uncomment to run valgrind memcheck"
|
||||
#valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=1 ./SQLiteCpp_example1
|
||||
#valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=1 ./SQLiteCpp_tests
|
66
third-party/SQLiteCpp/cmake/FindSQLite3.cmake
generated
vendored
66
third-party/SQLiteCpp/cmake/FindSQLite3.cmake
generated
vendored
@ -1,66 +0,0 @@
|
||||
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||
|
||||
#[=======================================================================[.rst:
|
||||
FindSQLite3
|
||||
-----------
|
||||
|
||||
Find the SQLite libraries, v3
|
||||
|
||||
IMPORTED targets
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module defines the following :prop_tgt:`IMPORTED` target:
|
||||
|
||||
``SQLite::SQLite3``
|
||||
|
||||
Result variables
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
This module will set the following variables if found:
|
||||
|
||||
``SQLite3_INCLUDE_DIRS``
|
||||
where to find sqlite3.h, etc.
|
||||
``SQLite3_LIBRARIES``
|
||||
the libraries to link against to use SQLite3.
|
||||
``SQLite3_VERSION``
|
||||
version of the SQLite3 library found
|
||||
``SQLite3_FOUND``
|
||||
TRUE if found
|
||||
|
||||
#]=======================================================================]
|
||||
|
||||
# Look for the necessary header
|
||||
find_path(SQLite3_INCLUDE_DIR NAMES sqlite3.h)
|
||||
mark_as_advanced(SQLite3_INCLUDE_DIR)
|
||||
|
||||
# Look for the necessary library
|
||||
find_library(SQLite3_LIBRARY NAMES sqlite3 sqlite)
|
||||
mark_as_advanced(SQLite3_LIBRARY)
|
||||
|
||||
# Extract version information from the header file
|
||||
if(SQLite3_INCLUDE_DIR)
|
||||
file(STRINGS ${SQLite3_INCLUDE_DIR}/sqlite3.h _ver_line
|
||||
REGEX "^#define SQLITE_VERSION *\"[0-9]+\\.[0-9]+\\.[0-9]+\""
|
||||
LIMIT_COUNT 1)
|
||||
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+"
|
||||
SQLite3_VERSION "${_ver_line}")
|
||||
unset(_ver_line)
|
||||
endif()
|
||||
|
||||
include(${CMAKE_ROOT}/Modules/FindPackageHandleStandardArgs.cmake)
|
||||
find_package_handle_standard_args(SQLite3
|
||||
REQUIRED_VARS SQLite3_INCLUDE_DIR SQLite3_LIBRARY
|
||||
VERSION_VAR SQLite3_VERSION)
|
||||
|
||||
# Create the imported target
|
||||
if(SQLite3_FOUND)
|
||||
set(SQLite3_INCLUDE_DIRS ${SQLite3_INCLUDE_DIR})
|
||||
set(SQLite3_LIBRARIES ${SQLite3_LIBRARY})
|
||||
if(NOT TARGET SQLite::SQLite3)
|
||||
add_library(SQLite::SQLite3 UNKNOWN IMPORTED)
|
||||
set_target_properties(SQLite::SQLite3 PROPERTIES
|
||||
IMPORTED_LOCATION "${SQLite3_LIBRARY}"
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${SQLite3_INCLUDE_DIR}")
|
||||
endif()
|
||||
endif()
|
13
third-party/SQLiteCpp/cmake/SQLiteCppConfig.cmake.in
generated
vendored
13
third-party/SQLiteCpp/cmake/SQLiteCppConfig.cmake.in
generated
vendored
@ -1,13 +0,0 @@
|
||||
include(CMakeFindDependencyMacro)
|
||||
if(NOT @SQLITECPP_INTERNAL_SQLITE@)
|
||||
find_dependency(SQLite3 REQUIRED)
|
||||
endif()
|
||||
if(@UNIX@)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG @THREADS_PREFER_PTHREAD_FLAG@)
|
||||
find_dependency(Threads REQUIRED)
|
||||
endif()
|
||||
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
|
||||
check_required_components("@PROJECT_NAME@")
|
4807
third-party/SQLiteCpp/cpplint.py
generated
vendored
4807
third-party/SQLiteCpp/cpplint.py
generated
vendored
File diff suppressed because it is too large
Load Diff
359
third-party/SQLiteCpp/docs/README.md
generated
vendored
359
third-party/SQLiteCpp/docs/README.md
generated
vendored
@ -1,359 +0,0 @@
|
||||
SQLiteC++
|
||||
---------
|
||||
|
||||
[![release](https://img.shields.io/github/release/SRombauts/SQLiteCpp.svg)](https://github.com/SRombauts/SQLiteCpp/releases)
|
||||
[![license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/SRombauts/SQLiteCpp/blob/master/LICENSE.txt)
|
||||
[![Travis CI Linux Build Status](https://travis-ci.org/SRombauts/SQLiteCpp.svg?branch=master)](https://travis-ci.org/SRombauts/SQLiteCpp "Travis CI Linux Build Status")
|
||||
[![AppVeyor Windows Build status](https://ci.appveyor.com/api/projects/status/github/SRombauts/SQLiteCpp?svg=true)](https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp "AppVeyor Windows Build status")
|
||||
[![GitHub Actions Build status](https://github.com/SRombauts/SQLiteCpp/workflows/build/badge.svg)](https://github.com/SRombauts/SQLiteCpp/actions "GitHhub Actions Build status")
|
||||
[![Coveralls](https://img.shields.io/coveralls/SRombauts/SQLiteCpp.svg)](https://coveralls.io/github/SRombauts/SQLiteCpp "Coveralls test coverage")
|
||||
[![Coverity](https://img.shields.io/coverity/scan/14508.svg)](https://scan.coverity.com/projects/srombauts-sqlitecpp "Coverity Scan Build Status")
|
||||
[![Join the chat at https://gitter.im/SRombauts/SQLiteCpp](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/SRombauts/SQLiteCpp?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
SQLiteC++ (SQLiteCpp) is a lean and easy to use C++ SQLite3 wrapper.
|
||||
|
||||
<!--Keywords: sqlite, sqlite3, C, library, wrapper C++-->
|
||||
<meta name="keywords" content="sqlite, sqlite3, C, library, wrapper C++">
|
||||
|
||||
## About SQLiteC++:
|
||||
|
||||
SQLiteC++ offers an encapsulation around the native C APIs of SQLite,
|
||||
with a few intuitive and well documented C++ classes.
|
||||
|
||||
### License:
|
||||
|
||||
Copyright (c) 2012-2022 Sébastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
<a href="https://www.paypal.me/SRombauts" title="Pay Me a Beer! Donate with PayPal :)"><img src="https://www.paypalobjects.com/webstatic/paypalme/images/pp_logo_small.png" width="118"></a>
|
||||
|
||||
Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
or copy at http://opensource.org/licenses/MIT)
|
||||
|
||||
#### Note on redistribution of SQLite source files
|
||||
|
||||
As stated by the MIT License, you are welcome to reuse, modify, and redistribute the SQLiteCpp source code
|
||||
the way you want it to, be it a git submodule, a subdirectory, or a selection of some source files.
|
||||
|
||||
I would love a mention in your README, a web link to the SQLite repository, and a mention of the author,
|
||||
but none of those are mandatory.
|
||||
|
||||
### About SQLite underlying library:
|
||||
|
||||
SQLite is a library that implements a serverless transactional SQL database engine.
|
||||
It is the most widely deployed SQL database engine in the world.
|
||||
All of the code and documentation in SQLite has been dedicated to the public domain by the authors.
|
||||
[http://www.sqlite.org/about.html](http://www.sqlite.org/about.html)
|
||||
|
||||
### The goals of SQLiteC++ are:
|
||||
|
||||
- to offer the best of the existing simple C++ SQLite wrappers
|
||||
- to be elegantly written with good C++11 design, STL, exceptions and RAII idiom
|
||||
- to keep dependencies to a minimum (C++11 STL and SQLite3)
|
||||
- to be portable
|
||||
- to be light and fast
|
||||
- to be thread-safe only as much as SQLite "Multi-thread" mode (see below)
|
||||
- to have a good unit test coverage
|
||||
- to use API names sticking with those of the SQLite library
|
||||
- to be well documented with Doxygen tags, and with some good examples
|
||||
- to be well maintained
|
||||
- to use a permissive MIT license, similar to BSD or Boost, for proprietary/commercial usage
|
||||
|
||||
It is designed using the Resource Acquisition Is Initialization (RAII) idiom
|
||||
(see [http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization](http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization)),
|
||||
and throwing exceptions in case of SQLite errors (except in destructors,
|
||||
where assert() are used instead).
|
||||
Each SQLiteC++ object must be constructed with a valid SQLite database connection,
|
||||
and then is always valid until destroyed.
|
||||
|
||||
### Supported platforms:
|
||||
|
||||
Now requires a C++11 compiler. Use branch [sqlitecpp-2.x](https://github.com/SRombauts/SQLiteCpp/tree/sqlitecpp-2.x) for latest pre-C++11 developments.
|
||||
|
||||
Developments and tests are done under the following OSs:
|
||||
- Ubuntu 14.04, 16.04 and 18.04 (Travis CI and Github Actions)
|
||||
- Windows 10, and Windows Server 2012 R2, Windows Server 2016, Windows Server 2022 (AppVeyor and Github Actions)
|
||||
- MacOS 10.11 and 11.7 (Travis CI and Github Actions)
|
||||
- Valgrind memcheck tool
|
||||
|
||||
And the following IDEs/Compilers
|
||||
- GCC 4.8.4, 5.3.0, 7.1.1 and latest eg 9.4 (C++11, C++14, C++17)
|
||||
- Clang 5 and 7 (Travis CI)
|
||||
- AppleClang 8, 9 and 13 (Travis CI and Github Actions)
|
||||
- Xcode 8 & 9 (Travis CI)
|
||||
- Visual Studio Community/Entreprise 2022, 2019, 2017, and 2015 (AppVeyor and Github Actions)
|
||||
|
||||
### Dependencies
|
||||
|
||||
- a modern C++11 STL implementation with GCC, Clang, or Visual Studio 2015
|
||||
- exception support (the class Exception inherits from std::runtime_error)
|
||||
- the SQLite library (3.7.15 minimum from 2012-12-12) either by linking to it dynamically or statically (install the libsqlite3-dev package under Debian/Ubuntu/Mint Linux),
|
||||
or by adding its source file in your project code base (source code provided in src/sqlite3 for Windows),
|
||||
with the `SQLITE_ENABLE_COLUMN_METADATA` macro defined (see http://www.sqlite.org/compile.html#enable_column_metadata).
|
||||
|
||||
## Getting started
|
||||
### Installation
|
||||
|
||||
To use this wrapper, you need to add the SQLiteC++ source files from the src/ directory
|
||||
in your project code base, and compile/link against the sqlite library.
|
||||
|
||||
The easiest way to do this is to add the wrapper as a library.
|
||||
The "CMakeLists.txt" file defining the static library is provided in the root directory,
|
||||
so you simply have to add_subdirectory(SQLiteCpp) to you main CMakeLists.txt
|
||||
and link to the "SQLiteCpp" wrapper library.
|
||||
|
||||
Example for Linux:
|
||||
```cmake
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/thirdparty/SQLiteCpp)
|
||||
|
||||
add_executable(main src/main.cpp)
|
||||
target_link_libraries(main
|
||||
SQLiteCpp
|
||||
sqlite3
|
||||
pthread
|
||||
dl
|
||||
)
|
||||
```
|
||||
Thus this SQLiteCpp repository can be directly used as a Git submodule.
|
||||
See the [SQLiteCpp_Example](https://github.com/SRombauts/SQLiteCpp_Example) side repository for a standalone "from scratch" example.
|
||||
|
||||
Under Debian/Ubuntu/Mint Linux, you can install the libsqlite3-dev package if you don't want to use the embedded sqlite3 library.
|
||||
|
||||
### Building example and unit-tests:
|
||||
|
||||
Use git to clone the repository. Then init and update submodule "googletest".
|
||||
|
||||
```Shell
|
||||
git clone https://github.com/SRombauts/SQLiteCpp.git
|
||||
cd SQLiteCpp
|
||||
git submodule init
|
||||
git submodule update
|
||||
```
|
||||
|
||||
### Installing SQLiteCpp (vcpkg)
|
||||
|
||||
Alternatively, you can build and install SQLiteCpp using [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
|
||||
|
||||
```bash or powershell
|
||||
git clone https://github.com/Microsoft/vcpkg.git
|
||||
cd vcpkg
|
||||
./bootstrap-vcpkg.sh
|
||||
./vcpkg integrate install
|
||||
./vcpkg install sqlitecpp
|
||||
```
|
||||
|
||||
The SQLiteCpp port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||
|
||||
|
||||
#### Using SQLiteCpp on a system-wide installation
|
||||
|
||||
If you installed this package to your system, a `SQLiteCppConfig.cmake` file will be generated & installed to your system.
|
||||
This file lets you link against the SQLiteCpp library for use in your Cmake project.
|
||||
|
||||
Here's an example of using this in your CMakeLists.txt
|
||||
```cmake
|
||||
# You can optionally define a minimum version in this call
|
||||
find_package(SQLiteCpp REQUIRED)
|
||||
# For this example, lets say you created an target with add_executable (or add_library) called "my_target"
|
||||
# You can optionally declare PUBLIC or PRIVATE linkage here, depending on your needs.
|
||||
target_link_libraries(my_target PRIVATE SQLiteCpp)
|
||||
```
|
||||
|
||||
#### CMake and tests
|
||||
A CMake configuration file is also provided for multi-platform support and testing.
|
||||
|
||||
Typical generic build for MS Visual Studio under Windows (from [build.bat](build.bat)):
|
||||
|
||||
```Batchfile
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
cmake .. # cmake .. -G "Visual Studio 16 2019" # for Visual Studio 2019
|
||||
@REM Generate a Visual Studio solution for latest version found
|
||||
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
|
||||
@REM Build default configuration (ie 'Debug')
|
||||
cmake --build .
|
||||
|
||||
@REM Build and run tests
|
||||
ctest --output-on-failure
|
||||
```
|
||||
|
||||
Generating the Linux Makefile, building in Debug and executing the tests (from [build.sh](build.sh)):
|
||||
|
||||
```Shell
|
||||
mkdir Debug
|
||||
cd Debug
|
||||
|
||||
# Generate a Makefile for GCC (or Clang, depanding on CC/CXX envvar)
|
||||
cmake -DSQLITECPP_BUILD_EXAMPLES=ON -DSQLITECPP_BUILD_TESTS=ON ..
|
||||
|
||||
# Build (ie 'make')
|
||||
cmake --build .
|
||||
|
||||
# Build and run unit-tests (ie 'make test')
|
||||
ctest --output-on-failure
|
||||
```
|
||||
|
||||
#### CMake options
|
||||
|
||||
* For more options on customizing the build, see the [CMakeLists.txt](https://github.com/SRombauts/SQLiteCpp/blob/master/CMakeLists.txt) file.
|
||||
|
||||
#### Troubleshooting
|
||||
|
||||
Under Linux, if you get multiple linker errors like "undefined reference to sqlite3_xxx",
|
||||
it's that you lack the "sqlite3" library: install the libsqlite3-dev package.
|
||||
|
||||
If you get a single linker error "Column.cpp: undefined reference to sqlite3_column_origin_name",
|
||||
it's that your "sqlite3" library was not compiled with
|
||||
the `SQLITE_ENABLE_COLUMN_METADATA` macro defined (see [http://www.sqlite.org/compile.html#enable_column_metadata](http://www.sqlite.org/compile.html#enable_column_metadata)).
|
||||
You can:
|
||||
- either recompile the sqlite3 library provided by your distribution yourself (seek help online)
|
||||
- or turn off the `option(SQLITE_ENABLE_COLUMN_METADATA "Enable Column::getColumnOriginName(). Require support from sqlite3 library." ON)` in [CMakeFiles.txt](CMakeFiles.txt) (or other build system scripts)
|
||||
- or turn on the `option(SQLITECPP_INTERNAL_SQLITE "Add the internal SQLite3 source to the project." ON)` in [CMakeFiles.txt](CMakeFiles.txt)
|
||||
|
||||
### Continuous Integration
|
||||
|
||||
This project is continuously tested under Ubuntu Linux with the gcc and clang compilers
|
||||
using the Travis CI community service with the above CMake building and testing procedure.
|
||||
It is also tested in the same way under Windows Server 2012 R2 with Visual Studio 2013 compiler
|
||||
using the AppVeyor continuous integration service.
|
||||
|
||||
Detailed results can be seen online:
|
||||
- [https://travis-ci.org/SRombauts/SQLiteCpp](https://travis-ci.org/SRombauts/SQLiteCpp)
|
||||
- [https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp](https://ci.appveyor.com/project/SbastienRombauts/SQLiteCpp)
|
||||
|
||||
### Thread-safety
|
||||
|
||||
SQLite supports three modes of thread safety, as describe in "SQLite And Multiple Threads":
|
||||
see [http://www.sqlite.org/threadsafe.html](http://www.sqlite.org/threadsafe.html)
|
||||
|
||||
This SQLiteC++ wrapper does no add any locks (no mutexes) nor any other thread-safety mechanism
|
||||
above the SQLite library itself, by design, for lightness and speed.
|
||||
|
||||
Thus, SQLiteC++ naturally supports the "Multi Thread" mode of SQLite:
|
||||
"In this mode, SQLite can be safely used by multiple threads
|
||||
provided that no single database connection is used simultaneously in two or more threads."
|
||||
|
||||
But SQLiteC++ does not support the fully thread-safe "Serialized" mode of SQLite,
|
||||
because of the way it shares the underlying SQLite precompiled statement
|
||||
in a custom shared pointer (See the inner class "Statement::Ptr").
|
||||
|
||||
### Valgrind memcheck
|
||||
|
||||
Run valgrind to search for memory leaks in your application, the SQLiteCpp wrapper, or the sqlite3 library.
|
||||
Execute the following command under Unix like OS (Linux, MacOS or WSL2/Ubuntu under Windows Subsystem for Linux):
|
||||
|
||||
```Shell
|
||||
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --verbose build/SQLiteCpp_example1
|
||||
```
|
||||
|
||||
or uncoment the line at the end of [build.sh](build.sh)
|
||||
|
||||
## Examples
|
||||
### The first sample demonstrates how to query a database and get results:
|
||||
|
||||
```C++
|
||||
try
|
||||
{
|
||||
// Open a database file
|
||||
SQLite::Database db("example.db3");
|
||||
|
||||
// Compile a SQL query, containing one parameter (index 1)
|
||||
SQLite::Statement query(db, "SELECT * FROM test WHERE size > ?");
|
||||
|
||||
// Bind the integer value 6 to the first parameter of the SQL query
|
||||
query.bind(1, 6);
|
||||
|
||||
// Loop to execute the query step by step, to get rows of result
|
||||
while (query.executeStep())
|
||||
{
|
||||
// Demonstrate how to get some typed column value
|
||||
int id = query.getColumn(0);
|
||||
const char* value = query.getColumn(1);
|
||||
int size = query.getColumn(2);
|
||||
|
||||
std::cout << "row: " << id << ", " << value << ", " << size << std::endl;
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "exception: " << e.what() << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
### The second sample shows how to manage a transaction:
|
||||
|
||||
```C++
|
||||
try
|
||||
{
|
||||
SQLite::Database db("transaction.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
|
||||
|
||||
// Commit transaction
|
||||
transaction.commit();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "exception: " << e.what() << std::endl;
|
||||
}
|
||||
```
|
||||
|
||||
### How to handle assertion in SQLiteC++:
|
||||
Exceptions shall not be used in destructors, so SQLiteC++ uses SQLITECPP_ASSERT() to check for errors in destructors.
|
||||
If you don't want assert() to be called, you have to enable and define an assert handler as shown below,
|
||||
and by setting the flag SQLITECPP_ENABLE_ASSERT_HANDLER when compiling the lib.
|
||||
|
||||
```C++
|
||||
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
namespace SQLite
|
||||
{
|
||||
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
|
||||
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
|
||||
{
|
||||
// Print a message to the standard error output stream, and abort the program.
|
||||
std::cerr << apFile << ":" << apLine << ":" << " error: assertion failed (" << apExpr << ") in " << apFunc << "() with message \"" << apMsg << "\"\n";
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
```
|
||||
|
||||
## How to contribute
|
||||
### GitHub website
|
||||
The most efficient way to help and contribute to this wrapper project is to
|
||||
use the tools provided by GitHub:
|
||||
- please fill bug reports and feature requests here: [https://github.com/SRombauts/SQLiteCpp/issues](https://github.com/SRombauts/SQLiteCpp/issues)
|
||||
- fork the repository, make some small changes and submit them with pull-request
|
||||
|
||||
### Contact
|
||||
You can also email me directly, I will try to answer questions and requests whenever I get the time for it.
|
||||
|
||||
### Coding Style Guidelines
|
||||
The source code use the CamelCase naming style variant where:
|
||||
- type names (class, struct, typedef, enums...) begin with a capital letter
|
||||
- files (.cpp/.h) are named like the class they contain
|
||||
- function and variable names begin with a lower case letter
|
||||
- member variables begin with a 'm', function arguments begin with a 'a', booleans with a 'b', pointers with a 'p'
|
||||
- each file, class, method and member variable is documented using Doxygen tags
|
||||
- braces on their own line
|
||||
See also [http://www.appinf.com/download/CppCodingStyleGuide.pdf](http://www.appinf.com/download/CppCodingStyleGuide.pdf) for good guidelines
|
||||
|
||||
## See also - Some other simple C++ SQLite wrappers:
|
||||
|
||||
See bellow a short comparison of other wrappers done at the time of writing:
|
||||
- [sqdbcpp](http://code.google.com/p/sqdbcpp/): RAII design, simple, no dependencies, UTF-8/UTF-16, new BSD license
|
||||
- [sqlite3cc](http://ed.am/dev/sqlite3cc): uses boost, modern design, LPGPL
|
||||
- [sqlite3pp](https://github.com/iwongu/sqlite3pp): modern design inspired by boost, MIT License
|
||||
- [SQLite++](http://sqlitepp.berlios.de/): uses boost build system, Boost License 1.0
|
||||
- [CppSQLite](http://www.codeproject.com/Articles/6343/CppSQLite-C-Wrapper-for-SQLite/): famous Code Project but old design, BSD License
|
||||
- [easySQLite](http://code.google.com/p/easysqlite/): manages table as structured objects, complex
|
||||
- [sqlite_modern_cpp](https://github.com/keramer/sqlite_modern_cpp): modern C++11, all in one file, MIT license
|
||||
- [sqlite_orm](https://github.com/fnc12/sqlite_orm): modern C++14, header only all in one file, no raw string queries, BSD-3 license
|
6
third-party/SQLiteCpp/examples/example1/README.md
generated
vendored
6
third-party/SQLiteCpp/examples/example1/README.md
generated
vendored
@ -1,6 +0,0 @@
|
||||
examples/example1 - main example
|
||||
--------------------------------
|
||||
|
||||
SQLiteCpp_Example demonstrates how to use SQLiteCpp as a subdirectory of a CMake project.
|
||||
|
||||
See also examples/example2 on how to use SQLiteCpp as a subdirectory of a CMake project
|
BIN
third-party/SQLiteCpp/examples/example1/example.db3
generated
vendored
BIN
third-party/SQLiteCpp/examples/example1/example.db3
generated
vendored
Binary file not shown.
BIN
third-party/SQLiteCpp/examples/example1/logo.png
generated
vendored
BIN
third-party/SQLiteCpp/examples/example1/logo.png
generated
vendored
Binary file not shown.
Before Width: | Height: | Size: 12 KiB |
507
third-party/SQLiteCpp/examples/example1/main.cpp
generated
vendored
507
third-party/SQLiteCpp/examples/example1/main.cpp
generated
vendored
@ -1,507 +0,0 @@
|
||||
/**
|
||||
* @file main.cpp
|
||||
* @brief A few short examples in a row.
|
||||
*
|
||||
* Demonstrates how-to use the SQLite++ wrapper
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include <SQLiteCpp/SQLiteCpp.h>
|
||||
#include <SQLiteCpp/VariadicBind.h>
|
||||
|
||||
|
||||
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
namespace SQLite
|
||||
{
|
||||
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
|
||||
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
|
||||
{
|
||||
// Print a message to the standard error output stream, and abort the program.
|
||||
std::cerr << apFile << ":" << apLine << ":" << " error: assertion failed (" << apExpr << ") in " << apFunc << "() with message \"" << apMsg << "\"\n";
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Get path to this example's directory (including the final separator '/' or '\')
|
||||
static inline std::string getExamplePath()
|
||||
{
|
||||
std::string filePath(__FILE__);
|
||||
return filePath.substr( 0, filePath.length() - std::string("main.cpp").length());
|
||||
}
|
||||
|
||||
/// Example Database
|
||||
static const std::string filename_example_db3 = getExamplePath() + "example.db3";
|
||||
/// Image (SQLite logo as a 12581 bytes PNG file)
|
||||
static const int sizeof_logo_png = 12581;
|
||||
static const std::string filename_logo_png = getExamplePath() + "logo.png";
|
||||
|
||||
|
||||
/// Object Oriented Basic example
|
||||
class Example
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
Example() :
|
||||
mDb(filename_example_db3), // Open a database file in read-only mode
|
||||
mQuery(mDb, "SELECT * FROM test WHERE weight > :min_weight")// Compile a SQL query, containing one parameter (index 1)
|
||||
{
|
||||
}
|
||||
virtual ~Example()
|
||||
{
|
||||
}
|
||||
|
||||
/// List the rows where the "weight" column is greater than the provided aParamValue
|
||||
void ListGreaterThan(const int aParamValue)
|
||||
{
|
||||
std::cout << "ListGreaterThan(" << aParamValue << ")\n";
|
||||
|
||||
// Bind the integer value provided to the first parameter of the SQL query
|
||||
mQuery.bind(":min_weight", aParamValue); // same as mQuery.bind(1, aParamValue);
|
||||
|
||||
// Loop to execute the query step by step, to get one a row of results at a time
|
||||
while (mQuery.executeStep())
|
||||
{
|
||||
std::cout << "row (" << mQuery.getColumn(0) << ", \"" << mQuery.getColumn(1) << "\", " << mQuery.getColumn(2) << ")\n";
|
||||
}
|
||||
|
||||
// Reset the query to be able to use it again later
|
||||
mQuery.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
SQLite::Database mDb; ///< Database connection
|
||||
SQLite::Statement mQuery; ///< Database prepared SQL query
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// Using SQLITE_VERSION would require #include <sqlite3.h> which we want to avoid: use SQLite::VERSION if possible.
|
||||
// std::cout << "SQlite3 version " << SQLITE_VERSION << std::endl;
|
||||
std::cout << "SQlite3 version " << SQLite::VERSION << " (" << SQLite::getLibVersion() << ")" << std::endl;
|
||||
std::cout << "SQliteC++ version " << SQLITECPP_VERSION << std::endl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Inspect a database via SQLite header information
|
||||
try
|
||||
{
|
||||
const SQLite::Header header = SQLite::Database::getHeaderInfo(filename_example_db3);
|
||||
|
||||
// Print values for all header fields
|
||||
// Official documentation for fields can be found here: https://www.sqlite.org/fileformat.html#the_database_header
|
||||
std::cout << "Magic header string: " << header.headerStr << std::endl;
|
||||
std::cout << "Page size bytes: " << header.pageSizeBytes << std::endl;
|
||||
std::cout << "File format write version: " << (int)header.fileFormatWriteVersion << std::endl;
|
||||
std::cout << "File format read version: " << (int)header.fileFormatReadVersion << std::endl;
|
||||
std::cout << "Reserved space bytes: " << (int)header.reservedSpaceBytes << std::endl;
|
||||
std::cout << "Max embedded payload fraction " << (int)header.maxEmbeddedPayloadFrac << std::endl;
|
||||
std::cout << "Min embedded payload fraction: " << (int)header.minEmbeddedPayloadFrac << std::endl;
|
||||
std::cout << "Leaf payload fraction: " << (int)header.leafPayloadFrac << std::endl;
|
||||
std::cout << "File change counter: " << header.fileChangeCounter << std::endl;
|
||||
std::cout << "Database size pages: " << header.databaseSizePages << std::endl;
|
||||
std::cout << "First freelist trunk page: " << header.firstFreelistTrunkPage << std::endl;
|
||||
std::cout << "Total freelist trunk pages: " << header.totalFreelistPages << std::endl;
|
||||
std::cout << "Schema cookie: " << header.schemaCookie << std::endl;
|
||||
std::cout << "Schema format number: " << header.schemaFormatNumber << std::endl;
|
||||
std::cout << "Default page cache size bytes: " << header.defaultPageCacheSizeBytes << std::endl;
|
||||
std::cout << "Largest B tree page number: " << header.largestBTreePageNumber << std::endl;
|
||||
std::cout << "Database text encoding: " << header.databaseTextEncoding << std::endl;
|
||||
std::cout << "User version: " << header.userVersion << std::endl;
|
||||
std::cout << "Incremental vaccum mode: " << header.incrementalVaccumMode << std::endl;
|
||||
std::cout << "Application ID: " << header.applicationId << std::endl;
|
||||
std::cout << "Version valid for: " << header.versionValidFor << std::endl;
|
||||
std::cout << "SQLite version: " << header.sqliteVersion << std::endl;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Very basic first example (1/7) :
|
||||
try
|
||||
{
|
||||
// Open a database file in read-only mode
|
||||
SQLite::Database db(filename_example_db3); // SQLite::OPEN_READONLY
|
||||
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
|
||||
|
||||
// Test if the 'test' table exists
|
||||
const bool bExists = db.tableExists("test");
|
||||
std::cout << "SQLite table 'test' exists=" << bExists << "\n";
|
||||
|
||||
// Get a single value result with an easy to use shortcut
|
||||
const std::string value = db.execAndGet("SELECT value FROM test WHERE id=2");
|
||||
std::cout << "execAndGet=" << value.c_str() << std::endl;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Simple select query - few variations (2/7) :
|
||||
try
|
||||
{
|
||||
// Open a database file in read-only mode
|
||||
SQLite::Database db(filename_example_db3); // SQLite::OPEN_READONLY
|
||||
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
|
||||
|
||||
///// a) Loop to get values of column by index, using auto cast to variable type
|
||||
|
||||
// Compile a SQL query, containing one parameter (index 1)
|
||||
SQLite::Statement query(db, "SELECT id as test_id, value as test_val, weight as test_weight FROM test WHERE weight > ?");
|
||||
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' compiled (" << query.getColumnCount() << " columns in the result)\n";
|
||||
// Bind the integer value 2 to the first parameter of the SQL query
|
||||
query.bind(1, 2);
|
||||
std::cout << "binded with integer value '2' :\n";
|
||||
|
||||
// Loop to execute the query step by step, to get one a row of results at a time
|
||||
while (query.executeStep())
|
||||
{
|
||||
// Demonstrates how to get some typed column value (and the equivalent explicit call)
|
||||
const int id = query.getColumn(0); // = query.getColumn(0).getInt();
|
||||
//const char* pvalue = query.getColumn(1); // = query.getColumn(1).getText();
|
||||
const std::string value = query.getColumn(1); // = query.getColumn(1).getText();
|
||||
const int bytes = query.getColumn(1).size(); // .getColumn(1).getBytes();
|
||||
const double weight = query.getColumn(2); // = query.getColumn(2).getInt();
|
||||
std::cout << "row (" << id << ", \"" << value.c_str() << "\"(" << bytes << ") " << weight << ")\n";
|
||||
}
|
||||
|
||||
///// b) Get aliased column names (and original column names if possible)
|
||||
|
||||
// Reset the query to use it again
|
||||
query.reset();
|
||||
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' reseted (" << query.getColumnCount() << " columns in the result)\n";
|
||||
|
||||
// Show how to get the aliased names of the result columns.
|
||||
const std::string name0 = query.getColumnName(0);
|
||||
const std::string name1 = query.getColumnName(1);
|
||||
const std::string name2 = query.getColumnName(2);
|
||||
std::cout << "aliased result [\"" << name0.c_str() << "\", \"" << name1.c_str() << "\", \"" << name2.c_str() << "\"]\n";
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Show how to get origin names of the table columns from which theses result columns come from.
|
||||
// Requires the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro to be
|
||||
// also defined at compile times of the SQLite library itself.
|
||||
const std::string oname0 = query.getColumnOriginName(0);
|
||||
const std::string oname1 = query.getColumnOriginName(1);
|
||||
const std::string oname2 = query.getColumnOriginName(2);
|
||||
std::cout << "origin table 'test' [\"" << oname0.c_str() << "\", \"" << oname1.c_str() << "\", \"" << oname2.c_str() << "\"]\n";
|
||||
#endif
|
||||
// Loop to execute the query step by step, to get one a row of results at a time
|
||||
while (query.executeStep())
|
||||
{
|
||||
// Demonstrates that inserting column value in a std:ostream is natural
|
||||
std::cout << "row (" << query.getColumn(0) << ", \"" << query.getColumn(1) << "\", " << query.getColumn(2) << ")\n";
|
||||
}
|
||||
|
||||
///// c) Get columns by name
|
||||
|
||||
// Reset the query to use it again
|
||||
query.reset();
|
||||
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' reseted (" << query.getColumnCount() << " columns in the result)\n";
|
||||
|
||||
// Loop to execute the query step by step, to get one a row of results at a time
|
||||
while (query.executeStep())
|
||||
{
|
||||
// Demonstrates how to get column value by aliased name (not the original table names, see above)
|
||||
const int id = query.getColumn("test_id");
|
||||
const std::string value = query.getColumn("test_val");
|
||||
const double weight = query.getColumn("test_weight");
|
||||
std::cout << "row (" << id << ", \"" << value.c_str() << "\" " << weight << ")\n";
|
||||
}
|
||||
|
||||
///// d) Uses explicit typed getters instead of auto cast operators
|
||||
|
||||
// Reset the query to use it again
|
||||
query.reset();
|
||||
std::cout << "SQLite statement '" << query.getQuery().c_str() << "' reseted (" << query.getColumnCount () << " columns in the result)\n";
|
||||
// Bind the string value "6" to the first parameter of the SQL query
|
||||
query.bind(1, "6");
|
||||
std::cout << "binded with string value \"6\" :\n";
|
||||
// Reuses variables: uses assignment operator in the loop instead of constructor with initialization
|
||||
int id = 0;
|
||||
std::string value;
|
||||
double weight = 0.0;
|
||||
while (query.executeStep())
|
||||
{
|
||||
id = query.getColumn(0).getInt();
|
||||
value = query.getColumn(1).getText();
|
||||
weight = query.getColumn(2).getInt();
|
||||
std::cout << "row (" << id << ", \"" << value << "\", " << weight << ")\n";
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Object Oriented Basic example (3/7) :
|
||||
try
|
||||
{
|
||||
// Open the database and compile the query
|
||||
Example example;
|
||||
|
||||
// Demonstrates the way to use the same query with different parameter values
|
||||
example.ListGreaterThan(8);
|
||||
example.ListGreaterThan(6);
|
||||
example.ListGreaterThan(2);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
|
||||
// The execAndGet wrapper example (4/7) :
|
||||
try
|
||||
{
|
||||
// Open a database file in read-only mode
|
||||
SQLite::Database db(filename_example_db3); // SQLite::OPEN_READONLY
|
||||
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
|
||||
|
||||
// WARNING: Be very careful with this dangerous method: you have to
|
||||
// make a COPY OF THE result, else it will be destroy before the next line
|
||||
// (when the underlying temporary Statement and Column objects are destroyed)
|
||||
std::string value = db.execAndGet("SELECT value FROM test WHERE id=2");
|
||||
std::cout << "execAndGet=" << value.c_str() << std::endl;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Simple batch queries example (5/7) :
|
||||
try
|
||||
{
|
||||
// Open a database file in create/write mode
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
|
||||
|
||||
// Create a new table with an explicit "id" column aliasing the underlying rowid
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
// first row
|
||||
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
|
||||
|
||||
// second row
|
||||
nb = db.exec("INSERT INTO test VALUES (NULL, \"second\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"second\")\", returned " << nb << std::endl;
|
||||
|
||||
// update the second row
|
||||
nb = db.exec("UPDATE test SET value=\"second-updated\" WHERE id='2'");
|
||||
std::cout << "UPDATE test SET value=\"second-updated\" WHERE id='2', returned " << nb << std::endl;
|
||||
|
||||
nb = db.getTotalChanges();
|
||||
std::cout << "Nb of total changes since connection: " << nb << std::endl;
|
||||
|
||||
// Check the results : expect two row of result
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
std::cout << "SELECT * FROM test :\n";
|
||||
while (query.executeStep())
|
||||
{
|
||||
std::cout << "row (" << query.getColumn(0) << ", \"" << query.getColumn(1) << "\")\n";
|
||||
}
|
||||
|
||||
db.exec("DROP TABLE test");
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
remove("test.db3");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// RAII transaction example (6/7) :
|
||||
try
|
||||
{
|
||||
// Open a database file in create/write mode
|
||||
SQLite::Database db("transaction.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
|
||||
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
|
||||
// Exemple of a successful transaction :
|
||||
try
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
|
||||
|
||||
// Commit transaction
|
||||
transaction.commit();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
|
||||
// Exemple of a rollbacked transaction :
|
||||
try
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
int nb = db.exec("INSERT INTO test VALUES (NULL, \"second\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"second\")\", returned " << nb << std::endl;
|
||||
|
||||
nb = db.exec("INSERT INTO test ObviousError");
|
||||
std::cout << "INSERT INTO test \"error\", returned " << nb << std::endl;
|
||||
|
||||
return EXIT_FAILURE; // we should never get there : exit the example program
|
||||
|
||||
// Commit transaction
|
||||
transaction.commit();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
// expected error, see above
|
||||
}
|
||||
|
||||
// Check the results (expect only one row of result, as the second one has been rollbacked by the error)
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
std::cout << "SELECT * FROM test :\n";
|
||||
while (query.executeStep())
|
||||
{
|
||||
std::cout << "row (" << query.getColumn(0) << ", \"" << query.getColumn(1) << "\")\n";
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
remove("transaction.db3");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Binary blob and in-memory database example (7/7) :
|
||||
try
|
||||
{
|
||||
// Open a database file in create/write mode
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
|
||||
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value BLOB)");
|
||||
|
||||
// A) insert the logo.png image into the db as a blob
|
||||
FILE* fp = fopen(filename_logo_png.c_str(), "rb");
|
||||
if (NULL != fp)
|
||||
{
|
||||
char buffer[16*1024];
|
||||
static_assert(sizeof(buffer) > sizeof_logo_png, "Buffer is smaller than the size of the file to read");
|
||||
void* blob = &buffer;
|
||||
const int size = static_cast<int>(fread(blob, 1, 16*1024, fp));
|
||||
buffer[size] = '\0';
|
||||
SQLITECPP_ASSERT(size == sizeof_logo_png, "unexpected fread return value"); // See SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
fclose(fp);
|
||||
std::cout << filename_logo_png << " file size=" << size << " bytes\n";
|
||||
|
||||
// Insert query
|
||||
SQLite::Statement query(db, "INSERT INTO test VALUES (NULL, ?)");
|
||||
// Bind the blob value to the first parameter of the SQL query
|
||||
query.bind(1, blob, size);
|
||||
std::cout << "blob binded successfully\n";
|
||||
|
||||
// Execute the one-step query to insert the blob
|
||||
int nb = query.exec();
|
||||
std::cout << "INSERT INTO test VALUES (NULL, ?)\", returned " << nb << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file " << filename_logo_png << " not found !\n";
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
|
||||
// B) select the blob from the db and write it to disk into a "out.png" image file
|
||||
fp = fopen("out.png", "wb");
|
||||
if (NULL != fp)
|
||||
{
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
std::cout << "SELECT * FROM test :\n";
|
||||
if (query.executeStep())
|
||||
{
|
||||
SQLite::Column colBlob = query.getColumn(1);
|
||||
const void* const blob = colBlob.getBlob();
|
||||
const size_t size = colBlob.getBytes();
|
||||
std::cout << "row (" << query.getColumn(0) << ", size=" << size << " bytes)\n";
|
||||
size_t sizew = fwrite(blob, 1, size, fp);
|
||||
SQLITECPP_ASSERT(sizew == size, "fwrite failed"); // See SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
fclose(fp);
|
||||
}
|
||||
// NOTE: here the blob is still held in memory, until the Statement is finalized at the end of the scope
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "file out.png not created !\n";
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
remove("out.png");
|
||||
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
// example with C++14 variadic bind
|
||||
try
|
||||
{
|
||||
// Open a database file in create/write mode
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
{
|
||||
SQLite::Statement query(db, "INSERT INTO test VALUES (?, ?)");
|
||||
|
||||
SQLite::bind(query, 42, "fortytwo");
|
||||
// Execute the one-step query to insert the blob
|
||||
int nb = query.exec();
|
||||
std::cout << "INSERT INTO test VALUES (NULL, ?)\", returned " << nb << std::endl;
|
||||
}
|
||||
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
std::cout << "SELECT * FROM test :\n";
|
||||
if (query.executeStep())
|
||||
{
|
||||
std::cout << query.getColumn(0).getInt() << "\t\"" << query.getColumn(1).getText() << "\"\n";
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
#endif
|
||||
|
||||
std::cout << "everything ok, quitting\n";
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
26
third-party/SQLiteCpp/examples/example2/CMakeLists.txt
generated
vendored
26
third-party/SQLiteCpp/examples/example2/CMakeLists.txt
generated
vendored
@ -1,26 +0,0 @@
|
||||
# Example CMake file for compiling & linking a project with the the SQLiteCpp wrapper
|
||||
#
|
||||
# Copyright (c) 2012-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
#
|
||||
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
# or copy at http://opensource.org/licenses/MIT)
|
||||
cmake_minimum_required(VERSION 3.1) # for "CMAKE_CXX_STANDARD" version
|
||||
project(SQLiteCpp_Example VERSION 2.0)
|
||||
|
||||
# SQLiteC++ 3.x now requires C++11 compiler
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Add SQLite3 C++ wrapper around sqlite3 library (and sqlite3 itself provided for ease of use)
|
||||
# Here you can set CMake variables to avoid building Example, as well as cpplint, cppcheck...
|
||||
# or set them in the cmake command line (see for instance provided build.bat/build.sh scripts)
|
||||
set(SQLITECPP_RUN_CPPCHECK OFF CACHE BOOL "" FORCE)
|
||||
set(SQLITECPP_RUN_CPPLINT OFF CACHE BOOL "" FORCE)
|
||||
set(SQLITECPP_USE_STATIC_RUNTIME OFF CACHE BOOL "" FORCE)
|
||||
add_subdirectory(../.. SQLiteCpp) # out-of-source build requires explicit subdir name for compilation artifacts
|
||||
|
||||
# Add main.cpp example source code to the executable
|
||||
add_executable(SQLiteCpp_Example src/main.cpp)
|
||||
|
||||
# Link SQLiteCpp_example1 with SQLiteCpp
|
||||
target_link_libraries(SQLiteCpp_Example SQLiteCpp)
|
8
third-party/SQLiteCpp/examples/example2/README.md
generated
vendored
8
third-party/SQLiteCpp/examples/example2/README.md
generated
vendored
@ -1,8 +0,0 @@
|
||||
examples/example2 - SQLiteCpp_Example
|
||||
-------------------------------------
|
||||
|
||||
SQLiteCpp_Example demonstrates how to use SQLiteCpp as a subdirectory of a CMake project.
|
||||
|
||||
See https://github.com/SRombauts/SQLiteCpp_Example
|
||||
|
||||
See also examples/example1 for the main example on how to use SQLiteCpp in a C++ project
|
21
third-party/SQLiteCpp/examples/example2/build.bat
generated
vendored
21
third-party/SQLiteCpp/examples/example2/build.bat
generated
vendored
@ -1,21 +0,0 @@
|
||||
@REM Copyright (c) 2012-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
@REM
|
||||
@REM Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
@REM or copy at http://opensource.org/licenses/MIT)
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
@REM Generate a Visual Studio solution for latest version found
|
||||
cmake ..
|
||||
@if ERRORLEVEL 1 goto onError
|
||||
|
||||
@REM Build default configuration (ie 'Debug')
|
||||
cmake --build .
|
||||
@if ERRORLEVEL 1 goto onError
|
||||
|
||||
goto onSuccess
|
||||
|
||||
:onError
|
||||
@echo An error occured!
|
||||
:onSuccess
|
||||
cd ..
|
18
third-party/SQLiteCpp/examples/example2/build.sh
generated
vendored
18
third-party/SQLiteCpp/examples/example2/build.sh
generated
vendored
@ -1,18 +0,0 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2012-2020 Sébastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
#
|
||||
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
# or copy at http://opensource.org/licenses/MIT)
|
||||
|
||||
# exit on first error
|
||||
set -e
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
# Generate a Makefile for GCC (or Clang, depanding on CC/CXX envvar)
|
||||
cmake -DCMAKE_BUILD_TYPE=Debug ..
|
||||
|
||||
# Build (ie 'make')
|
||||
cmake --build .
|
||||
|
84
third-party/SQLiteCpp/examples/example2/src/main.cpp
generated
vendored
84
third-party/SQLiteCpp/examples/example2/src/main.cpp
generated
vendored
@ -1,84 +0,0 @@
|
||||
/**
|
||||
* @file main.cpp
|
||||
* @brief A few short examples in a row.
|
||||
*
|
||||
* Demonstrates how-to use the SQLite++ wrapper
|
||||
*
|
||||
* Copyright (c) 2012-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include <SQLiteCpp/SQLiteCpp.h>
|
||||
|
||||
|
||||
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
namespace SQLite
|
||||
{
|
||||
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
|
||||
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
|
||||
{
|
||||
// Print a message to the standard error output stream, and abort the program.
|
||||
std::cerr << apFile << ":" << apLine << ":" << " error: assertion failed (" << apExpr << ") in " << apFunc << "() with message \"" << apMsg << "\"\n";
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main ()
|
||||
{
|
||||
// Using SQLITE_VERSION would require #include <sqlite3.h> which we want to avoid: use SQLite::VERSION if possible.
|
||||
// std::cout << "SQlite3 version " << SQLITE_VERSION << std::endl;
|
||||
std::cout << "SQlite3 version " << SQLite::VERSION << " (" << SQLite::getLibVersion() << ")" << std::endl;
|
||||
std::cout << "SQliteC++ version " << SQLITECPP_VERSION << std::endl;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Simple batch queries example :
|
||||
try
|
||||
{
|
||||
// Open a database file in create/write mode
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
std::cout << "SQLite database file '" << db.getFilename().c_str() << "' opened successfully\n";
|
||||
|
||||
// Create a new table with an explicit "id" column aliasing the underlying rowid
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
// first row
|
||||
int nb = db.exec("INSERT INTO test VALUES (NULL, \"test\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"test\")\", returned " << nb << std::endl;
|
||||
|
||||
// second row
|
||||
nb = db.exec("INSERT INTO test VALUES (NULL, \"second\")");
|
||||
std::cout << "INSERT INTO test VALUES (NULL, \"second\")\", returned " << nb << std::endl;
|
||||
|
||||
// update the second row
|
||||
nb = db.exec("UPDATE test SET value=\"second-updated\" WHERE id='2'");
|
||||
std::cout << "UPDATE test SET value=\"second-updated\" WHERE id='2', returned " << nb << std::endl;
|
||||
|
||||
// Check the results : expect two row of result
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
std::cout << "SELECT * FROM test :\n";
|
||||
while (query.executeStep())
|
||||
{
|
||||
std::cout << "row (" << query.getColumn(0) << ", \"" << query.getColumn(1) << "\")\n";
|
||||
}
|
||||
|
||||
db.exec("DROP TABLE test");
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
return EXIT_FAILURE; // unexpected error : exit the example program
|
||||
}
|
||||
remove("test.db3");
|
||||
|
||||
std::cout << "everything ok, quitting\n";
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
46
third-party/SQLiteCpp/include/SQLiteCpp/Assertion.h
generated
vendored
46
third-party/SQLiteCpp/include/SQLiteCpp/Assertion.h
generated
vendored
@ -1,46 +0,0 @@
|
||||
/**
|
||||
* @file Assertion.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Definition of the SQLITECPP_ASSERT() macro.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
|
||||
|
||||
/**
|
||||
* SQLITECPP_ASSERT SQLITECPP_ASSERT() is used in destructors, where exceptions shall not be thrown
|
||||
*
|
||||
* Define SQLITECPP_ENABLE_ASSERT_HANDLER at the project level
|
||||
* and define a SQLite::assertion_failed() assertion handler
|
||||
* to tell SQLiteC++ to use it instead of assert() when an assertion fail.
|
||||
*/
|
||||
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
|
||||
// if an assert handler is provided by user code, use it instead of assert()
|
||||
namespace SQLite
|
||||
{
|
||||
// declaration of the assert handler to define in user code
|
||||
void assertion_failed(const char* apFile, const int apLine, const char* apFunc,
|
||||
const char* apExpr, const char* apMsg);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __func__ __FUNCTION__
|
||||
#endif
|
||||
// call the assert handler provided by user code
|
||||
#define SQLITECPP_ASSERT(expression, message) \
|
||||
if (!(expression)) SQLite::assertion_failed(__FILE__, __LINE__, __func__, #expression, message)
|
||||
} // namespace SQLite
|
||||
|
||||
#else
|
||||
|
||||
// if no assert handler provided by user code, use standard assert()
|
||||
// (note: in release mode assert() does nothing)
|
||||
#define SQLITECPP_ASSERT(expression, message) assert(expression && message)
|
||||
|
||||
#endif
|
130
third-party/SQLiteCpp/include/SQLiteCpp/Backup.h
generated
vendored
130
third-party/SQLiteCpp/include/SQLiteCpp/Backup.h
generated
vendored
@ -1,130 +0,0 @@
|
||||
/**
|
||||
* @file Backup.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Backup is used to backup a database file in a safe and online way.
|
||||
*
|
||||
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
|
||||
* Copyright (c) 2015-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
// Forward declaration to avoid inclusion of <sqlite3.h> in a header
|
||||
struct sqlite3_backup;
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief RAII encapsulation of a SQLite Database Backup process.
|
||||
*
|
||||
* A Backup object is used to backup a source database file to a destination database file
|
||||
* in a safe and online way.
|
||||
*
|
||||
* See also the a reference implementation of live backup taken from the official site:
|
||||
* https://www.sqlite.org/backup.html
|
||||
*/
|
||||
class Backup
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Initialize a SQLite Backup object.
|
||||
*
|
||||
* Initialize a SQLite Backup object for the source database and destination database.
|
||||
* The database name is "main" for the main database, "temp" for the temporary database,
|
||||
* or the name specified after the AS keyword in an ATTACH statement for an attached database.
|
||||
*
|
||||
* Exception is thrown in case of error, then the Backup object is NOT constructed.
|
||||
*
|
||||
* @param[in] aDestDatabase Destination database connection
|
||||
* @param[in] apDestDatabaseName Destination database name
|
||||
* @param[in] aSrcDatabase Source database connection
|
||||
* @param[in] apSrcDatabaseName Source database name
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Backup(Database& aDestDatabase,
|
||||
const char* apDestDatabaseName,
|
||||
Database& aSrcDatabase,
|
||||
const char* apSrcDatabaseName);
|
||||
|
||||
/**
|
||||
* @brief Initialize a SQLite Backup object.
|
||||
*
|
||||
* Initialize a SQLite Backup object for source database and destination database.
|
||||
* The database name is "main" for the main database, "temp" for the temporary database,
|
||||
* or the name specified after the AS keyword in an ATTACH statement for an attached database.
|
||||
*
|
||||
* Exception is thrown in case of error, then the Backup object is NOT constructed.
|
||||
*
|
||||
* @param[in] aDestDatabase Destination database connection
|
||||
* @param[in] aDestDatabaseName Destination database name
|
||||
* @param[in] aSrcDatabase Source database connection
|
||||
* @param[in] aSrcDatabaseName Source database name
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Backup(Database& aDestDatabase,
|
||||
const std::string& aDestDatabaseName,
|
||||
Database& aSrcDatabase,
|
||||
const std::string& aSrcDatabaseName);
|
||||
|
||||
/**
|
||||
* @brief Initialize a SQLite Backup object for main databases.
|
||||
*
|
||||
* Initialize a SQLite Backup object for source database and destination database.
|
||||
* Backup the main databases between the source and the destination.
|
||||
*
|
||||
* Exception is thrown in case of error, then the Backup object is NOT constructed.
|
||||
*
|
||||
* @param[in] aDestDatabase Destination database connection
|
||||
* @param[in] aSrcDatabase Source database connection
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Backup(Database& aDestDatabase,
|
||||
Database& aSrcDatabase);
|
||||
|
||||
// Backup is non-copyable
|
||||
Backup(const Backup&) = delete;
|
||||
Backup& operator=(const Backup&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Execute a step of backup with a given number of source pages to be copied
|
||||
*
|
||||
* Exception is thrown when SQLITE_IOERR_XXX, SQLITE_NOMEM, or SQLITE_READONLY is returned
|
||||
* in sqlite3_backup_step(). These errors are considered fatal, so there is no point
|
||||
* in retrying the call to executeStep().
|
||||
*
|
||||
* @param[in] aNumPage The number of source pages to be copied, with a negative value meaning all remaining source pages
|
||||
*
|
||||
* @return SQLITE_OK/SQLITE_DONE/SQLITE_BUSY/SQLITE_LOCKED
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
int executeStep(const int aNumPage = -1);
|
||||
|
||||
/// Return the number of source pages still to be backed up as of the most recent call to executeStep().
|
||||
int getRemainingPageCount() const;
|
||||
|
||||
/// Return the total number of pages in the source database as of the most recent call to executeStep().
|
||||
int getTotalPageCount() const;
|
||||
|
||||
private:
|
||||
// Deleter functor to use with smart pointers to close the SQLite database backup in an RAII fashion.
|
||||
struct Deleter
|
||||
{
|
||||
void operator()(sqlite3_backup* apBackup);
|
||||
};
|
||||
|
||||
std::unique_ptr<sqlite3_backup, Deleter> mpSQLiteBackup{}; ///< Pointer to SQLite Database Backup Handle
|
||||
};
|
||||
|
||||
} // namespace SQLite
|
263
third-party/SQLiteCpp/include/SQLiteCpp/Column.h
generated
vendored
263
third-party/SQLiteCpp/include/SQLiteCpp/Column.h
generated
vendored
@ -1,263 +0,0 @@
|
||||
/**
|
||||
* @file Column.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Encapsulation of a Column in a row of the result pointed by the prepared SQLite::Statement.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
// Forward declarations to avoid inclusion of <sqlite3.h> in a header
|
||||
struct sqlite3_stmt;
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
extern const int INTEGER; ///< SQLITE_INTEGER
|
||||
extern const int FLOAT; ///< SQLITE_FLOAT
|
||||
extern const int TEXT; ///< SQLITE_TEXT
|
||||
extern const int BLOB; ///< SQLITE_BLOB
|
||||
extern const int Null; ///< SQLITE_NULL
|
||||
|
||||
/**
|
||||
* @brief Encapsulation of a Column in a row of the result pointed by the prepared Statement.
|
||||
*
|
||||
* A Column is a particular field of SQLite data in the current row of result
|
||||
* of the Statement : it points to a single cell.
|
||||
*
|
||||
* Its value can be expressed as a text, and, when applicable, as a numeric
|
||||
* (integer or floating point) or a binary blob.
|
||||
*
|
||||
* Thread-safety: a Column object shall not be shared by multiple threads, because :
|
||||
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
|
||||
* provided that no single database connection is used simultaneously in two or more threads."
|
||||
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
|
||||
* because of the way it shares the underling SQLite precompiled statement
|
||||
* in a custom shared pointer (See the inner class "Statement::Ptr").
|
||||
*/
|
||||
class Column
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Encapsulation of a Column in a Row of the result.
|
||||
*
|
||||
* @param[in] aStmtPtr Shared pointer to the prepared SQLite Statement Object.
|
||||
* @param[in] aIndex Index of the column in the row of result, starting at 0
|
||||
*/
|
||||
explicit Column(const Statement::TStatementPtr& aStmtPtr, int aIndex);
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the named assigned to this result column (potentially aliased)
|
||||
*
|
||||
* @see getOriginName() to get original column name (not aliased)
|
||||
*/
|
||||
const char* getName() const noexcept;
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
/**
|
||||
* @brief Return a pointer to the table column name that is the origin of this result column
|
||||
*
|
||||
* Require definition of the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro :
|
||||
* - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance),
|
||||
* - and also when compiling this wrapper.
|
||||
*/
|
||||
const char* getOriginName() const noexcept;
|
||||
#endif
|
||||
|
||||
/// Return the integer value of the column.
|
||||
int32_t getInt() const noexcept;
|
||||
/// Return the 32bits unsigned integer value of the column (note that SQLite3 does not support unsigned 64bits).
|
||||
uint32_t getUInt() const noexcept;
|
||||
/// Return the 64bits integer value of the column (note that SQLite3 does not support unsigned 64bits).
|
||||
int64_t getInt64() const noexcept;
|
||||
/// Return the double (64bits float) value of the column
|
||||
double getDouble() const noexcept;
|
||||
/**
|
||||
* @brief Return a pointer to the text value (NULL terminated string) of the column.
|
||||
*
|
||||
* @warning The value pointed at is only valid while the statement is valid (ie. not finalized),
|
||||
* thus you must copy it before using it beyond its scope (to a std::string for instance).
|
||||
*/
|
||||
const char* getText(const char* apDefaultValue = "") const noexcept;
|
||||
/**
|
||||
* @brief Return a pointer to the binary blob value of the column.
|
||||
*
|
||||
* @warning The value pointed at is only valid while the statement is valid (ie. not finalized),
|
||||
* thus you must copy it before using it beyond its scope (to a std::string for instance).
|
||||
*/
|
||||
const void* getBlob() const noexcept;
|
||||
/**
|
||||
* @brief Return a std::string for a TEXT or BLOB column.
|
||||
*
|
||||
* Note this correctly handles strings that contain null bytes.
|
||||
*/
|
||||
std::string getString() const;
|
||||
|
||||
/**
|
||||
* @brief Return the type of the value of the column
|
||||
*
|
||||
* Return either SQLite::INTEGER, SQLite::FLOAT, SQLite::TEXT, SQLite::BLOB, or SQLite::Null.
|
||||
*
|
||||
* @warning After a type conversion (by a call to a getXxx on a Column of a Yyy type),
|
||||
* the value returned by sqlite3_column_type() is undefined.
|
||||
*/
|
||||
int getType() const noexcept;
|
||||
|
||||
/// Test if the column is an integer type value (meaningful only before any conversion)
|
||||
bool isInteger() const noexcept
|
||||
{
|
||||
return (SQLite::INTEGER == getType());
|
||||
}
|
||||
/// Test if the column is a floating point type value (meaningful only before any conversion)
|
||||
bool isFloat() const noexcept
|
||||
{
|
||||
return (SQLite::FLOAT == getType());
|
||||
}
|
||||
/// Test if the column is a text type value (meaningful only before any conversion)
|
||||
bool isText() const noexcept
|
||||
{
|
||||
return (SQLite::TEXT == getType());
|
||||
}
|
||||
/// Test if the column is a binary blob type value (meaningful only before any conversion)
|
||||
bool isBlob() const noexcept
|
||||
{
|
||||
return (SQLite::BLOB == getType());
|
||||
}
|
||||
/// Test if the column is NULL (meaningful only before any conversion)
|
||||
bool isNull() const noexcept
|
||||
{
|
||||
return (SQLite::Null == getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return the number of bytes used by the text (or blob) value of the column
|
||||
*
|
||||
* Return either :
|
||||
* - size in bytes (not in characters) of the string returned by getText() without the '\0' terminator
|
||||
* - size in bytes of the string representation of the numerical value (integer or double)
|
||||
* - size in bytes of the binary blob returned by getBlob()
|
||||
* - 0 for a NULL value
|
||||
*/
|
||||
int getBytes() const noexcept;
|
||||
|
||||
/// Alias returning the number of bytes used by the text (or blob) value of the column
|
||||
int size() const noexcept
|
||||
{
|
||||
return getBytes ();
|
||||
}
|
||||
|
||||
/// Inline cast operators to basic types
|
||||
operator char() const
|
||||
{
|
||||
return static_cast<char>(getInt());
|
||||
}
|
||||
operator int8_t() const
|
||||
{
|
||||
return static_cast<int8_t>(getInt());
|
||||
}
|
||||
operator uint8_t() const
|
||||
{
|
||||
return static_cast<uint8_t>(getInt());
|
||||
}
|
||||
operator int16_t() const
|
||||
{
|
||||
return static_cast<int16_t>(getInt());
|
||||
}
|
||||
operator uint16_t() const
|
||||
{
|
||||
return static_cast<uint16_t>(getInt());
|
||||
}
|
||||
operator int32_t() const
|
||||
{
|
||||
return getInt();
|
||||
}
|
||||
operator uint32_t() const
|
||||
{
|
||||
return getUInt();
|
||||
}
|
||||
operator int64_t() const
|
||||
{
|
||||
return getInt64();
|
||||
}
|
||||
operator double() const
|
||||
{
|
||||
return getDouble();
|
||||
}
|
||||
/**
|
||||
* @brief Inline cast operator to char*
|
||||
*
|
||||
* @see getText
|
||||
*/
|
||||
operator const char*() const
|
||||
{
|
||||
return getText();
|
||||
}
|
||||
/**
|
||||
* @brief Inline cast operator to void*
|
||||
*
|
||||
* @see getBlob
|
||||
*/
|
||||
operator const void*() const
|
||||
{
|
||||
return getBlob();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Inline cast operator to std::string
|
||||
*
|
||||
* Handles BLOB or TEXT, which may contain null bytes within
|
||||
*
|
||||
* @see getString
|
||||
*/
|
||||
operator std::string() const
|
||||
{
|
||||
return getString();
|
||||
}
|
||||
|
||||
private:
|
||||
Statement::TStatementPtr mStmtPtr; ///< Shared Pointer to the prepared SQLite Statement Object
|
||||
int mIndex; ///< Index of the column in the row of result, starting at 0
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Standard std::ostream text inserter
|
||||
*
|
||||
* Insert the text value of the Column object, using getText(), into the provided stream.
|
||||
*
|
||||
* @param[in] aStream Stream to use
|
||||
* @param[in] aColumn Column object to insert into the provided stream
|
||||
*
|
||||
* @return Reference to the stream used
|
||||
*/
|
||||
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn);
|
||||
|
||||
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900) // c++14: Visual Studio 2015
|
||||
|
||||
// Create an instance of T from the first N columns, see declaration in Statement.h for full details
|
||||
template<typename T, int N>
|
||||
T Statement::getColumns()
|
||||
{
|
||||
checkRow();
|
||||
checkIndex(N - 1);
|
||||
return getColumns<T>(std::make_integer_sequence<int, N>{});
|
||||
}
|
||||
|
||||
// Helper function called by getColums<typename T, int N>
|
||||
template<typename T, const int... Is>
|
||||
T Statement::getColumns(const std::integer_sequence<int, Is...>)
|
||||
{
|
||||
return T{Column(mpPreparedStatement, Is)...};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace SQLite
|
608
third-party/SQLiteCpp/include/SQLiteCpp/Database.h
generated
vendored
608
third-party/SQLiteCpp/include/SQLiteCpp/Database.h
generated
vendored
@ -1,608 +0,0 @@
|
||||
/**
|
||||
* @file Database.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Management of a SQLite Database Connection.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SQLiteCpp/Column.h>
|
||||
|
||||
// c++17: MinGW GCC version > 8
|
||||
// c++17: Visual Studio 2017 version 15.7
|
||||
// c++17: macOS unless targetting compatibility with macOS < 10.15
|
||||
#ifndef SQLITECPP_HAVE_STD_EXPERIMENTAL_FILESYSTEM
|
||||
#if __cplusplus >= 201703L
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#if __GNUC__ > 8 // MinGW requires GCC version > 8 for std::filesystem
|
||||
#define SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
#endif
|
||||
#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500
|
||||
// macOS clang won't let us touch std::filesystem if we're targetting earlier than 10.15
|
||||
#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && defined(__IPHONE_13_0) && \
|
||||
__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_13_0
|
||||
// build for iOS clang won't let us touch std::filesystem if we're targetting earlier than iOS 13
|
||||
#else
|
||||
#define SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
#endif
|
||||
#elif defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
|
||||
#define SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
#endif
|
||||
|
||||
#ifdef SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
#include <filesystem>
|
||||
#endif // c++17 and a suitable compiler
|
||||
|
||||
#else // SQLITECPP_HAVE_STD_EXPERIMENTAL_FILESYSTEM
|
||||
|
||||
#define SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
#include <experimental/filesystem>
|
||||
namespace std {
|
||||
namespace filesystem = experimental::filesystem;
|
||||
}
|
||||
|
||||
#endif // SQLITECPP_HAVE_STD_EXPERIMENTAL_FILESYSTEM
|
||||
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
|
||||
// Forward declarations to avoid inclusion of <sqlite3.h> in a header
|
||||
struct sqlite3;
|
||||
struct sqlite3_context;
|
||||
|
||||
#ifndef SQLITE_USE_LEGACY_STRUCT // Since SQLITE 3.19 (used by default since SQLiteCpp 2.1.0)
|
||||
typedef struct sqlite3_value sqlite3_value;
|
||||
#else // Before SQLite 3.19 (legacy struct forward declaration can be activated with CMake SQLITECPP_LEGACY_STRUCT var)
|
||||
struct Mem;
|
||||
typedef struct Mem sqlite3_value;
|
||||
#endif
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
// Those public constants enable most usages of SQLiteCpp without including <sqlite3.h> in the client application.
|
||||
|
||||
/// The database is opened in read-only mode. If the database does not already exist, an error is returned.
|
||||
extern const int OPEN_READONLY; // SQLITE_OPEN_READONLY
|
||||
/// The database is opened for reading and writing if possible, or reading only if the file is write protected
|
||||
/// by the operating system. In either case the database must already exist, otherwise an error is returned.
|
||||
extern const int OPEN_READWRITE; // SQLITE_OPEN_READWRITE
|
||||
/// With OPEN_READWRITE: The database is opened for reading and writing, and is created if it does not already exist.
|
||||
extern const int OPEN_CREATE; // SQLITE_OPEN_CREATE
|
||||
/// Enable URI filename interpretation, parsed according to RFC 3986 (ex. "file:data.db?mode=ro&cache=private")
|
||||
extern const int OPEN_URI; // SQLITE_OPEN_URI
|
||||
/// Open in memory database
|
||||
extern const int OPEN_MEMORY; // SQLITE_OPEN_MEMORY
|
||||
/// Open database in multi-thread threading mode
|
||||
extern const int OPEN_NOMUTEX; // SQLITE_OPEN_NOMUTEX
|
||||
/// Open database with thread-safety in serialized threading mode
|
||||
extern const int OPEN_FULLMUTEX; // SQLITE_OPEN_FULLMUTEX
|
||||
/// Open database with shared cache enabled
|
||||
extern const int OPEN_SHAREDCACHE; // SQLITE_OPEN_SHAREDCACHE
|
||||
/// Open database with shared cache disabled
|
||||
extern const int OPEN_PRIVATECACHE; // SQLITE_OPEN_PRIVATECACHE
|
||||
/// Database filename is not allowed to be a symbolic link (Note: only since SQlite 3.31.0 from 2020-01-22)
|
||||
extern const int OPEN_NOFOLLOW; // SQLITE_OPEN_NOFOLLOW
|
||||
|
||||
|
||||
extern const int OK; ///< SQLITE_OK (used by check() bellow)
|
||||
|
||||
extern const char* const VERSION; ///< SQLITE_VERSION string from the sqlite3.h used at compile time
|
||||
extern const int VERSION_NUMBER; ///< SQLITE_VERSION_NUMBER from the sqlite3.h used at compile time
|
||||
|
||||
/// Return SQLite version string using runtime call to the compiled library
|
||||
const char* getLibVersion() noexcept;
|
||||
/// Return SQLite version number using runtime call to the compiled library
|
||||
int getLibVersionNumber() noexcept;
|
||||
|
||||
// Public structure for representing all fields contained within the SQLite header.
|
||||
// Official documentation for fields: https://www.sqlite.org/fileformat.html#the_database_header
|
||||
struct Header {
|
||||
unsigned char headerStr[16];
|
||||
unsigned int pageSizeBytes;
|
||||
unsigned char fileFormatWriteVersion;
|
||||
unsigned char fileFormatReadVersion;
|
||||
unsigned char reservedSpaceBytes;
|
||||
unsigned char maxEmbeddedPayloadFrac;
|
||||
unsigned char minEmbeddedPayloadFrac;
|
||||
unsigned char leafPayloadFrac;
|
||||
unsigned long fileChangeCounter;
|
||||
unsigned long databaseSizePages;
|
||||
unsigned long firstFreelistTrunkPage;
|
||||
unsigned long totalFreelistPages;
|
||||
unsigned long schemaCookie;
|
||||
unsigned long schemaFormatNumber;
|
||||
unsigned long defaultPageCacheSizeBytes;
|
||||
unsigned long largestBTreePageNumber;
|
||||
unsigned long databaseTextEncoding;
|
||||
unsigned long userVersion;
|
||||
unsigned long incrementalVaccumMode;
|
||||
unsigned long applicationId;
|
||||
unsigned long versionValidFor;
|
||||
unsigned long sqliteVersion;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief RAII management of a SQLite Database Connection.
|
||||
*
|
||||
* A Database object manage a list of all SQLite Statements associated with the
|
||||
* underlying SQLite 3 database connection.
|
||||
*
|
||||
* Resource Acquisition Is Initialization (RAII) means that the Database Connection
|
||||
* is opened in the constructor and closed in the destructor, so that there is
|
||||
* no need to worry about memory management or the validity of the underlying SQLite Connection.
|
||||
*
|
||||
* Thread-safety: a Database object shall not be shared by multiple threads, because :
|
||||
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
|
||||
* provided that no single database connection is used simultaneously in two or more threads."
|
||||
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
|
||||
* because of the way it shares the underling SQLite precompiled statement
|
||||
* in a custom shared pointer (See the inner class "Statement::Ptr").
|
||||
*/
|
||||
class Database
|
||||
{
|
||||
friend class Statement; // Give Statement constructor access to the mSQLitePtr Connection Handle
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Open the provided database UTF-8 filename.
|
||||
*
|
||||
* Uses sqlite3_open_v2() with readonly default flag, which is the opposite behavior
|
||||
* of the old sqlite3_open() function (READWRITE+CREATE).
|
||||
* This makes sense if you want to use it on a readonly filesystem
|
||||
* or to prevent creation of a void file when a required file is missing.
|
||||
*
|
||||
* Exception is thrown in case of error, then the Database object is NOT constructed.
|
||||
*
|
||||
* @param[in] apFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
|
||||
* @param[in] aFlags SQLite::OPEN_READONLY/SQLite::OPEN_READWRITE/SQLite::OPEN_CREATE...
|
||||
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
|
||||
* @param[in] apVfs UTF-8 name of custom VFS to use, or nullptr for sqlite3 default
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Database(const char* apFilename,
|
||||
const int aFlags = SQLite::OPEN_READONLY,
|
||||
const int aBusyTimeoutMs = 0,
|
||||
const char* apVfs = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Open the provided database UTF-8 filename.
|
||||
*
|
||||
* Uses sqlite3_open_v2() with readonly default flag, which is the opposite behavior
|
||||
* of the old sqlite3_open() function (READWRITE+CREATE).
|
||||
* This makes sense if you want to use it on a readonly filesystem
|
||||
* or to prevent creation of a void file when a required file is missing.
|
||||
*
|
||||
* Exception is thrown in case of error, then the Database object is NOT constructed.
|
||||
*
|
||||
* @param[in] aFilename UTF-8 path/uri to the database file ("filename" sqlite3 parameter)
|
||||
* @param[in] aFlags SQLite::OPEN_READONLY/SQLite::OPEN_READWRITE/SQLite::OPEN_CREATE...
|
||||
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
|
||||
* @param[in] aVfs UTF-8 name of custom VFS to use, or empty string for sqlite3 default
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Database(const std::string& aFilename,
|
||||
const int aFlags = SQLite::OPEN_READONLY,
|
||||
const int aBusyTimeoutMs = 0,
|
||||
const std::string& aVfs = "") :
|
||||
Database(aFilename.c_str(), aFlags, aBusyTimeoutMs, aVfs.empty() ? nullptr : aVfs.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
#ifdef SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
|
||||
/**
|
||||
* @brief Open the provided database std::filesystem::path.
|
||||
*
|
||||
* @note This feature requires std=C++17
|
||||
*
|
||||
* Uses sqlite3_open_v2() with readonly default flag, which is the opposite behavior
|
||||
* of the old sqlite3_open() function (READWRITE+CREATE).
|
||||
* This makes sense if you want to use it on a readonly filesystem
|
||||
* or to prevent creation of a void file when a required file is missing.
|
||||
*
|
||||
* Exception is thrown in case of error, then the Database object is NOT constructed.
|
||||
*
|
||||
* @param[in] apFilename Path/uri to the database file ("filename" sqlite3 parameter)
|
||||
* @param[in] aFlags SQLite::OPEN_READONLY/SQLite::OPEN_READWRITE/SQLite::OPEN_CREATE...
|
||||
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY (see setBusyTimeout())
|
||||
* @param[in] apVfs UTF-8 name of custom VFS to use, or nullptr for sqlite3 default
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Database(const std::filesystem::path& apFilename,
|
||||
const int aFlags = SQLite::OPEN_READONLY,
|
||||
const int aBusyTimeoutMs = 0,
|
||||
const std::string& aVfs = "") :
|
||||
Database(reinterpret_cast<const char*>(apFilename.u8string().c_str()),
|
||||
aFlags, aBusyTimeoutMs, aVfs.empty() ? nullptr : aVfs.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
#endif // have std::filesystem
|
||||
|
||||
// Database is non-copyable
|
||||
Database(const Database&) = delete;
|
||||
Database& operator=(const Database&) = delete;
|
||||
|
||||
// Database is movable
|
||||
Database(Database&& aDatabase) = default;
|
||||
Database& operator=(Database&& aDatabase) = default;
|
||||
|
||||
/**
|
||||
* @brief Close the SQLite database connection.
|
||||
*
|
||||
* All SQLite statements must have been finalized before,
|
||||
* so all Statement objects must have been unregistered.
|
||||
*
|
||||
* @warning assert in case of error
|
||||
*/
|
||||
~Database() = default;
|
||||
|
||||
// Deleter functor to use with smart pointers to close the SQLite database connection in an RAII fashion.
|
||||
struct Deleter
|
||||
{
|
||||
void operator()(sqlite3* apSQLite);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
|
||||
*
|
||||
* This is useful in multithreaded program to handle case where a table is locked for writing by a thread.
|
||||
* Any other thread cannot access the table and will receive a SQLITE_BUSY error:
|
||||
* setting a timeout will wait and retry up to the time specified before returning this SQLITE_BUSY error.
|
||||
* Reading the value of timeout for current connection can be done with SQL query "PRAGMA busy_timeout;".
|
||||
* Default busy timeout is 0ms.
|
||||
*
|
||||
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
void setBusyTimeout(const int aBusyTimeoutMs);
|
||||
|
||||
/**
|
||||
* @brief Shortcut to execute one or multiple statements without results. Return the number of changes.
|
||||
*
|
||||
* This is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
|
||||
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
|
||||
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
|
||||
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
|
||||
*
|
||||
* @see Database::tryExec() to execute, returning the sqlite result code
|
||||
* @see Statement::exec() to handle precompiled statements (for better performances) without results
|
||||
* @see Statement::executeStep() to handle "SELECT" queries with results
|
||||
*
|
||||
* @param[in] apQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
|
||||
*
|
||||
* @return number of rows modified by the *last* INSERT, UPDATE or DELETE statement (beware of multiple statements)
|
||||
* @warning undefined for CREATE or DROP table: returns the value of a previous INSERT, UPDATE or DELETE statement.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
int exec(const char* apQueries);
|
||||
|
||||
/**
|
||||
* @brief Shortcut to execute one or multiple statements without results.
|
||||
*
|
||||
* This is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
|
||||
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
|
||||
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
|
||||
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
|
||||
*
|
||||
* @see Database::tryExec() to execute, returning the sqlite result code
|
||||
* @see Statement::exec() to handle precompiled statements (for better performances) without results
|
||||
* @see Statement::executeStep() to handle "SELECT" queries with results
|
||||
*
|
||||
* @param[in] aQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
|
||||
*
|
||||
* @return number of rows modified by the *last* INSERT, UPDATE or DELETE statement (beware of multiple statements)
|
||||
* @warning undefined for CREATE or DROP table: returns the value of a previous INSERT, UPDATE or DELETE statement.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
int exec(const std::string& aQueries)
|
||||
{
|
||||
return exec(aQueries.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Try to execute one or multiple statements, returning the sqlite result code.
|
||||
*
|
||||
* This is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
|
||||
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
|
||||
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
|
||||
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
|
||||
*
|
||||
* @see exec() to execute, returning number of rows modified
|
||||
*
|
||||
* @param[in] aQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
|
||||
*
|
||||
* @return the sqlite result code.
|
||||
*/
|
||||
int tryExec(const char* apQueries) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Try to execute one or multiple statements, returning the sqlite result code.
|
||||
*
|
||||
* This is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
|
||||
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
|
||||
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
|
||||
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
|
||||
*
|
||||
* @see exec() to execute, returning number of rows modified
|
||||
*
|
||||
* @param[in] aQueries one or multiple UTF-8 encoded, semicolon-separate SQL statements
|
||||
*
|
||||
* @return the sqlite result code.
|
||||
*/
|
||||
int tryExec(const std::string& aQueries) noexcept
|
||||
{
|
||||
return tryExec(aQueries.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shortcut to execute a one step query and fetch the first column of the result.
|
||||
*
|
||||
* This is a shortcut to execute a simple statement with a single result.
|
||||
* This should be used only for non reusable queries (else you should use a Statement with bind()).
|
||||
* This should be used only for queries with expected results (else an exception is fired).
|
||||
*
|
||||
* @warning WARNING: Be very careful with this dangerous method: you have to
|
||||
* make a COPY OF THE result, else it will be destroy before the next line
|
||||
* (when the underlying temporary Statement and Column objects are destroyed)
|
||||
*
|
||||
* @see also Statement class for handling queries with multiple results
|
||||
*
|
||||
* @param[in] apQuery an UTF-8 encoded SQL query
|
||||
*
|
||||
* @return a temporary Column object with the first column of result.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Column execAndGet(const char* apQuery);
|
||||
|
||||
/**
|
||||
* @brief Shortcut to execute a one step query and fetch the first column of the result.
|
||||
*
|
||||
* This is a shortcut to execute a simple statement with a single result.
|
||||
* This should be used only for non reusable queries (else you should use a Statement with bind()).
|
||||
* This should be used only for queries with expected results (else an exception is fired).
|
||||
*
|
||||
* @warning WARNING: Be very careful with this dangerous method: you have to
|
||||
* make a COPY OF THE result, else it will be destroy before the next line
|
||||
* (when the underlying temporary Statement and Column objects are destroyed)
|
||||
*
|
||||
* @see also Statement class for handling queries with multiple results
|
||||
*
|
||||
* @param[in] aQuery an UTF-8 encoded SQL query
|
||||
*
|
||||
* @return a temporary Column object with the first column of result.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
Column execAndGet(const std::string& aQuery)
|
||||
{
|
||||
return execAndGet(aQuery.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Shortcut to test if a table exists.
|
||||
*
|
||||
* Table names are case sensitive.
|
||||
*
|
||||
* @param[in] apTableName an UTF-8 encoded case sensitive Table name
|
||||
*
|
||||
* @return true if the table exists.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
bool tableExists(const char* apTableName) const;
|
||||
|
||||
/**
|
||||
* @brief Shortcut to test if a table exists.
|
||||
*
|
||||
* Table names are case sensitive.
|
||||
*
|
||||
* @param[in] aTableName an UTF-8 encoded case sensitive Table name
|
||||
*
|
||||
* @return true if the table exists.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
bool tableExists(const std::string& aTableName) const
|
||||
{
|
||||
return tableExists(aTableName.c_str());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the rowid of the most recent successful INSERT into the database from the current connection.
|
||||
*
|
||||
* Each entry in an SQLite table always has a unique 64-bit signed integer key called the rowid.
|
||||
* If the table has a column of type INTEGER PRIMARY KEY, then it is an alias for the rowid.
|
||||
*
|
||||
* @return Rowid of the most recent successful INSERT into the database, or 0 if there was none.
|
||||
*/
|
||||
int64_t getLastInsertRowid() const noexcept;
|
||||
|
||||
/// Get number of rows modified by last INSERT, UPDATE or DELETE statement (not DROP table).
|
||||
int getChanges() const noexcept;
|
||||
|
||||
/// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection (not DROP table).
|
||||
int getTotalChanges() const noexcept;
|
||||
|
||||
/// Return the numeric result code for the most recent failed API call (if any).
|
||||
int getErrorCode() const noexcept;
|
||||
/// Return the extended numeric result code for the most recent failed API call (if any).
|
||||
int getExtendedErrorCode() const noexcept;
|
||||
/// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
|
||||
const char* getErrorMsg() const noexcept;
|
||||
|
||||
/// Return the filename used to open the database.
|
||||
const std::string& getFilename() const noexcept
|
||||
{
|
||||
return mFilename;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return raw pointer to SQLite Database Connection Handle.
|
||||
*
|
||||
* This is often needed to mix this wrapper with other libraries or for advance usage not supported by SQLiteCpp.
|
||||
*/
|
||||
sqlite3* getHandle() const noexcept
|
||||
{
|
||||
return mSQLitePtr.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create or redefine a SQL function or aggregate in the sqlite database.
|
||||
*
|
||||
* This is the equivalent of the sqlite3_create_function_v2 command.
|
||||
* @see http://www.sqlite.org/c3ref/create_function.html
|
||||
*
|
||||
* @note UTF-8 text encoding assumed.
|
||||
*
|
||||
* @param[in] apFuncName Name of the SQL function to be created or redefined
|
||||
* @param[in] aNbArg Number of arguments in the function
|
||||
* @param[in] abDeterministic Optimize for deterministic functions (most are). A random number generator is not.
|
||||
* @param[in] apApp Arbitrary pointer of user data, accessible with sqlite3_user_data().
|
||||
* @param[in] apFunc Pointer to a C-function to implement a scalar SQL function (apStep & apFinal nullptr)
|
||||
* @param[in] apStep Pointer to a C-function to implement an aggregate SQL function (apFunc nullptr)
|
||||
* @param[in] apFinal Pointer to a C-function to implement an aggregate SQL function (apFunc nullptr)
|
||||
* @param[in] apDestroy If not nullptr, then it is the destructor for the application data pointer.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
void createFunction(const char* apFuncName,
|
||||
int aNbArg,
|
||||
bool abDeterministic,
|
||||
void* apApp,
|
||||
void (*apFunc)(sqlite3_context *, int, sqlite3_value **),
|
||||
void (*apStep)(sqlite3_context *, int, sqlite3_value **) = nullptr,
|
||||
void (*apFinal)(sqlite3_context *) = nullptr, // NOLINT(readability/casting)
|
||||
void (*apDestroy)(void *) = nullptr);
|
||||
|
||||
/**
|
||||
* @brief Load a module into the current sqlite database instance.
|
||||
*
|
||||
* This is the equivalent of the sqlite3_load_extension call, but additionally enables
|
||||
* module loading support prior to loading the requested module.
|
||||
*
|
||||
* @see http://www.sqlite.org/c3ref/load_extension.html
|
||||
*
|
||||
* @note UTF-8 text encoding assumed.
|
||||
*
|
||||
* @param[in] apExtensionName Name of the shared library containing extension
|
||||
* @param[in] apEntryPointName Name of the entry point (nullptr to let sqlite work it out)
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
void loadExtension(const char* apExtensionName, const char* apEntryPointName);
|
||||
|
||||
/**
|
||||
* @brief Set the key for the current sqlite database instance.
|
||||
*
|
||||
* This is the equivalent of the sqlite3_key call and should thus be called
|
||||
* directly after opening the database.
|
||||
* Open encrypted database -> call db.key("secret") -> database ready
|
||||
*
|
||||
* @param[in] aKey Key to decode/encode the database
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
void key(const std::string& aKey) const;
|
||||
|
||||
/**
|
||||
* @brief Reset the key for the current sqlite database instance.
|
||||
*
|
||||
* This is the equivalent of the sqlite3_rekey call and should thus be called
|
||||
* after the database has been opened with a valid key. To decrypt a
|
||||
* database, call this method with an empty string.
|
||||
* Open normal database -> call db.rekey("secret") -> encrypted database, database ready
|
||||
* Open encrypted database -> call db.key("secret") -> call db.rekey("newsecret") -> change key, database ready
|
||||
* Open encrypted database -> call db.key("secret") -> call db.rekey("") -> decrypted database, database ready
|
||||
*
|
||||
* @param[in] aNewKey New key to encode the database
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
void rekey(const std::string& aNewKey) const;
|
||||
|
||||
/**
|
||||
* @brief Test if a file contains an unencrypted database.
|
||||
*
|
||||
* This is a simple test that reads the first bytes of a database file and
|
||||
* compares them to the standard header for unencrypted databases. If the
|
||||
* header does not match the standard string, we assume that we have an
|
||||
* encrypted file.
|
||||
*
|
||||
* @param[in] aFilename path/uri to a file
|
||||
*
|
||||
* @return true if the database has the standard header.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
static bool isUnencrypted(const std::string& aFilename);
|
||||
|
||||
/**
|
||||
* @brief Parse SQLite header data from a database file.
|
||||
*
|
||||
* This function reads the first 100 bytes of a SQLite database file
|
||||
* and reconstructs groups of individual bytes into the associated fields
|
||||
* in a Header object.
|
||||
*
|
||||
* @param[in] aFilename path/uri to a file
|
||||
*
|
||||
* @return Header object containing file data
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
static Header getHeaderInfo(const std::string& aFilename);
|
||||
|
||||
// Parse SQLite header data from a database file.
|
||||
Header getHeaderInfo() const
|
||||
{
|
||||
return getHeaderInfo(mFilename);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BackupType for the backup() method
|
||||
*/
|
||||
enum BackupType { Save, Load };
|
||||
|
||||
/**
|
||||
* @brief Load or save the database content.
|
||||
*
|
||||
* This function is used to load the contents of a database file on disk
|
||||
* into the "main" database of open database connection, or to save the current
|
||||
* contents of the database into a database file on disk.
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
void backup(const char* apFilename, BackupType aType);
|
||||
|
||||
/**
|
||||
* @brief Check if aRet equal SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
|
||||
*/
|
||||
void check(const int aRet) const
|
||||
{
|
||||
if (SQLite::OK != aRet)
|
||||
{
|
||||
throw SQLite::Exception(getHandle(), aRet);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// TODO: perhaps switch to having Statement sharing a pointer to the Connexion
|
||||
std::unique_ptr<sqlite3, Deleter> mSQLitePtr; ///< Pointer to SQLite Database Connection Handle
|
||||
std::string mFilename; ///< UTF-8 filename used to open the database
|
||||
};
|
||||
|
||||
|
||||
} // namespace SQLite
|
92
third-party/SQLiteCpp/include/SQLiteCpp/Exception.h
generated
vendored
92
third-party/SQLiteCpp/include/SQLiteCpp/Exception.h
generated
vendored
@ -1,92 +0,0 @@
|
||||
/**
|
||||
* @file Exception.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Encapsulation of the error message from SQLite3 on a std::runtime_error.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// Forward declaration to avoid inclusion of <sqlite3.h> in a header
|
||||
struct sqlite3;
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
|
||||
*/
|
||||
class Exception : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
|
||||
*
|
||||
* @param[in] aErrorMessage The string message describing the SQLite error
|
||||
* @param[in] ret Return value from function call that failed.
|
||||
*/
|
||||
Exception(const char* aErrorMessage, int ret);
|
||||
|
||||
Exception(const std::string& aErrorMessage, int ret) :
|
||||
Exception(aErrorMessage.c_str(), ret)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
|
||||
*
|
||||
* @param[in] aErrorMessage The string message describing the SQLite error
|
||||
*/
|
||||
explicit Exception(const char* aErrorMessage) :
|
||||
Exception(aErrorMessage, -1) // 0 would be SQLITE_OK, which doesn't make sense
|
||||
{
|
||||
}
|
||||
explicit Exception(const std::string& aErrorMessage) :
|
||||
Exception(aErrorMessage.c_str(), -1) // 0 would be SQLITE_OK, which doesn't make sense
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
|
||||
*
|
||||
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
|
||||
*/
|
||||
explicit Exception(sqlite3* apSQLite);
|
||||
|
||||
/**
|
||||
* @brief Encapsulation of the error message from SQLite3, based on std::runtime_error.
|
||||
*
|
||||
* @param[in] apSQLite The SQLite object, to obtain detailed error messages from.
|
||||
* @param[in] ret Return value from function call that failed.
|
||||
*/
|
||||
Exception(sqlite3* apSQLite, int ret);
|
||||
|
||||
/// Return the result code (if any, otherwise -1).
|
||||
int getErrorCode() const noexcept
|
||||
{
|
||||
return mErrcode;
|
||||
}
|
||||
|
||||
/// Return the extended numeric result code (if any, otherwise -1).
|
||||
int getExtendedErrorCode() const noexcept
|
||||
{
|
||||
return mExtendedErrcode;
|
||||
}
|
||||
|
||||
/// Return a string, solely based on the error code
|
||||
const char* getErrorStr() const noexcept;
|
||||
|
||||
private:
|
||||
int mErrcode; ///< Error code value
|
||||
int mExtendedErrcode; ///< Detailed error code if any
|
||||
};
|
||||
|
||||
|
||||
} // namespace SQLite
|
90
third-party/SQLiteCpp/include/SQLiteCpp/ExecuteMany.h
generated
vendored
90
third-party/SQLiteCpp/include/SQLiteCpp/ExecuteMany.h
generated
vendored
@ -1,90 +0,0 @@
|
||||
/**
|
||||
* @file ExecuteMany.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Convenience function to execute a Statement with multiple Parameter sets
|
||||
*
|
||||
* Copyright (c) 2019 Maximilian Bachmann (contact@maxbachmann.de)
|
||||
* Copyright (c) 2019-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/VariadicBind.h>
|
||||
|
||||
/// @cond
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* \brief Convenience function to execute a Statement with multiple Parameter sets once for each parameter set given.
|
||||
*
|
||||
*
|
||||
* This feature requires a c++14 capable compiler.
|
||||
*
|
||||
* \code{.cpp}
|
||||
* execute_many(db, "INSERT INTO test VALUES (?, ?)",
|
||||
* 1,
|
||||
* std::make_tuple(2),
|
||||
* std::make_tuple(3, "three")
|
||||
* );
|
||||
* \endcode
|
||||
* @param aDatabase Database to use
|
||||
* @param apQuery Query to use with all parameter sets
|
||||
* @param aArg first tuple with parameters
|
||||
* @param aParams the following tuples with parameters
|
||||
*/
|
||||
template <typename Arg, typename... Types>
|
||||
void execute_many(Database& aDatabase, const char* apQuery, Arg&& aArg, Types&&... aParams)
|
||||
{
|
||||
SQLite::Statement query(aDatabase, apQuery);
|
||||
bind_exec(query, std::forward<Arg>(aArg));
|
||||
(void)std::initializer_list<int>
|
||||
{
|
||||
((void)reset_bind_exec(query, std::forward<Types>(aParams)), 0)...
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convenience function to reset a statement and call bind_exec to
|
||||
* bind new values to the statement and execute it
|
||||
*
|
||||
* This feature requires a c++14 capable compiler.
|
||||
*
|
||||
* @param apQuery Query to use
|
||||
* @param aTuple Tuple to bind
|
||||
*/
|
||||
template <typename TupleT>
|
||||
void reset_bind_exec(Statement& apQuery, TupleT&& aTuple)
|
||||
{
|
||||
apQuery.reset();
|
||||
bind_exec(apQuery, std::forward<TupleT>(aTuple));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convenience function to bind values a the statement and execute it
|
||||
*
|
||||
* This feature requires a c++14 capable compiler.
|
||||
*
|
||||
* @param apQuery Query to use
|
||||
* @param aTuple Tuple to bind
|
||||
*/
|
||||
template <typename TupleT>
|
||||
void bind_exec(Statement& apQuery, TupleT&& aTuple)
|
||||
{
|
||||
SQLite::bind(apQuery, std::forward<TupleT>(aTuple));
|
||||
while (apQuery.executeStep()) {}
|
||||
}
|
||||
|
||||
} // namespace SQLite
|
||||
|
||||
#endif // c++14
|
44
third-party/SQLiteCpp/include/SQLiteCpp/SQLiteCpp.h
generated
vendored
44
third-party/SQLiteCpp/include/SQLiteCpp/SQLiteCpp.h
generated
vendored
@ -1,44 +0,0 @@
|
||||
/**
|
||||
* @file SQLiteCpp.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. This file is only "easy include" for other files.
|
||||
*
|
||||
* Include this main header file in your project to gain access to all functionality provided by the wrapper.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
/**
|
||||
* @defgroup SQLiteCpp SQLiteC++
|
||||
* @brief SQLiteC++ is a smart and simple C++ SQLite3 wrapper. This file is only "easy include" for other files.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
|
||||
// Include useful headers of SQLiteC++
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Column.h>
|
||||
#include <SQLiteCpp/Transaction.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Version numbers for SQLiteC++ are provided in the same way as sqlite3.h
|
||||
*
|
||||
* The [SQLITECPP_VERSION] C preprocessor macro in the SQLiteC++.h header
|
||||
* evaluates to a string literal that is the SQLite version in the
|
||||
* format "X.Y.Z" where X is the major version number
|
||||
* and Y is the minor version number and Z is the release number.
|
||||
*
|
||||
* The [SQLITECPP_VERSION_NUMBER] C preprocessor macro resolves to an integer
|
||||
* with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same
|
||||
* numbers used in [SQLITECPP_VERSION].
|
||||
*
|
||||
* WARNING: shall always be updated in sync with PROJECT_VERSION in CMakeLists.txt
|
||||
*/
|
||||
#define SQLITECPP_VERSION "3.02.00" // 3.2.0
|
||||
#define SQLITECPP_VERSION_NUMBER 3002000 // 3.2.0
|
95
third-party/SQLiteCpp/include/SQLiteCpp/Savepoint.h
generated
vendored
95
third-party/SQLiteCpp/include/SQLiteCpp/Savepoint.h
generated
vendored
@ -1,95 +0,0 @@
|
||||
/**
|
||||
* @file Savepoint.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief A Savepoint is a way to group multiple SQL statements into an atomic
|
||||
* secured operation. Similar to a transaction while allowing child savepoints.
|
||||
*
|
||||
* Copyright (c) 2020 Kelvin Hammond (hammond.kelvin@gmail.com)
|
||||
* Copyright (c) 2020-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt or
|
||||
* copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
namespace SQLite {
|
||||
|
||||
// Foward declaration
|
||||
class Database;
|
||||
|
||||
/**
|
||||
* @brief RAII encapsulation of a SQLite Savepoint.
|
||||
*
|
||||
* A Savepoint is a way to group multiple SQL statements into an atomic
|
||||
* secureced operation; either it succeeds, with all the changes commited to the
|
||||
* database file, or if it fails, all the changes are rolled back to the initial
|
||||
* state at the start of the savepoint.
|
||||
*
|
||||
* This method also offers big performances improvements compared to
|
||||
* individually executed statements.
|
||||
*
|
||||
* Caveats:
|
||||
*
|
||||
* 1) Calling COMMIT or commiting a parent transaction or RELEASE on a parent
|
||||
* savepoint will cause this savepoint to be released.
|
||||
*
|
||||
* 2) Calling ROLLBACK or rolling back a parent savepoint will cause this
|
||||
* savepoint to be rolled back.
|
||||
*
|
||||
* 3) This savepoint is not saved to the database until this and all savepoints
|
||||
* or transaction in the savepoint stack have been released or commited.
|
||||
*
|
||||
* See also: https://sqlite.org/lang_savepoint.html
|
||||
*
|
||||
* Thread-safety: a Transaction object shall not be shared by multiple threads,
|
||||
* because:
|
||||
*
|
||||
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple
|
||||
* threads provided that no single database connection is used simultaneously in
|
||||
* two or more threads."
|
||||
*
|
||||
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++, because of the
|
||||
* way it shares the underling SQLite precompiled statement in a custom shared
|
||||
* pointer (See the inner class "Statement::Ptr").
|
||||
*/
|
||||
|
||||
class Savepoint {
|
||||
public:
|
||||
/**
|
||||
* @brief Begins the SQLite savepoint
|
||||
*
|
||||
* @param[in] aDatabase the SQLite Database Connection
|
||||
* @param[in] aName the name of the Savepoint
|
||||
*
|
||||
* Exception is thrown in case of error, then the Savepoint is NOT
|
||||
* initiated.
|
||||
*/
|
||||
Savepoint(Database& aDatabase, const std::string& name);
|
||||
|
||||
// Savepoint is non-copyable
|
||||
Savepoint(const Savepoint&) = delete;
|
||||
Savepoint& operator=(const Savepoint&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Safely rollback the savepoint if it has not been commited.
|
||||
*/
|
||||
~Savepoint();
|
||||
|
||||
/**
|
||||
* @brief Commit and release the savepoint.
|
||||
*/
|
||||
void release();
|
||||
|
||||
/**
|
||||
* @brief Rollback the savepoint
|
||||
*/
|
||||
void rollback();
|
||||
|
||||
private:
|
||||
Database& mDatabase; ///< Reference to the SQLite Database Connection
|
||||
std::string msName; ///< Name of the Savepoint
|
||||
bool mbReleased = false; ///< True when release has been called
|
||||
};
|
||||
} // namespace SQLite
|
710
third-party/SQLiteCpp/include/SQLiteCpp/Statement.h
generated
vendored
710
third-party/SQLiteCpp/include/SQLiteCpp/Statement.h
generated
vendored
@ -1,710 +0,0 @@
|
||||
/**
|
||||
* @file Statement.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief A prepared SQLite Statement is a compiled SQL query ready to be executed, pointing to a row of result.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
#include <SQLiteCpp/Utils.h> // SQLITECPP_PURE_FUNC
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
// Forward declarations to avoid inclusion of <sqlite3.h> in a header
|
||||
struct sqlite3;
|
||||
struct sqlite3_stmt;
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
|
||||
// Forward declaration
|
||||
class Database;
|
||||
class Column;
|
||||
|
||||
extern const int OK; ///< SQLITE_OK
|
||||
|
||||
/**
|
||||
* @brief RAII encapsulation of a prepared SQLite Statement.
|
||||
*
|
||||
* A Statement is a compiled SQL query ready to be executed step by step
|
||||
* to provide results one row at a time.
|
||||
*
|
||||
* Resource Acquisition Is Initialization (RAII) means that the Statement
|
||||
* is compiled in the constructor and finalized in the destructor, so that there is
|
||||
* no need to worry about memory management or the validity of the underlying SQLite Statement.
|
||||
*
|
||||
* Thread-safety: a Statement object shall not be shared by multiple threads, because :
|
||||
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
|
||||
* provided that no single database connection is used simultaneously in two or more threads."
|
||||
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
|
||||
* because of the way it shares the underling SQLite precompiled statement
|
||||
* in a custom shared pointer (See the inner class "Statement::Ptr").
|
||||
*/
|
||||
class Statement
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Compile and register the SQL query for the provided SQLite Database Connection
|
||||
*
|
||||
* @param[in] aDatabase the SQLite Database Connection
|
||||
* @param[in] apQuery an UTF-8 encoded query string
|
||||
*
|
||||
* Exception is thrown in case of error, then the Statement object is NOT constructed.
|
||||
*/
|
||||
Statement(const Database& aDatabase, const char* apQuery);
|
||||
|
||||
/**
|
||||
* @brief Compile and register the SQL query for the provided SQLite Database Connection
|
||||
*
|
||||
* @param[in] aDatabase the SQLite Database Connection
|
||||
* @param[in] aQuery an UTF-8 encoded query string
|
||||
*
|
||||
* Exception is thrown in case of error, then the Statement object is NOT constructed.
|
||||
*/
|
||||
Statement(const Database& aDatabase, const std::string& aQuery) :
|
||||
Statement(aDatabase, aQuery.c_str())
|
||||
{}
|
||||
|
||||
// Statement is non-copyable
|
||||
Statement(const Statement&) = delete;
|
||||
Statement& operator=(const Statement&) = delete;
|
||||
|
||||
// TODO: Change Statement move constructor to default
|
||||
Statement(Statement&& aStatement) noexcept;
|
||||
Statement& operator=(Statement&& aStatement) noexcept = default;
|
||||
|
||||
/// Finalize and unregister the SQL query from the SQLite Database Connection.
|
||||
/// The finalization will be done by the destructor of the last shared pointer
|
||||
~Statement() = default;
|
||||
|
||||
/// Reset the statement to make it ready for a new execution. Throws an exception on error.
|
||||
void reset();
|
||||
|
||||
/// Reset the statement. Returns the sqlite result code instead of throwing an exception on error.
|
||||
int tryReset() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Clears away all the bindings of a prepared statement.
|
||||
*
|
||||
* Contrary to the intuition of many, reset() does not reset the bindings on a prepared statement.
|
||||
* Use this routine to reset all parameters to NULL.
|
||||
*/
|
||||
void clearBindings(); // throw(SQLite::Exception)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Bind a value to a parameter of the SQL statement,
|
||||
// in the form "?" (unnamed), "?NNN", ":VVV", "@VVV" or "$VVV".
|
||||
//
|
||||
// Can use the parameter index, starting from "1", to the higher NNN value,
|
||||
// or the complete parameter name "?NNN", ":VVV", "@VVV" or "$VVV"
|
||||
// (prefixed with the corresponding sign "?", ":", "@" or "$")
|
||||
//
|
||||
// Note that for text and blob values, the SQLITE_TRANSIENT flag is used,
|
||||
// which tell the sqlite library to make its own copy of the data before the bind() call returns.
|
||||
// This choice is done to prevent any common misuses, like passing a pointer to a
|
||||
// dynamic allocated and temporary variable (a std::string for instance).
|
||||
// This is under-optimized for static data (a static text define in code)
|
||||
// as well as for dynamic allocated buffer which could be transfer to sqlite
|
||||
// instead of being copied.
|
||||
// => if you know what you are doing, use bindNoCopy() instead of bind()
|
||||
|
||||
SQLITECPP_PURE_FUNC
|
||||
int getIndex(const char * const apName) const;
|
||||
|
||||
/**
|
||||
* @brief Bind an int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const int aIndex, const int32_t aValue);
|
||||
/**
|
||||
* @brief Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const int aIndex, const uint32_t aValue);
|
||||
/**
|
||||
* @brief Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const int aIndex, const int64_t aValue);
|
||||
/**
|
||||
* @brief Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const int aIndex, const double aValue);
|
||||
/**
|
||||
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const int aIndex, const std::string& aValue);
|
||||
/**
|
||||
* @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const int aIndex, const char* apValue);
|
||||
/**
|
||||
* @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const int aIndex, const void* apValue, const int aSize);
|
||||
/**
|
||||
* @brief Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1).
|
||||
*
|
||||
* The string can contain null characters as it is binded using its size.
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const int aIndex, const std::string& aValue);
|
||||
/**
|
||||
* @brief Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* Main usage is with null-terminated literal text (aka in code static strings)
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const int aIndex, const char* apValue);
|
||||
/**
|
||||
* @brief Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const int aIndex, const void* apValue, const int aSize);
|
||||
/**
|
||||
* @brief Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @see clearBindings() to set all bound parameters to NULL.
|
||||
*/
|
||||
void bind(const int aIndex);
|
||||
|
||||
/**
|
||||
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const char* apName, const int32_t aValue)
|
||||
{
|
||||
bind(getIndex(apName), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a 32bits unsigned int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const char* apName, const uint32_t aValue)
|
||||
{
|
||||
bind(getIndex(apName), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const char* apName, const int64_t aValue)
|
||||
{
|
||||
bind(getIndex(apName), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const char* apName, const double aValue)
|
||||
{
|
||||
bind(getIndex(apName), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const char* apName, const std::string& aValue)
|
||||
{
|
||||
bind(getIndex(apName), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const char* apName, const char* apValue)
|
||||
{
|
||||
bind(getIndex(apName), apValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const char* apName, const void* apValue, const int aSize)
|
||||
{
|
||||
bind(getIndex(apName), apValue, aSize);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* The string can contain null characters as it is binded using its size.
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const char* apName, const std::string& aValue)
|
||||
{
|
||||
bindNoCopy(getIndex(apName), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* Main usage is with null-terminated literal text (aka in code static strings)
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const char* apName, const char* apValue)
|
||||
{
|
||||
bindNoCopy(getIndex(apName), apValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const char* apName, const void* apValue, const int aSize)
|
||||
{
|
||||
bindNoCopy(getIndex(apName), apValue, aSize);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @see clearBindings() to set all bound parameters to NULL.
|
||||
*/
|
||||
void bind(const char* apName) // bind NULL value
|
||||
{
|
||||
bind(getIndex(apName));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Bind an int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const std::string& aName, const int32_t aValue)
|
||||
{
|
||||
bind(aName.c_str(), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a 32bits unsigned int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const std::string& aName, const uint32_t aValue)
|
||||
{
|
||||
bind(aName.c_str(), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a 64bits int value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const std::string& aName, const int64_t aValue)
|
||||
{
|
||||
bind(aName.c_str(), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a double (64bits float) value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*/
|
||||
void bind(const std::string& aName, const double aValue)
|
||||
{
|
||||
bind(aName.c_str(), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const std::string& aName, const std::string& aValue)
|
||||
{
|
||||
bind(aName.c_str(), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const std::string& aName, const char* apValue)
|
||||
{
|
||||
bind(aName.c_str(), apValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @note Uses the SQLITE_TRANSIENT flag, making a copy of the data, for SQLite internal use
|
||||
*/
|
||||
void bind(const std::string& aName, const void* apValue, const int aSize)
|
||||
{
|
||||
bind(aName.c_str(), apValue, aSize);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a string value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* The string can contain null characters as it is binded using its size.
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const std::string& aName, const std::string& aValue)
|
||||
{
|
||||
bindNoCopy(aName.c_str(), aValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a text value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* Main usage is with null-terminated literal text (aka in code static strings)
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const std::string& aName, const char* apValue)
|
||||
{
|
||||
bindNoCopy(aName.c_str(), apValue);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a binary blob value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @warning Uses the SQLITE_STATIC flag, avoiding a copy of the data. The string must remains unchanged while executing the statement.
|
||||
*/
|
||||
void bindNoCopy(const std::string& aName, const void* apValue, const int aSize)
|
||||
{
|
||||
bindNoCopy(aName.c_str(), apValue, aSize);
|
||||
}
|
||||
/**
|
||||
* @brief Bind a NULL value to a named parameter "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement (aIndex >= 1)
|
||||
*
|
||||
* @see clearBindings() to set all bound parameters to NULL.
|
||||
*/
|
||||
void bind(const std::string& aName) // bind NULL value
|
||||
{
|
||||
bind(aName.c_str());
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Execute a step of the prepared query to fetch one row of results.
|
||||
*
|
||||
* While true is returned, a row of results is available, and can be accessed
|
||||
* through the getColumn() method
|
||||
*
|
||||
* @see exec() execute a one-step prepared statement with no expected result
|
||||
* @see tryExecuteStep() try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
|
||||
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
||||
*
|
||||
* @return - true (SQLITE_ROW) if there is another row ready : you can call getColumn(N) to get it
|
||||
* then you have to call executeStep() again to fetch more rows until the query is finished
|
||||
* - false (SQLITE_DONE) if the query has finished executing : there is no (more) row of result
|
||||
* (case of a query with no result, or after N rows fetched successfully)
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
bool executeStep();
|
||||
|
||||
/**
|
||||
* @brief Try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @see exec() execute a one-step prepared statement with no expected result
|
||||
* @see executeStep() execute a step of the prepared query to fetch one row of results
|
||||
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
||||
*
|
||||
* @return the sqlite result code.
|
||||
*/
|
||||
int tryExecuteStep() noexcept;
|
||||
|
||||
/**
|
||||
* @brief Execute a one-step query with no expected result, and return the number of changes.
|
||||
*
|
||||
* This method is useful for any kind of statements other than the Data Query Language (DQL) "SELECT" :
|
||||
* - Data Definition Language (DDL) statements "CREATE", "ALTER" and "DROP"
|
||||
* - Data Manipulation Language (DML) statements "INSERT", "UPDATE" and "DELETE"
|
||||
* - Data Control Language (DCL) statements "GRANT", "REVOKE", "COMMIT" and "ROLLBACK"
|
||||
*
|
||||
* It is similar to Database::exec(), but using a precompiled statement, it adds :
|
||||
* - the ability to bind() arguments to it (best way to insert data),
|
||||
* - reusing it allows for better performances (efficient for multiple insertion).
|
||||
*
|
||||
* @see executeStep() execute a step of the prepared query to fetch one row of results
|
||||
* @see tryExecuteStep() try to execute a step of the prepared query to fetch one row of results, returning the sqlite result code.
|
||||
* @see Database::exec() is a shortcut to execute one or multiple statements without results
|
||||
*
|
||||
* @return number of row modified by this SQL statement (INSERT, UPDATE or DELETE)
|
||||
*
|
||||
* @throw SQLite::Exception in case of error, or if row of results are returned while they are not expected!
|
||||
*/
|
||||
int exec();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @brief Return a copy of the column data specified by its index
|
||||
*
|
||||
* Can be used to access the data of the current row of result when applicable,
|
||||
* while the executeStep() method returns true.
|
||||
*
|
||||
* Throw an exception if there is no row to return a Column from:
|
||||
* - if provided index is out of bound
|
||||
* - before any executeStep() call
|
||||
* - after the last executeStep() returned false
|
||||
* - after a reset() call
|
||||
*
|
||||
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
|
||||
*
|
||||
* @param[in] aIndex Index of the column, starting at 0
|
||||
*
|
||||
* @note This method is not const, reflecting the fact that the returned Column object will
|
||||
* share the ownership of the underlying sqlite3_stmt.
|
||||
*
|
||||
* @warning The resulting Column object must not be memorized "as-is".
|
||||
* Is is only a wrapper around the current result row, so it is only valid
|
||||
* while the row from the Statement remains valid, that is only until next executeStep() call.
|
||||
* Thus, you should instead extract immediately its data (getInt(), getText()...)
|
||||
* and use or copy this data for any later usage.
|
||||
*/
|
||||
Column getColumn(const int aIndex) const;
|
||||
|
||||
/**
|
||||
* @brief Return a copy of the column data specified by its column name (less efficient than using an index)
|
||||
*
|
||||
* Can be used to access the data of the current row of result when applicable,
|
||||
* while the executeStep() method returns true.
|
||||
*
|
||||
* Throw an exception if there is no row to return a Column from :
|
||||
* - if provided name is not one of the aliased column names
|
||||
* - before any executeStep() call
|
||||
* - after the last executeStep() returned false
|
||||
* - after a reset() call
|
||||
*
|
||||
* Throw an exception if the specified name is not an on of the aliased name of the columns in the result.
|
||||
*
|
||||
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
|
||||
*
|
||||
* @note Uses a map of column names to indexes, build on first call.
|
||||
*
|
||||
* @note This method is not const, reflecting the fact that the returned Column object will
|
||||
* share the ownership of the underlying sqlite3_stmt.
|
||||
*
|
||||
* @warning The resulting Column object must not be memorized "as-is".
|
||||
* Is is only a wrapper around the current result row, so it is only valid
|
||||
* while the row from the Statement remains valid, that is only until next executeStep() call.
|
||||
* Thus, you should instead extract immediately its data (getInt(), getText()...)
|
||||
* and use or copy this data for any later usage.
|
||||
*
|
||||
* Throw an exception if the specified name is not one of the aliased name of the columns in the result.
|
||||
*/
|
||||
Column getColumn(const char* apName) const;
|
||||
|
||||
#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1900) // c++14: Visual Studio 2015
|
||||
/**
|
||||
* @brief Return an instance of T constructed from copies of the first N columns
|
||||
*
|
||||
* Can be used to access the data of the current row of result when applicable,
|
||||
* while the executeStep() method returns true.
|
||||
*
|
||||
* Throw an exception if there is no row to return a Column from:
|
||||
* - if provided column count is out of bound
|
||||
* - before any executeStep() call
|
||||
* - after the last executeStep() returned false
|
||||
* - after a reset() call
|
||||
*
|
||||
* Throw an exception if the specified column count is out of the [0, getColumnCount()) range.
|
||||
*
|
||||
* @tparam T Object type to construct
|
||||
* @tparam N Number of columns
|
||||
*
|
||||
* @note Requires std=C++14
|
||||
*/
|
||||
template<typename T, int N>
|
||||
T getColumns();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Helper function used by getColumns<typename T, int N> to expand an integer_sequence used to generate
|
||||
* the required Column objects
|
||||
*/
|
||||
template<typename T, const int... Is>
|
||||
T getColumns(const std::integer_sequence<int, Is...>);
|
||||
|
||||
public:
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Test if the column value is NULL
|
||||
*
|
||||
* @param[in] aIndex Index of the column, starting at 0
|
||||
*
|
||||
* @return true if the column value is NULL
|
||||
*
|
||||
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
|
||||
*/
|
||||
bool isColumnNull(const int aIndex) const;
|
||||
|
||||
/**
|
||||
* @brief Test if the column value is NULL
|
||||
*
|
||||
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
|
||||
*
|
||||
* @return true if the column value is NULL
|
||||
*
|
||||
* Throw an exception if the specified name is not one of the aliased name of the columns in the result.
|
||||
*/
|
||||
bool isColumnNull(const char* apName) const;
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the named assigned to the specified result column (potentially aliased)
|
||||
*
|
||||
* @param[in] aIndex Index of the column in the range [0, getColumnCount()).
|
||||
*
|
||||
* @see getColumnOriginName() to get original column name (not aliased)
|
||||
*
|
||||
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
|
||||
*/
|
||||
const char* getColumnName(const int aIndex) const;
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
/**
|
||||
* @brief Return a pointer to the table column name that is the origin of the specified result column
|
||||
*
|
||||
* Require definition of the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro :
|
||||
* - when building the SQLite library itself (which is the case for the Debian libsqlite3 binary for instance),
|
||||
* - and also when compiling this wrapper.
|
||||
*
|
||||
* Throw an exception if the specified index is out of the [0, getColumnCount()) range.
|
||||
*/
|
||||
const char* getColumnOriginName(const int aIndex) const;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Return the index of the specified (potentially aliased) column name
|
||||
*
|
||||
* @param[in] apName Aliased name of the column, that is, the named specified in the query (not the original name)
|
||||
*
|
||||
* @note Uses a map of column names to indexes, build on first call.
|
||||
*
|
||||
* Throw an exception if the specified name is not known.
|
||||
*/
|
||||
int getColumnIndex(const char* apName) const;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return the declared type of the specified result column for a SELECT statement.
|
||||
*
|
||||
* This is the type given at creation of the column and not the actual data type.
|
||||
* SQLite stores data types dynamically for each value and not per column.
|
||||
*
|
||||
* @param[in] aIndex Index of the column in the range [0, getColumnCount()).
|
||||
*
|
||||
* Throw an exception if the type can't be determined because:
|
||||
* - the specified index is out of the [0, getColumnCount()) range
|
||||
* - the statement is not a SELECT query
|
||||
* - the column at aIndex is not a table column but an expression or subquery
|
||||
*/
|
||||
const char * getColumnDeclaredType(const int aIndex) const;
|
||||
|
||||
|
||||
/// Get number of rows modified by last INSERT, UPDATE or DELETE statement (not DROP table).
|
||||
int getChanges() const noexcept;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// Return the UTF-8 SQL Query.
|
||||
const std::string& getQuery() const
|
||||
{
|
||||
return mQuery;
|
||||
}
|
||||
|
||||
// Return a UTF-8 string containing the SQL text of prepared statement with bound parameters expanded.
|
||||
std::string getExpandedSQL() const;
|
||||
|
||||
/// Return the number of columns in the result set returned by the prepared statement
|
||||
int getColumnCount() const
|
||||
{
|
||||
return mColumnCount;
|
||||
}
|
||||
/// true when a row has been fetched with executeStep()
|
||||
bool hasRow() const
|
||||
{
|
||||
return mbHasRow;
|
||||
}
|
||||
/// true when the last executeStep() had no more row to fetch
|
||||
bool isDone() const
|
||||
{
|
||||
return mbDone;
|
||||
}
|
||||
|
||||
/// Return the number of bind parameters in the statement
|
||||
int getBindParameterCount() const noexcept;
|
||||
|
||||
/// Return the numeric result code for the most recent failed API call (if any).
|
||||
int getErrorCode() const noexcept;
|
||||
/// Return the extended numeric result code for the most recent failed API call (if any).
|
||||
int getExtendedErrorCode() const noexcept;
|
||||
/// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
|
||||
const char* getErrorMsg() const noexcept;
|
||||
|
||||
/// Shared pointer to SQLite Prepared Statement Object
|
||||
using TStatementPtr = std::shared_ptr<sqlite3_stmt>;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Check if a return code equals SQLITE_OK, else throw a SQLite::Exception with the SQLite error message
|
||||
*
|
||||
* @param[in] aRet SQLite return code to test against the SQLITE_OK expected value
|
||||
*/
|
||||
void check(const int aRet) const
|
||||
{
|
||||
if (SQLite::OK != aRet)
|
||||
{
|
||||
throw SQLite::Exception(mpSQLite, aRet);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if there is a row of result returned by executeStep(), else throw a SQLite::Exception.
|
||||
*/
|
||||
void checkRow() const
|
||||
{
|
||||
if (false == mbHasRow)
|
||||
{
|
||||
throw SQLite::Exception("No row to get a column from. executeStep() was not called, or returned false.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if there is a Column index is in the range of columns in the result.
|
||||
*/
|
||||
void checkIndex(const int aIndex) const
|
||||
{
|
||||
if ((aIndex < 0) || (aIndex >= mColumnCount))
|
||||
{
|
||||
throw SQLite::Exception("Column index out of range.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prepare statement object.
|
||||
*
|
||||
* @return Shared pointer to prepared statement object
|
||||
*/
|
||||
TStatementPtr prepareStatement();
|
||||
|
||||
/**
|
||||
* @brief Return a prepared statement object.
|
||||
*
|
||||
* Throw an exception if the statement object was not prepared.
|
||||
* @return raw pointer to Prepared Statement Object
|
||||
*/
|
||||
sqlite3_stmt* getPreparedStatement() const;
|
||||
|
||||
std::string mQuery; //!< UTF-8 SQL Query
|
||||
sqlite3* mpSQLite; //!< Pointer to SQLite Database Connection Handle
|
||||
TStatementPtr mpPreparedStatement; //!< Shared Pointer to the prepared SQLite Statement Object
|
||||
int mColumnCount = 0; //!< Number of columns in the result of the prepared statement
|
||||
bool mbHasRow = false; //!< true when a row has been fetched with executeStep()
|
||||
bool mbDone = false; //!< true when the last executeStep() had no more row to fetch
|
||||
|
||||
/// Map of columns index by name (mutable so getColumnIndex can be const)
|
||||
mutable std::map<std::string, int> mColumnNames;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SQLite
|
95
third-party/SQLiteCpp/include/SQLiteCpp/Transaction.h
generated
vendored
95
third-party/SQLiteCpp/include/SQLiteCpp/Transaction.h
generated
vendored
@ -1,95 +0,0 @@
|
||||
/**
|
||||
* @file Transaction.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief A Transaction is way to group multiple SQL statements into an atomic secured operation.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
|
||||
// Forward declaration
|
||||
class Database;
|
||||
|
||||
/**
|
||||
* @brief Transaction behaviors when opening an SQLite transaction.
|
||||
* Names correspond directly to the behavior.
|
||||
*/
|
||||
enum class TransactionBehavior {
|
||||
DEFERRED,
|
||||
IMMEDIATE,
|
||||
EXCLUSIVE,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief RAII encapsulation of a SQLite Transaction.
|
||||
*
|
||||
* A Transaction is a way to group multiple SQL statements into an atomic secured operation;
|
||||
* either it succeeds, with all the changes committed to the database file,
|
||||
* or if it fails, all the changes are rolled back to the initial state.
|
||||
*
|
||||
* Resource Acquisition Is Initialization (RAII) means that the Transaction
|
||||
* begins in the constructor and is rollbacked in the destructor, so that there is
|
||||
* no need to worry about memory management or the validity of the underlying SQLite Connection.
|
||||
*
|
||||
* This method also offers big performances improvements compared to individually executed statements.
|
||||
*
|
||||
* Thread-safety: a Transaction object shall not be shared by multiple threads, because :
|
||||
* 1) in the SQLite "Thread Safe" mode, "SQLite can be safely used by multiple threads
|
||||
* provided that no single database connection is used simultaneously in two or more threads."
|
||||
* 2) the SQLite "Serialized" mode is not supported by SQLiteC++,
|
||||
* because of the way it shares the underling SQLite precompiled statement
|
||||
* in a custom shared pointer (See the inner class "Statement::Ptr").
|
||||
*/
|
||||
class Transaction
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Begins the SQLite transaction using the default transaction behavior.
|
||||
*
|
||||
* @param[in] aDatabase the SQLite Database Connection
|
||||
*
|
||||
* Exception is thrown in case of error, then the Transaction is NOT initiated.
|
||||
*/
|
||||
explicit Transaction(Database& aDatabase);
|
||||
|
||||
/**
|
||||
* @brief Begins the SQLite transaction with the specified behavior.
|
||||
*
|
||||
* @param[in] aDatabase the SQLite Database Connection
|
||||
* @param[in] behavior the requested transaction behavior
|
||||
*
|
||||
* Exception is thrown in case of error, then the Transaction is NOT initiated.
|
||||
*/
|
||||
explicit Transaction(Database& aDatabase, TransactionBehavior behavior);
|
||||
|
||||
// Transaction is non-copyable
|
||||
Transaction(const Transaction&) = delete;
|
||||
Transaction& operator=(const Transaction&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Safely rollback the transaction if it has not been committed.
|
||||
*/
|
||||
~Transaction();
|
||||
|
||||
/**
|
||||
* @brief Commit the transaction.
|
||||
*/
|
||||
void commit();
|
||||
|
||||
private:
|
||||
Database& mDatabase; ///< Reference to the SQLite Database Connection
|
||||
bool mbCommited = false; ///< True when commit has been called
|
||||
};
|
||||
|
||||
|
||||
} // namespace SQLite
|
31
third-party/SQLiteCpp/include/SQLiteCpp/Utils.h
generated
vendored
31
third-party/SQLiteCpp/include/SQLiteCpp/Utils.h
generated
vendored
@ -1,31 +0,0 @@
|
||||
/**
|
||||
* @file Utils.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Definition of the SQLITECPP_PURE_FUNC macro.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// macro taken from https://github.com/nemequ/hedley/blob/master/hedley.h that was in public domain at this time
|
||||
#if defined(__GNUC__) || defined(__GNUG__) || defined(__clang__) ||\
|
||||
(defined(__INTEL_COMPILER) && __INTEL_COMPILER > 1600) ||\
|
||||
(defined(__ARMCC_VERSION) && __ARMCC_VERSION > 4010000) ||\
|
||||
(\
|
||||
defined(__TI_COMPILER_VERSION__) && (\
|
||||
__TI_COMPILER_VERSION__ > 8003000 ||\
|
||||
(__TI_COMPILER_VERSION__ > 7003000 && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))\
|
||||
)\
|
||||
)
|
||||
#if defined(__has_attribute)
|
||||
#if !defined(SQLITECPP_PURE_FUNC) && __has_attribute(pure)
|
||||
#define SQLITECPP_PURE_FUNC __attribute__((pure))
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(SQLITECPP_PURE_FUNC)
|
||||
#define SQLITECPP_PURE_FUNC
|
||||
#endif
|
98
third-party/SQLiteCpp/include/SQLiteCpp/VariadicBind.h
generated
vendored
98
third-party/SQLiteCpp/include/SQLiteCpp/VariadicBind.h
generated
vendored
@ -1,98 +0,0 @@
|
||||
/**
|
||||
* @file VariadicBind.h
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Convenience function for Statement::bind(...)
|
||||
*
|
||||
* Copyright (c) 2016 Paul Dreik (github@pauldreik.se)
|
||||
* Copyright (c) 2016-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
* Copyright (c) 2019 Maximilian Bachmann (contact@maxbachmann.de)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
#include <tuple>
|
||||
#endif // c++14
|
||||
|
||||
/// @cond
|
||||
#include <utility>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* \brief Convenience function for calling Statement::bind(...) once for each argument given.
|
||||
*
|
||||
* This takes care of incrementing the index between each calls to bind.
|
||||
*
|
||||
* This feature requires a c++11 capable compiler.
|
||||
*
|
||||
* \code{.cpp}
|
||||
* SQLite::Statement stm("SELECT * FROM MyTable WHERE colA>? && colB=? && colC<?");
|
||||
* SQLite::bind(stm,a,b,c);
|
||||
* //...is equivalent to
|
||||
* stm.bind(1,a);
|
||||
* stm.bind(2,b);
|
||||
* stm.bind(3,c);
|
||||
* \endcode
|
||||
* @param query statement
|
||||
* @param args zero or more args to bind.
|
||||
*/
|
||||
template<class ...Args>
|
||||
void bind(SQLite::Statement& query, const Args& ... args)
|
||||
{
|
||||
int pos = 0;
|
||||
(void)std::initializer_list<int>{
|
||||
((void)query.bind(++pos, std::forward<decltype(args)>(args)), 0)...
|
||||
};
|
||||
}
|
||||
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
|
||||
/**
|
||||
* \brief Convenience function for calling Statement::bind(...) once for each parameter of a tuple,
|
||||
* by forwarding them to the variadic template
|
||||
*
|
||||
* This feature requires a c++14 capable compiler.
|
||||
*
|
||||
* \code{.cpp}
|
||||
* SQLite::Statement stm("SELECT * FROM MyTable WHERE colA>? && colB=? && colC<?");
|
||||
* SQLite::bind(stm, std::make_tuple(a, b, c));
|
||||
* //...is equivalent to
|
||||
* stm.bind(1,a);
|
||||
* stm.bind(2,b);
|
||||
* stm.bind(3,c);
|
||||
* \endcode
|
||||
* @param query statement
|
||||
* @param tuple tuple with values to bind
|
||||
*/
|
||||
template <typename ... Types>
|
||||
void bind(SQLite::Statement& query, const std::tuple<Types...> &tuple)
|
||||
{
|
||||
bind(query, tuple, std::index_sequence_for<Types...>());
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convenience function for calling Statement::bind(...) once for each parameter of a tuple,
|
||||
* by forwarding them to the variadic template. This function is just needed to convert the tuples
|
||||
* to parameter packs
|
||||
*
|
||||
* This feature requires a c++14 capable compiler.
|
||||
*
|
||||
* @param query statement
|
||||
* @param tuple tuple with values to bind
|
||||
*/
|
||||
template <typename ... Types, std::size_t ... Indices>
|
||||
void bind(SQLite::Statement& query, const std::tuple<Types...> &tuple, std::index_sequence<Indices...>)
|
||||
{
|
||||
bind(query, std::get<Indices>(tuple)...);
|
||||
}
|
||||
#endif // c++14
|
||||
|
||||
} // namespace SQLite
|
226
third-party/SQLiteCpp/meson.build
generated
vendored
226
third-party/SQLiteCpp/meson.build
generated
vendored
@ -1,226 +0,0 @@
|
||||
project(
|
||||
'SQLiteCpp', 'cpp',
|
||||
# SQLiteCpp requires C++11 support
|
||||
default_options: ['cpp_std=c++11'],
|
||||
license: 'MIT',
|
||||
version: '3.1.1',
|
||||
)
|
||||
|
||||
cxx = meson.get_compiler('cpp')
|
||||
|
||||
## at best we might try to test if this code compiles
|
||||
## testing for compilers or platforms is not reliable enough
|
||||
## example: native clang on windows or mingw in windows
|
||||
unix_like_code = '''
|
||||
#if defined(unix) || defined(__unix__) || defined(__unix)
|
||||
// do nothing
|
||||
#else
|
||||
# error "Non Unix-like OS"
|
||||
#endif
|
||||
'''
|
||||
unix_like = cxx.compiles(unix_like_code, name : 'unix like environment')
|
||||
|
||||
thread_dep = dependency('threads')
|
||||
# sqlite3 support
|
||||
sqlite3_dep = dependency(
|
||||
'sqlite3',
|
||||
fallback: ['sqlite3', 'sqlite3_dep']
|
||||
)
|
||||
|
||||
sqlitecpp_incl = [
|
||||
include_directories('include')
|
||||
]
|
||||
sqlitecpp_srcs = [
|
||||
'src/Backup.cpp',
|
||||
'src/Column.cpp',
|
||||
'src/Database.cpp',
|
||||
'src/Exception.cpp',
|
||||
'src/Statement.cpp',
|
||||
'src/Transaction.cpp',
|
||||
]
|
||||
sqlitecpp_args = [
|
||||
'-Wall',
|
||||
]
|
||||
sqlitecpp_link = []
|
||||
sqlitecpp_deps = [
|
||||
sqlite3_dep,
|
||||
thread_dep,
|
||||
]
|
||||
## used to override the default sqlitecpp options like cpp standard
|
||||
sqlitecpp_opts = []
|
||||
|
||||
## tests
|
||||
|
||||
sqlitecpp_test_srcs = [
|
||||
'tests/Column_test.cpp',
|
||||
'tests/Database_test.cpp',
|
||||
'tests/Statement_test.cpp',
|
||||
'tests/Backup_test.cpp',
|
||||
'tests/Transaction_test.cpp',
|
||||
'tests/VariadicBind_test.cpp',
|
||||
'tests/Exception_test.cpp',
|
||||
'tests/ExecuteMany_test.cpp',
|
||||
]
|
||||
sqlitecpp_test_args = [
|
||||
# do not use ambiguous overloads by default
|
||||
'-DNON_AMBIGOUS_OVERLOAD'
|
||||
]
|
||||
|
||||
## samples
|
||||
|
||||
sqlitecpp_sample_srcs = [
|
||||
'examples/example1/main.cpp',
|
||||
]
|
||||
|
||||
# if not using MSVC we need to add this compiler arguments
|
||||
# for a list of MSVC supported arguments please check:
|
||||
# https://docs.microsoft.com/en-us/cpp/build/reference/compiler-options-listed-alphabetically?view=msvc-170
|
||||
if not (host_machine.system() == 'windows' and cxx.get_id() == 'msvc')
|
||||
sqlitecpp_args += [
|
||||
'-Wextra',
|
||||
'-Wpedantic',
|
||||
'-Wswitch-enum',
|
||||
'-Wshadow',
|
||||
'-Wno-long-long',
|
||||
]
|
||||
endif
|
||||
## using MSVC headers requires c++14, if not will show an error on xstddef as:
|
||||
## 'auto' return without trailing return type; deduced return types are a C++14 extension
|
||||
if host_machine.system() == 'windows'
|
||||
message('[WINDOWS] using c++14 standard')
|
||||
sqlitecpp_opts += [
|
||||
'cpp_std=c++14',
|
||||
]
|
||||
endif
|
||||
# Options relative to SQLite and SQLiteC++ functions
|
||||
|
||||
if get_option('SQLITE_ENABLE_COLUMN_METADATA')
|
||||
sqlitecpp_args += [
|
||||
'-DSQLITE_ENABLE_COLUMN_METADATA',
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('SQLITE_ENABLE_ASSERT_HANDLER')
|
||||
sqlitecpp_args += [
|
||||
'-DSQLITE_ENABLE_ASSERT_HANDLER',
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('SQLITE_HAS_CODEC')
|
||||
sqlitecpp_args += [
|
||||
'SQLITE_HAS_CODEC',
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('SQLITE_USE_LEGACY_STRUCT')
|
||||
sqlitecpp_args += [
|
||||
'-DSQLITE_USE_LEGACY_STRUCT',
|
||||
]
|
||||
endif
|
||||
|
||||
if unix_like
|
||||
sqlitecpp_args += [
|
||||
'-DfPIC',
|
||||
]
|
||||
# add dl dependency
|
||||
libdl_dep = cxx.find_library('dl')
|
||||
sqlitecpp_deps += [
|
||||
libdl_dep,
|
||||
]
|
||||
endif
|
||||
|
||||
if get_option('b_coverage')
|
||||
# Prevent the compiler from removing the unused inline functions so that they get tracked as "non-covered"
|
||||
sqlitecpp_args += [
|
||||
'-fkeep-inline-functions',
|
||||
'-fkeep-static-functions',
|
||||
]
|
||||
endif
|
||||
|
||||
|
||||
libsqlitecpp = library(
|
||||
'sqlitecpp',
|
||||
sqlitecpp_srcs,
|
||||
include_directories: sqlitecpp_incl,
|
||||
cpp_args: sqlitecpp_args,
|
||||
dependencies: sqlitecpp_deps,
|
||||
# override the default options
|
||||
override_options: sqlitecpp_opts,
|
||||
# install: true,
|
||||
# API version for SQLiteCpp shared library.
|
||||
version: '0',)
|
||||
if get_option('SQLITECPP_BUILD_TESTS')
|
||||
# for the unit tests we need to link against a static version of SQLiteCpp
|
||||
libsqlitecpp_static = static_library(
|
||||
'sqlitecpp_static',
|
||||
sqlitecpp_srcs,
|
||||
include_directories: sqlitecpp_incl,
|
||||
cpp_args: sqlitecpp_args,
|
||||
dependencies: sqlitecpp_deps,
|
||||
# override the default options
|
||||
override_options: sqlitecpp_opts,)
|
||||
# static libraries do not have a version
|
||||
endif
|
||||
|
||||
install_headers(
|
||||
'include/SQLiteCpp/SQLiteCpp.h',
|
||||
'include/SQLiteCpp/Assertion.h',
|
||||
'include/SQLiteCpp/Backup.h',
|
||||
'include/SQLiteCpp/Column.h',
|
||||
'include/SQLiteCpp/Database.h',
|
||||
'include/SQLiteCpp/Exception.h',
|
||||
'include/SQLiteCpp/Statement.h',
|
||||
'include/SQLiteCpp/Transaction.h',
|
||||
'include/SQLiteCpp/VariadicBind.h',
|
||||
'include/SQLiteCpp/ExecuteMany.h',
|
||||
)
|
||||
|
||||
sqlitecpp_dep = declare_dependency(
|
||||
include_directories: sqlitecpp_incl,
|
||||
link_with: libsqlitecpp,
|
||||
)
|
||||
if get_option('SQLITECPP_BUILD_TESTS')
|
||||
## make the dependency static so the unit tests can link against it
|
||||
## (mainly for windows as the symbols are not exported by default)
|
||||
sqlitecpp_static_dep = declare_dependency(
|
||||
include_directories: sqlitecpp_incl,
|
||||
link_with: libsqlitecpp_static,
|
||||
)
|
||||
endif
|
||||
|
||||
if get_option('SQLITECPP_BUILD_TESTS')
|
||||
gtest_dep = dependency(
|
||||
'gtest',
|
||||
main : true,
|
||||
fallback: ['gtest', 'gtest_dep'])
|
||||
sqlitecpp_test_dependencies = [
|
||||
gtest_dep,
|
||||
sqlitecpp_static_dep,
|
||||
sqlite3_dep,
|
||||
]
|
||||
|
||||
testexe = executable('testexe', sqlitecpp_test_srcs,
|
||||
dependencies: sqlitecpp_test_dependencies,
|
||||
cpp_args: sqlitecpp_test_args,
|
||||
# override the default options
|
||||
override_options: sqlitecpp_opts,)
|
||||
|
||||
test_args = []
|
||||
|
||||
test('sqlitecpp unit tests', testexe, args: test_args)
|
||||
endif
|
||||
if get_option('SQLITECPP_BUILD_EXAMPLES')
|
||||
## demo executable
|
||||
sqlitecpp_demo_exe = executable('SQLITECPP_sample_demo',
|
||||
sqlitecpp_sample_srcs,
|
||||
dependencies: sqlitecpp_dep,
|
||||
# override the default options
|
||||
override_options: sqlitecpp_opts,)
|
||||
endif
|
||||
|
||||
pkgconfig = import('pkgconfig')
|
||||
pkgconfig.generate(
|
||||
libsqlitecpp,
|
||||
description: 'a smart and easy to use C++ SQLite3 wrapper.',
|
||||
version: meson.project_version(),
|
||||
)
|
13
third-party/SQLiteCpp/meson_options.txt
generated
vendored
13
third-party/SQLiteCpp/meson_options.txt
generated
vendored
@ -1,13 +0,0 @@
|
||||
# Options relative to SQLite and SQLiteC++ functions
|
||||
## Enable the use of SQLite column metadata and Column::getColumnOriginName() method,
|
||||
## Require that the sqlite3 library is also compiled with this flag (default under Debian/Ubuntu, but not on Mac OS X).
|
||||
option('SQLITE_ENABLE_COLUMN_METADATA', type: 'boolean', value: false, description: 'Enable Column::getColumnOriginName(). Require support from sqlite3 library.')
|
||||
## Enable the user definition of a assertion_failed() handler (default to false, easier to handler for beginners).
|
||||
option('SQLITE_ENABLE_ASSERT_HANDLER', type: 'boolean', value: false, description: 'Enable the user definition of a assertion_failed() handler.')
|
||||
## Enable database encryption API. Requires implementations of sqlite3_key & sqlite3_key_v2.
|
||||
## Eg. SQLCipher (libsqlcipher-dev) is an SQLite extension that provides 256 bit AES encryption of database files.
|
||||
option('SQLITE_HAS_CODEC', type: 'boolean', value: false, description: 'Enable database encryption API. Not available in the public release of SQLite.')
|
||||
## Force forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)
|
||||
option('SQLITE_USE_LEGACY_STRUCT', type: 'boolean', value: false, description: 'Fallback to forward declaration of legacy struct sqlite3_value (pre SQLite 3.19)')
|
||||
option('SQLITECPP_BUILD_TESTS', type: 'boolean', value: false, description: 'Build SQLiteC++ unit tests.')
|
||||
option('SQLITECPP_BUILD_EXAMPLES', type: 'boolean', value: false, description: 'Build SQLiteC++ examples.')
|
21
third-party/SQLiteCpp/package.xml
generated
vendored
21
third-party/SQLiteCpp/package.xml
generated
vendored
@ -1,21 +0,0 @@
|
||||
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||
<package format="3">
|
||||
<name>SQLiteCpp</name>
|
||||
<version>3.1.1</version>
|
||||
<description>A smart and easy to use C++ SQLite3 wrapper.</description>
|
||||
|
||||
<maintainer email="sebastien.rombauts@gmail.com">Sébastien Rombauts</maintainer>
|
||||
|
||||
<license>MIT</license>
|
||||
|
||||
<author email="sebastien.rombauts@gmail.com">Sébastien Rombauts</author>
|
||||
|
||||
<buildtool_depend>cmake</buildtool_depend>
|
||||
|
||||
<depend>libsqlite3-dev</depend>
|
||||
|
||||
<export>
|
||||
<build_type>cmake</build_type>
|
||||
</export>
|
||||
|
||||
</package>
|
65
third-party/SQLiteCpp/sqlite3/CMakeLists.txt
generated
vendored
65
third-party/SQLiteCpp/sqlite3/CMakeLists.txt
generated
vendored
@ -1,65 +0,0 @@
|
||||
# CMake file for compiling the sqlite3 static library under Windows (for ease of use)
|
||||
#
|
||||
# Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
#
|
||||
# Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
# or copy at http://opensource.org/licenses/MIT)
|
||||
|
||||
# add sources of the "sqlite3" static library
|
||||
add_library(sqlite3
|
||||
sqlite3.c
|
||||
sqlite3.h
|
||||
)
|
||||
|
||||
add_library(SQLite::SQLite3 ALIAS sqlite3)
|
||||
|
||||
target_include_directories(sqlite3
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
$<INSTALL_INTERFACE:include/>)
|
||||
|
||||
if (SQLITE_ENABLE_COLUMN_METADATA)
|
||||
# Enable the use of SQLite column metadata method
|
||||
# Require that the sqlite3 library is also compiled with this flag:
|
||||
target_compile_definitions(sqlite3 PUBLIC SQLITE_ENABLE_COLUMN_METADATA)
|
||||
endif (SQLITE_ENABLE_COLUMN_METADATA)
|
||||
|
||||
if (SQLITE_ENABLE_JSON1)
|
||||
# Enable JSON1 extension when building sqlite3
|
||||
# See more here: https://www.sqlite.org/json1.html
|
||||
target_compile_definitions(sqlite3 PUBLIC SQLITE_ENABLE_JSON1)
|
||||
endif (SQLITE_ENABLE_JSON1)
|
||||
|
||||
if(SQLITE_ENABLE_RTREE)
|
||||
# Enable RTree extension when building sqlite3
|
||||
# See more here: https://sqlite.org/rtree.html
|
||||
target_compile_definitions(sqlite3 PUBLIC SQLITE_ENABLE_RTREE)
|
||||
endif (SQLITE_ENABLE_RTREE)
|
||||
|
||||
if (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
|
||||
set_target_properties(sqlite3 PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
|
||||
# Put each function in its own section to allow the linker garbage
|
||||
# collection to remove unused section and produced a smaller
|
||||
# statically-lined executables.
|
||||
target_compile_options(sqlite3 PRIVATE "-ffunction-sections")
|
||||
endif (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
|
||||
|
||||
if (UNIX AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
||||
target_compile_options(sqlite3 PRIVATE "-Wimplicit-fallthrough=0")
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
|
||||
target_compile_options(sqlite3 PRIVATE "-Wno-cast-function-type")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Allow the library to be installed via "make install" and found with "find_package"
|
||||
|
||||
include(GNUInstallDirs)
|
||||
install(TARGETS sqlite3
|
||||
EXPORT ${PROJECT_NAME}Targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
COMPONENT libraries)
|
||||
install(FILES sqlite3.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} COMPONENT headers)
|
16
third-party/SQLiteCpp/sqlite3/README.md
generated
vendored
16
third-party/SQLiteCpp/sqlite3/README.md
generated
vendored
@ -1,16 +0,0 @@
|
||||
sqlite3
|
||||
-------
|
||||
|
||||
Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
|
||||
"sqlite3.c" and "sqlite3.h" files from sqlite-amalgamation-3370200.zip (SQLite 3.37.2 2022-01-06)
|
||||
|
||||
Those files are provided for easy setup and compatibility under Windows/Linux/MacOS.
|
||||
They are used by default by the CMake build.
|
||||
|
||||
Use -DSQLITECPP_INTERNAL_SQLITE=OFF to link against the Linux "libsqlite3-dev" package instead.
|
||||
|
||||
### License:
|
||||
|
||||
All of the code and documentation in SQLite has been dedicated to the public domain by the authors.
|
||||
|
84
third-party/SQLiteCpp/src/Backup.cpp
generated
vendored
84
third-party/SQLiteCpp/src/Backup.cpp
generated
vendored
@ -1,84 +0,0 @@
|
||||
/**
|
||||
* @file Backup.cpp
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Backup is used to backup a database file in a safe and online way.
|
||||
*
|
||||
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
|
||||
* Copyright (c) 2015-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Backup.h>
|
||||
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
// Initialize resource for SQLite database backup
|
||||
Backup::Backup(Database& aDestDatabase,
|
||||
const char* apDestDatabaseName,
|
||||
Database& aSrcDatabase,
|
||||
const char* apSrcDatabaseName)
|
||||
{
|
||||
mpSQLiteBackup.reset(sqlite3_backup_init(aDestDatabase.getHandle(),
|
||||
apDestDatabaseName,
|
||||
aSrcDatabase.getHandle(),
|
||||
apSrcDatabaseName));
|
||||
if (nullptr == mpSQLiteBackup)
|
||||
{
|
||||
// If an error occurs, the error code and message are attached to the destination database connection.
|
||||
throw SQLite::Exception(aDestDatabase.getHandle());
|
||||
}
|
||||
}
|
||||
|
||||
Backup::Backup(Database& aDestDatabase,
|
||||
const std::string& aDestDatabaseName,
|
||||
Database& aSrcDatabase,
|
||||
const std::string& aSrcDatabaseName) :
|
||||
Backup(aDestDatabase, aDestDatabaseName.c_str(), aSrcDatabase, aSrcDatabaseName.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
Backup::Backup(Database &aDestDatabase, Database &aSrcDatabase) :
|
||||
Backup(aDestDatabase, "main", aSrcDatabase, "main")
|
||||
{
|
||||
}
|
||||
|
||||
// Execute backup step with a given number of source pages to be copied
|
||||
int Backup::executeStep(const int aNumPage /* = -1 */)
|
||||
{
|
||||
const int res = sqlite3_backup_step(mpSQLiteBackup.get(), aNumPage);
|
||||
if (SQLITE_OK != res && SQLITE_DONE != res && SQLITE_BUSY != res && SQLITE_LOCKED != res)
|
||||
{
|
||||
throw SQLite::Exception(sqlite3_errstr(res), res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// Get the number of remaining source pages to be copied in this backup process
|
||||
int Backup::getRemainingPageCount() const
|
||||
{
|
||||
return sqlite3_backup_remaining(mpSQLiteBackup.get());
|
||||
}
|
||||
|
||||
// Get the number of total source pages to be copied in this backup process
|
||||
int Backup::getTotalPageCount() const
|
||||
{
|
||||
return sqlite3_backup_pagecount(mpSQLiteBackup.get());
|
||||
}
|
||||
|
||||
// Release resource for SQLite database backup
|
||||
void SQLite::Backup::Deleter::operator()(sqlite3_backup* apBackup)
|
||||
{
|
||||
if (apBackup)
|
||||
{
|
||||
sqlite3_backup_finish(apBackup);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
122
third-party/SQLiteCpp/src/Column.cpp
generated
vendored
122
third-party/SQLiteCpp/src/Column.cpp
generated
vendored
@ -1,122 +0,0 @@
|
||||
/**
|
||||
* @file Column.cpp
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Encapsulation of a Column in a row of the result pointed by the prepared SQLite::Statement.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Column.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
const int INTEGER = SQLITE_INTEGER;
|
||||
const int FLOAT = SQLITE_FLOAT;
|
||||
const int TEXT = SQLITE_TEXT;
|
||||
const int BLOB = SQLITE_BLOB;
|
||||
const int Null = SQLITE_NULL;
|
||||
|
||||
|
||||
// Encapsulation of a Column in a row of the result pointed by the prepared Statement.
|
||||
Column::Column(const Statement::TStatementPtr& aStmtPtr, int aIndex) :
|
||||
mStmtPtr(aStmtPtr),
|
||||
mIndex(aIndex)
|
||||
{
|
||||
if (!aStmtPtr)
|
||||
{
|
||||
throw SQLite::Exception("Statement was destroyed");
|
||||
}
|
||||
}
|
||||
|
||||
// Return the named assigned to this result column (potentially aliased)
|
||||
const char* Column::getName() const noexcept
|
||||
{
|
||||
return sqlite3_column_name(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Return the name of the table column that is the origin of this result column
|
||||
const char* Column::getOriginName() const noexcept
|
||||
{
|
||||
return sqlite3_column_origin_name(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Return the integer value of the column specified by its index starting at 0
|
||||
int32_t Column::getInt() const noexcept
|
||||
{
|
||||
return sqlite3_column_int(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
|
||||
// Return the unsigned integer value of the column specified by its index starting at 0
|
||||
uint32_t Column::getUInt() const noexcept
|
||||
{
|
||||
return static_cast<unsigned>(getInt64());
|
||||
}
|
||||
|
||||
// Return the 64bits integer value of the column specified by its index starting at 0
|
||||
int64_t Column::getInt64() const noexcept
|
||||
{
|
||||
return sqlite3_column_int64(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
|
||||
// Return the double value of the column specified by its index starting at 0
|
||||
double Column::getDouble() const noexcept
|
||||
{
|
||||
return sqlite3_column_double(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
|
||||
// Return a pointer to the text value (NULL terminated string) of the column specified by its index starting at 0
|
||||
const char* Column::getText(const char* apDefaultValue /* = "" */) const noexcept
|
||||
{
|
||||
auto pText = reinterpret_cast<const char*>(sqlite3_column_text(mStmtPtr.get(), mIndex));
|
||||
return (pText ? pText : apDefaultValue);
|
||||
}
|
||||
|
||||
// Return a pointer to the blob value (*not* NULL terminated) of the column specified by its index starting at 0
|
||||
const void* Column::getBlob() const noexcept
|
||||
{
|
||||
return sqlite3_column_blob(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
|
||||
// Return a std::string to a TEXT or BLOB column
|
||||
std::string Column::getString() const
|
||||
{
|
||||
// Note: using sqlite3_column_blob and not sqlite3_column_text
|
||||
// - no need for sqlite3_column_text to add a \0 on the end, as we're getting the bytes length directly
|
||||
auto data = static_cast<const char *>(sqlite3_column_blob(mStmtPtr.get(), mIndex));
|
||||
|
||||
// SQLite docs: "The safest policy is to invoke… sqlite3_column_blob() followed by sqlite3_column_bytes()"
|
||||
// Note: std::string is ok to pass nullptr as first arg, if length is 0
|
||||
return std::string(data, sqlite3_column_bytes(mStmtPtr.get(), mIndex));
|
||||
}
|
||||
|
||||
// Return the type of the value of the column
|
||||
int Column::getType() const noexcept
|
||||
{
|
||||
return sqlite3_column_type(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
|
||||
// Return the number of bytes used by the text value of the column
|
||||
int Column::getBytes() const noexcept
|
||||
{
|
||||
return sqlite3_column_bytes(mStmtPtr.get(), mIndex);
|
||||
}
|
||||
|
||||
// Standard std::ostream inserter
|
||||
std::ostream& operator<<(std::ostream& aStream, const Column& aColumn)
|
||||
{
|
||||
aStream.write(aColumn.getText(), aColumn.getBytes());
|
||||
return aStream;
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
451
third-party/SQLiteCpp/src/Database.cpp
generated
vendored
451
third-party/SQLiteCpp/src/Database.cpp
generated
vendored
@ -1,451 +0,0 @@
|
||||
/**
|
||||
* @file Database.cpp
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Management of a SQLite Database Connection.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Database.h>
|
||||
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
#include <SQLiteCpp/Backup.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <fstream>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef SQLITE_DETERMINISTIC
|
||||
#define SQLITE_DETERMINISTIC 0x800
|
||||
#endif // SQLITE_DETERMINISTIC
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
const int OK = SQLITE_OK;
|
||||
const int OPEN_READONLY = SQLITE_OPEN_READONLY;
|
||||
const int OPEN_READWRITE = SQLITE_OPEN_READWRITE;
|
||||
const int OPEN_CREATE = SQLITE_OPEN_CREATE;
|
||||
const int OPEN_URI = SQLITE_OPEN_URI;
|
||||
const int OPEN_MEMORY = SQLITE_OPEN_MEMORY;
|
||||
const int OPEN_NOMUTEX = SQLITE_OPEN_NOMUTEX;
|
||||
const int OPEN_FULLMUTEX = SQLITE_OPEN_FULLMUTEX;
|
||||
const int OPEN_SHAREDCACHE = SQLITE_OPEN_SHAREDCACHE;
|
||||
const int OPEN_PRIVATECACHE = SQLITE_OPEN_PRIVATECACHE;
|
||||
#if SQLITE_VERSION_NUMBER >= 3031000
|
||||
const int OPEN_NOFOLLOW = SQLITE_OPEN_NOFOLLOW;
|
||||
#else
|
||||
const int OPEN_NOFOLLOW = 0;
|
||||
#endif
|
||||
|
||||
const char* const VERSION = SQLITE_VERSION;
|
||||
const int VERSION_NUMBER = SQLITE_VERSION_NUMBER;
|
||||
|
||||
// Return SQLite version string using runtime call to the compiled library
|
||||
const char* getLibVersion() noexcept
|
||||
{
|
||||
return sqlite3_libversion();
|
||||
}
|
||||
|
||||
// Return SQLite version number using runtime call to the compiled library
|
||||
int getLibVersionNumber() noexcept
|
||||
{
|
||||
return sqlite3_libversion_number();
|
||||
}
|
||||
|
||||
|
||||
// Open the provided database UTF-8 filename with SQLite::OPEN_xxx provided flags.
|
||||
Database::Database(const char* apFilename,
|
||||
const int aFlags /* = SQLite::OPEN_READONLY*/,
|
||||
const int aBusyTimeoutMs /* = 0 */,
|
||||
const char* apVfs /* = nullptr*/) :
|
||||
mFilename(apFilename)
|
||||
{
|
||||
sqlite3* handle;
|
||||
const int ret = sqlite3_open_v2(apFilename, &handle, aFlags, apVfs);
|
||||
mSQLitePtr.reset(handle);
|
||||
if (SQLITE_OK != ret)
|
||||
{
|
||||
throw SQLite::Exception(handle, ret);
|
||||
}
|
||||
if (aBusyTimeoutMs > 0)
|
||||
{
|
||||
setBusyTimeout(aBusyTimeoutMs);
|
||||
}
|
||||
}
|
||||
|
||||
// Deleter functor to use with smart pointers to close the SQLite database connection in an RAII fashion.
|
||||
void Database::Deleter::operator()(sqlite3* apSQLite)
|
||||
{
|
||||
const int ret = sqlite3_close(apSQLite); // Calling sqlite3_close() with a nullptr argument is a harmless no-op.
|
||||
|
||||
// Avoid unreferenced variable warning when build in release mode
|
||||
(void) ret;
|
||||
|
||||
// Only case of error is SQLITE_BUSY: "database is locked" (some statements are not finalized)
|
||||
// Never throw an exception in a destructor :
|
||||
SQLITECPP_ASSERT(SQLITE_OK == ret, "database is locked"); // See SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set a busy handler that sleeps for a specified amount of time when a table is locked.
|
||||
*
|
||||
* This is useful in multithreaded program to handle case where a table is locked for writting by a thread.
|
||||
* Any other thread cannot access the table and will receive a SQLITE_BUSY error:
|
||||
* setting a timeout will wait and retry up to the time specified before returning this SQLITE_BUSY error.
|
||||
* Reading the value of timeout for current connection can be done with SQL query "PRAGMA busy_timeout;".
|
||||
* Default busy timeout is 0ms.
|
||||
*
|
||||
* @param[in] aBusyTimeoutMs Amount of milliseconds to wait before returning SQLITE_BUSY
|
||||
*
|
||||
* @throw SQLite::Exception in case of error
|
||||
*/
|
||||
void Database::setBusyTimeout(const int aBusyTimeoutMs)
|
||||
{
|
||||
const int ret = sqlite3_busy_timeout(getHandle(), aBusyTimeoutMs);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Shortcut to execute one or multiple SQL statements without results (UPDATE, INSERT, ALTER, COMMIT, CREATE...).
|
||||
// Return the number of changes.
|
||||
int Database::exec(const char* apQueries)
|
||||
{
|
||||
const int ret = tryExec(apQueries);
|
||||
check(ret);
|
||||
|
||||
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE only)
|
||||
return sqlite3_changes(getHandle());
|
||||
}
|
||||
|
||||
int Database::tryExec(const char* apQueries) noexcept
|
||||
{
|
||||
return sqlite3_exec(getHandle(), apQueries, nullptr, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// Shortcut to execute a one step query and fetch the first column of the result.
|
||||
// WARNING: Be very careful with this dangerous method: you have to
|
||||
// make a COPY OF THE result, else it will be destroy before the next line
|
||||
// (when the underlying temporary Statement and Column objects are destroyed)
|
||||
// this is an issue only for pointer type result (ie. char* and blob)
|
||||
// (use the Column copy-constructor)
|
||||
Column Database::execAndGet(const char* apQuery)
|
||||
{
|
||||
Statement query(*this, apQuery);
|
||||
(void)query.executeStep(); // Can return false if no result, which will throw next line in getColumn()
|
||||
return query.getColumn(0);
|
||||
}
|
||||
|
||||
// Shortcut to test if a table exists.
|
||||
bool Database::tableExists(const char* apTableName) const
|
||||
{
|
||||
Statement query(*this, "SELECT count(*) FROM sqlite_master WHERE type='table' AND name=?");
|
||||
query.bind(1, apTableName);
|
||||
(void)query.executeStep(); // Cannot return false, as the above query always return a result
|
||||
return (1 == query.getColumn(0).getInt());
|
||||
}
|
||||
|
||||
// Get the rowid of the most recent successful INSERT into the database from the current connection.
|
||||
int64_t Database::getLastInsertRowid() const noexcept
|
||||
{
|
||||
return sqlite3_last_insert_rowid(getHandle());
|
||||
}
|
||||
|
||||
// Get number of rows modified by last INSERT, UPDATE or DELETE statement (not DROP table).
|
||||
int Database::getChanges() const noexcept
|
||||
{
|
||||
return sqlite3_changes(getHandle());
|
||||
}
|
||||
|
||||
// Get total number of rows modified by all INSERT, UPDATE or DELETE statement since connection.
|
||||
int Database::getTotalChanges() const noexcept
|
||||
{
|
||||
return sqlite3_total_changes(getHandle());
|
||||
}
|
||||
|
||||
// Return the numeric result code for the most recent failed API call (if any).
|
||||
int Database::getErrorCode() const noexcept
|
||||
{
|
||||
return sqlite3_errcode(getHandle());
|
||||
}
|
||||
|
||||
// Return the extended numeric result code for the most recent failed API call (if any).
|
||||
int Database::getExtendedErrorCode() const noexcept
|
||||
{
|
||||
return sqlite3_extended_errcode(getHandle());
|
||||
}
|
||||
|
||||
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
|
||||
const char* Database::getErrorMsg() const noexcept
|
||||
{
|
||||
return sqlite3_errmsg(getHandle());
|
||||
}
|
||||
|
||||
// Attach a custom function to your sqlite database. Assumes UTF8 text representation.
|
||||
// Parameter details can be found here: http://www.sqlite.org/c3ref/create_function.html
|
||||
void Database::createFunction(const char* apFuncName,
|
||||
int aNbArg,
|
||||
bool abDeterministic,
|
||||
void* apApp,
|
||||
void (*apFunc)(sqlite3_context *, int, sqlite3_value **),
|
||||
void (*apStep)(sqlite3_context *, int, sqlite3_value **) /* = nullptr */,
|
||||
void (*apFinal)(sqlite3_context *) /* = nullptr */, // NOLINT(readability/casting)
|
||||
void (*apDestroy)(void *) /* = nullptr */)
|
||||
{
|
||||
int textRep = SQLITE_UTF8;
|
||||
// optimization if deterministic function (e.g. of nondeterministic function random())
|
||||
if (abDeterministic)
|
||||
{
|
||||
textRep = textRep | SQLITE_DETERMINISTIC;
|
||||
}
|
||||
const int ret = sqlite3_create_function_v2(getHandle(), apFuncName, aNbArg, textRep,
|
||||
apApp, apFunc, apStep, apFinal, apDestroy);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Load an extension into the sqlite database. Only affects the current connection.
|
||||
// Parameter details can be found here: http://www.sqlite.org/c3ref/load_extension.html
|
||||
void Database::loadExtension(const char* apExtensionName, const char *apEntryPointName)
|
||||
{
|
||||
#ifdef SQLITE_OMIT_LOAD_EXTENSION
|
||||
// Unused
|
||||
(void)apExtensionName;
|
||||
(void)apEntryPointName;
|
||||
|
||||
throw SQLite::Exception("sqlite extensions are disabled");
|
||||
#else
|
||||
#ifdef SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION // Since SQLite 3.13 (2016-05-18):
|
||||
// Security warning:
|
||||
// It is recommended that the SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION method be used to enable only this interface.
|
||||
// The use of the sqlite3_enable_load_extension() interface should be avoided to keep the SQL load_extension()
|
||||
// disabled and prevent SQL injections from giving attackers access to extension loading capabilities.
|
||||
// (NOTE: not using nullptr: cannot pass object of non-POD type 'std::__1::nullptr_t' through variadic function)
|
||||
int ret = sqlite3_db_config(getHandle(), SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, NULL); // NOTE: not using nullptr
|
||||
#else
|
||||
int ret = sqlite3_enable_load_extension(getHandle(), 1);
|
||||
#endif
|
||||
check(ret);
|
||||
|
||||
ret = sqlite3_load_extension(getHandle(), apExtensionName, apEntryPointName, 0);
|
||||
check(ret);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Set the key for the current sqlite database instance.
|
||||
void Database::key(const std::string& aKey) const
|
||||
{
|
||||
int passLen = static_cast<int>(aKey.length());
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
if (passLen > 0)
|
||||
{
|
||||
const int ret = sqlite3_key(getHandle(), aKey.c_str(), passLen);
|
||||
check(ret);
|
||||
}
|
||||
#else // SQLITE_HAS_CODEC
|
||||
if (passLen > 0)
|
||||
{
|
||||
throw SQLite::Exception("No encryption support, recompile with SQLITE_HAS_CODEC to enable.");
|
||||
}
|
||||
#endif // SQLITE_HAS_CODEC
|
||||
}
|
||||
|
||||
// Reset the key for the current sqlite database instance.
|
||||
void Database::rekey(const std::string& aNewKey) const
|
||||
{
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
int passLen = aNewKey.length();
|
||||
if (passLen > 0)
|
||||
{
|
||||
const int ret = sqlite3_rekey(getHandle(), aNewKey.c_str(), passLen);
|
||||
check(ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int ret = sqlite3_rekey(getHandle(), nullptr, 0);
|
||||
check(ret);
|
||||
}
|
||||
#else // SQLITE_HAS_CODEC
|
||||
static_cast<void>(aNewKey); // silence unused parameter warning
|
||||
throw SQLite::Exception("No encryption support, recompile with SQLITE_HAS_CODEC to enable.");
|
||||
#endif // SQLITE_HAS_CODEC
|
||||
}
|
||||
|
||||
// Test if a file contains an unencrypted database.
|
||||
bool Database::isUnencrypted(const std::string& aFilename)
|
||||
{
|
||||
if (aFilename.empty())
|
||||
{
|
||||
throw SQLite::Exception("Could not open database, the aFilename parameter was empty.");
|
||||
}
|
||||
|
||||
std::ifstream fileBuffer(aFilename.c_str(), std::ios::in | std::ios::binary);
|
||||
char header[16];
|
||||
if (fileBuffer.is_open())
|
||||
{
|
||||
fileBuffer.seekg(0, std::ios::beg);
|
||||
fileBuffer.getline(header, 16);
|
||||
fileBuffer.close();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SQLite::Exception("Error opening file: " + aFilename);
|
||||
}
|
||||
|
||||
return strncmp(header, "SQLite format 3\000", 16) == 0;
|
||||
}
|
||||
|
||||
// Parse header data from a database.
|
||||
Header Database::getHeaderInfo(const std::string& aFilename)
|
||||
{
|
||||
Header h;
|
||||
unsigned char buf[100];
|
||||
char* pBuf = reinterpret_cast<char*>(&buf[0]);
|
||||
char* pHeaderStr = reinterpret_cast<char*>(&h.headerStr[0]);
|
||||
|
||||
if (aFilename.empty())
|
||||
{
|
||||
throw SQLite::Exception("Filename parameter is empty");
|
||||
}
|
||||
|
||||
{
|
||||
std::ifstream fileBuffer(aFilename.c_str(), std::ios::in | std::ios::binary);
|
||||
if (fileBuffer.is_open())
|
||||
{
|
||||
fileBuffer.seekg(0, std::ios::beg);
|
||||
fileBuffer.read(pBuf, 100);
|
||||
fileBuffer.close();
|
||||
if (fileBuffer.gcount() < 100)
|
||||
{
|
||||
throw SQLite::Exception("File " + aFilename + " is too short");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SQLite::Exception("Error opening file " + aFilename);
|
||||
}
|
||||
}
|
||||
|
||||
// If the "magic string" can't be found then header is invalid, corrupt or unreadable
|
||||
memcpy(pHeaderStr, pBuf, 16);
|
||||
pHeaderStr[15] = '\0';
|
||||
if (strncmp(pHeaderStr, "SQLite format 3", 15) != 0)
|
||||
{
|
||||
throw SQLite::Exception("Invalid or encrypted SQLite header in file " + aFilename);
|
||||
}
|
||||
|
||||
h.pageSizeBytes = (buf[16] << 8) | buf[17];
|
||||
h.fileFormatWriteVersion = buf[18];
|
||||
h.fileFormatReadVersion = buf[19];
|
||||
h.reservedSpaceBytes = buf[20];
|
||||
h.maxEmbeddedPayloadFrac = buf[21];
|
||||
h.minEmbeddedPayloadFrac = buf[22];
|
||||
h.leafPayloadFrac = buf[23];
|
||||
|
||||
h.fileChangeCounter =
|
||||
(buf[24] << 24) |
|
||||
(buf[25] << 16) |
|
||||
(buf[26] << 8) |
|
||||
(buf[27] << 0);
|
||||
|
||||
h.databaseSizePages =
|
||||
(buf[28] << 24) |
|
||||
(buf[29] << 16) |
|
||||
(buf[30] << 8) |
|
||||
(buf[31] << 0);
|
||||
|
||||
h.firstFreelistTrunkPage =
|
||||
(buf[32] << 24) |
|
||||
(buf[33] << 16) |
|
||||
(buf[34] << 8) |
|
||||
(buf[35] << 0);
|
||||
|
||||
h.totalFreelistPages =
|
||||
(buf[36] << 24) |
|
||||
(buf[37] << 16) |
|
||||
(buf[38] << 8) |
|
||||
(buf[39] << 0);
|
||||
|
||||
h.schemaCookie =
|
||||
(buf[40] << 24) |
|
||||
(buf[41] << 16) |
|
||||
(buf[42] << 8) |
|
||||
(buf[43] << 0);
|
||||
|
||||
h.schemaFormatNumber =
|
||||
(buf[44] << 24) |
|
||||
(buf[45] << 16) |
|
||||
(buf[46] << 8) |
|
||||
(buf[47] << 0);
|
||||
|
||||
h.defaultPageCacheSizeBytes =
|
||||
(buf[48] << 24) |
|
||||
(buf[49] << 16) |
|
||||
(buf[50] << 8) |
|
||||
(buf[51] << 0);
|
||||
|
||||
h.largestBTreePageNumber =
|
||||
(buf[52] << 24) |
|
||||
(buf[53] << 16) |
|
||||
(buf[54] << 8) |
|
||||
(buf[55] << 0);
|
||||
|
||||
h.databaseTextEncoding =
|
||||
(buf[56] << 24) |
|
||||
(buf[57] << 16) |
|
||||
(buf[58] << 8) |
|
||||
(buf[59] << 0);
|
||||
|
||||
h.userVersion =
|
||||
(buf[60] << 24) |
|
||||
(buf[61] << 16) |
|
||||
(buf[62] << 8) |
|
||||
(buf[63] << 0);
|
||||
|
||||
h.incrementalVaccumMode =
|
||||
(buf[64] << 24) |
|
||||
(buf[65] << 16) |
|
||||
(buf[66] << 8) |
|
||||
(buf[67] << 0);
|
||||
|
||||
h.applicationId =
|
||||
(buf[68] << 24) |
|
||||
(buf[69] << 16) |
|
||||
(buf[70] << 8) |
|
||||
(buf[71] << 0);
|
||||
|
||||
h.versionValidFor =
|
||||
(buf[92] << 24) |
|
||||
(buf[93] << 16) |
|
||||
(buf[94] << 8) |
|
||||
(buf[95] << 0);
|
||||
|
||||
h.sqliteVersion =
|
||||
(buf[96] << 24) |
|
||||
(buf[97] << 16) |
|
||||
(buf[98] << 8) |
|
||||
(buf[99] << 0);
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
void Database::backup(const char* apFilename, BackupType aType)
|
||||
{
|
||||
// Open the database file identified by apFilename
|
||||
Database otherDatabase(apFilename, SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
|
||||
// For a 'Save' operation, data is copied from the current Database to the other. A 'Load' is the reverse.
|
||||
Database& src = (aType == BackupType::Save ? *this : otherDatabase);
|
||||
Database& dest = (aType == BackupType::Save ? otherDatabase : *this);
|
||||
|
||||
// Set up the backup procedure to copy between the "main" databases of each connection
|
||||
Backup bkp(dest, src);
|
||||
bkp.executeStep(); // Execute all steps at once
|
||||
|
||||
// RAII Finish Backup an Close the other Database
|
||||
}
|
||||
|
||||
} // namespace SQLite
|
47
third-party/SQLiteCpp/src/Exception.cpp
generated
vendored
47
third-party/SQLiteCpp/src/Exception.cpp
generated
vendored
@ -1,47 +0,0 @@
|
||||
/**
|
||||
* @file Exception.cpp
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief Encapsulation of the error message from SQLite3 on a std::runtime_error.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
Exception::Exception(const char* aErrorMessage, int ret) :
|
||||
std::runtime_error(aErrorMessage),
|
||||
mErrcode(ret),
|
||||
mExtendedErrcode(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Exception::Exception(sqlite3* apSQLite) :
|
||||
std::runtime_error(sqlite3_errmsg(apSQLite)),
|
||||
mErrcode(sqlite3_errcode(apSQLite)),
|
||||
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
|
||||
{
|
||||
}
|
||||
|
||||
Exception::Exception(sqlite3* apSQLite, int ret) :
|
||||
std::runtime_error(sqlite3_errmsg(apSQLite)),
|
||||
mErrcode(ret),
|
||||
mExtendedErrcode(sqlite3_extended_errcode(apSQLite))
|
||||
{
|
||||
}
|
||||
|
||||
// Return a string, solely based on the error code
|
||||
const char* Exception::getErrorStr() const noexcept
|
||||
{
|
||||
return sqlite3_errstr(mErrcode);
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
66
third-party/SQLiteCpp/src/Savepoint.cpp
generated
vendored
66
third-party/SQLiteCpp/src/Savepoint.cpp
generated
vendored
@ -1,66 +0,0 @@
|
||||
/**
|
||||
* @file Savepoint.cpp
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief A Savepoint is a way to group multiple SQL statements into an atomic
|
||||
* secured operation. Similar to a transaction while allowing child savepoints.
|
||||
*
|
||||
* Copyright (c) 2020 Kelvin Hammond (hammond.kelvin@gmail.com)
|
||||
* Copyright (c) 2020-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt or
|
||||
* copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Savepoint.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
|
||||
namespace SQLite {
|
||||
|
||||
// Begins the SQLite savepoint
|
||||
Savepoint::Savepoint(Database& aDatabase, const std::string& aName)
|
||||
: mDatabase(aDatabase), msName(aName) {
|
||||
// workaround because you cannot bind to SAVEPOINT
|
||||
// escape name for use in query
|
||||
Statement stmt(mDatabase, "SELECT quote(?)");
|
||||
stmt.bind(1, msName);
|
||||
stmt.executeStep();
|
||||
msName = stmt.getColumn(0).getText();
|
||||
|
||||
mDatabase.exec(std::string("SAVEPOINT ") + msName);
|
||||
}
|
||||
|
||||
// Safely rollback the savepoint if it has not been committed.
|
||||
Savepoint::~Savepoint() {
|
||||
if (!mbReleased) {
|
||||
try {
|
||||
rollback();
|
||||
} catch (SQLite::Exception&) {
|
||||
// Never throw an exception in a destructor: error if already rolled
|
||||
// back or released, but no harm is caused by this.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Release the savepoint and commit
|
||||
void Savepoint::release() {
|
||||
if (!mbReleased) {
|
||||
mDatabase.exec(std::string("RELEASE SAVEPOINT ") + msName);
|
||||
mbReleased = true;
|
||||
} else {
|
||||
throw SQLite::Exception("Savepoint already released or rolled back.");
|
||||
}
|
||||
}
|
||||
|
||||
// Rollback the savepoint
|
||||
void Savepoint::rollback() {
|
||||
if (!mbReleased) {
|
||||
mDatabase.exec(std::string("ROLLBACK TO SAVEPOINT ") + msName);
|
||||
mbReleased = true;
|
||||
} else {
|
||||
throw SQLite::Exception("Savepoint already released or rolled back.");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace SQLite
|
368
third-party/SQLiteCpp/src/Statement.cpp
generated
vendored
368
third-party/SQLiteCpp/src/Statement.cpp
generated
vendored
@ -1,368 +0,0 @@
|
||||
/**
|
||||
* @file Statement.cpp
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief A prepared SQLite Statement is a compiled SQL query ready to be executed, pointing to a row of result.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Column.h>
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
Statement::Statement(const Database& aDatabase, const char* apQuery) :
|
||||
mQuery(apQuery),
|
||||
mpSQLite(aDatabase.getHandle()),
|
||||
mpPreparedStatement(prepareStatement()) // prepare the SQL query (needs Database friendship)
|
||||
{
|
||||
mColumnCount = sqlite3_column_count(mpPreparedStatement.get());
|
||||
}
|
||||
|
||||
Statement::Statement(Statement&& aStatement) noexcept :
|
||||
mQuery(std::move(aStatement.mQuery)),
|
||||
mpSQLite(aStatement.mpSQLite),
|
||||
mpPreparedStatement(std::move(aStatement.mpPreparedStatement)),
|
||||
mColumnCount(aStatement.mColumnCount),
|
||||
mbHasRow(aStatement.mbHasRow),
|
||||
mbDone(aStatement.mbDone),
|
||||
mColumnNames(std::move(aStatement.mColumnNames))
|
||||
{
|
||||
aStatement.mpSQLite = nullptr;
|
||||
aStatement.mColumnCount = 0;
|
||||
aStatement.mbHasRow = false;
|
||||
aStatement.mbDone = false;
|
||||
}
|
||||
|
||||
// Reset the statement to make it ready for a new execution (see also #clearBindings() bellow)
|
||||
void Statement::reset()
|
||||
{
|
||||
const int ret = tryReset();
|
||||
check(ret);
|
||||
}
|
||||
|
||||
int Statement::tryReset() noexcept
|
||||
{
|
||||
mbHasRow = false;
|
||||
mbDone = false;
|
||||
return sqlite3_reset(mpPreparedStatement.get());
|
||||
}
|
||||
|
||||
// Clears away all the bindings of a prepared statement (can be associated with #reset() above).
|
||||
void Statement::clearBindings()
|
||||
{
|
||||
const int ret = sqlite3_clear_bindings(getPreparedStatement());
|
||||
check(ret);
|
||||
}
|
||||
|
||||
int Statement::getIndex(const char * const apName) const
|
||||
{
|
||||
return sqlite3_bind_parameter_index(getPreparedStatement(), apName);
|
||||
}
|
||||
|
||||
// Bind an 32bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const int32_t aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_int(getPreparedStatement(), aIndex, aValue);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a 32bits unsigned int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const uint32_t aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_int64(getPreparedStatement(), aIndex, aValue);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a 64bits int value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const int64_t aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_int64(getPreparedStatement(), aIndex, aValue);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a double (64bits float) value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const double aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_double(getPreparedStatement(), aIndex, aValue);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const std::string& aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_text(getPreparedStatement(), aIndex, aValue.c_str(),
|
||||
static_cast<int>(aValue.size()), SQLITE_TRANSIENT);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const char* apValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_text(getPreparedStatement(), aIndex, apValue, -1, SQLITE_TRANSIENT);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex, const void* apValue, const int aSize)
|
||||
{
|
||||
const int ret = sqlite3_bind_blob(getPreparedStatement(), aIndex, apValue, aSize, SQLITE_TRANSIENT);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a string value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const int aIndex, const std::string& aValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_text(getPreparedStatement(), aIndex, aValue.c_str(),
|
||||
static_cast<int>(aValue.size()), SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a text value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const int aIndex, const char* apValue)
|
||||
{
|
||||
const int ret = sqlite3_bind_text(getPreparedStatement(), aIndex, apValue, -1, SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a binary blob value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bindNoCopy(const int aIndex, const void* apValue, const int aSize)
|
||||
{
|
||||
const int ret = sqlite3_bind_blob(getPreparedStatement(), aIndex, apValue, aSize, SQLITE_STATIC);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
// Bind a NULL value to a parameter "?", "?NNN", ":VVV", "@VVV" or "$VVV" in the SQL prepared statement
|
||||
void Statement::bind(const int aIndex)
|
||||
{
|
||||
const int ret = sqlite3_bind_null(getPreparedStatement(), aIndex);
|
||||
check(ret);
|
||||
}
|
||||
|
||||
|
||||
// Execute a step of the query to fetch one row of results
|
||||
bool Statement::executeStep()
|
||||
{
|
||||
const int ret = tryExecuteStep();
|
||||
if ((SQLITE_ROW != ret) && (SQLITE_DONE != ret)) // on row or no (more) row ready, else it's a problem
|
||||
{
|
||||
if (ret == sqlite3_errcode(mpSQLite))
|
||||
{
|
||||
throw SQLite::Exception(mpSQLite, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SQLite::Exception("Statement needs to be reseted", ret);
|
||||
}
|
||||
}
|
||||
|
||||
return mbHasRow; // true only if one row is accessible by getColumn(N)
|
||||
}
|
||||
|
||||
// Execute a one-step query with no expected result, and return the number of changes.
|
||||
int Statement::exec()
|
||||
{
|
||||
const int ret = tryExecuteStep();
|
||||
if (SQLITE_DONE != ret) // the statement has finished executing successfully
|
||||
{
|
||||
if (SQLITE_ROW == ret)
|
||||
{
|
||||
throw SQLite::Exception("exec() does not expect results. Use executeStep.");
|
||||
}
|
||||
else if (ret == sqlite3_errcode(mpSQLite))
|
||||
{
|
||||
throw SQLite::Exception(mpSQLite, ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SQLite::Exception("Statement needs to be reseted", ret);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the number of rows modified by those SQL statements (INSERT, UPDATE or DELETE)
|
||||
return sqlite3_changes(mpSQLite);
|
||||
}
|
||||
|
||||
int Statement::tryExecuteStep() noexcept
|
||||
{
|
||||
if (mbDone)
|
||||
{
|
||||
return SQLITE_MISUSE; // Statement needs to be reseted !
|
||||
}
|
||||
|
||||
const int ret = sqlite3_step(mpPreparedStatement.get());
|
||||
if (SQLITE_ROW == ret) // one row is ready : call getColumn(N) to access it
|
||||
{
|
||||
mbHasRow = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mbHasRow = false;
|
||||
mbDone = SQLITE_DONE == ret; // check if the query has finished executing
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Return a copy of the column data specified by its index starting at 0
|
||||
// (use the Column copy-constructor)
|
||||
Column Statement::getColumn(const int aIndex) const
|
||||
{
|
||||
checkRow();
|
||||
checkIndex(aIndex);
|
||||
|
||||
// Share the Statement Object handle with the new Column created
|
||||
return Column(mpPreparedStatement, aIndex);
|
||||
}
|
||||
|
||||
// Return a copy of the column data specified by its column name starting at 0
|
||||
// (use the Column copy-constructor)
|
||||
Column Statement::getColumn(const char* apName) const
|
||||
{
|
||||
checkRow();
|
||||
const int index = getColumnIndex(apName);
|
||||
|
||||
// Share the Statement Object handle with the new Column created
|
||||
return Column(mpPreparedStatement, index);
|
||||
}
|
||||
|
||||
// Test if the column is NULL
|
||||
bool Statement::isColumnNull(const int aIndex) const
|
||||
{
|
||||
checkRow();
|
||||
checkIndex(aIndex);
|
||||
return (SQLITE_NULL == sqlite3_column_type(getPreparedStatement(), aIndex));
|
||||
}
|
||||
|
||||
bool Statement::isColumnNull(const char* apName) const
|
||||
{
|
||||
checkRow();
|
||||
const int index = getColumnIndex(apName);
|
||||
return (SQLITE_NULL == sqlite3_column_type(getPreparedStatement(), index));
|
||||
}
|
||||
|
||||
// Return the named assigned to the specified result column (potentially aliased)
|
||||
const char* Statement::getColumnName(const int aIndex) const
|
||||
{
|
||||
checkIndex(aIndex);
|
||||
return sqlite3_column_name(getPreparedStatement(), aIndex);
|
||||
}
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Return the named assigned to the specified result column (potentially aliased)
|
||||
const char* Statement::getColumnOriginName(const int aIndex) const
|
||||
{
|
||||
checkIndex(aIndex);
|
||||
return sqlite3_column_origin_name(getPreparedStatement(), aIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Return the index of the specified (potentially aliased) column name
|
||||
int Statement::getColumnIndex(const char* apName) const
|
||||
{
|
||||
// Build the map of column index by name on first call
|
||||
if (mColumnNames.empty())
|
||||
{
|
||||
for (int i = 0; i < mColumnCount; ++i)
|
||||
{
|
||||
const char* pName = sqlite3_column_name(getPreparedStatement(), i);
|
||||
mColumnNames[pName] = i;
|
||||
}
|
||||
}
|
||||
|
||||
const auto iIndex = mColumnNames.find(apName);
|
||||
if (iIndex == mColumnNames.end())
|
||||
{
|
||||
throw SQLite::Exception("Unknown column name.");
|
||||
}
|
||||
|
||||
return iIndex->second;
|
||||
}
|
||||
|
||||
const char* Statement::getColumnDeclaredType(const int aIndex) const
|
||||
{
|
||||
checkIndex(aIndex);
|
||||
const char * result = sqlite3_column_decltype(getPreparedStatement(), aIndex);
|
||||
if (!result)
|
||||
{
|
||||
throw SQLite::Exception("Could not determine declared column type.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// Get number of rows modified by last INSERT, UPDATE or DELETE statement (not DROP table).
|
||||
int Statement::getChanges() const noexcept
|
||||
{
|
||||
return sqlite3_changes(mpSQLite);
|
||||
}
|
||||
|
||||
int Statement::getBindParameterCount() const noexcept
|
||||
{
|
||||
return sqlite3_bind_parameter_count(mpPreparedStatement.get());
|
||||
}
|
||||
|
||||
// Return the numeric result code for the most recent failed API call (if any).
|
||||
int Statement::getErrorCode() const noexcept
|
||||
{
|
||||
return sqlite3_errcode(mpSQLite);
|
||||
}
|
||||
|
||||
// Return the extended numeric result code for the most recent failed API call (if any).
|
||||
int Statement::getExtendedErrorCode() const noexcept
|
||||
{
|
||||
return sqlite3_extended_errcode(mpSQLite);
|
||||
}
|
||||
|
||||
// Return UTF-8 encoded English language explanation of the most recent failed API call (if any).
|
||||
const char* Statement::getErrorMsg() const noexcept
|
||||
{
|
||||
return sqlite3_errmsg(mpSQLite);
|
||||
}
|
||||
|
||||
// Return a UTF-8 string containing the SQL text of prepared statement with bound parameters expanded.
|
||||
std::string Statement::getExpandedSQL() const {
|
||||
char* expanded = sqlite3_expanded_sql(getPreparedStatement());
|
||||
std::string expandedString(expanded);
|
||||
sqlite3_free(expanded);
|
||||
return expandedString;
|
||||
}
|
||||
|
||||
// Prepare SQLite statement object and return shared pointer to this object
|
||||
Statement::TStatementPtr Statement::prepareStatement()
|
||||
{
|
||||
sqlite3_stmt* statement;
|
||||
const int ret = sqlite3_prepare_v2(mpSQLite, mQuery.c_str(), static_cast<int>(mQuery.size()), &statement, nullptr);
|
||||
if (SQLITE_OK != ret)
|
||||
{
|
||||
throw SQLite::Exception(mpSQLite, ret);
|
||||
}
|
||||
return Statement::TStatementPtr(statement, [](sqlite3_stmt* stmt)
|
||||
{
|
||||
sqlite3_finalize(stmt);
|
||||
});
|
||||
}
|
||||
|
||||
// Return prepered statement object or throw
|
||||
sqlite3_stmt* Statement::getPreparedStatement() const
|
||||
{
|
||||
sqlite3_stmt* ret = mpPreparedStatement.get();
|
||||
if (ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
throw SQLite::Exception("Statement was not prepared.");
|
||||
}
|
||||
|
||||
} // namespace SQLite
|
81
third-party/SQLiteCpp/src/Transaction.cpp
generated
vendored
81
third-party/SQLiteCpp/src/Transaction.cpp
generated
vendored
@ -1,81 +0,0 @@
|
||||
/**
|
||||
* @file Transaction.cpp
|
||||
* @ingroup SQLiteCpp
|
||||
* @brief A Transaction is way to group multiple SQL statements into an atomic secured operation.
|
||||
*
|
||||
* Copyright (c) 2012-2022 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
#include <SQLiteCpp/Transaction.h>
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Assertion.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace SQLite
|
||||
{
|
||||
|
||||
|
||||
// Begins the SQLite transaction
|
||||
Transaction::Transaction(Database& aDatabase, TransactionBehavior behavior) :
|
||||
mDatabase(aDatabase)
|
||||
{
|
||||
const char *stmt;
|
||||
switch (behavior) {
|
||||
case TransactionBehavior::DEFERRED:
|
||||
stmt = "BEGIN DEFERRED";
|
||||
break;
|
||||
case TransactionBehavior::IMMEDIATE:
|
||||
stmt = "BEGIN IMMEDIATE";
|
||||
break;
|
||||
case TransactionBehavior::EXCLUSIVE:
|
||||
stmt = "BEGIN EXCLUSIVE";
|
||||
break;
|
||||
default:
|
||||
throw SQLite::Exception("invalid/unknown transaction behavior", SQLITE_ERROR);
|
||||
}
|
||||
mDatabase.exec(stmt);
|
||||
}
|
||||
|
||||
// Begins the SQLite transaction
|
||||
Transaction::Transaction(Database &aDatabase) :
|
||||
mDatabase(aDatabase)
|
||||
{
|
||||
mDatabase.exec("BEGIN");
|
||||
}
|
||||
|
||||
// Safely rollback the transaction if it has not been committed.
|
||||
Transaction::~Transaction()
|
||||
{
|
||||
if (false == mbCommited)
|
||||
{
|
||||
try
|
||||
{
|
||||
mDatabase.exec("ROLLBACK");
|
||||
}
|
||||
catch (SQLite::Exception&)
|
||||
{
|
||||
// Never throw an exception in a destructor: error if already rollbacked, but no harm is caused by this.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Commit the transaction.
|
||||
void Transaction::commit()
|
||||
{
|
||||
if (false == mbCommited)
|
||||
{
|
||||
mDatabase.exec("COMMIT");
|
||||
mbCommited = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw SQLite::Exception("Transaction already committed.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace SQLite
|
5
third-party/SQLiteCpp/subprojects/.gitignore
generated
vendored
5
third-party/SQLiteCpp/subprojects/.gitignore
generated
vendored
@ -1,5 +0,0 @@
|
||||
#ignore everything here
|
||||
*
|
||||
# but not the wrap files and the .gitignore
|
||||
!*.wrap
|
||||
!*.gitignore
|
12
third-party/SQLiteCpp/subprojects/gtest.wrap
generated
vendored
12
third-party/SQLiteCpp/subprojects/gtest.wrap
generated
vendored
@ -1,12 +0,0 @@
|
||||
[wrap-file]
|
||||
directory = googletest-release-1.11.0
|
||||
source_url = https://github.com/google/googletest/archive/release-1.11.0.tar.gz
|
||||
source_filename = gtest-1.11.0.tar.gz
|
||||
source_hash = b4870bf121ff7795ba20d20bcdd8627b8e088f2d1dab299a031c1034eddc93d5
|
||||
patch_directory = gtest
|
||||
|
||||
[provide]
|
||||
gtest = gtest_dep
|
||||
gtest_main = gtest_main_dep
|
||||
gmock = gmock_dep
|
||||
gmock_main = gmock_main_dep
|
12
third-party/SQLiteCpp/subprojects/sqlite3.wrap
generated
vendored
12
third-party/SQLiteCpp/subprojects/sqlite3.wrap
generated
vendored
@ -1,12 +0,0 @@
|
||||
[wrap-file]
|
||||
directory = sqlite-amalgamation-3380000
|
||||
source_url = https://sqlite.org/2022/sqlite-amalgamation-3380000.zip
|
||||
source_filename = sqlite-amalgamation-3380000.zip
|
||||
source_hash = e055f6054e97747a135c89e36520c0a423249e8a91c5fc445163f4a6adb20df6
|
||||
patch_filename = sqlite3_3.38.0-1_patch.zip
|
||||
patch_url = https://wrapdb.mesonbuild.com/v2/sqlite3_3.38.0-1/get_patch
|
||||
patch_hash = 49e30bf010ff63ab772d5417885e6905379025ceac80382e292c6dbd3a9da744
|
||||
|
||||
[provide]
|
||||
sqlite3 = sqlite3_dep
|
||||
|
127
third-party/SQLiteCpp/tests/Backup_test.cpp
generated
vendored
127
third-party/SQLiteCpp/tests/Backup_test.cpp
generated
vendored
@ -1,127 +0,0 @@
|
||||
/**
|
||||
* @file Backup_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLite Backup.
|
||||
*
|
||||
* Copyright (c) 2015 Shibao HONG (shibaohong@outlook.com)
|
||||
* Copyright (c) 2015-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Backup.h>
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <sqlite3.h> // for SQLITE_ERROR, SQLITE_RANGE and SQLITE_DONE
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
TEST(Backup, initException)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
{
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, srcDB), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, "main", srcDB, "main"), SQLite::Exception);
|
||||
const std::string name("main");
|
||||
EXPECT_THROW(SQLite::Backup backup(srcDB, name, srcDB, name), SQLite::Exception);
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
}
|
||||
|
||||
TEST(Backup, executeStepOne)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
{
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, "main", srcDB, "main");
|
||||
int res = backup.executeStep(1); // backup only one page at a time
|
||||
ASSERT_EQ(SQLite::OK, res);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(1, remaining);
|
||||
res = backup.executeStep(1); // backup the second and last page
|
||||
ASSERT_EQ(SQLITE_DONE, res);
|
||||
remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
||||
|
||||
TEST(Backup, executeStepAll)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
{
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
const int res = backup.executeStep(); // uses default argument "-1" => execute all steps at once
|
||||
ASSERT_EQ(res, SQLITE_DONE);
|
||||
const int total = backup.getTotalPageCount();
|
||||
ASSERT_EQ(2, total);
|
||||
const int remaining = backup.getRemainingPageCount();
|
||||
ASSERT_EQ(0, remaining);
|
||||
|
||||
SQLite::Statement query(destDB, "SELECT * FROM backup_test ORDER BY id ASC");
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1));
|
||||
ASSERT_TRUE(query.executeStep());
|
||||
EXPECT_EQ(2, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("second", query.getColumn(1));
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
||||
|
||||
TEST(Backup, executeStepException)
|
||||
{
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
{
|
||||
SQLite::Database srcDB("backup_test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
srcDB.exec("CREATE TABLE backup_test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (1, \"first\")"));
|
||||
ASSERT_EQ(1, srcDB.exec("INSERT INTO backup_test VALUES (2, \"second\")"));
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
(void)destDB;
|
||||
}
|
||||
{
|
||||
SQLite::Database destDB("backup_test.db3.backup", SQLite::OPEN_READONLY);
|
||||
SQLite::Backup backup(destDB, srcDB);
|
||||
EXPECT_THROW(backup.executeStep(), SQLite::Exception);
|
||||
}
|
||||
}
|
||||
remove("backup_test.db3");
|
||||
remove("backup_test.db3.backup");
|
||||
}
|
275
third-party/SQLiteCpp/tests/Column_test.cpp
generated
vendored
275
third-party/SQLiteCpp/tests/Column_test.cpp
generated
vendored
@ -1,275 +0,0 @@
|
||||
/**
|
||||
* @file Column_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLiteCpp Column.
|
||||
*
|
||||
* Copyright (c) 2012-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Column.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
TEST(Column, basis)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// Create a new table
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT, int INTEGER, double REAL, binary BLOB, empty TEXT)"));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
|
||||
// Create a first row (autoid: 1) with all kind of data and a null value
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (NULL, \"first\", -123, 0.123, ?, NULL)");
|
||||
// Bind the blob value to the first parameter of the SQL query
|
||||
const char buffer[] = {'b', 'l', '\0', 'b'}; // "bl\0b" : 4 char, with a null byte inside
|
||||
const int size = sizeof(buffer); // size = 4
|
||||
const void* blob = &buffer;
|
||||
insert.bind(1, blob, size);
|
||||
// Execute the one-step query to insert the row
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
EXPECT_THROW(insert.exec(), SQLite::Exception); // exec() shall throw as it needs to be reseted
|
||||
|
||||
// Compile a SQL query
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
EXPECT_STREQ("SELECT * FROM test", query.getQuery().c_str());
|
||||
EXPECT_EQ(6, query.getColumnCount ());
|
||||
query.executeStep();
|
||||
EXPECT_TRUE (query.hasRow());
|
||||
EXPECT_FALSE(query.isDone());
|
||||
|
||||
// validates every variant of cast operators, and conversions of types
|
||||
{
|
||||
const int64_t id1 = query.getColumn(0); // operator int64_t()
|
||||
const int32_t id2 = query.getColumn(0); // operator int32_t()
|
||||
const int id3 = query.getColumn(0); // operator int32_t()
|
||||
const int16_t id4 = query.getColumn(0); // operator int32_t()
|
||||
const short id5 = query.getColumn(0); // operator int32_t()
|
||||
const int8_t id6 = query.getColumn(0); // operator int32_t()
|
||||
const char id7 = query.getColumn(0); // operator int32_t()
|
||||
const unsigned int uint1 = query.getColumn(0); // operator unsigned int()
|
||||
const uint32_t uint2 = query.getColumn(0); // operator unsigned int()
|
||||
const unsigned char uint3 = query.getColumn(0); // operator unsigned char()
|
||||
const unsigned short uint4 = query.getColumn(0); // operator unsigned short()
|
||||
const char* ptxt = query.getColumn(1); // operator const char*()
|
||||
const std::string msg = query.getColumn(1); // operator std::string() (or const char* with MSVC)
|
||||
const int integer = query.getColumn(2); // operator int()
|
||||
const double real = query.getColumn(3); // operator double()
|
||||
const void* pblob = query.getColumn(4); // operator void*()
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
// This implicit cast should use operator std::string()
|
||||
// but would fallback to const char* with MSVC 2010-2013 (witch does not work with the NULL char in the middle)
|
||||
const std::string sblob = query.getColumn(4); // operator std::string()
|
||||
#endif
|
||||
const void* pempty = query.getColumn(5); // operator void*()
|
||||
EXPECT_EQ(1, id1);
|
||||
EXPECT_EQ(1, id2);
|
||||
EXPECT_EQ(1, id3);
|
||||
EXPECT_EQ(1U, uint1);
|
||||
EXPECT_EQ(1U, uint2);
|
||||
EXPECT_EQ(1U, uint3);
|
||||
EXPECT_EQ(1U, uint4);
|
||||
EXPECT_STREQ("first", ptxt);
|
||||
EXPECT_EQ("first", msg);
|
||||
EXPECT_EQ(-123, integer);
|
||||
EXPECT_EQ(0.123, real);
|
||||
EXPECT_EQ(0, memcmp("bl\0b", pblob, size));
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
EXPECT_EQ((size_t)size, sblob.size());
|
||||
EXPECT_EQ(0, memcmp("bl\0b", &sblob[0], size));
|
||||
#endif
|
||||
EXPECT_EQ(NULL, pempty);
|
||||
}
|
||||
|
||||
// validates every variant of explicit getters
|
||||
{
|
||||
int64_t id = query.getColumn(0).getInt64();
|
||||
const unsigned int uint1 = query.getColumn(0).getUInt();
|
||||
const uint32_t uint2 = query.getColumn(0).getUInt();
|
||||
const char* ptxt = query.getColumn(1).getText();
|
||||
const std::string msg1 = query.getColumn(1).getText();
|
||||
const std::string msg2 = query.getColumn(1).getString();
|
||||
const int integer = query.getColumn(2).getInt();
|
||||
const double real = query.getColumn(3).getDouble();
|
||||
const void* pblob = query.getColumn(4).getBlob();
|
||||
const std::string sblob = query.getColumn(4).getString();
|
||||
EXPECT_EQ(1, id);
|
||||
EXPECT_EQ(1U, uint1);
|
||||
EXPECT_EQ(1U, uint2);
|
||||
EXPECT_STREQ("first", ptxt);
|
||||
EXPECT_EQ("first", msg1);
|
||||
EXPECT_EQ("first", msg2);
|
||||
EXPECT_EQ(-123, integer);
|
||||
EXPECT_EQ(0.123, real);
|
||||
EXPECT_EQ(0, memcmp("bl\0b", pblob, 4));
|
||||
EXPECT_EQ(0, memcmp("bl\0b", &sblob[0], 4));
|
||||
}
|
||||
|
||||
// Validate getBytes(), getType(), isInteger(), isNull()...
|
||||
EXPECT_EQ(SQLite::INTEGER, query.getColumn(0).getType());
|
||||
EXPECT_EQ(true, query.getColumn(0).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(0).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(0).isText());
|
||||
EXPECT_EQ(false, query.getColumn(0).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(0).isNull());
|
||||
EXPECT_STREQ("1", query.getColumn(0).getText()); // convert to string
|
||||
EXPECT_EQ(1, query.getColumn(0).getBytes()); // size of the string "1" without the null terminator
|
||||
EXPECT_EQ(SQLite::TEXT, query.getColumn(1).getType());
|
||||
EXPECT_EQ(false, query.getColumn(1).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(1).isFloat());
|
||||
EXPECT_EQ(true, query.getColumn(1).isText());
|
||||
EXPECT_EQ(false, query.getColumn(1).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(1).isNull());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText()); // convert to string
|
||||
EXPECT_EQ(5, query.getColumn(1).getBytes()); // size of the string "first"
|
||||
EXPECT_EQ(SQLite::INTEGER, query.getColumn(2).getType());
|
||||
EXPECT_EQ(true, query.getColumn(2).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(2).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(2).isText());
|
||||
EXPECT_EQ(false, query.getColumn(2).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(2).isNull());
|
||||
EXPECT_STREQ("-123", query.getColumn(2).getText()); // convert to string
|
||||
EXPECT_EQ(4, query.getColumn(2).getBytes()); // size of the string "-123"
|
||||
EXPECT_EQ(SQLite::FLOAT, query.getColumn(3).getType());
|
||||
EXPECT_EQ(false, query.getColumn(3).isInteger());
|
||||
EXPECT_EQ(true, query.getColumn(3).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(3).isText());
|
||||
EXPECT_EQ(false, query.getColumn(3).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(3).isNull());
|
||||
EXPECT_STREQ("0.123", query.getColumn(3).getText()); // convert to string
|
||||
EXPECT_EQ(5, query.getColumn(3).getBytes()); // size of the string "0.123"
|
||||
EXPECT_EQ(SQLite::BLOB, query.getColumn(4).getType());
|
||||
EXPECT_EQ(false, query.getColumn(4).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(4).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(4).isText());
|
||||
EXPECT_EQ(true, query.getColumn(4).isBlob());
|
||||
EXPECT_EQ(false, query.getColumn(4).isNull());
|
||||
EXPECT_STREQ("bl\0b", query.getColumn(4).getText()); // convert to string
|
||||
EXPECT_EQ(4, query.getColumn(4).getBytes()); // size of the blob "bl\0b" with the null char
|
||||
EXPECT_EQ(SQLite::Null, query.getColumn(5).getType());
|
||||
EXPECT_EQ(false, query.getColumn(5).isInteger());
|
||||
EXPECT_EQ(false, query.getColumn(5).isFloat());
|
||||
EXPECT_EQ(false, query.getColumn(5).isText());
|
||||
EXPECT_EQ(false, query.getColumn(5).isBlob());
|
||||
EXPECT_EQ(true, query.getColumn(5).isNull());
|
||||
EXPECT_STREQ("", query.getColumn(5).getText()); // convert to string
|
||||
EXPECT_EQ(0, query.getColumn(5).getBytes()); // size of the string "" without the null terminator
|
||||
|
||||
// Use intermediate Column objects (this is not the recommended way to use the API)
|
||||
{
|
||||
const SQLite::Column id = query.getColumn(0);
|
||||
EXPECT_EQ(1, id.getInt64());
|
||||
const SQLite::Column msg = query.getColumn(1);
|
||||
EXPECT_EQ("first", msg.getString());
|
||||
const SQLite::Column integer = query.getColumn(2);
|
||||
EXPECT_EQ(-123, integer.getInt());
|
||||
const SQLite::Column dbl = query.getColumn(3);
|
||||
EXPECT_EQ(0.123, dbl.getDouble());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Column, getName)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
|
||||
// Compile a SQL query, using the "id" column name as-is, but aliasing the "msg" column with new name "value"
|
||||
SQLite::Statement query(db, "SELECT id, msg as value FROM test");
|
||||
query.executeStep();
|
||||
|
||||
// Show how to get the aliased names of the result columns.
|
||||
const std::string name0 = query.getColumn(0).getName();
|
||||
const std::string name1 = query.getColumn(1).getName();
|
||||
EXPECT_EQ("id", name0);
|
||||
EXPECT_EQ("value", name1);
|
||||
|
||||
#ifdef SQLITE_ENABLE_COLUMN_METADATA
|
||||
// Show how to get origin names of the table columns from which theses result columns come from.
|
||||
// Requires the SQLITE_ENABLE_COLUMN_METADATA preprocessor macro to be
|
||||
// also defined at compile times of the SQLite library itself.
|
||||
const std::string oname0 = query.getColumn(0).getOriginName();
|
||||
const std::string oname1 = query.getColumn(1).getOriginName();
|
||||
EXPECT_EQ("id", oname0);
|
||||
EXPECT_EQ("msg", oname1);
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Column, stream)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (msg TEXT)"));
|
||||
SQLite::Statement insert(db, "INSERT INTO test VALUES (?)");
|
||||
|
||||
// content to test
|
||||
const char str_[] = "stringwith\0embedded";
|
||||
std::string str(str_, sizeof(str_)-1);
|
||||
|
||||
insert.bind(1, str);
|
||||
// Execute the one-step query to insert the row
|
||||
EXPECT_EQ(1, insert.exec());
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
query.executeStep();
|
||||
std::stringstream ss;
|
||||
ss << query.getColumn(0);
|
||||
std::string content = ss.str();
|
||||
EXPECT_EQ(content, str);
|
||||
}
|
||||
|
||||
TEST(Column, shared_ptr)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, msg TEXT)"));
|
||||
EXPECT_EQ(1, db.exec(R"(INSERT INTO test VALUES (42, "fortytwo"))"));
|
||||
const char* query_str = "SELECT id, msg FROM test";
|
||||
|
||||
std::unique_ptr<SQLite::Statement> query{ new SQLite::Statement(db, query_str) };
|
||||
query->executeStep();
|
||||
|
||||
auto column0 = query->getColumn(0);
|
||||
auto column1 = query->getColumn(1);
|
||||
query.reset();
|
||||
|
||||
EXPECT_EQ(42, column0.getInt());
|
||||
EXPECT_STREQ("fortytwo", column1.getText());
|
||||
|
||||
query.reset(new SQLite::Statement(db, query_str));
|
||||
query->executeStep();
|
||||
column0 = query->getColumn(0);
|
||||
EXPECT_EQ(true, column0.isInteger());
|
||||
query->executeStep(); // query is done
|
||||
|
||||
// Undefined behavior
|
||||
// auto x = column0.getInt();
|
||||
|
||||
query.reset();
|
||||
|
||||
// Undefined behavior
|
||||
// auto x = column0.getInt();
|
||||
// bool isInt = column0.isInteger();
|
||||
|
||||
EXPECT_STREQ("id", column0.getName());
|
||||
}
|
638
third-party/SQLiteCpp/tests/Database_test.cpp
generated
vendored
638
third-party/SQLiteCpp/tests/Database_test.cpp
generated
vendored
@ -1,638 +0,0 @@
|
||||
/**
|
||||
* @file Database_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLiteCpp Database.
|
||||
*
|
||||
* Copyright (c) 2012-2021 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
|
||||
#include <sqlite3.h> // for SQLITE_ERROR and SQLITE_VERSION_NUMBER
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#ifdef SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
#include <filesystem>
|
||||
#endif // c++17
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
|
||||
#ifdef SQLITECPP_ENABLE_ASSERT_HANDLER
|
||||
namespace SQLite
|
||||
{
|
||||
/// definition of the assertion handler enabled when SQLITECPP_ENABLE_ASSERT_HANDLER is defined in the project (CMakeList.txt)
|
||||
void assertion_failed(const char* apFile, const long apLine, const char* apFunc, const char* apExpr, const char* apMsg)
|
||||
{
|
||||
// TODO: unit test that this assertion callback get called (already tested manually)
|
||||
std::cout << "assertion_failed(" << apFile << ", " << apLine << ", " << apFunc << ", " << apExpr << ", " << apMsg << ")\n";
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(SQLiteCpp, version)
|
||||
{
|
||||
EXPECT_STREQ(SQLITE_VERSION, SQLite::VERSION);
|
||||
EXPECT_EQ (SQLITE_VERSION_NUMBER, SQLite::VERSION_NUMBER);
|
||||
EXPECT_STREQ(SQLITE_VERSION, SQLite::getLibVersion());
|
||||
EXPECT_EQ (SQLITE_VERSION_NUMBER, SQLite::getLibVersionNumber());
|
||||
}
|
||||
|
||||
TEST(Database, ctorExecCreateDropExist)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open a non-existing database
|
||||
std::string filename = "test.db3";
|
||||
EXPECT_THROW(SQLite::Database not_found(filename), SQLite::Exception);
|
||||
|
||||
// Create a new database using a string or a std::filesystem::path if using c++17 and a
|
||||
// compatible compiler
|
||||
#ifdef SQLITECPP_HAVE_STD_FILESYSTEM
|
||||
SQLite::Database db(std::filesystem::path("test.db3"), SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
#else
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
#endif // have std::filesystem
|
||||
|
||||
EXPECT_STREQ("test.db3", db.getFilename().c_str());
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_FALSE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
|
||||
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_FALSE(db.tableExists(std::string("test")));
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
|
||||
SQLite::Database DatabaseBuilder(const char* apName)
|
||||
{
|
||||
return SQLite::Database(apName, SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
}
|
||||
|
||||
TEST(Database, moveConstructor)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Create a new database, using the move constructor
|
||||
SQLite::Database db = DatabaseBuilder("test.db3");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.getHandle() != NULL);
|
||||
SQLite::Database moved = std::move(db);
|
||||
EXPECT_TRUE(db.getHandle() == NULL);
|
||||
EXPECT_TRUE(moved.getHandle() != NULL);
|
||||
EXPECT_FALSE(moved.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
TEST(Database, createCloseReopen)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open the non-existing database
|
||||
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
|
||||
TEST(Database, inMemory)
|
||||
{
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
// Create a new database: not shared with the above db
|
||||
SQLite::Database db2(":memory:");
|
||||
EXPECT_FALSE(db2.tableExists("test"));
|
||||
} // Close an destroy DBs
|
||||
{
|
||||
// Create a new database: no more "test" table
|
||||
SQLite::Database db(":memory:");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
} // Close an destroy DB
|
||||
}
|
||||
|
||||
TEST(Database, backup)
|
||||
{
|
||||
// Create a new in-memory database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
|
||||
// Export the data into a file
|
||||
remove("backup.db3");
|
||||
EXPECT_NO_THROW(db.backup("backup.db3", SQLite::Database::Save));
|
||||
|
||||
// Trash the table
|
||||
db.exec("DROP TABLE test;");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
|
||||
// Import the data back from the file
|
||||
EXPECT_NO_THROW(db.backup("backup.db3", SQLite::Database::Load));
|
||||
remove("backup.db3");
|
||||
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
}
|
||||
|
||||
#if SQLITE_VERSION_NUMBER >= 3007015 // SQLite v3.7.15 is first version with PRAGMA busy_timeout
|
||||
TEST(Database, busyTimeout)
|
||||
{
|
||||
{
|
||||
// Create a new database with default timeout of 0ms
|
||||
SQLite::Database db(":memory:");
|
||||
// Busy timeout default to 0ms: any contention between threads or process leads to SQLITE_BUSY error
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Set a non null busy timeout: any contention between threads will leads to as much retry as possible during the time
|
||||
db.setBusyTimeout(5000);
|
||||
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Reset timeout to 0
|
||||
db.setBusyTimeout(0);
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
}
|
||||
{
|
||||
// Create a new database with a non null busy timeout
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE, 5000);
|
||||
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Reset timeout to null
|
||||
db.setBusyTimeout(0);
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
}
|
||||
{
|
||||
// Create a new database with a non null busy timeout
|
||||
const std::string memory = ":memory:";
|
||||
SQLite::Database db(memory, SQLite::OPEN_READWRITE, 5000);
|
||||
EXPECT_EQ(5000, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
|
||||
// Reset timeout to null
|
||||
db.setBusyTimeout(0);
|
||||
EXPECT_EQ(0, db.execAndGet("PRAGMA busy_timeout").getInt());
|
||||
}
|
||||
}
|
||||
#endif // SQLITE_VERSION_NUMBER >= 3007015
|
||||
|
||||
TEST(Database, exec)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
|
||||
// Create a new table with an explicit "id" column aliasing the underlying rowid
|
||||
// NOTE: here exec() returns 0 only because it is the first statements since database connexion,
|
||||
// but its return is an undefined value for "CREATE TABLE" statements.
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_EQ(0, db.getChanges());
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
EXPECT_EQ(0, db.getTotalChanges());
|
||||
|
||||
// first row : insert the "first" text value into new row of id 1
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
// second row : insert the "second" text value into new row of id 2
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\")"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
EXPECT_EQ(2, db.getTotalChanges());
|
||||
|
||||
// third row : insert the "third" text value into new row of id 3
|
||||
const std::string insert("INSERT INTO test VALUES (NULL, \"third\")");
|
||||
EXPECT_EQ(1, db.exec(insert));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(3, db.getLastInsertRowid());
|
||||
EXPECT_EQ(3, db.getTotalChanges());
|
||||
|
||||
// update the second row : update text value to "second_updated"
|
||||
EXPECT_EQ(1, db.exec("UPDATE test SET value=\"second-updated\" WHERE id='2'"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(3, db.getLastInsertRowid()); // last inserted row ID is still 3
|
||||
EXPECT_EQ(4, db.getTotalChanges());
|
||||
|
||||
// delete the third row
|
||||
EXPECT_EQ(1, db.exec("DELETE FROM test WHERE id='3'"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(3, db.getLastInsertRowid());
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// drop the whole table, ie the two remaining columns
|
||||
// NOTE: here exec() returns 1, like the last time, as it is an undefined value for "DROP TABLE" statements
|
||||
db.exec("DROP TABLE IF EXISTS test");
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// Re-Create the same table
|
||||
// NOTE: here exec() returns 1, like the last time, as it is an undefined value for "CREATE TABLE" statements
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// insert two rows with two *different* statements => returns only 1, ie. for the second INSERT statement
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\");INSERT INTO test VALUES (NULL, \"second\");"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
EXPECT_EQ(7, db.getTotalChanges());
|
||||
|
||||
#if (SQLITE_VERSION_NUMBER >= 3007011)
|
||||
// insert two rows with only one statement (starting with SQLite 3.7.11) => returns 2
|
||||
EXPECT_EQ(2, db.exec("INSERT INTO test VALUES (NULL, \"third\"), (NULL, \"fourth\");"));
|
||||
EXPECT_EQ(2, db.getChanges());
|
||||
EXPECT_EQ(4, db.getLastInsertRowid());
|
||||
EXPECT_EQ(9, db.getTotalChanges());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Database, tryExec)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
|
||||
// Create a new table with an explicit "id" column aliasing the underlying rowid
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_EQ(0, db.getChanges());
|
||||
EXPECT_EQ(0, db.getLastInsertRowid());
|
||||
EXPECT_EQ(0, db.getTotalChanges());
|
||||
|
||||
// first row : insert the "first" text value into new row of id 1
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
EXPECT_EQ(1, db.getTotalChanges());
|
||||
|
||||
// second row : insert the "second" text value into new row of id 2
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("INSERT INTO test VALUES (NULL, \"second\")"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
EXPECT_EQ(2, db.getTotalChanges());
|
||||
|
||||
// third row : insert the "third" text value into new row of id 3
|
||||
const std::string insert("INSERT INTO test VALUES (NULL, \"third\")");
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec(insert));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(3, db.getLastInsertRowid());
|
||||
EXPECT_EQ(3, db.getTotalChanges());
|
||||
|
||||
// update the second row : update text value to "second_updated"
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("UPDATE test SET value=\"second-updated\" WHERE id='2'"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(3, db.getLastInsertRowid()); // last inserted row ID is still 3
|
||||
EXPECT_EQ(4, db.getTotalChanges());
|
||||
|
||||
// delete the third row
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("DELETE FROM test WHERE id='3'"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(3, db.getLastInsertRowid());
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// drop the whole table, ie the two remaining columns
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("DROP TABLE IF EXISTS test"));
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// Re-Create the same table
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_EQ(5, db.getTotalChanges());
|
||||
|
||||
// insert two rows with two *different* statements => only 1 change, ie. for the second INSERT statement
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("INSERT INTO test VALUES (NULL, \"first\");INSERT INTO test VALUES (NULL, \"second\");"));
|
||||
EXPECT_EQ(1, db.getChanges());
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
EXPECT_EQ(7, db.getTotalChanges());
|
||||
|
||||
#if (SQLITE_VERSION_NUMBER >= 3007011)
|
||||
// insert two rows with only one statement (starting with SQLite 3.7.11)
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("INSERT INTO test VALUES (NULL, \"third\"), (NULL, \"fourth\");"));
|
||||
EXPECT_EQ(2, db.getChanges());
|
||||
EXPECT_EQ(4, db.getLastInsertRowid());
|
||||
EXPECT_EQ(9, db.getTotalChanges());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(Database, execAndGet)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
|
||||
// Create a new table with an explicit "id" column aliasing the underlying rowid
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT, weight INTEGER)");
|
||||
|
||||
// insert a few rows
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\", 5)"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\", 7)"));
|
||||
|
||||
// Get a single value result with an easy to use shortcut
|
||||
EXPECT_STREQ("second", db.execAndGet("SELECT value FROM test WHERE id=2"));
|
||||
EXPECT_STREQ("third", db.execAndGet("SELECT value FROM test WHERE weight=7"));
|
||||
const std::string query("SELECT weight FROM test WHERE value=\"first\"");
|
||||
EXPECT_EQ(3, db.execAndGet(query).getInt());
|
||||
}
|
||||
|
||||
TEST(Database, execException)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// exception with SQL error: "no such table"
|
||||
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("no such table: test", db.getErrorMsg());
|
||||
|
||||
// Create a new table
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT, weight INTEGER)");
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("not an error", db.getErrorMsg());
|
||||
|
||||
// exception with SQL error: "table test has 3 columns but 2 values were supplied"
|
||||
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, 3)"), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("table test has 3 columns but 2 values were supplied", db.getErrorMsg());
|
||||
|
||||
// exception with SQL error: "No row to get a column from"
|
||||
EXPECT_THROW(db.execAndGet("SELECT weight FROM test WHERE value=\"first\""), SQLite::Exception);
|
||||
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
|
||||
// exception with SQL error: "No row to get a column from"
|
||||
EXPECT_THROW(db.execAndGet("SELECT weight FROM test WHERE value=\"second\""), SQLite::Exception);
|
||||
|
||||
// Add a row with more values than columns in the table: "table test has 3 columns but 4 values were supplied"
|
||||
EXPECT_THROW(db.exec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"), SQLite::Exception);
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("table test has 3 columns but 4 values were supplied", db.getErrorMsg());
|
||||
}
|
||||
|
||||
TEST(Database, tryExecError)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
|
||||
// Insert into nonexistent table: "no such table"
|
||||
EXPECT_EQ(SQLITE_ERROR, db.tryExec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("no such table: test", db.getErrorMsg());
|
||||
|
||||
// Create a new table
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT, weight INTEGER)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
EXPECT_EQ(SQLite::OK, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("not an error", db.getErrorMsg());
|
||||
|
||||
// Add a row with fewer values than columns in the table: "table test has 3 columns but 2 values were supplied"
|
||||
EXPECT_EQ(SQLITE_ERROR, db.tryExec("INSERT INTO test VALUES (NULL, 3)"));
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("table test has 3 columns but 2 values were supplied", db.getErrorMsg());
|
||||
|
||||
// Add a row with more values than columns in the table: "table test has 3 columns but 4 values were supplied"
|
||||
EXPECT_EQ(SQLITE_ERROR, db.tryExec("INSERT INTO test VALUES (NULL, \"first\", 123, 0.123)"));
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_ERROR, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("table test has 3 columns but 4 values were supplied", db.getErrorMsg());
|
||||
|
||||
// Create a first row
|
||||
EXPECT_EQ(SQLite::OK, db.tryExec("INSERT INTO test VALUES (NULL, \"first\", 3)"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
|
||||
// Try to insert a new row with the same PRIMARY KEY: "UNIQUE constraint failed: test.id"
|
||||
EXPECT_EQ(SQLITE_CONSTRAINT, db.tryExec("INSERT INTO test VALUES (1, \"impossible\", 456)"));
|
||||
EXPECT_EQ(SQLITE_CONSTRAINT, db.getErrorCode());
|
||||
EXPECT_EQ(SQLITE_CONSTRAINT_PRIMARYKEY, db.getExtendedErrorCode());
|
||||
EXPECT_STREQ("UNIQUE constraint failed: test.id", db.getErrorMsg());
|
||||
}
|
||||
|
||||
// From https://stackoverflow.com/a/8283265/1163698 How can I create a user-defined function in SQLite?
|
||||
static void firstchar(sqlite3_context *context, int argc, sqlite3_value **argv)
|
||||
{
|
||||
if (argc == 1)
|
||||
{
|
||||
const unsigned char *text = sqlite3_value_text(argv[0]);
|
||||
if (text && text[0])
|
||||
{
|
||||
char result[2];
|
||||
result[0] = text[0]; result[1] = '\0';
|
||||
sqlite3_result_text(context, result, -1, SQLITE_TRANSIENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
sqlite3_result_null(context);
|
||||
}
|
||||
|
||||
TEST(Database, createFunction)
|
||||
{
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\")"));
|
||||
|
||||
// exception with SQL error: "no such function: firstchar"
|
||||
EXPECT_THROW(db.exec("SELECT firstchar(value) FROM test WHERE id=1"), SQLite::Exception);
|
||||
|
||||
db.createFunction("firstchar", 1, true, nullptr, &firstchar, nullptr, nullptr, nullptr);
|
||||
|
||||
EXPECT_EQ(1, db.exec("SELECT firstchar(value) FROM test WHERE id=1"));
|
||||
}
|
||||
|
||||
TEST(Database, loadExtension)
|
||||
{
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE);
|
||||
|
||||
// Try to load a non-existing extension (no dynamic library found)
|
||||
EXPECT_THROW(db.loadExtension("non-existing-extension", "entry-point"), SQLite::Exception);
|
||||
|
||||
// TODO: test a proper extension
|
||||
}
|
||||
|
||||
TEST(Database, getHeaderInfo)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Call without passing a database file name
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo(""),SQLite::Exception);
|
||||
|
||||
// Call with a non-existent database
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo("test.db3"), SQLite::Exception);
|
||||
|
||||
// Simulate an incomplete header by writing garbage to a file
|
||||
{
|
||||
const unsigned char badData[] = "garbage...";
|
||||
const char* pBadData = reinterpret_cast<const char*>(&badData[0]);
|
||||
|
||||
remove("short.db3");
|
||||
std::ofstream corruptDb;
|
||||
corruptDb.open("short.db3", std::ios::app | std::ios::binary);
|
||||
corruptDb.write(pBadData, sizeof(badData));
|
||||
corruptDb.close();
|
||||
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo("short.db3"), SQLite::Exception);
|
||||
remove("short.db3");
|
||||
}
|
||||
|
||||
// Simulate a corrupt header by writing garbage to a file
|
||||
{
|
||||
const unsigned char badData[100] = "garbage...";
|
||||
const char* pBadData = reinterpret_cast<const char*>(&badData[0]);
|
||||
|
||||
remove("corrupt.db3");
|
||||
std::ofstream corruptDb;
|
||||
corruptDb.open("corrupt.db3", std::ios::app | std::ios::binary);
|
||||
corruptDb.write(pBadData, sizeof(badData));
|
||||
corruptDb.close();
|
||||
|
||||
EXPECT_THROW(SQLite::Database::getHeaderInfo("corrupt.db3"), SQLite::Exception);
|
||||
remove("corrupt.db3");
|
||||
}
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
|
||||
// Set assorted SQLite header values using associated PRAGMA
|
||||
db.exec("PRAGMA main.user_version = 12345");
|
||||
db.exec("PRAGMA main.application_id = 2468");
|
||||
|
||||
// Parse header fields from test database
|
||||
const SQLite::Header h = db.getHeaderInfo();
|
||||
|
||||
//Test header values explicitly set via PRAGMA statements
|
||||
EXPECT_EQ(h.userVersion, 12345);
|
||||
EXPECT_EQ(h.applicationId, 2468);
|
||||
|
||||
//Test header values with expected default values
|
||||
EXPECT_EQ(h.pageSizeBytes, 4096);
|
||||
EXPECT_EQ(h.fileFormatWriteVersion,1);
|
||||
EXPECT_EQ(h.fileFormatReadVersion,1);
|
||||
EXPECT_EQ(h.reservedSpaceBytes,0);
|
||||
EXPECT_EQ(h.maxEmbeddedPayloadFrac, 64);
|
||||
EXPECT_EQ(h.minEmbeddedPayloadFrac, 32);
|
||||
EXPECT_EQ(h.leafPayloadFrac, 32);
|
||||
EXPECT_EQ(h.fileChangeCounter, 3);
|
||||
EXPECT_EQ(h.databaseSizePages, 2);
|
||||
EXPECT_EQ(h.firstFreelistTrunkPage, 0);
|
||||
EXPECT_EQ(h.totalFreelistPages, 0);
|
||||
EXPECT_EQ(h.schemaCookie, 1);
|
||||
EXPECT_EQ(h.schemaFormatNumber, 4);
|
||||
EXPECT_EQ(h.defaultPageCacheSizeBytes, 0);
|
||||
EXPECT_EQ(h.largestBTreePageNumber, 0);
|
||||
EXPECT_EQ(h.databaseTextEncoding, 1);
|
||||
EXPECT_EQ(h.incrementalVaccumMode, 0);
|
||||
EXPECT_EQ(h.versionValidFor, 3);
|
||||
EXPECT_EQ(h.sqliteVersion, SQLITE_VERSION_NUMBER);
|
||||
}
|
||||
remove("test.db3");
|
||||
}
|
||||
|
||||
#ifdef SQLITE_HAS_CODEC
|
||||
TEST(Database, encryptAndDecrypt)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open the non-existing database
|
||||
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Database::isUnencrypted("test.db3"), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Database::isUnencrypted(""), SQLite::Exception);
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and encrypt it
|
||||
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
// Encrypt the database
|
||||
db.rekey("123secret");
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and try to use it
|
||||
EXPECT_FALSE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READONLY);
|
||||
EXPECT_THROW(db.tableExists("test"), SQLite::Exception);
|
||||
db.key("123secret");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and decrypt it
|
||||
EXPECT_FALSE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
// Decrypt the database
|
||||
db.key("123secret");
|
||||
db.rekey("");
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and use it
|
||||
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
#else // SQLITE_HAS_CODEC
|
||||
TEST(Database, encryptAndDecrypt)
|
||||
{
|
||||
remove("test.db3");
|
||||
{
|
||||
// Try to open the non-existing database
|
||||
EXPECT_THROW(SQLite::Database not_found("test.db3"), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Database::isUnencrypted("test.db3"), SQLite::Exception);
|
||||
EXPECT_THROW(SQLite::Database::isUnencrypted(""), SQLite::Exception);
|
||||
|
||||
// Create a new database
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_FALSE(db.tableExists("test"));
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)");
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
} // Close DB test.db3
|
||||
{
|
||||
// Reopen the database file and encrypt it
|
||||
EXPECT_TRUE(SQLite::Database::isUnencrypted("test.db3"));
|
||||
SQLite::Database db("test.db3", SQLite::OPEN_READWRITE);
|
||||
// Encrypt the database
|
||||
EXPECT_THROW(db.key("123secret"), SQLite::Exception);
|
||||
EXPECT_THROW(db.rekey("123secret"), SQLite::Exception);
|
||||
} // Close DB test.db3
|
||||
remove("test.db3");
|
||||
}
|
||||
#endif // SQLITE_HAS_CODEC
|
89
third-party/SQLiteCpp/tests/Exception_test.cpp
generated
vendored
89
third-party/SQLiteCpp/tests/Exception_test.cpp
generated
vendored
@ -1,89 +0,0 @@
|
||||
/**
|
||||
* @file Transaction_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLite Transaction.
|
||||
*
|
||||
* Copyright (c) 2012-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
TEST(Exception, copy)
|
||||
{
|
||||
const SQLite::Exception ex1("some error", 2);
|
||||
const SQLite::Exception ex2 = ex1;
|
||||
EXPECT_STREQ(ex1.what(), ex2.what());
|
||||
EXPECT_EQ(ex1.getErrorCode(), ex2.getErrorCode());
|
||||
EXPECT_EQ(ex1.getExtendedErrorCode(), ex2.getExtendedErrorCode());
|
||||
}
|
||||
|
||||
// see http://eel.is/c++draft/exception#2 or http://www.cplusplus.com/reference/exception/exception/operator=/
|
||||
// an assignment operator is expected to be avaiable
|
||||
TEST(Exception, assignment)
|
||||
{
|
||||
const char message[] = "some error";
|
||||
const SQLite::Exception ex1(message, 1);
|
||||
SQLite::Exception ex2("another error", 2);
|
||||
|
||||
ex2 = ex1;
|
||||
|
||||
EXPECT_STREQ(ex2.what(), message);
|
||||
EXPECT_EQ(ex2.getErrorCode(), 1);
|
||||
EXPECT_EQ(ex2.getExtendedErrorCode(), -1);
|
||||
EXPECT_STREQ(ex2.getErrorStr(), "SQL logic error");
|
||||
}
|
||||
|
||||
TEST(Exception, throw_catch)
|
||||
{
|
||||
const char message[] = "some error";
|
||||
try
|
||||
{
|
||||
throw SQLite::Exception(message);
|
||||
}
|
||||
catch (const std::runtime_error& ex)
|
||||
{
|
||||
EXPECT_STREQ(ex.what(), message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(Exception, constructor)
|
||||
{
|
||||
const char msg1[] = "some error";
|
||||
std::string msg2 = "another error";
|
||||
{
|
||||
const SQLite::Exception ex(msg1);
|
||||
EXPECT_STREQ(ex.what(), msg1);
|
||||
EXPECT_EQ(ex.getErrorCode(), -1);
|
||||
EXPECT_EQ(ex.getExtendedErrorCode(), -1);
|
||||
EXPECT_STREQ("unknown error", ex.getErrorStr());
|
||||
}
|
||||
{
|
||||
const SQLite::Exception ex(msg2);
|
||||
EXPECT_STREQ(ex.what(), msg2.c_str());
|
||||
EXPECT_EQ(ex.getErrorCode(), -1);
|
||||
EXPECT_EQ(ex.getExtendedErrorCode(), -1);
|
||||
EXPECT_STREQ("unknown error", ex.getErrorStr());
|
||||
}
|
||||
{
|
||||
const SQLite::Exception ex(msg1, 1);
|
||||
EXPECT_STREQ(ex.what(), msg1);
|
||||
EXPECT_EQ(ex.getErrorCode(), 1);
|
||||
EXPECT_EQ(ex.getExtendedErrorCode(), -1);
|
||||
EXPECT_STREQ(ex.getErrorStr(), "SQL logic error");
|
||||
}
|
||||
{
|
||||
const SQLite::Exception ex(msg2, 2);
|
||||
EXPECT_STREQ(ex.what(), msg2.c_str());
|
||||
EXPECT_EQ(ex.getErrorCode(), 2);
|
||||
EXPECT_EQ(ex.getExtendedErrorCode(), -1);
|
||||
EXPECT_STREQ(ex.getErrorStr(), "unknown error");
|
||||
}
|
||||
}
|
54
third-party/SQLiteCpp/tests/ExecuteMany_test.cpp
generated
vendored
54
third-party/SQLiteCpp/tests/ExecuteMany_test.cpp
generated
vendored
@ -1,54 +0,0 @@
|
||||
/**
|
||||
* @file VariadicBind_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of variadic bind
|
||||
*
|
||||
* Copyright (c) 2019 Maximilian Bachmann (contact@maxbachmann.de)
|
||||
* Copyright (c) 2019-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/ExecuteMany.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
TEST(ExecuteMany, invalid)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
|
||||
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT DEFAULT 'default')"));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
{
|
||||
execute_many(db, "INSERT INTO test VALUES (?, ?)",
|
||||
1,
|
||||
std::make_tuple(2),
|
||||
std::make_tuple(3, "three")
|
||||
);
|
||||
}
|
||||
// make sure the content is as expected
|
||||
{
|
||||
SQLite::Statement query(db, std::string{"SELECT id, value FROM test ORDER BY id"});
|
||||
std::vector<std::pair<int, std::string> > results;
|
||||
while (query.executeStep())
|
||||
{
|
||||
const int id = query.getColumn(0);
|
||||
std::string value = query.getColumn(1);
|
||||
results.emplace_back( id, std::move(value) );
|
||||
}
|
||||
EXPECT_EQ(std::size_t(3), results.size());
|
||||
|
||||
EXPECT_EQ(std::make_pair(1,std::string{""}), results.at(0));
|
||||
EXPECT_EQ(std::make_pair(2,std::string{""}), results.at(1));
|
||||
EXPECT_EQ(std::make_pair(3,std::string{"three"}), results.at(2));
|
||||
}
|
||||
}
|
||||
#endif // c++14
|
108
third-party/SQLiteCpp/tests/Savepoint_test.cpp
generated
vendored
108
third-party/SQLiteCpp/tests/Savepoint_test.cpp
generated
vendored
@ -1,108 +0,0 @@
|
||||
/**
|
||||
* @file Savepoint_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLite Savepoint.
|
||||
*
|
||||
* Copyright (c) 2020 Kelvin Hammond (hammond.kelvin@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt or
|
||||
* copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
#include <SQLiteCpp/Savepoint.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Transaction.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
TEST(Savepoint, commitRollback) {
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:",
|
||||
SQLite::OPEN_READWRITE | SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
{
|
||||
// Begin savepoint
|
||||
SQLite::Savepoint savepoint(db, "sp1");
|
||||
|
||||
EXPECT_EQ(
|
||||
0,
|
||||
db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Insert a first valu
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 'first')"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
|
||||
// release savepoint
|
||||
savepoint.release();
|
||||
|
||||
// Commit again throw an exception
|
||||
EXPECT_THROW(savepoint.release(), SQLite::Exception);
|
||||
EXPECT_THROW(savepoint.rollback(), SQLite::Exception);
|
||||
}
|
||||
|
||||
// Auto rollback if no release() before the end of scope
|
||||
{
|
||||
// Begin savepoint
|
||||
SQLite::Savepoint savepoint(db, "sp2");
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 'third')"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// end of scope: automatic rollback
|
||||
}
|
||||
|
||||
// Auto rollback of a transaction on error / exception
|
||||
try {
|
||||
// Begin savepoint
|
||||
SQLite::Savepoint savepoint(db, "sp3");
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 'second')"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// Execute with an error => exception with auto-rollback
|
||||
db.exec(
|
||||
"DesiredSyntaxError to raise an exception to rollback the "
|
||||
"transaction");
|
||||
|
||||
GTEST_FATAL_FAILURE_("we should never get there");
|
||||
savepoint.release(); // We should never get there
|
||||
} catch (std::exception& e) {
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
// expected error, see above
|
||||
}
|
||||
|
||||
// Double rollback with a manual command before the end of scope
|
||||
{
|
||||
// Begin savepoint
|
||||
SQLite::Savepoint savepoint(db, "sp4");
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, 'third')"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// Execute a manual rollback (no real use case I can think of, so no
|
||||
// rollback() method)
|
||||
db.exec("ROLLBACK");
|
||||
|
||||
// end of scope: the automatic rollback should not raise an error
|
||||
// because it is harmless
|
||||
}
|
||||
|
||||
// Check the results (expect only one row of result, as all other one have
|
||||
// been rollbacked)
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
int nbRows = 0;
|
||||
while (query.executeStep()) {
|
||||
nbRows++;
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText());
|
||||
}
|
||||
EXPECT_EQ(1, nbRows);
|
||||
}
|
1028
third-party/SQLiteCpp/tests/Statement_test.cpp
generated
vendored
1028
third-party/SQLiteCpp/tests/Statement_test.cpp
generated
vendored
File diff suppressed because it is too large
Load Diff
118
third-party/SQLiteCpp/tests/Transaction_test.cpp
generated
vendored
118
third-party/SQLiteCpp/tests/Transaction_test.cpp
generated
vendored
@ -1,118 +0,0 @@
|
||||
/**
|
||||
* @file Transaction_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of a SQLite Transaction.
|
||||
*
|
||||
* Copyright (c) 2012-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Transaction.h>
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/Exception.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
TEST(Transaction, commitRollback)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
EXPECT_EQ(0, db.exec("CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT)"));
|
||||
EXPECT_EQ(SQLite::OK, db.getErrorCode());
|
||||
|
||||
// Insert a first value
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"first\")"));
|
||||
EXPECT_EQ(1, db.getLastInsertRowid());
|
||||
|
||||
// Commit transaction
|
||||
transaction.commit();
|
||||
|
||||
// Commit again throw an exception
|
||||
EXPECT_THROW(transaction.commit(), SQLite::Exception);
|
||||
}
|
||||
|
||||
// ensure transactions with different types are well-formed
|
||||
{
|
||||
for (auto behavior : {
|
||||
SQLite::TransactionBehavior::DEFERRED,
|
||||
SQLite::TransactionBehavior::IMMEDIATE,
|
||||
SQLite::TransactionBehavior::EXCLUSIVE })
|
||||
{
|
||||
SQLite::Transaction transaction(db, behavior);
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
EXPECT_THROW(SQLite::Transaction(db, static_cast<SQLite::TransactionBehavior>(-1)), SQLite::Exception);
|
||||
}
|
||||
|
||||
// Auto rollback if no commit() before the end of scope
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\")"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// end of scope: automatic rollback
|
||||
}
|
||||
|
||||
// Auto rollback of a transaction on error/exception
|
||||
try
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"second\")"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// Execute with an error => exception with auto-rollback
|
||||
db.exec("DesiredSyntaxError to raise an exception to rollback the transaction");
|
||||
|
||||
GTEST_FATAL_FAILURE_("we should never get there");
|
||||
transaction.commit(); // We should never get there
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "SQLite exception: " << e.what() << std::endl;
|
||||
// expected error, see above
|
||||
}
|
||||
|
||||
// Double rollback with a manual command before the end of scope
|
||||
{
|
||||
// Begin transaction
|
||||
SQLite::Transaction transaction(db);
|
||||
|
||||
// Insert a second value (that will be rollbacked)
|
||||
EXPECT_EQ(1, db.exec("INSERT INTO test VALUES (NULL, \"third\")"));
|
||||
EXPECT_EQ(2, db.getLastInsertRowid());
|
||||
|
||||
// Execute a manual rollback (no real use case I can think of, so no rollback() method)
|
||||
db.exec("ROLLBACK");
|
||||
|
||||
// end of scope: the automatic rollback should not raise an error because it is harmless
|
||||
}
|
||||
|
||||
// Check the results (expect only one row of result, as all other one have been rollbacked)
|
||||
SQLite::Statement query(db, "SELECT * FROM test");
|
||||
int nbRows = 0;
|
||||
while (query.executeStep())
|
||||
{
|
||||
nbRows++;
|
||||
EXPECT_EQ(1, query.getColumn(0).getInt());
|
||||
EXPECT_STREQ("first", query.getColumn(1).getText());
|
||||
}
|
||||
EXPECT_EQ(1, nbRows);
|
||||
}
|
109
third-party/SQLiteCpp/tests/VariadicBind_test.cpp
generated
vendored
109
third-party/SQLiteCpp/tests/VariadicBind_test.cpp
generated
vendored
@ -1,109 +0,0 @@
|
||||
/**
|
||||
* @file VariadicBind_test.cpp
|
||||
* @ingroup tests
|
||||
* @brief Test of variadic bind
|
||||
*
|
||||
* Copyright (c) 2016 Paul Dreik (github@pauldreik.se)
|
||||
* Copyright (c) 2016-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
|
||||
* Copyright (c) 2019 Maximilian Bachmann (github@maxbachmann)
|
||||
*
|
||||
* Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
|
||||
* or copy at http://opensource.org/licenses/MIT)
|
||||
*/
|
||||
|
||||
#include <SQLiteCpp/Database.h>
|
||||
#include <SQLiteCpp/Statement.h>
|
||||
#include <SQLiteCpp/VariadicBind.h>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#if (__cplusplus >= 201103L) || ( defined(_MSC_VER) && (_MSC_VER >= 1800) ) // c++11: Visual Studio 2013
|
||||
TEST(VariadicBind, invalid)
|
||||
{
|
||||
// Create a new database
|
||||
SQLite::Database db(":memory:", SQLite::OPEN_READWRITE|SQLite::OPEN_CREATE);
|
||||
|
||||
EXPECT_EQ(0, db.exec("DROP TABLE IF EXISTS test"));
|
||||
EXPECT_EQ(0,
|
||||
db.exec(
|
||||
"CREATE TABLE test (id INTEGER PRIMARY KEY, value TEXT DEFAULT 'default') "));
|
||||
EXPECT_EQ(0,
|
||||
db.exec(
|
||||
"CREATE TABLE test2 (id INTEGER PRIMARY KEY, value TEXT DEFAULT 'default') "));
|
||||
EXPECT_TRUE(db.tableExists("test"));
|
||||
EXPECT_TRUE(db.tableExists("test2"));
|
||||
|
||||
{
|
||||
SQLite::Statement query(db, "INSERT INTO test VALUES (?, ?)");
|
||||
|
||||
// bind one argument less than expected - should be fine.
|
||||
// the unspecified argument should be set to null, not the default.
|
||||
SQLite::bind(query, 1);
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind all arguments - should work just fine
|
||||
SQLite::bind(query, 2, "two");
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind too many arguments - should throw.
|
||||
EXPECT_THROW(SQLite::bind(query, 3, "three", 0), SQLite::Exception);
|
||||
EXPECT_EQ(1, query.exec());
|
||||
}
|
||||
// make sure the content is as expected
|
||||
{
|
||||
SQLite::Statement query(db, std::string{"SELECT id, value FROM test ORDER BY id"});
|
||||
std::vector<std::pair<int, std::string> > results;
|
||||
while (query.executeStep())
|
||||
{
|
||||
const int id = query.getColumn(0);
|
||||
std::string value = query.getColumn(1);
|
||||
results.emplace_back( id, std::move(value) );
|
||||
}
|
||||
EXPECT_EQ(std::size_t(3), results.size());
|
||||
|
||||
EXPECT_EQ(std::make_pair(1,std::string{""}), results.at(0));
|
||||
EXPECT_EQ(std::make_pair(2,std::string{"two"}), results.at(1));
|
||||
EXPECT_EQ(std::make_pair(3,std::string{"three"}), results.at(2));
|
||||
}
|
||||
#if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
|
||||
{
|
||||
SQLite::Statement query(db, "INSERT INTO test2 VALUES (?, ?)");
|
||||
|
||||
// bind one argument less than expected - should be fine.
|
||||
// the unspecified argument should be set to null, not the default.
|
||||
SQLite::bind(query, std::make_tuple(1));
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind all arguments - should work just fine
|
||||
SQLite::bind(query, std::make_tuple(2, "two"));
|
||||
EXPECT_EQ(1, query.exec());
|
||||
query.reset();
|
||||
|
||||
// bind too many arguments - should throw.
|
||||
EXPECT_THROW(SQLite::bind(query, std::make_tuple(3, "three", 0)), SQLite::Exception);
|
||||
EXPECT_EQ(1, query.exec());
|
||||
}
|
||||
// make sure the content is as expected
|
||||
{
|
||||
SQLite::Statement query(db, std::string{"SELECT id, value FROM test2 ORDER BY id"});
|
||||
std::vector<std::pair<int, std::string> > results;
|
||||
while (query.executeStep())
|
||||
{
|
||||
const int id = query.getColumn(0);
|
||||
std::string value = query.getColumn(1);
|
||||
results.emplace_back( id, std::move(value) );
|
||||
}
|
||||
EXPECT_EQ(std::size_t(3), results.size());
|
||||
|
||||
EXPECT_EQ(std::make_pair(1,std::string{""}), results.at(0));
|
||||
EXPECT_EQ(std::make_pair(2,std::string{"two"}), results.at(1));
|
||||
EXPECT_EQ(std::make_pair(3,std::string{"three"}), results.at(2));
|
||||
}
|
||||
#endif // c++14
|
||||
}
|
||||
#endif // c++11
|
29
third-party/sqlite3/CMakeLists.txt
generated
vendored
Normal file
29
third-party/sqlite3/CMakeLists.txt
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
add_library(sqlite3
|
||||
sqlite3.c
|
||||
sqlite3.h
|
||||
)
|
||||
|
||||
if (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
|
||||
set_target_properties(sqlite3 PROPERTIES COMPILE_FLAGS "-fPIC")
|
||||
|
||||
# Put each function in its own section to allow the linker garbage
|
||||
# collection to remove unused section and produced a smaller
|
||||
# statically-lined executables.
|
||||
target_compile_options(sqlite3 PRIVATE "-ffunction-sections")
|
||||
endif (UNIX AND (CMAKE_COMPILER_IS_GNUCXX OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang"))
|
||||
|
||||
if (UNIX AND CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
||||
target_compile_options(sqlite3 PRIVATE "-Wimplicit-fallthrough=0")
|
||||
endif()
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
|
||||
target_compile_options(sqlite3 PRIVATE "-Wno-cast-function-type")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Link target with pthread and dl for Unix
|
||||
if (UNIX)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
target_link_libraries(sqlite3 PUBLIC Threads::Threads ${CMAKE_DL_LIBS})
|
||||
endif (UNIX)
|
18
third-party/sqlite3/LICENSE
generated
vendored
Normal file
18
third-party/sqlite3/LICENSE
generated
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
SQLite Is Public Domain
|
||||
|
||||
All of the code and documentation in SQLite has been dedicated to the public domain by the authors.
|
||||
All code authors, and representatives of the companies they work for, have signed affidavits dedicating
|
||||
their contributions to the public domain and originals of those signed affidavits are stored in a firesafe
|
||||
at the main offices of Hwaci. All contributors are citizens of countries that allow creative works to be
|
||||
dedicated into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute
|
||||
the original SQLite code, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means.
|
||||
|
||||
The previous paragraph applies to the deliverable code and documentation in SQLite - those parts of the SQLite
|
||||
library that you actually bundle and ship with a larger application. Some scripts used as part of the build
|
||||
process (for example the "configure" scripts generated by autoconf) might fall under other open-source licenses.
|
||||
Nothing from these build scripts ever reaches the final deliverable SQLite library, however, and so the licenses
|
||||
associated with those scripts should not be a factor in assessing your rights to copy and use the SQLite library.
|
||||
|
||||
All of the deliverable code in SQLite has been written from scratch. No code has been taken from other projects
|
||||
or from the open internet. Every line of code can be traced back to its original author, and all of those authors
|
||||
have public domain dedications on file. So the SQLite code base is clean and is uncontaminated with licensed code from other projects.
|
28032
third-party/sqlite3/shell.c
generated
vendored
Normal file
28032
third-party/sqlite3/shell.c
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user