Update style for data classes

This commit is contained in:
Noi 2021-10-18 16:14:46 -07:00
parent fdffa5425c
commit 160152a0b4
3 changed files with 359 additions and 389 deletions

View file

@ -1,26 +1,21 @@
using Npgsql; using Npgsql;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace BirthdayBot.Data namespace BirthdayBot.Data;
{
/// <summary> internal static class Database {
/// Database access and some abstractions.
/// </summary>
internal static class Database
{
public static string DBConnectionString { get; set; } public static string DBConnectionString { get; set; }
public static async Task<NpgsqlConnection> OpenConnectionAsync() /// <summary>
{ /// Sets up and opens a database connection.
if (DBConnectionString == null) throw new Exception("Database connection string not set"); /// </summary>
public static async Task<NpgsqlConnection> OpenConnectionAsync() {
var db = new NpgsqlConnection(DBConnectionString); var db = new NpgsqlConnection(DBConnectionString);
await db.OpenAsync().ConfigureAwait(false); await db.OpenAsync().ConfigureAwait(false);
return db; return db;
} }
public static async Task DoInitialDatabaseSetupAsync() public static async Task DoInitialDatabaseSetupAsync() {
{
using var db = await OpenConnectionAsync().ConfigureAwait(false); using var db = await OpenConnectionAsync().ConfigureAwait(false);
// Refer to the methods being called for information on how the database is set up. // Refer to the methods being called for information on how the database is set up.
@ -29,4 +24,3 @@ namespace BirthdayBot.Data
await GuildUserConfiguration.DatabaseSetupAsync(db).ConfigureAwait(false); await GuildUserConfiguration.DatabaseSetupAsync(db).ConfigureAwait(false);
} }
} }
}

View file

@ -6,14 +6,13 @@ using System.Data.Common;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace BirthdayBot.Data namespace BirthdayBot.Data;
{
/// <summary> /// <summary>
/// Represents guild-specific configuration as exists in the database. /// Represents guild-specific configuration as exists in the database.
/// Updating any property requires a call to <see cref="UpdateAsync"/> for changes to take effect. /// Updating any property requires a call to <see cref="UpdateAsync"/> for changes to take effect.
/// </summary> /// </summary>
class GuildConfiguration class GuildConfiguration {
{
/// <summary> /// <summary>
/// Gets this configuration's corresponding guild ID. /// Gets this configuration's corresponding guild ID.
/// </summary> /// </summary>
@ -62,8 +61,7 @@ namespace BirthdayBot.Data
public bool AnnouncePing { get; set; } public bool AnnouncePing { get; set; }
// Called by Load. Double-check ordinals when changes are made. // Called by Load. Double-check ordinals when changes are made.
private GuildConfiguration(DbDataReader reader) private GuildConfiguration(DbDataReader reader) {
{
GuildId = (ulong)reader.GetInt64(0); GuildId = (ulong)reader.GetInt64(0);
if (!reader.IsDBNull(1)) RoleId = (ulong)reader.GetInt64(1); if (!reader.IsDBNull(1)) RoleId = (ulong)reader.GetInt64(1);
if (!reader.IsDBNull(2)) AnnounceChannelId = (ulong)reader.GetInt64(2); if (!reader.IsDBNull(2)) AnnounceChannelId = (ulong)reader.GetInt64(2);
@ -80,8 +78,7 @@ namespace BirthdayBot.Data
/// Checks if the given user exists in the block list. /// Checks if the given user exists in the block list.
/// If the server is in moderated mode, this always returns true. /// If the server is in moderated mode, this always returns true.
/// </summary> /// </summary>
public async Task<bool> IsUserBlockedAsync(ulong userId) public async Task<bool> IsUserBlockedAsync(ulong userId) {
{
if (IsModerated) return true; if (IsModerated) return true;
using var db = await Database.OpenConnectionAsync().ConfigureAwait(false); using var db = await Database.OpenConnectionAsync().ConfigureAwait(false);
@ -99,8 +96,7 @@ namespace BirthdayBot.Data
/// <summary> /// <summary>
/// Adds the specified user to the block list corresponding to this guild. /// Adds the specified user to the block list corresponding to this guild.
/// </summary> /// </summary>
public async Task BlockUserAsync(ulong userId) public async Task BlockUserAsync(ulong userId) {
{
using var db = await Database.OpenConnectionAsync().ConfigureAwait(false); using var db = await Database.OpenConnectionAsync().ConfigureAwait(false);
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"insert into {BackingTableBans} (guild_id, user_id) " c.CommandText = $"insert into {BackingTableBans} (guild_id, user_id) "
@ -117,8 +113,7 @@ namespace BirthdayBot.Data
/// Removes the specified user from the block list corresponding to this guild. /// Removes the specified user from the block list corresponding to this guild.
/// </summary> /// </summary>
/// <returns>True if a user has been removed, false if the requested user was not in this list.</returns> /// <returns>True if a user has been removed, false if the requested user was not in this list.</returns>
public async Task<bool> UnblockUserAsync(ulong userId) public async Task<bool> UnblockUserAsync(ulong userId) {
{
using var db = await Database.OpenConnectionAsync().ConfigureAwait(false); using var db = await Database.OpenConnectionAsync().ConfigureAwait(false);
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"delete from {BackingTableBans} where " c.CommandText = $"delete from {BackingTableBans} where "
@ -141,10 +136,8 @@ namespace BirthdayBot.Data
public const string BackingTable = "settings"; public const string BackingTable = "settings";
public const string BackingTableBans = "banned_users"; public const string BackingTableBans = "banned_users";
internal static async Task DatabaseSetupAsync(NpgsqlConnection db) internal static async Task DatabaseSetupAsync(NpgsqlConnection db) {
{ using (var c = db.CreateCommand()) {
using (var c = db.CreateCommand())
{
c.CommandText = $"create table if not exists {BackingTable} (" c.CommandText = $"create table if not exists {BackingTable} ("
+ "guild_id bigint primary key, " + "guild_id bigint primary key, "
+ "role_id bigint null, " + "role_id bigint null, "
@ -159,8 +152,7 @@ namespace BirthdayBot.Data
+ ")"; + ")";
await c.ExecuteNonQueryAsync().ConfigureAwait(false); await c.ExecuteNonQueryAsync().ConfigureAwait(false);
} }
using (var c = db.CreateCommand()) using (var c = db.CreateCommand()) {
{
c.CommandText = $"create table if not exists {BackingTableBans} (" c.CommandText = $"create table if not exists {BackingTableBans} ("
+ $"guild_id bigint not null references {BackingTable} ON DELETE CASCADE, " + $"guild_id bigint not null references {BackingTable} ON DELETE CASCADE, "
+ "user_id bigint not null, " + "user_id bigint not null, "
@ -177,12 +169,9 @@ namespace BirthdayBot.Data
/// If true, this method shall not create a new entry and will return null if the guild does /// If true, this method shall not create a new entry and will return null if the guild does
/// not exist in the database. /// not exist in the database.
/// </param> /// </param>
public static async Task<GuildConfiguration> LoadAsync(ulong guildId, bool nullIfUnknown) public static async Task<GuildConfiguration> LoadAsync(ulong guildId, bool nullIfUnknown) {
{ using (var db = await Database.OpenConnectionAsync().ConfigureAwait(false)) {
using (var db = await Database.OpenConnectionAsync().ConfigureAwait(false)) using (var c = db.CreateCommand()) {
{
using (var c = db.CreateCommand())
{
// Take note of ordinals for the constructor // Take note of ordinals for the constructor
c.CommandText = "select guild_id, role_id, channel_announce_id, time_zone, " c.CommandText = "select guild_id, role_id, channel_announce_id, time_zone, "
+ " moderated, moderator_role, announce_message, announce_message_pl, announce_ping " + " moderated, moderator_role, announce_message, announce_message_pl, announce_ping "
@ -195,8 +184,7 @@ namespace BirthdayBot.Data
if (nullIfUnknown) return null; if (nullIfUnknown) return null;
// If we got here, no row exists. Create it with default values. // If we got here, no row exists. Create it with default values.
using (var c = db.CreateCommand()) using (var c = db.CreateCommand()) {
{
c.CommandText = $"insert into {BackingTable} (guild_id) values (@Gid)"; c.CommandText = $"insert into {BackingTable} (guild_id) values (@Gid)";
c.Parameters.Add("@Gid", NpgsqlDbType.Bigint).Value = (long)guildId; c.Parameters.Add("@Gid", NpgsqlDbType.Bigint).Value = (long)guildId;
c.Prepare(); c.Prepare();
@ -210,8 +198,7 @@ namespace BirthdayBot.Data
/// <summary> /// <summary>
/// Updates values on the backing database with values from this object instance. /// Updates values on the backing database with values from this object instance.
/// </summary> /// </summary>
public async Task UpdateAsync() public async Task UpdateAsync() {
{
using var db = await Database.OpenConnectionAsync().ConfigureAwait(false); using var db = await Database.OpenConnectionAsync().ConfigureAwait(false);
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"update {BackingTable} set " c.CommandText = $"update {BackingTable} set "
@ -260,4 +247,3 @@ namespace BirthdayBot.Data
} }
#endregion #endregion
} }
}

View file

@ -5,13 +5,12 @@ using System.Collections.Generic;
using System.Data.Common; using System.Data.Common;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace BirthdayBot.Data namespace BirthdayBot.Data;
{
/// <summary> /// <summary>
/// Represents configuration for a guild user. /// Represents configuration for a guild user as may exist in the database.
/// </summary> /// </summary>
class GuildUserConfiguration class GuildUserConfiguration {
{
public ulong GuildId { get; } public ulong GuildId { get; }
public ulong UserId { get; } public ulong UserId { get; }
@ -31,15 +30,13 @@ namespace BirthdayBot.Data
/// Creates a new, data-less instance without a corresponding database entry. /// Creates a new, data-less instance without a corresponding database entry.
/// Calling <see cref="UpdateAsync(int, int, int)"/> will create a real database enty /// Calling <see cref="UpdateAsync(int, int, int)"/> will create a real database enty
/// </summary> /// </summary>
private GuildUserConfiguration(ulong guildId, ulong userId) private GuildUserConfiguration(ulong guildId, ulong userId) {
{
GuildId = guildId; GuildId = guildId;
UserId = userId; UserId = userId;
} }
// Called by GetGuildUsersAsync. Double-check ordinals when changes are made. // Called by GetGuildUsersAsync. Double-check ordinals when changes are made.
private GuildUserConfiguration(DbDataReader reader) private GuildUserConfiguration(DbDataReader reader) {
{
GuildId = (ulong)reader.GetInt64(0); GuildId = (ulong)reader.GetInt64(0);
UserId = (ulong)reader.GetInt64(1); UserId = (ulong)reader.GetInt64(1);
BirthMonth = reader.GetInt32(2); BirthMonth = reader.GetInt32(2);
@ -50,10 +47,8 @@ namespace BirthdayBot.Data
/// <summary> /// <summary>
/// Updates user with given information. /// Updates user with given information.
/// </summary> /// </summary>
public async Task UpdateAsync(int month, int day, string newtz) public async Task UpdateAsync(int month, int day, string newtz) {
{ using (var db = await Database.OpenConnectionAsync().ConfigureAwait(false)) {
using (var db = await Database.OpenConnectionAsync().ConfigureAwait(false))
{
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"insert into {BackingTable} " c.CommandText = $"insert into {BackingTable} "
+ "(guild_id, user_id, birth_month, birth_day, time_zone) values " + "(guild_id, user_id, birth_month, birth_day, time_zone) values "
@ -81,8 +76,7 @@ namespace BirthdayBot.Data
/// Deletes information of this user from the backing database. /// Deletes information of this user from the backing database.
/// The corresponding object reference should ideally be discarded after calling this. /// The corresponding object reference should ideally be discarded after calling this.
/// </summary> /// </summary>
public async Task DeleteAsync() public async Task DeleteAsync() {
{
using var db = await Database.OpenConnectionAsync().ConfigureAwait(false); using var db = await Database.OpenConnectionAsync().ConfigureAwait(false);
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"delete from {BackingTable} " c.CommandText = $"delete from {BackingTable} "
@ -98,8 +92,7 @@ namespace BirthdayBot.Data
// Take note of ordinals for use in the constructor // Take note of ordinals for use in the constructor
private const string SelectFields = "guild_id, user_id, birth_month, birth_day, time_zone"; private const string SelectFields = "guild_id, user_id, birth_month, birth_day, time_zone";
internal static async Task DatabaseSetupAsync(NpgsqlConnection db) internal static async Task DatabaseSetupAsync(NpgsqlConnection db) {
{
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"create table if not exists {BackingTable} (" c.CommandText = $"create table if not exists {BackingTable} ("
+ $"guild_id bigint not null references {GuildConfiguration.BackingTable} ON DELETE CASCADE, " + $"guild_id bigint not null references {GuildConfiguration.BackingTable} ON DELETE CASCADE, "
@ -116,8 +109,7 @@ namespace BirthdayBot.Data
/// <summary> /// <summary>
/// Attempts to retrieve a user's configuration. Returns a new, updateable instance if none is found. /// Attempts to retrieve a user's configuration. Returns a new, updateable instance if none is found.
/// </summary> /// </summary>
public static async Task<GuildUserConfiguration> LoadAsync(ulong guildId, ulong userId) public static async Task<GuildUserConfiguration> LoadAsync(ulong guildId, ulong userId) {
{
using var db = await Database.OpenConnectionAsync().ConfigureAwait(false); using var db = await Database.OpenConnectionAsync().ConfigureAwait(false);
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"select {SelectFields} from {BackingTable} where guild_id = @Gid and user_id = @Uid"; c.CommandText = $"select {SelectFields} from {BackingTable} where guild_id = @Gid and user_id = @Uid";
@ -133,8 +125,7 @@ namespace BirthdayBot.Data
/// <summary> /// <summary>
/// Gets all known user configuration records associated with the specified guild. /// Gets all known user configuration records associated with the specified guild.
/// </summary> /// </summary>
public static async Task<IEnumerable<GuildUserConfiguration>> LoadAllAsync(ulong guildId) public static async Task<IEnumerable<GuildUserConfiguration>> LoadAllAsync(ulong guildId) {
{
using var db = await Database.OpenConnectionAsync().ConfigureAwait(false); using var db = await Database.OpenConnectionAsync().ConfigureAwait(false);
using var c = db.CreateCommand(); using var c = db.CreateCommand();
c.CommandText = $"select {SelectFields} from {BackingTable} where guild_id = @Gid"; c.CommandText = $"select {SelectFields} from {BackingTable} where guild_id = @Gid";
@ -148,4 +139,3 @@ namespace BirthdayBot.Data
} }
#endregion #endregion
} }
}