diff options
Diffstat (limited to 'dsa/FireBase/Offline')
-rw-r--r-- | dsa/FireBase/Offline/ConcurrentOfflineDatabase.cs | 51 | ||||
-rw-r--r-- | dsa/FireBase/Offline/DatabaseExtensions.cs | 39 | ||||
-rw-r--r-- | dsa/FireBase/Offline/ISetHandler.cs | 6 | ||||
-rw-r--r-- | dsa/FireBase/Offline/InitialPullStrategy.cs | 6 | ||||
-rw-r--r-- | dsa/FireBase/Offline/Internals/MemberAccessVisitor.cs | 24 | ||||
-rw-r--r-- | dsa/FireBase/Offline/OfflineCacheAdapter.cs | 72 | ||||
-rw-r--r-- | dsa/FireBase/Offline/OfflineDatabase.cs | 51 | ||||
-rw-r--r-- | dsa/FireBase/Offline/OfflineEntry.cs | 18 | ||||
-rw-r--r-- | dsa/FireBase/Offline/RealtimeDatabase.cs | 129 | ||||
-rw-r--r-- | dsa/FireBase/Offline/SetHandler.cs | 12 | ||||
-rw-r--r-- | dsa/FireBase/Offline/StreamingOptions.cs | 6 | ||||
-rw-r--r-- | dsa/FireBase/Offline/SyncOptions.cs | 6 |
12 files changed, 140 insertions, 280 deletions
diff --git a/dsa/FireBase/Offline/ConcurrentOfflineDatabase.cs b/dsa/FireBase/Offline/ConcurrentOfflineDatabase.cs index 1a9e607..724115f 100644 --- a/dsa/FireBase/Offline/ConcurrentOfflineDatabase.cs +++ b/dsa/FireBase/Offline/ConcurrentOfflineDatabase.cs @@ -6,13 +6,11 @@ using System.IO; using System.Linq; using LiteDB; -namespace Firebase.Database.Offline -{ +namespace Firebase.Database.Offline { /// <summary> /// The offline database. /// </summary> - public class ConcurrentOfflineDatabase : IDictionary<string, OfflineEntry> - { + public class ConcurrentOfflineDatabase : IDictionary<string, OfflineEntry> { private readonly ConcurrentDictionary<string, OfflineEntry> ccache; private readonly LiteRepository db; @@ -21,8 +19,7 @@ namespace Firebase.Database.Offline /// </summary> /// <param name="itemType"> The item type which is used to determine the database file name. </param> /// <param name="filenameModifier"> Custom string which will get appended to the file name. </param> - public ConcurrentOfflineDatabase(Type itemType, string filenameModifier) - { + public ConcurrentOfflineDatabase(Type itemType, string filenameModifier) { var fullName = GetFileName(itemType.ToString()); if (fullName.Length > 100) fullName = fullName.Substring(0, 100); @@ -78,12 +75,10 @@ namespace Firebase.Database.Offline /// </summary> /// <param name="key">The key of the element to get or set.</param> /// <returns> The element with the specified key. </returns> - public OfflineEntry this[string key] - { + public OfflineEntry this[string key] { get => ccache[key]; - set - { + set { ccache.AddOrUpdate(key, value, (k, existing) => value); db.Upsert(value); } @@ -93,13 +88,11 @@ namespace Firebase.Database.Offline /// Returns an enumerator that iterates through the collection. /// </summary> /// <returns> An enumerator that can be used to iterate through the collection. </returns> - public IEnumerator<KeyValuePair<string, OfflineEntry>> GetEnumerator() - { + public IEnumerator<KeyValuePair<string, OfflineEntry>> GetEnumerator() { return ccache.GetEnumerator(); } - IEnumerator IEnumerable.GetEnumerator() - { + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } @@ -107,16 +100,14 @@ namespace Firebase.Database.Offline /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />. /// </summary> /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param> - public void Add(KeyValuePair<string, OfflineEntry> item) - { + public void Add(KeyValuePair<string, OfflineEntry> item) { Add(item.Key, item.Value); } /// <summary> /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1" />. /// </summary> - public void Clear() - { + public void Clear() { ccache.Clear(); db.Delete<OfflineEntry>(LiteDB.Query.All()); } @@ -129,8 +120,7 @@ namespace Firebase.Database.Offline /// True if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; /// otherwise, false. /// </returns> - public bool Contains(KeyValuePair<string, OfflineEntry> item) - { + public bool Contains(KeyValuePair<string, OfflineEntry> item) { return ContainsKey(item.Key); } @@ -144,8 +134,7 @@ namespace Firebase.Database.Offline /// zero-based indexing. /// </param> /// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param> - public void CopyTo(KeyValuePair<string, OfflineEntry>[] array, int arrayIndex) - { + public void CopyTo(KeyValuePair<string, OfflineEntry>[] array, int arrayIndex) { ccache.ToList().CopyTo(array, arrayIndex); } @@ -159,8 +148,7 @@ namespace Firebase.Database.Offline /// <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if /// <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />. /// </returns> - public bool Remove(KeyValuePair<string, OfflineEntry> item) - { + public bool Remove(KeyValuePair<string, OfflineEntry> item) { return Remove(item.Key); } @@ -173,8 +161,7 @@ namespace Firebase.Database.Offline /// True if the <see cref="T:System.Collections.Generic.IDictionary`2" /> contains an element with the key; /// otherwise, false. /// </returns> - public bool ContainsKey(string key) - { + public bool ContainsKey(string key) { return ccache.ContainsKey(key); } @@ -183,8 +170,7 @@ namespace Firebase.Database.Offline /// </summary> /// <param name="key">The object to use as the key of the element to add.</param> /// <param name="value">The object to use as the value of the element to add.</param> - public void Add(string key, OfflineEntry value) - { + public void Add(string key, OfflineEntry value) { ccache.AddOrUpdate(key, value, (k, existing) => value); db.Upsert(value); } @@ -197,8 +183,7 @@ namespace Firebase.Database.Offline /// True if the element is successfully removed; otherwise, false. This method also returns false if /// <paramref name="key" /> was not found in the original <see cref="T:System.Collections.Generic.IDictionary`2" />. /// </returns> - public bool Remove(string key) - { + public bool Remove(string key) { ccache.TryRemove(key, out _); return db.Delete<OfflineEntry>(key); } @@ -216,13 +201,11 @@ namespace Firebase.Database.Offline /// True if the object that implements <see cref="T:System.Collections.Generic.IDictionary`2" /> contains an /// element with the specified key; otherwise, false. /// </returns> - public bool TryGetValue(string key, out OfflineEntry value) - { + public bool TryGetValue(string key, out OfflineEntry value) { return ccache.TryGetValue(key, out value); } - private string GetFileName(string fileName) - { + private string GetFileName(string fileName) { var invalidChars = new[] {'`', '[', ',', '='}; foreach (var c in invalidChars.Concat(Path.GetInvalidFileNameChars()).Distinct()) fileName = fileName.Replace(c, '_'); diff --git a/dsa/FireBase/Offline/DatabaseExtensions.cs b/dsa/FireBase/Offline/DatabaseExtensions.cs index e7c4074..75624f1 100644 --- a/dsa/FireBase/Offline/DatabaseExtensions.cs +++ b/dsa/FireBase/Offline/DatabaseExtensions.cs @@ -4,10 +4,8 @@ using System.Linq.Expressions; using System.Reflection; using Firebase.Database.Query; -namespace Firebase.Database.Offline -{ - public static class DatabaseExtensions - { +namespace Firebase.Database.Offline { + public static class DatabaseExtensions { /// <summary> /// Create new instances of the <see cref="RealtimeDatabase{T}" />. /// </summary> @@ -24,8 +22,7 @@ namespace Firebase.Database.Offline public static RealtimeDatabase<T> AsRealtimeDatabase<T>(this ChildQuery query, string filenameModifier = "", string elementRoot = "", StreamingOptions streamingOptions = StreamingOptions.LatestOnly, InitialPullStrategy initialPullStrategy = InitialPullStrategy.MissingOnly, bool pushChanges = true) - where T : class - { + where T : class { return new RealtimeDatabase<T>(query, elementRoot, query.Client.Options.OfflineDatabaseFactory, filenameModifier, streamingOptions, initialPullStrategy, pushChanges); } @@ -49,8 +46,7 @@ namespace Firebase.Database.Offline StreamingOptions streamingOptions = StreamingOptions.LatestOnly, InitialPullStrategy initialPullStrategy = InitialPullStrategy.MissingOnly, bool pushChanges = true) where T : class - where TSetHandler : ISetHandler<T>, new() - { + where TSetHandler : ISetHandler<T>, new() { return new RealtimeDatabase<T>(query, elementRoot, query.Client.Options.OfflineDatabaseFactory, filenameModifier, streamingOptions, initialPullStrategy, pushChanges, Activator.CreateInstance<TSetHandler>()); @@ -68,8 +64,7 @@ namespace Firebase.Database.Offline /// </param> public static void Patch<T>(this RealtimeDatabase<T> db, string key, T obj, bool syncOnline = true, int priority = 1) - where T : class - { + where T : class { db.Set(key, obj, syncOnline ? SyncOptions.Patch : SyncOptions.None, priority); } @@ -85,8 +80,7 @@ namespace Firebase.Database.Offline /// </param> public static void Put<T>(this RealtimeDatabase<T> db, string key, T obj, bool syncOnline = true, int priority = 1) - where T : class - { + where T : class { db.Set(key, obj, syncOnline ? SyncOptions.Put : SyncOptions.None, priority); } @@ -101,8 +95,7 @@ namespace Firebase.Database.Offline /// </param> /// <returns> The generated key for this object. </returns> public static string Post<T>(this RealtimeDatabase<T> db, T obj, bool syncOnline = true, int priority = 1) - where T : class - { + where T : class { var key = FirebaseKeyGenerator.Next(); db.Set(key, obj, syncOnline ? SyncOptions.Put : SyncOptions.None, priority); @@ -120,8 +113,7 @@ namespace Firebase.Database.Offline /// priority. /// </param> public static void Delete<T>(this RealtimeDatabase<T> db, string key, bool syncOnline = true, int priority = 1) - where T : class - { + where T : class { db.Set(key, null, syncOnline ? SyncOptions.Put : SyncOptions.None, priority); } @@ -143,8 +135,7 @@ namespace Firebase.Database.Offline public static void Put<T, TProperty>(this RealtimeDatabase<T> db, string key, Expression<Func<T, TProperty>> propertyExpression, TProperty value, bool syncOnline = true, int priority = 1) - where T : class - { + where T : class { db.Set(key, propertyExpression, value, syncOnline ? SyncOptions.Put : SyncOptions.None, priority); } @@ -166,8 +157,7 @@ namespace Firebase.Database.Offline public static void Patch<T, TProperty>(this RealtimeDatabase<T> db, string key, Expression<Func<T, TProperty>> propertyExpression, TProperty value, bool syncOnline = true, int priority = 1) - where T : class - { + where T : class { db.Set(key, propertyExpression, value, syncOnline ? SyncOptions.Patch : SyncOptions.None, priority); } @@ -189,8 +179,7 @@ namespace Firebase.Database.Offline public static void Delete<T, TProperty>(this RealtimeDatabase<T> db, string key, Expression<Func<T, TProperty>> propertyExpression, bool syncOnline = true, int priority = 1) where T : class - where TProperty : class - { + where TProperty : class { db.Set(key, propertyExpression, null, syncOnline ? SyncOptions.Put : SyncOptions.None, priority); } @@ -215,8 +204,7 @@ namespace Firebase.Database.Offline Expression<Func<T, TSelector>> propertyExpression, TProperty value, bool syncOnline = true, int priority = 1) where T : class - where TSelector : IDictionary<string, TProperty> - { + where TSelector : IDictionary<string, TProperty> { var nextKey = FirebaseKeyGenerator.Next(); var expression = Expression.Lambda<Func<T, TProperty>>( Expression.Call(propertyExpression.Body, @@ -245,8 +233,7 @@ namespace Firebase.Database.Offline public static void Delete<T, TProperty>(this RealtimeDatabase<T> db, string key, Expression<Func<T, IDictionary<string, TProperty>>> propertyExpression, string dictionaryKey, bool syncOnline = true, int priority = 1) - where T : class - { + where T : class { var expression = Expression.Lambda<Func<T, TProperty>>( Expression.Call(propertyExpression.Body, typeof(IDictionary<string, TProperty>).GetRuntimeMethod("get_Item", new[] {typeof(string)}), diff --git a/dsa/FireBase/Offline/ISetHandler.cs b/dsa/FireBase/Offline/ISetHandler.cs index c04bd41..699d33a 100644 --- a/dsa/FireBase/Offline/ISetHandler.cs +++ b/dsa/FireBase/Offline/ISetHandler.cs @@ -1,10 +1,8 @@ using System.Threading.Tasks; using Firebase.Database.Query; -namespace Firebase.Database.Offline -{ - public interface ISetHandler<in T> - { +namespace Firebase.Database.Offline { + public interface ISetHandler<in T> { Task SetAsync(ChildQuery query, string key, OfflineEntry entry); } }
\ No newline at end of file diff --git a/dsa/FireBase/Offline/InitialPullStrategy.cs b/dsa/FireBase/Offline/InitialPullStrategy.cs index ca2bebf..292c716 100644 --- a/dsa/FireBase/Offline/InitialPullStrategy.cs +++ b/dsa/FireBase/Offline/InitialPullStrategy.cs @@ -1,10 +1,8 @@ -namespace Firebase.Database.Offline -{ +namespace Firebase.Database.Offline { /// <summary> /// Specifies the strategy for initial pull of server data. /// </summary> - public enum InitialPullStrategy - { + public enum InitialPullStrategy { /// <summary> /// Don't pull anything. /// </summary> diff --git a/dsa/FireBase/Offline/Internals/MemberAccessVisitor.cs b/dsa/FireBase/Offline/Internals/MemberAccessVisitor.cs index 89a77da..fe888ac 100644 --- a/dsa/FireBase/Offline/Internals/MemberAccessVisitor.cs +++ b/dsa/FireBase/Offline/Internals/MemberAccessVisitor.cs @@ -3,37 +3,29 @@ using System.Linq.Expressions; using System.Reflection; using Newtonsoft.Json; -namespace Firebase.Database.Offline.Internals -{ - public class MemberAccessVisitor : ExpressionVisitor - { +namespace Firebase.Database.Offline.Internals { + public class MemberAccessVisitor : ExpressionVisitor { private readonly IList<string> propertyNames = new List<string>(); private bool wasDictionaryAccess; public IEnumerable<string> PropertyNames => propertyNames; - public override Expression Visit(Expression expr) - { - if (expr?.NodeType == ExpressionType.MemberAccess) - { - if (wasDictionaryAccess) - { + public override Expression Visit(Expression expr) { + if (expr?.NodeType == ExpressionType.MemberAccess) { + if (wasDictionaryAccess) { wasDictionaryAccess = false; } - else - { + else { var memberExpr = (MemberExpression) expr; var jsonAttr = memberExpr.Member.GetCustomAttribute<JsonPropertyAttribute>(); propertyNames.Add(jsonAttr?.PropertyName ?? memberExpr.Member.Name); } } - else if (expr?.NodeType == ExpressionType.Call) - { + else if (expr?.NodeType == ExpressionType.Call) { var callExpr = (MethodCallExpression) expr; - if (callExpr.Method.Name == "get_Item" && callExpr.Arguments.Count == 1) - { + if (callExpr.Method.Name == "get_Item" && callExpr.Arguments.Count == 1) { var e = Expression.Lambda(callExpr.Arguments[0]).Compile(); propertyNames.Add(e.DynamicInvoke().ToString()); wasDictionaryAccess = callExpr.Arguments[0].NodeType == ExpressionType.MemberAccess; diff --git a/dsa/FireBase/Offline/OfflineCacheAdapter.cs b/dsa/FireBase/Offline/OfflineCacheAdapter.cs index 3153d1b..9881c78 100644 --- a/dsa/FireBase/Offline/OfflineCacheAdapter.cs +++ b/dsa/FireBase/Offline/OfflineCacheAdapter.cs @@ -3,19 +3,15 @@ using System.Collections; using System.Collections.Generic; using System.Linq; -namespace Firebase.Database.Offline -{ - internal class OfflineCacheAdapter<TKey, T> : IDictionary<string, T>, IDictionary - { +namespace Firebase.Database.Offline { + internal class OfflineCacheAdapter<TKey, T> : IDictionary<string, T>, IDictionary { private readonly IDictionary<string, OfflineEntry> database; - public OfflineCacheAdapter(IDictionary<string, OfflineEntry> database) - { + public OfflineCacheAdapter(IDictionary<string, OfflineEntry> database) { this.database = database; } - public void CopyTo(Array array, int index) - { + public void CopyTo(Array array, int index) { throw new NotImplementedException(); } @@ -23,12 +19,10 @@ namespace Firebase.Database.Offline public object SyncRoot { get; } - object IDictionary.this[object key] - { + object IDictionary.this[object key] { get => database[key.ToString()].Deserialize<T>(); - set - { + set { var keyString = key.ToString(); if (database.ContainsKey(keyString)) database[keyString] = new OfflineEntry(keyString, value, database[keyString].Priority, @@ -42,25 +36,21 @@ namespace Firebase.Database.Offline ICollection IDictionary.Keys { get; } - public bool Contains(object key) - { + public bool Contains(object key) { return ContainsKey(key.ToString()); } - IDictionaryEnumerator IDictionary.GetEnumerator() - { + IDictionaryEnumerator IDictionary.GetEnumerator() { throw new NotImplementedException(); } - public void Remove(object key) - { + public void Remove(object key) { Remove(key.ToString()); } public bool IsFixedSize => false; - public void Add(object key, object value) - { + public void Add(object key, object value) { Add(key.ToString(), (T) value); } @@ -72,12 +62,10 @@ namespace Firebase.Database.Offline public ICollection<T> Values => database.Values.Select(o => o.Deserialize<T>()).ToList(); - public T this[string key] - { + public T this[string key] { get => database[key].Deserialize<T>(); - set - { + set { if (database.ContainsKey(key)) database[key] = new OfflineEntry(key, value, database[key].Priority, database[key].SyncOptions); else @@ -85,62 +73,50 @@ namespace Firebase.Database.Offline } } - public IEnumerator<KeyValuePair<string, T>> GetEnumerator() - { + public IEnumerator<KeyValuePair<string, T>> GetEnumerator() { return database.Select(d => new KeyValuePair<string, T>(d.Key, d.Value.Deserialize<T>())).GetEnumerator(); } - IEnumerator IEnumerable.GetEnumerator() - { + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } - public void Add(KeyValuePair<string, T> item) - { + public void Add(KeyValuePair<string, T> item) { Add(item.Key, item.Value); } - public void Clear() - { + public void Clear() { database.Clear(); } - public bool Contains(KeyValuePair<string, T> item) - { + public bool Contains(KeyValuePair<string, T> item) { return ContainsKey(item.Key); } - public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex) - { + public void CopyTo(KeyValuePair<string, T>[] array, int arrayIndex) { throw new NotImplementedException(); } - public bool Remove(KeyValuePair<string, T> item) - { + public bool Remove(KeyValuePair<string, T> item) { return database.Remove(item.Key); } - public void Add(string key, T value) - { + public void Add(string key, T value) { database.Add(key, new OfflineEntry(key, value, 1, SyncOptions.None)); } - public bool ContainsKey(string key) - { + public bool ContainsKey(string key) { return database.ContainsKey(key); } - public bool Remove(string key) - { + public bool Remove(string key) { return database.Remove(key); } - public bool TryGetValue(string key, out T value) - { + public bool TryGetValue(string key, out T value) { OfflineEntry val; - if (database.TryGetValue(key, out val)) - { + if (database.TryGetValue(key, out val)) { value = val.Deserialize<T>(); return true; } diff --git a/dsa/FireBase/Offline/OfflineDatabase.cs b/dsa/FireBase/Offline/OfflineDatabase.cs index be0380b..5820dc6 100644 --- a/dsa/FireBase/Offline/OfflineDatabase.cs +++ b/dsa/FireBase/Offline/OfflineDatabase.cs @@ -5,13 +5,11 @@ using System.IO; using System.Linq; using LiteDB; -namespace Firebase.Database.Offline -{ +namespace Firebase.Database.Offline { /// <summary> /// The offline database. /// </summary> - public class OfflineDatabase : IDictionary<string, OfflineEntry> - { + public class OfflineDatabase : IDictionary<string, OfflineEntry> { private readonly IDictionary<string, OfflineEntry> cache; private readonly LiteRepository db; @@ -20,8 +18,7 @@ namespace Firebase.Database.Offline /// </summary> /// <param name="itemType"> The item type which is used to determine the database file name. </param> /// <param name="filenameModifier"> Custom string which will get appended to the file name. </param> - public OfflineDatabase(Type itemType, string filenameModifier) - { + public OfflineDatabase(Type itemType, string filenameModifier) { var fullName = GetFileName(itemType.ToString()); if (fullName.Length > 100) fullName = fullName.Substring(0, 100); @@ -73,12 +70,10 @@ namespace Firebase.Database.Offline /// </summary> /// <param name="key">The key of the element to get or set.</param> /// <returns> The element with the specified key. </returns> - public OfflineEntry this[string key] - { + public OfflineEntry this[string key] { get => cache[key]; - set - { + set { cache[key] = value; db.Upsert(value); } @@ -88,13 +83,11 @@ namespace Firebase.Database.Offline /// Returns an enumerator that iterates through the collection. /// </summary> /// <returns> An enumerator that can be used to iterate through the collection. </returns> - public IEnumerator<KeyValuePair<string, OfflineEntry>> GetEnumerator() - { + public IEnumerator<KeyValuePair<string, OfflineEntry>> GetEnumerator() { return cache.GetEnumerator(); } - IEnumerator IEnumerable.GetEnumerator() - { + IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } @@ -102,16 +95,14 @@ namespace Firebase.Database.Offline /// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />. /// </summary> /// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param> - public void Add(KeyValuePair<string, OfflineEntry> item) - { + public void Add(KeyValuePair<string, OfflineEntry> item) { Add(item.Key, item.Value); } /// <summary> /// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1" />. /// </summary> - public void Clear() - { + public void Clear() { cache.Clear(); db.Delete<OfflineEntry>(LiteDB.Query.All()); } @@ -124,8 +115,7 @@ namespace Firebase.Database.Offline /// True if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; /// otherwise, false. /// </returns> - public bool Contains(KeyValuePair<string, OfflineEntry> item) - { + public bool Contains(KeyValuePair<string, OfflineEntry> item) { return ContainsKey(item.Key); } @@ -139,8 +129,7 @@ namespace Firebase.Database.Offline /// zero-based indexing. /// </param> /// <param name="arrayIndex">The zero-based index in <paramref name="array" /> at which copying begins.</param> - public void CopyTo(KeyValuePair<string, OfflineEntry>[] array, int arrayIndex) - { + public void CopyTo(KeyValuePair<string, OfflineEntry>[] array, int arrayIndex) { cache.CopyTo(array, arrayIndex); } @@ -154,8 +143,7 @@ namespace Firebase.Database.Offline /// <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if /// <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />. /// </returns> - public bool Remove(KeyValuePair<string, OfflineEntry> item) - { + public bool Remove(KeyValuePair<string, OfflineEntry> item) { return Remove(item.Key); } @@ -168,8 +156,7 @@ namespace Firebase.Database.Offline /// True if the <see cref="T:System.Collections.Generic.IDictionary`2" /> contains an element with the key; /// otherwise, false. /// </returns> - public bool ContainsKey(string key) - { + public bool ContainsKey(string key) { return cache.ContainsKey(key); } @@ -178,8 +165,7 @@ namespace Firebase.Database.Offline /// </summary> /// <param name="key">The object to use as the key of the element to add.</param> /// <param name="value">The object to use as the value of the element to add.</param> - public void Add(string key, OfflineEntry value) - { + public void Add(string key, OfflineEntry value) { cache.Add(key, value); db.Insert(value); } @@ -192,8 +178,7 @@ namespace Firebase.Database.Offline /// True if the element is successfully removed; otherwise, false. This method also returns false if /// <paramref name="key" /> was not found in the original <see cref="T:System.Collections.Generic.IDictionary`2" />. /// </returns> - public bool Remove(string key) - { + public bool Remove(string key) { cache.Remove(key); return db.Delete<OfflineEntry>(key); } @@ -211,13 +196,11 @@ namespace Firebase.Database.Offline /// True if the object that implements <see cref="T:System.Collections.Generic.IDictionary`2" /> contains an /// element with the specified key; otherwise, false. /// </returns> - public bool TryGetValue(string key, out OfflineEntry value) - { + public bool TryGetValue(string key, out OfflineEntry value) { return cache.TryGetValue(key, out value); } - private string GetFileName(string fileName) - { + private string GetFileName(string fileName) { var invalidChars = new[] {'`', '[', ',', '='}; foreach (var c in invalidChars.Concat(Path.GetInvalidFileNameChars()).Distinct()) fileName = fileName.Replace(c, '_'); diff --git a/dsa/FireBase/Offline/OfflineEntry.cs b/dsa/FireBase/Offline/OfflineEntry.cs index 9feffa3..c959510 100644 --- a/dsa/FireBase/Offline/OfflineEntry.cs +++ b/dsa/FireBase/Offline/OfflineEntry.cs @@ -1,13 +1,11 @@ using System; using Newtonsoft.Json; -namespace Firebase.Database.Offline -{ +namespace Firebase.Database.Offline { /// <summary> /// Represents an object stored in offline storage. /// </summary> - public class OfflineEntry - { + public class OfflineEntry { private object dataInstance; /// <summary> @@ -21,8 +19,7 @@ namespace Firebase.Database.Offline /// </param> /// <param name="syncOptions"> The sync options. </param> public OfflineEntry(string key, object obj, string data, int priority, SyncOptions syncOptions, - bool isPartial = false) - { + bool isPartial = false) { Key = key; Priority = priority; Data = data; @@ -44,15 +41,13 @@ namespace Firebase.Database.Offline /// </param> /// <param name="syncOptions"> The sync options. </param> public OfflineEntry(string key, object obj, int priority, SyncOptions syncOptions, bool isPartial = false) - : this(key, obj, JsonConvert.SerializeObject(obj), priority, syncOptions, isPartial) - { + : this(key, obj, JsonConvert.SerializeObject(obj), priority, syncOptions, isPartial) { } /// <summary> /// Initializes a new instance of the <see cref="OfflineEntry" /> class. /// </summary> - public OfflineEntry() - { + public OfflineEntry() { } /// <summary> @@ -91,8 +86,7 @@ namespace Firebase.Database.Offline /// </summary> /// <typeparam name="T"> Type of object to deserialize into. </typeparam> /// <returns> Instance of <typeparamref name="T" />. </returns> - public T Deserialize<T>() - { + public T Deserialize<T>() { return (T) (dataInstance ?? (dataInstance = JsonConvert.DeserializeObject<T>(Data))); } } diff --git a/dsa/FireBase/Offline/RealtimeDatabase.cs b/dsa/FireBase/Offline/RealtimeDatabase.cs index 973db46..e66a1f1 100644 --- a/dsa/FireBase/Offline/RealtimeDatabase.cs +++ b/dsa/FireBase/Offline/RealtimeDatabase.cs @@ -16,14 +16,12 @@ using Firebase.Database.Query; using Firebase.Database.Streaming; using Newtonsoft.Json; -namespace Firebase.Database.Offline -{ +namespace Firebase.Database.Offline { /// <summary> /// The real-time Database which synchronizes online and offline data. /// </summary> /// <typeparam name="T"> Type of entities. </typeparam> - public class RealtimeDatabase<T> : IDisposable where T : class - { + public class RealtimeDatabase<T> : IDisposable where T : class { private readonly ChildQuery childQuery; private readonly string elementRoot; private readonly FirebaseCache<T> firebaseCache; @@ -55,8 +53,7 @@ namespace Firebase.Database.Offline public RealtimeDatabase(ChildQuery childQuery, string elementRoot, Func<Type, string, IDictionary<string, OfflineEntry>> offlineDatabaseFactory, string filenameModifier, StreamingOptions streamingOptions, InitialPullStrategy initialPullStrategy, bool pushChanges, - ISetHandler<T> setHandler = null) - { + ISetHandler<T> setHandler = null) { this.childQuery = childQuery; this.elementRoot = elementRoot; this.streamingOptions = streamingOptions; @@ -80,8 +77,7 @@ namespace Firebase.Database.Offline public ISetHandler<T> PutHandler { private get; set; } - public void Dispose() - { + public void Dispose() { subject.OnCompleted(); firebaseSubscription?.Dispose(); } @@ -102,19 +98,16 @@ namespace Firebase.Database.Offline /// The priority. Objects with higher priority will be synced first. Higher number indicates higher /// priority. /// </param> - public void Set(string key, T obj, SyncOptions syncOptions, int priority = 1) - { + public void Set(string key, T obj, SyncOptions syncOptions, int priority = 1) { SetAndRaise(key, new OfflineEntry(key, obj, priority, syncOptions)); } public void Set<TProperty>(string key, Expression<Func<T, TProperty>> propertyExpression, object value, - SyncOptions syncOptions, int priority = 1) - { + SyncOptions syncOptions, int priority = 1) { var fullKey = GenerateFullKey(key, propertyExpression, syncOptions); var serializedObject = JsonConvert.SerializeObject(value).Trim('"', '\\'); - if (fullKey.Item3) - { + if (fullKey.Item3) { if (typeof(TProperty) != typeof(string) || value == null) // don't escape non-string primitives and null; serializedObject = $"{{ \"{fullKey.Item2}\" : {serializedObject} }}"; @@ -142,8 +135,7 @@ namespace Firebase.Database.Offline /// The priority. Objects with higher priority will be synced first. Higher number indicates higher /// priority. /// </param> - public void Pull(string key, int priority = 1) - { + public void Pull(string key, int priority = 1) { if (!Database.ContainsKey(key)) Database[key] = new OfflineEntry(key, null, priority, SyncOptions.Pull); else if (Database[key].SyncOptions == SyncOptions.None) @@ -154,8 +146,7 @@ namespace Firebase.Database.Offline /// <summary> /// Fetches everything from the remote database. /// </summary> - public async Task PullAsync() - { + public async Task PullAsync() { var existingEntries = await childQuery .OnceAsync<T>() .ToObservable() @@ -166,8 +157,7 @@ namespace Firebase.Database.Offline .OK) // OK implies the request couldn't complete due to network error. .Select(e => ResetDatabaseFromInitial(e, false)) .SelectMany(e => e) - .Do(e => - { + .Do(e => { Database[e.Key] = new OfflineEntry(e.Key, e.Object, 1, SyncOptions.None); subject.OnNext(new FirebaseEvent<T>(e.Key, e.Object, FirebaseEventType.InsertOrUpdate, FirebaseEventSource.OnlinePull)); @@ -175,8 +165,7 @@ namespace Firebase.Database.Offline .ToList(); // Remove items not stored online - foreach (var item in Database.Keys.Except(existingEntries.Select(f => f.Key)).ToList()) - { + foreach (var item in Database.Keys.Except(existingEntries.Select(f => f.Key)).ToList()) { Database.Remove(item); subject.OnNext(new FirebaseEvent<T>(item, null, FirebaseEventType.Delete, FirebaseEventSource.OnlinePull)); @@ -186,8 +175,7 @@ namespace Firebase.Database.Offline /// <summary> /// Retrieves all offline items currently stored in local database. /// </summary> - public IEnumerable<FirebaseObject<T>> Once() - { + public IEnumerable<FirebaseObject<T>> Once() { return Database .Where(kvp => !string.IsNullOrEmpty(kvp.Value.Data) && kvp.Value.Data != "null" && !kvp.Value.IsPartial) .Select(kvp => new FirebaseObject<T>(kvp.Key, kvp.Value.Deserialize<T>())) @@ -198,17 +186,14 @@ namespace Firebase.Database.Offline /// Starts observing the real-time Database. Events will be fired both when change is done locally and remotely. /// </summary> /// <returns> Stream of <see cref="FirebaseEvent{T}" />. </returns> - public IObservable<FirebaseEvent<T>> AsObservable() - { - if (!isSyncRunning) - { + public IObservable<FirebaseEvent<T>> AsObservable() { + if (!isSyncRunning) { isSyncRunning = true; Task.Factory.StartNew(SynchronizeThread, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default); } - if (observable == null) - { + if (observable == null) { var initialData = Observable.Return(FirebaseEvent<T>.Empty(FirebaseEventSource.Offline)); if (Database.TryGetValue(elementRoot, out var oe)) initialData = Observable.Return(oe) @@ -251,8 +236,7 @@ namespace Firebase.Database.Offline } private IReadOnlyCollection<FirebaseObject<T>> ResetDatabaseFromInitial( - IReadOnlyCollection<FirebaseObject<T>> collection, bool onlyWhenInitialEverything = true) - { + IReadOnlyCollection<FirebaseObject<T>> collection, bool onlyWhenInitialEverything = true) { if (onlyWhenInitialEverything && initialPullStrategy != InitialPullStrategy.Everything) return collection; // items which are in local db, but not in the online collection @@ -264,8 +248,7 @@ namespace Firebase.Database.Offline return collection.Concat(extra).ToList(); } - private void SetObjectFromInitialPull(FirebaseObject<T> e) - { + private void SetObjectFromInitialPull(FirebaseObject<T> e) { // set object with no sync only if it doesn't exist yet // and the InitialPullStrategy != Everything // this attempts to deal with scenario when you are offline, have local changes and go online @@ -276,11 +259,9 @@ namespace Firebase.Database.Offline Database[e.Key] = new OfflineEntry(e.Key, e.Object, 1, SyncOptions.None); } - private IObservable<IReadOnlyCollection<FirebaseObject<T>>> GetInitialPullObservable() - { + private IObservable<IReadOnlyCollection<FirebaseObject<T>>> GetInitialPullObservable() { FirebaseQuery query; - switch (initialPullStrategy) - { + switch (initialPullStrategy) { case InitialPullStrategy.MissingOnly: query = childQuery.OrderByKey().StartAt(() => GetLatestKey()); break; @@ -301,12 +282,10 @@ namespace Firebase.Database.Offline .Select(e => new[] {new FirebaseObject<T>(elementRoot, e)})); } - private IDisposable InitializeStreamingSubscription(IObserver<FirebaseEvent<T>> observer) - { + private IDisposable InitializeStreamingSubscription(IObserver<FirebaseEvent<T>> observer) { var completeDisposable = Disposable.Create(() => isSyncRunning = false); - switch (streamingOptions) - { + switch (streamingOptions) { case StreamingOptions.LatestOnly: // stream since the latest key var queryLatest = childQuery.OrderByKey().StartAt(() => GetLatestKey()); @@ -328,8 +307,7 @@ namespace Firebase.Database.Offline } private void SetAndRaise(string key, OfflineEntry obj, - FirebaseEventSource eventSource = FirebaseEventSource.Offline) - { + FirebaseEventSource eventSource = FirebaseEventSource.Offline) { Database[key] = obj; subject.OnNext(new FirebaseEvent<T>(key, obj?.Deserialize<T>(), string.IsNullOrEmpty(obj?.Data) || obj?.Data == "null" @@ -337,12 +315,9 @@ namespace Firebase.Database.Offline : FirebaseEventType.InsertOrUpdate, eventSource)); } - private async void SynchronizeThread() - { - while (isSyncRunning) - { - try - { + private async void SynchronizeThread() { + while (isSyncRunning) { + try { var validEntries = Database.Where(e => e.Value != null); await PullEntriesAsync(validEntries.Where(kvp => kvp.Value.SyncOptions == SyncOptions.Pull)); @@ -350,8 +325,7 @@ namespace Firebase.Database.Offline await PushEntriesAsync(validEntries.Where(kvp => kvp.Value.SyncOptions == SyncOptions.Put || kvp.Value.SyncOptions == SyncOptions.Patch)); } - catch (Exception ex) - { + catch (Exception ex) { SyncExceptionThrown?.Invoke(this, new ExceptionEventArgs(ex)); } @@ -359,8 +333,7 @@ namespace Firebase.Database.Offline } } - private string GetLatestKey() - { + private string GetLatestKey() { var key = Database.OrderBy(o => o.Key, StringComparer.Ordinal).LastOrDefault().Key ?? string.Empty; if (!string.IsNullOrWhiteSpace(key)) @@ -369,60 +342,50 @@ namespace Firebase.Database.Offline return key; } - private async Task PushEntriesAsync(IEnumerable<KeyValuePair<string, OfflineEntry>> pushEntries) - { + private async Task PushEntriesAsync(IEnumerable<KeyValuePair<string, OfflineEntry>> pushEntries) { var groups = pushEntries.GroupBy(pair => pair.Value.Priority).OrderByDescending(kvp => kvp.Key).ToList(); - foreach (var group in groups) - { + foreach (var group in groups) { var tasks = group.OrderBy(kvp => kvp.Value.IsPartial).Select(kvp => kvp.Value.IsPartial ? ResetSyncAfterPush(PutHandler.SetAsync(childQuery, kvp.Key, kvp.Value), kvp.Key) : ResetSyncAfterPush(PutHandler.SetAsync(childQuery, kvp.Key, kvp.Value), kvp.Key, kvp.Value.Deserialize<T>())); - try - { + try { await Task.WhenAll(tasks).WithAggregateException(); } - catch (Exception ex) - { + catch (Exception ex) { SyncExceptionThrown?.Invoke(this, new ExceptionEventArgs(ex)); } } } - private async Task PullEntriesAsync(IEnumerable<KeyValuePair<string, OfflineEntry>> pullEntries) - { + private async Task PullEntriesAsync(IEnumerable<KeyValuePair<string, OfflineEntry>> pullEntries) { var taskGroups = pullEntries.GroupBy(pair => pair.Value.Priority).OrderByDescending(kvp => kvp.Key); - foreach (var group in taskGroups) - { + foreach (var group in taskGroups) { var tasks = group.Select(pair => ResetAfterPull( childQuery.Child(pair.Key == elementRoot ? string.Empty : pair.Key).OnceSingleAsync<T>(), pair.Key, pair.Value)); - try - { + try { await Task.WhenAll(tasks).WithAggregateException(); } - catch (Exception ex) - { + catch (Exception ex) { SyncExceptionThrown?.Invoke(this, new ExceptionEventArgs(ex)); } } } - private async Task ResetAfterPull(Task<T> task, string key, OfflineEntry entry) - { + private async Task ResetAfterPull(Task<T> task, string key, OfflineEntry entry) { await task; SetAndRaise(key, new OfflineEntry(key, task.Result, entry.Priority, SyncOptions.None), FirebaseEventSource.OnlinePull); } - private async Task ResetSyncAfterPush(Task task, string key, T obj) - { + private async Task ResetSyncAfterPush(Task task, string key, T obj) { await ResetSyncAfterPush(task, key); if (streamingOptions == StreamingOptions.None) @@ -431,35 +394,29 @@ namespace Firebase.Database.Offline FirebaseEventSource.OnlinePush)); } - private async Task ResetSyncAfterPush(Task task, string key) - { + private async Task ResetSyncAfterPush(Task task, string key) { await task; ResetSyncOptions(key); } - private void ResetSyncOptions(string key) - { + private void ResetSyncOptions(string key) { var item = Database[key]; - if (item.IsPartial) - { + if (item.IsPartial) { Database.Remove(key); } - else - { + else { item.SyncOptions = SyncOptions.None; Database[key] = item; } } - private void StreamingExceptionThrown(object sender, ExceptionEventArgs<FirebaseException> e) - { + private void StreamingExceptionThrown(object sender, ExceptionEventArgs<FirebaseException> e) { SyncExceptionThrown?.Invoke(this, new ExceptionEventArgs(e.Exception)); } private Tuple<string, string, bool> GenerateFullKey<TProperty>(string key, - Expression<Func<T, TProperty>> propertyGetter, SyncOptions syncOptions) - { + Expression<Func<T, TProperty>> propertyGetter, SyncOptions syncOptions) { var visitor = new MemberAccessVisitor(); visitor.Visit(propertyGetter); var propertyType = typeof(TProperty).GetTypeInfo(); diff --git a/dsa/FireBase/Offline/SetHandler.cs b/dsa/FireBase/Offline/SetHandler.cs index 6314c3c..c683fdd 100644 --- a/dsa/FireBase/Offline/SetHandler.cs +++ b/dsa/FireBase/Offline/SetHandler.cs @@ -1,14 +1,10 @@ using System.Threading.Tasks; using Firebase.Database.Query; -namespace Firebase.Database.Offline -{ - public class SetHandler<T> : ISetHandler<T> - { - public virtual async Task SetAsync(ChildQuery query, string key, OfflineEntry entry) - { - using (var child = query.Child(key)) - { +namespace Firebase.Database.Offline { + public class SetHandler<T> : ISetHandler<T> { + public virtual async Task SetAsync(ChildQuery query, string key, OfflineEntry entry) { + using (var child = query.Child(key)) { if (entry.SyncOptions == SyncOptions.Put) await child.PutAsync(entry.Data); else diff --git a/dsa/FireBase/Offline/StreamingOptions.cs b/dsa/FireBase/Offline/StreamingOptions.cs index a420cbb..205118d 100644 --- a/dsa/FireBase/Offline/StreamingOptions.cs +++ b/dsa/FireBase/Offline/StreamingOptions.cs @@ -1,7 +1,5 @@ -namespace Firebase.Database.Offline -{ - public enum StreamingOptions - { +namespace Firebase.Database.Offline { + public enum StreamingOptions { /// <summary> /// No realtime streaming. /// </summary> diff --git a/dsa/FireBase/Offline/SyncOptions.cs b/dsa/FireBase/Offline/SyncOptions.cs index ca68d0a..3b6e9c8 100644 --- a/dsa/FireBase/Offline/SyncOptions.cs +++ b/dsa/FireBase/Offline/SyncOptions.cs @@ -1,10 +1,8 @@ -namespace Firebase.Database.Offline -{ +namespace Firebase.Database.Offline { /// <summary> /// Specifies type of sync requested for given data. /// </summary> - public enum SyncOptions - { + public enum SyncOptions { /// <summary> /// No sync needed for given data. /// </summary> |