From d2f31d07308d3c6c84fb832fb7841f444f451de0 Mon Sep 17 00:00:00 2001 From: runebaas Date: Thu, 10 May 2018 00:00:51 +0200 Subject: [PATCH] Use Postgresql, add db run params, npgsql logging adapter and empty models --- Geekbot.net/Commands/Utils/Quote/Quote.cs | 22 +++--- Geekbot.net/Database/DatabaseContext.cs | 16 ++-- Geekbot.net/Database/DatabaseInitializer.cs | 16 +++- Geekbot.net/Database/InMemoryDatabase.cs | 3 +- .../LoggingAdapter/NpgsqlLoggingAdapter.cs | 73 +++++++++++++++++++ .../NpgsqlLoggingProviderAdapter.cs | 20 +++++ .../Database/Models/GuildSettingsModel.cs | 7 ++ Geekbot.net/Database/Models/GuildsModel.cs | 7 ++ Geekbot.net/Database/Models/KarmaModel.cs | 7 ++ .../Database/{ => Models}/QuoteModel.cs | 7 +- .../Database/Models/RoleSelfServiceModel.cs | 7 ++ Geekbot.net/Database/Models/ShipsModel.cs | 7 ++ Geekbot.net/Database/Models/SlapsModel.cs | 7 ++ Geekbot.net/Database/Models/UserModel.cs | 7 ++ Geekbot.net/Database/SqlConnectionString.cs | 12 +-- Geekbot.net/Database/SqlDatabase.cs | 4 +- Geekbot.net/Geekbot.net.csproj | 6 +- Geekbot.net/Lib/Extensions/LongExtensions.cs | 12 +++ Geekbot.net/Lib/Extensions/UlongExtensions.cs | 12 +++ Geekbot.net/Lib/Logger/GeekbotLogger.cs | 10 +++ Geekbot.net/Lib/Logger/IGeekbotLogger.cs | 2 + Geekbot.net/Lib/Logger/LogSource.cs | 1 + Geekbot.net/Lib/Logger/LoggerFactory.cs | 2 +- Geekbot.net/Lib/RunParameters.cs | 24 +++++- 24 files changed, 252 insertions(+), 39 deletions(-) create mode 100644 Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingAdapter.cs create mode 100644 Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingProviderAdapter.cs create mode 100644 Geekbot.net/Database/Models/GuildSettingsModel.cs create mode 100644 Geekbot.net/Database/Models/GuildsModel.cs create mode 100644 Geekbot.net/Database/Models/KarmaModel.cs rename Geekbot.net/Database/{ => Models}/QuoteModel.cs (73%) create mode 100644 Geekbot.net/Database/Models/RoleSelfServiceModel.cs create mode 100644 Geekbot.net/Database/Models/ShipsModel.cs create mode 100644 Geekbot.net/Database/Models/SlapsModel.cs create mode 100644 Geekbot.net/Database/Models/UserModel.cs create mode 100644 Geekbot.net/Lib/Extensions/LongExtensions.cs create mode 100644 Geekbot.net/Lib/Extensions/UlongExtensions.cs diff --git a/Geekbot.net/Commands/Utils/Quote/Quote.cs b/Geekbot.net/Commands/Utils/Quote/Quote.cs index 8186f56..18eab22 100644 --- a/Geekbot.net/Commands/Utils/Quote/Quote.cs +++ b/Geekbot.net/Commands/Utils/Quote/Quote.cs @@ -4,10 +4,11 @@ using System.Threading.Tasks; using Discord; using Discord.Commands; using Geekbot.net.Database; +using Geekbot.net.Database.Models; using Geekbot.net.Lib; using Geekbot.net.Lib.ErrorHandling; +using Geekbot.net.Lib.Extensions; using Geekbot.net.Lib.Polyfills; -using Newtonsoft.Json; using StackExchange.Redis; namespace Geekbot.net.Commands.Utils.Quote @@ -33,7 +34,7 @@ namespace Geekbot.net.Commands.Utils.Quote { try { - var s = _database.Quotes.OrderBy(e => e.GuildId).Where(e => e.GuildId.Equals(Context.Guild.Id)).ToList(); + var s = _database.Quotes.Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong())).ToList(); if (!s.Any()) { @@ -41,8 +42,8 @@ namespace Geekbot.net.Commands.Utils.Quote return; } - var random = new Random().Next(1, s.Count()); - var quote = s[random - 1]; + var random = new Random().Next(s.Count()); + var quote = s[random]; var embed = QuoteBuilder(quote); await ReplyAsync("", false, embed.Build()); @@ -172,7 +173,7 @@ namespace Geekbot.net.Commands.Utils.Quote { try { - var quote = _database.Quotes.Where(e => e.GuildId == Context.Guild.Id && e.InternalId == id)?.FirstOrDefault(); + var quote = _database.Quotes.Where(e => e.GuildId == Context.Guild.Id.AsLong() && e.InternalId == id)?.FirstOrDefault(); if (quote != null) { _database.Quotes.Remove(quote); @@ -212,7 +213,7 @@ namespace Geekbot.net.Commands.Utils.Quote private EmbedBuilder QuoteBuilder(QuoteModel quote) { - var user = Context.Client.GetUserAsync(quote.UserId).Result ?? new UserPolyfillDto { Username = "Unknown User" }; + var user = Context.Client.GetUserAsync(quote.UserId.AsUlong()).Result ?? new UserPolyfillDto { Username = "Unknown User" }; var eb = new EmbedBuilder(); eb.WithColor(new Color(143, 167, 232)); eb.Title = $"#{quote.InternalId} | {user.Username} @ {quote.Time.Day}.{quote.Time.Month}.{quote.Time.Year}"; @@ -234,12 +235,15 @@ namespace Geekbot.net.Commands.Utils.Quote image = null; } - var internalId = _database.Quotes.Count(e => e.GuildId == Context.Guild.Id); + var last = _database.Quotes.Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong())) + .OrderByDescending(e => e.InternalId).FirstOrDefault(); + int internalId = 1; + if (last != null) internalId = last.InternalId + 1; return new QuoteModel() { InternalId = internalId, - GuildId = Context.Guild.Id, - UserId = message.Author.Id, + GuildId = Context.Guild.Id.AsLong(), + UserId = message.Author.Id.AsLong(), Time = message.Timestamp.DateTime, Quote = message.Content, Image = image diff --git a/Geekbot.net/Database/DatabaseContext.cs b/Geekbot.net/Database/DatabaseContext.cs index d2645a1..4426c8d 100644 --- a/Geekbot.net/Database/DatabaseContext.cs +++ b/Geekbot.net/Database/DatabaseContext.cs @@ -1,15 +1,17 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; +using Geekbot.net.Database.Models; +using Microsoft.EntityFrameworkCore; namespace Geekbot.net.Database { public class DatabaseContext : DbContext { public DbSet Quotes { get; set; } - - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole()) -// .UseInMemoryDatabase(databaseName: "Geekbot"); - .UseMySql(@"Server=localhost;database=geekbot;uid=geekbot;"); +// public DbSet Users { get; set; } +// public DbSet Guilds { get; set; } +// public DbSet GuildSettings { get; set; } +// public DbSet Karma { get; set; } +// public DbSet Ships { get; set; } +// public DbSet RoleSelfService { get; set; } +// public DbSet SlapsModels { get; set; } } } \ No newline at end of file diff --git a/Geekbot.net/Database/DatabaseInitializer.cs b/Geekbot.net/Database/DatabaseInitializer.cs index 838eb48..f4bb8f1 100644 --- a/Geekbot.net/Database/DatabaseInitializer.cs +++ b/Geekbot.net/Database/DatabaseInitializer.cs @@ -1,6 +1,8 @@ using System; +using Geekbot.net.Database.LoggingAdapter; using Geekbot.net.Lib; using Geekbot.net.Lib.Logger; +using Npgsql.Logging; namespace Geekbot.net.Database { @@ -26,9 +28,16 @@ namespace Geekbot.net.Database } else { - database = new SqlDatabase(new SqlConnectionString()); + NpgsqlLogManager.Provider = new NpgsqlLoggingProviderAdapter(_logger); + database = new SqlDatabase(new SqlConnectionString + { + Host = _runParameters.DbHost, + Port = _runParameters.DbPort, + Database = _runParameters.DbDatabase, + Username = _runParameters.DbUser, + Password = _runParameters.DbPassword + }); } - database.Database.EnsureCreated(); } catch (Exception e) @@ -36,7 +45,8 @@ namespace Geekbot.net.Database _logger.Error(LogSource.Geekbot, "Could not Connect to datbase", e); Environment.Exit(GeekbotExitCode.DatabaseConnectionFailed.GetHashCode()); } - + + _logger.Information(LogSource.Database, $"Connected with {database.Database.ProviderName}"); return database; } } diff --git a/Geekbot.net/Database/InMemoryDatabase.cs b/Geekbot.net/Database/InMemoryDatabase.cs index cfef816..178c0e3 100644 --- a/Geekbot.net/Database/InMemoryDatabase.cs +++ b/Geekbot.net/Database/InMemoryDatabase.cs @@ -13,7 +13,6 @@ namespace Geekbot.net.Database } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole()) - .UseInMemoryDatabase(databaseName: _name); + => optionsBuilder.UseInMemoryDatabase(databaseName: _name); } } \ No newline at end of file diff --git a/Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingAdapter.cs b/Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingAdapter.cs new file mode 100644 index 0000000..80d60b3 --- /dev/null +++ b/Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingAdapter.cs @@ -0,0 +1,73 @@ +using System; +using Geekbot.net.Lib.Logger; +using Npgsql.Logging; +using LogLevel = NLog.LogLevel; + +namespace Geekbot.net.Database.LoggingAdapter +{ + public class NpgsqlLoggingAdapter : NpgsqlLogger + { + private readonly string _name; + private readonly IGeekbotLogger _geekbotLogger; + + public NpgsqlLoggingAdapter(string name, IGeekbotLogger geekbotLogger) + { + _name = name.Substring(7); + _geekbotLogger = geekbotLogger; + geekbotLogger.Trace(LogSource.Database, $"Loaded Npgsql logging adapter: {name}"); + } + + public override bool IsEnabled(NpgsqlLogLevel level) + { + return !_geekbotLogger.LogAsJson() && _geekbotLogger.GetNLogger().IsEnabled(ToGeekbotLogLevel(level)); + } + + public override void Log(NpgsqlLogLevel level, int connectorId, string msg, Exception exception = null) + { + var nameAndMessage = $"{_name}: {msg}"; + switch (level) + { + case NpgsqlLogLevel.Trace: + _geekbotLogger.Trace(LogSource.Database, nameAndMessage); + break; + case NpgsqlLogLevel.Debug: + _geekbotLogger.Debug(LogSource.Database, nameAndMessage); + break; + case NpgsqlLogLevel.Info: + _geekbotLogger.Information(LogSource.Database, nameAndMessage); + break; + case NpgsqlLogLevel.Warn: + _geekbotLogger.Warning(LogSource.Database, nameAndMessage, exception); + break; + case NpgsqlLogLevel.Error: + case NpgsqlLogLevel.Fatal: + _geekbotLogger.Error(LogSource.Database, nameAndMessage, exception); + break; + default: + _geekbotLogger.Information(LogSource.Database, nameAndMessage); + break; + } + } + + private static LogLevel ToGeekbotLogLevel(NpgsqlLogLevel level) + { + switch (level) + { + case NpgsqlLogLevel.Trace: + return LogLevel.Trace; + case NpgsqlLogLevel.Debug: + return LogLevel.Debug; + case NpgsqlLogLevel.Info: + return LogLevel.Info; + case NpgsqlLogLevel.Warn: + return LogLevel.Warn; + case NpgsqlLogLevel.Error: + return LogLevel.Error; + case NpgsqlLogLevel.Fatal: + return LogLevel.Fatal; + default: + throw new ArgumentOutOfRangeException(nameof(level)); + } + } + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingProviderAdapter.cs b/Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingProviderAdapter.cs new file mode 100644 index 0000000..0888111 --- /dev/null +++ b/Geekbot.net/Database/LoggingAdapter/NpgsqlLoggingProviderAdapter.cs @@ -0,0 +1,20 @@ +using Geekbot.net.Lib.Logger; +using Npgsql.Logging; + +namespace Geekbot.net.Database.LoggingAdapter +{ + public class NpgsqlLoggingProviderAdapter : INpgsqlLoggingProvider + { + private readonly GeekbotLogger _geekbotLogger; + + public NpgsqlLoggingProviderAdapter(GeekbotLogger geekbotLogger) + { + _geekbotLogger = geekbotLogger; + } + + public NpgsqlLogger CreateLogger(string name) + { + return new NpgsqlLoggingAdapter(name, _geekbotLogger); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/Models/GuildSettingsModel.cs b/Geekbot.net/Database/Models/GuildSettingsModel.cs new file mode 100644 index 0000000..b8ae300 --- /dev/null +++ b/Geekbot.net/Database/Models/GuildSettingsModel.cs @@ -0,0 +1,7 @@ +namespace Geekbot.net.Database.Models +{ + public class GuildSettingsModel + { + + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/Models/GuildsModel.cs b/Geekbot.net/Database/Models/GuildsModel.cs new file mode 100644 index 0000000..0b8ec3c --- /dev/null +++ b/Geekbot.net/Database/Models/GuildsModel.cs @@ -0,0 +1,7 @@ +namespace Geekbot.net.Database.Models +{ + public class GuildsModel + { + + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/Models/KarmaModel.cs b/Geekbot.net/Database/Models/KarmaModel.cs new file mode 100644 index 0000000..d29f313 --- /dev/null +++ b/Geekbot.net/Database/Models/KarmaModel.cs @@ -0,0 +1,7 @@ +namespace Geekbot.net.Database.Models +{ + public class KarmaModel + { + + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/QuoteModel.cs b/Geekbot.net/Database/Models/QuoteModel.cs similarity index 73% rename from Geekbot.net/Database/QuoteModel.cs rename to Geekbot.net/Database/Models/QuoteModel.cs index 37d4a37..98e8b21 100644 --- a/Geekbot.net/Database/QuoteModel.cs +++ b/Geekbot.net/Database/Models/QuoteModel.cs @@ -1,8 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; -namespace Geekbot.net.Database +namespace Geekbot.net.Database.Models { public class QuoteModel { @@ -13,10 +12,10 @@ namespace Geekbot.net.Database public int InternalId { get; set; } [Required] - public ulong GuildId { get; set; } + public long GuildId { get; set; } [Required] - public ulong UserId { get; set; } + public long UserId { get; set; } [Required] [DataType(DataType.DateTime)] diff --git a/Geekbot.net/Database/Models/RoleSelfServiceModel.cs b/Geekbot.net/Database/Models/RoleSelfServiceModel.cs new file mode 100644 index 0000000..4bb7f01 --- /dev/null +++ b/Geekbot.net/Database/Models/RoleSelfServiceModel.cs @@ -0,0 +1,7 @@ +namespace Geekbot.net.Database.Models +{ + public class RoleSelfServiceModel + { + + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/Models/ShipsModel.cs b/Geekbot.net/Database/Models/ShipsModel.cs new file mode 100644 index 0000000..6eda191 --- /dev/null +++ b/Geekbot.net/Database/Models/ShipsModel.cs @@ -0,0 +1,7 @@ +namespace Geekbot.net.Database.Models +{ + public class ShipsModel + { + + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/Models/SlapsModel.cs b/Geekbot.net/Database/Models/SlapsModel.cs new file mode 100644 index 0000000..80ee199 --- /dev/null +++ b/Geekbot.net/Database/Models/SlapsModel.cs @@ -0,0 +1,7 @@ +namespace Geekbot.net.Database.Models +{ + public class SlapsModel + { + + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/Models/UserModel.cs b/Geekbot.net/Database/Models/UserModel.cs new file mode 100644 index 0000000..d68f178 --- /dev/null +++ b/Geekbot.net/Database/Models/UserModel.cs @@ -0,0 +1,7 @@ +namespace Geekbot.net.Database.Models +{ + public class UserModel + { + + } +} \ No newline at end of file diff --git a/Geekbot.net/Database/SqlConnectionString.cs b/Geekbot.net/Database/SqlConnectionString.cs index 1dcfabb..3228a05 100644 --- a/Geekbot.net/Database/SqlConnectionString.cs +++ b/Geekbot.net/Database/SqlConnectionString.cs @@ -2,15 +2,15 @@ { public class SqlConnectionString { - public string Server { get; set; } = "localhost"; - public string Port { get; set; } = "3306"; - public string Database { get; set; } = "geekbot"; - public string Username { get; set; } = "geekbot"; - public string Password { get; set; } = ""; + public string Host { get; set; } + public string Port { get; set; } + public string Database { get; set; } + public string Username { get; set; } + public string Password { get; set; } public override string ToString() { - return $"Server={Server};Port={Port};Database={Database};Uid={Username};Pwd={Password};"; + return $"Server={Host};Port={Port};Database={Database};Uid={Username};Pwd={Password};"; } } } \ No newline at end of file diff --git a/Geekbot.net/Database/SqlDatabase.cs b/Geekbot.net/Database/SqlDatabase.cs index 0d9cd8f..e6d03d4 100644 --- a/Geekbot.net/Database/SqlDatabase.cs +++ b/Geekbot.net/Database/SqlDatabase.cs @@ -1,5 +1,4 @@ using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Logging; namespace Geekbot.net.Database { @@ -13,7 +12,6 @@ namespace Geekbot.net.Database } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - => optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole()) - .UseMySql(_connectionString.ToString()); + => optionsBuilder.UseNpgsql(_connectionString.ToString()); } } \ No newline at end of file diff --git a/Geekbot.net/Geekbot.net.csproj b/Geekbot.net/Geekbot.net.csproj index f8554c9..8e01709 100755 --- a/Geekbot.net/Geekbot.net.csproj +++ b/Geekbot.net/Geekbot.net.csproj @@ -32,15 +32,15 @@ + + - - 1.2.6 - + diff --git a/Geekbot.net/Lib/Extensions/LongExtensions.cs b/Geekbot.net/Lib/Extensions/LongExtensions.cs new file mode 100644 index 0000000..1bcdd9b --- /dev/null +++ b/Geekbot.net/Lib/Extensions/LongExtensions.cs @@ -0,0 +1,12 @@ +using System; + +namespace Geekbot.net.Lib.Extensions +{ + public static class LongExtensions + { + public static ulong AsUlong(this long thing) + { + return Convert.ToUInt64(thing); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/Lib/Extensions/UlongExtensions.cs b/Geekbot.net/Lib/Extensions/UlongExtensions.cs new file mode 100644 index 0000000..8fa2a67 --- /dev/null +++ b/Geekbot.net/Lib/Extensions/UlongExtensions.cs @@ -0,0 +1,12 @@ +using System; + +namespace Geekbot.net.Lib.Extensions +{ + public static class UlongExtensions + { + public static long AsLong(this ulong thing) + { + return Convert.ToInt64(thing); + } + } +} \ No newline at end of file diff --git a/Geekbot.net/Lib/Logger/GeekbotLogger.cs b/Geekbot.net/Lib/Logger/GeekbotLogger.cs index b2bb677..09a3ecb 100644 --- a/Geekbot.net/Lib/Logger/GeekbotLogger.cs +++ b/Geekbot.net/Lib/Logger/GeekbotLogger.cs @@ -49,6 +49,16 @@ namespace Geekbot.net.Lib.Logger else _logger.Error(stackTrace, CreateLogString("Error", source, message, stackTrace, extra)); } + public NLog.Logger GetNLogger() + { + return _logger; + } + + public bool LogAsJson() + { + return _logAsJson; + } + private string CreateLogString(string type, LogSource source, string message, Exception stackTrace = null, object extra = null) { if (_logAsJson) diff --git a/Geekbot.net/Lib/Logger/IGeekbotLogger.cs b/Geekbot.net/Lib/Logger/IGeekbotLogger.cs index 1f76cb0..944524a 100644 --- a/Geekbot.net/Lib/Logger/IGeekbotLogger.cs +++ b/Geekbot.net/Lib/Logger/IGeekbotLogger.cs @@ -9,5 +9,7 @@ namespace Geekbot.net.Lib.Logger void Information(LogSource source, string message, object extra = null); void Warning(LogSource source, string message, Exception stackTrace = null, object extra = null); void Error(LogSource source, string message, Exception stackTrace, object extra = null); + NLog.Logger GetNLogger(); + bool LogAsJson(); } } \ No newline at end of file diff --git a/Geekbot.net/Lib/Logger/LogSource.cs b/Geekbot.net/Lib/Logger/LogSource.cs index d9a8629..cccc930 100644 --- a/Geekbot.net/Lib/Logger/LogSource.cs +++ b/Geekbot.net/Lib/Logger/LogSource.cs @@ -11,6 +11,7 @@ namespace Geekbot.net.Lib.Logger Gateway, Discord, Redis, + Database, Message, UserRepository, Command, diff --git a/Geekbot.net/Lib/Logger/LoggerFactory.cs b/Geekbot.net/Lib/Logger/LoggerFactory.cs index 4095d00..9c5f759 100644 --- a/Geekbot.net/Lib/Logger/LoggerFactory.cs +++ b/Geekbot.net/Lib/Logger/LoggerFactory.cs @@ -34,7 +34,7 @@ namespace Geekbot.net.Lib.Logger { var minLevel = runParameters.Verbose ? LogLevel.Trace : LogLevel.Info; config.LoggingRules.Add( - new LoggingRule("*", LogLevel.Info, LogLevel.Fatal, + new LoggingRule("*", minLevel, LogLevel.Fatal, new ColoredConsoleTarget { Name = "Console", diff --git a/Geekbot.net/Lib/RunParameters.cs b/Geekbot.net/Lib/RunParameters.cs index 1e1048b..5485533 100644 --- a/Geekbot.net/Lib/RunParameters.cs +++ b/Geekbot.net/Lib/RunParameters.cs @@ -5,6 +5,9 @@ namespace Geekbot.net.Lib { public class RunParameters { + /** + * General Parameters + */ [Option('V', "verbose", Default = false, HelpText = "Prints all messages to standard output.")] public bool Verbose { get; set; } @@ -23,7 +26,26 @@ namespace Geekbot.net.Lib [Option("token", Default = null, HelpText = "Set a new bot token")] public string Token { get; set; } - [Option("in-memory", Default = false, HelpText = "Disables the web api")] + /** + * Database Stuff + */ + [Option("in-memory", Default = false, HelpText = "Uses the in-memory database instead of postgresql")] public bool InMemory { get; set; } + + // Postresql connection + [Option("database", Default = false, HelpText = "Select a postgresql database")] + public string DbDatabase { get; set; } = "geekbot"; + + [Option("db-host", Default = false, HelpText = "Set a postgresql host (e.g. 127.0.0.1)")] + public string DbHost { get; set; } = "localhost"; + + [Option("db-port", Default = false, HelpText = "Set a postgresql host (e.g. 5432)")] + public string DbPort { get; set; } = "5432"; + + [Option("db-user", Default = false, HelpText = "Set a postgresql user")] + public string DbUser { get; set; } = "geekbot"; + + [Option("db-password", Default = false, HelpText = "Set a posgresql password")] + public string DbPassword { get; set; } = ""; } } \ No newline at end of file