17 #include "SQLamarr/db_functions.h"
18 #include "SQLamarr/GlobalPRNG.h"
19 #include "SQLamarr/SQLiteError.h"
20 #include "SQLamarr/custom_sql_functions.h"
31 std::stringstream ret;
34 for (iCh = 0; s[iCh] !=
'\0'; ++iCh);
35 const int s_len = iCh;
40 for (iCh = s_len; iCh < length; iCh++)
43 else if (column_type == SQLITE_TEXT)
45 for (iCh = 0; iCh < length/2 - 1; iCh++)
48 for (iCh = s_len - length/2 + 1; iCh < s_len; iCh++)
51 else if (column_type == SQLITE_INTEGER || column_type == SQLITE_FLOAT)
54 sprintf(buf,
"%g%100s", atof(
reinterpret_cast<const char *
>(s)),
"");
91 init = SQL_CREATE_SCHEMA;
93 retcode = sqlite3_open_v2(filename.c_str(), &db, flags,
nullptr);
96 std::cerr <<
"Failure while initializing " << filename <<
": "
100 throw SQLiteError(
"Failed to instantiate SQLite3 DB");
103 retcode = sqlite3_exec(db, init.c_str(),
nullptr,
nullptr, &zErrMsg);
106 std::cerr << sqlite3_errmsg(db) << std::endl;
114 int ret = sqlite3_close(ptr);
115 if (ret != SQLITE_OK)
117 std::cerr <<
"sqlite3_close returned errorcode: " << ret << std::endl;
118 throw (
SQLiteError(
"Failed closing the connection"));
131 int retcode = sqlite3_prepare_v2(
132 db.get(), query.c_str(), -1, &stmt,
nullptr
135 if (retcode != SQLITE_OK)
137 std::cerr << sqlite3_errmsg(db.get()) << std::endl;
149 std::stringstream ret;
150 constexpr
char SEPARATOR[] =
" ";
156 while (sqlite3_step(stmt) == SQLITE_ROW)
158 nColumns = sqlite3_column_count(stmt);
164 for (iCol = 0; iCol < nColumns; ++iCol)
166 auto s = sqlite3_column_name (stmt, iCol);
167 auto t = sqlite3_column_type (stmt, iCol);
170 ret << f << SEPARATOR;
180 for (iCol = 0; iCol < nColumns; ++iCol)
182 auto t = sqlite3_column_type (stmt, iCol);
184 if (t == SQLITE_NULL)
187 for (
int iCh = 0; iCh < n-3; ++iCh) ret <<
" ";
192 auto s = sqlite3_column_text (stmt, iCol);
194 ret << f << SEPARATOR;
199 ret <<
"\n[" << nRows <<
" rows x " << nColumns <<
" columns]" << std::endl;
201 sqlite3_finalize(stmt);
211 switch (sqlite3_column_type(stmt, iCol))
214 buf =
static_cast<float>(sqlite3_column_int(stmt, iCol));
217 buf =
static_cast<float>(sqlite3_column_double(stmt, iCol));
232 const int forbidden = std::count_if(token.begin(), token.end(),
233 [](
unsigned char c){ return !std::isalnum(c) && c !=
'_'; }
239 <<
"Found non alphanumeric token in SQL query: "
242 throw std::runtime_error(
"Invalid token");
258 std::uniform_int_distribution<long> distribution(0, 0xFFFFFFFFL);
259 uint64_t new_seed = distribution(*old_generator);
263 sqlamarr_create_sql_functions(new_database.get());
266 old_db.swap(new_database);
static PRNG * get_or_create(const sqlite3_context *db, uint64_t seed=no_seed)
Return a pointer to an initialized generator.
static bool release(const sqlite3 *db)
Releases a generator (delete). May require re-seeding.
A database connection handler easying sharing the DB between C++ and Python.
int _get_field_length(int column_type)
sqlite3_stmt * prepare_statement(SQLite3DB &db, const std::string &query)
Prpare a statement.
void update_db_connection(SQLite3DB &old_db, const std::string &db_uri, int flags=SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI)
Force synchronization to disk by closing and opening the connection.
void validate_token(const std::string &token)
Ensure a token is alphanumeric.
SQLite3DB make_database(std::string filename, int flags=SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI, std::string init=std::string())
Initialize the database.
float read_as_float(sqlite3_stmt *, int)
Read a column field from a sqlite3 statement and convert it to float.
std::unique_ptr< sqlite3, void(*)(sqlite3 *)> SQLite3DB
Unique pointer to the sqlite3 connection.
std::string _string_field(T *s, int length, int column_type)
std::string dump_table(SQLite3DB &db, const std::string &query)
Dump the result of a query to a string.