Move friendLog to SQLite

This commit is contained in:
Natsumi
2021-07-02 20:16:19 +12:00
parent 6cb5f2028d
commit 08a32e27f0
3 changed files with 195 additions and 74 deletions

View File

@@ -1,4 +1,4 @@
// Copyright(c) 2019 pypy. All rights reserved. // Copyright(c) 2019 pypy. All rights reserved.
// //
// This work is licensed under the terms of the MIT license. // This work is licensed under the terms of the MIT license.
// For a copy, see <https://opensource.org/licenses/MIT>. // For a copy, see <https://opensource.org/licenses/MIT>.
@@ -122,5 +122,18 @@ namespace VRCX
m_Lock.ExitWriteLock(); m_Lock.ExitWriteLock();
} }
} }
public string GetAll()
{
m_Lock.EnterReadLock();
try
{
return System.Text.Json.JsonSerializer.Serialize(m_Storage);
}
finally
{
m_Lock.ExitReadLock();
}
}
} }
} }

View File

@@ -5285,14 +5285,12 @@ speechSynthesis.getVoices();
}; };
$app.methods.migrateMemos = function () { $app.methods.migrateMemos = function () {
//move memos from json to SQLite
var json = JSON.parse(VRCXStorage.GetAll()); var json = JSON.parse(VRCXStorage.GetAll());
for (var line in json) { for (var line in json) {
if (line.substring(0, 8) === 'memo_usr') { if (line.substring(0, 8) === 'memo_usr') {
var userId = line.substring(5); var userId = line.substring(5);
var memo = json[line]; var memo = json[line];
if (memo) { if (memo) {
console.log(userId);
this.saveMemo(userId, memo); this.saveMemo(userId, memo);
VRCXStorage.Remove(`memo_${userId}`); VRCXStorage.Remove(`memo_${userId}`);
} }
@@ -5428,7 +5426,6 @@ speechSynthesis.getVoices();
}); });
API.$on('USER:CURRENT', function (args) { API.$on('USER:CURRENT', function (args) {
// initFriendship()이 LOGIN에서 처리되기 때문에
// USER:CURRENT에서 처리를 함 // USER:CURRENT에서 처리를 함
$app.refreshFriends(args.ref, args.origin); $app.refreshFriends(args.ref, args.origin);
}); });
@@ -5507,7 +5504,7 @@ speechSynthesis.getVoices();
ctx.memo = memo; ctx.memo = memo;
}); });
if (typeof ref === 'undefined') { if (typeof ref === 'undefined') {
ref = this.friendLog[id]; ref = this.friendLog.get(id);
if (typeof ref !== 'undefined' && if (typeof ref !== 'undefined' &&
ref.displayName) { ref.displayName) {
ctx.name = ref.displayName; ctx.name = ref.displayName;
@@ -6141,9 +6138,14 @@ speechSynthesis.getVoices();
await database.init(args.json.id); await database.init(args.json.id);
$app.feedTable.data = await database.getFeedDatabase(); $app.feedTable.data = await database.getFeedDatabase();
$app.sweepFeed(); $app.sweepFeed();
//remove old table //remove old data from json file and migrate them to SQLite
VRCXStorage.Remove(`${args.ref.id}_feedTable`); VRCXStorage.Remove(`${args.json.id}_feedTable`);
$app.migrateMemos(); $app.migrateMemos();
if (VRCXStorage.Get(`${args.json.id}_friendLogUpdatedAt`)) {
$app.migrateFriendLog(args.json.id);
} else {
$app.initFriendLog();
}
}); });
API.$on('USER:UPDATE', async function (args) { API.$on('USER:UPDATE', async function (args) {
@@ -6852,7 +6854,7 @@ speechSynthesis.getVoices();
if (type === 'friend') { if (type === 'friend') {
var ref = API.cachedUsers.get(objectId); var ref = API.cachedUsers.get(objectId);
if (typeof ref === 'undefined') { if (typeof ref === 'undefined') {
ref = this.friendLog[objectId]; ref = this.friendLog.get(objectId);
if (typeof ref !== 'undefined' && if (typeof ref !== 'undefined' &&
ref.displayName) { ref.displayName) {
ctx.name = ref.displayName; ctx.name = ref.displayName;
@@ -7032,7 +7034,7 @@ speechSynthesis.getVoices();
// App: friendLog // App: friendLog
$app.data.friendLog = {}; $app.data.friendLog = new Map();
$app.data.friendLogTable = { $app.data.friendLogTable = {
data: [], data: [],
filters: [ filters: [
@@ -7067,10 +7069,6 @@ speechSynthesis.getVoices();
} }
}; };
API.$on('LOGIN', function (args) {
$app.initFriendship(args.ref);
});
API.$on('USER:CURRENT', function (args) { API.$on('USER:CURRENT', function (args) {
$app.updateFriendships(args.ref); $app.updateFriendships(args.ref);
}); });
@@ -7092,13 +7090,14 @@ speechSynthesis.getVoices();
if (typeof ref === 'undefined') { if (typeof ref === 'undefined') {
return; return;
} }
$app.friendLogTable.data.push({ var friendLogHistory = {
created_at: new Date().toJSON(), created_at: new Date().toJSON(),
type: 'FriendRequest', type: 'FriendRequest',
userId: ref.id, userId: ref.id,
displayName: ref.displayName displayName: ref.displayName
}); };
$app.saveFriendLog(); $app.friendLogTable.data.push(friendLogHistory);
database.addFriendLogHistory(friendLogHistory);
}); });
API.$on('FRIEND:REQUEST:CANCEL', function (args) { API.$on('FRIEND:REQUEST:CANCEL', function (args) {
@@ -7106,56 +7105,54 @@ speechSynthesis.getVoices();
if (typeof ref === 'undefined') { if (typeof ref === 'undefined') {
return; return;
} }
$app.friendLogTable.data.push({ var friendLogHistory = {
created_at: new Date().toJSON(), created_at: new Date().toJSON(),
type: 'CancelFriendRequst', type: 'CancelFriendRequst',
userId: ref.id, userId: ref.id,
displayName: ref.displayName displayName: ref.displayName
}); };
$app.saveFriendLog(); $app.friendLogTable.data.push(friendLogHistory);
database.addFriendLogHistory(friendLogHistory);
}); });
var saveFriendLogTimer = null; $app.data.friendLogInitStatus = false;
$app.methods.saveFriendLog = function () {
if (saveFriendLogTimer !== null) { $app.methods.migrateFriendLog = function (userId) {
return; this.friendLog = new Map();
var oldFriendLog = VRCXStorage.GetObject(`${userId}_friendLog`);
for (var i in oldFriendLog) {
var friend = oldFriendLog[i];
var row = {
userId: friend.id,
displayName: friend.displayName,
trustLevel: friend.trustLevel
};
this.friendLog.set(friend.id, row);
database.setFriendLogCurrent(row);
} }
this.updateSharedFeed(true); VRCXStorage.Remove(`${userId}_friendLog`);
saveFriendLogTimer = setTimeout(() => { this.friendLogTable.data = VRCXStorage.GetArray(`${userId}_friendLogTable`);
saveFriendLogTimer = null; for (var line of this.friendLogTable.data) {
VRCXStorage.SetObject(`${API.currentUser.id}_friendLog`, this.friendLog); database.addFriendLogHistory(line);
VRCXStorage.SetArray(`${API.currentUser.id}_friendLogTable`, this.friendLogTable.data); }
VRCXStorage.Set(`${API.currentUser.id}_friendLogUpdatedAt`, new Date().toJSON()); VRCXStorage.Remove(`${userId}_friendLogTable`);
}, 1); VRCXStorage.Remove(`${userId}_friendLogUpdatedAt`);
this.friendLogInitStatus = true;
}; };
$app.methods.initFriendship = function (ref) { $app.methods.initFriendLog = async function () {
if (VRCXStorage.Get(`${ref.id}_friendLogUpdatedAt`)) { this.friendLog = new Map();
this.friendLog = VRCXStorage.GetObject(`${ref.id}_friendLog`); var friendLogCurrentArray = await database.getFriendLogCurrent();
this.friendLogTable.data = VRCXStorage.GetArray(`${ref.id}_friendLogTable`); for (var friend of friendLogCurrentArray) {
} else { this.friendLog.set(friend.userId, friend);
var friendLog = {};
for (var id of ref.friends) {
// DO NOT set displayName,
// it's flag about it's new friend
var ctx = {
id
};
var user = API.cachedUsers.get(id);
if (typeof user !== 'undefined') {
ctx.displayName = user.displayName;
ctx.trustLevel = user.$trustLevel;
}
friendLog[id] = ctx;
}
this.friendLog = friendLog;
this.friendLogTable.data = [];
this.saveFriendLog();
} }
this.friendLogTable.data = [];
this.friendLogTable.data = await database.getFriendLogHistory();
this.friendLogInitStatus = true;
}; };
$app.methods.addFriendship = function (id) { $app.methods.addFriendship = function (id) {
if (typeof this.friendLog[id] !== 'undefined') { if ((!this.friendLogInitStatus) || (this.friendLog.has(id))) {
return; return;
} }
var ctx = { var ctx = {
@@ -7163,35 +7160,44 @@ speechSynthesis.getVoices();
displayName: null, displayName: null,
trustLevel: null trustLevel: null
}; };
Vue.set(this.friendLog, id, ctx);
var ref = API.cachedUsers.get(id); var ref = API.cachedUsers.get(id);
if (typeof ref !== 'undefined') { if (typeof ref !== 'undefined') {
ctx.displayName = ref.displayName; ctx.displayName = ref.displayName;
ctx.trustLevel = ref.$trustLevel; ctx.trustLevel = ref.$trustLevel;
this.friendLogTable.data.push({ var friendLogHistory = {
created_at: new Date().toJSON(), created_at: new Date().toJSON(),
type: 'Friend', type: 'Friend',
userId: ref.id, userId: id,
displayName: ctx.displayName displayName: ctx.displayName
}); };
this.friendLogTable.data.push(friendLogHistory);
database.addFriendLogHistory(friendLogHistory);
} }
this.saveFriendLog(); var friendLogCurrent = {
userId: id,
displayName: ctx.displayName,
trustLevel: ctx.trustLevel
};
this.friendLog.set(id, friendLogCurrent);
database.setFriendLogCurrent(friendLogCurrent);
this.notifyMenu('friendLog'); this.notifyMenu('friendLog');
}; };
$app.methods.deleteFriendship = function (id) { $app.methods.deleteFriendship = function (id) {
var ctx = this.friendLog[id]; var ctx = this.friendLog.get(id);
if (typeof ctx === 'undefined') { if (typeof ctx === 'undefined') {
return; return;
} }
Vue.delete(this.friendLog, id); var friendLogHistory = {
this.friendLogTable.data.push({
created_at: new Date().toJSON(), created_at: new Date().toJSON(),
type: 'Unfriend', type: 'Unfriend',
userId: id, userId: id,
displayName: ctx.displayName displayName: ctx.displayName
}); };
this.saveFriendLog(); this.friendLogTable.data.push(friendLogHistory);
database.addFriendLogHistory(friendLogHistory);
this.friendLog.delete(id);
database.deleteFriendLogCurrent(id);
this.notifyMenu('friendLog'); this.notifyMenu('friendLog');
}; };
@@ -7209,47 +7215,61 @@ speechSynthesis.getVoices();
}; };
$app.methods.updateFriendship = function (ref) { $app.methods.updateFriendship = function (ref) {
var ctx = this.friendLog[ref.id]; var ctx = this.friendLog.get(ref.id);
if (typeof ctx === 'undefined') { if ((!this.friendLogInitStatus) || (typeof ctx === 'undefined')) {
return; return;
} }
if (ctx.displayName !== ref.displayName) { if (ctx.displayName !== ref.displayName) {
if (ctx.displayName) { if (ctx.displayName) {
this.friendLogTable.data.push({ var friendLogHistory = {
created_at: new Date().toJSON(), created_at: new Date().toJSON(),
type: 'DisplayName', type: 'DisplayName',
userId: ref.id, userId: ref.id,
displayName: ref.displayName, displayName: ref.displayName,
previousDisplayName: ctx.displayName previousDisplayName: ctx.displayName
}); };
this.friendLogTable.data.push(friendLogHistory);
database.addFriendLogHistory(friendLogHistory);
} else if (ctx.displayName === null) { } else if (ctx.displayName === null) {
this.friendLogTable.data.push({ var friendLogHistory = {
created_at: new Date().toJSON(), created_at: new Date().toJSON(),
type: 'Friend', type: 'Friend',
userId: ref.id, userId: ref.id,
displayName: ref.displayName displayName: ref.displayName
}); };
this.friendLogTable.data.push(friendLogHistory);
database.addFriendLogHistory(friendLogHistory);
} }
ctx.displayName = ref.displayName; ctx.displayName = ref.displayName;
this.saveFriendLog();
this.notifyMenu('friendLog'); this.notifyMenu('friendLog');
} }
if (ref.$trustLevel && if (ref.$trustLevel &&
ctx.trustLevel !== ref.$trustLevel) { ctx.trustLevel !== ref.$trustLevel) {
if (ctx.trustLevel) { if (ctx.trustLevel) {
this.friendLogTable.data.push({ var friendLogHistory = {
created_at: new Date().toJSON(), created_at: new Date().toJSON(),
type: 'TrustLevel', type: 'TrustLevel',
userId: ref.id, userId: ref.id,
displayName: ref.displayName, displayName: ref.displayName,
trustLevel: ref.$trustLevel, trustLevel: ref.$trustLevel,
previousTrustLevel: ctx.trustLevel previousTrustLevel: ctx.trustLevel
}); };
this.friendLogTable.data.push(friendLogHistory);
database.addFriendLogHistory(friendLogHistory);
} }
ctx.trustLevel = ref.$trustLevel; ctx.trustLevel = ref.$trustLevel;
this.saveFriendLog();
this.notifyMenu('friendLog'); this.notifyMenu('friendLog');
} }
if ((ctx.displayName !== ref.displayName) ||
((ref.$trustLevel) && (ctx.trustLevel !== ref.$trustLevel))) {
var friendLogCurrent = {
userId: ref.id,
displayName: ref.displayName,
trustLevel: ref.trustLevel
};
this.friendLog.set(ref.id, friendLogCurrent);
database.setFriendLogCurrent(friendLogCurrent);
}
}; };
$app.methods.deleteFriendLog = function (row) { $app.methods.deleteFriendLog = function (row) {
@@ -7261,7 +7281,7 @@ speechSynthesis.getVoices();
callback: (action) => { callback: (action) => {
if (action === 'confirm' && if (action === 'confirm' &&
removeFromArray(this.friendLogTable.data, row)) { removeFromArray(this.friendLogTable.data, row)) {
this.saveFriendLog(); database.deleteFriendLogHistory(row.rowId);
} }
} }
}); });

View File

@@ -15,6 +15,12 @@ class Database {
await sqliteService.executeNonQuery( await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS ${Database.userId}_feed_online_offline (id INTEGER PRIMARY KEY, created_at TEXT, user_id TEXT, display_name TEXT, type TEXT, location TEXT, world_name TEXT, time INTEGER)` `CREATE TABLE IF NOT EXISTS ${Database.userId}_feed_online_offline (id INTEGER PRIMARY KEY, created_at TEXT, user_id TEXT, display_name TEXT, type TEXT, location TEXT, world_name TEXT, time INTEGER)`
); );
await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS ${Database.userId}_friend_log_current (user_id TEXT PRIMARY KEY, display_name TEXT, trust_level TEXT)`
);
await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS ${Database.userId}_friend_log_history (id INTEGER PRIMARY KEY, created_at TEXT, type TEXT, user_id TEXT, display_name TEXT, previous_display_name TEXT, trust_level TEXT, previous_trust_level TEXT)`
);
await sqliteService.executeNonQuery( await sqliteService.executeNonQuery(
`CREATE TABLE IF NOT EXISTS memos (user_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)` `CREATE TABLE IF NOT EXISTS memos (user_id TEXT PRIMARY KEY, edited_at TEXT, memo TEXT)`
); );
@@ -27,6 +33,7 @@ class Database {
var dateOffset = date.toJSON(); var dateOffset = date.toJSON();
await sqliteService.execute((dbRow) => { await sqliteService.execute((dbRow) => {
var row = { var row = {
rowId: dbRow[0],
created_at: dbRow[1], created_at: dbRow[1],
userId: dbRow[2], userId: dbRow[2],
displayName: dbRow[3], displayName: dbRow[3],
@@ -40,6 +47,7 @@ class Database {
}, `SELECT * FROM ${Database.userId}_feed_gps WHERE created_at >= date('${dateOffset}')`); }, `SELECT * FROM ${Database.userId}_feed_gps WHERE created_at >= date('${dateOffset}')`);
await sqliteService.execute((dbRow) => { await sqliteService.execute((dbRow) => {
var row = { var row = {
rowId: dbRow[0],
created_at: dbRow[1], created_at: dbRow[1],
userId: dbRow[2], userId: dbRow[2],
displayName: dbRow[3], displayName: dbRow[3],
@@ -53,6 +61,7 @@ class Database {
}, `SELECT * FROM ${Database.userId}_feed_status WHERE created_at >= date('${dateOffset}')`); }, `SELECT * FROM ${Database.userId}_feed_status WHERE created_at >= date('${dateOffset}')`);
await sqliteService.execute((dbRow) => { await sqliteService.execute((dbRow) => {
var row = { var row = {
rowId: dbRow[0],
created_at: dbRow[1], created_at: dbRow[1],
userId: dbRow[2], userId: dbRow[2],
displayName: dbRow[3], displayName: dbRow[3],
@@ -68,6 +77,7 @@ class Database {
}, `SELECT * FROM ${Database.userId}_feed_avatar WHERE created_at >= date('${dateOffset}')`); }, `SELECT * FROM ${Database.userId}_feed_avatar WHERE created_at >= date('${dateOffset}')`);
await sqliteService.execute((dbRow) => { await sqliteService.execute((dbRow) => {
var row = { var row = {
rowId: dbRow[0],
created_at: dbRow[1], created_at: dbRow[1],
userId: dbRow[2], userId: dbRow[2],
displayName: dbRow[3], displayName: dbRow[3],
@@ -125,6 +135,84 @@ class Database {
); );
} }
async getFriendLogCurrent() {
var friendLogCurrent = [];
await sqliteService.execute((dbRow) => {
var row = {
userId: dbRow[0],
displayName: dbRow[1],
trustLevel: dbRow[2]
};
friendLogCurrent.unshift(row);
}, `SELECT * FROM ${Database.userId}_friend_log_current`);
return friendLogCurrent;
}
setFriendLogCurrent(entry) {
sqliteService.executeNonQuery(
`INSERT OR REPLACE INTO ${Database.userId}_friend_log_current (user_id, display_name, trust_level) VALUES (@user_id, @display_name, @trust_level)`,
{
'@user_id': entry.userId,
'@display_name': entry.displayName,
'@trust_level': entry.trustLevel
}
);
}
deleteFriendLogCurrent(userId) {
sqliteService.executeNonQuery(
`DELETE FROM ${Database.userId}_friend_log_current WHERE user_id = @user_id`,
{
'@user_id': userId
}
);
}
async getFriendLogHistory() {
var friendLogHistory = [];
await sqliteService.execute((dbRow) => {
var row = {
rowId: dbRow[0],
created_at: dbRow[1],
type: dbRow[2],
userId: dbRow[3],
displayName: dbRow[4]
};
if (row.type === 'DisplayName') {
row.previousDisplayName = dbRow[5];
} else if (row.type === 'TrustLevel') {
row.trustLevel = dbRow[6];
row.previousTrustLevel = dbRow[7];
}
friendLogHistory.unshift(row);
}, `SELECT * FROM ${Database.userId}_friend_log_history`);
return friendLogHistory;
}
addFriendLogHistory(entry) {
sqliteService.executeNonQuery(
`INSERT OR IGNORE INTO ${Database.userId}_friend_log_history (created_at, type, user_id, display_name, previous_display_name, trust_level, previous_trust_level) VALUES (@created_at, @type, @user_id, @display_name, @previous_display_name, @trust_level, @previous_trust_level)`,
{
'@created_at': entry.created_at,
'@type': entry.type,
'@user_id': entry.userId,
'@display_name': entry.displayName,
'@previous_display_name': entry.previousDisplayName,
'@trust_level': entry.trustLevel,
'@previous_trust_level': entry.previousTrustLevel
}
);
}
deleteFriendLogHistory(rowId) {
sqliteService.executeNonQuery(
`DELETE FROM ${Database.userId}_friend_log_history WHERE id = @row_id`,
{
'@row_id': rowId
}
);
}
addGPSToDatabase(entry) { addGPSToDatabase(entry) {
sqliteService.executeNonQuery( sqliteService.executeNonQuery(
`INSERT OR IGNORE INTO ${Database.userId}_feed_gps (created_at, user_id, display_name, location, world_name, previous_location, time) VALUES (@created_at, @user_id, @display_name, @location, @world_name, @previous_location, @time)`, `INSERT OR IGNORE INTO ${Database.userId}_feed_gps (created_at, user_id, display_name, location, world_name, previous_location, time) VALUES (@created_at, @user_id, @display_name, @location, @world_name, @previous_location, @time)`,