From af49d3435302118d036c512aef1def848fb88089 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Tue, 27 Mar 2018 17:13:37 -0400 Subject: Migrated to hkutil --- .gitmodules | 3 + CMakeLists.txt | 3 +- cadence.cpp | 58 ++++---------- generator/CMakeLists.txt | 8 +- generator/database.cpp | 173 ------------------------------------------ generator/database.h | 73 ------------------ generator/field.cpp | 193 ----------------------------------------------- generator/field.h | 76 ------------------- generator/generator.cpp | 27 +++---- generator/generator.h | 4 +- generator/progress.h | 56 -------------- util.h | 74 ------------------ vendor/hkutil | 1 + 13 files changed, 42 insertions(+), 707 deletions(-) delete mode 100644 generator/database.cpp delete mode 100644 generator/database.h delete mode 100644 generator/field.cpp delete mode 100644 generator/field.h delete mode 100644 generator/progress.h delete mode 100644 util.h create mode 160000 vendor/hkutil diff --git a/.gitmodules b/.gitmodules index e1d506f..b51cbff 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "vendor/libtwittercpp"] path = vendor/libtwittercpp url = https://github.com/hatkirby/libtwittercpp +[submodule "vendor/hkutil"] + path = vendor/hkutil + url = git@github.com:hatkirby/hkutil diff --git a/CMakeLists.txt b/CMakeLists.txt index 4345e90..a64833d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,8 @@ add_subdirectory(vendor/libtwittercpp) include_directories( ${sqlite3_INCLUDE_DIR} vendor/libtwittercpp/src - ${yaml-cpp_INCLUDE_DIRS}) + ${yaml-cpp_INCLUDE_DIRS} + vendor/hkutil) add_executable(cadence cadence.cpp) set_property(TARGET cadence PROPERTY CXX_STANDARD 11) diff --git a/cadence.cpp b/cadence.cpp index 80e4a05..704f946 100644 --- a/cadence.cpp +++ b/cadence.cpp @@ -10,7 +10,8 @@ #include #include #include -#include "util.h" +#include +#include const std::vector moods = {"party", "chill", "crazy", "happy", "sad", "instrumental", "vocal"}; @@ -72,19 +73,9 @@ int main(int argc, char** argv) std::mt19937 random_engine{random_device()}; // Connect to the AcousticBrainz data file. - sqlite3* ppdb = nullptr; - - if (sqlite3_open_v2(config["acoustic_datafile"].as().c_str(), &ppdb, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK) - { - // We still have to free the resources allocated. In the event that - // allocation failed, ppdb will be null and sqlite3_close_v2 will just - // ignore it. - sqlite3_close_v2(ppdb); - - std::cout << "Could not open acoustic datafile." << std::endl; - - return 1; - } + hatkirby::database abdb( + config["acoustic_datafile"].as(), + hatkirby::dbmode::read); for (;;) { @@ -92,36 +83,15 @@ int main(int argc, char** argv) std::string mood = moods[std::uniform_int_distribution(0, moods.size()-1)(random_engine)]; - std::string songTitle; - std::string songArtist; - - sqlite3_stmt* ppstmt; - std::string query = "SELECT title, artist FROM songs WHERE category = ? ORDER BY RANDOM() LIMIT 1"; - - if (sqlite3_prepare_v2(ppdb, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - std::cout << "Error reading from acoustic datafile:" << std::endl; - std::cout << sqlite3_errmsg(ppdb) << std::endl; - - return 1; - } - - sqlite3_bind_text(ppstmt, 1, mood.c_str(), mood.length(), SQLITE_TRANSIENT); - - if (sqlite3_step(ppstmt) == SQLITE_ROW) - { - songTitle = reinterpret_cast(sqlite3_column_blob(ppstmt, 0)); - songArtist = reinterpret_cast(sqlite3_column_blob(ppstmt, 1)); - } else { - std::cout << "Error reading from acoustic datafile:" << std::endl; - std::cout << sqlite3_errmsg(ppdb) << std::endl; - - return 1; - } + hatkirby::row song = + abdb.queryFirst( + "SELECT title, artist FROM songs WHERE category = ? ORDER BY RANDOM() LIMIT 1", + { mood }); - sqlite3_finalize(ppstmt); + std::string songTitle = mpark::get(song[0]); + std::string songArtist = mpark::get(song[1]); - std::string action = "{" + cadence::uppercase(mood) + "}"; + std::string action = "{" + hatkirby::uppercase(mood) + "}"; int tknloc; while ((tknloc = action.find("{")) != std::string::npos) { @@ -182,13 +152,13 @@ int main(int argc, char** argv) }); } else if (isupper(token[0]) && !isupper(token[1])) { - auto words = cadence::split>(result, " "); + auto words = hatkirby::split>(result, " "); for (auto& word : words) { word[0] = std::toupper(word[0]); } - finalresult = cadence::implode(std::begin(words), std::end(words), " "); + finalresult = hatkirby::implode(std::begin(words), std::end(words), " "); } else { finalresult = result; } diff --git a/generator/CMakeLists.txt b/generator/CMakeLists.txt index af023c4..dffbe0e 100644 --- a/generator/CMakeLists.txt +++ b/generator/CMakeLists.txt @@ -4,8 +4,12 @@ project (generator) find_package(PkgConfig) pkg_check_modules(sqlite3 sqlite3 REQUIRED) -include_directories(${sqlite3_INCLUDE_DIR} vendor/json) -add_executable(generator mood.cpp database.cpp field.cpp generator.cpp main.cpp) +include_directories( + ${sqlite3_INCLUDE_DIR} + vendor/json + ../vendor/hkutil) + +add_executable(generator mood.cpp generator.cpp main.cpp) set_property(TARGET generator PROPERTY CXX_STANDARD 11) set_property(TARGET generator PROPERTY CXX_STANDARD_REQUIRED ON) target_link_libraries(generator ${sqlite3_LIBRARIES}) diff --git a/generator/database.cpp b/generator/database.cpp deleted file mode 100644 index b46a0d1..0000000 --- a/generator/database.cpp +++ /dev/null @@ -1,173 +0,0 @@ -#include "database.h" -#include -#include -#include -#include -#include -#include -#include "field.h" -#include "../util.h" - -namespace cadence { - namespace generator { - - sqlite3_error::sqlite3_error( - const std::string& what, - const std::string& db_err) : - what_(what + " (" + db_err + ")"), - db_err_(db_err) - { - } - - const char* sqlite3_error::what() const noexcept - { - return what_.c_str(); - } - - const char* sqlite3_error::db_err() const noexcept - { - return db_err_.c_str(); - } - - database::database(std::string path) - { - // If there is already a file at this path, overwrite it. - if (std::ifstream(path)) - { - if (std::remove(path.c_str())) - { - throw std::logic_error("Could not overwrite file at path"); - } - } - - if (sqlite3_open_v2(path.c_str(), &ppdb_, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL) != SQLITE_OK) - { - // We still have to free the resources allocated. In the event that - // allocation failed, ppdb will be null and sqlite3_close_v2 will just - // ignore it. - std::string errmsg(sqlite3_errmsg(ppdb_)); - sqlite3_close_v2(ppdb_); - - throw sqlite3_error("Could not create output datafile", errmsg); - } - } - - database::database(database&& other) : database() - { - swap(*this, other); - } - - database& database::operator=(database&& other) - { - swap(*this, other); - - return *this; - } - - void swap(database& first, database& second) - { - std::swap(first.ppdb_, second.ppdb_); - } - - database::~database() - { - sqlite3_close_v2(ppdb_); - } - - void database::runQuery(std::string query) - { - // This can only happen when doing bad things with move semantics. - assert(ppdb_ != nullptr); - - sqlite3_stmt* ppstmt; - - if (sqlite3_prepare_v2(ppdb_, query.c_str(), query.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw sqlite3_error("Error writing to database", sqlite3_errmsg(ppdb_)); - } - - int result = sqlite3_step(ppstmt); - sqlite3_finalize(ppstmt); - - if (result != SQLITE_DONE) - { - throw sqlite3_error("Error writing to database", sqlite3_errmsg(ppdb_)); - } - } - - void database::insertIntoTable(std::string table, std::list fields) - { - // This can only happen when doing bad things with move semantics. - assert(ppdb_ != nullptr); - - // This shouldn't happen. - assert(!fields.empty()); - - std::list fieldNames; - std::list qs; - for (field& f : fields) - { - fieldNames.push_back(f.getName()); - qs.push_back("?"); - } - - std::ostringstream query; - query << "INSERT INTO "; - query << table; - query << " ("; - query << implode(std::begin(fieldNames), std::end(fieldNames), ", "); - query << ") VALUES ("; - query << implode(std::begin(qs), std::end(qs), ", "); - query << ")"; - - std::string query_str = query.str(); - - sqlite3_stmt* ppstmt; - - if (sqlite3_prepare_v2(ppdb_, query_str.c_str(), query_str.length(), &ppstmt, NULL) != SQLITE_OK) - { - throw sqlite3_error("Error writing to database", sqlite3_errmsg(ppdb_)); - } - - int i = 1; - for (field& f : fields) - { - switch (f.getType()) - { - case field::type::integer: - { - sqlite3_bind_int(ppstmt, i, f.getInteger()); - - break; - } - - case field::type::string: - { - sqlite3_bind_text(ppstmt, i, f.getString().c_str(), f.getString().length(), SQLITE_TRANSIENT); - - break; - } - - case field::type::invalid: - { - // Fields can only be invalid when doing bad things with move semantics. - assert(false); - - break; - } - } - - i++; - } - - int result = sqlite3_step(ppstmt); - sqlite3_finalize(ppstmt); - - if (result != SQLITE_DONE) - { - throw sqlite3_error("Error writing to database", sqlite3_errmsg(ppdb_)); - } - } - - }; -}; diff --git a/generator/database.h b/generator/database.h deleted file mode 100644 index e4f3ba2..0000000 --- a/generator/database.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef DATABASE_H_0B0A47D2 -#define DATABASE_H_0B0A47D2 - -#include -#include -#include - -struct sqlite3; - -namespace cadence { - namespace generator { - - class field; - - class sqlite3_error : public std::exception { - public: - - sqlite3_error(const std::string& what, const std::string& db_err); - - const char* what() const noexcept override; - const char* db_err() const noexcept; - - private: - std::string what_; - std::string db_err_; - - }; - - class database { - public: - - // Constructor - - explicit database(std::string path); - - // Disable copying - - database(const database& other) = delete; - database& operator=(const database& other) = delete; - - // Move constructor and move assignment - - database(database&& other); - database& operator=(database&& other); - - // Swap - - friend void swap(database& first, database& second); - - // Destructor - - ~database(); - - // Actions - - void runQuery(std::string query); - - void insertIntoTable(std::string table, std::list fields); - - private: - - database() - { - } - - sqlite3* ppdb_ = nullptr; - - }; - - }; -}; - -#endif /* end of include guard: DATABASE_H_0B0A47D2 */ diff --git a/generator/field.cpp b/generator/field.cpp deleted file mode 100644 index 7e7453d..0000000 --- a/generator/field.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "field.h" -#include -#include - -namespace cadence { - namespace generator { - - field::field(const field& other) - { - type_ = other.type_; - name_ = other.name_; - - switch (type_) - { - case type::integer: - { - integer_ = other.integer_; - - break; - } - - case type::string: - { - new(&string_) std::string(other.string_); - - break; - } - - case type::invalid: - { - break; - } - } - } - - field::field(field&& other) : field() - { - swap(*this, other); - } - - field& field::operator=(field other) - { - swap(*this, other); - - return *this; - } - - void swap(field& first, field& second) - { - using type = field::type; - - type tempType = first.type_; - std::string tempName = std::move(first.name_); - int tempInteger; - std::string tempString; - - switch (first.type_) - { - case type::integer: - { - tempInteger = first.integer_; - - break; - } - - case type::string: - { - tempString = std::move(tempString); - - break; - } - - case type::invalid: - { - break; - } - } - - first.~field(); - - first.type_ = second.type_; - first.name_ = std::move(second.name_); - - switch (second.type_) - { - case type::integer: - { - first.integer_ = second.integer_; - - break; - } - - case type::string: - { - new(&first.string_) std::string(std::move(second.string_)); - - break; - } - - case type::invalid: - { - break; - } - } - - second.~field(); - - second.type_ = tempType; - second.name_ = std::move(tempName); - - switch (tempType) - { - case type::integer: - { - second.integer_ = tempInteger; - - break; - } - - case type::string: - { - new(&second.string_) std::string(std::move(tempString)); - - break; - } - - case type::invalid: - { - break; - } - } - } - - field::~field() - { - switch (type_) - { - case type::string: - { - using string_type = std::string; - string_.~string_type(); - - break; - } - - case type::integer: - case type::invalid: - { - break; - } - } - } - - field::field( - std::string name, - int arg) : - type_(type::integer), - name_(name), - integer_(arg) - { - } - - int field::getInteger() const - { - if (type_ != type::integer) - { - throw std::domain_error("field::getInteger called on non-integer field"); - } - - return integer_; - } - - field::field( - std::string name, - std::string arg) : - type_(type::string), - name_(name) - { - new(&string_) std::string(arg); - } - - std::string field::getString() const - { - if (type_ != type::string) - { - throw std::domain_error("field::getString called on non-string field"); - } - - return string_; - } - - }; -}; diff --git a/generator/field.h b/generator/field.h deleted file mode 100644 index 836c079..0000000 --- a/generator/field.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef BINDING_H_CAE0B18E -#define BINDING_H_CAE0B18E - -#include - -namespace cadence { - namespace generator { - - class field { - public: - enum class type { - invalid, - integer, - string - }; - - // Copy and move constructors - - field(const field& other); - field(field&& other); - - // Assignment - - field& operator=(field other); - - // Swap - - friend void swap(field& first, field& second); - - // Destructor - - ~field(); - - // Generic accessors - - type getType() const - { - return type_; - } - - std::string getName() const - { - return name_; - } - - // Integer - - field(std::string name, int arg); - - int getInteger() const; - - // String - - field(std::string name, std::string arg); - - std::string getString() const; - - private: - - field() - { - } - - union { - int integer_; - std::string string_; - }; - - type type_ = type::invalid; - std::string name_; - }; - - }; -}; - -#endif /* end of include guard: BINDING_H_CAE0B18E */ diff --git a/generator/generator.cpp b/generator/generator.cpp index 54f5d69..19eba70 100644 --- a/generator/generator.cpp +++ b/generator/generator.cpp @@ -4,9 +4,8 @@ #include #include #include -#include "progress.h" -#include "field.h" -#include "../util.h" +#include +#include #include "mood.h" namespace cadence { @@ -16,7 +15,7 @@ namespace cadence { std::string inputpath, std::string outputpath) : inputpath_(inputpath), - db_(outputpath) + db_(outputpath, hatkirby::dbmode::create) { // Add directory separator to input path if ((inputpath_.back() != '/') && (inputpath_.back() != '\\')) @@ -61,13 +60,13 @@ namespace cadence { } std::string schema = schemaBuilder.str(); - auto queries = split>(schema, ";"); - progress ppgs("Writing database schema...", queries.size()); + auto queries = hatkirby::split>(schema, ";"); + hatkirby::progress ppgs("Writing database schema...", queries.size()); for (std::string query : queries) { if (!queries.empty()) { - db_.runQuery(query); + db_.execute(query); } ppgs.update(); @@ -134,7 +133,9 @@ namespace cadence { void generator::parseData() { - progress ppgs("Parsing AcousticBrainz data files...", datafiles_.size()); + hatkirby::progress ppgs( + "Parsing AcousticBrainz data files...", + datafiles_.size()); for (std::string datafile : datafiles_) { @@ -163,12 +164,12 @@ namespace cadence { return left.getProbability() > right.getProbability(); }); - std::list fields; - fields.emplace_back("title", jsonData["metadata"]["tags"]["title"][0].get()); - fields.emplace_back("artist", jsonData["metadata"]["tags"]["artist"][0].get()); - fields.emplace_back("category", moods.front().getCategory()); + std::list columns; + columns.emplace_back("title", jsonData["metadata"]["tags"]["title"][0].get()); + columns.emplace_back("artist", jsonData["metadata"]["tags"]["artist"][0].get()); + columns.emplace_back("category", moods.front().getCategory()); - db_.insertIntoTable("songs", std::move(fields)); + db_.insertIntoTable("songs", std::move(columns)); } catch (const std::domain_error& ex) { // Weird data. Ignore silently. diff --git a/generator/generator.h b/generator/generator.h index dff8eeb..8db6764 100644 --- a/generator/generator.h +++ b/generator/generator.h @@ -3,7 +3,7 @@ #include #include -#include "database.h" +#include namespace cadence { namespace generator { @@ -37,7 +37,7 @@ namespace cadence { // Output - database db_; + hatkirby::database db_; // Cache diff --git a/generator/progress.h b/generator/progress.h deleted file mode 100644 index e5cc13d..0000000 --- a/generator/progress.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef PROGRESS_H_A34EF856 -#define PROGRESS_H_A34EF856 - -#include - -namespace cadence { - namespace generator { - - class progress { - private: - std::string message; - int total; - int cur = 0; - int lprint = 0; - - public: - progress(std::string message, int total) : message(message), total(total) - { - std::cout << message << " 0%" << std::flush; - } - - void update(int val) - { - if (val <= total) - { - cur = val; - } else { - cur = total; - } - - int pp = cur * 100 / total; - if (pp != lprint) - { - lprint = pp; - - std::cout << "\b\b\b\b" << std::right; - std::cout.width(3); - std::cout << pp << "%" << std::flush; - } - } - - void update() - { - update(cur+1); - } - - ~progress() - { - std::cout << "\b\b\b\b100%" << std::endl; - } - }; - - }; -}; - -#endif /* end of include guard: PROGRESS_H_A34EF856 */ diff --git a/util.h b/util.h deleted file mode 100644 index 5d16649..0000000 --- a/util.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef UTIL_H_CED7A66D -#define UTIL_H_CED7A66D - -#include -#include -#include -#include -#include - -namespace cadence { - - inline std::string uppercase(std::string in) - { - std::string result; - std::transform(std::begin(in), std::end(in), std::back_inserter(result), [] (char ch) - { - return std::toupper(ch); - }); - - return result; - } - - template - std::string implode(InputIterator first, InputIterator last, std::string delimiter) - { - std::stringstream result; - - for (InputIterator it = first; it != last; it++) - { - if (it != first) - { - result << delimiter; - } - - result << *it; - } - - return result.str(); - } - - template - void split(std::string input, std::string delimiter, OutputIterator out) - { - while (!input.empty()) - { - int divider = input.find(delimiter); - if (divider == std::string::npos) - { - *out = input; - out++; - - input = ""; - } else { - *out = input.substr(0, divider); - out++; - - input = input.substr(divider+delimiter.length()); - } - } - } - - template - Container split(std::string input, std::string delimiter) - { - Container result; - - split(input, delimiter, std::back_inserter(result)); - - return result; - } - -}; - -#endif /* end of include guard: UTIL_H_CED7A66D */ diff --git a/vendor/hkutil b/vendor/hkutil new file mode 160000 index 0000000..41f2eb0 --- /dev/null +++ b/vendor/hkutil @@ -0,0 +1 @@ +Subproject commit 41f2eb087900d4f2ea95c3e11087cf2c71395bae -- cgit 1.4.1