Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 7 additions & 19 deletions sqlwriter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


Expand Down Expand Up @@ -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 "<<name<<" in table "<<table<<endl;
// this could be more efficient somehow
pair<string, string> 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));
}


Expand Down Expand Up @@ -346,22 +340,16 @@ void SQLiteWriter::addValueGeneric(const std::string& table, const T& values, bo
if(!haveColumn(table, p.first)) {
if(std::get_if<double>(&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<string>(&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<vector<uint8_t>>(&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+=", ";
Expand Down
5 changes: 3 additions & 2 deletions sqlwriter.hh
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint64_t> s_execs, s_sorts, s_fullscans, s_autoindexes;

private:
Expand All @@ -58,7 +61,6 @@ private:
std::vector<std::vector<std::string>> 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
Expand Down Expand Up @@ -117,7 +119,6 @@ private:
std::mutex d_mutex;
MiniSQLite d_db;
SQLWFlag d_flag{SQLWFlag::NoFlag};
std::unordered_map<std::string, std::vector<std::pair<std::string, std::string>>> d_columns;
std::unordered_map<std::string, std::vector<std::string>> d_lastsig;
std::unordered_map<std::string, bool> d_lastreplace;
std::map<std::string, std::map<std::string, std::string>> d_meta;
Expand Down
54 changes: 54 additions & 0 deletions testrunner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down