// Copyright Epic Games, Inc. All Rights Reserved.
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
namespace EpicGames.MongoDB
{
///
/// Extension methods for MongoDB
///
public static class MongoExtensions
{
///
/// Filters the documents returned from a search
///
/// The query to filter
/// Index of the first document to return
/// Number of documents to return
/// New query
public static IFindFluent Range(this IFindFluent query, int? index, int? count)
{
if (index != null)
{
query = query.Skip(index.Value);
}
if(count != null)
{
query = query.Limit(count.Value);
}
return query;
}
///
/// Filters the documents returned from a search
///
/// The query to filter
/// New query
public static async Task> ToListAsync(this IAsyncCursorSource query) where TDocument : TResult
{
List results = new List();
using (IAsyncCursor cursor = await query.ToCursorAsync())
{
while (await cursor.MoveNextAsync())
{
foreach (TDocument document in cursor.Current)
{
results.Add(document);
}
}
}
return results;
}
///
/// Attempts to insert a document into a collection, handling the error case that a document with the given key already exists
///
///
/// Collection to insert into
/// The document to insert
/// True if the document was inserted, false if it already exists
public static async Task InsertOneIgnoreDuplicatesAsync(this IMongoCollection collection, TDocument newDocument)
{
try
{
await collection.InsertOneAsync(newDocument);
return true;
}
catch (MongoWriteException ex)
{
if (ex.WriteError.Category == ServerErrorCategory.DuplicateKey)
{
return false;
}
else
{
throw;
}
}
}
///
/// Sets a field to a value, or unsets it if the value is null
///
/// The document type
/// Type of the field to set
/// Update builder
/// Expression for the field to set
/// New value to set
/// Update defintiion
public static UpdateDefinition SetOrUnsetNull(this UpdateDefinitionBuilder updateBuilder, Expression> field, TField? value) where TField : struct
{
if (value.HasValue)
{
return updateBuilder.Set(field, value.Value);
}
else
{
return updateBuilder.Unset(new ExpressionFieldDefinition(field));
}
}
///
/// Sets a field to a value, or unsets it if the value is null
///
/// The document type
/// Type of the field to set
/// Update builder
/// Expression for the field to set
/// New value to set
/// Update defintiion
public static UpdateDefinition SetOrUnsetNullRef(this UpdateDefinitionBuilder updateBuilder, Expression> field, TField? value) where TField : class
{
if (value != null)
{
return updateBuilder.Set(field, value);
}
else
{
return updateBuilder.Unset(new ExpressionFieldDefinition(field));
}
}
///
/// Creates a filter definition from a linq expression. This is not generally explicitly castable, so expose it as a FilterDefinitionBuilder method.
///
/// The document type
/// The filter builder
/// Expression to parse
/// New filter definition
[System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter")]
public static FilterDefinition Expr(this FilterDefinitionBuilder filter, Expression> expression)
{
return expression;
}
}
}