vector <int> Database_MorphHb::rowids (int book, int chapter, int verse) { SqliteDatabase sql = SqliteDatabase (filename ()); sql.add ("SELECT rowid FROM morphhb WHERE book ="); sql.add (book); sql.add ("AND chapter ="); sql.add (chapter); sql.add ("AND verse ="); sql.add (verse); sql.add ("ORDER BY rowid;"); vector <string> result = sql.query () ["rowid"]; vector <int> rowids; for (auto rowid : result) rowids.push_back (convert_to_int (rowid)); return rowids; }
// Returns true if a record for $username / $bible / $book exists in the database. // When the $book = 0, it takes any book. bool Database_Privileges::getBibleBookExists (string username, string bible, int book) { SqliteDatabase sql (database ()); sql.add ("SELECT rowid FROM bibles WHERE username ="******"AND bible ="); sql.add (bible); if (book) { sql.add ("AND book ="); sql.add (book); } sql.add (";"); vector <string> result = sql.query () ["rowid"]; return !result.empty(); }
// Remove privileges for $username from the entire database. void Database_Privileges::removeUser (string username) { SqliteDatabase sql (database ()); sql.add ("DELETE FROM bibles WHERE username ="******";"); sql.execute (); sql.clear (); sql.add ("DELETE FROM features WHERE username ="******";"); sql.execute (); }
// Returns whether the device that matches the remote IP $address and the browser's user $agent, // and the other fingerprint, is touch-enabled. bool Database_Login::getTouchEnabled (string address, string agent, string fingerprint) { address = md5 (address); agent = md5 (agent); fingerprint = md5 (fingerprint); SqliteDatabase sql (database ()); sql.add ("SELECT touch FROM logins WHERE address ="); sql.add (address); sql.add ("AND agent ="); sql.add (agent); sql.add ("AND fingerprint ="); sql.add (fingerprint); sql.add (";"); vector <string> result = sql.query () ["touch"]; if (!result.empty()) return convert_to_bool (result [0]); return false; }
// Read the privilege from the database whether $username has access to $bible $book. // The privileges are stored in $read for read-only access, // and in $write for write access. void Database_Privileges::getBibleBook (string username, string bible, int book, bool & read, bool & write) { SqliteDatabase sql (database ()); sql.add ("SELECT write FROM bibles WHERE username ="******"AND bible ="); sql.add (bible); sql.add ("AND book ="); sql.add (book); sql.add (";"); vector <string> result = sql.query () ["write"]; if (result.empty()) { // Not in database: No access. read = false; write = false; } else { // Occurs in database: Read access. read = true; // Take write access from the database field. write = convert_to_bool (result [0]); } }
string Database_Privileges::save (string username) { SqliteDatabase sql (database ()); vector <string> lines; lines.push_back (bibles_start ()); sql.add ("SELECT bible, book, write FROM bibles WHERE username ="******";"); map <string, vector <string> > result = sql.query (); vector <string> bible = result ["bible"]; vector <string> book = result ["book"]; vector <string> write = result ["write"]; for (size_t i = 0; i < bible.size (); i++) { lines.push_back (bible [i]); lines.push_back (book [i]); // It could have just stored 0 or 1 for the boolean values. // But if that were done, then there would be no change in the length of the file // when changing only boolean values. // And then the client would not re-download that file. // To use "on" and "off", that solves the issue. bool b = convert_to_bool (write[i]); if (b) lines.push_back (on ()); else lines.push_back (off ()); } lines.push_back (bibles_end ()); lines.push_back (features_start ()); sql.clear (); sql.add ("SELECT feature FROM features WHERE username ="******";"); result = sql.query (); vector <string> feature = result ["feature"]; for (size_t i = 0; i < feature.size (); i++) { lines.push_back (feature [i]); } lines.push_back (features_end ()); return filter_string_implode (lines, "\n"); }
// stores a confirmation cycle void Database_Confirm::store (unsigned int id, string query, string to, string subject, string body) { SqliteDatabase sql (filename ()); sql.add ("INSERT INTO confirm VALUES ("); sql.add (id); sql.add (","); sql.add (query); sql.add (","); sql.add (filter_date_seconds_since_epoch ()); sql.add (","); sql.add (to); sql.add (","); sql.add (subject); sql.add (","); sql.add (body); sql.add (");"); sql.execute (); }
void Database_Confirm::optimize () { SqliteDatabase sql (filename ()); sql.add ("VACUUM confirm;"); sql.execute (); }
void Database_MorphGnt::store (int book, int chapter, int verse, string pos, string parsing, string word, string lemma) { int pos_id = get_id ("pos", pos); int parsing_id = get_id ("parsing", parsing); int word_id = get_id ("word", word); int lemma_id = get_id ("lemma", lemma); SqliteDatabase sql = SqliteDatabase (filename ()); sql.add ("PRAGMA temp_store = MEMORY;"); sql.execute (); sql.clear (); sql.add ("PRAGMA synchronous = OFF;"); sql.execute (); sql.clear (); sql.add ("PRAGMA journal_mode = OFF;"); sql.execute (); sql.clear (); sql.add ("INSERT INTO morphgnt VALUES ("); sql.add (book); sql.add (","); sql.add (chapter); sql.add (","); sql.add (verse); sql.add (","); sql.add (pos_id); sql.add (","); sql.add (parsing_id); sql.add (","); sql.add (word_id); sql.add (","); sql.add (lemma_id); sql.add (");"); sql.execute (); }
void Database_MorphGnt::optimize () { SqliteDatabase sql = SqliteDatabase (filename ()); sql.add ("VACUUM;"); sql.execute (); }
string Database_MorphGnt::get_item (const char * item, int rowid) { // The $rowid refers to the main table. // Update it so it refers to the sub table. SqliteDatabase sql = SqliteDatabase (filename ()); sql.add ("SELECT"); sql.add (item); sql.add ("FROM morphgnt WHERE rowid ="); sql.add (rowid); sql.add (";"); vector <string> result = sql.query () [item]; rowid = 0; if (!result.empty ()) rowid = convert_to_int (result [0]); // Retrieve the requested value from the sub table. sql.clear (); sql.add ("SELECT"); sql.add (item); sql.add ("FROM"); sql.add (item); sql.add ("WHERE rowid ="); sql.add (rowid); sql.add (";"); result = sql.query () [item]; if (!result.empty ()) return result [0]; // Not found. return ""; }
int Database_MorphGnt::get_id (const char * table_row, string item) { SqliteDatabase sql = SqliteDatabase (filename ()); // Two iterations to be sure a rowid can be returned. for (unsigned int i = 0; i < 2; i++) { // Check on the rowid and return it if it's there. sql.clear (); sql.add ("SELECT rowid FROM"); sql.add (table_row); sql.add ("WHERE"); sql.add (table_row); sql.add ("="); sql.add (item); sql.add (";"); vector <string> result = sql.query () ["rowid"]; if (!result.empty ()) return convert_to_int (result [0]); // The rowid was not found: Insert the word into the table. // The rowid will now be found during the second iteration. sql.clear (); sql.add ("INSERT INTO"); sql.add (table_row); sql.add ("VALUES ("); sql.add (item); sql.add (");"); sql.execute (); } return 0; }
// Returns the username that matches the remote IP $address and the browser's user $agent, // and the other fingerprints from the user. string Database_Login::getUsername (string address, string agent, string fingerprint) { address = md5 (address); agent = md5 (agent); fingerprint = md5 (fingerprint); SqliteDatabase sql (database ()); sql.add ("SELECT rowid, timestamp, username FROM logins WHERE address ="); sql.add (address); sql.add ("AND agent ="); sql.add (agent); sql.add ("AND fingerprint ="); sql.add (fingerprint); sql.add (";"); map <string, vector <string> > result = sql.query (); if (result.empty()) return ""; string username = result ["username"][0]; int stamp = convert_to_int (result ["timestamp"] [0]); if (stamp != timestamp ()) { // Touch the timestamp. This occurs once a day. int rowid = convert_to_int (result ["rowid"] [0]); sql.clear (); sql.add ("UPDATE logins SET timestamp ="); sql.add (timestamp ()); sql.add ("WHERE rowid ="); sql.add (rowid); sql.execute (); } return username; }
void Database_Login::renameTokens (string username_existing, string username_new, string address, string agent, string fingerprint) { address = md5 (address); agent = md5 (agent); fingerprint = md5 (fingerprint); SqliteDatabase sql (database ()); sql.add ("UPDATE logins SET username ="******"WHERE username ="******"AND address ="); sql.add (address); sql.add ("AND agent ="); sql.add (agent); sql.add ("AND fingerprint ="); sql.add (fingerprint); sql.add (";"); sql.execute (); }
void Database_Login::testTimestamp () { SqliteDatabase sql (database ()); sql.add ("UPDATE logins SET timestamp = timestamp - 370;"); sql.execute (); }
void Database_Kjv::store (int book, int chapter, int verse, string strong, string english) { int strongid = get_id ("strong", strong); int englishid = get_id ("english", english); SqliteDatabase sql = SqliteDatabase (filename ()); sql.add ("PRAGMA temp_store = MEMORY;"); sql.execute (); sql.clear (); sql.add ("PRAGMA synchronous = OFF;"); sql.execute (); sql.clear (); sql.add ("PRAGMA journal_mode = OFF;"); sql.execute (); sql.clear (); sql.add ("INSERT INTO kjv2 VALUES ("); sql.add (book); sql.add (","); sql.add (chapter); sql.add (","); sql.add (verse); sql.add (","); sql.add (strongid); sql.add (","); sql.add (englishid); sql.add (");"); sql.execute (); }
// Sets the login security tokens for a user. // Also store whether the device is touch-enabled. // It only writes to the table if the combination of username and tokens differs from what the table already contains. void Database_Login::setTokens (string username, string address, string agent, string fingerprint, string cookie, bool touch) { bool daily; if (username == getUsername (cookie, daily)) return; address = md5 (address); agent = md5 (agent); fingerprint = md5 (fingerprint); SqliteDatabase sql (database ()); sql.add ("INSERT INTO logins VALUES ("); sql.add (username); sql.add (","); sql.add (address); sql.add (","); sql.add (agent); sql.add (","); sql.add (fingerprint); sql.add (","); sql.add (cookie); sql.add (","); sql.add (touch); sql.add (","); sql.add (timestamp ()); sql.add (");"); sql.execute (); }
void Database_HebrewLexicon::optimize () { SqliteDatabase sql = SqliteDatabase (filename ()); sql.add ("VACUUM;"); sql.execute (); }