diff options
Diffstat (limited to 'MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs')
| -rw-r--r-- | MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs | 173 |
1 files changed, 152 insertions, 21 deletions
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs index 4e388b4b0..0f0488168 100644 --- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs +++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs @@ -2,8 +2,8 @@ using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Persistence; using MediaBrowser.Model.Logging; -using MediaBrowser.Model.Serialization; using System; +using System.Collections.Generic; using System.Data; using System.IO; using System.Threading; @@ -56,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Persistence } private SqliteShrinkMemoryTimer _shrinkMemoryTimer; - + /// <summary> /// Opens the connection to the database /// </summary> @@ -117,6 +117,20 @@ namespace MediaBrowser.Server.Implementations.Persistence return PersistUserData(userId, key, userData, cancellationToken); } + public Task SaveAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken) + { + if (userData == null) + { + throw new ArgumentNullException("userData"); + } + if (userId == Guid.Empty) + { + throw new ArgumentNullException("userId"); + } + + return PersistAllUserData(userId, userData, cancellationToken); + } + /// <summary> /// Persists the user data. /// </summary> @@ -189,6 +203,81 @@ namespace MediaBrowser.Server.Implementations.Persistence } /// <summary> + /// Persist all user data for the specified user + /// </summary> + /// <param name="userId"></param> + /// <param name="userData"></param> + /// <param name="cancellationToken"></param> + /// <returns></returns> + private async Task PersistAllUserData(Guid userId, IEnumerable<UserItemData> userData, CancellationToken cancellationToken) + { + cancellationToken.ThrowIfCancellationRequested(); + + await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false); + + IDbTransaction transaction = null; + + try + { + transaction = _connection.BeginTransaction(); + + foreach (var userItemData in userData) + { + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "replace into userdata (key, userId, rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate) values (@key, @userId, @rating,@played,@playCount,@isFavorite,@playbackPositionTicks,@lastPlayedDate)"; + + cmd.Parameters.Add(cmd, "@key", DbType.String).Value = userItemData.Key; + cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; + cmd.Parameters.Add(cmd, "@rating", DbType.Double).Value = userItemData.Rating; + cmd.Parameters.Add(cmd, "@played", DbType.Boolean).Value = userItemData.Played; + cmd.Parameters.Add(cmd, "@playCount", DbType.Int32).Value = userItemData.PlayCount; + cmd.Parameters.Add(cmd, "@isFavorite", DbType.Boolean).Value = userItemData.IsFavorite; + cmd.Parameters.Add(cmd, "@playbackPositionTicks", DbType.Int64).Value = userItemData.PlaybackPositionTicks; + cmd.Parameters.Add(cmd, "@lastPlayedDate", DbType.DateTime).Value = userItemData.LastPlayedDate; + + cmd.Transaction = transaction; + + cmd.ExecuteNonQuery(); + } + + cancellationToken.ThrowIfCancellationRequested(); + } + + transaction.Commit(); + } + catch (OperationCanceledException) + { + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + catch (Exception e) + { + _logger.ErrorException("Failed to save user data:", e); + + if (transaction != null) + { + transaction.Rollback(); + } + + throw; + } + finally + { + if (transaction != null) + { + transaction.Dispose(); + } + + _writeLock.Release(); + } + } + + /// <summary> /// Gets the user data. /// </summary> /// <param name="userId">The user id.</param> @@ -212,40 +301,82 @@ namespace MediaBrowser.Server.Implementations.Persistence using (var cmd = _connection.CreateCommand()) { - cmd.CommandText = "select rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId"; + cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where key = @key and userId=@userId"; cmd.Parameters.Add(cmd, "@key", DbType.String).Value = key; cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; - var userData = new UserItemData + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) + { + if (reader.Read()) + { + return ReadRow(reader); + } + } + + return new UserItemData { UserId = userId, Key = key }; + } + } - using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult | CommandBehavior.SingleRow)) - { - if (reader.Read()) - { - if (!reader.IsDBNull(0)) - { - userData.Rating = reader.GetDouble(0); - } + /// <summary> + /// Return all user-data associated with the given user + /// </summary> + /// <param name="userId"></param> + /// <returns></returns> + public IEnumerable<UserItemData> GetAllUserData(Guid userId) + { + if (userId == Guid.Empty) + { + throw new ArgumentNullException("userId"); + } + + using (var cmd = _connection.CreateCommand()) + { + cmd.CommandText = "select key,userid,rating,played,playCount,isFavorite,playbackPositionTicks,lastPlayedDate from userdata where userId=@userId"; - userData.Played = reader.GetBoolean(1); - userData.PlayCount = reader.GetInt32(2); - userData.IsFavorite = reader.GetBoolean(3); - userData.PlaybackPositionTicks = reader.GetInt64(4); + cmd.Parameters.Add(cmd, "@userId", DbType.Guid).Value = userId; - if (!reader.IsDBNull(5)) - { - userData.LastPlayedDate = reader.GetDateTime(5).ToUniversalTime(); - } + using (var reader = cmd.ExecuteReader(CommandBehavior.SequentialAccess | CommandBehavior.SingleResult)) + { + while (reader.Read()) + { + yield return ReadRow(reader); } } + } + } + + /// <summary> + /// Read a row from the specified reader into the provided userData object + /// </summary> + /// <param name="reader"></param> + private UserItemData ReadRow(IDataReader reader) + { + var userData = new UserItemData(); + + userData.Key = reader.GetString(0); + userData.UserId = reader.GetGuid(1); - return userData; + if (!reader.IsDBNull(2)) + { + userData.Rating = reader.GetDouble(2); + } + + userData.Played = reader.GetBoolean(3); + userData.PlayCount = reader.GetInt32(4); + userData.IsFavorite = reader.GetBoolean(5); + userData.PlaybackPositionTicks = reader.GetInt64(6); + + if (!reader.IsDBNull(7)) + { + userData.LastPlayedDate = reader.GetDateTime(7).ToUniversalTime(); } + + return userData; } /// <summary> |
