2018-01-05 20:21:19 +09:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
2017-04-17 14:37:52 +09:00
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2017-10-25 22:07:32 +09:00
using System.Linq ;
using Microsoft.EntityFrameworkCore ;
2017-07-26 20:22:02 +09:00
using osu.Framework.Platform ;
2017-04-17 14:37:52 +09:00
namespace osu.Game.Database
{
2017-07-27 16:56:41 +09:00
public abstract class DatabaseBackedStore
2017-04-17 14:37:52 +09:00
{
2017-07-26 20:22:02 +09:00
protected readonly Storage Storage ;
2017-04-17 14:37:52 +09:00
2017-10-23 16:35:35 +09:00
/// <summary>
/// Create a new <see cref="OsuDbContext"/> instance (separate from the shared context via <see cref="GetContext"/> for performing isolated operations.
/// </summary>
2018-02-12 23:10:05 +09:00
protected readonly IDatabaseContextFactory ContextFactory ;
2017-10-23 16:35:35 +09:00
2017-10-25 18:28:28 +09:00
/// <summary>
2017-10-25 22:07:32 +09:00
/// Refresh an instance potentially from a different thread with a local context-tracked instance.
2017-10-25 18:28:28 +09:00
/// </summary>
2017-10-25 22:19:47 +09:00
/// <param name="obj">The object to use as a reference when negotiating a local instance.</param>
/// <param name="lookupSource">An optional lookup source which will be used to query and populate a freshly retrieved replacement. If not provided, the refreshed object will still be returned but will not have any includes.</param>
/// <typeparam name="T">A valid EF-stored type.</typeparam>
2018-02-15 15:51:59 +09:00
protected virtual void Refresh < T > ( ref T obj , IQueryable < T > lookupSource = null ) where T : class , IHasPrimaryKey
2017-10-25 22:07:32 +09:00
{
2018-02-12 17:55:11 +09:00
using ( var usage = ContextFactory . GetForWrite ( ) )
2018-01-24 17:35:37 +09:00
{
2018-02-12 17:55:11 +09:00
var context = usage . Context ;
if ( context . Entry ( obj ) . State ! = EntityState . Detached ) return ;
var id = obj . ID ;
var foundObject = lookupSource ? . SingleOrDefault ( t = > t . ID = = id ) ? ? context . Find < T > ( id ) ;
if ( foundObject ! = null )
obj = foundObject ;
else
context . Add ( obj ) ;
2018-01-24 17:35:37 +09:00
}
2017-10-25 22:07:32 +09:00
}
2017-10-25 18:28:28 +09:00
2018-02-12 23:10:05 +09:00
protected DatabaseBackedStore ( IDatabaseContextFactory contextFactory , Storage storage = null )
2017-04-17 14:37:52 +09:00
{
2018-02-12 17:55:11 +09:00
ContextFactory = contextFactory ;
2017-07-26 20:22:02 +09:00
Storage = storage ;
2017-04-17 14:37:52 +09:00
}
/// <summary>
2017-10-17 19:58:33 +09:00
/// Perform any common clean-up tasks. Should be run when idle, or whenever necessary.
2017-08-01 10:08:05 +09:00
/// </summary>
2018-02-15 16:31:42 +09:00
public virtual void Cleanup ( )
2017-08-01 10:08:05 +09:00
{
}
2017-04-17 14:37:52 +09:00
}
2017-07-27 15:06:10 +09:00
}