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.");
	}
}
Esempio n. 2
0
  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;
  }
Esempio n. 3
0
  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);
  }
Esempio n. 4
0
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;
	}
}
Esempio n. 5
0
  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);
  }
Esempio n. 6
0
 bool SqliteDatabase::hasView(const string& name)
 {
   return hasTable(name, true);
 }