// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Input.Bindings; using osu.Game.IO; using osu.Game.Rulesets; using LogLevel = Microsoft.Extensions.Logging.LogLevel; namespace osu.Game.Database { public class OsuDbContext : DbContext { public DbSet BeatmapInfo { get; set; } public DbSet BeatmapSetInfo { get; set; } public DbSet DatabasedKeyBinding { get; set; } public DbSet FileInfo { get; set; } public DbSet RulesetInfo { get; set; } private readonly string connectionString; static OsuDbContext() { // required to initialise native SQLite libraries on some platforms. SQLitePCL.Batteries_V2.Init(); } /// /// Create a new OsuDbContext instance. /// /// A valid SQLite connection string. If not provided, an in-memory instance will be created. public OsuDbContext(string connectionString = "DataSource=:memory:") { this.connectionString = connectionString; Database.SetCommandTimeout(new TimeSpan(TimeSpan.TicksPerSecond * 10)); var connection = Database.GetDbConnection(); connection.Open(); using (var cmd = connection.CreateCommand()) { cmd.CommandText = "PRAGMA journal_mode=WAL;"; cmd.ExecuteNonQuery(); } } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { base.OnConfiguring(optionsBuilder); optionsBuilder.UseSqlite(connectionString); optionsBuilder.UseLoggerFactory(new OsuDbLoggerFactory()); } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity().HasIndex(b => b.MD5Hash); modelBuilder.Entity().HasIndex(b => b.DeletePending); modelBuilder.Entity().HasIndex(b => b.Variant); modelBuilder.Entity().HasIndex(b => b.IntAction); modelBuilder.Entity().HasIndex(b => b.Hash).IsUnique(); modelBuilder.Entity().HasIndex(b => b.ReferenceCount); modelBuilder.Entity().HasIndex(b => b.Name).IsUnique(); modelBuilder.Entity().HasIndex(b => b.InstantiationInfo).IsUnique(); modelBuilder.Entity().HasIndex(b => b.Available); } private class OsuDbLoggerFactory : ILoggerFactory { #region Disposal public void Dispose() { } #endregion public ILogger CreateLogger(string categoryName) => new OsuDbLogger(); public void AddProvider(ILoggerProvider provider) { throw new NotImplementedException(); } private class OsuDbLoggerProvider : ILoggerProvider { #region Disposal public void Dispose() { } #endregion public ILogger CreateLogger(string categoryName) => new OsuDbLogger(); } private class OsuDbLogger : ILogger { public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) => Logger.Log(formatter(state, exception), LoggingTarget.Database, Framework.Logging.LogLevel.Debug); public bool IsEnabled(LogLevel logLevel) => true; public IDisposable BeginScope(TState state) => null; } } } }