Removed exceptions from NzbDrone.Services.
This commit is contained in:
parent
e6712e5aa2
commit
25cc23a9c1
|
@ -1,8 +1,7 @@
|
|||
using MongoDB.Driver;
|
||||
using NzbDrone.Services.Service.Datastore;
|
||||
using Microsoft.Web.Infrastructure.DynamicModuleHelper;
|
||||
using Ninject;
|
||||
using Ninject.Web.Mvc;
|
||||
using NzbDrone.Services.Service.Datastore;
|
||||
using NzbDrone.Services.Service.Migrations;
|
||||
using Services.PetaPoco;
|
||||
|
||||
|
@ -33,8 +32,6 @@ namespace NzbDrone.Services.Service.App_Start
|
|||
var kernel = new StandardKernel();
|
||||
MigrationsHelper.Run(Connection.GetConnectionString);
|
||||
kernel.Bind<IDatabase>().ToMethod(c => Connection.GetPetaPocoDb());
|
||||
kernel.Bind<MongoDatabase>().ToConstant(Connection.GetMongoDb());
|
||||
|
||||
|
||||
return kernel;
|
||||
}
|
||||
|
|
|
@ -1,153 +1,24 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using MongoDB.Driver;
|
||||
using NLog;
|
||||
using Ninject;
|
||||
using NzbDrone.Common.Contract;
|
||||
using NzbDrone.Services.Service.Exceptions;
|
||||
using NzbDrone.Services.Service.Repository.Reporting;
|
||||
using Services.PetaPoco;
|
||||
using ExceptionInstance = NzbDrone.Services.Service.Repository.Reporting.ExceptionInstance;
|
||||
using ExceptionReport = NzbDrone.Common.Contract.ExceptionReport;
|
||||
|
||||
namespace NzbDrone.Services.Service.Controllers
|
||||
{
|
||||
public class ExceptionController : Controller
|
||||
{
|
||||
private readonly IDatabase _database;
|
||||
private readonly ExceptionRepository _exceptionRepository;
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Inject]
|
||||
public ExceptionController(IDatabase database, ExceptionRepository exceptionRepository)
|
||||
{
|
||||
_database = database;
|
||||
_exceptionRepository = exceptionRepository;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public EmptyResult ReportExisting(ExistingExceptionReport existingExceptionReport)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ExceptionHashExists(existingExceptionReport.Hash))
|
||||
{
|
||||
|
||||
var exceptionInstance = new ExceptionInstance
|
||||
{
|
||||
ExceptionHash = existingExceptionReport.Hash,
|
||||
IsProduction = existingExceptionReport.IsProduction,
|
||||
LogMessage = existingExceptionReport.LogMessage,
|
||||
UGuid = existingExceptionReport.UGuid,
|
||||
Timestamp = DateTime.Now
|
||||
};
|
||||
|
||||
_database.Insert(exceptionInstance);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn("Invalid exception hash '{0}'", existingExceptionReport.Hash);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.FatalException("Error has occurred while saving exception", e);
|
||||
throw;
|
||||
}
|
||||
|
||||
return new EmptyResult();
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public JsonResult ReportNew(ExceptionReport exceptionReport)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
var report = new Exceptions.ExceptionReport();
|
||||
report.AppVersion = exceptionReport.Version;
|
||||
report.ApplicationId = "NzbDrone";
|
||||
report.ExceptionMessage = exceptionReport.ExceptionMessage;
|
||||
report.ExceptionType = exceptionReport.Type;
|
||||
report.Location = exceptionReport.Logger;
|
||||
report.Message = exceptionReport.LogMessage;
|
||||
report.Stack = exceptionReport.Stack;
|
||||
report.Uid = exceptionReport.UGuid.ToString();
|
||||
|
||||
_exceptionRepository.Store(report);
|
||||
|
||||
var exceptionHash = GetExceptionDetailId(exceptionReport);
|
||||
|
||||
var exceptionInstance = new ExceptionInstance
|
||||
{
|
||||
ExceptionHash = exceptionHash,
|
||||
IsProduction = exceptionReport.IsProduction,
|
||||
LogMessage = exceptionReport.LogMessage,
|
||||
Timestamp = DateTime.Now,
|
||||
UGuid = exceptionReport.UGuid
|
||||
};
|
||||
|
||||
_database.Insert(exceptionInstance);
|
||||
|
||||
return new JsonResult { Data = new ExceptionReportResponse { ExceptionHash = exceptionHash } };
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.FatalException("Error has occurred while saving exception", e);
|
||||
if (!exceptionReport.IsProduction)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return new JsonResult();
|
||||
}
|
||||
|
||||
private string GetExceptionDetailId(ExceptionReport exceptionReport)
|
||||
{
|
||||
var reportHash = Hash(String.Concat(exceptionReport.Version, exceptionReport.String, exceptionReport.Logger));
|
||||
|
||||
if (!ExceptionHashExists(reportHash))
|
||||
{
|
||||
var exeptionDetail = new ExceptionDetail();
|
||||
exeptionDetail.Hash = reportHash;
|
||||
exeptionDetail.Logger = exceptionReport.Logger;
|
||||
exeptionDetail.String = exceptionReport.String;
|
||||
exeptionDetail.Type = exceptionReport.Type;
|
||||
exeptionDetail.Version = exceptionReport.Version;
|
||||
|
||||
_database.Insert(exeptionDetail);
|
||||
}
|
||||
|
||||
return reportHash;
|
||||
}
|
||||
|
||||
private bool ExceptionHashExists(string reportHash)
|
||||
{
|
||||
return _database.Exists<ExceptionDetail>(reportHash);
|
||||
}
|
||||
|
||||
private static string Hash(string input)
|
||||
{
|
||||
uint mCrc = 0xffffffff;
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input);
|
||||
foreach (byte myByte in bytes)
|
||||
{
|
||||
mCrc ^= ((uint)(myByte) << 24);
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
if ((Convert.ToUInt32(mCrc) & 0x80000000) == 0x80000000)
|
||||
{
|
||||
mCrc = (mCrc << 1) ^ 0x04C11DB7;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCrc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return String.Format("{0:x8}", mCrc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
using System;
|
||||
using System.Configuration;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Driver;
|
||||
using NzbDrone.Services.Service.Migrations;
|
||||
using Services.PetaPoco;
|
||||
|
||||
|
||||
|
@ -28,22 +24,6 @@ namespace NzbDrone.Services.Service.Datastore
|
|||
}
|
||||
|
||||
|
||||
public static MongoDatabase GetMongoDb()
|
||||
{
|
||||
var serverSettings = new MongoServerSettings()
|
||||
{
|
||||
ConnectionMode = ConnectionMode.Direct,
|
||||
ConnectTimeout = TimeSpan.FromSeconds(10),
|
||||
DefaultCredentials = new MongoCredentials("nzbdrone", "nzbdronepassword"),
|
||||
GuidRepresentation = GuidRepresentation.Standard,
|
||||
Server = new MongoServerAddress("ds031747.mongolab.com", 31747),
|
||||
SafeMode = new SafeMode(true) { J = true },
|
||||
};
|
||||
|
||||
|
||||
var server = MongoServer.Create(serverSettings);
|
||||
|
||||
return server.GetDatabase("nzbdrone_ex");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace NzbDrone.Services.Service.Exceptions
|
||||
{
|
||||
public class ExceptionInfo
|
||||
{
|
||||
public ExceptionInfo()
|
||||
{
|
||||
Instances = new ExceptionInstance[0];
|
||||
}
|
||||
|
||||
[BsonId]
|
||||
public string Hash { get; set; }
|
||||
|
||||
[BsonElement("xtype")]
|
||||
public string ExceptionType { get; set; }
|
||||
|
||||
[BsonElement("stk")]
|
||||
public string Stack { get; set; }
|
||||
|
||||
[BsonElement("loc")]
|
||||
public string Location { get; set; }
|
||||
|
||||
[BsonElement("inst")]
|
||||
public IEnumerable<ExceptionInstance> Instances { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
using System.Linq;
|
||||
using System;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
namespace NzbDrone.Services.Service.Exceptions
|
||||
{
|
||||
public class ExceptionInstance
|
||||
{
|
||||
[BsonElement("ver")]
|
||||
public string AppVersion { get; set; }
|
||||
|
||||
[BsonElement("uid")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[BsonElement("xmsg")]
|
||||
public string ExceptionMessage { get; set; }
|
||||
|
||||
[BsonElement("msg")]
|
||||
public string Message { get; set; }
|
||||
|
||||
[BsonElement("time")]
|
||||
public DateTime Time { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
using System.Linq;
|
||||
|
||||
namespace NzbDrone.Services.Service.Exceptions
|
||||
{
|
||||
public class ExceptionReport
|
||||
{
|
||||
public string ApplicationId { get; set; }
|
||||
public string AppVersion { get; set; }
|
||||
public string Uid { get; set; }
|
||||
public string ExceptionType { get; set; }
|
||||
public string ExceptionMessage { get; set; }
|
||||
public string Stack { get; set; }
|
||||
public string Location { get; set; }
|
||||
public string Message { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using MongoDB.Driver;
|
||||
using MongoDB.Driver.Builders;
|
||||
|
||||
namespace NzbDrone.Services.Service.Exceptions
|
||||
{
|
||||
public class ExceptionRepository
|
||||
{
|
||||
private readonly MongoDatabase _mongoDb;
|
||||
|
||||
public ExceptionRepository(MongoDatabase mongoDb)
|
||||
{
|
||||
_mongoDb = mongoDb;
|
||||
}
|
||||
|
||||
public ExceptionRepository()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual string Store(NzbDrone.Services.Service.Exceptions.ExceptionReport exceptionReport)
|
||||
{
|
||||
var hash = GetExceptionDetailId(exceptionReport);
|
||||
|
||||
var exceptionInstance = new NzbDrone.Services.Service.Exceptions.ExceptionInstance
|
||||
{
|
||||
AppVersion = exceptionReport.AppVersion,
|
||||
ExceptionMessage = exceptionReport.ExceptionMessage,
|
||||
Message = exceptionReport.Message,
|
||||
Time = DateTime.UtcNow,
|
||||
UserId = exceptionReport.Uid
|
||||
};
|
||||
|
||||
|
||||
|
||||
var applicationExceptions = _mongoDb.GetCollection(exceptionReport.ApplicationId);
|
||||
|
||||
applicationExceptions.Update(Query.EQ("_id", hash), Update.PushWrapped("inst", exceptionInstance));
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
private string GetExceptionDetailId(NzbDrone.Services.Service.Exceptions.ExceptionReport exceptionReport)
|
||||
{
|
||||
var hash = Hash(String.Concat(exceptionReport.AppVersion, exceptionReport.Location, exceptionReport.ExceptionType, exceptionReport.Stack));
|
||||
|
||||
if (!ExceptionInfoExists(exceptionReport.ApplicationId, hash))
|
||||
{
|
||||
var exceptionInfo = new NzbDrone.Services.Service.Exceptions.ExceptionInfo
|
||||
{
|
||||
Hash = hash,
|
||||
Stack = exceptionReport.Stack,
|
||||
ExceptionType = exceptionReport.ExceptionType,
|
||||
Location = exceptionReport.Location
|
||||
};
|
||||
|
||||
_mongoDb.GetCollection(exceptionReport.ApplicationId).Insert(exceptionInfo);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
public bool ExceptionInfoExists(string applicationId, string hash)
|
||||
{
|
||||
var appCollection = _mongoDb.GetCollection(applicationId);
|
||||
return appCollection.FindAs<NzbDrone.Services.Service.Exceptions.ExceptionInfo>(Query.EQ("_id", hash)).Any();
|
||||
}
|
||||
|
||||
private static string Hash(string input)
|
||||
{
|
||||
uint mCrc = 0xffffffff;
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(input);
|
||||
foreach (byte myByte in bytes)
|
||||
{
|
||||
mCrc ^= ((uint)(myByte) << 24);
|
||||
for (var i = 0; i < 8; i++)
|
||||
{
|
||||
if ((Convert.ToUInt32(mCrc) & 0x80000000) == 0x80000000)
|
||||
{
|
||||
mCrc = (mCrc << 1) ^ 0x04C11DB7;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCrc <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return String.Format("{0:x8}", mCrc);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,9 +41,6 @@
|
|||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="AutoMapper">
|
||||
<HintPath>..\..\packages\AutoMapper.2.0.0\lib\net40-client\AutoMapper.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Elmah">
|
||||
<HintPath>..\..\packages\elmah.corelibrary.1.2.1\lib\Elmah.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -64,12 +61,6 @@
|
|||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\Libraries\Migrator.NET\Migrator.Providers.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MongoDB.Bson">
|
||||
<HintPath>..\..\packages\mongocsharpdriver.1.4\lib\net35\MongoDB.Bson.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MongoDB.Driver">
|
||||
<HintPath>..\..\packages\mongocsharpdriver.1.4\lib\net35\MongoDB.Driver.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=4.0.8.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\packages\Newtonsoft.Json.4.0.8\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
|
@ -100,8 +91,6 @@
|
|||
<Reference Include="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Configuration" />
|
||||
|
@ -222,15 +211,9 @@
|
|||
<Compile Include="App_Start\Logging.cs" />
|
||||
<Compile Include="App_Start\NinjectMVC3.cs" />
|
||||
<Compile Include="Controllers\ExceptionController.cs" />
|
||||
<Compile Include="Exceptions\ExceptionInfo.cs" />
|
||||
<Compile Include="Exceptions\ExceptionInstance.cs" />
|
||||
<Compile Include="Exceptions\ExceptionReport.cs" />
|
||||
<Compile Include="Exceptions\ExceptionRepository.cs" />
|
||||
<Compile Include="Helpers\HtmlIncludeExtentions.cs" />
|
||||
<Compile Include="Migrations\Migration20120226.cs" />
|
||||
<Compile Include="Migrations\Migration20120229.cs" />
|
||||
<Compile Include="Repository\Reporting\ExceptionDetail.cs" />
|
||||
<Compile Include="Repository\Reporting\ExceptionInstance.cs" />
|
||||
<Compile Include="Services.PetaPoco.cs" />
|
||||
<Compile Include="Datastore\Connection.cs" />
|
||||
<Compile Include="Controllers\DailySeriesController.cs" />
|
||||
|
@ -252,7 +235,6 @@
|
|||
<Compile Include="Providers\SceneMappingProvider.cs" />
|
||||
<Compile Include="Repository\DailySeries.cs" />
|
||||
<Compile Include="Repository\PendingSceneMapping.cs" />
|
||||
<Compile Include="Repository\Reporting\ExceptionRow.cs" />
|
||||
<Compile Include="Repository\Reporting\ParseErrorRow.cs" />
|
||||
<Compile Include="Repository\Reporting\ReportRowBase.cs" />
|
||||
<Compile Include="Repository\SceneMapping.cs" />
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
using System.Linq;
|
||||
using Services.PetaPoco;
|
||||
|
||||
namespace NzbDrone.Services.Service.Repository.Reporting
|
||||
{
|
||||
[TableName("Exceptions")]
|
||||
[PrimaryKey("Hash", autoIncrement = false)]
|
||||
public class ExceptionDetail
|
||||
{
|
||||
public string Hash { get; set; }
|
||||
public string Logger { get; set; }
|
||||
public string Type { get; set; }
|
||||
public string String { get; set; }
|
||||
public string Version { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using Services.PetaPoco;
|
||||
|
||||
namespace NzbDrone.Services.Service.Repository.Reporting
|
||||
{
|
||||
[TableName("ExceptionInstances")]
|
||||
public class ExceptionInstance
|
||||
{
|
||||
public long Id { get; set; }
|
||||
public string ExceptionHash { get; set; }
|
||||
public string LogMessage { get; set; }
|
||||
public DateTime Timestamp { get; set; }
|
||||
public bool IsProduction { get; set; }
|
||||
public Guid UGuid { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
using System.Linq;
|
||||
using Services.PetaPoco;
|
||||
|
||||
namespace NzbDrone.Services.Service.Repository.Reporting
|
||||
{
|
||||
[TableName("ExceptionReports")]
|
||||
public class ExceptionRow : ReportRowBase
|
||||
{
|
||||
public string Type { get; set; }
|
||||
public string Logger { get; set; }
|
||||
public string LogMessage { get; set; }
|
||||
public string String { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="AutoMapper" version="2.0.0" />
|
||||
<package id="elmah" version="1.2.0.1" />
|
||||
<package id="elmah.corelibrary" version="1.2.1" />
|
||||
<package id="elmah.sqlserver" version="1.2" />
|
||||
|
@ -9,7 +8,6 @@
|
|||
<package id="jQuery.UI.Combined" version="1.8.17" />
|
||||
<package id="jQuery.Validation" version="1.9" />
|
||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" />
|
||||
<package id="mongocsharpdriver" version="1.4" />
|
||||
<package id="Newtonsoft.Json" version="4.0.8" />
|
||||
<package id="Ninject" version="2.2.1.4" />
|
||||
<package id="Ninject.MVC3" version="2.2.2.0" />
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Contract;
|
||||
using NzbDrone.Services.Service.Repository.Reporting;
|
||||
using NzbDrone.Services.Tests.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Services.Tests.ExceptionControllerTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ReportExistingFixture : ServicesTestBase
|
||||
{
|
||||
|
||||
Service.Controllers.ExceptionController Controller
|
||||
{
|
||||
get
|
||||
{
|
||||
return Mocker.Resolve<Service.Controllers.ExceptionController>();
|
||||
}
|
||||
}
|
||||
|
||||
private static ExistingExceptionReport CreateExceptionReport()
|
||||
{
|
||||
return new ExistingExceptionReport
|
||||
{
|
||||
IsProduction = true,
|
||||
Version = "1.1.2.323456",
|
||||
UGuid = Guid.NewGuid(),
|
||||
LogMessage = @"Log message",
|
||||
Hash = "ABC123"
|
||||
};
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_log_warn_if_hash_doesnt_exist()
|
||||
{
|
||||
WithRealDb();
|
||||
|
||||
Controller.ReportExisting(CreateExceptionReport());
|
||||
|
||||
Db.Fetch<ExceptionDetail>().Should().BeEmpty();
|
||||
Db.Fetch<ExceptionInstance>().Should().BeEmpty();
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_save_instance_if_hash_is_valid()
|
||||
{
|
||||
WithRealDb();
|
||||
|
||||
var existing = CreateExceptionReport();
|
||||
|
||||
|
||||
Db.Insert(Builder<ExceptionDetail>.CreateNew().With(c => c.Hash = existing.Hash).Build());
|
||||
|
||||
Controller.ReportExisting(existing);
|
||||
|
||||
Db.Fetch<ExceptionDetail>().Should().HaveCount(1);
|
||||
var exceptionInstance = Db.Fetch<ExceptionInstance>();
|
||||
exceptionInstance.Should().HaveCount(1);
|
||||
exceptionInstance.Single().Id.Should().BeGreaterThan(0);
|
||||
exceptionInstance.Single().ExceptionHash.Should().NotBeBlank();
|
||||
exceptionInstance.Single().IsProduction.Should().Be(existing.IsProduction);
|
||||
exceptionInstance.Single().Timestamp.Should().BeWithin(TimeSpan.FromSeconds(4)).Before(DateTime.Now);
|
||||
exceptionInstance.Single().LogMessage.Should().Be(existing.LogMessage);
|
||||
exceptionInstance.Single().UGuid.Should().Be(existing.UGuid);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,213 +0,0 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Contract;
|
||||
using NzbDrone.Services.Service.Repository.Reporting;
|
||||
using NzbDrone.Services.Tests.Framework;
|
||||
|
||||
namespace NzbDrone.Services.Tests.ExceptionControllerTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class ReportNewFixture : ServicesTestBase
|
||||
{
|
||||
|
||||
Service.Controllers.ExceptionController Controller
|
||||
{
|
||||
get
|
||||
{
|
||||
return Mocker.Resolve<Service.Controllers.ExceptionController>();
|
||||
}
|
||||
}
|
||||
|
||||
private static ExceptionReport CreateExceptionReport()
|
||||
{
|
||||
return new ExceptionReport
|
||||
{
|
||||
IsProduction = true,
|
||||
Version = "1.1.2.323456",
|
||||
UGuid = Guid.NewGuid(),
|
||||
Logger = "NzbDrone.Logger.Name",
|
||||
LogMessage = @"Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message",
|
||||
String = @"Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message
|
||||
Long message Long message Long messageLong messageLong messageLong messageLong messageLong messageLong messageLong messageLong message",
|
||||
|
||||
Type = typeof(InvalidOperationException).Name
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void ReportNew_should_save_instance()
|
||||
{
|
||||
var exceptionReport = CreateExceptionReport();
|
||||
|
||||
WithRealDb();
|
||||
|
||||
Controller.ReportNew(exceptionReport);
|
||||
|
||||
var exceptionInstance = Db.Fetch<ExceptionInstance>();
|
||||
exceptionInstance.Should().HaveCount(1);
|
||||
exceptionInstance.Single().Id.Should().BeGreaterThan(0);
|
||||
exceptionInstance.Single().ExceptionHash.Should().NotBeBlank();
|
||||
exceptionInstance.Single().IsProduction.Should().Be(exceptionReport.IsProduction);
|
||||
exceptionInstance.Single().Timestamp.Should().BeWithin(TimeSpan.FromSeconds(4)).Before(DateTime.Now);
|
||||
exceptionInstance.Single().LogMessage.Should().Be(exceptionReport.LogMessage);
|
||||
exceptionInstance.Single().UGuid.Should().Be(exceptionReport.UGuid);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReportNew_should_save_detail()
|
||||
{
|
||||
var exceptionReport = CreateExceptionReport();
|
||||
|
||||
WithRealDb();
|
||||
|
||||
Controller.ReportNew(exceptionReport);
|
||||
|
||||
var exceptionDetails = Db.Fetch<ExceptionDetail>();
|
||||
exceptionDetails.Should().HaveCount(1);
|
||||
exceptionDetails.Single().Hash.Should().NotBeBlank();
|
||||
exceptionDetails.Single().Logger.Should().Be(exceptionReport.Logger);
|
||||
exceptionDetails.Single().Type.Should().Be(exceptionReport.Type);
|
||||
exceptionDetails.Single().String.Should().Be(exceptionReport.String);
|
||||
exceptionDetails.Single().Version.Should().Be(exceptionReport.Version);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ReportNew_should_return_exception_id()
|
||||
{
|
||||
var exceptionReport = CreateExceptionReport();
|
||||
|
||||
WithRealDb();
|
||||
|
||||
var response = Controller.ReportNew(exceptionReport);
|
||||
|
||||
response.Data.Should().BeOfType<ExceptionReportResponse>();
|
||||
((ExceptionReportResponse)response.Data).ExceptionHash.Should().NotBeBlank();
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Reporting_exception_more_than_once_should_create_single_detail_with_multiple_instances()
|
||||
{
|
||||
var exceptionReport = CreateExceptionReport();
|
||||
|
||||
WithRealDb();
|
||||
|
||||
var response1 = Controller.ReportNew(exceptionReport);
|
||||
var response2 = Controller.ReportNew(exceptionReport);
|
||||
var response3 = Controller.ReportNew(exceptionReport);
|
||||
|
||||
var detail = Db.Fetch<ExceptionDetail>();
|
||||
var instances = Db.Fetch<ExceptionInstance>();
|
||||
|
||||
detail.Should().HaveCount(1);
|
||||
instances.Should().HaveCount(3);
|
||||
|
||||
instances.Should().OnlyContain(c => c.ExceptionHash == detail.Single().Hash);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Reporting_exception_with_diffrent_version_should_create_new_detail()
|
||||
{
|
||||
var exceptionReport1 = CreateExceptionReport();
|
||||
exceptionReport1.Version = "0.1.1";
|
||||
|
||||
var exceptionReport2 = CreateExceptionReport();
|
||||
exceptionReport2.Version = "0.2.1";
|
||||
|
||||
WithRealDb();
|
||||
|
||||
Controller.ReportNew(exceptionReport1);
|
||||
Controller.ReportNew(exceptionReport2);
|
||||
|
||||
var detail = Db.Fetch<ExceptionDetail>();
|
||||
var instances = Db.Fetch<ExceptionInstance>();
|
||||
|
||||
detail.Should().HaveCount(2);
|
||||
instances.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Reporting_exception_with_diffrent_strting_should_create_new_detail()
|
||||
{
|
||||
var exceptionReport1 = CreateExceptionReport();
|
||||
exceptionReport1.String = "Error1";
|
||||
|
||||
var exceptionReport2 = CreateExceptionReport();
|
||||
exceptionReport2.String = "Error2";
|
||||
|
||||
WithRealDb();
|
||||
|
||||
Controller.ReportNew(exceptionReport1);
|
||||
Controller.ReportNew(exceptionReport2);
|
||||
|
||||
var detail = Db.Fetch<ExceptionDetail>();
|
||||
var instances = Db.Fetch<ExceptionInstance>();
|
||||
|
||||
detail.Should().HaveCount(2);
|
||||
instances.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Reporting_exception_with_diffrent_logger_should_create_new_detail()
|
||||
{
|
||||
var exceptionReport1 = CreateExceptionReport();
|
||||
exceptionReport1.Logger = "logger1";
|
||||
|
||||
var exceptionReport2 = CreateExceptionReport();
|
||||
exceptionReport2.Logger = "logger2";
|
||||
|
||||
WithRealDb();
|
||||
|
||||
Controller.ReportNew(exceptionReport1);
|
||||
Controller.ReportNew(exceptionReport2);
|
||||
|
||||
var detail = Db.Fetch<ExceptionDetail>();
|
||||
var instances = Db.Fetch<ExceptionInstance>();
|
||||
|
||||
detail.Should().HaveCount(2);
|
||||
instances.Should().HaveCount(2);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -68,8 +68,6 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ExceptionControllerTests\ReportExistingFixture.cs" />
|
||||
<Compile Include="ExceptionControllerTests\ReportNewFixture.cs" />
|
||||
<Compile Include="ReportingControllerFixture.cs" />
|
||||
<Compile Include="Framework\ServicesTestBase.cs" />
|
||||
<Compile Include="Framework\TestDbHelper.cs" />
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>AutoMapper</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:AutoMapper.MappingEngine.ConversionVisitor">
|
||||
<summary>
|
||||
This expression visitor will replace an input parameter by another one
|
||||
|
||||
see http://stackoverflow.com/questions/4601844/expression-tree-copy-or-convert
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
|
@ -1,671 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>AutoMapper</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:AutoMapper.MappingEngine.ConversionVisitor">
|
||||
<summary>
|
||||
This expression visitor will replace an input parameter by another one
|
||||
|
||||
see http://stackoverflow.com/questions/4601844/expression-tree-copy-or-convert
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TvdP.Collections.ConcurrentDictionaryKey`2">
|
||||
<summary>
|
||||
Search key structure for <see cref="T:TvdP.Collections.ConcurrentDictionary`2"/>
|
||||
</summary>
|
||||
<typeparam name="TKey">Type of the key.</typeparam>
|
||||
<typeparam name="TValue">Type of the value.</typeparam>
|
||||
</member>
|
||||
<member name="T:TvdP.Collections.ConcurrentDictionary`2">
|
||||
<summary>
|
||||
A Concurrent <see cref="T:System.Collections.Generic.IDictionary`2"/> implementation.
|
||||
</summary>
|
||||
<typeparam name="TKey">Type of the keys.</typeparam>
|
||||
<typeparam name="TValue">Type of the values.</typeparam>
|
||||
<remarks>
|
||||
This class is threadsafe and highly concurrent. This means that multiple threads can do lookup and insert operations
|
||||
on this dictionary simultaneously.
|
||||
It is not guaranteed that collisions will not occur. The dictionary is partitioned in segments. A segment contains
|
||||
a set of items based on a hash of those items. The more segments there are and the beter the hash, the fewer collisions will occur.
|
||||
This means that a nearly empty ConcurrentDictionary is not as concurrent as one containing many items.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:TvdP.Collections.ConcurrentHashtable`2">
|
||||
<summary>
|
||||
Base class for concurrent hashtable implementations
|
||||
</summary>
|
||||
<typeparam name="TStored">Type of the items stored in the hashtable.</typeparam>
|
||||
<typeparam name="TSearch">Type of the key to search with.</typeparam>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.#ctor">
|
||||
<summary>
|
||||
Constructor (protected)
|
||||
</summary>
|
||||
<remarks>Use Initialize method after construction.</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.Initialize">
|
||||
<summary>
|
||||
Initialize the newly created ConcurrentHashtable. Invoke in final (sealed) constructor
|
||||
or Create method.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.CreateSegmentRange(System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Create a segment range
|
||||
</summary>
|
||||
<param name="segmentCount">Number of segments in range.</param>
|
||||
<param name="initialSegmentSize">Number of slots allocated initialy in each segment.</param>
|
||||
<returns>The created <see cref="T:TvdP.Collections.Segmentrange`2"/> instance.</returns>
|
||||
</member>
|
||||
<member name="F:TvdP.Collections.ConcurrentHashtable`2._NewRange">
|
||||
<summary>
|
||||
While adjusting the segmentation, _NewRange will hold a reference to the new range of segments.
|
||||
when the adjustment is complete this reference will be copied to _CurrentRange.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:TvdP.Collections.ConcurrentHashtable`2._CurrentRange">
|
||||
<summary>
|
||||
Will hold the most current reange of segments. When busy adjusting the segmentation, this
|
||||
field will hold a reference to the old range.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:TvdP.Collections.ConcurrentHashtable`2._SwitchPoint">
|
||||
<summary>
|
||||
While adjusting the segmentation this field will hold a boundary.
|
||||
Clients accessing items with a key hash value below this boundary (unsigned compared)
|
||||
will access _NewRange. The others will access _CurrentRange
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.GetItemHashCode(`0@)">
|
||||
<summary>
|
||||
Get a hashcode for given storeable item.
|
||||
</summary>
|
||||
<param name="item">Reference to the item to get a hash value for.</param>
|
||||
<returns>The hash value as an <see cref="T:System.UInt32"/>.</returns>
|
||||
<remarks>
|
||||
The hash returned should be properly randomized hash. The standard GetItemHashCode methods are usually not good enough.
|
||||
A storeable item and a matching search key should return the same hash code.
|
||||
So the statement <code>ItemEqualsItem(storeableItem, searchKey) ? GetItemHashCode(storeableItem) == GetItemHashCode(searchKey) : true </code> should always be true;
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.GetKeyHashCode(`1@)">
|
||||
<summary>
|
||||
Get a hashcode for given search key.
|
||||
</summary>
|
||||
<param name="key">Reference to the key to get a hash value for.</param>
|
||||
<returns>The hash value as an <see cref="T:System.UInt32"/>.</returns>
|
||||
<remarks>
|
||||
The hash returned should be properly randomized hash. The standard GetItemHashCode methods are usually not good enough.
|
||||
A storeable item and a matching search key should return the same hash code.
|
||||
So the statement <code>ItemEqualsItem(storeableItem, searchKey) ? GetItemHashCode(storeableItem) == GetItemHashCode(searchKey) : true </code> should always be true;
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.ItemEqualsKey(`0@,`1@)">
|
||||
<summary>
|
||||
Compares a storeable item to a search key. Should return true if they match.
|
||||
</summary>
|
||||
<param name="item">Reference to the storeable item to compare.</param>
|
||||
<param name="key">Reference to the search key to compare.</param>
|
||||
<returns>True if the storeable item and search key match; false otherwise.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.ItemEqualsItem(`0@,`0@)">
|
||||
<summary>
|
||||
Compares two storeable items for equality.
|
||||
</summary>
|
||||
<param name="item1">Reference to the first storeable item to compare.</param>
|
||||
<param name="item2">Reference to the second storeable item to compare.</param>
|
||||
<returns>True if the two soreable items should be regarded as equal.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.IsEmpty(`0@)">
|
||||
<summary>
|
||||
Indicates if a specific item reference contains a valid item.
|
||||
</summary>
|
||||
<param name="item">The storeable item reference to check.</param>
|
||||
<returns>True if the reference doesn't refer to a valid item; false otherwise.</returns>
|
||||
<remarks>The statement <code>IsEmpty(default(TStoredI))</code> should always be true.</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.GetKeyType(`0@)">
|
||||
<summary>
|
||||
Returns the type of the key value or object.
|
||||
</summary>
|
||||
<param name="item">The stored item to get the type of the key for.</param>
|
||||
<returns>The actual type of the key or null if it can not be determined.</returns>
|
||||
<remarks>
|
||||
Used for diagnostics purposes.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.GetSegment(System.UInt32)">
|
||||
<summary>
|
||||
Gets a segment out of either _NewRange or _CurrentRange based on the hash value.
|
||||
</summary>
|
||||
<param name="hash"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.GetSegmentLockedForWriting(System.UInt32)">
|
||||
<summary>
|
||||
Gets a LOCKED segment out of either _NewRange or _CurrentRange based on the hash value.
|
||||
Unlock needs to be called on this segment before it can be used by other clients.
|
||||
</summary>
|
||||
<param name="hash"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.GetSegmentLockedForReading(System.UInt32)">
|
||||
<summary>
|
||||
Gets a LOCKED segment out of either _NewRange or _CurrentRange based on the hash value.
|
||||
Unlock needs to be called on this segment before it can be used by other clients.
|
||||
</summary>
|
||||
<param name="hash"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.FindItem(`1@,`0@)">
|
||||
<summary>
|
||||
Finds an item in the table collection that maches the given searchKey
|
||||
</summary>
|
||||
<param name="searchKey">The key to the item.</param>
|
||||
<param name="item">Out reference to a field that will receive the found item.</param>
|
||||
<returns>A boolean that will be true if an item has been found and false otherwise.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.GetOldestItem(`0@,`0@)">
|
||||
<summary>
|
||||
Looks for an existing item in the table contents using an alternative copy. If it can be found it will be returned.
|
||||
If not then the alternative copy will be added to the table contents and the alternative copy will be returned.
|
||||
</summary>
|
||||
<param name="searchKey">A copy to search an already existing instance with</param>
|
||||
<param name="item">Out reference to receive the found item or the alternative copy</param>
|
||||
<returns>A boolean that will be true if an existing copy was found and false otherwise.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.ReplaceItem(`1@,`0@,`0@,System.Func{`0,System.Boolean})">
|
||||
<summary>
|
||||
Replaces and existing item
|
||||
</summary>
|
||||
<param name="newItem"></param>
|
||||
<param name="oldItem"></param>
|
||||
<param name="sanction"></param>
|
||||
<returns>true is the existing item was successfully replaced.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.InsertItem(`0@,`0@)">
|
||||
<summary>
|
||||
Inserts an item in the table contents possibly replacing an existing item.
|
||||
</summary>
|
||||
<param name="searchKey">The item to insert in the table</param>
|
||||
<param name="replacedItem">Out reference to a field that will receive any possibly replaced item.</param>
|
||||
<returns>A boolean that will be true if an existing copy was found and replaced and false otherwise.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.RemoveItem(`1@,`0@)">
|
||||
<summary>
|
||||
Removes an item from the table contents.
|
||||
</summary>
|
||||
<param name="searchKey">The key to find the item with.</param>
|
||||
<param name="removedItem">Out reference to a field that will receive the found and removed item.</param>
|
||||
<returns>A boolean that will be rue if an item was found and removed and false otherwise.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.EnumerateAmorphLockedSegments(System.Boolean)">
|
||||
<summary>
|
||||
Enumerates all segments in _CurrentRange and locking them before yielding them and resleasing the lock afterwards
|
||||
The order in which the segments are returned is undefined.
|
||||
Lock SyncRoot before using this enumerable.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.Clear">
|
||||
<summary>
|
||||
Removes all items from the collection.
|
||||
Aquires a lock on SyncRoot before it does it's thing.
|
||||
When this method returns and multiple threads have access to this table it
|
||||
is not guaranteed that the table is actually empty.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.SegmentationAdjustmentNeeded">
|
||||
<summary>
|
||||
Determines if a segmentation adjustment is needed.
|
||||
</summary>
|
||||
<returns>True</returns>
|
||||
</member>
|
||||
<member name="F:TvdP.Collections.ConcurrentHashtable`2._AssessSegmentationPending">
|
||||
<summary>
|
||||
Bool as int (for interlocked functions) that is true if a Segmentation assesment is pending.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:TvdP.Collections.ConcurrentHashtable`2._AllocatedSpace">
|
||||
<summary>
|
||||
The total allocated number of item slots. Filled with nonempty items or not.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.EffectTotalAllocatedSpace(System.Int32)">
|
||||
<summary>
|
||||
When a segment resizes it uses this method to inform the hashtable of the change in allocated space.
|
||||
</summary>
|
||||
<param name="effect"></param>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.ScheduleMaintenance">
|
||||
<summary>
|
||||
Schedule a call to the AssessSegmentation() method.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.AssessSegmentation(System.Object)">
|
||||
<summary>
|
||||
Checks if segmentation needs to be adjusted and if so performs the adjustment.
|
||||
</summary>
|
||||
<param name="dummy"></param>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.AssessSegmentation">
|
||||
<summary>
|
||||
This method is called when a re-segmentation is expected to be needed. It checks if it actually is needed and, if so, performs the re-segementation.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentHashtable`2.SetSegmentation(System.Int32,System.Int32)">
|
||||
<summary>
|
||||
Adjusts the segmentation to the new segment count
|
||||
</summary>
|
||||
<param name="newSegmentCount">The new number of segments to use. This must be a power of 2.</param>
|
||||
<param name="segmentSize">The number of item slots to reserve in each segment.</param>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentHashtable`2.SyncRoot">
|
||||
<summary>
|
||||
Returns an object that serves as a lock for range operations
|
||||
</summary>
|
||||
<remarks>
|
||||
Clients use this primarily for enumerating over the Tables contents.
|
||||
Locking doesn't guarantee that the contents don't change, but prevents operations that would
|
||||
disrupt the enumeration process.
|
||||
Operations that use this lock:
|
||||
Count, Clear, DisposeGarbage and AssessSegmentation.
|
||||
Keeping this lock will prevent the table from re-segmenting.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentHashtable`2.Items">
|
||||
<summary>
|
||||
Gets an IEnumerable to iterate over all items in all segments.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
<remarks>
|
||||
A lock should be aquired and held on SyncRoot while this IEnumerable is being used.
|
||||
The order in which the items are returned is undetermined.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentHashtable`2.Count">
|
||||
<summary>
|
||||
Returns a count of all items in teh collection. This may not be
|
||||
aqurate when multiple threads are accessing this table.
|
||||
Aquires a lock on SyncRoot before it does it's thing.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentHashtable`2.MinSegments">
|
||||
<summary>
|
||||
Gives the minimum number of segments a hashtable can contain. This should be 1 or more and always a power of 2.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentHashtable`2.MinSegmentAllocatedSpace">
|
||||
<summary>
|
||||
Gives the minimum number of allocated item slots per segment. This should be 1 or more, always a power of 2
|
||||
and less than 1/2 of MeanSegmentAllocatedSpace.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentHashtable`2.MeanSegmentAllocatedSpace">
|
||||
<summary>
|
||||
Gives the prefered number of allocated item slots per segment. This should be 4 or more and always a power of 2.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.#ctor">
|
||||
<summary>
|
||||
Constructs a <see cref="T:TvdP.Collections.ConcurrentDictionary`2"/> instance using the default <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> to compare keys.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.#ctor(System.Collections.Generic.IEqualityComparer{`0})">
|
||||
<summary>
|
||||
Constructs a <see cref="T:TvdP.Collections.ConcurrentDictionary`2"/> instance using the specified <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> to compare keys.
|
||||
</summary>
|
||||
<param name="comparer">The <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> tp compare keys with.</param>
|
||||
<exception cref="T:System.ArgumentNullException"><paramref name="comparer"/> is null.</exception>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.GetItemHashCode(System.Nullable{System.Collections.Generic.KeyValuePair{`0,`1}}@)">
|
||||
<summary>
|
||||
Get a hashcode for given storeable item.
|
||||
</summary>
|
||||
<param name="item">Reference to the item to get a hash value for.</param>
|
||||
<returns>The hash value as an <see cref="T:System.UInt32"/>.</returns>
|
||||
<remarks>
|
||||
The hash returned should be properly randomized hash. The standard GetItemHashCode methods are usually not good enough.
|
||||
A storeable item and a matching search key should return the same hash code.
|
||||
So the statement <code>ItemEqualsItem(storeableItem, searchKey) ? GetItemHashCode(storeableItem) == GetItemHashCode(searchKey) : true </code> should always be true;
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.GetKeyHashCode(TvdP.Collections.ConcurrentDictionaryKey{`0,`1}@)">
|
||||
<summary>
|
||||
Get a hashcode for given search key.
|
||||
</summary>
|
||||
<param name="key">Reference to the key to get a hash value for.</param>
|
||||
<returns>The hash value as an <see cref="T:System.UInt32"/>.</returns>
|
||||
<remarks>
|
||||
The hash returned should be properly randomized hash. The standard GetItemHashCode methods are usually not good enough.
|
||||
A storeable item and a matching search key should return the same hash code.
|
||||
So the statement <code>ItemEqualsItem(storeableItem, searchKey) ? GetItemHashCode(storeableItem) == GetItemHashCode(searchKey) : true </code> should always be true;
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.ItemEqualsKey(System.Nullable{System.Collections.Generic.KeyValuePair{`0,`1}}@,TvdP.Collections.ConcurrentDictionaryKey{`0,`1}@)">
|
||||
<summary>
|
||||
Compares a storeable item to a search key. Should return true if they match.
|
||||
</summary>
|
||||
<param name="item">Reference to the storeable item to compare.</param>
|
||||
<param name="key">Reference to the search key to compare.</param>
|
||||
<returns>True if the storeable item and search key match; false otherwise.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.ItemEqualsItem(System.Nullable{System.Collections.Generic.KeyValuePair{`0,`1}}@,System.Nullable{System.Collections.Generic.KeyValuePair{`0,`1}}@)">
|
||||
<summary>
|
||||
Compares two storeable items for equality.
|
||||
</summary>
|
||||
<param name="item1">Reference to the first storeable item to compare.</param>
|
||||
<param name="item2">Reference to the second storeable item to compare.</param>
|
||||
<returns>True if the two soreable items should be regarded as equal.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.IsEmpty(System.Nullable{System.Collections.Generic.KeyValuePair{`0,`1}}@)">
|
||||
<summary>
|
||||
Indicates if a specific item reference contains a valid item.
|
||||
</summary>
|
||||
<param name="item">The storeable item reference to check.</param>
|
||||
<returns>True if the reference doesn't refer to a valid item; false otherwise.</returns>
|
||||
<remarks>The statement <code>IsEmpty(default(TStoredI))</code> should always be true.</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.System#Collections#Generic#IDictionary{TKey@TValue}#Add(`0,`1)">
|
||||
<summary>
|
||||
Adds an element with the provided key and value to the dictionary.
|
||||
</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>
|
||||
<exception cref="T:System.ArgumentException">An element with the same key already exists in the dictionary.</exception>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.ContainsKey(`0)">
|
||||
<summary>
|
||||
Determines whether the dictionary
|
||||
contains an element with the specified key.
|
||||
</summary>
|
||||
<param name="key">The key to locate in the dictionary.</param>
|
||||
<returns>true if the dictionary contains
|
||||
an element with the key; otherwise, false.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.System#Collections#Generic#IDictionary{TKey@TValue}#Remove(`0)">
|
||||
<summary>
|
||||
Removes the element with the specified key from the dictionary.
|
||||
</summary>
|
||||
<param name="key">The key of the element to remove.</param>
|
||||
<returns>true if the element is successfully removed; otherwise, false. This method
|
||||
also returns false if key was not found in the original dictionary.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.TryGetValue(`0,`1@)">
|
||||
<summary>
|
||||
Gets the value associated with the specified key.
|
||||
</summary>
|
||||
<param name="key">The key whose value to get.</param>
|
||||
<param name="value">
|
||||
When this method returns, the value associated with the specified key, if
|
||||
the key is found; otherwise, the default value for the type of the value
|
||||
parameter. This parameter is passed uninitialized.
|
||||
</param>
|
||||
<returns>
|
||||
true if the dictionary contains an element with the specified key; otherwise, false.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.System#Collections#Generic#ICollection{System#Collections#Generic#KeyValuePair{TKey@TValue}}#Add(System.Collections.Generic.KeyValuePair{`0,`1})">
|
||||
<summary>
|
||||
Adds an association to the dictionary.
|
||||
</summary>
|
||||
<param name="item">A <see cref="T:System.Collections.Generic.KeyValuePair`2"/> that represents the association to add.</param>
|
||||
<exception cref="T:System.ArgumentException">An association with an equal key already exists in the dicitonary.</exception>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.Clear">
|
||||
<summary>
|
||||
Removes all items from the dictionary.
|
||||
</summary>
|
||||
<remarks>WHen working with multiple threads, that each can add items to this dictionary, it is not guaranteed that the dictionary will be empty when this method returns.</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.System#Collections#Generic#ICollection{System#Collections#Generic#KeyValuePair{TKey@TValue}}#Contains(System.Collections.Generic.KeyValuePair{`0,`1})">
|
||||
<summary>
|
||||
Determines whether the specified association exists in the dictionary.
|
||||
</summary>
|
||||
<param name="item">The key-value association to search fo in the dicionary.</param>
|
||||
<returns>True if item is found in the dictionary; otherwise, false.</returns>
|
||||
<remarks>
|
||||
This method compares both key and value. It uses the default equality comparer to compare values.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.System#Collections#Generic#ICollection{System#Collections#Generic#KeyValuePair{TKey@TValue}}#CopyTo(System.Collections.Generic.KeyValuePair{`0,`1}[],System.Int32)">
|
||||
<summary>
|
||||
Copies all associations of the dictionary to an
|
||||
<see cref="T:System.Array"/>, starting at a particular <see cref="T:System.Array"/> index.
|
||||
</summary>
|
||||
<param name="array">The one-dimensional <see cref="T:System.Array"/> that is the destination of the associations
|
||||
copied from <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/>. The <see cref="T:System.Array"/> must
|
||||
have zero-based indexing.</param>
|
||||
<param name="arrayIndex">The zero-based index in <paramref name="array"/> at which copying begins.</param>
|
||||
<exception cref="T:System.ArgumentNullException"><paramref name="array"/> is null.</exception>
|
||||
<exception cref="T:System.ArgumentOutOfRangeException"><paramref name="arrayIndex"/> is less than 0.</exception>
|
||||
<exception cref="T:System.ArgumentException"><paramref name="arrayIndex"/> is equal to or greater than the length of <paramref name="array"/>.</exception>
|
||||
<exception cref="T:System.ArgumentException">The number of associations to be copied
|
||||
is greater than the available space from <paramref name="arrayIndex"/> to the end of the destination
|
||||
<paramref name="array"/>.</exception>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.System#Collections#Generic#ICollection{System#Collections#Generic#KeyValuePair{TKey@TValue}}#Remove(System.Collections.Generic.KeyValuePair{`0,`1})">
|
||||
<summary>
|
||||
Removes the specified association from the <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/>, comparing both key and value.
|
||||
</summary>
|
||||
<param name="item">A <see cref="T:System.Collections.Generic.KeyValuePair`2"/> representing the association to remove.</param>
|
||||
<returns>true if the association was successfully removed from the <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/>;
|
||||
otherwise, false. This method also returns false if the association is not found in
|
||||
the original <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/>.
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through all associations in the <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/> at the moment of invocation.
|
||||
</summary>
|
||||
<returns>A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the associations.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.ConcurrentDictionary`2.System#Collections#IEnumerable#GetEnumerator">
|
||||
<summary>
|
||||
Returns an enumerator that iterates through all associations in the <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/> at the moment of invocation.
|
||||
</summary>
|
||||
<returns>A <see cref="T:System.Collections.IEnumerator"/> that can be used to iterate through the associations.</returns>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentDictionary`2.Comparer">
|
||||
<summary>
|
||||
Gives the <see cref="T:System.Collections.Generic.IEqualityComparer`1"/> of TKey that is used to compare keys.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentDictionary`2.Keys">
|
||||
<summary>
|
||||
Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the keys of
|
||||
the dictionary.
|
||||
</summary>
|
||||
<returns>An <see cref="T:System.Collections.Generic.ICollection`1"/> containing the keys of the dictionary.</returns>
|
||||
<remarks>This property takes a snapshot of the current keys collection of the dictionary at the moment of invocation.</remarks>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentDictionary`2.Values">
|
||||
<summary>
|
||||
Gets an <see cref="T:System.Collections.Generic.ICollection`1"/> containing the values in
|
||||
the dictionary.
|
||||
</summary>
|
||||
<returns>
|
||||
An <see cref="T:System.Collections.Generic.ICollection`1"/> containing the values in the dictionary.
|
||||
</returns>
|
||||
<remarks>This property takes a snapshot of the current keys collection of the dictionary at the moment of invocation.</remarks>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentDictionary`2.Item(`0)">
|
||||
<summary>
|
||||
Gets or sets the value associated with the specified key.
|
||||
</summary>
|
||||
<param name="key">The key of the value to get or set.</param>
|
||||
<returns>The value associated with the specified key. If the specified key is not found, a get operation throws a KeyNotFoundException, and a set operation creates a new element with the specified key.</returns>
|
||||
<remarks>
|
||||
When working with multiple threads, that can each potentialy remove the searched for item, a <see cref="T:System.Collections.Generic.KeyNotFoundException"/> can always be expected.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentDictionary`2.Count">
|
||||
<summary>
|
||||
Gets the number of elements contained in the <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.ConcurrentDictionary`2.System#Collections#Generic#ICollection{System#Collections#Generic#KeyValuePair{TKey@TValue}}#IsReadOnly">
|
||||
<summary>
|
||||
Gets a value indicating whether the <see cref="T:TvdP.Collections.ConcurrentDictionaryKey`2"/> is read-only, which is always false.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TvdP.Collections.Segment`2">
|
||||
<summary>
|
||||
A 'single writer - multi reader' threaded segment in a hashtable.
|
||||
</summary>
|
||||
<typeparam name="TStored"></typeparam>
|
||||
<typeparam name="TSearch"></typeparam>
|
||||
<remarks>
|
||||
Though each segment can be accessed by 1 writer thread simultaneously, the hashtable becomes concurrent
|
||||
for writing by containing many segments so that collisions are rare. The table will be fully concurrent
|
||||
for read operations as far as they are not colliding with write operations.
|
||||
Each segment is itself a small hashtable that can grow and shrink individualy. This prevents blocking of
|
||||
the entire hashtable when growing or shrinking is needed. Because each segment is relatively small (depending on
|
||||
the quality of the hash) resizing of the individual segments should not take much time.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.Initialize(System.Int32)">
|
||||
<summary>
|
||||
Initialize the segment.
|
||||
</summary>
|
||||
<param name="initialSize"></param>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.Welcome(TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
When segment gets introduced into hashtable then its allocated space should be added to the
|
||||
total allocated space.
|
||||
Single threaded access or locking is needed
|
||||
</summary>
|
||||
<param name="traits"></param>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.Bye(TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
When segment gets removed from hashtable then its allocated space should be subtracted to the
|
||||
total allocated space.
|
||||
Single threaded access or locking is needed
|
||||
</summary>
|
||||
<param name="traits"></param>
|
||||
</member>
|
||||
<member name="F:TvdP.Collections.Segment`2._List">
|
||||
<summary>
|
||||
Array with 'slots'. Each slot can be filled or empty.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.InsertItemAtIndex(System.UInt32,System.UInt32,`0,TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
Inserts an item into a *not empty* spot given by position i. It moves items forward until an empty spot is found.
|
||||
</summary>
|
||||
<param name="mask"></param>
|
||||
<param name="i"></param>
|
||||
<param name="itemCopy"></param>
|
||||
<param name="traits"></param>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.FindItem(`1@,`0@,TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
Find item in segment.
|
||||
</summary>
|
||||
<param name="key">Reference to the search key to use.</param>
|
||||
<param name="item">Out reference to store the found item in.</param>
|
||||
<param name="traits">Object that tells this segment how to treat items and keys.</param>
|
||||
<returns>True if an item could be found, otherwise false.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.GetOldestItem(`0@,`0@,TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
Find an existing item or, if it can't be found, insert a new item.
|
||||
</summary>
|
||||
<param name="key">Reference to the item that will be inserted if an existing item can't be found. It will also be used to search with.</param>
|
||||
<param name="item">Out reference to store the found item or, if it can not be found, the new inserted item.</param>
|
||||
<param name="traits">Object that tells this segment how to treat items and keys.</param>
|
||||
<returns>True if an existing item could be found, otherwise false.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.InsertItem(`0@,`0@,TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
Inserts an item in the segment, possibly replacing an equal existing item.
|
||||
</summary>
|
||||
<param name="key">A reference to the item to insert.</param>
|
||||
<param name="item">An out reference where any replaced item will be written to, if no item was replaced the new item will be written to this reference.</param>
|
||||
<param name="traits">Object that tells this segment how to treat items and keys.</param>
|
||||
<returns>True if an existing item could be found and is replaced, otherwise false.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.RemoveItem(`1@,`0@,TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
Removes an item from the segment.
|
||||
</summary>
|
||||
<param name="key">A reference to the key to search with.</param>
|
||||
<param name="item">An out reference where the removed item will be stored or default(<typeparamref name="TStored"/>) if no item to remove can be found.</param>
|
||||
<param name="traits">Object that tells this segment how to treat items and keys.</param>
|
||||
<returns>True if an item could be found and is removed, false otherwise.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.GetNextItem(System.Int32,`0@,TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
Iterate over items in the segment.
|
||||
</summary>
|
||||
<param name="beyond">Position beyond which the next filled slot will be found and the item in that slot returned. (Starting with -1)</param>
|
||||
<param name="item">Out reference where the next item will be stored or default if the end of the segment is reached.</param>
|
||||
<param name="traits">Object that tells this segment how to treat items and keys.</param>
|
||||
<returns>The index position the next item has been found or -1 otherwise.</returns>
|
||||
</member>
|
||||
<member name="F:TvdP.Collections.Segment`2._Count">
|
||||
<summary>
|
||||
Total numer of filled slots in _List.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Collections.Segment`2.Trim(TvdP.Collections.ConcurrentHashtable{`0,`1})">
|
||||
<summary>
|
||||
Remove any excess allocated space
|
||||
</summary>
|
||||
<param name="traits"></param>
|
||||
</member>
|
||||
<member name="P:TvdP.Collections.Segment`2.IsAlive">
|
||||
<summary>
|
||||
Boolean value indicating if this segment has not been trashed yet.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:TvdP.Threading.TinyReaderWriterLock">
|
||||
<summary>
|
||||
Tiny spin lock that allows multiple readers simultanously and 1 writer exclusively
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Threading.TinyReaderWriterLock.ReleaseForReading">
|
||||
<summary>
|
||||
Release a reader lock
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Threading.TinyReaderWriterLock.ReleaseForWriting">
|
||||
<summary>
|
||||
Release a writer lock
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Threading.TinyReaderWriterLock.LockForReading">
|
||||
<summary>
|
||||
Aquire a reader lock. Wait until lock is aquired.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Threading.TinyReaderWriterLock.LockForReading(System.Boolean)">
|
||||
<summary>
|
||||
Aquire a reader lock.
|
||||
</summary>
|
||||
<param name="wait">True if to wait until lock aquired, False to return immediately.</param>
|
||||
<returns>Boolean indicating if lock was successfuly aquired.</returns>
|
||||
</member>
|
||||
<member name="M:TvdP.Threading.TinyReaderWriterLock.LockForWriting">
|
||||
<summary>
|
||||
Aquire a writer lock. Wait until lock is aquired.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:TvdP.Threading.TinyReaderWriterLock.LockForWriting(System.Boolean)">
|
||||
<summary>
|
||||
Aquire a writer lock.
|
||||
</summary>
|
||||
<param name="wait">True if to wait until lock aquired, False to return immediately.</param>
|
||||
<returns>Boolean indicating if lock was successfuly aquired.</returns>
|
||||
</member>
|
||||
<member name="T:System.SerializableAttribute">
|
||||
<summary>
|
||||
Attempts to replicate the Desktop CLR.
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
Binary file not shown.
|
@ -0,0 +1,237 @@
|
|||
C# Driver Version 1.4.1 Release Notes
|
||||
=====================================
|
||||
|
||||
This minor release fixes a few issues found by users of the LINQ support added
|
||||
in v1.4 of the C# driver and also adds support for a few new LINQ query
|
||||
operators and where clauses.
|
||||
|
||||
File by file change logs are available at:
|
||||
|
||||
https://github.com/mongodb/mongo-csharp-driver/blob/master/Release%20Notes/Change%20Log%20v1.4.1-Bson.txt
|
||||
https://github.com/mongodb/mongo-csharp-driver/blob/master/Release%20Notes/Change%20Log%20v1.4.1-Driver.txt
|
||||
|
||||
These release notes describe the changes at a higher level, and omit describing
|
||||
some of the minor changes.
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
||||
There are no breaking changes in this release.
|
||||
|
||||
JIRA issues resolved
|
||||
--------------------
|
||||
|
||||
The full list of JIRA issues resolved in this release is available at:
|
||||
|
||||
https://jira.mongodb.org/secure/IssueNavigator.jspa?mode=hide&requestId=11397
|
||||
|
||||
LINQ query support
|
||||
==================
|
||||
|
||||
The main purpose of this minor release is to fix some issues found by users of
|
||||
the new LINQ support added in v1.4.
|
||||
|
||||
One bug that many have encountered is a NullReferenceException when writing a
|
||||
query against an inherited property.
|
||||
|
||||
https://jira.mongodb.org/browse/CSHARP-418
|
||||
|
||||
You would hit this error if you had any queries that were similar to this:
|
||||
|
||||
public class B
|
||||
{
|
||||
public ObjectId Id;
|
||||
}
|
||||
|
||||
public class C : B
|
||||
{
|
||||
public int X;
|
||||
}
|
||||
|
||||
var query =
|
||||
from c in collection.AsQueryable<C>()
|
||||
where c.Id = id // class C inherits Id from class B
|
||||
select c;
|
||||
|
||||
Another bug that a few users have encountered is an ArgumentOutOfRangeException
|
||||
when writing a LINQ query that consists of a bare AsQueryable and nothing else:
|
||||
|
||||
https://jira.mongodb.org/browse/CSHARP-419
|
||||
|
||||
as in this sample:
|
||||
|
||||
var query = collection.AsQueryable<C>(); // no where clause
|
||||
|
||||
Normally a query would contain something else besides the call to AsQueryable
|
||||
(like a where clause), but this is a legal query and is now supported.
|
||||
|
||||
BSON library changes
|
||||
====================
|
||||
|
||||
MaxSerializationDepth
|
||||
---------------------
|
||||
|
||||
The BSON serialization mechanism does not support circular references in your
|
||||
object graph. In earlier versions of the C# driver if you attempted to
|
||||
serialize an object with circular references you would get a
|
||||
StackOverflowExpection. The 1.4.1 version now tracks the serialization depth
|
||||
as it serializes an object and if it exceeds MaxSerializationDepth a
|
||||
BsonSerializationException is thrown. The problem with StackOverflowException
|
||||
was that it was fatal to your process, but the BsonSerializationException can
|
||||
be caught and your process can continue executing if you choose.
|
||||
|
||||
The default MaxSerializationDepth is 100.
|
||||
|
||||
Interpretation of C# null vs BsonNull.Value
|
||||
-------------------------------------------
|
||||
|
||||
When working with the BsonDocument object model a C# null is usually ignored,
|
||||
specially when creating BsonDocuments using functional construction. However,
|
||||
when mapping between .NET types and the BsonDocument object model a C# null
|
||||
will now be mapped to a BsonNull. For example:
|
||||
|
||||
var dictionary = new Dictionary<string, object> { { "x", null } };
|
||||
var document = new BsonDocument(dictionary);
|
||||
// document["x"] == BsonNull.Value
|
||||
|
||||
and when mapping in the reverse direction a BsonNull will map to a C# null:
|
||||
|
||||
var document = new BsonDocument { { "x", BsonNull.Value } };
|
||||
var dictionary = document.ToDictionary();
|
||||
// dictionary["x"] == null
|
||||
|
||||
Usually mapping between .NET types and the BsonDocument object model happens
|
||||
automatically as needed, but if you want to invoke the mapping yourself you
|
||||
can access the BsonTypeMapper directly:
|
||||
|
||||
var dictionary = new Dictionary<string, object> { { "x", null } };
|
||||
var document = BsonTypeMapper.MapToBsonValue(dictionary);
|
||||
// document["x"] == BsonNull.Value
|
||||
|
||||
or in the other direction:
|
||||
|
||||
var document = new BsonDocument { { "x", BsonNull.Value } };
|
||||
var dictionary = (IDictionary<string, object>)BsonTypeMapper.MapToDotNetValue(document);
|
||||
// dictionary["x"] == null
|
||||
|
||||
Serializing read-only properties
|
||||
--------------------------------
|
||||
|
||||
The class map based serialization support normally serializes only public
|
||||
read-write properties (or fields). Sometimes it can be useful to serialize
|
||||
read-only properties as well, specially if you want to query against them.
|
||||
You can now opt-in your read-only properties so that they appear in the
|
||||
serialized document. For example:
|
||||
|
||||
public class Book
|
||||
{
|
||||
public ObjectId Id;
|
||||
public string Title;
|
||||
[BsonElement] // opt-in the read-only LowercaseTitle property
|
||||
public string LowercaseTitle { get { return Title.ToLower(); } }
|
||||
}
|
||||
|
||||
Now when a Book is serialized the document will look like:
|
||||
|
||||
{
|
||||
_id : ObjectId("4f8d771dae879111d289dbc0"),
|
||||
Title : "For Whom the Bell Tolls",
|
||||
LowercaseTitle : "for whom the bell tolls"
|
||||
}
|
||||
|
||||
During deserialization any elements in the serialized document that
|
||||
correspond to read-only properties are ignored.
|
||||
|
||||
Driver changes
|
||||
==============
|
||||
|
||||
MongoServer
|
||||
-----------
|
||||
|
||||
There is a new method called IsDatabaseNameValid that you can call to test if
|
||||
a database name is valid.
|
||||
|
||||
MongoDatabase
|
||||
-------------
|
||||
|
||||
There is a new method called IsCollectionNameValid that you can call to test if a
|
||||
collection name is valid.
|
||||
|
||||
MongoGridFS
|
||||
-----------
|
||||
|
||||
You can now disable computing the MD5 at the server when uploading a GridFS
|
||||
file. You can also disable the client side verification of the MD5 that is
|
||||
normally done on Upload or Download. The reason you might choose to disable
|
||||
MD5 verification is that it is computationally expensive to compute the MD5.
|
||||
|
||||
LINQ OfType\<T\> query operator
|
||||
-------------------------------
|
||||
|
||||
You can now use the OfType\<T\> query operator in LINQ queries. For example:
|
||||
|
||||
var query = collection.AsQueryable<B>().OfType<C>();
|
||||
|
||||
this generates a query against the "_t" discriminator value that is used to
|
||||
identify the actual type of a serialized document.
|
||||
|
||||
Additional expressions supported in LINQ where clauses
|
||||
------------------------------------------------------
|
||||
|
||||
The following expressions are now supported in LINQ where clauses:
|
||||
|
||||
// d is the document
|
||||
// p is a property of the document
|
||||
// c is a character constant
|
||||
// ca is an array of character constants
|
||||
// s is a string constant
|
||||
// i, j, k, n are integer constants
|
||||
|
||||
where d.p.Equals(constant)
|
||||
where string.IsNullOrEmpty(d.p)
|
||||
where d.p.IndexOf(c) == i
|
||||
where d.p.IndexOf(c, j) == i
|
||||
where d.p.IndexOf(c, j, k) == i
|
||||
where d.p.IndexOf(s) == i
|
||||
where d.p.IndexOf(s, j) == i
|
||||
where d.p.IndexOf(s, j, k) == i
|
||||
where d.p.IndexOfAny(ca) == i
|
||||
where d.p.IndexOfAny(ca, j) == i
|
||||
where d.p.IndexOfAny(ca, j, k) == i
|
||||
where d.p[i] == c
|
||||
where d.p.Length == n
|
||||
where d.p.ToLower().Contains("xyz")
|
||||
where d.p.ToLower().StartsWith("xyz")
|
||||
where d.p.ToLower().EndsWith("xyz")
|
||||
where d.p.ToUpper().Contains("xyz")
|
||||
where d.p.ToUpper().StartsWith("xyz")
|
||||
where d.p.ToUpper().EndsWith("xyz")
|
||||
where d.p.Trim().Contains("xyz")
|
||||
where d.p.Trim().StartsWith("xyz")
|
||||
where d.p.Trim().EndsWith("xyz")
|
||||
where d.p.TrimStart().Contains("xyz")
|
||||
where d.p.TrimStart().StartsWith("xyz")
|
||||
where d.p.TrimStart().EndsWith("xyz")
|
||||
where d.p.TrimEnd().Contains("xyz")
|
||||
where d.p.TrimEnd().StartsWith("xyz")
|
||||
where d.p.TrimEnd().EndsWith("xyz")
|
||||
where d.GetType() == typeof(T)
|
||||
where d is T
|
||||
|
||||
// you can use any combination of ToLower/ToUpper/Trim/TrimStart/TrimEnd
|
||||
// before Contains/StartsWith/EndsWith
|
||||
|
||||
In the 1.4 version of the C# driver the constant always had to appear on the
|
||||
right of a comparison operator. That restriction is lifted in 1.4.1 so now the
|
||||
following are equivalent:
|
||||
|
||||
where d.Height < 60
|
||||
where 60 > d.Height
|
||||
|
||||
Type of \<T\> in AsQueryable can now be deduced
|
||||
-----------------------------------------------
|
||||
|
||||
The type of \<T\> in the call to AsQueryable can now be deduced from the collection argument:
|
||||
|
||||
var collection = database.GetCollection<MyDocument>("mydocuments")
|
||||
var query = collection.AsQueryable(); // <T> is deduced to be MyDocument
|
Binary file not shown.
Binary file not shown.
|
@ -2305,6 +2305,25 @@
|
|||
</summary>
|
||||
<returns>The frozen serialization options.</returns>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.Serialization.TypeNameDiscriminator">
|
||||
<summary>
|
||||
Supports using type names as discriminators.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.TypeNameDiscriminator.GetActualType(System.String)">
|
||||
<summary>
|
||||
Resolves a type name discriminator.
|
||||
</summary>
|
||||
<param name="typeName">The type name.</param>
|
||||
<returns>The type if type type name can be resolved; otherwise, null.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.TypeNameDiscriminator.GetDiscriminator(System.Type)">
|
||||
<summary>
|
||||
Gets a type name to be used as a discriminator (like AssemblyQualifiedName but shortened for common DLLs).
|
||||
</summary>
|
||||
<param name="type">The type.</param>
|
||||
<returns>The type name.</returns>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.Serialization.IBsonSerializable">
|
||||
<summary>
|
||||
An interface implemented by classes that handle their own BSON serialization.
|
||||
|
@ -3697,9 +3716,9 @@
|
|||
<param name="info">The SerializationInfo.</param>
|
||||
<param name="context">The StreamingContext.</param>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.Serialization.IdGenerators.BsonObjectIdGenerator">
|
||||
<member name="T:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator">
|
||||
<summary>
|
||||
Represents an Id generator for BsonObjectIds.
|
||||
Represents an Id generator for Guids stored in BsonBinaryData values.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.Serialization.IIdGenerator">
|
||||
|
@ -3722,6 +3741,64 @@
|
|||
<param name="id">The Id.</param>
|
||||
<returns>True if the Id is empty.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.#ctor(MongoDB.Bson.GuidRepresentation)">
|
||||
<summary>
|
||||
Initializes a new instance of the BsonBinaryDataGuidGenerator class.
|
||||
</summary>
|
||||
<param name="guidRepresentation">The GuidRepresentation to use when generating new Id values.</param>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.GetInstance(MongoDB.Bson.GuidRepresentation)">
|
||||
<summary>
|
||||
Gets the instance of BsonBinaryDataGuidGenerator for a GuidRepresentation.
|
||||
</summary>
|
||||
<param name="guidRepresentation">The GuidRepresentation.</param>
|
||||
<returns>The instance of BsonBinaryDataGuidGenerator for a GuidRepresentation.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.GenerateId(System.Object,System.Object)">
|
||||
<summary>
|
||||
Generates an Id for a document.
|
||||
</summary>
|
||||
<param name="container">The container of the document (will be a MongoCollection when called from the C# driver). </param>
|
||||
<param name="document">The document.</param>
|
||||
<returns>An Id.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.IsEmpty(System.Object)">
|
||||
<summary>
|
||||
Tests whether an Id is empty.
|
||||
</summary>
|
||||
<param name="id">The Id.</param>
|
||||
<returns>True if the Id is empty.</returns>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.CSharpLegacyInstance">
|
||||
<summary>
|
||||
Gets an instance of BsonBinaryDataGuidGenerator for CSharpLegacy GuidRepresentation.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.JavaLegacyInstance">
|
||||
<summary>
|
||||
Gets an instance of BsonBinaryDataGuidGenerator for JavaLegacy GuidRepresentation.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.PythonLegacyInstance">
|
||||
<summary>
|
||||
Gets an instance of BsonBinaryDataGuidGenerator for PythonLegacy GuidRepresentation.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.StandardInstance">
|
||||
<summary>
|
||||
Gets an instance of BsonBinaryDataGuidGenerator for Standard GuidRepresentation.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.IdGenerators.BsonBinaryDataGuidGenerator.UnspecifedInstance">
|
||||
<summary>
|
||||
Gets an instance of BsonBinaryDataGuidGenerator for Unspecifed GuidRepresentation.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.Serialization.IdGenerators.BsonObjectIdGenerator">
|
||||
<summary>
|
||||
Represents an Id generator for BsonObjectIds.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.IdGenerators.BsonObjectIdGenerator.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the BsonObjectIdGenerator class.
|
||||
|
@ -4613,6 +4690,11 @@
|
|||
Gets or sets whether to check an update document (turns CheckElementNames on if first element name does *not* start with $).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.IO.BsonWriter.SerializationDepth">
|
||||
<summary>
|
||||
Gets the current serialization depth.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.IO.BsonWriter.Settings">
|
||||
<summary>
|
||||
Gets the settings of the writer.
|
||||
|
@ -5505,6 +5587,11 @@
|
|||
Gets whether the settings are frozen.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.IO.BsonWriterSettings.MaxSerializationDepth">
|
||||
<summary>
|
||||
Gets or sets the max serialization depth allowed (used to detect circular references).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.IO.BsonDocumentWriterSettings.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the BsonDocumentWriterSettings class.
|
||||
|
@ -6221,13 +6308,6 @@
|
|||
<param name="memberInfo">The member info.</param>
|
||||
<returns>The type of the member.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.BsonClassMap.GetTypeNameDiscriminator(System.Type)">
|
||||
<summary>
|
||||
Gets a loadable type name (like AssemblyQualifiedName but shortened when possible)
|
||||
</summary>
|
||||
<param name="type">The type.</param>
|
||||
<returns>The type name.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.BsonClassMap.IsClassMapRegistered(System.Type)">
|
||||
<summary>
|
||||
Checks whether a class map is registered for a type.
|
||||
|
@ -6296,10 +6376,10 @@
|
|||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.BsonClassMap.GetMemberMap(System.String)">
|
||||
<summary>
|
||||
Gets a member map.
|
||||
Gets a member map (only considers members declared in this class).
|
||||
</summary>
|
||||
<param name="memberName">The member name.</param>
|
||||
<returns>The member map.</returns>
|
||||
<returns>The member map (or null if the member was not found).</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.BsonClassMap.GetMemberMapForElement(System.String)">
|
||||
<summary>
|
||||
|
@ -6431,6 +6511,11 @@
|
|||
</summary>
|
||||
<param name="propertyName">The name of the property.</param>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.BsonClassMap.AllMemberMaps">
|
||||
<summary>
|
||||
Gets all the member maps (including maps for inherited members).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.BsonClassMap.BaseClassMap">
|
||||
<summary>
|
||||
Gets the base class map.
|
||||
|
@ -6446,6 +6531,11 @@
|
|||
Gets the conventions used with this class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.BsonClassMap.DeclaredMemberMaps">
|
||||
<summary>
|
||||
Gets the declared member maps (only for members declared in this class).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.BsonClassMap.Discriminator">
|
||||
<summary>
|
||||
Gets the discriminator.
|
||||
|
@ -6629,6 +6719,11 @@
|
|||
Specifies the element name and related options for a field or property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.Attributes.BsonElementAttribute.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the BsonElementAttribute class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.Serialization.Attributes.BsonElementAttribute.#ctor(System.String)">
|
||||
<summary>
|
||||
Initializes a new instance of the BsonElementAttribute class.
|
||||
|
@ -7462,6 +7557,78 @@
|
|||
Gets the external representation.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.DuplicateNameHandling">
|
||||
<summary>
|
||||
Represents how duplicate names should be handled.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MongoDB.Bson.DuplicateNameHandling.Overwrite">
|
||||
<summary>
|
||||
Overwrite original value with new value.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MongoDB.Bson.DuplicateNameHandling.Ignore">
|
||||
<summary>
|
||||
Ignore duplicate name and keep original value.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:MongoDB.Bson.DuplicateNameHandling.ThrowException">
|
||||
<summary>
|
||||
Throw an exception.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.BsonTypeMapperOptions">
|
||||
<summary>
|
||||
Represents options used by the BsonTypeMapper.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonTypeMapperOptions.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the BsonTypeMapperOptions class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonTypeMapperOptions.Clone">
|
||||
<summary>
|
||||
Clones the BsonTypeMapperOptions.
|
||||
</summary>
|
||||
<returns>The cloned BsonTypeMapperOptions.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonTypeMapperOptions.Freeze">
|
||||
<summary>
|
||||
Freezes the BsonTypeMapperOptions.
|
||||
</summary>
|
||||
<returns>The frozen BsonTypeMapperOptions.</returns>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.BsonTypeMapperOptions.Defaults">
|
||||
<summary>
|
||||
Gets or sets the default BsonTypeMapperOptions.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.BsonTypeMapperOptions.DuplicateNameHandling">
|
||||
<summary>
|
||||
Gets or sets how duplicate names should be handled.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.BsonTypeMapperOptions.IsFrozen">
|
||||
<summary>
|
||||
Gets whether the BsonTypeMapperOptions is frozen.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.BsonTypeMapperOptions.MapBsonArrayTo">
|
||||
<summary>
|
||||
Gets or sets the type that a BsonArray should be mapped to.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.BsonTypeMapperOptions.MapBsonDocumentTo">
|
||||
<summary>
|
||||
Gets or sets the type that a BsonDocument should be mapped to.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.BsonTypeMapperOptions.MapOldBinaryToByteArray">
|
||||
<summary>
|
||||
Gets or sets whether binary sub type OldBinary should be mapped to byte[] the way sub type Binary is.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.ObjectId">
|
||||
<summary>
|
||||
Represents an ObjectId (see also BsonObjectId).
|
||||
|
@ -7471,7 +7638,7 @@
|
|||
<summary>
|
||||
Initializes a new instance of the ObjectId class.
|
||||
</summary>
|
||||
<param name="bytes">The value.</param>
|
||||
<param name="bytes">The bytes.</param>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.ObjectId.#ctor(System.DateTime,System.Int32,System.Int16,System.Int32)">
|
||||
<summary>
|
||||
|
@ -10347,7 +10514,7 @@
|
|||
<summary>
|
||||
Initializes a new instance of the BsonObjectId class.
|
||||
</summary>
|
||||
<param name="value">The value.</param>
|
||||
<param name="bytes">The bytes.</param>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonObjectId.#ctor(System.DateTime,System.Int32,System.Int16,System.Int32)">
|
||||
<summary>
|
||||
|
@ -10709,7 +10876,7 @@
|
|||
<summary>
|
||||
Converts a byte array to a BsonBinaryData.
|
||||
</summary>
|
||||
<param name="value">A byte array.</param>
|
||||
<param name="bytes">A byte array.</param>
|
||||
<returns>A BsonBinaryData.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonBinaryData.op_Implicit(System.Guid)~MongoDB.Bson.BsonBinaryData">
|
||||
|
@ -12752,6 +12919,14 @@
|
|||
Gets the default value.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.Serialization.BsonMemberMap.IsReadOnly">
|
||||
<summary>
|
||||
Gets whether the member is readonly.
|
||||
</summary>
|
||||
<remarks>
|
||||
Readonly indicates that the member is written to the database, but not read from the database.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.Serialization.Serializers.DictionarySerializer">
|
||||
<summary>
|
||||
Represents a serializer for dictionaries.
|
||||
|
@ -12918,7 +13093,22 @@
|
|||
</summary>
|
||||
<param name="value">An object.</param>
|
||||
<param name="bsonType">The BsonType to map to.</param>
|
||||
<returns>A BsonValue.</returns>
|
||||
<returns>A BsonValue of the desired type (or BsonNull.Value if value is null and bsonType is Null).</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonTypeMapper.MapToDotNetValue(MongoDB.Bson.BsonValue)">
|
||||
<summary>
|
||||
Maps a BsonValue to a .NET value using the default BsonTypeMapperOptions.
|
||||
</summary>
|
||||
<param name="bsonValue">The BsonValue.</param>
|
||||
<returns>The mapped .NET value.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonTypeMapper.MapToDotNetValue(MongoDB.Bson.BsonValue,MongoDB.Bson.BsonTypeMapperOptions)">
|
||||
<summary>
|
||||
Maps a BsonValue to a .NET value.
|
||||
</summary>
|
||||
<param name="bsonValue">The BsonValue.</param>
|
||||
<param name="options">The BsonTypeMapperOptions.</param>
|
||||
<returns>The mapped .NET value.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Bson.BsonTypeMapper.RegisterCustomTypeMapper(System.Type,MongoDB.Bson.ICustomBsonTypeMapper)">
|
||||
<summary>
|
||||
|
@ -13243,6 +13433,11 @@
|
|||
Gets or sets the default max document size. The default is 4MiB.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Bson.BsonDefaults.MaxSerializationDepth">
|
||||
<summary>
|
||||
Gets or sets the default max serialization depth (used to detect circular references during serialization). The default is 100.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MongoDB.Bson.Serialization.Attributes.BsonIgnoreAttribute">
|
||||
<summary>
|
||||
Indicates that this field or property should be ignored when this class is serialized.
|
|
@ -152,6 +152,11 @@
|
|||
</summary>
|
||||
<param name="expression">The LINQ query expression tree.</param>
|
||||
</member>
|
||||
<member name="P:MongoDB.Driver.Linq.SelectQuery.OfType">
|
||||
<summary>
|
||||
Gets the final result type if an OfType query operator was used (otherwise null).
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Driver.Linq.SelectQuery.OrderBy">
|
||||
<summary>
|
||||
Gets a list of Expressions that defines the sort order (or null if not specified).
|
||||
|
@ -2695,6 +2700,37 @@
|
|||
</summary>
|
||||
<returns>An enumerator for the result objects.</returns>
|
||||
</member>
|
||||
<member name="T:MongoDB.Driver.Linq.ExpressionParameterFinder">
|
||||
<summary>
|
||||
A class that finds the first parameter in an expression.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.Linq.ExpressionParameterFinder.#ctor">
|
||||
<summary>
|
||||
Initializes a new instance of the ExpressionParameterFinder class.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.Linq.ExpressionParameterFinder.FindParameter(System.Linq.Expressions.Expression)">
|
||||
<summary>
|
||||
Finds the first parameter in an expression.
|
||||
</summary>
|
||||
<param name="node">The expression containing the parameter that should be found.</param>
|
||||
<returns>The first parameter found in the expression (or null if none was found).</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.Linq.ExpressionParameterFinder.Visit(System.Linq.Expressions.Expression)">
|
||||
<summary>
|
||||
Visits an Expression.
|
||||
</summary>
|
||||
<param name="node">The Expression.</param>
|
||||
<returns>The Expression (posibly modified).</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.Linq.ExpressionParameterFinder.VisitParameter(System.Linq.Expressions.ParameterExpression)">
|
||||
<summary>
|
||||
Remembers this parameter if it is the first parameter found.
|
||||
</summary>
|
||||
<param name="node">The ParameterExpression.</param>
|
||||
<returns>The ParameterExpression.</returns>
|
||||
</member>
|
||||
<member name="T:MongoDB.Driver.GridFS.MongoGridFSException">
|
||||
<summary>
|
||||
Represents a MongoDB GridFS exception.
|
||||
|
@ -4222,6 +4258,16 @@
|
|||
Gets or sets the safe mode.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Driver.GridFS.MongoGridFSSettings.UpdateMD5">
|
||||
<summary>
|
||||
Gets or sets whether to udpate the MD5 hash on the server when a file is uploaded or modified.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:MongoDB.Driver.GridFS.MongoGridFSSettings.VerifyMD5">
|
||||
<summary>
|
||||
Gets or sets whether to verify the MD5 hash when a file is uploaded or downloaded.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:MongoDB.Driver.Internal.MongoConnectionPool">
|
||||
<summary>
|
||||
Represents a pool of connections to a MongoDB server.
|
||||
|
@ -5566,6 +5612,14 @@
|
|||
</summary>
|
||||
<returns>An instance of DatabaseStatsResult.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.MongoDatabase.IsCollectionNameValid(System.String,System.String@)">
|
||||
<summary>
|
||||
Checks whether a given collection name is valid in this database.
|
||||
</summary>
|
||||
<param name="collectionName">The collection name.</param>
|
||||
<param name="message">An error message if the collection name is not valid.</param>
|
||||
<returns>True if the collection name is valid; otherwise, false.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.MongoDatabase.RemoveUser(MongoDB.Driver.MongoUser)">
|
||||
<summary>
|
||||
Removes a user from this database.
|
||||
|
@ -6485,6 +6539,14 @@
|
|||
<param name="collection">The name of the collection.</param>
|
||||
<returns>An instance of IQueryable{{T}} for a MongoCollection.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.Linq.LinqExtensionMethods.AsQueryable``1(MongoDB.Driver.MongoCollection{``0})">
|
||||
<summary>
|
||||
Returns an instance of IQueryable{{T}} for a MongoCollection.
|
||||
</summary>
|
||||
<typeparam name="T">The type of the returned documents.</typeparam>
|
||||
<param name="collection">The name of the collection.</param>
|
||||
<returns>An instance of IQueryable{{T}} for a MongoCollection.</returns>
|
||||
</member>
|
||||
<member name="T:MongoDB.Driver.Internal.BlockingQueue`1">
|
||||
<summary>
|
||||
Represents a thread-safe queue.
|
||||
|
@ -7579,6 +7641,14 @@
|
|||
<param name="adminCredentials">Credentials for the admin database.</param>
|
||||
<returns>The last error (<see cref="T:MongoDB.Driver.GetLastErrorResult"/>)</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.MongoServer.IsDatabaseNameValid(System.String,System.String@)">
|
||||
<summary>
|
||||
Checks whether a given database name is valid on this server.
|
||||
</summary>
|
||||
<param name="databaseName">The database name.</param>
|
||||
<param name="message">An error message if the database name is not valid.</param>
|
||||
<returns>True if the database name is valid; otherwise, false.</returns>
|
||||
</member>
|
||||
<member name="M:MongoDB.Driver.MongoServer.Ping">
|
||||
<summary>
|
||||
Checks whether the server is alive (throws an exception if not). If server is a replica set, pings all members one at a time.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,348 +0,0 @@
|
|||
C# Driver Version 1.4 Release Notes
|
||||
===================================
|
||||
|
||||
The major feature of this release is support for LINQ queries. Some of the other
|
||||
changes (e.g. new IBsonSerializer methods) are also in support of the new LINQ
|
||||
implementation.
|
||||
|
||||
File by file change logs are available at:
|
||||
|
||||
https://github.com/mongodb/mongo-csharp-driver/blob/master/Release%20Notes/Change%20Log%20v1.4-Bson.txt
|
||||
https://github.com/mongodb/mongo-csharp-driver/blob/master/Release%20Notes/Change%20Log%20v1.4-Driver.txt
|
||||
|
||||
These release notes describe the changes at a higher level, and omit describing
|
||||
some of the minor changes.
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
||||
There are some breaking changes in this release. Some of them are only breaking
|
||||
at the binary level and are easily taken care of by simply recompiling your
|
||||
application. Others require minor changes to your source code. Many of the
|
||||
breaking changes are in low level classes, and these won't affect most users,
|
||||
unless for example you are doing things like writing custom serializers.
|
||||
|
||||
Please read these release notes carefully before adopting the new 1.4 release
|
||||
of the C# driver to determine if any of the breaking changes affect you.
|
||||
|
||||
LINQ query support
|
||||
------------------
|
||||
|
||||
As stated previously, the major feature of this release is support for LINQ
|
||||
queries. These release notes don't describe the new LINQ support, for that
|
||||
please refer to the online LINQ tutorial at:
|
||||
|
||||
http://www.mongodb.org/display/DOCS/CSharp+Driver+LINQ+Tutorial
|
||||
|
||||
(Please note that the LINQ tutorial won't be available until several weeks
|
||||
after the 1.4 release has been shipped. Sorry.)
|
||||
|
||||
CLS compliance
|
||||
--------------
|
||||
|
||||
Both the MongoDB.Bson.dll and MongoDB.Driver.dll libraries have been marked
|
||||
as CLS compliant, which should make them more useful from other .NET languages.
|
||||
Most of the changes required to make the libraries CLS compliant are not even
|
||||
visible in the public interface.
|
||||
|
||||
Release builds
|
||||
--------------
|
||||
|
||||
Starting with the 1.4 version we are shipping Release builds of the DLLs.
|
||||
|
||||
Code formatting changes
|
||||
-----------------------
|
||||
|
||||
In response to popular demand the code base has been reformatted using the
|
||||
default Visual Studio C# code formatting settings. We have also adopted
|
||||
the convention of prefixing instance field names with a single "_" and static
|
||||
fields names with a double "__" (while this convention for static fields is
|
||||
not common it is very useful). One of the nice benefits of these conventions
|
||||
is that the drop down menu in Visual Studio that displays class members ends
|
||||
up grouping all static fields first, followed by instance fields, followed by
|
||||
the rest of the properties and methods.
|
||||
|
||||
BSON library changes
|
||||
====================
|
||||
|
||||
ArraySerializationOptions
|
||||
-------------------------
|
||||
|
||||
This new class allows you to specify serialization options for array-like
|
||||
members. Initially the only option available is to specify serialization
|
||||
options for the items of the array. When using attributes to specify
|
||||
serialization options any attributes that don't apply to the collection as a
|
||||
whole implictly apply to the items of the collection.
|
||||
|
||||
BsonDateTime is now a pure BSON DateTime value
|
||||
----------------------------------------------
|
||||
|
||||
In previous versions the BsonDateTime class stored its value twice in two
|
||||
different private fields: _millisecondsSinceEpoch (a long) and _value (a .NET
|
||||
DateTime). The idea was that you could store a .NET DateTime without losing any
|
||||
precision. However, that turns out to be confusing because as soon as you save
|
||||
the BsonDateTime value to the database and read it back you are going to lose
|
||||
precision anyway, so you might as well lose it right up front and not make
|
||||
false promises.
|
||||
|
||||
BsonDateTime also has two new helper methods: ToLocalTime and ToUniversalTime.
|
||||
These methods convert the BSON DateTime to either local or UTC .NET DateTime
|
||||
values. There are also new AsLocalTime and AsUniversalTime properties in
|
||||
BsonValues that can be used to convert BsonValues to .NET DateTime values (like
|
||||
all AsXyz properties in BsonValue they throw an InvalidCastException if the
|
||||
BsonValue is not actually a BsonDateTime).
|
||||
|
||||
BsonIgnoreExtraElements attribute
|
||||
---------------------------------
|
||||
|
||||
The BsonIgnoreExtraElements attribute has a new property called Inherited. If
|
||||
this property is set to true then all classes derived from this one will
|
||||
automatically inherit this setting, which makes it easy to set it for an
|
||||
entire class hierarchy at once.
|
||||
|
||||
BsonIgnoreIfDefault attribute
|
||||
-----------------------------
|
||||
|
||||
This new attribute allows you to specify that you want a field to be ignored
|
||||
during serialization if it is equal to the default value. This replaces the
|
||||
SerializeDefaultValue parameter of the BsonDefaultValue attribute. By making
|
||||
this a separate attribute you can specify that you want the default value
|
||||
ignored without having to specify the default value as well.
|
||||
|
||||
BsonReader: CurrentBsonType vs GetCurrentBsonType
|
||||
-------------------------------------------------
|
||||
|
||||
In previous versions the CurrentBsonType property had side effects. In general
|
||||
it is bad form for the get accessor of a property to have side effects, as even
|
||||
something as simple as looking at the value of the property in a debugger can
|
||||
have unintended consequences. Therefore, in the 1.4 release the CurrentBsonType
|
||||
property has no side effects. The previous behavior is now implemented in the
|
||||
GetCurrentBsonType method. While this is mostly an internal change, *if* you
|
||||
have written a custom serializer that used the CurrentBsonType property and
|
||||
were relying on its side effects you will have to change your custom serializer
|
||||
to call GetCurrentBsonType instead.
|
||||
|
||||
ConventionProfile new conventions
|
||||
---------------------------------
|
||||
|
||||
The ConventionProfile class has two new conventions: IgnoreIfDefaultConvention
|
||||
and SerializationOptionsConvention. Also, the SerializeDefaultValueConvention
|
||||
has been obsoleted in favor of the new IgnoreIfDefaultConvention.
|
||||
|
||||
DictionarySerializationOptions
|
||||
------------------------------
|
||||
|
||||
This class has a new property called ItemSerializationOptions that can be used
|
||||
to specify the options to use when serializing the value of the items in the
|
||||
dictionary. When using attributes to specify serialization options, any
|
||||
attributes that don't apply to the dictionary as a whole implicitly apply to
|
||||
the value of the items in the dictionary.
|
||||
|
||||
ExtraElements
|
||||
-------------
|
||||
|
||||
Previous versions of the C# driver allowed you to specify a field of the class
|
||||
to be used to store any extra elements encountered during deserialization.
|
||||
However, this field *had* to be of type BsonDocument, which meant introducing
|
||||
a dependency on the driver into your data model classes (which some developers
|
||||
don't want to do). You now have the additional option of declaring your
|
||||
ExtraElements field to be of type IDictionary\<string, object\> instead.
|
||||
|
||||
IBsonSerializationOptions
|
||||
-------------------------
|
||||
|
||||
The IBsonSerializationOptions has several new methods. ApplyAttribute is used
|
||||
during the AutoMap process to apply an attribute to some serialization options
|
||||
that are being built incrementally (starting from the default serialization
|
||||
options). This provides an extensible mechanism for applying new attributes to
|
||||
new serialization options classes. The Clone and Freeze methods are introduced
|
||||
to allow serialization options to be converted to read-only once initialization
|
||||
is complete to provide thread safety.
|
||||
|
||||
IBsonSerializer
|
||||
---------------
|
||||
|
||||
The IBsonSerializer has several new methods. GetDefaultSerializationOptions
|
||||
provides an initial set of serialization options that any serialization
|
||||
attributes found can be applied against. GetItemSerializationInfo provides
|
||||
serialization info about the items and applies only to serializers for
|
||||
collection-like classes. GetMemberSerializationInfo provides serialization
|
||||
info about members of a class. The last two are used in the implementation
|
||||
of LINQ queries.
|
||||
|
||||
Image/Bitmap serializers
|
||||
------------------------
|
||||
|
||||
New serializers have been provided for the Image abstract base class and the
|
||||
Bitmap class derived from it.
|
||||
|
||||
ISupportInitialize
|
||||
------------------
|
||||
|
||||
The ISupportInitialize interface defines two methods: BeginInit and EndInit.
|
||||
The BsonClassMapSerializer now checks whether the class being deserialized
|
||||
implements this interface, and if so, calls BeginInit just before it starts
|
||||
to deserialize a class, and EndInit just after it has finished. You can
|
||||
use this feature to do any pre- or post-processing.
|
||||
|
||||
ObjectId/BsonObjectId creation
|
||||
------------------------------
|
||||
|
||||
ObjectId (and BsonObjectId) have a new constructor that allows you to supply
|
||||
the timestamp as a .NET DateTime value and it will automatically be converted
|
||||
to seconds since the Unix Epoch. These new constructors are useful if you want
|
||||
to create artificial ObjectIds to use in range based ObjectId queries (in
|
||||
which case you will usually set the machine, pid and increment fields to zero).
|
||||
|
||||
There are also two new overloads of GenerateNewId that allow you to provide
|
||||
the desired timestamp as either an int or a .NET DateTime. These new overloads
|
||||
are useful if you need to create backdated ObjectIds. When generating backdated
|
||||
ObjectIds there is a slight risk that you might create an ObjectId that is
|
||||
not unique (but that risk is very small).
|
||||
|
||||
TimeSpanSerializationOptions
|
||||
----------------------------
|
||||
|
||||
You can now choose any of the following representations for a TimeSpan: string,
|
||||
double, Int32 or Int64. In addition, when using any of the numeric
|
||||
representations, you can use the Units property to choose the units that the
|
||||
numeric value is in (choose from: Ticks, Days, Hours, Minutes, Seconds,
|
||||
Milliseconds and Nanoseconds).
|
||||
|
||||
Driver changes
|
||||
==============
|
||||
|
||||
Authentication support improved
|
||||
-------------------------------
|
||||
|
||||
Operations that require admin credentials previously required you to set the
|
||||
DefaultCredentials of MongoServerSetttings to admin credentials. But that is
|
||||
undesirable because it provides the client code full access to all databases,
|
||||
essentially negating the benefit of using authentication in the first place.
|
||||
In the 1.4 release all operations that require admin credentials have a new
|
||||
overload where you can provide the needed credentials; you no longer have to
|
||||
set the DefaultCredentials. Another option is to store credentials for the
|
||||
admin database in the new MongoCredentialsStore.
|
||||
|
||||
Connection pool defaults changed
|
||||
--------------------------------
|
||||
|
||||
The default value of WaitQueueMultiple has been changed from 1.0 to 5.0 and the
|
||||
default value of WaitQueueTimeout has been changed from 0.5 seconds to 2
|
||||
minutes. These new values are taken from the Java driver, where they have
|
||||
reportedly been working well for users running under heavy loads. These new
|
||||
values mean that many more threads can be waiting for a longer time before a
|
||||
timeout exception is thrown.
|
||||
|
||||
Exceptions are no longer caught and rethrown when possible
|
||||
----------------------------------------------------------
|
||||
|
||||
Wherever possible exception handling code that used to use catch exceptions
|
||||
and rethrow them after processing them has been changed to roughly equivalent
|
||||
code that uses try/finally to accomplish the same objective. This is specially
|
||||
helpful if you are running the debugger set to stop whenever an exception is
|
||||
thrown.
|
||||
|
||||
IBsonSerializable semi-deprecated
|
||||
---------------------------------
|
||||
|
||||
The LINQ support relies heavily on the new methods added to IBsonSerializer.
|
||||
Because of this it is highly encouraged that *if* you have to handle your own
|
||||
serialization that you always opt to write an IBsonSerializer for your class
|
||||
instead of having it implement IBsonSerializable (see the notes for MongoDBRef
|
||||
and SystemProfileInfo for examples of where the driver itself has switched
|
||||
from IBsonSerializable to using a IBsonSerializer). IBsonSerializable still
|
||||
has a modest role to play in classes that just need to be serialized quickly
|
||||
and simply and for which we won't be writing LINQ queries (for example, the
|
||||
driver's Builders and Wrappers still use IBsonSerializable).
|
||||
|
||||
LINQ query support
|
||||
------------------
|
||||
|
||||
As mentioned earlier in the release notes more information about the new
|
||||
support for LINQ queries can be found in the forthcoming LINQ tutorial:
|
||||
|
||||
http://www.mongodb.org/display/DOCS/CSharp+Driver+LINQ+Tutorial
|
||||
|
||||
Locking issues
|
||||
--------------
|
||||
|
||||
A number of locking issues related to connection pooling have been resolved.
|
||||
These issues were particularly likely to occur if you had more threads than
|
||||
the maximum size of the connection pool and were using the connections heavily
|
||||
enough that the connection pool could be used up.
|
||||
|
||||
MongoCredentialsStore
|
||||
---------------------
|
||||
|
||||
You can now create a credentials store which contains credentials for multiple
|
||||
databases (the name of the database is the key and the credentials are the
|
||||
value). The credentials store must be set up (in the MongoServerSettings)
|
||||
before you call MongoServer.Create, so it is only intended for scenarios
|
||||
where you have a fixed set of credentials that aren't going to change at runtime.
|
||||
|
||||
MongoDBRef no longer implements IBsonSerializable
|
||||
-------------------------------------------------
|
||||
|
||||
MongoDBRef used to handle its own serialization by virtue of implementing
|
||||
IBsonSerializable. But the IBsonSerializable interface is not helpful when we
|
||||
try to add support for writing LINQ queries against components of a MongoDBRef.
|
||||
Instead, there is now a MongoDBRefSerializer which handles serialization of
|
||||
MongoDBRefs, as well as implementing GetMemberSerializationInfo which enables
|
||||
the LINQ implementation to support LINQ queries against MongoDBRefs.
|
||||
|
||||
MongoInsertOptions/MongoUpdateOptions constructor changed
|
||||
---------------------------------------------------------
|
||||
|
||||
The constructors for MongoInsertOptions and MongoUpdateOptions used to require
|
||||
that the collection be passed in as a parameter. The purpose was to allow
|
||||
the constructor to inherit some of the options from the collection settings.
|
||||
To the developer however, this was awkward, as it required providing the
|
||||
collection where it seemed to be redundant. By handling default values in a
|
||||
different way we no longer require the collection to be supplied to the
|
||||
constructors. The old constructors (that require the collection parameter) are
|
||||
still temporarily supported but have been marked as deprecated with a warning.
|
||||
|
||||
MongoServer Admin properties and methods removed
|
||||
------------------------------------------------
|
||||
|
||||
The following Admin properties and methods have been removed from MongoServer:
|
||||
AdminDatabase, GetAdminDatabase, RunAdminCommand, and RunAdminCommandAs. The
|
||||
reason for removing them is that many developers would never use them anyway,
|
||||
and adding new overloads for providing admin credentials would have resulted
|
||||
in even more of these rarely used properties and methods. If you were using
|
||||
any of these methods or properties they can easily be replaced with calls to
|
||||
methods of an instance of MongoDatabase (use one of the overloads of
|
||||
GetDatabase with "admin" as the database name to get a reference to the admin
|
||||
database).
|
||||
|
||||
RequestStart/RequestDone
|
||||
------------------------
|
||||
|
||||
Recall that the purpose of RequestStart is to tell the driver that a series of
|
||||
operations should all be done using the same connection (which in the case of a
|
||||
replica set also implies using the same member of the connection set). Which
|
||||
member of a replica set was chosen depended on the slaveOk parameter: a value
|
||||
of false meant that the primary had to be used, and a value of true meant that
|
||||
an arbitrary secondary could be used. A new overload of RequestStart now allows
|
||||
the caller to specify which member should be used, which can be very useful for
|
||||
implementing custom query routing algorithms or for querying specific members
|
||||
of a replica set. In general though, keep in mind that you should *not* be
|
||||
using RequestStart unless you have an unusual scenario which requires it.
|
||||
|
||||
SocketTimeout default changed
|
||||
-----------------------------
|
||||
|
||||
The default value for SocketTimeout has been changed from 30 seconds to 0,
|
||||
which is a special value meaning to use the operating system default value,
|
||||
which in turn is infinity. If you actually want a SocketTimeout you now
|
||||
have to set it yourself. The SocketTimeout is currently a server level setting,
|
||||
but most likely in a future release it will be possible to set it at other
|
||||
levels, including for individual operations.
|
||||
|
||||
SystemProfileInfo no longer implements IBsonSerializable
|
||||
--------------------------------------------------------
|
||||
|
||||
See the notes for MongoDBRef. SystemProfileInfo no longer implements
|
||||
IBsonSerializable for the same reasons, and there is a new
|
||||
SystemProfileInfoSerializer instead.
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue