コード例 #1
0
		public override void AfterPut(string key, RavenJObject document, RavenJObject metadata, System.Guid etag, TransactionInformation transactionInformation)
		{
			if (key.StartsWith("Raven/"))
			{
				return;
			}

			var entityName = metadata.Value<string>(Constants.RavenEntityName) + "/";

			var properties = metadata.Value<RavenJArray>(Constants.EnsureUniqueConstraints);

			if (properties == null || properties.Length <= 0) 
				return;

			var constraintMetaObject = new RavenJObject { { Constants.IsConstraintDocument, true } };
			constraintMetaObject.EnsureSnapshot();
			foreach (var property in properties)
			{
				var propName = ((RavenJValue)property).Value.ToString();
				var uniqueValue = document.Value<string>(propName);
				if(uniqueValue == null)
					continue;
				string documentName = "UniqueConstraints/" + entityName + propName + "/" +Util.EscapeUniqueValue(uniqueValue);
				Database.Put(
					documentName,
					null,
					RavenJObject.FromObject(new { RelatedId = key }),
					(RavenJObject)constraintMetaObject.CreateSnapshot(),
					transactionInformation);
			}
		}
コード例 #2
0
ファイル: WriteConflicts.cs プロジェクト: JPT123/ravendb
		public void WhileCreatingDocumentInTransactionTryingToWriteOutsideTransactionFail()
		{
			var transactionInformation = new TransactionInformation { Id = Guid.NewGuid(), Timeout = TimeSpan.FromMinutes(1) };
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'rahien'}"), new RavenJObject(), transactionInformation);
			Assert.Throws<ConcurrencyException>(
				() => db.Put("ayende", null, RavenJObject.Parse("{ayende:'oren'}"), new RavenJObject(), null));
		}
コード例 #3
0
ファイル: Deletes.cs プロジェクト: nhsevidence/ravendb
		public void DeletingDocumentInTransactionInNotVisibleBeforeCommit()
		{
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'oren'}"), new RavenJObject(), null);
			var transactionInformation = new TransactionInformation { Id = Guid.NewGuid(), Timeout = TimeSpan.FromMinutes(1) };
			db.Delete("ayende", null, transactionInformation);
			Assert.NotNull(db.Get("ayende", null));
		}
コード例 #4
0
        public void Should_save_put_to_tenant_database_if_tenant_database_is_reloaded_in_the_middle_of_the_put_transaction()
        {
			using (var server = GetNewServer(runInMemory: false))
            using (var store = new DocumentStore
            {
                Url = "http://*****:*****@"~\Databases\Mine" } }, });

                var tx1 = new TransactionInformation { Id = Guid.NewGuid().ToString() };
                var tx2 = new TransactionInformation { Id = Guid.NewGuid().ToString() };

                var tenantDatabaseDocument = store.DatabaseCommands.Get("Raven/Databases/" + TenantName);
                server.Database.Put("Raven/Databases/mydb", null, tenantDatabaseDocument.DataAsJson, tenantDatabaseDocument.Metadata, tx1);

                var tenantDb = GetDocumentDatabaseForTenant(server, TenantName);
                tenantDb.Put("Foo/1", null, new RavenJObject { { "Test", "123" } }, new RavenJObject(), tx2);

				server.Database.PrepareTransaction(tx1.Id);
                server.Database.Commit(tx1.Id);

                tenantDb = GetDocumentDatabaseForTenant(server, TenantName);
				tenantDb.PrepareTransaction(tx2.Id);
                tenantDb.Commit(tx2.Id);

                var fooDoc = tenantDb.Get("Foo/1", new TransactionInformation { Id = Guid.NewGuid().ToString() });
                Assert.NotNull(fooDoc);
            }
        }
コード例 #5
0
		public override void OnDelete(string key, TransactionInformation transactionInformation)
		{
			var document = Database.Get(key, null);
			if (document == null)
				return;
			Database.Delete(document.Metadata.Value<string>("Cascade-Delete"), null, null);
		}
コード例 #6
0
ファイル: Simple.cs プロジェクト: JPT123/ravendb
		public void PutNewDocInTxAndThenGetItBeforeCommitReturnsNull()
		{
			var transactionInformation = new TransactionInformation { Id = Guid.NewGuid(), Timeout = TimeSpan.FromMinutes(1) };
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'rahien'}"), new RavenJObject(), transactionInformation);

			Assert.True(db.Get("ayende", null).Metadata.Value<bool>(Constants.RavenDocumentDoesNotExists));
		}
コード例 #7
0
ファイル: Simple.cs プロジェクト: JPT123/ravendb
		public void PutNewDocInTxAndThenGetItBeforeCommitInSameTransactionReturnsNonNull()
		{
			var transactionInformation = new TransactionInformation { Id = Guid.NewGuid(), Timeout = TimeSpan.FromMinutes(1) };
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'rahien'}"), new RavenJObject(), transactionInformation);

			Assert.NotNull(db.Get("ayende", transactionInformation));
		}
コード例 #8
0
ファイル: AncestryPutTrigger.cs プロジェクト: nzdunic/ravendb
        public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            if (key.StartsWith("Raven/")) // we don't deal with system documents
                return;
            var doc = Database.Get(key, null);
			if (doc != null)
			{
				var history = doc.Metadata.Value<RavenJArray>(ReplicationConstants.RavenReplicationHistory) ?? new RavenJArray();
				metadata[ReplicationConstants.RavenReplicationHistory] = history;

				history.Add(new RavenJObject
				{
					{ReplicationConstants.RavenReplicationVersion, doc.Metadata[ReplicationConstants.RavenReplicationVersion]},
					{ReplicationConstants.RavenReplicationSource, doc.Metadata[ReplicationConstants.RavenReplicationSource]}

				});

				if (history.Length > ReplicationConstants.ChangeHistoryLength)
				{
					history.RemoveAt(0);
				}
			}
            metadata[ReplicationConstants.RavenReplicationVersion] = RavenJToken.FromObject(hiLo.NextId());
			metadata[ReplicationConstants.RavenReplicationSource] = RavenJToken.FromObject(Database.TransactionalStorage.Id);
        }
コード例 #9
0
ファイル: Transactions.cs プロジェクト: kblooie/ravendb
		public void AfterCommittingCanSeeChangesWithoutTx()
		{
			var transactionInformation = new TransactionInformation
			{
				Id = Guid.NewGuid(),
				Timeout = TimeSpan.FromDays(7)
			};

			using (var tx = NewTransactionalStorage())
			{
                tx.Batch(mutator => mutator.Transactions.AddDocumentInTransaction("Ayende", null, RavenJObject.FromObject(new { Name = "Rahien" }), new RavenJObject(),
					transactionInformation));

                tx.Batch(mutator => mutator.Transactions.CompleteTransaction(transactionInformation.Id, data =>
				{
					if (data.Delete)
					{
						RavenJObject metadata;
						mutator.Documents.DeleteDocument(data.Key, null, out metadata);
					}
					else
						mutator.Documents.AddDocument(data.Key, null, data.Data, data.Metadata);
				}));
                tx.Batch(viewer =>
					Assert.NotNull(viewer.Documents.DocumentByKey("Ayende", null)));
			}
		}
コード例 #10
0
		public override void OnDelete(string key, TransactionInformation transactionInformation)
		{
			if (key.StartsWith("Raven"))
				return;

			var doc = Database.Get(key, transactionInformation);

			if (doc == null)
				return;

			var metadata = doc.Metadata;

			var entityName = metadata.Value<string>(Constants.RavenEntityName) + "/";

			var uniqueConstraits = metadata.Value<RavenJArray>(Constants.EnsureUniqueConstraints);

			if (uniqueConstraits == null)
				return;

			foreach (var property in uniqueConstraits)
			{
				var checkKey = "UniqueConstraints/" + entityName  + property + "/" + doc.DataAsJson.Value<string>(property.Value<string>());

				Database.Delete(checkKey, null, transactionInformation);
			}
		}
コード例 #11
0
ファイル: WorkerRole.cs プロジェクト: gatepoet/DeiCon.Seznam
        private void SetupReplication()
        {
            if (RoleEnvironment.CurrentRoleInstance.Role.Instances.Count < 2)
            {
                var tr = new TransactionInformation();
                _database.Put("Debug", null,
                              JObject.Parse(@"{""Url"":""" +
                                            GetEndPointAddress(MyInstanceEndpoint.IPEndpoint) + @"""}"),
                              new JObject(), tr);

                _database.Commit(tr.Id);

            }
            else
            {
                var json = BuildDestinationsString();
                Trace.WriteLine(json);

                var tr = new TransactionInformation();
                _database.Delete("Raven/Replication/Destinations", null, tr);
                _database.Put("Raven/Replication/Destinations", null, JObject.Parse(json),
                              new JObject(), tr);
                _database.Commit(tr.Id);
            }
        }
 public override VetoResult AllowPut(string key,
                                     RavenJObject document,
                                     RavenJObject metadata,
                                     TransactionInformation transactionInformation)
 {
     return VetoResult.Allowed;
 }
コード例 #13
0
		public override void OnDelete(string key, TransactionInformation transactionInformation)
		{
			if (key.StartsWith("Raven"))
				return;

			var doc = Database.Get(key, transactionInformation);

			if (doc == null)
				return;

			var metadata = doc.Metadata;

			var entityName = metadata.Value<string>(Constants.RavenEntityName) + "/";

			var uniqueConstraits = metadata.Value<RavenJArray>(Constants.EnsureUniqueConstraints);

			if (uniqueConstraits == null)
				return;

			foreach (var property in uniqueConstraits)
			{
			    var constraint = Util.GetConstraint(property);
                var prefix = "UniqueConstraints/" + entityName + constraint.PropName+ "/"; // UniqueConstraints/EntityNamePropertyName/
                var prop = doc.DataAsJson[constraint.PropName];
				if (prop == null || prop.Type == JTokenType.Null)
					continue;
				var array = prop as RavenJArray;
				var checkKeys = array != null ? array.Select(p => p.Value<string>()) : new[] {prop.Value<string>()};

				foreach (var checkKey in checkKeys)
				{
					Database.Delete(prefix + Util.EscapeUniqueValue(checkKey, constraint.CaseInsensitive), null, transactionInformation);
				}
			}
		}
コード例 #14
0
 private TransactionInformation(TransactionInformation other)
 {
     this.local_id = other.local_id;
     this.dtcId = other.dtcId;
     this.creation_time = other.creation_time;
     this.status = other.status;
 }
コード例 #15
0
		private TransactionInformation (TransactionInformation other)
		{
			local_id = other.local_id;
			dtcId = other.dtcId;
			creation_time = other.creation_time;
			status = other.status;
		}
コード例 #16
0
ファイル: StorageHelper.cs プロジェクト: VirtueMe/ravendb
        public static void AssertNotModifiedByAnotherTransaction(TableStorage storage, ITransactionStorageActions transactionStorageActions, string key, Table.ReadResult readResult, TransactionInformation transactionInformation)
        {
            if (readResult == null)
                return;
            var txIdAsBytes = readResult.Key.Value<byte[]>("txId");
            if (txIdAsBytes == null)
                return;

            var txId = new Guid(txIdAsBytes);
            if (transactionInformation != null && transactionInformation.Id == txId)
            {
                return;
            }

            var existingTx = storage.Transactions.Read(new JObject { { "txId", txId.ToByteArray() } });
            if (existingTx == null)//probably a bug, ignoring this as not a real tx
                return;

            var timeout = existingTx.Key.Value<DateTime>("timeout");
            if (DateTime.UtcNow > timeout)
            {
                transactionStorageActions.RollbackTransaction(txId);
                return;
            }

            throw new ConcurrencyException("Document '" + key + "' is locked by transacton: " + txId);
        }
コード例 #17
0
		public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
		{
			if (key.StartsWith("Raven/"))
			{
				return;
			}

			var entityName = metadata.Value<string>(Constants.RavenEntityName) +"/";

			var properties = metadata.Value<RavenJArray>(Constants.EnsureUniqueConstraints);

			if (properties == null || properties.Length <= 0) 
				return;

			var oldDoc = Database.Get(key, transactionInformation);

			if (oldDoc == null)
			{
				return;
			}

			var oldJson = oldDoc.DataAsJson;

			foreach (var property in metadata.Value<RavenJArray>(Constants.EnsureUniqueConstraints))
			{
				var propName = ((RavenJValue)property).Value.ToString();

				// Handle Updates in the Constraint
				if (!oldJson.Value<string>(propName).Equals(document.Value<string>(propName)))
				{
					Database.Delete("UniqueConstraints/" + entityName + propName + "/" + oldJson.Value<string>(propName), null, transactionInformation);
				}
			}
		}
コード例 #18
0
		public override void AfterPut(string key, RavenJObject document, RavenJObject metadata, System.Guid etag, TransactionInformation transactionInformation)
		{
			if (key.StartsWith("Raven/"))
			{
				return;
			}

			var entityName = metadata.Value<string>(Constants.RavenEntityName) + "/";

			var properties = metadata.Value<RavenJArray>(Constants.EnsureUniqueConstraints);

			if (properties == null || properties.Count() <= 0) 
				return;

			var constraintMetaObject = new RavenJObject { { Constants.IsConstraintDocument, true } };
			foreach (var property in properties)
			{
				var propName = ((RavenJValue)property).Value.ToString();
				Database.Put(
					"UniqueConstraints/" + entityName + propName + "/" + document.Value<string>(propName),
					null,
					RavenJObject.FromObject(new { RelatedId = key }),
					constraintMetaObject,
					transactionInformation);
			}
		}
コード例 #19
0
        public override void OnDelete(string key, TransactionInformation transactionInformation)
        {
            if (CascadeDeleteContext.IsInCascadeDeleteContext)
                return;

            var document = Database.Get(key, transactionInformation);
            if (document == null)
                return;

            using (CascadeDeleteContext.Enter())
            {
                var documentsToDelete = document.Metadata.Value<JArray>(MetadataKeys.DocumentsToCascadeDelete);

                if (documentsToDelete != null)
                {
                    foreach (var documentToDelete in documentsToDelete)
                    {
                        var documentId = documentToDelete.Value<string>();
                        if (!CascadeDeleteContext.HasAlreadyDeletedDocument(documentId))
                        {
                            CascadeDeleteContext.AddDeletedDocument(documentId);
                            Database.Delete(documentId, null, transactionInformation);
                        }
                    }
                }

                var attachmentsToDelete = document.Metadata.Value<JArray>(MetadataKeys.AttachmentsToCascadeDelete);

                if (attachmentsToDelete != null)
                    foreach (var attachmentToDelete in attachmentsToDelete)
                        Database.DeleteStatic(attachmentToDelete.Value<string>(), null);
            }
        }
コード例 #20
0
ファイル: Plugins.cs プロジェクト: modulexcite/docs-8
			public virtual void OnPut(
				string key,
				RavenJObject document,
				RavenJObject metadata,
				TransactionInformation transactionInformation)
			{
			}
コード例 #21
0
ファイル: Transactions.cs プロジェクト: kblooie/ravendb
		public void CanModifyTxId()
		{
			var transactionInformation = new TransactionInformation
			{
				Id = Guid.NewGuid(),
				Timeout = TimeSpan.FromDays(7)
			};

			using (var tx = NewTransactionalStorage())
			{
                tx.Batch(mutator => mutator.Transactions.AddDocumentInTransaction("Ayende", null, RavenJObject.FromObject(new { Name = "Rahien" }), new RavenJObject(),
					transactionInformation));

				var txInfo2 = new TransactionInformation
				{
					Id = Guid.NewGuid(),
					Timeout = TimeSpan.FromDays(1)
				};

                tx.Batch(mutator => mutator.Transactions.ModifyTransactionId(transactionInformation.Id, txInfo2.Id, txInfo2.Timeout));


                tx.Batch(viewer =>
					Assert.NotNull(viewer.Documents.DocumentByKey("Ayende", txInfo2)));
			}
		}
コード例 #22
0
		public override void OnDelete(string key, TransactionInformation transactionInformation)
		{
			if (key.StartsWith("Raven"))
				return;

			var doc = Database.Get(key, transactionInformation);

			if (doc == null)
				return;

			var metadata = doc.Metadata;

			var entityName = metadata.Value<string>(Constants.RavenEntityName) + "/";

			var uniqueConstraits = metadata.Value<RavenJArray>(Constants.EnsureUniqueConstraints);

			if (uniqueConstraits == null)
				return;

			foreach (var property in uniqueConstraits)
			{
			    var constraint = Util.GetConstraint(property);
                var prefix = "UniqueConstraints/" + entityName + constraint.PropName+ "/"; // UniqueConstraints/EntityNamePropertyName/
                var prop = doc.DataAsJson[constraint.PropName];

			    string[] uniqueValues;
                if (!Util.TryGetUniqueValues(prop, out uniqueValues))
                    continue;

				foreach (var uniqueValue in uniqueValues)
				{
					Database.Delete(prefix + Util.EscapeUniqueValue(uniqueValue, constraint.CaseInsensitive), null, transactionInformation);
				}
			}
		}
コード例 #23
0
ファイル: Documents.cs プロジェクト: nathanpalmer/ravendb
		public JsonDocument DocumentByKey(string key, TransactionInformation transactionInformation)
		{
			byte[] data;
			JObject metadata;
			if (transactionInformation != null)
			{
				Api.JetSetCurrentIndex(session, DocumentsModifiedByTransactions, "by_key");
				Api.MakeKey(session, DocumentsModifiedByTransactions, key, Encoding.Unicode, MakeKeyGrbit.NewKey);
				if (Api.TrySeek(session, DocumentsModifiedByTransactions, SeekGrbit.SeekEQ))
				{
					var txId = Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["locked_by_transaction"]);
					if (new Guid(txId) == transactionInformation.Id)
					{
						if (Api.RetrieveColumnAsBoolean(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["delete_document"]) == true)
						{
							logger.DebugFormat("Document with key '{0}' was deleted in transaction: {1}", key, transactionInformation.Id);
							return null;
						}
						data = Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["data"]);

						metadata = Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["metadata"]).ToJObject();

						data = documentCodecs.Aggregate(data, (bytes, codec) => codec.Decode(key, metadata, bytes));

						logger.DebugFormat("Document with key '{0}' was found in transaction: {1}", key, transactionInformation.Id);
						var etag = new Guid(Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["etag"]));
						return new JsonDocument
						{
							DataAsJson = data.ToJObject(),
							Etag = etag,
							Key = Api.RetrieveColumnAsString(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["key"], Encoding.Unicode),
							Metadata = metadata
						};
					}
				}
			}

			Api.JetSetCurrentIndex(session, Documents, "by_key");
			Api.MakeKey(session, Documents, key, Encoding.Unicode, MakeKeyGrbit.NewKey);
			if (Api.TrySeek(session, Documents, SeekGrbit.SeekEQ) == false)
			{
				logger.DebugFormat("Document with key '{0}' was not found", key);
				return null;
			}
			data = Api.RetrieveColumn(session, Documents, tableColumnsCache.DocumentsColumns["data"]);
			metadata = Api.RetrieveColumn(session, Documents, tableColumnsCache.DocumentsColumns["metadata"]).ToJObject();

			data = documentCodecs.Aggregate(data, (bytes, codec) => codec.Decode(key, metadata, bytes));

			logger.DebugFormat("Document with key '{0}' was found", key);
			var existingEtag = new Guid(Api.RetrieveColumn(session, Documents, tableColumnsCache.DocumentsColumns["etag"]));
			return new JsonDocument
			{
				DataAsJson = data.ToJObject(),
				Etag = existingEtag,
				Key = Api.RetrieveColumnAsString(session, Documents, tableColumnsCache.DocumentsColumns["key"], Encoding.Unicode),
				Metadata = metadata
			};
		}
コード例 #24
0
 public override ReadVetoResult AllowRead(string key, JObject document, JObject metadata, ReadOperation operation, TransactionInformation transactionInformation)
 {
     if(key == null)
         return ReadVetoResult.Allowed;
     if (key.StartsWith("Raven/") && operation == ReadOperation.Query)
         return ReadVetoResult.Ignore; // hide Raven's documentation from queries
     return ReadVetoResult.Allowed;
 }
コード例 #25
0
 public override void OnDelete(string key, TransactionInformation transactionInformation)
 {
     var document = Database.Get(key, transactionInformation);
     if (document == null)
         return;
     deletedSource.Value = document.Metadata[ReplicationConstants.RavenReplicationSource];
     deletedVersion.Value = document.Metadata[ReplicationConstants.RavenReplicationVersion];
 }
コード例 #26
0
ファイル: WriteConflicts.cs プロジェクト: JPT123/ravendb
		public void WhileDocumentIsBeingUpdatedInTransactionCannotUpdateOutsideTransaction()
		{
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'oren'}"), new RavenJObject(), null);
			var transactionInformation = new TransactionInformation { Id = Guid.NewGuid(), Timeout = TimeSpan.FromMinutes(1) };
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'rahien'}"), new RavenJObject(), transactionInformation);
			Assert.Throws<ConcurrencyException>(
				() => db.Put("ayende", null, RavenJObject.Parse("{ayende:'oren'}"), new RavenJObject(), null));
		}
コード例 #27
0
ファイル: Simple.cs プロジェクト: JPT123/ravendb
		public void UpdateDocInTxAndThenGetItBeforeCommit()
		{
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'oren'}"), new RavenJObject(), null);
			var transactionInformation = new TransactionInformation { Id = Guid.NewGuid(), Timeout = TimeSpan.FromMinutes(1) };
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'rahien'}"), new RavenJObject(), transactionInformation);

			Assert.NotNull(db.Get("ayende", null));
			Assert.Equal("oren", db.Get("ayende", null).ToJson()["ayende"].Value<string>());
		}
コード例 #28
0
ファイル: Deletes.cs プロジェクト: cocytus/ravendb
		public void DeletingDocumentInTransactionInNotFoundInSameTransactionBeforeCommit()
		{
            EnsureDtcIsSupported(db);
			db.Documents.Put("ayende", null, RavenJObject.Parse("{ayende:'oren'}"), new RavenJObject(), null);
            var transactionInformation = new TransactionInformation { Id = Guid.NewGuid().ToString(), Timeout = TimeSpan.FromMinutes(1) };
			db.Documents.Delete("ayende", null, transactionInformation);
			Assert.Null(db.Documents.Get("ayende", transactionInformation));
	   
		}
コード例 #29
0
        public override VetoResult AllowPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
		{
			var name = document["name"];
			if(name != null && name.Value<string>().Any(char.IsUpper))
			{
				return VetoResult.Deny("Can't use upper case characters in the 'name' property");
			}
			return VetoResult.Allowed;
		}
コード例 #30
0
ファイル: Etags.cs プロジェクト: nberardi/ravendb
		public void WhenUsingTransactionWillFailIfDocumentEtagDoesNotMatch()
		{
			db.Put("ayende", null, RavenJObject.Parse("{ayende:'oren'}"), new RavenJObject(), null);
			var transactionInformation = new TransactionInformation { Id = Guid.NewGuid(), Timeout = TimeSpan.FromMinutes(1) };
			Assert.Throws<ConcurrencyException>(
				() =>
				db.Put("ayende", Guid.NewGuid(), RavenJObject.Parse("{ayende:'rahien'}"), new RavenJObject(),
					   transactionInformation));
		}
コード例 #31
0
ファイル: DocumentActions.cs プロジェクト: xinix00/ravendb
        public bool Delete(string key, Etag etag, TransactionInformation transactionInformation, out RavenJObject metadata, IEnumerable <string> participatingIds = null)
        {
            if (key == null)
            {
                throw new ArgumentNullException("key");
            }
            key = key.Trim();

            var deleted = false;

            if (Log.IsDebugEnabled)
            {
                Log.Debug("Delete a document with key: {0} and etag {1}", key, etag);
            }
            RavenJObject metadataVar = null;

            using (Database.DocumentLock.Lock())
            {
                TransactionalStorage.Batch(actions =>
                {
                    AssertDeleteOperationNotVetoed(key, transactionInformation);
                    if (transactionInformation == null)
                    {
                        Database.DeleteTriggers.Apply(trigger => trigger.OnDelete(key, null));

                        string collection = null;
                        Etag deletedETag;
                        if (actions.Documents.DeleteDocument(key, etag, out metadataVar, out deletedETag))
                        {
                            deleted = true;
                            actions.Indexing.RemoveAllDocumentReferencesFrom(key);
                            WorkContext.MarkDeleted(key);

                            Database.Indexes.CheckReferenceBecauseOfDocumentUpdate(key, actions, participatingIds);

                            collection = metadataVar.Value <string>(Constants.RavenEntityName);

                            DeleteDocumentFromIndexesForCollection(key, collection, actions);
                            if (deletedETag != null)
                            {
                                Database.Prefetcher.AfterDelete(key, deletedETag);
                            }
                            Database.DeleteTriggers.Apply(trigger => trigger.AfterDelete(key, null, metadataVar));
                        }

                        TransactionalStorage
                        .ExecuteImmediatelyOrRegisterForSynchronization(() =>
                        {
                            Database.DeleteTriggers.Apply(trigger => trigger.AfterCommit(key));
                            if (string.IsNullOrEmpty(collection) == false)
                            {
                                Database.LastCollectionEtags.Update(collection);
                            }

                            Database.Notifications.RaiseNotifications(new DocumentChangeNotification
                            {
                                Id             = key,
                                Type           = DocumentChangeTypes.Delete,
                                TypeName       = (metadataVar != null) ? metadataVar.Value <string>(Constants.RavenClrType) : null,
                                CollectionName = (metadataVar != null) ? metadataVar.Value <string>(Constants.RavenEntityName) : null
                            }, metadataVar);
                        });
                    }
                    else
                    {
                        var doc = actions.Documents.DocumentMetadataByKey(key);

                        Database.InFlightTransactionalState.DeleteDocumentInTransaction(transactionInformation, key,
                                                                                        etag,
                                                                                        doc == null ? Etag.Empty : doc.Etag,
                                                                                        UuidGenerator);
                        deleted = doc != null;
                    }

                    WorkContext.ShouldNotifyAboutWork(() => "DEL " + key);
                });

                metadata = metadataVar;
                return(deleted);
            }
        }
コード例 #32
0
ファイル: ReadTriggers.cs プロジェクト: philiphoy/ravendb
            public override ReadVetoResult AllowRead(string key, JObject metadata, ReadOperation operation, TransactionInformation transactionInformation)
            {
                if (operation == ReadOperation.Index)
                {
                    return(ReadVetoResult.Allowed);
                }
                var name = metadata["hidden"];

                if (name != null && name.Value <bool>())
                {
                    return(ReadVetoResult.Ignore);
                }
                return(ReadVetoResult.Allowed);
            }
コード例 #33
0
ファイル: Documents.cs プロジェクト: Jalalhejazi/ravendb
        public Guid AddDocumentInTransaction(string key, Guid?etag, JObject data, JObject metadata, TransactionInformation transactionInformation)
        {
            Api.JetSetCurrentIndex(session, Documents, "by_key");
            Api.MakeKey(session, Documents, key, Encoding.Unicode, MakeKeyGrbit.NewKey);
            var isUpdate = Api.TrySeek(session, Documents, SeekGrbit.SeekEQ);

            if (isUpdate)
            {
                EnsureNotLockedByTransaction(key, transactionInformation.Id);
                EnsureDocumentEtagMatchInTransaction(key, etag);
                using (var update = new Update(session, Documents, JET_prep.Replace))
                {
                    Api.SetColumn(session, Documents, tableColumnsCache.DocumentsColumns["locked_by_transaction"], transactionInformation.Id.ToByteArray());
                    update.Save();
                }
            }
            else
            {
                EnsureDocumentIsNotCreatedInAnotherTransaction(key, transactionInformation.Id);
            }
            EnsureTransactionExists(transactionInformation);
            Guid newEtag = DocumentDatabase.CreateSequentialUuid();

            Api.JetSetCurrentIndex(session, DocumentsModifiedByTransactions, "by_key");
            Api.MakeKey(session, DocumentsModifiedByTransactions, key, Encoding.Unicode, MakeKeyGrbit.NewKey);
            var isUpdateInTransaction = Api.TrySeek(session, DocumentsModifiedByTransactions, SeekGrbit.SeekEQ);

            var bytes = documentCodecs.Aggregate(Encoding.UTF8.GetBytes(data.ToString()), (current, codec) => codec.Encode(key, data, metadata, current));

            using (var update = new Update(session, DocumentsModifiedByTransactions, isUpdateInTransaction ? JET_prep.Replace : JET_prep.Insert))
            {
                Api.SetColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["key"], key, Encoding.Unicode);
                Api.SetColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["data"], bytes);
                Api.SetColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["etag"], newEtag.ToByteArray());
                Api.SetColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["metadata"], Encoding.UTF8.GetBytes(metadata.ToString()));
                Api.SetColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["delete_document"], false);
                Api.SetColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["locked_by_transaction"], transactionInformation.Id.ToByteArray());

                update.Save();
            }
            logger.DebugFormat("Inserted a new document with key '{0}', update: {1}, in transaction: {2}",
                               key, isUpdate, transactionInformation.Id);

            return(newEtag);
        }
コード例 #34
0
        public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            VersioningConfiguration versioningConfiguration;

            if (metadata.ContainsKey(Constants.RavenCreateVersion))
            {
                metadata.__ExternalState[Constants.RavenCreateVersion] = metadata[Constants.RavenCreateVersion];
                metadata.Remove(Constants.RavenCreateVersion);
            }

            if (TryGetVersioningConfiguration(key, metadata, out versioningConfiguration) == false)
            {
                return;
            }

            var revision = GetNextRevisionNumber(key);

            using (Database.DisableAllTriggersForCurrentThread())
            {
                RemoveOldRevisions(key, revision, versioningConfiguration, transactionInformation);
            }
            metadata.__ExternalState["Next-Revision"] = revision;

            metadata.__ExternalState["Parent-Revision"] = metadata.Value <string>(VersioningUtil.RavenDocumentRevision);

            metadata[VersioningUtil.RavenDocumentRevisionStatus] = RavenJToken.FromObject("Current");
            metadata[VersioningUtil.RavenDocumentRevision]       = RavenJToken.FromObject(revision);
        }
コード例 #35
0
        public override VetoResult AllowPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            if (Database.Name != null && Database.Name != Constants.SystemDatabase)
            {
                return(VetoResult.Allowed);
            }

            if (key.StartsWith(RavenDatabasesPrefix, StringComparison.InvariantCultureIgnoreCase) == false)
            {
                return(VetoResult.Allowed);
            }

            var tempPermission = metadata[Constants.AllowBundlesChange];

            if (tempPermission != null)
            {
                metadata.Remove(Constants.AllowBundlesChange);         // this is a temp marker so do not persist this medatada
            }
            var bundlesChangesAllowed = tempPermission != null &&
                                        tempPermission.Value <string>()
                                        .Equals("true", StringComparison.InvariantCultureIgnoreCase);

            if (bundlesChangesAllowed)
            {
                return(VetoResult.Allowed);
            }

            var existingDbDoc = Database.Documents.Get(key, transactionInformation);

            if (existingDbDoc == null)
            {
                return(VetoResult.Allowed);
            }

            var currentDbDocument = existingDbDoc.DataAsJson.JsonDeserialization <DatabaseDocument>();

            var    currentBundles = new List <string>();
            string value;

            if (currentDbDocument.Settings.TryGetValue(Constants.ActiveBundles, out value))
            {
                currentBundles = value.GetSemicolonSeparatedValues();
            }

            var newDbDocument = document.JsonDeserialization <DatabaseDocument>();
            var newBundles    = new List <string>();

            if (newDbDocument.Settings.TryGetValue(Constants.ActiveBundles, out value))
            {
                newBundles = value.GetSemicolonSeparatedValues();
            }


            if (currentBundles.Count == newBundles.Count)
            {
                return(VetoResult.Allowed);
            }

            if (currentBundles.Count == 0)
            {
                return(VetoResult.Allowed);
            }

            if (currentBundles.TrueForAll(x => newBundles.Contains(x)))
            {
                return(VetoResult.Allowed);
            }

            return(VetoResult.Deny(
                       "You should not change 'Raven/ActiveBundles' setting for a database. This setting should be set only once when a database is created. " +
                       "If you really need to override it you have to specify {\"" + Constants.AllowBundlesChange +
                       "\": true} in metadata of a database document every time when you send it." + Environment.NewLine +
                       "Current: " + string.Join("; ", currentBundles) + Environment.NewLine +
                       "New: " + string.Join("; '", newBundles)));
        }
コード例 #36
0
        private T DocumentByKeyInternal <T>(string key, TransactionInformation transactionInformation, Func <Tuple <MemoryStream, RavenJObject, int>, JsonDocumentMetadata, T> createResult)
            where T : class
        {
            RavenJObject metadata;

            var resultInTx = storage.DocumentsModifiedByTransactions.Read(new RavenJObject {
                { "key", key }
            });

            if (transactionInformation != null && resultInTx != null)
            {
                if (resultInTx.Key.Value <string>("txId") == transactionInformation.Id)
                {
                    if (resultInTx.Key.Value <bool>("deleted"))
                    {
                        return(null);
                    }

                    var txEtag   = Etag.Parse(resultInTx.Key.Value <byte[]>("etag"));
                    var resultTx = ReadMetadata(key, txEtag, resultInTx.Data, out metadata);
                    return(createResult(resultTx, new JsonDocumentMetadata
                    {
                        Key = resultInTx.Key.Value <string>("key"),
                        Etag = txEtag,
                        Metadata = metadata,
                        LastModified = resultInTx.Key.Value <DateTime>("modified"),
                    }));
                }
            }

            var readResult = storage.Documents.Read(new RavenJObject {
                { "key", key }
            });

            if (readResult == null)
            {
                if (resultInTx != null)
                {
                    return(createResult(Tuple.Create <MemoryStream, RavenJObject, int>(null, new RavenJObject(), 0), new JsonDocumentMetadata
                    {
                        Key = resultInTx.Key.Value <string>("key"),
                        Etag = Etag.Empty,
                        Metadata = new RavenJObject {
                            { Constants.RavenDocumentDoesNotExists, true }
                        },
                        NonAuthoritativeInformation = true,
                        LastModified = DateTime.MinValue
                    }));
                }
                return(null);
            }

            var etag   = Etag.Parse(readResult.Key.Value <byte[]>("etag"));
            var result = ReadMetadata(key, etag, readResult.Data, out metadata);

            return(createResult(result, new JsonDocumentMetadata
            {
                Key = readResult.Key.Value <string>("key"),
                Etag = etag,
                Metadata = metadata,
                LastModified = readResult.Key.Value <DateTime>("modified")
            }));
        }
コード例 #37
0
        public Guid AddDocumentInTransaction(string key, Guid?etag, RavenJObject data, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            var readResult = storage.Documents.Read(new RavenJObject {
                { "key", key }
            });

            if (readResult != null)             // update
            {
                StorageHelper.AssertNotModifiedByAnotherTransaction(storage, this, key, readResult, transactionInformation);
                AssertValidEtag(key, readResult, storage.DocumentsModifiedByTransactions.Read(new RavenJObject {
                    { "key", key }
                }), etag, "DELETE");

                var ravenJObject = ((RavenJObject)readResult.Key.CloneToken());
                ravenJObject["txId"] = transactionInformation.Id.ToByteArray();
                if (storage.Documents.UpdateKey(ravenJObject) == false)
                {
                    throw new ConcurrencyException("PUT attempted on document '" + key +
                                                   "' that is currently being modified by another transaction");
                }
            }
            else
            {
                readResult = storage.DocumentsModifiedByTransactions.Read(new RavenJObject {
                    { "key", key }
                });
                StorageHelper.AssertNotModifiedByAnotherTransaction(storage, this, key, readResult, transactionInformation);
            }

            storage.Transactions.UpdateKey(new RavenJObject
            {
                { "txId", transactionInformation.Id.ToByteArray() },
                { "timeout", SystemTime.UtcNow.Add(transactionInformation.Timeout) }
            });

            var ms = new MemoryStream();

            metadata.WriteTo(ms);
            using (var stream = documentCodecs.Aggregate <Lazy <AbstractDocumentCodec>, Stream>(ms, (memoryStream, codec) => codec.Value.Encode(key, data, metadata, memoryStream)))
            {
                data.WriteTo(stream);
                stream.Flush();
            }
            var newEtag = generator.CreateSequentialUuid(UuidType.DocumentTransactions);

            storage.DocumentsModifiedByTransactions.Put(new RavenJObject
            {
                { "key", key },
                { "etag", newEtag.ToByteArray() },
                { "modified", SystemTime.UtcNow },
                { "txId", transactionInformation.Id.ToByteArray() }
            }, ms.ToArray());

            return(newEtag);
        }
コード例 #38
0
        public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            if (string.IsNullOrEmpty(Database.Name) == false && Database.Name != Constants.SystemDatabase)
            {
                return;
            }

            if (key.StartsWith(Constants.Database.Prefix, StringComparison.OrdinalIgnoreCase) == false)
            {
                return;
            }

            RavenJObject settings;
            RavenJToken  value;

            if (document.TryGetValue("Settings", out value) == false)
            {
                document["Settings"] = settings = new RavenJObject();
            }
            else
            {
                settings = (RavenJObject)value;
            }

            EnsureQuotasBundleActivated(settings);
            EnsureVoronIsSetAsStorageEngineAndIsRunningInMemory(settings);
        }
コード例 #39
0
        public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            using (Database.DisableAllTriggersForCurrentThread())
            {
                metadata.Remove(Constants.RavenReplicationConflict);                // you can't put conflicts

                var oldVersion = Database.Documents.Get(key, transactionInformation);
                if (oldVersion == null)
                {
                    return;
                }
                if (oldVersion.Metadata[Constants.RavenReplicationConflict] == null)
                {
                    return;
                }

                var history = new RavenJArray();
                metadata[Constants.RavenReplicationHistory] = history;

                // this is a conflict document, holding document keys in the
                // values of the properties
                var conflicts = oldVersion.DataAsJson.Value <RavenJArray>("Conflicts");
                if (conflicts == null)
                {
                    return;
                }

                var list = new List <RavenJArray>
                {
                    new RavenJArray(ReplicationData.GetHistory(metadata))             // first item to interleave
                };

                foreach (var prop in conflicts)
                {
                    RavenJObject deletedMetadata;
                    Database.Documents.Delete(prop.Value <string>(), null, transactionInformation, out deletedMetadata);

                    if (deletedMetadata != null)
                    {
                        var conflictHistory = new RavenJArray(ReplicationData.GetHistory(deletedMetadata));
                        conflictHistory.Add(new RavenJObject
                        {
                            { Constants.RavenReplicationVersion, deletedMetadata[Constants.RavenReplicationVersion] },
                            { Constants.RavenReplicationSource, deletedMetadata[Constants.RavenReplicationSource] }
                        });
                        list.Add(conflictHistory);
                    }
                }


                int  index = 0;
                bool added = true;
                while (added) // interleave the history from all conflicts
                {
                    added = false;
                    foreach (var deletedMetadata in list)
                    {
                        // add the conflict history to the mix, so we make sure that we mark that we resolved the conflict
                        if (index < deletedMetadata.Length)
                        {
                            history.Add(deletedMetadata[index]);
                            added = true;
                        }
                    }
                    index++;
                }

                while (history.Length > Constants.ChangeHistoryLength)
                {
                    history.RemoveAt(0);
                }
            }
        }
コード例 #40
0
ファイル: MainController.cs プロジェクト: radtek/NBXplorer
        public async Task <IActionResult> GetTransactions(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DerivationStrategyModelBinder))]
            DerivationStrategyBase derivationScheme,
            [ModelBinder(BinderType = typeof(BitcoinAddressModelBinder))]
            BitcoinAddress address,
            [ModelBinder(BinderType = typeof(UInt256ModelBinding))]
            uint256 txId            = null,
            bool includeTransaction = true)
        {
            var trackedSource = GetTrackedSource(derivationScheme, address);

            if (trackedSource == null)
            {
                throw new ArgumentNullException(nameof(trackedSource));
            }
            TransactionInformation fetchedTransactionInfo = null;

            var network = GetNetwork(cryptoCode, false);
            var chain   = ChainProvider.GetChain(network);
            var repo    = RepositoryProvider.GetRepository(network);

            var response      = new GetTransactionsResponse();
            int currentHeight = chain.Height;

            response.Height = currentHeight;
            var txs = await GetAnnotatedTransactions(repo, chain, trackedSource, txId);

            foreach (var item in new[]
            {
                new
                {
                    TxSet = response.ConfirmedTransactions,
                    AnnotatedTx = txs.ConfirmedTransactions
                },
                new
                {
                    TxSet = response.UnconfirmedTransactions,
                    AnnotatedTx = txs.UnconfirmedTransactions
                },
                new
                {
                    TxSet = response.ReplacedTransactions,
                    AnnotatedTx = txs.ReplacedTransactions
                },
            })
            {
                foreach (var tx in item.AnnotatedTx)
                {
                    var txInfo = new TransactionInformation()
                    {
                        BlockHash     = tx.Height.HasValue ? tx.Record.BlockHash : null,
                        Height        = tx.Height,
                        TransactionId = tx.Record.TransactionHash,
                        Transaction   = includeTransaction ? tx.Record.Transaction : null,
                        Confirmations = tx.Height.HasValue ? currentHeight - tx.Height.Value + 1 : 0,
                        Timestamp     = tx.Record.FirstSeen,
                        Inputs        = tx.Record.SpentOutpoints.Select(o => txs.GetUTXO(o)).Where(o => o != null).ToList(),
                        Outputs       = tx.Record.GetReceivedOutputs().ToList()
                    };

                    if (txId == null || txId == txInfo.TransactionId)
                    {
                        item.TxSet.Transactions.Add(txInfo);
                    }
                    if (txId != null && txId == txInfo.TransactionId)
                    {
                        fetchedTransactionInfo = txInfo;
                    }

                    txInfo.BalanceChange = txInfo.Outputs.Select(o => o.Value).Sum() - txInfo.Inputs.Select(o => o.Value).Sum();
                }
                item.TxSet.Transactions.Reverse();                 // So the youngest transaction is generally first
            }



            if (txId == null)
            {
                return(Json(response));
            }
            else if (fetchedTransactionInfo == null)
            {
                return(NotFound());
            }
            else
            {
                return(Json(fetchedTransactionInfo));
            }
        }
コード例 #41
0
ファイル: Documents.cs プロジェクト: Jalalhejazi/ravendb
        public JsonDocument DocumentByKey(string key, TransactionInformation transactionInformation)
        {
            byte[]  data;
            JObject metadata;

            if (transactionInformation != null)
            {
                Api.JetSetCurrentIndex(session, DocumentsModifiedByTransactions, "by_key");
                Api.MakeKey(session, DocumentsModifiedByTransactions, key, Encoding.Unicode, MakeKeyGrbit.NewKey);
                if (Api.TrySeek(session, DocumentsModifiedByTransactions, SeekGrbit.SeekEQ))
                {
                    var txId = Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["locked_by_transaction"]);
                    if (new Guid(txId) == transactionInformation.Id)
                    {
                        if (Api.RetrieveColumnAsBoolean(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["delete_document"]) == true)
                        {
                            logger.DebugFormat("Document with key '{0}' was deleted in transaction: {1}", key, transactionInformation.Id);
                            return(null);
                        }
                        data = Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["data"]);

                        metadata = Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["metadata"]).ToJObject();

                        data = documentCodecs.Aggregate(data, (bytes, codec) => codec.Decode(key, metadata, bytes));

                        logger.DebugFormat("Document with key '{0}' was found in transaction: {1}", key, transactionInformation.Id);
                        var etag = new Guid(Api.RetrieveColumn(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["etag"]));
                        return(new JsonDocument
                        {
                            DataAsJson = data.ToJObject(),
                            Etag = etag,
                            Key = Api.RetrieveColumnAsString(session, DocumentsModifiedByTransactions, tableColumnsCache.DocumentsModifiedByTransactionsColumns["key"], Encoding.Unicode),
                            Metadata = metadata
                        });
                    }
                }
            }

            Api.JetSetCurrentIndex(session, Documents, "by_key");
            Api.MakeKey(session, Documents, key, Encoding.Unicode, MakeKeyGrbit.NewKey);
            if (Api.TrySeek(session, Documents, SeekGrbit.SeekEQ) == false)
            {
                logger.DebugFormat("Document with key '{0}' was not found", key);
                return(null);
            }
            data     = Api.RetrieveColumn(session, Documents, tableColumnsCache.DocumentsColumns["data"]);
            metadata = Api.RetrieveColumn(session, Documents, tableColumnsCache.DocumentsColumns["metadata"]).ToJObject();

            data = documentCodecs.Aggregate(data, (bytes, codec) => codec.Decode(key, metadata, bytes));

            logger.DebugFormat("Document with key '{0}' was found", key);
            var existingEtag = new Guid(Api.RetrieveColumn(session, Documents, tableColumnsCache.DocumentsColumns["etag"]));

            return(new JsonDocument
            {
                DataAsJson = data.ToJObject(),
                Etag = existingEtag,
                Key = Api.RetrieveColumnAsString(session, Documents, tableColumnsCache.DocumentsColumns["key"], Encoding.Unicode),
                Metadata = metadata
            });
        }
コード例 #42
0
 public JsonDocumentMetadata DocumentMetadataByKey(string key, TransactionInformation transactionInformation)
 {
     return(DocumentByKeyInternal(key, transactionInformation, (stream, metadata) => metadata));
 }
コード例 #43
0
 /// <summary>
 /// Initializes a new instance of the <see cref="RavenClientEnlistment"/> class.
 /// </summary>
 public RavenClientEnlistment(ITransactionalDocumentSession session, Action onTxComplete)
 {
     transaction       = Transaction.Current.TransactionInformation;
     this.session      = session;
     this.onTxComplete = onTxComplete;
 }
コード例 #44
0
        private PatchResultData ApplyPatchInternal(string docId, Etag etag,
                                                   TransactionInformation transactionInformation,
                                                   Func <JsonDocument, RavenJObject> patcher,
                                                   Func <RavenJObject> patcherIfMissing,
                                                   Func <IList <JsonDocument> > getDocsCreatedInPatch,
                                                   Func <RavenJObject> getDebugActions,
                                                   bool debugMode)
        {
            if (docId == null)
            {
                throw new ArgumentNullException("docId");
            }
            docId = docId.Trim();
            var result = new PatchResultData
            {
                PatchResult = PatchResult.Patched
            };

            bool   shouldRetry = false;
            int    retries     = 128;
            Random rand        = null;

            do
            {
                var doc = Database.Documents.Get(docId, transactionInformation);
                Log.Debug(() => string.Format("Preparing to apply patch on ({0}). Document found?: {1}.", docId, doc != null));

                if (etag != null && doc != null && doc.Etag != etag)
                {
                    Debug.Assert(doc.Etag != null);
                    Log.Debug(() => string.Format("Got concurrent exception while tried to patch the following document ID: {0}", docId));
                    throw new ConcurrencyException("Could not patch document '" + docId + "' because non current etag was used")
                          {
                              ActualETag   = doc.Etag,
                              ExpectedETag = etag,
                          };
                }
                var documentBeforePatching = doc != null?doc.ToJson().CloneToken() : null;

                var jsonDoc = (doc != null ? patcher(doc) : patcherIfMissing());

                if (jsonDoc == null)
                {
                    Log.Debug(() => string.Format("Preparing to apply patch on ({0}). DocumentDoesNotExists.", docId));
                    result.PatchResult = PatchResult.DocumentDoesNotExists;
                }
                else
                {
                    if (debugMode)
                    {
                        result.Document     = jsonDoc;
                        result.PatchResult  = PatchResult.Tested;
                        result.DebugActions = getDebugActions();
                    }
                    else
                    {
                        try
                        {
                            var notModified = false;

                            if (doc == null)
                            {
                                Database.Documents.Put(docId, null, jsonDoc, jsonDoc.Value <RavenJObject>(Constants.Metadata), transactionInformation);
                            }
                            else
                            {
                                if (IsNotModified(jsonDoc.CloneToken(), documentBeforePatching))
                                {
                                    notModified = true;
                                }
                                else
                                {
                                    Database.Documents.Put(doc.Key, (doc.Etag), jsonDoc, jsonDoc.Value <RavenJObject>(Constants.Metadata), transactionInformation);
                                }
                            }

                            var docsCreatedInPatch = getDocsCreatedInPatch();
                            if (docsCreatedInPatch != null && docsCreatedInPatch.Count > 0)
                            {
                                foreach (var docFromPatch in docsCreatedInPatch)
                                {
                                    Database.Documents.Put(docFromPatch.Key, docFromPatch.Etag, docFromPatch.DataAsJson,
                                                           docFromPatch.Metadata, transactionInformation);
                                }
                            }
                            shouldRetry        = false;
                            result.PatchResult = notModified ? PatchResult.NotModified : PatchResult.Patched;
                        }
                        catch (ConcurrencyException)
                        {
                            if (TransactionalStorage.IsAlreadyInBatch)
                            {
                                throw;
                            }
                            if (retries-- > 0)
                            {
                                shouldRetry = true;
                                if (rand == null)
                                {
                                    rand = new Random();
                                }
                                Thread.Sleep(rand.Next(5, Math.Max(retries * 2, 10)));
                                continue;
                            }

                            throw;
                        }
                    }
                }

                if (shouldRetry == false)
                {
                    WorkContext.ShouldNotifyAboutWork(() => "PATCH " + docId);
                }
            } while (shouldRetry);

            return(result);
        }
コード例 #45
0
        public override void AfterPut(string key, RavenJObject document, RavenJObject metadata, Etag etag, TransactionInformation transactionInformation)
        {
            VersioningConfiguration versioningConfiguration;

            if (TryGetVersioningConfiguration(key, metadata, out versioningConfiguration) == false)
            {
                return;
            }

            using (Database.DisableAllTriggersForCurrentThread())
            {
                var copyMetadata = new RavenJObject(metadata);
                copyMetadata[VersioningUtil.RavenDocumentRevisionStatus] = RavenJToken.FromObject("Historical");
                copyMetadata[Constants.RavenReadOnly] = true;
                copyMetadata.Remove(VersioningUtil.RavenDocumentRevision);
                object parentRevision;
                metadata.__ExternalState.TryGetValue("Parent-Revision", out parentRevision);
                if (parentRevision != null)
                {
                    copyMetadata[VersioningUtil.RavenDocumentParentRevision] = key + "/revisions/" + parentRevision;
                }

                object value;
                metadata.__ExternalState.TryGetValue("Next-Revision", out value);
                Database.Documents.Put(key + "/revisions/" + value, null, (RavenJObject)document.CreateSnapshot(), copyMetadata,
                                       transactionInformation);
            }
        }
コード例 #46
0
ファイル: AuditPutTrigger.cs プロジェクト: JontyMC/ravendb
 public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
 {
     document["created_at"] = new RavenJValue(new DateTime(2000, 1, 1, 0, 0, 0, DateTimeKind.Utc));
 }
コード例 #47
0
        public override VetoResult AllowPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            var jsonDocument = Database.Documents.Get(key, transactionInformation);

            if (jsonDocument == null)
            {
                return(VetoResult.Allowed);
            }

            if (Database.ChangesToRevisionsAllowed() == false &&
                jsonDocument.Metadata.Value <string>(VersioningUtil.RavenDocumentRevisionStatus) == "Historical" &&
                Database.IsVersioningActive(metadata))
            {
                return(VetoResult.Deny("Modifying a historical revision is not allowed"));
            }

            return(VetoResult.Allowed);
        }
コード例 #48
0
ファイル: ReadTriggers.cs プロジェクト: philiphoy/ravendb
            public override void OnRead(string key, JObject document, JObject metadata, ReadOperation operation, TransactionInformation transactionInformation)
            {
                var name = document.Property("name");

                if (name != null)
                {
                    name.Value = new JValue(name.Value.Value <string>().ToUpper());
                }
            }
コード例 #49
0
ファイル: AuditPutTrigger.cs プロジェクト: JontyMC/ravendb
 public override VetoResult AllowPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
 {
     return(VetoResult.Allowed);
 }
コード例 #50
0
        private Etag AssertValidEtag(string key, Etag etag, string op, TransactionInformation transactionInformation)
        {
            var readResult = storage.Documents.Read(new RavenJObject {
                { "key", key }
            });

            if (readResult != null)
            {
                var existingEtag = Etag.Parse(readResult.Key.Value <byte[]>("etag"));

                if (etag != null)
                {
                    Etag next;
                    while (etagTouches.TryGetValue(etag, out next))
                    {
                        etag = next;
                    }

                    if (existingEtag != etag)
                    {
                        if (etag == Etag.Empty)
                        {
                            RavenJObject metadata;
                            ReadMetadata(key, existingEtag, readResult.Data, out metadata);
                            if (metadata.ContainsKey(Constants.RavenDeleteMarker) && metadata.Value <bool>(Constants.RavenDeleteMarker))
                            {
                                return(existingEtag);
                            }
                        }

                        throw new ConcurrencyException(op + " attempted on document '" + key +
                                                       "' using a non current etag")
                              {
                                  ActualETag   = existingEtag,
                                  ExpectedETag = etag
                              };
                    }
                }
                return(existingEtag);
            }

            if (etag != null && etag != Etag.Empty)             // expected something to be there.
            {
                throw new ConcurrencyException("PUT attempted on document '" + key +
                                               "' using a non current etag (document deleted)")
                      {
                          ExpectedETag = etag
                      }
            }
            ;

            readResult = storage.DocumentsModifiedByTransactions.Read(new RavenJObject {
                { "key", key }
            });

            if (readResult == null)
            {
                return(null);
            }

            return(Etag.Parse(readResult.Key.Value <byte[]>("etag")));
        }
    }
コード例 #51
0
        private void RemoveOldRevisions(string key, long revision, VersioningConfiguration versioningConfiguration, TransactionInformation transactionInformation)
        {
            long latestValidRevision = revision - versioningConfiguration.MaxRevisions;

            if (latestValidRevision <= 0)
            {
                return;
            }

            Database.Documents.Delete(string.Format("{0}/revisions/{1}", key, latestValidRevision), null, transactionInformation);
        }
コード例 #52
0
        public async Task <GetTransactionsResponse> GetTransactions(
            string cryptoCode,
            [ModelBinder(BinderType = typeof(DestinationModelBinder))]
            DerivationStrategyBase extPubKey,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> unconfirmedBookmarks = null,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> confirmedBookmarks = null,
            [ModelBinder(BinderType = typeof(BookmarksModelBinding))]
            HashSet <Bookmark> replacedBookmarks = null,
            bool includeTransaction = true,
            bool longPolling        = false)
        {
            if (extPubKey == null)
            {
                throw new ArgumentNullException(nameof(extPubKey));
            }
            GetTransactionsResponse response = null;

            using (CancellationTokenSource cts = new CancellationTokenSource())
            {
                if (longPolling)
                {
                    cts.CancelAfter(LongPollTimeout);
                }
                var network = GetNetwork(cryptoCode, false);
                var chain   = ChainProvider.GetChain(network);
                var repo    = RepositoryProvider.GetRepository(network);

                while (true)
                {
                    response = new GetTransactionsResponse();
                    int currentHeight = chain.Height;
                    response.Height = currentHeight;
                    var txs = GetAnnotatedTransactions(repo, chain, extPubKey);
                    foreach (var item in new[]
                    {
                        new
                        {
                            TxSet = response.ConfirmedTransactions,
                            KnownBookmarks = confirmedBookmarks ?? new HashSet <Bookmark>(),
                            AnnotatedTx = txs.ConfirmedTransactions
                        },
                        new
                        {
                            TxSet = response.UnconfirmedTransactions,
                            KnownBookmarks = unconfirmedBookmarks ?? new HashSet <Bookmark>(),
                            AnnotatedTx = txs.UnconfirmedTransactions
                        },
                        new
                        {
                            TxSet = response.ReplacedTransactions,
                            KnownBookmarks = replacedBookmarks ?? new HashSet <Bookmark>(),
                            AnnotatedTx = txs.ReplacedTransactions
                        },
                    })
                    {
                        item.TxSet.Bookmark      = Bookmark.Start;
                        item.TxSet.KnownBookmark = item.KnownBookmarks.Contains(Bookmark.Start) ? Bookmark.Start : null;

                        BookmarkProcessor processor = new BookmarkProcessor(32 + 32 + 25);
                        foreach (var tx in item.AnnotatedTx.Values)
                        {
                            processor.PushNew();
                            processor.AddData(tx.Record.Transaction.GetHash());
                            processor.AddData(tx.Record.BlockHash ?? uint256.Zero);
                            processor.UpdateBookmark();

                            var txInfo = new TransactionInformation()
                            {
                                BlockHash     = tx.Record.BlockHash,
                                Height        = tx.Record.BlockHash == null ? null : tx.Height,
                                TransactionId = tx.Record.Transaction.GetHash(),
                                Transaction   = includeTransaction ? tx.Record.Transaction : null,
                                Confirmations = tx.Record.BlockHash == null ? 0 : currentHeight - tx.Height.Value + 1,
                                Timestamp     = txs.GetByTxId(tx.Record.Transaction.GetHash()).Select(t => t.Record.FirstSeen).First(),
                                Inputs        = ToMatch(txs, tx.Record.Transaction.Inputs.Select(o => txs.GetUTXO(o.PrevOut)).ToList(), extPubKey, tx.Record.TransactionMatch.Inputs),
                                Outputs       = ToMatch(txs, tx.Record.Transaction.Outputs, extPubKey, tx.Record.TransactionMatch.Outputs)
                            };

                            item.TxSet.Transactions.Add(txInfo);

                            txInfo.BalanceChange = txInfo.Outputs.Select(o => o.Value).Sum() - txInfo.Inputs.Select(o => o.Value).Sum();

                            item.TxSet.Bookmark = processor.CurrentBookmark;
                            if (item.KnownBookmarks.Contains(processor.CurrentBookmark))
                            {
                                item.TxSet.KnownBookmark = processor.CurrentBookmark;
                                item.TxSet.Transactions.Clear();
                            }
                        }
                    }

                    if (!longPolling || response.HasChanges())
                    {
                        break;
                    }
                    if (!await WaitingTransaction(extPubKey, cts.Token))
                    {
                        break;
                    }
                }
            }
            return(response);
        }
コード例 #53
0
ファイル: ReadTriggers.cs プロジェクト: philiphoy/ravendb
            public override ReadVetoResult AllowRead(string key, JObject metadata, ReadOperation operation, TransactionInformation transactionInformation)
            {
                if (operation == ReadOperation.Index)
                {
                    return(ReadVetoResult.Allowed);
                }
                var name = metadata["name"];

                if (name != null && name.Value <string>().Any(char.IsUpper))
                {
                    return(ReadVetoResult.Deny("Upper case characters in the 'name' property means the document is a secret!"));
                }
                return(ReadVetoResult.Allowed);
            }
コード例 #54
0
 public override VetoResult AllowPut(string key, RavenJObject document, RavenJObject metadata,
                                     TransactionInformation transactionInformation)
 {
     return(SizeQuotaConfiguration.GetConfiguration(Database).AllowPut());
 }
コード例 #55
0
        private Guid?AssertValidEtag(string key, Guid?etag, string op, TransactionInformation transactionInformation)
        {
            var readResult = storage.Documents.Read(new RavenJObject {
                { "key", key }
            });

            if (readResult != null)
            {
                StorageHelper.AssertNotModifiedByAnotherTransaction(storage, transactionStorageActions, key, readResult, transactionInformation);
                var existingEtag = new Guid(readResult.Key.Value <byte[]>("etag"));

                if (etag != null)
                {
                    if (existingEtag != etag)
                    {
                        if (etag.Value == Guid.Empty)
                        {
                            RavenJObject metadata;
                            ReadMetadata(key, existingEtag, readResult.Data, out metadata);
                            if (metadata.ContainsKey(Constants.RavenDeleteMarker) && metadata.Value <bool>(Constants.RavenDeleteMarker))
                            {
                                return(existingEtag);
                            }
                        }

                        throw new ConcurrencyException(op + " attempted on document '" + key +
                                                       "' using a non current etag")
                              {
                                  ActualETag   = etag.Value,
                                  ExpectedETag = existingEtag,
                                  Key          = key
                              };
                    }
                }
                return(existingEtag);
            }

            if (etag != null && etag != Guid.Empty)             // expected something to be there.
            {
                throw new ConcurrencyException("PUT attempted on document '" + key +
                                               "' using a non current etag (document deleted)")
                      {
                          ExpectedETag = etag.Value,
                          Key          = key
                      }
            }
            ;

            readResult = storage.DocumentsModifiedByTransactions.Read(new RavenJObject {
                { "key", key }
            });
            StorageHelper.AssertNotModifiedByAnotherTransaction(storage, transactionStorageActions, key, readResult, transactionInformation);

            if (readResult == null)
            {
                return(null);
            }

            return(new Guid(readResult.Key.Value <byte[]>("etag")));
        }
    }
コード例 #56
0
ファイル: AuditTrigger.cs プロジェクト: xinix00/ravendb
        public override void OnPut(string key, RavenJObject jsonReplicationDocument, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            if (AuditContext.IsInAuditContext)
            {
                return;
            }

            using (AuditContext.Enter())
            {
                if (metadata.Value <string>("Raven-Entity-Name") == "People")
                {
                    if (metadata["CreatedByPersonId"] == null)
                    {
                        metadata["CreatedByPersonId"] = CurrentOperationContext.Headers.Value.Value["CurrentUserPersonId"];
                        metadata["CreatedDate"]       = CreatedAtDateTime;
                    }
                    else
                    {
                        metadata["LastUpdatedPersonId"] = CurrentOperationContext.Headers.Value.Value["CurrentUserPersonId"];
                        metadata["LastUpdatedDate"]     = CreatedAtDateTime;
                    }
                }
            }
        }
コード例 #57
0
        private JsonDocument ExecuteReadTriggersOnRead(JsonDocument resultingDocument, TransactionInformation transactionInformation, ReadOperation operation)
        {
            if (resultingDocument == null)
            {
                return(null);
            }

            triggers.Apply(
                trigger =>
                trigger.OnRead(resultingDocument.Key, resultingDocument.DataAsJson, resultingDocument.Metadata, operation,
                               transactionInformation));

            return(resultingDocument);
        }
コード例 #58
0
 public JsonDocument ExecuteReadTriggers(JsonDocument document, TransactionInformation transactionInformation, ReadOperation operation)
 {
     return(ExecuteReadTriggersOnRead(ProcessReadVetoes(document, transactionInformation, operation),
                                      transactionInformation, operation));
 }
コード例 #59
0
 public override void OnPut(string key, RavenJObject jsonReplicationDocument, RavenJObject metadata, TransactionInformation transactionInformation)
 {
     Hello = CurrentOperationContext.Headers.Value.Value["Hello"];
     base.OnPut(key, jsonReplicationDocument, metadata, transactionInformation);
 }
コード例 #60
0
        public override void OnPut(string key, RavenJObject document, RavenJObject metadata, TransactionInformation transactionInformation)
        {
            if (key.StartsWith("Raven/", StringComparison.OrdinalIgnoreCase) &&             // we don't deal with system documents
                key.StartsWith("Raven/Hilo/", StringComparison.OrdinalIgnoreCase) == false) // except for hilos
            {
                return;
            }
            using (Database.DisableAllTriggersForCurrentThread())
            {
                var documentMetadata = GetDocumentMetadata(key);
                if (documentMetadata != null)
                {
                    RavenJArray history = new RavenJArray(ReplicationData.GetHistory(documentMetadata));
                    metadata[Constants.RavenReplicationHistory] = history;

                    if (documentMetadata.ContainsKey(Constants.RavenReplicationVersion) &&
                        documentMetadata.ContainsKey(Constants.RavenReplicationSource))
                    {
                        history.Add(new RavenJObject
                        {
                            { Constants.RavenReplicationVersion, documentMetadata[Constants.RavenReplicationVersion] },
                            { Constants.RavenReplicationSource, documentMetadata[Constants.RavenReplicationSource] }
                        });
                    }

                    while (history.Length > Constants.ChangeHistoryLength)
                    {
                        history.RemoveAt(0);
                    }
                }

                metadata[Constants.RavenReplicationVersion] = RavenJToken.FromObject(HiLo.NextId());
                metadata[Constants.RavenReplicationSource]  = RavenJToken.FromObject(Database.TransactionalStorage.Id);
            }
        }