private Type0CommandMessageSection <BsonDocument> CreateType0Section(ConnectionDescription connectionDescription) { var extraElements = new List <BsonElement>(); AddIfNotAlreadyAdded("$db", _databaseNamespace.DatabaseName); if (connectionDescription?.IsMasterResult.ServerType != ServerType.Standalone && _readPreference != null && _readPreference != ReadPreference.Primary) { var readPreferenceDocument = QueryHelper.CreateReadPreferenceDocument(_readPreference); AddIfNotAlreadyAdded("$readPreference", readPreferenceDocument); } if (_session.Id != null) { if (IsSessionAcknowledged()) { AddIfNotAlreadyAdded("lsid", _session.Id); } else { if (_session.IsImplicit) { // do not set sessionId if session is implicit and write is unacknowledged } else { throw new InvalidOperationException("Explicit session must not be used with unacknowledged writes."); } } } var snapshotReadConcernDocument = ReadConcernHelper.GetReadConcernForSnapshotSesssion(_session, connectionDescription); if (snapshotReadConcernDocument != null) { extraElements.Add(new BsonElement("readConcern", snapshotReadConcernDocument)); } if (_session.ClusterTime != null) { AddIfNotAlreadyAdded("$clusterTime", _session.ClusterTime); } #pragma warning disable 618 Action <BsonWriterSettings> writerSettingsConfigurator = null; if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2) { writerSettingsConfigurator = s => s.GuidRepresentation = GuidRepresentation.Unspecified; } #pragma warning restore 618 _session.AboutToSendCommand(); if (_session.IsInTransaction) { var transaction = _session.CurrentTransaction; AddIfNotAlreadyAdded("txnNumber", transaction.TransactionNumber); if (transaction.State == CoreTransactionState.Starting) { AddIfNotAlreadyAdded("startTransaction", true); var readConcern = ReadConcernHelper.GetReadConcernForFirstCommandInTransaction(_session, connectionDescription); if (readConcern != null) { AddIfNotAlreadyAdded("readConcern", readConcern); } } AddIfNotAlreadyAdded("autocommit", false); } if (_serverApi != null) { AddIfNotAlreadyAdded("apiVersion", _serverApi.Version.ToString()); if (_serverApi.Strict.HasValue) { AddIfNotAlreadyAdded("apiStrict", _serverApi.Strict.Value); } if (_serverApi.DeprecationErrors.HasValue) { AddIfNotAlreadyAdded("apiDeprecationErrors", _serverApi.DeprecationErrors.Value); } } var elementAppendingSerializer = new ElementAppendingSerializer <BsonDocument>(BsonDocumentSerializer.Instance, extraElements, writerSettingsConfigurator); return(new Type0CommandMessageSection <BsonDocument>(_command, elementAppendingSerializer)); void AddIfNotAlreadyAdded(string key, BsonValue value) { if (!_command.Contains(key)) { extraElements.Add(new BsonElement(key, value)); } } bool IsSessionAcknowledged() { if (_command.TryGetValue("writeConcern", out var writeConcernDocument)) { var writeConcern = WriteConcern.FromBsonDocument(writeConcernDocument.AsBsonDocument); return(writeConcern.IsAcknowledged); } else { return(true); } } }
public static List <BsonElement> _elements <TDocument>(this ElementAppendingSerializer <TDocument> instance) { var fieldInfo = typeof(ElementAppendingSerializer <TDocument>).GetField("_elements", BindingFlags.NonPublic | BindingFlags.Instance); return((List <BsonElement>)fieldInfo.GetValue(instance)); }
private BsonDocument WrapCommandForQueryMessage(BsonDocument command, ConnectionDescription connectionDescription, out bool messageContainsSessionId, out bool secondaryOk) { messageContainsSessionId = false; var extraElements = new List <BsonElement>(); if (_session.Id != null) { var areSessionsSupported = connectionDescription.IsMasterResult.LogicalSessionTimeout.HasValue; if (areSessionsSupported) { var lsid = new BsonElement("lsid", _session.Id); extraElements.Add(lsid); messageContainsSessionId = true; } else { if (!_session.IsImplicit) { throw new MongoClientException("Sessions are not supported."); } } } if (_serverApi != null) { extraElements.Add(new BsonElement("apiVersion", _serverApi.Version.ToString())); if (_serverApi.Strict.HasValue) { extraElements.Add(new BsonElement("apiStrict", _serverApi.Strict.Value)); } if (_serverApi.DeprecationErrors.HasValue) { extraElements.Add(new BsonElement("apiDeprecationErrors", _serverApi.DeprecationErrors.Value)); } } if (_session.ClusterTime != null) { var clusterTime = new BsonElement("$clusterTime", _session.ClusterTime); extraElements.Add(clusterTime); } #pragma warning disable 618 Action <BsonWriterSettings> writerSettingsConfigurator = null; if (BsonDefaults.GuidRepresentationMode == GuidRepresentationMode.V2) { writerSettingsConfigurator = s => s.GuidRepresentation = GuidRepresentation.Unspecified; } #pragma warning restore 618 var appendExtraElementsSerializer = new ElementAppendingSerializer <BsonDocument>(BsonDocumentSerializer.Instance, extraElements, writerSettingsConfigurator); var commandWithExtraElements = new BsonDocumentWrapper(command, appendExtraElementsSerializer); var serverType = connectionDescription != null ? connectionDescription.IsMasterResult.ServerType : ServerType.Unknown; var readPreferenceDocument = QueryHelper.CreateReadPreferenceDocument(serverType, _readPreference, out secondaryOk); var wrappedCommand = new BsonDocument { { "$query", commandWithExtraElements }, { "$readPreference", readPreferenceDocument, readPreferenceDocument != null } }; if (_additionalOptions != null) { wrappedCommand.Merge(_additionalOptions, overwriteExistingElements: false); } if (wrappedCommand.ElementCount == 1) { return(wrappedCommand["$query"].AsBsonDocument); } else { return(wrappedCommand); } }