using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using Firebase.Database.Query;
namespace Firebase.Database.Offline
{
public static class DatabaseExtensions
{
///
/// Create new instances of the .
///
/// Type of elements.
/// Custom string which will get appended to the file name.
/// Optional custom root element of received json items.
/// Realtime streaming options.
/// Specifies what strategy should be used for initial pulling of server data.
///
/// Specifies whether changed items should actually be pushed to the server. It this is false,
/// then Put / Post / Delete will not affect server data.
///
/// The .
public static RealtimeDatabase AsRealtimeDatabase(this ChildQuery query, string filenameModifier = "",
string elementRoot = "", StreamingOptions streamingOptions = StreamingOptions.LatestOnly,
InitialPullStrategy initialPullStrategy = InitialPullStrategy.MissingOnly, bool pushChanges = true)
where T : class
{
return new RealtimeDatabase(query, elementRoot, query.Client.Options.OfflineDatabaseFactory,
filenameModifier, streamingOptions, initialPullStrategy, pushChanges);
}
///
/// Create new instances of the .
///
/// Type of elements.
/// Type of the custom to use.
/// Custom string which will get appended to the file name.
/// Optional custom root element of received json items.
/// Realtime streaming options.
/// Specifies what strategy should be used for initial pulling of server data.
///
/// Specifies whether changed items should actually be pushed to the server. It this is false,
/// then Put / Post / Delete will not affect server data.
///
/// The .
public static RealtimeDatabase AsRealtimeDatabase(this ChildQuery query,
string filenameModifier = "", string elementRoot = "",
StreamingOptions streamingOptions = StreamingOptions.LatestOnly,
InitialPullStrategy initialPullStrategy = InitialPullStrategy.MissingOnly, bool pushChanges = true)
where T : class
where TSetHandler : ISetHandler, new()
{
return new RealtimeDatabase(query, elementRoot, query.Client.Options.OfflineDatabaseFactory,
filenameModifier, streamingOptions, initialPullStrategy, pushChanges,
Activator.CreateInstance());
}
///
/// Overwrites existing object with given key leaving any missing properties intact in firebase.
///
/// The key.
/// The object to set.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Patch(this RealtimeDatabase db, string key, T obj, bool syncOnline = true,
int priority = 1)
where T : class
{
db.Set(key, obj, syncOnline ? SyncOptions.Patch : SyncOptions.None, priority);
}
///
/// Overwrites existing object with given key.
///
/// The key.
/// The object to set.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Put(this RealtimeDatabase db, string key, T obj, bool syncOnline = true,
int priority = 1)
where T : class
{
db.Set(key, obj, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
}
///
/// Adds a new entity to the Database.
///
/// The object to add.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
/// The generated key for this object.
public static string Post(this RealtimeDatabase db, T obj, bool syncOnline = true, int priority = 1)
where T : class
{
var key = FirebaseKeyGenerator.Next();
db.Set(key, obj, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
return key;
}
///
/// Deletes the entity with the given key.
///
/// The key.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Delete(this RealtimeDatabase db, string key, bool syncOnline = true, int priority = 1)
where T : class
{
db.Set(key, null, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
}
///
/// Do a Put for a nested property specified by of an object with key
/// .
///
/// Type of the root elements.
/// Type of the property being modified
/// Database instance.
/// Key of the root element to modify.
/// Expression on the root element leading to target value to modify.
/// Value to put.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Put(this RealtimeDatabase db, string key,
Expression> propertyExpression, TProperty value, bool syncOnline = true,
int priority = 1)
where T : class
{
db.Set(key, propertyExpression, value, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
}
///
/// Do a Patch for a nested property specified by of an object with key
/// .
///
/// Type of the root elements.
/// Type of the property being modified
/// Database instance.
/// Key of the root element to modify.
/// Expression on the root element leading to target value to modify.
/// Value to patch.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Patch(this RealtimeDatabase db, string key,
Expression> propertyExpression, TProperty value, bool syncOnline = true,
int priority = 1)
where T : class
{
db.Set(key, propertyExpression, value, syncOnline ? SyncOptions.Patch : SyncOptions.None, priority);
}
///
/// Delete a nested property specified by of an object with key
/// . This basically does a Put with null value.
///
/// Type of the root elements.
/// Type of the property being modified
/// Database instance.
/// Key of the root element to modify.
/// Expression on the root element leading to target value to modify.
/// Value to put.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Delete(this RealtimeDatabase db, string key,
Expression> propertyExpression, bool syncOnline = true, int priority = 1)
where T : class
where TProperty : class
{
db.Set(key, propertyExpression, null, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
}
///
/// Post a new entity into the nested dictionary specified by of an object with
/// key .
/// The key of the new entity is automatically generated.
///
/// Type of the root elements.
/// Type of the dictionary being modified
/// Type of the value within the dictionary being modified
/// Database instance.
/// Key of the root element to modify.
/// Expression on the root element leading to target value to modify.
/// Value to put.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Post(this RealtimeDatabase db, string key,
Expression> propertyExpression, TProperty value, bool syncOnline = true,
int priority = 1)
where T : class
where TSelector : IDictionary
{
var nextKey = FirebaseKeyGenerator.Next();
var expression = Expression.Lambda>(
Expression.Call(propertyExpression.Body,
typeof(TSelector).GetRuntimeMethod("get_Item", new[] {typeof(string)}),
Expression.Constant(nextKey)), propertyExpression.Parameters);
db.Set(key, expression, value, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
}
///
/// Delete an entity with key in the nested dictionary specified by
/// of an object with key .
/// The key of the new entity is automatically generated.
///
/// Type of the root elements.
/// Type of the dictionary being modified
/// Type of the value within the dictionary being modified
/// Database instance.
/// Key of the root element to modify.
/// Expression on the root element leading to target value to modify.
/// Key within the nested dictionary to delete.
/// Indicates whether the item should be synced online.
///
/// The priority. Objects with higher priority will be synced first. Higher number indicates higher
/// priority.
///
public static void Delete(this RealtimeDatabase db, string key,
Expression>> propertyExpression, string dictionaryKey,
bool syncOnline = true, int priority = 1)
where T : class
{
var expression = Expression.Lambda>(
Expression.Call(propertyExpression.Body,
typeof(IDictionary).GetRuntimeMethod("get_Item", new[] {typeof(string)}),
Expression.Constant(dictionaryKey)), propertyExpression.Parameters);
db.Set(key, expression, null, syncOnline ? SyncOptions.Put : SyncOptions.None, priority);
}
}
}