Re-adding SQL inserts/updates

This commit is contained in:
Noikoio 2017-12-22 19:17:36 -08:00
parent 8bb274bd69
commit 2e0b408946
2 changed files with 111 additions and 97 deletions

View file

@ -2,9 +2,6 @@
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using Noikoio.RegexBot.ConfigItem; using Noikoio.RegexBot.ConfigItem;
using Npgsql; using Npgsql;
using NpgsqlTypes;
using System;
using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Noikoio.RegexBot.EntityCache namespace Noikoio.RegexBot.EntityCache
@ -12,7 +9,7 @@ namespace Noikoio.RegexBot.EntityCache
/// <summary> /// <summary>
/// Bot module portion of the entity cache. Caches information regarding all known guilds, channels, and users. /// Bot module portion of the entity cache. Caches information regarding all known guilds, channels, and users.
/// The function of this module should be transparent to the user, and thus no configuration is needed. /// The function of this module should be transparent to the user, and thus no configuration is needed.
/// This module should be initialized BEFORE any other modules that make use of guild and user cache. /// This module should be initialized BEFORE any other modules that make use of the entity cache.
/// </summary> /// </summary>
class Module : BotModule class Module : BotModule
{ {
@ -26,7 +23,7 @@ namespace Noikoio.RegexBot.EntityCache
if (_db.Available) if (_db.Available)
{ {
SqlHelper.CreateCacheTables(); SqlHelper.CreateCacheTablesAsync().Wait();
client.GuildAvailable += Client_GuildAvailable; client.GuildAvailable += Client_GuildAvailable;
client.GuildUpdated += Client_GuildUpdated; client.GuildUpdated += Client_GuildUpdated;
@ -48,110 +45,66 @@ namespace Noikoio.RegexBot.EntityCache
{ {
await Task.Run(async () => await Task.Run(async () =>
{ {
await UpdateGuild(arg); try
await UpdateGuildMember(arg.Users); {
} await SqlHelper.UpdateGuildAsync(arg);
); await SqlHelper.UpdateGuildMemberAsync(arg.Users);
}
catch (NpgsqlException ex)
{
await Log($"SQL error in {nameof(Client_GuildAvailable)}: {ex.Message}");
}
});
} }
// Guild information has changed // Guild information has changed
private async Task Client_GuildUpdated(SocketGuild arg1, SocketGuild arg2) private async Task Client_GuildUpdated(SocketGuild arg1, SocketGuild arg2)
{ {
await Task.Run(() => UpdateGuild(arg2)); await Task.Run(async () =>
{
try
{
await SqlHelper.UpdateGuildAsync(arg2);
}
catch (NpgsqlException ex)
{
await Log($"SQL error in {nameof(Client_GuildUpdated)}: {ex.Message}");
}
});
} }
// Guild member information has changed // Guild member information has changed
private async Task Client_GuildMemberUpdated(SocketGuildUser arg1, SocketGuildUser arg2) private async Task Client_GuildMemberUpdated(SocketGuildUser arg1, SocketGuildUser arg2)
{ {
await Task.Run(() => UpdateGuildMember(arg2)); await Task.Run(async () =>
{
try
{
await SqlHelper.UpdateGuildMemberAsync(arg2);
}
catch (NpgsqlException ex)
{
await Log($"SQL error in {nameof(Client_GuildMemberUpdated)}: {ex.Message}");
}
});
} }
// A new guild member has appeared // A new guild member has appeared
private async Task Client_UserJoined(SocketGuildUser arg) private async Task Client_UserJoined(SocketGuildUser arg)
{ {
await UpdateGuildMember(arg); await Task.Run(async () =>
{
try
{
await SqlHelper.UpdateGuildMemberAsync(arg);
}
catch (NpgsqlException ex)
{
await Log($"SQL error in {nameof(Client_UserJoined)}: {ex.Message}");
}
});
} }
#endregion #endregion
private async Task UpdateGuild(SocketGuild g)
{
try
{
using (var db = await _db.GetOpenConnectionAsync())
{
using (var c = db.CreateCommand())
{
c.CommandText = "INSERT INTO " + Sql.TableGuild + " (guild_id, current_name) "
+ "VALUES (@GuildId, @CurrentName) "
+ "ON CONFLICT (guild_id) DO UPDATE SET "
+ "current_name = EXCLUDED.current_name";
c.Parameters.Add("@GuildId", NpgsqlDbType.Bigint).Value = g.Id;
c.Parameters.Add("@CurrentName", NpgsqlDbType.Text).Value = g.Name;
c.Prepare();
await c.ExecuteNonQueryAsync();
}
}
}
catch (NpgsqlException ex)
{
await Log($"SQL error in {nameof(UpdateGuild)}: " + ex.Message);
}
}
private async Task UpdateGuildMember(IEnumerable<SocketGuildUser> users)
{
try
{
using (var db = await _db.GetOpenConnectionAsync())
{
using (var c = db.CreateCommand())
{
c.CommandText = "INSERT INTO " + Sql.TableUser
+ " (user_id, guild_id, cache_date, username, discriminator, nickname, avatar_url)"
+ " VALUES (@Uid, @Gid, @Date, @Uname, @Disc, @Nname, @Url) "
+ "ON CONFLICT (user_id, guild_id) DO UPDATE SET "
+ "cache_date = EXCLUDED.cache_date, username = EXCLUDED.username, "
+ "discriminator = EXCLUDED.discriminator, " // I've seen someone's discriminator change this one time...
+ "nickname = EXCLUDED.nickname, avatar_url = EXCLUDED.avatar_url";
var uid = c.Parameters.Add("@Uid", NpgsqlDbType.Bigint);
var gid = c.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
c.Parameters.Add("@Date", NpgsqlDbType.TimestampTZ).Value = DateTime.Now;
var uname = c.Parameters.Add("@Uname", NpgsqlDbType.Text);
var disc = c.Parameters.Add("@Disc", NpgsqlDbType.Text);
var nname = c.Parameters.Add("@Nname", NpgsqlDbType.Text);
var url = c.Parameters.Add("@Url", NpgsqlDbType.Text);
c.Prepare();
foreach (var item in users)
{
if (item.IsBot || item.IsWebhook) continue;
uid.Value = item.Id;
gid.Value = item.Guild.Id;
uname.Value = item.Username;
disc.Value = item.Discriminator;
nname.Value = item.Nickname;
if (nname.Value == null) nname.Value = DBNull.Value; // why can't ?? work here?
url.Value = item.GetAvatarUrl();
if (url.Value == null) url.Value = DBNull.Value;
await c.ExecuteNonQueryAsync();
}
}
}
}
catch (NpgsqlException ex)
{
await Log($"SQL error in {nameof(UpdateGuildMember)}: " + ex.Message);
}
}
private Task UpdateGuildMember(SocketGuildUser user)
{
var gid = user.Guild.Id;
var ml = new SocketGuildUser[] { user };
return UpdateGuildMember(ml);
}
} }
} }

View file

@ -1,13 +1,15 @@
using Npgsql; using Discord.WebSocket;
using Npgsql;
using NpgsqlTypes;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Noikoio.RegexBot.EntityCache namespace Noikoio.RegexBot.EntityCache
{ {
/// <summary> /// <summary>
/// Helper methods for database operations. /// Helper methods for database operations.
/// Exceptions are not handled within methods of this class.
/// </summary> /// </summary>
static class SqlHelper static class SqlHelper
{ {
@ -21,7 +23,7 @@ namespace Noikoio.RegexBot.EntityCache
return await RegexBot.Config.Database.GetOpenConnectionAsync(); return await RegexBot.Config.Database.GetOpenConnectionAsync();
} }
public static async Task CreateCacheTables() internal static async Task CreateCacheTablesAsync()
{ {
var db = await OpenDB(); var db = await OpenDB();
if (db == null) return; if (db == null) return;
@ -84,13 +86,72 @@ namespace Noikoio.RegexBot.EntityCache
} }
#region Insertions and updates #region Insertions and updates
static async Task UpdateGuild() internal static async Task UpdateGuildAsync(SocketGuild g)
{ {
var db = await OpenDB(); var db = await OpenDB();
if (db == null) return; if (db == null) return;
using (db) using (db)
{ {
using (var c = db.CreateCommand())
{
c.CommandText = "INSERT INTO " + Sql.TableGuild + " (guild_id, current_name) "
+ "VALUES (@GuildId, @CurrentName) "
+ "ON CONFLICT (guild_id) DO UPDATE SET "
+ "current_name = EXCLUDED.current_name";
c.Parameters.Add("@GuildId", NpgsqlDbType.Bigint).Value = g.Id;
c.Parameters.Add("@CurrentName", NpgsqlDbType.Text).Value = g.Name;
c.Prepare();
await c.ExecuteNonQueryAsync();
}
}
}
internal static Task UpdateGuildMemberAsync(SocketGuildUser user)
{
var ml = new SocketGuildUser[] { user };
return UpdateGuildMemberAsync(ml);
}
internal static async Task UpdateGuildMemberAsync(IEnumerable<SocketGuildUser> users)
{
var db = await OpenDB();
if (db == null) return;
using (db)
{
using (var c = db.CreateCommand())
{
c.CommandText = "INSERT INTO " + Sql.TableUser
+ " (user_id, guild_id, cache_date, username, discriminator, nickname, avatar_url)"
+ " VALUES (@Uid, @Gid, @Date, @Uname, @Disc, @Nname, @Url) "
+ "ON CONFLICT (user_id, guild_id) DO UPDATE SET "
+ "cache_date = EXCLUDED.cache_date, username = EXCLUDED.username, "
+ "discriminator = EXCLUDED.discriminator, " // I've seen someone's discriminator change this one time...
+ "nickname = EXCLUDED.nickname, avatar_url = EXCLUDED.avatar_url";
var uid = c.Parameters.Add("@Uid", NpgsqlDbType.Bigint);
var gid = c.Parameters.Add("@Gid", NpgsqlDbType.Bigint);
c.Parameters.Add("@Date", NpgsqlDbType.TimestampTZ).Value = DateTime.Now;
var uname = c.Parameters.Add("@Uname", NpgsqlDbType.Text);
var disc = c.Parameters.Add("@Disc", NpgsqlDbType.Text);
var nname = c.Parameters.Add("@Nname", NpgsqlDbType.Text);
var url = c.Parameters.Add("@Url", NpgsqlDbType.Text);
c.Prepare();
foreach (var item in users)
{
if (item.IsBot || item.IsWebhook) continue;
uid.Value = item.Id;
gid.Value = item.Guild.Id;
uname.Value = item.Username;
disc.Value = item.Discriminator;
nname.Value = item.Nickname;
if (nname.Value == null) nname.Value = DBNull.Value; // why can't ?? work here?
url.Value = item.GetAvatarUrl();
if (url.Value == null) url.Value = DBNull.Value;
await c.ExecuteNonQueryAsync();
}
}
} }
} }
#endregion #endregion