/* 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.Collections.Generic;
using System.Linq;
#if NET452
using System.Runtime.Serialization;
#endif
using System.Text;
using MongoDB.Driver.Core.Connections;
using MongoDB.Driver.Core.Operations;
using MongoDB.Driver.Support;
namespace MongoDB.Driver
{
///
/// Represents a bulk write exception.
///
#if NET452
[Serializable]
#endif
public abstract class MongoBulkWriteException : MongoServerException
{
// private fields
private readonly WriteConcernError _writeConcernError;
private readonly IReadOnlyList _writeErrors;
///
/// Initializes a new instance of the class.
///
/// The connection identifier.
/// The write errors.
/// The write concern error.
public MongoBulkWriteException(
ConnectionId connectionId,
IEnumerable writeErrors,
WriteConcernError writeConcernError)
: base(connectionId, message: FormatMessage(writeErrors, writeConcernError))
{
_writeErrors = writeErrors.ToList();
_writeConcernError = writeConcernError;
}
#if NET452
///
/// Initializes a new instance of the MongoQueryException class (this overload supports deserialization).
///
/// The SerializationInfo.
/// The StreamingContext.
public MongoBulkWriteException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
_writeConcernError = (WriteConcernError)info.GetValue("_writeConcernError", typeof(WriteConcernError));
_writeErrors = (IReadOnlyList)info.GetValue("_writeErrors", typeof(IReadOnlyList));
}
#endif
// properties
///
/// Gets the write concern error.
///
public WriteConcernError WriteConcernError
{
get { return _writeConcernError; }
}
///
/// Gets the write errors.
///
public IReadOnlyList WriteErrors
{
get { return _writeErrors; }
}
// methods
#if NET452
///
/// Gets the object data.
///
/// The information.
/// The context.
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("_writeConcernError", _writeConcernError);
info.AddValue("_writeErrors", _writeErrors);
}
#endif
// private static methods
private static string FormatMessage(IEnumerable writeErrors, WriteConcernError writeConcernError)
{
var sb = new StringBuilder("A bulk write operation resulted in one or more errors.");
if (writeErrors != null)
{
foreach (var writeError in writeErrors)
{
sb.AppendLine().Append(" " + writeError.Message);
}
}
if (writeConcernError != null)
{
sb.AppendLine().Append(" " + writeConcernError.Message);
}
return sb.ToString();
}
}
///
/// Represents a bulk write exception.
///
/// The type of the document.
#if NET452
[Serializable]
#endif
public sealed class MongoBulkWriteException : MongoBulkWriteException
{
// private fields
private readonly BulkWriteResult _result;
private readonly IReadOnlyList> _unprocessedRequests;
// constructors
///
/// Initializes a new instance of the class.
///
/// The connection identifier.
/// The result.
/// The write errors.
/// The write concern error.
/// The unprocessed requests.
public MongoBulkWriteException(
ConnectionId connectionId,
BulkWriteResult result,
IEnumerable writeErrors,
WriteConcernError writeConcernError,
IEnumerable> unprocessedRequests)
: base(connectionId, writeErrors, writeConcernError)
{
_result = result;
_unprocessedRequests = unprocessedRequests.ToList();
}
#if NET452
///
/// Initializes a new instance of the MongoQueryException class (this overload supports deserialization).
///
/// The SerializationInfo.
/// The StreamingContext.
public MongoBulkWriteException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
if (typeof(TDocument).IsSerializable)
{
_result = (BulkWriteResult)info.GetValue("_result", typeof(BulkWriteResult));
_unprocessedRequests = (IReadOnlyList>)info.GetValue("_unprocessedRequests", typeof(IReadOnlyList>));
}
}
#endif
// public properties
///
/// Gets the result of the bulk write operation.
///
public BulkWriteResult Result
{
get { return _result; }
}
///
/// Gets the unprocessed requests.
///
public IReadOnlyList> UnprocessedRequests
{
get { return _unprocessedRequests; }
}
// methods
#if NET452
///
/// Gets the object data.
///
/// The information.
/// The context.
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
if (typeof(TDocument).IsSerializable)
{
info.AddValue("_result", _result);
info.AddValue("_unprocessedRequests", _unprocessedRequests);
}
}
#endif
// internal static methods
internal static MongoBulkWriteException FromCore(MongoBulkWriteOperationException ex)
{
return new MongoBulkWriteException(
ex.ConnectionId,
BulkWriteResult.FromCore(ex.Result),
ex.WriteErrors.Select(e => BulkWriteError.FromCore(e)),
WriteConcernError.FromCore(ex.WriteConcernError),
ex.UnprocessedRequests.Select(r => WriteModel.FromCore(r)));
}
internal static MongoBulkWriteException FromCore(MongoBulkWriteOperationException ex, IReadOnlyList> requests)
{
var processedRequests = ex.Result.ProcessedRequests
.Select(r => new { CorrelationId = r.CorrelationId.Value, Request = requests[r.CorrelationId.Value] })
.OrderBy(x => x.CorrelationId)
.Select(x => x.Request);
var unprocessedRequests = ex.UnprocessedRequests
.Select(r => new { CorrelationId = r.CorrelationId.Value, Request = requests[r.CorrelationId.Value] })
.OrderBy(x => x.CorrelationId)
.Select(x => x.Request);
return new MongoBulkWriteException(
ex.ConnectionId,
BulkWriteResult.FromCore(ex.Result, processedRequests),
ex.WriteErrors.Select(e => BulkWriteError.FromCore(e)),
WriteConcernError.FromCore(ex.WriteConcernError),
unprocessedRequests);
}
}
}