diff --git a/sqlwriter.cc b/sqlwriter.cc index fab11e1..39a8550 100644 --- a/sqlwriter.cc +++ b/sqlwriter.cc @@ -250,7 +250,12 @@ void MiniSQLite::cycle() bool MiniSQLite::haveTable(const string& table) { - return !getSchema(table).empty(); + return sqlite3_table_column_metadata(d_sqlite, nullptr, table.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr, nullptr) == SQLITE_OK; +} + +bool MiniSQLite::haveColumn(const string& table, const string& column) +{ + return sqlite3_table_column_metadata(d_sqlite, nullptr, table.c_str(), column.c_str(), nullptr, nullptr, nullptr, nullptr, nullptr) == SQLITE_OK; } @@ -288,18 +293,7 @@ void SQLiteWriter::commitThread() bool SQLiteWriter::haveColumn(const std::string& table, std::string_view name) { - if(d_columns[table].empty()) { - d_columns[table] = d_db.getSchema(table); - } - // cout<<"Do we have column "< cmp{name, std::string()}; - return binary_search(d_columns[table].begin(), d_columns[table].end(), cmp, - [](const auto& a, const auto& b) - { - return a.first < b.first; - }); - + return d_db.haveColumn(table, string(name)); } @@ -346,22 +340,16 @@ void SQLiteWriter::addValueGeneric(const std::string& table, const T& values, bo if(!haveColumn(table, p.first)) { if(std::get_if(&p.second)) { d_db.addColumn(table, p.first, "REAL", d_meta[table][p.first]); - d_columns[table].push_back({p.first, "REAL"}); } else if(std::get_if(&p.second)) { d_db.addColumn(table, p.first, "TEXT", d_meta[table][p.first]); - d_columns[table].push_back({p.first, "TEXT"}); } else if(std::get_if>(&p.second)) { d_db.addColumn(table, p.first, "BLOB", d_meta[table][p.first]); - d_columns[table].push_back({p.first, "BLOB"}); } else { d_db.addColumn(table, p.first, "INT", d_meta[table][p.first]); - d_columns[table].push_back({p.first, "INT"}); } - - sort(d_columns[table].begin(), d_columns[table].end()); } if(!first) { q+=", "; diff --git a/sqlwriter.hh b/sqlwriter.hh index b85407f..4e79a0b 100644 --- a/sqlwriter.hh +++ b/sqlwriter.hh @@ -50,6 +50,9 @@ public: else return iter->second != nullptr; } + bool haveTable(const std::string& table); + bool haveColumn(const std::string& table, const std::string &column); + static std::atomic s_execs, s_sorts, s_fullscans, s_autoindexes; private: @@ -58,7 +61,6 @@ private: std::vector> d_rows; // for exec() static int helperFunc(void* ptr, int cols, char** colvals, char** colnames); bool d_intransaction{false}; - bool haveTable(const std::string& table); }; class SQLiteWriter @@ -117,7 +119,6 @@ private: std::mutex d_mutex; MiniSQLite d_db; SQLWFlag d_flag{SQLWFlag::NoFlag}; - std::unordered_map>> d_columns; std::unordered_map> d_lastsig; std::unordered_map d_lastreplace; std::map> d_meta; diff --git a/testrunner.cc b/testrunner.cc index 26672c2..3488543 100644 --- a/testrunner.cc +++ b/testrunner.cc @@ -158,6 +158,60 @@ TEST_CASE("test queries typed") { unlink("testrunner-example.sqlite3"); } +TEST_CASE("test multiple") { + unlink("testrunner-luke.sqlite3"); + + { + SQLiteWriter a("testrunner-luke.sqlite3"); + SQLiteWriter b("testrunner-luke.sqlite3"); + + a.addValue({{"dalton", "joe"}}); + b.addValue({{"dalton", "william"}}); + a.addValue({{"dalton", "jack"}}); + b.addValue({{"dalton", "averell"}}); + } + + unlink("testrunner-luke.sqlite3"); +} + +TEST_CASE("test column name case") { + unlink("testrunner-tintin.sqlite3"); + + { + SQLiteWriter sqw("testrunner-tintin.sqlite3"); + + sqw.addValue({{"name", "tintin"}}); + sqw.addValue({{"Name", "Snowy"}}); + sqw.addValue({{"NAME", "CAPTAIN HADDOCK"}}); + } + + { + SQLiteWriter sqw("testrunner-tintin.sqlite3"); + + auto res = sqw.query("select name from data order by rowid"); + CHECK(res.size() == 3); + CHECK(res.at(0).at("name") == "tintin"); + CHECK(res.at(1).at("name") == "Snowy"); + CHECK(res.at(2).at("name") == "CAPTAIN HADDOCK"); + } + + unlink("testrunner-tintin.sqlite3"); +} + +TEST_CASE("test table name case") { + unlink("testrunner-ao.sqlite3"); + + { + SQLiteWriter sqw("testrunner-ao.sqlite3"); + + sqw.addValue({{"name", "Asterix"}}, "a"); + sqw.addValue({{"name", "Obelix"}}, "a"); + sqw.addValue({{"name", "Getafix"}}, "A"); + sqw.addValue({{"name", "Vitalstatistix"}}, "A"); + } + + unlink("testrunner-ao.sqlite3"); +} TEST_CASE("test meta") { unlink("testrunner-example.sqlite3");