diff --git a/.gitmodules b/.gitmodules index 43dde67..1fef3b2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "vendor/libzip"] path = vendor/libzip - url = https://github.com/nih-at/libzip + url = https://github.com/nih-at/libzip \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index be6f2ac..efd25b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,6 @@ cmake_minimum_required(VERSION 3.10) +SET(CXX_STANDARD 17) + project(AnkiParser) diff --git a/ankiparser/CMakeLists.txt b/ankiparser/CMakeLists.txt index d19937f..db2396c 100644 --- a/ankiparser/CMakeLists.txt +++ b/ankiparser/CMakeLists.txt @@ -1,3 +1,5 @@ +find_package(sqlite3 REQUIRED) + file(GLOB_RECURSE target_src "src/*.cpp" ) @@ -14,8 +16,10 @@ add_library(ankiparser STATIC target_include_directories(ankiparser PUBLIC include libzip::zip + ${SQLite3_INCLUDE_DIR} ) target_link_libraries(ankiparser PUBLIC libzip::zip + ${SQLite3_LIBRARY} ) \ No newline at end of file diff --git a/ankiparser/include/Package.hpp b/ankiparser/include/Package.hpp index 9389bd2..2aef327 100644 --- a/ankiparser/include/Package.hpp +++ b/ankiparser/include/Package.hpp @@ -2,6 +2,8 @@ #include +struct sqlite3; + namespace Anki { class Package @@ -14,6 +16,12 @@ namespace Anki int Open(const std::string& filename); private: - char* collection; + void DumpAnki2File(const char* raw, size_t size); + + private: + sqlite3* collection; + std::string tmpDbName; + + static bool sqlite_init; }; } \ No newline at end of file diff --git a/ankiparser/src/Package.cpp b/ankiparser/src/Package.cpp index a6d8c9a..0a1cc27 100644 --- a/ankiparser/src/Package.cpp +++ b/ankiparser/src/Package.cpp @@ -1,12 +1,33 @@ #include "Package.hpp" #include +#include + #include +#include + +bool Anki::Package::sqlite_init = false; + +static int callback(void* NotUsed, int argc, char** argv, char** azColName) +{ + for (int i = 0; i < argc; i++) + { + std::cout << argv[i] << "\t"; + } + std::cout << std::endl; + return 0; +} namespace Anki { Package::Package() : collection(nullptr) { + if (!sqlite_init) + { + srand(time(NULL)); + sqlite3_initialize(); + sqlite_init = true; + } } Package::Package(const std::string& filename) : @@ -17,7 +38,7 @@ namespace Anki Package::~Package() { - if (collection != nullptr) delete collection; + sqlite3_close(collection); } int Package::Open(const std::string& filename) @@ -31,16 +52,46 @@ namespace Anki zip_stat_init(&st); zip_stat(archive, collection_filename, 0, &st); - collection = new char[st.size]; + char* collection_raw = new char[st.size]; zip_file* collection_file = zip_fopen(archive, collection_filename, 0); - zip_fread(collection_file, collection, st.size); + zip_fread(collection_file, collection_raw, st.size); zip_fclose(collection_file); zip_close(archive); - std::cout << collection << std::endl; + DumpAnki2File(collection_raw, st.size); + + delete[] collection_raw; return err; } + + void Package::DumpAnki2File(const char* raw, size_t size) + { + // SQLite is kinda stupid and can't create a database from data stored in memory. + // It insists on opening a database file instead. I don't see a way around that unfortunately + // So I have to dump the database into a file first + // tmpDbName = std::to_string(rand()) + ".db"; + tmpDbName = "test.db"; + std::ofstream tmp_db(tmpDbName, std::ios::binary); + tmp_db.write(raw, size); + tmp_db.close(); + + + + int result = sqlite3_open(tmpDbName.c_str(), &collection); + if (result) + { + std::cerr << result << std::endl; + return; + } + + char* errMsg = nullptr; + result = sqlite3_exec(collection, "SELECT decks FROM col;", callback, 0, &errMsg); + if (result != SQLITE_OK) + { + std::cerr << errMsg << std::endl; + } + } } \ No newline at end of file diff --git a/examples/test.cpp b/examples/test.cpp index 8cebb56..d7b278a 100644 --- a/examples/test.cpp +++ b/examples/test.cpp @@ -1,6 +1,7 @@ #include #include #include +#include int main(int argc, char** argv) {