Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3350750
D12138.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
D12138.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D12138: Implement SQLite API to handle entry store
Attached
Detach File
Event Timeline
Log In to Comment