/* Copyright 2010-present MongoDB Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Bson.Serialization;
using MongoDB.Driver.Core.Misc;
namespace MongoDB.Driver
{
///
/// Extension methods for
///
public static class IFindFluentExtensions
{
///
/// Projects the result.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The projection.
/// The fluent find interface.
public static IFindFluent Project(this IFindFluent find, ProjectionDefinition projection)
{
Ensure.IsNotNull(find, nameof(find));
Ensure.IsNotNull(projection, nameof(projection));
return find.Project(projection);
}
///
/// Projects the result.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The type of the new projection.
/// The fluent find.
/// The projection.
/// The fluent find interface.
public static IFindFluent Project(this IFindFluent find, Expression> projection)
{
Ensure.IsNotNull(find, nameof(find));
Ensure.IsNotNull(projection, nameof(projection));
return find.Project(new FindExpressionProjectionDefinition(projection));
}
///
/// Sorts the results by an ascending field.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The field.
/// The fluent find interface.
public static IOrderedFindFluent SortBy(this IFindFluent find, Expression> field)
{
Ensure.IsNotNull(find, nameof(find));
Ensure.IsNotNull(field, nameof(field));
// We require an implementation of IFindFluent
// to also implement IOrderedFindFluent
return (IOrderedFindFluent)find.Sort(
new DirectionalSortDefinition(new ExpressionFieldDefinition(field), SortDirection.Ascending));
}
///
/// Sorts the results by a descending field.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The field.
/// The fluent find interface.
public static IOrderedFindFluent SortByDescending(this IFindFluent find, Expression> field)
{
Ensure.IsNotNull(find, nameof(find));
Ensure.IsNotNull(field, nameof(field));
// We require an implementation of IFindFluent
// to also implement IOrderedFindFluent
return (IOrderedFindFluent)find.Sort(
new DirectionalSortDefinition(new ExpressionFieldDefinition(field), SortDirection.Descending));
}
///
/// Adds an ascending field to the existing sort.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The field.
/// The fluent find interface.
public static IOrderedFindFluent ThenBy(this IOrderedFindFluent find, Expression> field)
{
Ensure.IsNotNull(find, nameof(find));
Ensure.IsNotNull(field, nameof(field));
find.Options.Sort = new SortDefinitionBuilder().Combine(
find.Options.Sort,
new DirectionalSortDefinition(new ExpressionFieldDefinition(field), SortDirection.Ascending));
return find;
}
///
/// Adds a descending field to the existing sort.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The field.
/// The fluent find interface.
public static IOrderedFindFluent ThenByDescending(this IOrderedFindFluent find, Expression> field)
{
Ensure.IsNotNull(find, nameof(find));
Ensure.IsNotNull(field, nameof(field));
find.Options.Sort = new SortDefinitionBuilder().Combine(
find.Options.Sort,
new DirectionalSortDefinition(new ExpressionFieldDefinition(field), SortDirection.Descending));
return find;
}
///
/// Get the first result.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the first result.
public static TProjection First(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
return IAsyncCursorSourceExtensions.First(find.Limit(1), cancellationToken);
}
///
/// Get the first result.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the first result.
public static Task FirstAsync(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
return IAsyncCursorSourceExtensions.FirstAsync(find.Limit(1), cancellationToken);
}
///
/// Get the first result or null.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the first result or null.
public static TProjection FirstOrDefault(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
return IAsyncCursorSourceExtensions.FirstOrDefault(find.Limit(1), cancellationToken);
}
///
/// Get the first result or null.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the first result or null.
public static Task FirstOrDefaultAsync(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
return IAsyncCursorSourceExtensions.FirstOrDefaultAsync(find.Limit(1), cancellationToken);
}
///
/// Gets a single result.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the single result.
public static TProjection Single(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
if (!find.Options.Limit.HasValue || find.Options.Limit.Value > 2)
{
find = find.Limit(2);
}
return IAsyncCursorSourceExtensions.Single(find, cancellationToken);
}
///
/// Gets a single result.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the single result.
public static Task SingleAsync(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
if (!find.Options.Limit.HasValue || find.Options.Limit.Value > 2)
{
find = find.Limit(2);
}
return IAsyncCursorSourceExtensions.SingleAsync(find, cancellationToken);
}
///
/// Gets a single result or null.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the single result or null.
public static TProjection SingleOrDefault(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
if (!find.Options.Limit.HasValue || find.Options.Limit.Value > 2)
{
find = find.Limit(2);
}
return IAsyncCursorSourceExtensions.SingleOrDefault(find, cancellationToken);
}
///
/// Gets a single result or null.
///
/// The type of the document.
/// The type of the projection (same as TDocument if there is no projection).
/// The fluent find.
/// The cancellation token.
/// A Task whose result is the single result or null.
public static Task SingleOrDefaultAsync(this IFindFluent find, CancellationToken cancellationToken = default(CancellationToken))
{
Ensure.IsNotNull(find, nameof(find));
if (!find.Options.Limit.HasValue || find.Options.Limit.Value > 2)
{
find = find.Limit(2);
}
return IAsyncCursorSourceExtensions.SingleOrDefaultAsync(find, cancellationToken);
}
}
}