Revision 88cf406f
Added by David Sorber over 10 years ago
| software/sqlite_poc/DBManager.cc | ||
|---|---|---|
|
#include <iostream>
|
||
|
|
||
|
#include "DBManager.h"
|
||
|
|
||
|
DBManager::DBManager(const std::string& db_path)
|
||
|
{
|
||
|
|
||
|
int rc = sqlite3_open(db_path.c_str(), &this->db);
|
||
|
if (rc)
|
||
|
{
|
||
|
std::cerr << "Uh-oh spaghetti O's" << std::endl;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
std::cout << "WORKED" << std::endl;
|
||
|
}
|
||
|
|
||
|
numba = 17;
|
||
|
|
||
|
}
|
||
|
|
||
|
DBManager::~DBManager()
|
||
|
{
|
||
|
sqlite3_close(this->db);
|
||
|
}
|
||
|
|
||
|
void DBManager::test()
|
||
|
{
|
||
|
std::cout << "Numba: " << numba << std::endl;
|
||
|
}
|
||
|
|
||
|
|
||
|
//~ template<typename T>
|
||
|
//~ void DBManager::func(T foo)
|
||
|
//~ {
|
||
|
//~ std::cout << "Does this work??? " << foo << std::endl;
|
||
|
//~ }
|
||
| software/sqlite_poc/DBManager.h | ||
|---|---|---|
|
|
||
|
#include <cassert>
|
||
|
#include <string>
|
||
|
#include <tuple>
|
||
|
#include <type_traits>
|
||
|
#include <vector>
|
||
|
|
||
|
#include <sqlite3.h>
|
||
|
|
||
|
template <size_t I>
|
||
|
struct visit_impl
|
||
|
{
|
||
|
template <typename T, typename V>
|
||
|
static void visit(T& tup, size_t idx, V value)
|
||
|
{
|
||
|
if (idx == I - 1)
|
||
|
{
|
||
|
if (std::is_same<std::get<I - 1>(tup), value>)
|
||
|
{
|
||
|
std::get<I - 1>(tup) = value;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
assert(false);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
visit_impl<I - 1>::visit(tup, idx, value);
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
template <>
|
||
|
struct visit_impl<0>
|
||
|
{
|
||
|
template <typename T, typename V>
|
||
|
static void visit(T& tup, size_t idx, V fun) { assert(false); }
|
||
|
};
|
||
|
|
||
|
//~ template <typename V, typename... Ts>
|
||
|
//~ void visit_at(std::tuple<Ts...> const& tup, size_t idx, V value)
|
||
|
//~ {
|
||
|
//~ visit_impl<sizeof...(Ts)>::visit(tup, idx, value);
|
||
|
//~ }
|
||
|
|
||
|
template <typename V, typename... Ts>
|
||
|
void visit_at(std::tuple<Ts...>& tup, size_t idx, V value)
|
||
|
{
|
||
|
visit_impl<sizeof...(Ts)>::visit(tup, idx, value);
|
||
|
}
|
||
|
|
||
|
class DBManager
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
// Constructor
|
||
|
DBManager(const std::string& db_path);
|
||
|
|
||
|
// Destructor
|
||
|
~DBManager();
|
||
|
|
||
|
// execute query
|
||
|
template<typename T>
|
||
|
std::vector<T*>* execute_query(
|
||
|
const std::string& sql_statement,
|
||
|
int& return_code)
|
||
|
{
|
||
|
sqlite3_stmt* sqlite_statement;
|
||
|
|
||
|
// Prepare the sqlite statement
|
||
|
return_code = sqlite3_prepare_v2(db, sql_statement.c_str(), -1,
|
||
|
&sqlite_statement, nullptr);
|
||
|
if (return_code != SQLITE_OK)
|
||
|
{
|
||
|
return nullptr;
|
||
|
}
|
||
|
|
||
|
auto output_vector = new std::vector<T*>();
|
||
|
|
||
|
int step_return = 0;
|
||
|
|
||
|
// Iterate until we've collected all the output
|
||
|
do
|
||
|
{
|
||
|
// Gran the
|
||
|
step_return = sqlite3_step(sqlite_statement);
|
||
|
|
||
|
// Create a new result row to be populated below
|
||
|
auto result_row = new T();
|
||
|
|
||
|
// Iterate over the columns in the row
|
||
|
int num_cols = sqlite3_data_count(sqlite_statement);
|
||
|
for (int col_idx = 0; col_idx < num_cols; col_idx++)
|
||
|
{
|
||
|
switch(sqlite3_column_type(sqlite_statement, col_idx))
|
||
|
{
|
||
|
case SQLITE_INTEGER:
|
||
|
visit_at(*result_row, col_idx,
|
||
|
sqlite3_column_int64(sqlite_statement, col_idx));
|
||
|
|
||
|
//~ std::get<col_idx>(result_row) =
|
||
|
//~ sqlite3_column_int64(sqlite_statement, col_idx);
|
||
|
break;
|
||
|
|
||
|
case SQLITE_FLOAT:
|
||
|
visit_at(*result_row, col_idx, sqlite3_column_double(sqlite_statement, col_idx));
|
||
|
//~ std::get<col_idx>(result_row) =
|
||
|
//~ sqlite3_column_double(sqlite_statement, col_idx);
|
||
|
break;
|
||
|
|
||
|
case SQLITE_TEXT:
|
||
|
visit_at(*result_row, col_idx,
|
||
|
std::string(reinterpret_cast<const char*>(sqlite3_column_text(sqlite_statement, col_idx))));
|
||
|
|
||
|
//~ std::get<col_idx>(result_row) =
|
||
|
//~ std::string(sqlite3_column_text(sqlite_statement, col_idx));
|
||
|
break;
|
||
|
|
||
|
case SQLITE_BLOB:
|
||
|
break;
|
||
|
|
||
|
case SQLITE_NULL:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
while (step_return == SQLITE_ROW);
|
||
|
|
||
|
return output_vector;
|
||
|
}
|
||
|
|
||
|
void test();
|
||
|
|
||
|
// templatized member function!
|
||
|
template<typename T>
|
||
|
std::vector<T> func(T& foo)
|
||
|
{
|
||
|
std::cout << "Does this work??? " << std::get<2>(foo) << std::endl;
|
||
|
|
||
|
std::vector<T> bar;
|
||
|
bar.push_back(foo);
|
||
|
return bar;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
|
||
|
sqlite3 *db;
|
||
|
uint32_t numba;
|
||
|
};
|
||
| software/sqlite_poc/Makefile | ||
|---|---|---|
|
|
||
|
CXXFLAGS=-std=c++11
|
||
|
OBJECTS = main.o DBManager.o
|
||
|
|
||
|
all: main
|
||
|
|
||
|
main: $(OBJECTS)
|
||
|
g++ $(CXXFLAGS) $(OBJECTS) -lsqlite3 -o poc_test
|
||
|
|
||
|
%.o : %.c
|
||
|
g++ $(CXXFLAGS) -c $<
|
||
|
|
||
|
clean:
|
||
|
rm *.o
|
||
| software/sqlite_poc/main.cc | ||
|---|---|---|
|
|
||
|
#include <iostream>
|
||
|
#include <tuple>
|
||
|
|
||
|
#include "DBManager.h"
|
||
|
|
||
|
|
||
|
int main(int argc, char** argv)
|
||
|
{
|
||
|
std::cout << "SQLite Proof of Concept Exerciser" << std::endl;
|
||
|
|
||
|
DBManager db_mgr("database.db");
|
||
|
db_mgr.test();
|
||
|
|
||
|
//~ std::tuple<std::string, int, double> foo{"hello", 120, 3.14};
|
||
|
|
||
|
//~ db_mgr.func(foo);
|
||
|
|
||
|
//~ visit_at(foo, 1, 18);
|
||
|
|
||
|
|
||
|
std::string query("SELECT Number FROM sample;");
|
||
|
int rc(0);
|
||
|
|
||
|
|
||
|
auto results = db_mgr.execute_query<std::tuple<int64_t>>(query, rc);
|
||
|
|
||
|
std::cout << "Return code: " << rc << std::endl;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
Adding sqlite proof-of-concept. This code does not compile due to some template issues but I want to keep track of it none the less.