Partial progress on DBCache

This commit is contained in:
Noikoio 2017-11-01 16:24:22 -07:00
parent 2568b11c8e
commit 244debadf2
2 changed files with 145 additions and 29 deletions

View file

@ -47,7 +47,7 @@ namespace Noikoio.RegexBot.ConfigItem
_enabled = true;
}
public async Task<NpgsqlConnection> OpenConnectionAsync(ulong? guildId)
private async Task<NpgsqlConnection> P_OpenConnectionAsync(ulong? guildId = null)
{
if (!Enabled) return null;
@ -64,5 +64,24 @@ namespace Noikoio.RegexBot.ConfigItem
await db.OpenAsync();
return db;
}
public Task<NpgsqlConnection> OpenConnectionAsync(ulong guildId) => P_OpenConnectionAsync(guildId);
public async Task CreateGuildSchemaAsync(ulong gid)
{
if (!Enabled) return;
const string cs = "CREATE SCHEMA IF NOT EXISTS {0}";
string sn = "g_" + gid.ToString();
using (var db = await P_OpenConnectionAsync())
{
using (var c = db.CreateCommand())
{
c.CommandText = string.Format(cs, sn);
await c.ExecuteNonQueryAsync();
}
}
}
}
}

View file

@ -1,9 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Discord.WebSocket;
using Discord.WebSocket;
using Newtonsoft.Json.Linq;
using Noikoio.RegexBot.ConfigItem;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Noikoio.RegexBot.Feature.DBCache
{
@ -13,21 +13,74 @@ namespace Noikoio.RegexBot.Feature.DBCache
/// </summary>
class DBCache : BotFeature
{
private readonly DatabaseConfig _db;
public override string Name => "Database cache";
public DBCache(DiscordSocketClient client) : base(client)
{
_db = RegexBot.Config.Database;
client.GuildAvailable += Client_GuildAvailable;
client.GuildUpdated += Client_GuildUpdated;
client.GuildMemberUpdated += Client_GuildMemberUpdated;
// it may not be necessary to handle JoinedGuild, as GuildAvailable still provides info
client.MessageReceived += Client_MessageReceived;
client.MessageUpdated += Client_MessageUpdated;
//client.MessageUpdated += Client_MessageUpdated;
}
public override Task<object> ProcessConfiguration(JToken configSection) => Task.FromResult<object>(null);
#region Guild and user cache
#region Event handling
// Guild _and_ guild member information has become available
private async Task Client_GuildAvailable(SocketGuild arg)
{
if (!_db.Enabled) return;
await CreateCacheTables(arg.Id);
await Task.Run(() => UpdateGuild(arg));
await Task.Run(() => UpdateGuildMember(arg.Id, arg.Users));
}
// Guild information has changed
private async Task Client_GuildUpdated(SocketGuild arg1, SocketGuild arg2)
{
if (!_db.Enabled) return;
throw new NotImplementedException();
}
// Guild member information has changed
private async Task Client_GuildMemberUpdated(SocketGuildUser arg1, SocketGuildUser arg2)
{
if (!_db.Enabled) return;
await Task.Run(() => UpdateGuildMember(arg2));
}
// A new message has been created
private async Task Client_MessageReceived(SocketMessage arg)
{
if (!_db.Enabled) return;
throw new NotImplementedException();
}
//private Task Client_MessageUpdated(Discord.Cacheable<Discord.IMessage, ulong> arg1, SocketMessage arg2, ISocketMessageChannel arg3)
/*
* Edited messages seem to retain their ID. This is a problem.
* The point of this message cache was to have another feature be able to relay
* both the previous and current message at once.
* For now: Do nothing on updated messages.
*/
#endregion
#region Table setup
const string TableGuild = "cache_guild";
const string TableUser = "cache_users";
const string TableMessage = "cache_messages";
private async Task CreateCacheTables(ulong gid)
{
/* Note:
* We save information per guild in their own schemas named "g_NUM", where NUM is the Guild ID.
*
@ -36,39 +89,83 @@ namespace Noikoio.RegexBot.Feature.DBCache
* created yet in which to put them in.
* Got to figure that out.
*/
await _db.CreateGuildSchemaAsync(gid);
// Guild information has changed
private Task Client_GuildUpdated(SocketGuild arg1, SocketGuild arg2)
using (var db = await _db.OpenConnectionAsync(gid))
{
Task<int> c1, c2, c3;
// Uh... didn't think this through. For now this is a table that'll only ever have one column.
// Got to rethink this in particular.
using (var c = db.CreateCommand())
{
c.CommandText = "CREATE TABLE IF NOT EXISTS " + TableGuild + "("
+ "snowflake bigint primary key, "
+ "current_name text not null, "
+ "display_name text null"
+ ")";
c1 = c.ExecuteNonQueryAsync();
}
using (var c = db.CreateCommand())
{
c.CommandText = "CREATE TABLE IF NOT EXISTS " + TableUser + "("
+ "snowflake bigint primary key, "
+ "cache_date timestamptz not null, "
+ "username text not null, "
+ "discriminator text not null, "
+ "nickname text null, "
+ "avatar_url text null"
+ ")";
c2 = c.ExecuteNonQueryAsync();
}
using (var c = db.CreateCommand())
{
c.CommandText = "CREATE TABLE IF NOT EXISTS " + TableMessage + "("
+ "snowflake bigint primary key, "
+ "cache_date timestamptz not null, "
+ "author bigint not null"
+ ")";
c3 = c.ExecuteNonQueryAsync();
}
await c1;
await c2;
await c3;
}
}
#endregion
#region Guild and user cache updates
private async Task UpdateGuild(SocketGuild g)
{
throw new NotImplementedException();
}
// Single guild member information has changed
private Task Client_GuildMemberUpdated(SocketGuildUser arg1, SocketGuildUser arg2)
private async Task UpdateGuildMember(ulong gid, IEnumerable<SocketGuildUser> users)
{
// which is old and which is new?
throw new NotImplementedException();
}
// All member data in a guild has become known
private Task Client_GuildAvailable(SocketGuild arg)
private Task UpdateGuildMember(SocketGuildUser user)
{
throw new NotImplementedException();
var gid = user.Guild.Id;
var ml = new SocketGuildUser[] { user };
return UpdateGuildMember(gid, ml);
}
#endregion
#region Message cache
private Task Client_MessageUpdated(Discord.Cacheable<Discord.IMessage, ulong> arg1, SocketMessage arg2, ISocketMessageChannel arg3)
private async Task CacheMessage(SocketMessage msg)
{
throw new NotImplementedException();
}
private Task Client_MessageReceived(SocketMessage arg)
private async Task UpdateMessage(SocketMessage msg)
{
throw new NotImplementedException();
}
#endregion
}
}