Use Postgresql, add db run params, npgsql logging adapter and empty models

This commit is contained in:
runebaas 2018-05-10 00:00:51 +02:00
parent 3425896c0b
commit d2f31d0730
No known key found for this signature in database
GPG key ID: 2677AF508D0300D6
24 changed files with 252 additions and 39 deletions

View file

@ -4,10 +4,11 @@ using System.Threading.Tasks;
using Discord; using Discord;
using Discord.Commands; using Discord.Commands;
using Geekbot.net.Database; using Geekbot.net.Database;
using Geekbot.net.Database.Models;
using Geekbot.net.Lib; using Geekbot.net.Lib;
using Geekbot.net.Lib.ErrorHandling; using Geekbot.net.Lib.ErrorHandling;
using Geekbot.net.Lib.Extensions;
using Geekbot.net.Lib.Polyfills; using Geekbot.net.Lib.Polyfills;
using Newtonsoft.Json;
using StackExchange.Redis; using StackExchange.Redis;
namespace Geekbot.net.Commands.Utils.Quote namespace Geekbot.net.Commands.Utils.Quote
@ -33,7 +34,7 @@ namespace Geekbot.net.Commands.Utils.Quote
{ {
try 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()) if (!s.Any())
{ {
@ -41,8 +42,8 @@ namespace Geekbot.net.Commands.Utils.Quote
return; return;
} }
var random = new Random().Next(1, s.Count()); var random = new Random().Next(s.Count());
var quote = s[random - 1]; var quote = s[random];
var embed = QuoteBuilder(quote); var embed = QuoteBuilder(quote);
await ReplyAsync("", false, embed.Build()); await ReplyAsync("", false, embed.Build());
@ -172,7 +173,7 @@ namespace Geekbot.net.Commands.Utils.Quote
{ {
try 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) if (quote != null)
{ {
_database.Quotes.Remove(quote); _database.Quotes.Remove(quote);
@ -212,7 +213,7 @@ namespace Geekbot.net.Commands.Utils.Quote
private EmbedBuilder QuoteBuilder(QuoteModel 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(); var eb = new EmbedBuilder();
eb.WithColor(new Color(143, 167, 232)); eb.WithColor(new Color(143, 167, 232));
eb.Title = $"#{quote.InternalId} | {user.Username} @ {quote.Time.Day}.{quote.Time.Month}.{quote.Time.Year}"; 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; 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() return new QuoteModel()
{ {
InternalId = internalId, InternalId = internalId,
GuildId = Context.Guild.Id, GuildId = Context.Guild.Id.AsLong(),
UserId = message.Author.Id, UserId = message.Author.Id.AsLong(),
Time = message.Timestamp.DateTime, Time = message.Timestamp.DateTime,
Quote = message.Content, Quote = message.Content,
Image = image Image = image

View file

@ -1,15 +1,17 @@
using Microsoft.EntityFrameworkCore; using Geekbot.net.Database.Models;
using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore;
namespace Geekbot.net.Database namespace Geekbot.net.Database
{ {
public class DatabaseContext : DbContext public class DatabaseContext : DbContext
{ {
public DbSet<QuoteModel> Quotes { get; set; } public DbSet<QuoteModel> Quotes { get; set; }
// public DbSet<UserModel> Users { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) // public DbSet<GuildsModel> Guilds { get; set; }
=> optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole()) // public DbSet<GuildSettingsModel> GuildSettings { get; set; }
// .UseInMemoryDatabase(databaseName: "Geekbot"); // public DbSet<KarmaModel> Karma { get; set; }
.UseMySql(@"Server=localhost;database=geekbot;uid=geekbot;"); // public DbSet<ShipsModel> Ships { get; set; }
// public DbSet<RoleSelfServiceModel> RoleSelfService { get; set; }
// public DbSet<SlapsModel> SlapsModels { get; set; }
} }
} }

View file

@ -1,6 +1,8 @@
using System; using System;
using Geekbot.net.Database.LoggingAdapter;
using Geekbot.net.Lib; using Geekbot.net.Lib;
using Geekbot.net.Lib.Logger; using Geekbot.net.Lib.Logger;
using Npgsql.Logging;
namespace Geekbot.net.Database namespace Geekbot.net.Database
{ {
@ -26,9 +28,16 @@ namespace Geekbot.net.Database
} }
else 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(); database.Database.EnsureCreated();
} }
catch (Exception e) catch (Exception e)
@ -37,6 +46,7 @@ namespace Geekbot.net.Database
Environment.Exit(GeekbotExitCode.DatabaseConnectionFailed.GetHashCode()); Environment.Exit(GeekbotExitCode.DatabaseConnectionFailed.GetHashCode());
} }
_logger.Information(LogSource.Database, $"Connected with {database.Database.ProviderName}");
return database; return database;
} }
} }

View file

@ -13,7 +13,6 @@ namespace Geekbot.net.Database
} }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole()) => optionsBuilder.UseInMemoryDatabase(databaseName: _name);
.UseInMemoryDatabase(databaseName: _name);
} }
} }

View file

@ -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));
}
}
}
}

View file

@ -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);
}
}
}

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Database.Models
{
public class GuildSettingsModel
{
}
}

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Database.Models
{
public class GuildsModel
{
}
}

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Database.Models
{
public class KarmaModel
{
}
}

View file

@ -1,8 +1,7 @@
using System; using System;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore.Scaffolding.Metadata;
namespace Geekbot.net.Database namespace Geekbot.net.Database.Models
{ {
public class QuoteModel public class QuoteModel
{ {
@ -13,10 +12,10 @@ namespace Geekbot.net.Database
public int InternalId { get; set; } public int InternalId { get; set; }
[Required] [Required]
public ulong GuildId { get; set; } public long GuildId { get; set; }
[Required] [Required]
public ulong UserId { get; set; } public long UserId { get; set; }
[Required] [Required]
[DataType(DataType.DateTime)] [DataType(DataType.DateTime)]

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Database.Models
{
public class RoleSelfServiceModel
{
}
}

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Database.Models
{
public class ShipsModel
{
}
}

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Database.Models
{
public class SlapsModel
{
}
}

View file

@ -0,0 +1,7 @@
namespace Geekbot.net.Database.Models
{
public class UserModel
{
}
}

View file

@ -2,15 +2,15 @@
{ {
public class SqlConnectionString public class SqlConnectionString
{ {
public string Server { get; set; } = "localhost"; public string Host { get; set; }
public string Port { get; set; } = "3306"; public string Port { get; set; }
public string Database { get; set; } = "geekbot"; public string Database { get; set; }
public string Username { get; set; } = "geekbot"; public string Username { get; set; }
public string Password { get; set; } = ""; public string Password { get; set; }
public override string ToString() 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};";
} }
} }
} }

View file

@ -1,5 +1,4 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
namespace Geekbot.net.Database namespace Geekbot.net.Database
{ {
@ -13,7 +12,6 @@ namespace Geekbot.net.Database
} }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder.UseLoggerFactory(new LoggerFactory().AddConsole()) => optionsBuilder.UseNpgsql(_connectionString.ToString());
.UseMySql(_connectionString.ToString());
} }
} }

View file

@ -32,15 +32,15 @@
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" /> <PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
<PackageReference Include="NLog" Version="4.5.3" /> <PackageReference Include="NLog" Version="4.5.3" />
<PackageReference Include="NLog.Config" Version="4.5.3" /> <PackageReference Include="NLog.Config" Version="4.5.3" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.0.2" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.Design" Version="1.1.1" />
<PackageReference Include="Overwatch.Net" Version="3.1.0" /> <PackageReference Include="Overwatch.Net" Version="3.1.0" />
<PackageReference Include="PokeApi.NET" Version="1.1.0" /> <PackageReference Include="PokeApi.NET" Version="1.1.0" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql" Version="2.0.1" />
<PackageReference Include="Pomelo.EntityFrameworkCore.MySql.Design" Version="1.1.2" />
<PackageReference Include="SharpRaven" Version="2.3.2" /> <PackageReference Include="SharpRaven" Version="2.3.2" />
<PackageReference Include="StackExchange.Redis"> <PackageReference Include="StackExchange.Redis">
<Version>1.2.6</Version> <Version>1.2.6</Version>
</PackageReference> </PackageReference>
<PackageReference Include="SumoLogic.Logging.NLog" Version="1.0.0.2" /> <PackageReference Include="SumoLogic.Logging.NLog" Version="1.0.0.7" />
<PackageReference Include="System.Net.Http" Version="4.3.3" /> <PackageReference Include="System.Net.Http" Version="4.3.3" />
<PackageReference Include="System.Runtime.Serialization.Formatters" Version="4.3.0" /> <PackageReference Include="System.Runtime.Serialization.Formatters" Version="4.3.0" />
<PackageReference Include="System.Runtime.Serialization.Json"> <PackageReference Include="System.Runtime.Serialization.Json">

View file

@ -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);
}
}
}

View file

@ -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);
}
}
}

View file

@ -49,6 +49,16 @@ namespace Geekbot.net.Lib.Logger
else _logger.Error(stackTrace, CreateLogString("Error", source, message, stackTrace, extra)); 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) private string CreateLogString(string type, LogSource source, string message, Exception stackTrace = null, object extra = null)
{ {
if (_logAsJson) if (_logAsJson)

View file

@ -9,5 +9,7 @@ namespace Geekbot.net.Lib.Logger
void Information(LogSource source, string message, object extra = null); void Information(LogSource source, string message, object extra = null);
void Warning(LogSource source, string message, Exception stackTrace = null, 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); void Error(LogSource source, string message, Exception stackTrace, object extra = null);
NLog.Logger GetNLogger();
bool LogAsJson();
} }
} }

View file

@ -11,6 +11,7 @@ namespace Geekbot.net.Lib.Logger
Gateway, Gateway,
Discord, Discord,
Redis, Redis,
Database,
Message, Message,
UserRepository, UserRepository,
Command, Command,

View file

@ -34,7 +34,7 @@ namespace Geekbot.net.Lib.Logger
{ {
var minLevel = runParameters.Verbose ? LogLevel.Trace : LogLevel.Info; var minLevel = runParameters.Verbose ? LogLevel.Trace : LogLevel.Info;
config.LoggingRules.Add( config.LoggingRules.Add(
new LoggingRule("*", LogLevel.Info, LogLevel.Fatal, new LoggingRule("*", minLevel, LogLevel.Fatal,
new ColoredConsoleTarget new ColoredConsoleTarget
{ {
Name = "Console", Name = "Console",

View file

@ -5,6 +5,9 @@ namespace Geekbot.net.Lib
{ {
public class RunParameters public class RunParameters
{ {
/**
* General Parameters
*/
[Option('V', "verbose", Default = false, HelpText = "Prints all messages to standard output.")] [Option('V', "verbose", Default = false, HelpText = "Prints all messages to standard output.")]
public bool Verbose { get; set; } public bool Verbose { get; set; }
@ -23,7 +26,26 @@ namespace Geekbot.net.Lib
[Option("token", Default = null, HelpText = "Set a new bot token")] [Option("token", Default = null, HelpText = "Set a new bot token")]
public string Token { get; set; } 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; } 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; } = "";
} }
} }