Browse Source

use individual connections

Luke Pulverenti 9 years ago
parent
commit
4c7f292ba8

+ 214 - 229
MediaBrowser.Server.Implementations/Notifications/SqliteNotificationsRepository.cs

@@ -15,30 +15,20 @@ namespace MediaBrowser.Server.Implementations.Notifications
 {
 {
     public class SqliteNotificationsRepository : BaseSqliteRepository, INotificationsRepository
     public class SqliteNotificationsRepository : BaseSqliteRepository, INotificationsRepository
     {
     {
-        private IDbConnection _connection;
-        private readonly IServerApplicationPaths _appPaths;
+        public SqliteNotificationsRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector dbConnector) : base(logManager, dbConnector)
+        {
+            DbFilePath = Path.Combine(appPaths.DataPath, "notifications.db");
+        }
 
 
         public event EventHandler<NotificationUpdateEventArgs> NotificationAdded;
         public event EventHandler<NotificationUpdateEventArgs> NotificationAdded;
         public event EventHandler<NotificationReadEventArgs> NotificationsMarkedRead;
         public event EventHandler<NotificationReadEventArgs> NotificationsMarkedRead;
         public event EventHandler<NotificationUpdateEventArgs> NotificationUpdated;
         public event EventHandler<NotificationUpdateEventArgs> NotificationUpdated;
 
 
-        private IDbCommand _replaceNotificationCommand;
-        private IDbCommand _markReadCommand;
-        private IDbCommand _markAllReadCommand;
-
-        public SqliteNotificationsRepository(ILogManager logManager, IServerApplicationPaths appPaths)
-            : base(logManager)
+        public async Task Initialize()
         {
         {
-            _appPaths = appPaths;
-        }
-
-        public async Task Initialize(IDbConnector dbConnector)
-        {
-            var dbFile = Path.Combine(_appPaths.DataPath, "notifications.db");
-
-            _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
-
-            string[] queries = {
+            using (var connection = await CreateConnection().ConfigureAwait(false))
+            {
+                string[] queries = {
 
 
                                 "create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT, Url TEXT, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT, PRIMARY KEY (Id, UserId))",
                                 "create table if not exists Notifications (Id GUID NOT NULL, UserId GUID NOT NULL, Date DATETIME NOT NULL, Name TEXT NOT NULL, Description TEXT, Url TEXT, Level TEXT NOT NULL, IsRead BOOLEAN NOT NULL, Category TEXT NOT NULL, RelatedId TEXT, PRIMARY KEY (Id, UserId))",
                                 "create index if not exists idx_Notifications1 on Notifications(Id)",
                                 "create index if not exists idx_Notifications1 on Notifications(Id)",
@@ -50,39 +40,8 @@ namespace MediaBrowser.Server.Implementations.Notifications
                                 "pragma shrink_memory"
                                 "pragma shrink_memory"
                                };
                                };
 
 
-            _connection.RunQueries(queries, Logger);
-
-            PrepareStatements();
-        }
-
-        private void PrepareStatements()
-        {
-            _replaceNotificationCommand = _connection.CreateCommand();
-            _replaceNotificationCommand.CommandText = "replace into Notifications (Id, UserId, Date, Name, Description, Url, Level, IsRead, Category, RelatedId) values (@Id, @UserId, @Date, @Name, @Description, @Url, @Level, @IsRead, @Category, @RelatedId)";
-
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Id");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@UserId");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Date");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Name");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Description");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Url");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Level");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@Category");
-            _replaceNotificationCommand.Parameters.Add(_replaceNotificationCommand, "@RelatedId");
-
-            _markReadCommand = _connection.CreateCommand();
-            _markReadCommand.CommandText = "update Notifications set IsRead=@IsRead where Id=@Id and UserId=@UserId";
-
-            _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId");
-            _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead");
-            _markReadCommand.Parameters.Add(_replaceNotificationCommand, "@Id");
-
-            _markAllReadCommand = _connection.CreateCommand();
-            _markAllReadCommand.CommandText = "update Notifications set IsRead=@IsRead where UserId=@UserId";
-
-            _markAllReadCommand.Parameters.Add(_replaceNotificationCommand, "@UserId");
-            _markAllReadCommand.Parameters.Add(_replaceNotificationCommand, "@IsRead");
+                connection.RunQueries(queries, Logger);
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -94,49 +53,52 @@ namespace MediaBrowser.Server.Implementations.Notifications
         {
         {
             var result = new NotificationResult();
             var result = new NotificationResult();
 
 
-            using (var cmd = _connection.CreateCommand())
+            using (var connection = CreateConnection(true).Result)
             {
             {
-                var clauses = new List<string>();
-
-                if (query.IsRead.HasValue)
+                using (var cmd = connection.CreateCommand())
                 {
                 {
-                    clauses.Add("IsRead=@IsRead");
-                    cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = query.IsRead.Value;
-                }
+                    var clauses = new List<string>();
 
 
-                clauses.Add("UserId=@UserId");
-                cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(query.UserId);
+                    if (query.IsRead.HasValue)
+                    {
+                        clauses.Add("IsRead=@IsRead");
+                        cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = query.IsRead.Value;
+                    }
 
 
-                var whereClause = " where " + string.Join(" And ", clauses.ToArray());
+                    clauses.Add("UserId=@UserId");
+                    cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(query.UserId);
 
 
-                cmd.CommandText = string.Format("select count(Id) from Notifications{0};select Id,UserId,Date,Name,Description,Url,Level,IsRead,Category,RelatedId from Notifications{0} order by IsRead asc, Date desc", whereClause);
+                    var whereClause = " where " + string.Join(" And ", clauses.ToArray());
 
 
-                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
-                {
-                    if (reader.Read())
-                    {
-                        result.TotalRecordCount = reader.GetInt32(0);
-                    }
+                    cmd.CommandText = string.Format("select count(Id) from Notifications{0};select Id,UserId,Date,Name,Description,Url,Level,IsRead,Category,RelatedId from Notifications{0} order by IsRead asc, Date desc", whereClause);
 
 
-                    if (reader.NextResult())
+                    using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
                     {
                     {
-                        var notifications = GetNotifications(reader);
-
-                        if (query.StartIndex.HasValue)
+                        if (reader.Read())
                         {
                         {
-                            notifications = notifications.Skip(query.StartIndex.Value);
+                            result.TotalRecordCount = reader.GetInt32(0);
                         }
                         }
 
 
-                        if (query.Limit.HasValue)
+                        if (reader.NextResult())
                         {
                         {
-                            notifications = notifications.Take(query.Limit.Value);
-                        }
+                            var notifications = GetNotifications(reader);
 
 
-                        result.Notifications = notifications.ToArray();
+                            if (query.StartIndex.HasValue)
+                            {
+                                notifications = notifications.Skip(query.StartIndex.Value);
+                            }
+
+                            if (query.Limit.HasValue)
+                            {
+                                notifications = notifications.Take(query.Limit.Value);
+                            }
+
+                            result.Notifications = notifications.ToArray();
+                        }
                     }
                     }
-                }
 
 
-                return result;
+                    return result;
+                }
             }
             }
         }
         }
 
 
@@ -144,31 +106,34 @@ namespace MediaBrowser.Server.Implementations.Notifications
         {
         {
             var result = new NotificationsSummary();
             var result = new NotificationsSummary();
 
 
-            using (var cmd = _connection.CreateCommand())
+            using (var connection = CreateConnection(true).Result)
             {
             {
-                cmd.CommandText = "select Level from Notifications where UserId=@UserId and IsRead=@IsRead";
-
-                cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(userId);
-                cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = false;
-
-                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
+                using (var cmd = connection.CreateCommand())
                 {
                 {
-                    var levels = new List<NotificationLevel>();
+                    cmd.CommandText = "select Level from Notifications where UserId=@UserId and IsRead=@IsRead";
 
 
-                    while (reader.Read())
+                    cmd.Parameters.Add(cmd, "@UserId", DbType.Guid).Value = new Guid(userId);
+                    cmd.Parameters.Add(cmd, "@IsRead", DbType.Boolean).Value = false;
+
+                    using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
                     {
                     {
-                        levels.Add(GetLevel(reader, 0));
-                    }
+                        var levels = new List<NotificationLevel>();
 
 
-                    result.UnreadCount = levels.Count;
+                        while (reader.Read())
+                        {
+                            levels.Add(GetLevel(reader, 0));
+                        }
 
 
-                    if (levels.Count > 0)
-                    {
-                        result.MaxUnreadNotificationLevel = levels.Max();
+                        result.UnreadCount = levels.Count;
+
+                        if (levels.Count > 0)
+                        {
+                            result.MaxUnreadNotificationLevel = levels.Max();
+                        }
                     }
                     }
-                }
 
 
-                return result;
+                    return result;
+                }
             }
             }
         }
         }
 
 
@@ -179,10 +144,14 @@ namespace MediaBrowser.Server.Implementations.Notifications
         /// <returns>IEnumerable{Notification}.</returns>
         /// <returns>IEnumerable{Notification}.</returns>
         private IEnumerable<Notification> GetNotifications(IDataReader reader)
         private IEnumerable<Notification> GetNotifications(IDataReader reader)
         {
         {
+            var list = new List<Notification>();
+
             while (reader.Read())
             while (reader.Read())
             {
             {
-                yield return GetNotification(reader);
+                list.Add(GetNotification(reader));
             }
             }
+
+            return list;
         }
         }
 
 
         private Notification GetNotification(IDataReader reader)
         private Notification GetNotification(IDataReader reader)
@@ -273,59 +242,74 @@ namespace MediaBrowser.Server.Implementations.Notifications
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                transaction = _connection.BeginTransaction();
+                using (var replaceNotificationCommand = connection.CreateCommand())
+                {
+                    replaceNotificationCommand.CommandText = "replace into Notifications (Id, UserId, Date, Name, Description, Url, Level, IsRead, Category, RelatedId) values (@Id, @UserId, @Date, @Name, @Description, @Url, @Level, @IsRead, @Category, @RelatedId)";
+
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Id");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@UserId");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Date");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Name");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Description");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Url");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Level");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@IsRead");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@Category");
+                    replaceNotificationCommand.Parameters.Add(replaceNotificationCommand, "@RelatedId");
+
+                    IDbTransaction transaction = null;
+
+                    try
+                    {
+                        transaction = connection.BeginTransaction();
 
 
-                _replaceNotificationCommand.GetParameter(0).Value = new Guid(notification.Id);
-                _replaceNotificationCommand.GetParameter(1).Value = new Guid(notification.UserId);
-                _replaceNotificationCommand.GetParameter(2).Value = notification.Date.ToUniversalTime();
-                _replaceNotificationCommand.GetParameter(3).Value = notification.Name;
-                _replaceNotificationCommand.GetParameter(4).Value = notification.Description;
-                _replaceNotificationCommand.GetParameter(5).Value = notification.Url;
-                _replaceNotificationCommand.GetParameter(6).Value = notification.Level.ToString();
-                _replaceNotificationCommand.GetParameter(7).Value = notification.IsRead;
-                _replaceNotificationCommand.GetParameter(8).Value = string.Empty;
-                _replaceNotificationCommand.GetParameter(9).Value = string.Empty;
+                        replaceNotificationCommand.GetParameter(0).Value = new Guid(notification.Id);
+                        replaceNotificationCommand.GetParameter(1).Value = new Guid(notification.UserId);
+                        replaceNotificationCommand.GetParameter(2).Value = notification.Date.ToUniversalTime();
+                        replaceNotificationCommand.GetParameter(3).Value = notification.Name;
+                        replaceNotificationCommand.GetParameter(4).Value = notification.Description;
+                        replaceNotificationCommand.GetParameter(5).Value = notification.Url;
+                        replaceNotificationCommand.GetParameter(6).Value = notification.Level.ToString();
+                        replaceNotificationCommand.GetParameter(7).Value = notification.IsRead;
+                        replaceNotificationCommand.GetParameter(8).Value = string.Empty;
+                        replaceNotificationCommand.GetParameter(9).Value = string.Empty;
 
 
-                _replaceNotificationCommand.Transaction = transaction;
+                        replaceNotificationCommand.Transaction = transaction;
 
 
-                _replaceNotificationCommand.ExecuteNonQuery();
+                        replaceNotificationCommand.ExecuteNonQuery();
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        transaction.Commit();
+                    }
+                    catch (OperationCanceledException)
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save notification:", e);
+                        throw;
+                    }
+                    catch (Exception e)
+                    {
+                        Logger.ErrorException("Failed to save notification:", e);
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
-                {
-                    transaction.Dispose();
+                        throw;
+                    }
+                    finally
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Dispose();
+                        }
+                    }
                 }
                 }
-
-                WriteLock.Release();
             }
             }
         }
         }
 
 
@@ -366,51 +350,58 @@ namespace MediaBrowser.Server.Implementations.Notifications
         {
         {
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+            using (var connection = await CreateConnection().ConfigureAwait(false))
+            {
+                using (var markAllReadCommand = connection.CreateCommand())
+                {
+                    markAllReadCommand.CommandText = "update Notifications set IsRead=@IsRead where UserId=@UserId";
 
 
-            IDbTransaction transaction = null;
+                    markAllReadCommand.Parameters.Add(markAllReadCommand, "@UserId");
+                    markAllReadCommand.Parameters.Add(markAllReadCommand, "@IsRead");
 
 
-            try
-            {
-                cancellationToken.ThrowIfCancellationRequested();
+                    IDbTransaction transaction = null;
 
 
-                transaction = _connection.BeginTransaction();
+                    try
+                    {
+                        cancellationToken.ThrowIfCancellationRequested();
 
 
-                _markAllReadCommand.GetParameter(0).Value = new Guid(userId);
-                _markAllReadCommand.GetParameter(1).Value = isRead;
+                        transaction = connection.BeginTransaction();
 
 
-                _markAllReadCommand.ExecuteNonQuery();
+                        markAllReadCommand.GetParameter(0).Value = new Guid(userId);
+                        markAllReadCommand.GetParameter(1).Value = isRead;
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        markAllReadCommand.ExecuteNonQuery();
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save notification:", e);
+                        transaction.Commit();
+                    }
+                    catch (OperationCanceledException)
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        throw;
+                    }
+                    catch (Exception e)
+                    {
+                        Logger.ErrorException("Failed to save notification:", e);
 
 
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
-                {
-                    transaction.Dispose();
-                }
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                WriteLock.Release();
+                        throw;
+                    }
+                    finally
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Dispose();
+                        }
+                    }
+                }
             }
             }
         }
         }
 
 
@@ -418,72 +409,66 @@ namespace MediaBrowser.Server.Implementations.Notifications
         {
         {
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                cancellationToken.ThrowIfCancellationRequested();
+                using (var markReadCommand = connection.CreateCommand())
+                {
+                    markReadCommand.CommandText = "update Notifications set IsRead=@IsRead where Id=@Id and UserId=@UserId";
 
 
-                transaction = _connection.BeginTransaction();
+                    markReadCommand.Parameters.Add(markReadCommand, "@UserId");
+                    markReadCommand.Parameters.Add(markReadCommand, "@IsRead");
+                    markReadCommand.Parameters.Add(markReadCommand, "@Id");
 
 
-                _markReadCommand.GetParameter(0).Value = new Guid(userId);
-                _markReadCommand.GetParameter(1).Value = isRead;
+                    IDbTransaction transaction = null;
 
 
-                foreach (var id in notificationIdList)
-                {
-                    _markReadCommand.GetParameter(2).Value = id;
+                    try
+                    {
+                        cancellationToken.ThrowIfCancellationRequested();
 
 
-                    _markReadCommand.Transaction = transaction;
+                        transaction = connection.BeginTransaction();
 
 
-                    _markReadCommand.ExecuteNonQuery();
-                }
+                        markReadCommand.GetParameter(0).Value = new Guid(userId);
+                        markReadCommand.GetParameter(1).Value = isRead;
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        foreach (var id in notificationIdList)
+                        {
+                            markReadCommand.GetParameter(2).Value = id;
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save notification:", e);
+                            markReadCommand.Transaction = transaction;
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                            markReadCommand.ExecuteNonQuery();
+                        }
 
 
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
-                {
-                    transaction.Dispose();
-                }
+                        transaction.Commit();
+                    }
+                    catch (OperationCanceledException)
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                WriteLock.Release();
-            }
-        }
+                        throw;
+                    }
+                    catch (Exception e)
+                    {
+                        Logger.ErrorException("Failed to save notification:", e);
 
 
-        protected override void CloseConnection()
-        {
-            if (_connection != null)
-            {
-                if (_connection.IsOpen())
-                {
-                    _connection.Close();
-                }
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                _connection.Dispose();
-                _connection = null;
+                        throw;
+                    }
+                    finally
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Dispose();
+                        }
+                    }
+                }
             }
             }
         }
         }
     }
     }

+ 14 - 2
MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs

@@ -9,13 +9,22 @@ namespace MediaBrowser.Server.Implementations.Persistence
     public abstract class BaseSqliteRepository : IDisposable
     public abstract class BaseSqliteRepository : IDisposable
     {
     {
         protected readonly SemaphoreSlim WriteLock = new SemaphoreSlim(1, 1);
         protected readonly SemaphoreSlim WriteLock = new SemaphoreSlim(1, 1);
+        protected readonly IDbConnector DbConnector;
         protected ILogger Logger;
         protected ILogger Logger;
 
 
-        protected BaseSqliteRepository(ILogManager logManager)
+        protected string DbFilePath { get; set; }
+
+        protected BaseSqliteRepository(ILogManager logManager, IDbConnector dbConnector)
         {
         {
+            DbConnector = dbConnector;
             Logger = logManager.GetLogger(GetType().Name);
             Logger = logManager.GetLogger(GetType().Name);
         }
         }
 
 
+        protected Task<IDbConnection> CreateConnection(bool isReadOnly = false)
+        {
+            return DbConnector.Connect(DbFilePath, false, true);
+        }
+
         private bool _disposed;
         private bool _disposed;
         protected void CheckDisposed()
         protected void CheckDisposed()
         {
         {
@@ -84,6 +93,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
             }
             }
         }
         }
 
 
-        protected abstract void CloseConnection();
+        protected virtual void CloseConnection()
+        {
+            
+        }
     }
     }
 }
 }

+ 1 - 1
MediaBrowser.Server.Implementations/Persistence/IDbConnector.cs

@@ -5,6 +5,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
 {
 {
     public interface IDbConnector
     public interface IDbConnector
     {
     {
-        Task<IDbConnection> Connect(string dbPath, int? cacheSize = null);
+        Task<IDbConnection> Connect(string dbPath, bool isReadOnly, bool enablePooling = false, int? cacheSize = null);
     }
     }
 }
 }

+ 123 - 133
MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs

@@ -18,12 +18,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
     /// </summary>
     /// </summary>
     public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
     public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
     {
     {
-        private IDbConnection _connection;
-
-        public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths) : base(logManager)
+        public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector)
+            : base(logManager, dbConnector)
         {
         {
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
-            _appPaths = appPaths;
+            DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db");
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -43,22 +42,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// </summary>
         /// </summary>
         private readonly IJsonSerializer _jsonSerializer;
         private readonly IJsonSerializer _jsonSerializer;
 
 
-        /// <summary>
-        /// The _app paths
-        /// </summary>
-        private readonly IApplicationPaths _appPaths;
-
         /// <summary>
         /// <summary>
         /// Opens the connection to the database
         /// Opens the connection to the database
         /// </summary>
         /// </summary>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        public async Task Initialize(IDbConnector dbConnector)
+        public async Task Initialize()
         {
         {
-            var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db");
-
-            _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
-
-            string[] queries = {
+            using (var connection = await CreateConnection().ConfigureAwait(false))
+            {
+                string[] queries = {
 
 
                                 "create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)",
                                 "create table if not exists userdisplaypreferences (id GUID, userId GUID, client text, data BLOB)",
                                 "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)",
                                 "create unique index if not exists userdisplaypreferencesindex on userdisplaypreferences (id, userId, client)",
@@ -69,7 +61,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                                 "pragma shrink_memory"
                                 "pragma shrink_memory"
                                };
                                };
 
 
-            _connection.RunQueries(queries, Logger);
+                connection.RunQueries(queries, Logger);
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -96,58 +89,57 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             var serialized = _jsonSerializer.SerializeToBytes(displayPreferences);
             var serialized = _jsonSerializer.SerializeToBytes(displayPreferences);
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                transaction = _connection.BeginTransaction();
+                IDbTransaction transaction = null;
 
 
-                using (var cmd = _connection.CreateCommand())
+                try
                 {
                 {
-                    cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)";
+                    transaction = connection.BeginTransaction();
+
+                    using (var cmd = connection.CreateCommand())
+                    {
+                        cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)";
 
 
-                    cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreferences.Id);
-                    cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId;
-                    cmd.Parameters.Add(cmd, "@3", DbType.String).Value = client;
-                    cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized;
+                        cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreferences.Id);
+                        cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId;
+                        cmd.Parameters.Add(cmd, "@3", DbType.String).Value = client;
+                        cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized;
 
 
-                    cmd.Transaction = transaction;
+                        cmd.Transaction = transaction;
 
 
-                    cmd.ExecuteNonQuery();
-                }
+                        cmd.ExecuteNonQuery();
+                    }
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
+                    transaction.Commit();
+                }
+                catch (OperationCanceledException)
                 {
                 {
-                    transaction.Rollback();
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
+
+                    throw;
                 }
                 }
+                catch (Exception e)
+                {
+                    Logger.ErrorException("Failed to save display preferences:", e);
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save display preferences:", e);
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
+                    throw;
                 }
                 }
-
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
+                finally
                 {
                 {
-                    transaction.Dispose();
+                    if (transaction != null)
+                    {
+                        transaction.Dispose();
+                    }
                 }
                 }
-
-                WriteLock.Release();
             }
             }
         }
         }
 
 
@@ -168,64 +160,63 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                transaction = _connection.BeginTransaction();
+                IDbTransaction transaction = null;
 
 
-                foreach (var displayPreference in displayPreferences)
+                try
                 {
                 {
+                    transaction = connection.BeginTransaction();
 
 
-                    var serialized = _jsonSerializer.SerializeToBytes(displayPreference);
-
-                    using (var cmd = _connection.CreateCommand())
+                    foreach (var displayPreference in displayPreferences)
                     {
                     {
-                        cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)";
 
 
-                        cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreference.Id);
-                        cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId;
-                        cmd.Parameters.Add(cmd, "@3", DbType.String).Value = displayPreference.Client;
-                        cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized;
+                        var serialized = _jsonSerializer.SerializeToBytes(displayPreference);
 
 
-                        cmd.Transaction = transaction;
+                        using (var cmd = connection.CreateCommand())
+                        {
+                            cmd.CommandText = "replace into userdisplaypreferences (id, userid, client, data) values (@1, @2, @3, @4)";
 
 
-                        cmd.ExecuteNonQuery();
+                            cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = new Guid(displayPreference.Id);
+                            cmd.Parameters.Add(cmd, "@2", DbType.Guid).Value = userId;
+                            cmd.Parameters.Add(cmd, "@3", DbType.String).Value = displayPreference.Client;
+                            cmd.Parameters.Add(cmd, "@4", DbType.Binary).Value = serialized;
+
+                            cmd.Transaction = transaction;
+
+                            cmd.ExecuteNonQuery();
+                        }
                     }
                     }
-                }
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
+                    transaction.Commit();
+                }
+                catch (OperationCanceledException)
                 {
                 {
-                    transaction.Rollback();
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
+
+                    throw;
                 }
                 }
+                catch (Exception e)
+                {
+                    Logger.ErrorException("Failed to save display preferences:", e);
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save display preferences:", e);
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
+                    throw;
                 }
                 }
-
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
+                finally
                 {
                 {
-                    transaction.Dispose();
+                    if (transaction != null)
+                    {
+                        transaction.Dispose();
+                    }
                 }
                 }
-
-                WriteLock.Release();
             }
             }
         }
         }
 
 
@@ -246,28 +237,33 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             var guidId = displayPreferencesId.GetMD5();
             var guidId = displayPreferencesId.GetMD5();
 
 
-            var cmd = _connection.CreateCommand();
-            cmd.CommandText = "select data from userdisplaypreferences where id = @id and userId=@userId and client=@client";
-
-            cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = guidId;
-            cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
-            cmd.Parameters.Add(cmd, "@client", DbType.String).Value = client;
-
-            using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
+            using (var connection = CreateConnection(true).Result)
             {
             {
-                if (reader.Read())
+                using (var cmd = connection.CreateCommand())
                 {
                 {
-                    using (var stream = reader.GetMemoryStream(0))
+                    cmd.CommandText = "select data from userdisplaypreferences where id = @id and userId=@userId and client=@client";
+
+                    cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = guidId;
+                    cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
+                    cmd.Parameters.Add(cmd, "@client", DbType.String).Value = client;
+
+                    using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
                     {
                     {
-                        return _jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream);
+                        if (reader.Read())
+                        {
+                            using (var stream = reader.GetMemoryStream(0))
+                            {
+                                return _jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream);
+                            }
+                        }
                     }
                     }
+
+                    return new DisplayPreferences
+                    {
+                        Id = guidId.ToString("N")
+                    };
                 }
                 }
             }
             }
-
-            return new DisplayPreferences
-            {
-                Id = guidId.ToString("N")
-            };
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -278,36 +274,30 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <exception cref="System.ArgumentNullException">item</exception>
         /// <exception cref="System.ArgumentNullException">item</exception>
         public IEnumerable<DisplayPreferences> GetAllDisplayPreferences(Guid userId)
         public IEnumerable<DisplayPreferences> GetAllDisplayPreferences(Guid userId)
         {
         {
+            var list = new List<DisplayPreferences>();
 
 
-            var cmd = _connection.CreateCommand();
-            cmd.CommandText = "select data from userdisplaypreferences where userId=@userId";
-
-            cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
-
-            using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
+            using (var connection = CreateConnection(true).Result)
             {
             {
-                while (reader.Read())
+                using (var cmd = connection.CreateCommand())
                 {
                 {
-                    using (var stream = reader.GetMemoryStream(0))
+                    cmd.CommandText = "select data from userdisplaypreferences where userId=@userId";
+
+                    cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId;
+
+                    using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
                     {
                     {
-                        yield return _jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream);
+                        while (reader.Read())
+                        {
+                            using (var stream = reader.GetMemoryStream(0))
+                            {
+                                list.Add(_jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream));
+                            }
+                        }
                     }
                     }
                 }
                 }
             }
             }
-        }
-
-        protected override void CloseConnection()
-        {
-            if (_connection != null)
-            {
-                if (_connection.IsOpen())
-                {
-                    _connection.Close();
-                }
 
 
-                _connection.Dispose();
-                _connection = null;
-            }
+            return list;
         }
         }
 
 
         public Task SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken)
         public Task SaveDisplayPreferences(DisplayPreferences displayPreferences, string userId, string client, CancellationToken cancellationToken)

+ 4 - 16
MediaBrowser.Server.Implementations/Persistence/SqliteExtensions.cs

@@ -19,11 +19,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <summary>
         /// <summary>
         /// Connects to db.
         /// Connects to db.
         /// </summary>
         /// </summary>
-        /// <param name="dbPath">The db path.</param>
-        /// <param name="logger">The logger.</param>
-        /// <returns>Task{IDbConnection}.</returns>
-        /// <exception cref="System.ArgumentNullException">dbPath</exception>
-        public static async Task<IDbConnection> ConnectToDb(string dbPath, int? cacheSize, ILogger logger)
+        public static async Task<IDbConnection> ConnectToDb(string dbPath, bool isReadOnly, bool enablePooling, int? cacheSize, ILogger logger)
         {
         {
             if (string.IsNullOrEmpty(dbPath))
             if (string.IsNullOrEmpty(dbPath))
             {
             {
@@ -38,7 +34,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
                 CacheSize = cacheSize ?? 2000,
                 CacheSize = cacheSize ?? 2000,
                 SyncMode = SynchronizationModes.Normal,
                 SyncMode = SynchronizationModes.Normal,
                 DataSource = dbPath,
                 DataSource = dbPath,
-                JournalMode = SQLiteJournalModeEnum.Wal
+                JournalMode = SQLiteJournalModeEnum.Wal,
+                Pooling = enablePooling,
+                ReadOnly = isReadOnly
             };
             };
 
 
             var connection = new SQLiteConnection(connectionstr.ConnectionString);
             var connection = new SQLiteConnection(connectionstr.ConnectionString);
@@ -47,15 +45,5 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             return connection;
             return connection;
         }
         }
-
-        public static void BindFunction(this SQLiteConnection connection, SQLiteFunction function)
-        {
-            var attributes = function.GetType().GetCustomAttributes(typeof(SQLiteFunctionAttribute), true).Cast<SQLiteFunctionAttribute>().ToArray();
-            if (attributes.Length == 0)
-            {
-                throw new InvalidOperationException("SQLiteFunction doesn't have SQLiteFunctionAttribute");
-            }
-            connection.BindFunction(attributes[0], function);
-        }
     }
     }
 }
 }

+ 2 - 2
MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs

@@ -26,7 +26,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbCommand _deleteResultCommand;
         private IDbCommand _deleteResultCommand;
         private IDbCommand _deleteAllCommand;
         private IDbCommand _deleteAllCommand;
 
 
-        public SqliteFileOrganizationRepository(ILogManager logManager, IServerApplicationPaths appPaths) : base(logManager)
+        public SqliteFileOrganizationRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector connector) : base(logManager, connector)
         {
         {
             _appPaths = appPaths;
             _appPaths = appPaths;
         }
         }
@@ -39,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         {
         {
             var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db");
             var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db");
 
 
-            _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
+            _connection = await dbConnector.Connect(dbFile, false).ConfigureAwait(false);
 
 
             string[] queries = {
             string[] queries = {
 
 

+ 3 - 3
MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs

@@ -99,8 +99,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <summary>
         /// <summary>
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
         /// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
         /// </summary>
         /// </summary>
-        public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager)
-            : base(logManager)
+        public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager, IDbConnector connector)
+            : base(logManager, connector)
         {
         {
             if (config == null)
             if (config == null)
             {
             {
@@ -127,7 +127,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         {
         {
             var dbFile = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
             var dbFile = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
 
 
-            _connection = await dbConnector.Connect(dbFile, 6000).ConfigureAwait(false);
+            _connection = await dbConnector.Connect(dbFile, false, false, 6000).ConfigureAwait(false);
 
 
             var createMediaStreamsTableCommand
             var createMediaStreamsTableCommand
                = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))";
                = "create table if not exists mediastreams (ItemId GUID, StreamIndex INT, StreamType TEXT, Codec TEXT, Language TEXT, ChannelLayout TEXT, Profile TEXT, AspectRatio TEXT, Path TEXT, IsInterlaced BIT, BitRate INT NULL, Channels INT NULL, SampleRate INT NULL, IsDefault BIT, IsForced BIT, IsExternal BIT, Height INT NULL, Width INT NULL, AverageFrameRate FLOAT NULL, RealFrameRate FLOAT NULL, Level FLOAT NULL, PixelFormat TEXT, BitDepth INT NULL, IsAnamorphic BIT NULL, RefFrames INT NULL, CodecTag TEXT NULL, Comment TEXT NULL, NalLengthSize TEXT NULL, IsAvc BIT NULL, Title TEXT NULL, TimeBase TEXT NULL, CodecTimeBase TEXT NULL, PRIMARY KEY (ItemId, StreamIndex))";

+ 2 - 2
MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs

@@ -18,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         private IDbConnection _connection;
         private IDbConnection _connection;
         private readonly IApplicationPaths _appPaths;
         private readonly IApplicationPaths _appPaths;
 
 
-        public SqliteUserDataRepository(ILogManager logManager, IApplicationPaths appPaths) : base(logManager)
+        public SqliteUserDataRepository(ILogManager logManager, IApplicationPaths appPaths, IDbConnector connector) : base(logManager, connector)
         {
         {
             _appPaths = appPaths;
             _appPaths = appPaths;
         }
         }
@@ -43,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
         {
         {
             var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db");
             var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db");
 
 
-            _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
+            _connection = await dbConnector.Connect(dbFile, false).ConfigureAwait(false);
 
 
             string[] queries = {
             string[] queries = {
 
 

+ 95 - 106
MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs

@@ -17,14 +17,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
     /// </summary>
     /// </summary>
     public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
     public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
     {
     {
-        private IDbConnection _connection;
-        private readonly IServerApplicationPaths _appPaths;
         private readonly IJsonSerializer _jsonSerializer;
         private readonly IJsonSerializer _jsonSerializer;
 
 
-        public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer) : base(logManager)
+        public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector) : base(logManager, dbConnector)
         {
         {
-            _appPaths = appPaths;
             _jsonSerializer = jsonSerializer;
             _jsonSerializer = jsonSerializer;
+
+            DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -43,13 +42,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// Opens the connection to the database
         /// Opens the connection to the database
         /// </summary>
         /// </summary>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        public async Task Initialize(IDbConnector dbConnector)
+        public async Task Initialize()
         {
         {
-            var dbFile = Path.Combine(_appPaths.DataPath, "users.db");
-
-            _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
-
-            string[] queries = {
+            using (var connection = await CreateConnection().ConfigureAwait(false))
+            {
+                string[] queries = {
 
 
                                 "create table if not exists users (guid GUID primary key, data BLOB)",
                                 "create table if not exists users (guid GUID primary key, data BLOB)",
                                 "create index if not exists idx_users on users(guid)",
                                 "create index if not exists idx_users on users(guid)",
@@ -61,7 +58,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
                                 "pragma shrink_memory"
                                 "pragma shrink_memory"
                                };
                                };
 
 
-            _connection.RunQueries(queries, Logger);
+                connection.RunQueries(queries, Logger);
+            }
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -84,55 +82,54 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-            
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                transaction = _connection.BeginTransaction();
+                IDbTransaction transaction = null;
 
 
-                using (var cmd = _connection.CreateCommand())
+                try
                 {
                 {
-                    cmd.CommandText = "replace into users (guid, data) values (@1, @2)";
-                    cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = user.Id;
-                    cmd.Parameters.Add(cmd, "@2", DbType.Binary).Value = serialized;
+                    transaction = connection.BeginTransaction();
 
 
-                    cmd.Transaction = transaction;
+                    using (var cmd = connection.CreateCommand())
+                    {
+                        cmd.CommandText = "replace into users (guid, data) values (@1, @2)";
+                        cmd.Parameters.Add(cmd, "@1", DbType.Guid).Value = user.Id;
+                        cmd.Parameters.Add(cmd, "@2", DbType.Binary).Value = serialized;
 
 
-                    cmd.ExecuteNonQuery();
-                }
+                        cmd.Transaction = transaction;
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
+                        cmd.ExecuteNonQuery();
+                    }
+
+                    transaction.Commit();
+                }
+                catch (OperationCanceledException)
                 {
                 {
-                    transaction.Rollback();
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
+
+                    throw;
                 }
                 }
+                catch (Exception e)
+                {
+                    Logger.ErrorException("Failed to save user:", e);
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save user:", e);
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
+                    throw;
                 }
                 }
-
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
+                finally
                 {
                 {
-                    transaction.Dispose();
+                    if (transaction != null)
+                    {
+                        transaction.Dispose();
+                    }
                 }
                 }
-
-                WriteLock.Release();
             }
             }
         }
         }
 
 
@@ -142,25 +139,32 @@ namespace MediaBrowser.Server.Implementations.Persistence
         /// <returns>IEnumerable{User}.</returns>
         /// <returns>IEnumerable{User}.</returns>
         public IEnumerable<User> RetrieveAllUsers()
         public IEnumerable<User> RetrieveAllUsers()
         {
         {
-            using (var cmd = _connection.CreateCommand())
-            {
-                cmd.CommandText = "select guid,data from users";
+            var list = new List<User>();
 
 
-                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
+            using (var connection = CreateConnection(true).Result)
+            {
+                using (var cmd = connection.CreateCommand())
                 {
                 {
-                    while (reader.Read())
-                    {
-                        var id = reader.GetGuid(0);
+                    cmd.CommandText = "select guid,data from users";
 
 
-                        using (var stream = reader.GetMemoryStream(1))
+                    using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult))
+                    {
+                        while (reader.Read())
                         {
                         {
-                            var user = _jsonSerializer.DeserializeFromStream<User>(stream);
-                            user.Id = id;
-                            yield return user;
+                            var id = reader.GetGuid(0);
+
+                            using (var stream = reader.GetMemoryStream(1))
+                            {
+                                var user = _jsonSerializer.DeserializeFromStream<User>(stream);
+                                user.Id = id;
+                                list.Add(user);
+                            }
                         }
                         }
                     }
                     }
                 }
                 }
             }
             }
+
+            return list;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -179,69 +183,54 @@ namespace MediaBrowser.Server.Implementations.Persistence
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                transaction = _connection.BeginTransaction();
+                IDbTransaction transaction = null;
 
 
-                using (var cmd = _connection.CreateCommand())
+                try
                 {
                 {
-                    cmd.CommandText = "delete from users where guid=@guid";
-
-                    cmd.Parameters.Add(cmd, "@guid", DbType.Guid).Value = user.Id;
+                    transaction = connection.BeginTransaction();
 
 
-                    cmd.Transaction = transaction;
+                    using (var cmd = connection.CreateCommand())
+                    {
+                        cmd.CommandText = "delete from users where guid=@guid";
 
 
-                    cmd.ExecuteNonQuery();
-                }
+                        cmd.Parameters.Add(cmd, "@guid", DbType.Guid).Value = user.Id;
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        cmd.Transaction = transaction;
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to delete user:", e);
+                        cmd.ExecuteNonQuery();
+                    }
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
+                    transaction.Commit();
                 }
                 }
-
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
+                catch (OperationCanceledException)
                 {
                 {
-                    transaction.Dispose();
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
+
+                    throw;
                 }
                 }
+                catch (Exception e)
+                {
+                    Logger.ErrorException("Failed to delete user:", e);
 
 
-                WriteLock.Release();
-            }
-        }
+                    if (transaction != null)
+                    {
+                        transaction.Rollback();
+                    }
 
 
-        protected override void CloseConnection()
-        {
-            if (_connection != null)
-            {
-                if (_connection.IsOpen())
+                    throw;
+                }
+                finally
                 {
                 {
-                    _connection.Close();
+                    if (transaction != null)
+                    {
+                        transaction.Dispose();
+                    }
                 }
                 }
-
-                _connection.Dispose();
-                _connection = null;
             }
             }
         }
         }
     }
     }

+ 155 - 170
MediaBrowser.Server.Implementations/Security/AuthenticationRepository.cs

@@ -15,25 +15,21 @@ namespace MediaBrowser.Server.Implementations.Security
 {
 {
     public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository
     public class AuthenticationRepository : BaseSqliteRepository, IAuthenticationRepository
     {
     {
-        private IDbConnection _connection;
         private readonly IServerApplicationPaths _appPaths;
         private readonly IServerApplicationPaths _appPaths;
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
         private readonly CultureInfo _usCulture = new CultureInfo("en-US");
 
 
-        private IDbCommand _saveInfoCommand;
-
-        public AuthenticationRepository(ILogManager logManager, IServerApplicationPaths appPaths)
-            : base(logManager)
+        public AuthenticationRepository(ILogManager logManager, IServerApplicationPaths appPaths, IDbConnector connector)
+            : base(logManager, connector)
         {
         {
             _appPaths = appPaths;
             _appPaths = appPaths;
+            DbFilePath = Path.Combine(appPaths.DataPath, "authentication.db");
         }
         }
 
 
-        public async Task Initialize(IDbConnector dbConnector)
+        public async Task Initialize()
         {
         {
-            var dbFile = Path.Combine(_appPaths.DataPath, "authentication.db");
-
-            _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
-
-            string[] queries = {
+            using (var connection = await CreateConnection().ConfigureAwait(false))
+            {
+                string[] queries = {
 
 
                                 "create table if not exists AccessTokens (Id GUID PRIMARY KEY, AccessToken TEXT NOT NULL, DeviceId TEXT, AppName TEXT, AppVersion TEXT, DeviceName TEXT, UserId TEXT, IsActive BIT, DateCreated DATETIME NOT NULL, DateRevoked DATETIME)",
                                 "create table if not exists AccessTokens (Id GUID PRIMARY KEY, AccessToken TEXT NOT NULL, DeviceId TEXT, AppName TEXT, AppVersion TEXT, DeviceName TEXT, UserId TEXT, IsActive BIT, DateCreated DATETIME NOT NULL, DateRevoked DATETIME)",
                                 "create index if not exists idx_AccessTokens on AccessTokens(Id)",
                                 "create index if not exists idx_AccessTokens on AccessTokens(Id)",
@@ -44,28 +40,10 @@ namespace MediaBrowser.Server.Implementations.Security
                                 "pragma shrink_memory"
                                 "pragma shrink_memory"
                                };
                                };
 
 
-            _connection.RunQueries(queries, Logger);
-
-            _connection.AddColumn(Logger, "AccessTokens", "AppVersion", "TEXT");
+                connection.RunQueries(queries, Logger);
 
 
-            PrepareStatements();
-        }
-
-        private void PrepareStatements()
-        {
-            _saveInfoCommand = _connection.CreateCommand();
-            _saveInfoCommand.CommandText = "replace into AccessTokens (Id, AccessToken, DeviceId, AppName, AppVersion, DeviceName, UserId, IsActive, DateCreated, DateRevoked) values (@Id, @AccessToken, @DeviceId, @AppName, @AppVersion, @DeviceName, @UserId, @IsActive, @DateCreated, @DateRevoked)";
-
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@Id");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@AccessToken");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DeviceId");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@AppName");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@AppVersion");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DeviceName");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@UserId");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@IsActive");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DateCreated");
-            _saveInfoCommand.Parameters.Add(_saveInfoCommand, "@DateRevoked");
+                connection.AddColumn(Logger, "AccessTokens", "AppVersion", "TEXT");
+            }
         }
         }
 
 
         public Task Create(AuthenticationInfo info, CancellationToken cancellationToken)
         public Task Create(AuthenticationInfo info, CancellationToken cancellationToken)
@@ -84,61 +62,76 @@ namespace MediaBrowser.Server.Implementations.Security
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                transaction = _connection.BeginTransaction();
+                using (var saveInfoCommand = connection.CreateCommand())
+                {
+                    saveInfoCommand.CommandText = "replace into AccessTokens (Id, AccessToken, DeviceId, AppName, AppVersion, DeviceName, UserId, IsActive, DateCreated, DateRevoked) values (@Id, @AccessToken, @DeviceId, @AppName, @AppVersion, @DeviceName, @UserId, @IsActive, @DateCreated, @DateRevoked)";
+
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@Id");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@AccessToken");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@DeviceId");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@AppName");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@AppVersion");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@DeviceName");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@UserId");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@IsActive");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@DateCreated");
+                    saveInfoCommand.Parameters.Add(saveInfoCommand, "@DateRevoked");
+
+                    IDbTransaction transaction = null;
+
+                    try
+                    {
+                        transaction = connection.BeginTransaction();
 
 
-                var index = 0;
+                        var index = 0;
 
 
-                _saveInfoCommand.GetParameter(index++).Value = new Guid(info.Id);
-                _saveInfoCommand.GetParameter(index++).Value = info.AccessToken;
-                _saveInfoCommand.GetParameter(index++).Value = info.DeviceId;
-                _saveInfoCommand.GetParameter(index++).Value = info.AppName;
-                _saveInfoCommand.GetParameter(index++).Value = info.AppVersion;
-                _saveInfoCommand.GetParameter(index++).Value = info.DeviceName;
-                _saveInfoCommand.GetParameter(index++).Value = info.UserId;
-                _saveInfoCommand.GetParameter(index++).Value = info.IsActive;
-                _saveInfoCommand.GetParameter(index++).Value = info.DateCreated;
-                _saveInfoCommand.GetParameter(index++).Value = info.DateRevoked;
+                        saveInfoCommand.GetParameter(index++).Value = new Guid(info.Id);
+                        saveInfoCommand.GetParameter(index++).Value = info.AccessToken;
+                        saveInfoCommand.GetParameter(index++).Value = info.DeviceId;
+                        saveInfoCommand.GetParameter(index++).Value = info.AppName;
+                        saveInfoCommand.GetParameter(index++).Value = info.AppVersion;
+                        saveInfoCommand.GetParameter(index++).Value = info.DeviceName;
+                        saveInfoCommand.GetParameter(index++).Value = info.UserId;
+                        saveInfoCommand.GetParameter(index++).Value = info.IsActive;
+                        saveInfoCommand.GetParameter(index++).Value = info.DateCreated;
+                        saveInfoCommand.GetParameter(index++).Value = info.DateRevoked;
 
 
-                _saveInfoCommand.Transaction = transaction;
+                        saveInfoCommand.Transaction = transaction;
 
 
-                _saveInfoCommand.ExecuteNonQuery();
+                        saveInfoCommand.ExecuteNonQuery();
 
 
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        transaction.Commit();
+                    }
+                    catch (OperationCanceledException)
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save record:", e);
+                        throw;
+                    }
+                    catch (Exception e)
+                    {
+                        Logger.ErrorException("Failed to save record:", e);
 
 
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
 
 
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
-                {
-                    transaction.Dispose();
+                        throw;
+                    }
+                    finally
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Dispose();
+                        }
+                    }
                 }
                 }
-
-                WriteLock.Release();
             }
             }
         }
         }
 
 
@@ -151,101 +144,104 @@ namespace MediaBrowser.Server.Implementations.Security
                 throw new ArgumentNullException("query");
                 throw new ArgumentNullException("query");
             }
             }
 
 
-            using (var cmd = _connection.CreateCommand())
+            using (var connection = CreateConnection(true).Result)
             {
             {
-                cmd.CommandText = BaseSelectText;
-
-                var whereClauses = new List<string>();
-
-                var startIndex = query.StartIndex ?? 0;
-
-                if (!string.IsNullOrWhiteSpace(query.AccessToken))
+                using (var cmd = connection.CreateCommand())
                 {
                 {
-                    whereClauses.Add("AccessToken=@AccessToken");
-                    cmd.Parameters.Add(cmd, "@AccessToken", DbType.String).Value = query.AccessToken;
-                }
+                    cmd.CommandText = BaseSelectText;
 
 
-                if (!string.IsNullOrWhiteSpace(query.UserId))
-                {
-                    whereClauses.Add("UserId=@UserId");
-                    cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId;
-                }
+                    var whereClauses = new List<string>();
 
 
-                if (!string.IsNullOrWhiteSpace(query.DeviceId))
-                {
-                    whereClauses.Add("DeviceId=@DeviceId");
-                    cmd.Parameters.Add(cmd, "@DeviceId", DbType.String).Value = query.DeviceId;
-                }
+                    var startIndex = query.StartIndex ?? 0;
 
 
-                if (query.IsActive.HasValue)
-                {
-                    whereClauses.Add("IsActive=@IsActive");
-                    cmd.Parameters.Add(cmd, "@IsActive", DbType.Boolean).Value = query.IsActive.Value;
-                }
+                    if (!string.IsNullOrWhiteSpace(query.AccessToken))
+                    {
+                        whereClauses.Add("AccessToken=@AccessToken");
+                        cmd.Parameters.Add(cmd, "@AccessToken", DbType.String).Value = query.AccessToken;
+                    }
 
 
-                if (query.HasUser.HasValue)
-                {
-                    if (query.HasUser.Value)
+                    if (!string.IsNullOrWhiteSpace(query.UserId))
                     {
                     {
-                        whereClauses.Add("UserId not null");
+                        whereClauses.Add("UserId=@UserId");
+                        cmd.Parameters.Add(cmd, "@UserId", DbType.String).Value = query.UserId;
                     }
                     }
-                    else
+
+                    if (!string.IsNullOrWhiteSpace(query.DeviceId))
                     {
                     {
-                        whereClauses.Add("UserId is null");
+                        whereClauses.Add("DeviceId=@DeviceId");
+                        cmd.Parameters.Add(cmd, "@DeviceId", DbType.String).Value = query.DeviceId;
                     }
                     }
-                }
 
 
-                var whereTextWithoutPaging = whereClauses.Count == 0 ?
-                    string.Empty :
-                    " where " + string.Join(" AND ", whereClauses.ToArray());
+                    if (query.IsActive.HasValue)
+                    {
+                        whereClauses.Add("IsActive=@IsActive");
+                        cmd.Parameters.Add(cmd, "@IsActive", DbType.Boolean).Value = query.IsActive.Value;
+                    }
 
 
-                if (startIndex > 0)
-                {
-                    var pagingWhereText = whereClauses.Count == 0 ?
+                    if (query.HasUser.HasValue)
+                    {
+                        if (query.HasUser.Value)
+                        {
+                            whereClauses.Add("UserId not null");
+                        }
+                        else
+                        {
+                            whereClauses.Add("UserId is null");
+                        }
+                    }
+
+                    var whereTextWithoutPaging = whereClauses.Count == 0 ?
                         string.Empty :
                         string.Empty :
                         " where " + string.Join(" AND ", whereClauses.ToArray());
                         " where " + string.Join(" AND ", whereClauses.ToArray());
 
 
-                    whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM AccessTokens {0} ORDER BY DateCreated LIMIT {1})",
-                        pagingWhereText,
-                        startIndex.ToString(_usCulture)));
-                }
+                    if (startIndex > 0)
+                    {
+                        var pagingWhereText = whereClauses.Count == 0 ?
+                            string.Empty :
+                            " where " + string.Join(" AND ", whereClauses.ToArray());
+
+                        whereClauses.Add(string.Format("Id NOT IN (SELECT Id FROM AccessTokens {0} ORDER BY DateCreated LIMIT {1})",
+                            pagingWhereText,
+                            startIndex.ToString(_usCulture)));
+                    }
 
 
-                var whereText = whereClauses.Count == 0 ?
-                    string.Empty :
-                    " where " + string.Join(" AND ", whereClauses.ToArray());
+                    var whereText = whereClauses.Count == 0 ?
+                        string.Empty :
+                        " where " + string.Join(" AND ", whereClauses.ToArray());
 
 
-                cmd.CommandText += whereText;
+                    cmd.CommandText += whereText;
 
 
-                cmd.CommandText += " ORDER BY DateCreated";
+                    cmd.CommandText += " ORDER BY DateCreated";
 
 
-                if (query.Limit.HasValue)
-                {
-                    cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture);
-                }
+                    if (query.Limit.HasValue)
+                    {
+                        cmd.CommandText += " LIMIT " + query.Limit.Value.ToString(_usCulture);
+                    }
 
 
-                cmd.CommandText += "; select count (Id) from AccessTokens" + whereTextWithoutPaging;
+                    cmd.CommandText += "; select count (Id) from AccessTokens" + whereTextWithoutPaging;
 
 
-                var list = new List<AuthenticationInfo>();
-                var count = 0;
+                    var list = new List<AuthenticationInfo>();
+                    var count = 0;
 
 
-                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
-                {
-                    while (reader.Read())
+                    using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
                     {
                     {
-                        list.Add(Get(reader));
+                        while (reader.Read())
+                        {
+                            list.Add(Get(reader));
+                        }
+
+                        if (reader.NextResult() && reader.Read())
+                        {
+                            count = reader.GetInt32(0);
+                        }
                     }
                     }
 
 
-                    if (reader.NextResult() && reader.Read())
+                    return new QueryResult<AuthenticationInfo>()
                     {
                     {
-                        count = reader.GetInt32(0);
-                    }
+                        Items = list.ToArray(),
+                        TotalRecordCount = count
+                    };
                 }
                 }
-
-                return new QueryResult<AuthenticationInfo>()
-                {
-                    Items = list.ToArray(),
-                    TotalRecordCount = count
-                };
             }
             }
         }
         }
 
 
@@ -256,24 +252,27 @@ namespace MediaBrowser.Server.Implementations.Security
                 throw new ArgumentNullException("id");
                 throw new ArgumentNullException("id");
             }
             }
 
 
-            var guid = new Guid(id);
-
-            using (var cmd = _connection.CreateCommand())
+            using (var connection = CreateConnection(true).Result)
             {
             {
-                cmd.CommandText = BaseSelectText + " where Id=@Id";
-
-                cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid;
+                var guid = new Guid(id);
 
 
-                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
+                using (var cmd = connection.CreateCommand())
                 {
                 {
-                    if (reader.Read())
+                    cmd.CommandText = BaseSelectText + " where Id=@Id";
+
+                    cmd.Parameters.Add(cmd, "@Id", DbType.Guid).Value = guid;
+
+                    using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
                     {
                     {
-                        return Get(reader);
+                        if (reader.Read())
+                        {
+                            return Get(reader);
+                        }
                     }
                     }
                 }
                 }
-            }
 
 
-            return null;
+                return null;
+            }
         }
         }
 
 
         private AuthenticationInfo Get(IDataReader reader)
         private AuthenticationInfo Get(IDataReader reader)
@@ -319,19 +318,5 @@ namespace MediaBrowser.Server.Implementations.Security
 
 
             return info;
             return info;
         }
         }
-
-        protected override void CloseConnection()
-        {
-            if (_connection != null)
-            {
-                if (_connection.IsOpen())
-                {
-                    _connection.Close();
-                }
-
-                _connection.Dispose();
-                _connection = null;
-            }
-        }
     }
     }
 }
 }

+ 74 - 97
MediaBrowser.Server.Implementations/Social/SharingRepository.cs

@@ -12,27 +12,21 @@ namespace MediaBrowser.Server.Implementations.Social
 {
 {
     public class SharingRepository : BaseSqliteRepository
     public class SharingRepository : BaseSqliteRepository
     {
     {
-        private IDbConnection _connection;
-        private IDbCommand _saveShareCommand;
-        private readonly IApplicationPaths _appPaths;
-
-        public SharingRepository(ILogManager logManager, IApplicationPaths appPaths)
-            : base(logManager)
+        public SharingRepository(ILogManager logManager, IApplicationPaths appPaths, IDbConnector dbConnector)
+            : base(logManager, dbConnector)
         {
         {
-            _appPaths = appPaths;
+            DbFilePath = Path.Combine(appPaths.DataPath, "shares.db");
         }
         }
 
 
         /// <summary>
         /// <summary>
         /// Opens the connection to the database
         /// Opens the connection to the database
         /// </summary>
         /// </summary>
         /// <returns>Task.</returns>
         /// <returns>Task.</returns>
-        public async Task Initialize(IDbConnector dbConnector)
+        public async Task Initialize()
         {
         {
-            var dbFile = Path.Combine(_appPaths.DataPath, "shares.db");
-
-            _connection = await dbConnector.Connect(dbFile).ConfigureAwait(false);
-
-            string[] queries = {
+            using (var connection = await CreateConnection().ConfigureAwait(false))
+            {
+                string[] queries = {
 
 
                                 "create table if not exists Shares (Id GUID, ItemId TEXT, UserId TEXT, ExpirationDate DateTime, PRIMARY KEY (Id))",
                                 "create table if not exists Shares (Id GUID, ItemId TEXT, UserId TEXT, ExpirationDate DateTime, PRIMARY KEY (Id))",
                                 "create index if not exists idx_Shares on Shares(Id)",
                                 "create index if not exists idx_Shares on Shares(Id)",
@@ -43,23 +37,8 @@ namespace MediaBrowser.Server.Implementations.Social
                                 "pragma shrink_memory"
                                 "pragma shrink_memory"
                                };
                                };
 
 
-            _connection.RunQueries(queries, Logger);
-
-            PrepareStatements();
-        }
-
-        /// <summary>
-        /// Prepares the statements.
-        /// </summary>
-        private void PrepareStatements()
-        {
-            _saveShareCommand = _connection.CreateCommand();
-            _saveShareCommand.CommandText = "replace into Shares (Id, ItemId, UserId, ExpirationDate) values (@Id, @ItemId, @UserId, @ExpirationDate)";
-
-            _saveShareCommand.Parameters.Add(_saveShareCommand, "@Id");
-            _saveShareCommand.Parameters.Add(_saveShareCommand, "@ItemId");
-            _saveShareCommand.Parameters.Add(_saveShareCommand, "@UserId");
-            _saveShareCommand.Parameters.Add(_saveShareCommand, "@ExpirationDate");
+                connection.RunQueries(queries, Logger);
+            }
         }
         }
 
 
         public async Task CreateShare(SocialShareInfo info)
         public async Task CreateShare(SocialShareInfo info)
@@ -77,53 +56,62 @@ namespace MediaBrowser.Server.Implementations.Social
 
 
             cancellationToken.ThrowIfCancellationRequested();
             cancellationToken.ThrowIfCancellationRequested();
 
 
-            await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
-            IDbTransaction transaction = null;
-
-            try
+            using (var connection = await CreateConnection().ConfigureAwait(false))
             {
             {
-                transaction = _connection.BeginTransaction();
-
-                _saveShareCommand.GetParameter(0).Value = new Guid(info.Id);
-                _saveShareCommand.GetParameter(1).Value = info.ItemId;
-                _saveShareCommand.GetParameter(2).Value = info.UserId;
-                _saveShareCommand.GetParameter(3).Value = info.ExpirationDate;
-
-                _saveShareCommand.Transaction = transaction;
-
-                _saveShareCommand.ExecuteNonQuery();
-
-                transaction.Commit();
-            }
-            catch (OperationCanceledException)
-            {
-                if (transaction != null)
+                using (var saveShareCommand = connection.CreateCommand())
                 {
                 {
-                    transaction.Rollback();
+                    saveShareCommand.CommandText = "replace into Shares (Id, ItemId, UserId, ExpirationDate) values (@Id, @ItemId, @UserId, @ExpirationDate)";
+
+                    saveShareCommand.Parameters.Add(saveShareCommand, "@Id");
+                    saveShareCommand.Parameters.Add(saveShareCommand, "@ItemId");
+                    saveShareCommand.Parameters.Add(saveShareCommand, "@UserId");
+                    saveShareCommand.Parameters.Add(saveShareCommand, "@ExpirationDate");
+
+                    IDbTransaction transaction = null;
+
+                    try
+                    {
+                        transaction = connection.BeginTransaction();
+
+                        saveShareCommand.GetParameter(0).Value = new Guid(info.Id);
+                        saveShareCommand.GetParameter(1).Value = info.ItemId;
+                        saveShareCommand.GetParameter(2).Value = info.UserId;
+                        saveShareCommand.GetParameter(3).Value = info.ExpirationDate;
+
+                        saveShareCommand.Transaction = transaction;
+
+                        saveShareCommand.ExecuteNonQuery();
+
+                        transaction.Commit();
+                    }
+                    catch (OperationCanceledException)
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
+
+                        throw;
+                    }
+                    catch (Exception e)
+                    {
+                        Logger.ErrorException("Failed to save share:", e);
+
+                        if (transaction != null)
+                        {
+                            transaction.Rollback();
+                        }
+
+                        throw;
+                    }
+                    finally
+                    {
+                        if (transaction != null)
+                        {
+                            transaction.Dispose();
+                        }
+                    }
                 }
                 }
-
-                throw;
-            }
-            catch (Exception e)
-            {
-                Logger.ErrorException("Failed to save share:", e);
-
-                if (transaction != null)
-                {
-                    transaction.Rollback();
-                }
-
-                throw;
-            }
-            finally
-            {
-                if (transaction != null)
-                {
-                    transaction.Dispose();
-                }
-
-                WriteLock.Release();
             }
             }
         }
         }
 
 
@@ -134,20 +122,23 @@ namespace MediaBrowser.Server.Implementations.Social
                 throw new ArgumentNullException("id");
                 throw new ArgumentNullException("id");
             }
             }
 
 
-            var cmd = _connection.CreateCommand();
-            cmd.CommandText = "select Id, ItemId, UserId, ExpirationDate from Shares where id = @id";
+            using (var connection = CreateConnection(true).Result)
+            {
+                var cmd = connection.CreateCommand();
+                cmd.CommandText = "select Id, ItemId, UserId, ExpirationDate from Shares where id = @id";
 
 
-            cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = new Guid(id);
+                cmd.Parameters.Add(cmd, "@id", DbType.Guid).Value = new Guid(id);
 
 
-            using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
-            {
-                if (reader.Read())
+                using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow))
                 {
                 {
-                    return GetSocialShareInfo(reader);
+                    if (reader.Read())
+                    {
+                        return GetSocialShareInfo(reader);
+                    }
                 }
                 }
-            }
 
 
-            return null;
+                return null;
+            }
         }
         }
 
 
         private SocialShareInfo GetSocialShareInfo(IDataReader reader)
         private SocialShareInfo GetSocialShareInfo(IDataReader reader)
@@ -164,21 +155,7 @@ namespace MediaBrowser.Server.Implementations.Social
 
 
         public async Task DeleteShare(string id)
         public async Task DeleteShare(string id)
         {
         {
-            
-        }
-
-        protected override void CloseConnection()
-        {
-            if (_connection != null)
-            {
-                if (_connection.IsOpen())
-                {
-                    _connection.Close();
-                }
 
 
-                _connection.Dispose();
-                _connection = null;
-            }
         }
         }
     }
     }
 }
 }

File diff suppressed because it is too large
+ 427 - 424
MediaBrowser.Server.Implementations/Sync/SyncRepository.cs


Some files were not shown because too many files changed in this diff