diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h
--- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h
+++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h
@@ -4,6 +4,7 @@
 #include "entities/AuxUserInfo.h"
 #include "entities/CommunityInfo.h"
 #include "entities/Draft.h"
+#include "entities/EntryInfo.h"
 #include "entities/InboundP2PMessage.h"
 #include "entities/IntegrityThreadHash.h"
 #include "entities/KeyserverInfo.h"
@@ -108,6 +109,10 @@
   virtual void removeAllThreadActivityEntries() const = 0;
   virtual std::vector<ThreadActivityEntry>
   getAllThreadActivityEntries() const = 0;
+  virtual void replaceEntry(const EntryInfo &entry_info) const = 0;
+  virtual void removeEntries(const std::vector<std::string> &ids) const = 0;
+  virtual void removeAllEntries() const = 0;
+  virtual std::vector<EntryInfo> getAllEntries() const = 0;
   virtual void beginTransaction() const = 0;
   virtual void commitTransaction() const = 0;
   virtual void rollbackTransaction() const = 0;
diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h
--- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h
+++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h
@@ -120,6 +120,10 @@
       const std::vector<std::string> &ids) const override;
   void removeAllThreadActivityEntries() const override;
   std::vector<ThreadActivityEntry> getAllThreadActivityEntries() const override;
+  void replaceEntry(const EntryInfo &entry_info) const override;
+  void removeEntries(const std::vector<std::string> &ids) const override;
+  void removeAllEntries() const override;
+  std::vector<EntryInfo> getAllEntries() const override;
   void beginTransaction() const override;
   void commitTransaction() const override;
   void rollbackTransaction() const override;
diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
--- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
+++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp
@@ -3,6 +3,7 @@
 
 #include "entities/CommunityInfo.h"
 #include "entities/EntityQueryHelpers.h"
+#include "entities/EntryInfo.h"
 #include "entities/IntegrityThreadHash.h"
 #include "entities/KeyserverInfo.h"
 #include "entities/Metadata.h"
@@ -661,6 +662,15 @@
   return create_table(db, query, "outbound_p2p_messages");
 }
 
+bool create_entries_table(sqlite3 *db) {
+  std::string query =
+      "CREATE TABLE IF NOT EXISTS entries ("
+      "  id TEXT UNIQUE PRIMARY KEY NOT NULL,"
+      "  entry TEXT NOT NULL"
+      ");";
+  return create_table(db, query, "entries");
+}
+
 bool create_schema(sqlite3 *db) {
   char *error;
   sqlite3_exec(
@@ -799,6 +809,11 @@
       "  status TEXT NOT NULL"
       ");"
 
+      "CREATE TABLE IF NOT EXISTS entries ("
+      "  id TEXT UNIQUE PRIMARY KEY NOT NULL,"
+      "  entry TEXT NOT NULL"
+      ");"
+
       "CREATE INDEX IF NOT EXISTS media_idx_container"
       "  ON media (container);"
 
@@ -1053,7 +1068,8 @@
      {42, {add_version_column_to_olm_persist_sessions_table, true}},
      {43, {create_thread_activity_table, true}},
      {44, {create_received_messages_to_device, true}},
-     {45, {recreate_outbound_p2p_messages_table, true}}}};
+     {45, {recreate_outbound_p2p_messages_table, true}},
+     {46, {create_entries_table, true}}}};
 
 enum class MigrationResult { SUCCESS, FAILURE, NOT_APPLIED };
 
@@ -1952,6 +1968,43 @@
       SQLiteQueryExecutor::getConnection(), getAllThreadActivityEntriesSQL);
 }
 
+void SQLiteQueryExecutor::replaceEntry(const EntryInfo &entry_info) const {
+  static std::string replaceEntrySQL =
+      "REPLACE INTO entries (id, entry) "
+      "VALUES (?, ?);";
+  replaceEntity<EntryInfo>(
+      SQLiteQueryExecutor::getConnection(), replaceEntrySQL, entry_info);
+}
+
+void SQLiteQueryExecutor::removeAllEntries() const {
+  static std::string removeAllEntriesSQL = "DELETE FROM entries;";
+  removeAllEntities(SQLiteQueryExecutor::getConnection(), removeAllEntriesSQL);
+}
+
+void SQLiteQueryExecutor::removeEntries(
+    const std::vector<std::string> &ids) const {
+  if (!ids.size()) {
+    return;
+  }
+
+  std::stringstream removeEntriesByKeysSQLStream;
+  removeEntriesByKeysSQLStream << "DELETE FROM entries "
+                                  "WHERE id IN "
+                               << getSQLStatementArray(ids.size()) << ";";
+  removeEntitiesByKeys(
+      SQLiteQueryExecutor::getConnection(),
+      removeEntriesByKeysSQLStream.str(),
+      ids);
+}
+
+std::vector<EntryInfo> SQLiteQueryExecutor::getAllEntries() const {
+  static std::string getAllEntriesSQL =
+      "SELECT * "
+      "FROM entries;";
+  return getAllEntities<EntryInfo>(
+      SQLiteQueryExecutor::getConnection(), getAllEntriesSQL);
+}
+
 void SQLiteQueryExecutor::beginTransaction() const {
   executeQuery(SQLiteQueryExecutor::getConnection(), "BEGIN TRANSACTION;");
 }
diff --git a/native/cpp/CommonCpp/DatabaseManagers/entities/EntryInfo.h b/native/cpp/CommonCpp/DatabaseManagers/entities/EntryInfo.h
new file mode 100644
--- /dev/null
+++ b/native/cpp/CommonCpp/DatabaseManagers/entities/EntryInfo.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "SQLiteDataConverters.h"
+#include <sqlite3.h>
+#include <string>
+
+namespace comm {
+struct EntryInfo {
+  std::string id;
+  std::string entry;
+
+  static EntryInfo fromSQLResult(sqlite3_stmt *sqlRow, int idx) {
+    return EntryInfo{
+        getStringFromSQLRow(sqlRow, idx), getStringFromSQLRow(sqlRow, idx + 1)};
+  };
+
+  int bindToSQL(sqlite3_stmt *sql, int idx) const {
+    bindStringToSQL(id, sql, idx);
+    return bindStringToSQL(entry, sql, idx + 1);
+  }
+};
+
+} // namespace comm
diff --git a/web/cpp/SQLiteQueryExecutorBindings.cpp b/web/cpp/SQLiteQueryExecutorBindings.cpp
--- a/web/cpp/SQLiteQueryExecutorBindings.cpp
+++ b/web/cpp/SQLiteQueryExecutorBindings.cpp
@@ -68,6 +68,9 @@
       .field(
           "threadActivityStoreEntry",
           &ThreadActivityEntry::thread_activity_store_entry);
+  value_object<EntryInfo>("EntryInfo")
+      .field("id", &EntryInfo::id)
+      .field("entry", &EntryInfo::entry);
 
   value_object<WebThread>("WebThread")
       .field("id", &WebThread::id)
@@ -238,6 +241,10 @@
       .function(
           "getAllThreadActivityEntries",
           &SQLiteQueryExecutor::getAllThreadActivityEntries)
+      .function("replaceEntry", &SQLiteQueryExecutor::replaceEntry)
+      .function("removeEntries", &SQLiteQueryExecutor::removeEntries)
+      .function("removeAllEntries", &SQLiteQueryExecutor::removeAllEntries)
+      .function("getAllEntries", &SQLiteQueryExecutor::getAllEntries)
       .function("beginTransaction", &SQLiteQueryExecutor::beginTransaction)
       .function("commitTransaction", &SQLiteQueryExecutor::commitTransaction)
       .function(
diff --git a/web/shared-worker/_generated/comm_query_executor.wasm b/web/shared-worker/_generated/comm_query_executor.wasm
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
GIT binary patch
literal 0
Hc$@<O00001

literal 0
Hc$@<O00001

diff --git a/web/shared-worker/queries/entry-queries.test.js b/web/shared-worker/queries/entry-queries.test.js
new file mode 100644
--- /dev/null
+++ b/web/shared-worker/queries/entry-queries.test.js
@@ -0,0 +1,116 @@
+// @flow
+
+import {
+  convertEntryInfoIntoClientDBEntryInfo,
+  entryStoreOpsHandlers,
+} from 'lib/ops/entries-store-ops.js';
+import type { RawEntryInfo } from 'lib/types/entry-types.js';
+
+import { getDatabaseModule } from '../db-module.js';
+import type { EmscriptenModule } from '../types/module.js';
+import { type SQLiteQueryExecutor } from '../types/sqlite-query-executor.js';
+import { clearSensitiveData } from '../utils/db-utils.js';
+
+const FILE_PATH = 'test.sqlite';
+
+const TEST_ENTRY_1: RawEntryInfo = {
+  creationTime: 0,
+  creatorID: '0',
+  day: 0,
+  deleted: true,
+  id: '0',
+  month: 0,
+  text: 'test_text_1',
+  threadID: '0',
+  year: 0,
+};
+
+const TEST_ENTRY_2: RawEntryInfo = {
+  creationTime: 0,
+  creatorID: '1',
+  day: 0,
+  deleted: true,
+  localID: '1',
+  month: 0,
+  text: 'test_text_2',
+  threadID: '1',
+  year: 0,
+};
+
+describe('Entry Store queries', () => {
+  let queryExecutor: ?SQLiteQueryExecutor = null;
+  let dbModule: ?EmscriptenModule = null;
+
+  beforeAll(async () => {
+    dbModule = getDatabaseModule();
+  });
+
+  beforeEach(() => {
+    if (!dbModule) {
+      throw new Error('Database module is missing');
+    }
+    queryExecutor = new dbModule.SQLiteQueryExecutor(FILE_PATH);
+    if (!queryExecutor) {
+      throw new Error('SQLiteQueryExecutor is missing');
+    }
+    queryExecutor?.replaceEntry(
+      convertEntryInfoIntoClientDBEntryInfo({ id: '0', entry: TEST_ENTRY_1 }),
+    );
+    queryExecutor?.replaceEntry(
+      convertEntryInfoIntoClientDBEntryInfo({ id: '1', entry: TEST_ENTRY_2 }),
+    );
+  });
+
+  afterEach(() => {
+    if (!dbModule || !queryExecutor) {
+      return;
+    }
+    clearSensitiveData(dbModule, FILE_PATH, queryExecutor);
+  });
+
+  it('should return all entries', () => {
+    const entries = queryExecutor?.getAllEntries();
+    expect(entries?.length).toBe(2);
+  });
+
+  it('should remove all entries', () => {
+    queryExecutor?.removeAllEntries();
+    const entries = queryExecutor?.getAllEntries();
+    expect(entries?.length).toBe(0);
+  });
+
+  it('should update text property', () => {
+    const updatedText = 'updated_test_entry_text';
+    const updatedTestEntry = {
+      ...TEST_ENTRY_2,
+      text: updatedText,
+    };
+    queryExecutor?.replaceEntry(
+      convertEntryInfoIntoClientDBEntryInfo({
+        id: '1',
+        entry: updatedTestEntry,
+      }),
+    );
+
+    const dbEntries = queryExecutor?.getAllEntries();
+    if (!dbEntries) {
+      throw new Error('entries not defined');
+    }
+
+    const entries = entryStoreOpsHandlers.translateClientDBData(dbEntries);
+    expect(entries['1']).toBeDefined();
+    expect(entries['1'].creatorID).toBe('1');
+    expect(entries['1'].text).toBe(updatedText);
+  });
+
+  it('should remove entry', () => {
+    queryExecutor?.removeEntries(['1']);
+
+    const entries = queryExecutor?.getAllEntries();
+    if (!entries) {
+      throw new Error('entries not defined');
+    }
+    expect(entries.length).toBe(1);
+    expect(entries[0].id).toBe('0');
+  });
+});
diff --git a/web/shared-worker/types/sqlite-query-executor.js b/web/shared-worker/types/sqlite-query-executor.js
--- a/web/shared-worker/types/sqlite-query-executor.js
+++ b/web/shared-worker/types/sqlite-query-executor.js
@@ -2,6 +2,7 @@
 
 import type { ClientDBAuxUserInfo } from 'lib/ops/aux-user-store-ops.js';
 import type { ClientDBCommunityInfo } from 'lib/ops/community-store-ops.js';
+import type { ClientDBEntryInfo } from 'lib/ops/entries-store-ops.js';
 import type { ClientDBIntegrityThreadHash } from 'lib/ops/integrity-store-ops.js';
 import type { ClientDBKeyserverInfo } from 'lib/ops/keyserver-store-ops.js';
 import type { ClientDBReport } from 'lib/ops/report-store-ops.js';
@@ -139,6 +140,11 @@
   removeAllThreadActivityEntries(): void;
   getAllThreadActivityEntries(): ClientDBThreadActivityEntry[];
 
+  replaceEntry(entryInfo: ClientDBEntryInfo): void;
+  removeEntries(ids: $ReadOnlyArray<string>): void;
+  removeAllEntries(): void;
+  getAllEntries(): $ReadOnlyArray<ClientDBEntryInfo>;
+
   beginTransaction(): void;
   commitTransaction(): void;
   rollbackTransaction(): void;