void WhatsappDatabase::validate() { if (!hasTable("message_thumbnails") || !hasTable("messages_quotes") || !hasTable("messages_links") || !hasColumn("messages", "quoted_row_id") || !hasColumn("messages", "media_caption")) { throw Exception("It seems like you tried to open an older WhatsApp database. Please try to use an older version of WhatsApp Viewer."); } }
DbTab* SqliteDatabase::getTab(const string& tabName) { // try to find the tabl object in the cache auto it = tabCache.find(tabName); // if we have a hit, return the table object if (it != tabCache.end()) { return it->second; } // okay, we have a cache miss. // // check if the table exists if (!(hasTable(tabName))) { return nullptr; } // the table name is valid, but the table // has not yet been accessed. So we need to // create a new tab object DbTab* tab = new DbTab(this, tabName); tabCache[tabName] = tab; return tab; }
void SqliteDatabase::indexCreationHelper(const string &tabName, const string &idxName, const Sloppy::StringList &colNames, bool isUnique, int* errCodeOut) { if (idxName.empty()) return; if (!(hasTable(tabName))) return; string sql = "CREATE "; if (isUnique) sql += "UNIQUE "; sql += "INDEX IF NOT EXISTS "; sql += idxName + " ON " + tabName + " ("; sql += Sloppy::commaSepStringFromStringList(colNames) + ")"; execNonQuery(sql, errCodeOut); }
int TableManagement::addTable(TableInfo t){ if (hasTable(t.Tablename)) { cerr << "Table already has been existed\n"; return false; } else{ TableInfomation.push_back(t); TableNum++; writeToDisk(); return true; } }
bool SqliteDatabase::copyTable(const string& srcTabName, const string& dstTabName, int* errCodeOut, bool copyStructureOnly) { // ensure validity of parameters if (srcTabName.empty()) return false; if (dstTabName.empty()) return false; if (!(hasTable(srcTabName))) return false; if (hasTable(dstTabName)) return false; // retrieve the CREATE TABLE statement that describes the source table's structure int err; auto stmt = prepStatement("SELECT sql FROM sqlite_master WHERE type='table' AND name=?", &err); if (errCodeOut != nullptr) *errCodeOut = err; if (err != SQLITE_OK) return false; stmt->bindString(1, srcTabName); auto _sqlCreate = execScalarQueryString(stmt, &err); if (errCodeOut != nullptr) *errCodeOut = err; if (_sqlCreate == nullptr) return false; if (err != SQLITE_DONE) return false; if (_sqlCreate->isNull()) return false; string sqlCreate = _sqlCreate->get(); // Modify the string to be applicable to the new database name // // The string starts with "CREATE TABLE srcName (id ...". We search // for the opening parenthesis and replace everthing before that // character with "CREATE TABLE dstName ". auto posParenthesis = sqlCreate.find_first_of("("); if (posParenthesis == string::npos) return false; sqlCreate.replace(0, posParenthesis-1, "CREATE TABLE " + dstTabName); // before we create the new table and copy the contents, we // explicitly start a transaction to be able to restore the // original database state in case of errors auto tr = startTransaction(TRANSACTION_TYPE::IMMEDIATE, TRANSACTION_DESTRUCTOR_ACTION::ROLLBACK, &err); if (tr == nullptr) return false; if (err != SQLITE_DONE) return false; // actually create the new table bool isSuccess = execNonQuery(sqlCreate, &err); if (errCodeOut != nullptr) *errCodeOut = err; if (!isSuccess) { tr->rollback(); return false; } // if we're only requested to copy the schema, skip // the conent copying if (!copyStructureOnly) { string sqlCopy = "INSERT INTO " + dstTabName + " SELECT * FROM " + srcTabName; stmt = prepStatement(sqlCopy, &err); if (errCodeOut != nullptr) *errCodeOut = err; if (err != SQLITE_OK) return false; isSuccess = execNonQuery(stmt, &err); if (errCodeOut != nullptr) *errCodeOut = err; if (!isSuccess) { tr->rollback(); return false; } } // we're done. Commit all changes at once tr->commit(&err); if (errCodeOut != nullptr) *errCodeOut = err; return (err == SQLITE_DONE); }
bool SqliteDatabase::hasView(const string& name) { return hasTable(name, true); }