Page MenuHomePhabricator

D12138.diff
No OneTemporary

D12138.diff

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;

File Metadata

Mime Type
text/plain
Expires
Sat, Nov 23, 11:49 PM (20 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2572874
Default Alt Text
D12138.diff (11 KB)

Event Timeline