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 System;
using System.Threading.Tasks;
namespace BirthdayBot.Data
{
/// <summary>
/// Database access and some abstractions.
/// </summary>
internal static class Database
{
namespace BirthdayBot.Data;
internal static class Database {
public static string DBConnectionString { get; set; }
public static async Task<NpgsqlConnection> OpenConnectionAsync()
{
if (DBConnectionString == null) throw new Exception("Database connection string not set");
/// <summary>
/// Sets up and opens a database connection.
/// </summary>
public static async Task<NpgsqlConnection> OpenConnectionAsync() {
var db = new NpgsqlConnection(DBConnectionString);
await db.OpenAsync().ConfigureAwait(false);
return db;
}
public static async Task DoInitialDatabaseSetupAsync()
{
public static async Task DoInitialDatabaseSetupAsync() {
using var db = await OpenConnectionAsync().ConfigureAwait(false);
// 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);
}
}
}

View file

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

View file

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