Exemplo n.º 1
0
        /// <summary>
        /// Creates the put entity command.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="documentMetadata">The document metadata.</param>
        /// <returns></returns>
        protected ICommandData CreatePutEntityCommand(object entity, DocumentMetadata documentMetadata)
        {
            string id;

            if (GenerateEntityIdOnTheClient.TryGetIdFromInstance(entity, out id) &&
                documentMetadata.Key != null &&
                documentMetadata.Key.Equals(id, StringComparison.InvariantCultureIgnoreCase) == false)
            {
                throw new InvalidOperationException("Entity " + entity.GetType().FullName + " had document key '" +
                                                    documentMetadata.Key + "' but now has document key property '" + id + "'." +
                                                    Environment.NewLine +
                                                    "You cannot change the document key property of a entity loaded into the session");
            }

            var json = EntityToJson.ConvertEntityToJson(documentMetadata.Key, entity, documentMetadata.Metadata);

            var etag = UseOptimisticConcurrency || documentMetadata.ForceConcurrencyCheck
                                                   ? (documentMetadata.ETag ?? Guid.Empty)
                                                   : (Guid?)null;

            return(new PutCommandData
            {
                Document = json,
                Etag = etag,
                Key = documentMetadata.Key,
                Metadata = (RavenJObject)documentMetadata.Metadata.CloneToken(),
            });
        }
Exemplo n.º 2
0
        protected internal Task <string> GenerateDocumentKeyForStorageAsync(object entity)
        {
            if (entity is IDynamicMetaObjectProvider)
            {
                string id;
                if (GenerateEntityIdOnTheClient.TryGetIdFromDynamic(entity, out id))
                {
                    return(CompletedTask.With(id));
                }
                else
                {
                    return(GenerateKeyAsync(entity)
                           .ContinueWith(task =>
                    {
                        // If we generated a new id, store it back into the Id field so the client has access to to it
                        if (task.Result != null)
                        {
                            GenerateEntityIdOnTheClient.TrySetIdOnDynamic(entity, task.Result);
                        }
                        return task.Result;
                    }));
                }
            }

            return(GetOrGenerateDocumentKeyAsync(entity)
                   .ContinueWith(task =>
            {
                GenerateEntityIdOnTheClient.TrySetIdentity(entity, task.Result);
                return task.Result;
            }));
        }
Exemplo n.º 3
0
        internal Subscription(long id, string database, SubscriptionConnectionOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes, DocumentConvention conventions, bool open, Func <Task> ensureOpenSubscription)
        {
            this.id                     = id;
            this.options                = options;
            this.commands               = commands;
            this.changes                = changes;
            this.conventions            = conventions;
            this.ensureOpenSubscription = ensureOpenSubscription;

            SubscriptionLifetimeTask = taskCompletionSource.Task;

            if (typeof(T) != typeof(RavenJObject))
            {
                isStronglyTyped             = true;
                generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(conventions, entity => AsyncHelpers.RunSync(() => conventions.GenerateDocumentKeyAsync(database, commands, entity)));
            }

            if (open)
            {
                Start();
            }
            else
            {
                if (options.Strategy != SubscriptionOpeningStrategy.WaitForFree)
                {
                    throw new InvalidOperationException("Subscription isn't open while its opening strategy is: " + options.Strategy);
                }
            }

            if (options.Strategy == SubscriptionOpeningStrategy.WaitForFree)
            {
                WaitForSubscriptionReleased();
            }
        }
Exemplo n.º 4
0
        public Task StoreAsync(object entity)
        {
            string id;
            var    hasId = GenerateEntityIdOnTheClient.TryGetIdFromInstance(entity, out id);

            return(StoreAsyncInternal(entity, null, null, forceConcurrencyCheck: hasId == false));
        }
Exemplo n.º 5
0
        /// <summary>
        /// Stores the specified entity in the session. The entity will be saved when SaveChanges is called.
        /// </summary>
        public void Store(object entity)
        {
            string id;
            var    hasId = GenerateEntityIdOnTheClient.TryGetIdFromInstance(entity, out id);

            StoreInternal(entity, null, null, forceConcurrencyCheck: hasId == false);
        }
Exemplo n.º 6
0
        private DocumentMetadata GetDocumentMetadata <T>(T instance)
        {
            DocumentMetadata value;

            if (entitiesAndMetadata.TryGetValue(instance, out value) == false)
            {
                string id;
                if (GenerateEntityIdOnTheClient.TryGetIdFromInstance(instance, out id) ||
                    (instance is IDynamicMetaObjectProvider &&
                     GenerateEntityIdOnTheClient.TryGetIdFromDynamic(instance, out id))
                    )
                {
                    AssertNoNonUniqueInstance(instance, id);

                    var jsonDocument = GetJsonDocument(id);
                    entitiesByKey[id]             = instance;
                    entitiesAndMetadata[instance] = value = new DocumentMetadata
                    {
                        ETag             = UseOptimisticConcurrency ? (Guid?)Guid.Empty : null,
                        Key              = id,
                        OriginalMetadata = jsonDocument.Metadata,
                        Metadata         = (RavenJObject)jsonDocument.Metadata.CloneToken(),
                        OriginalValue    = new RavenJObject()
                    };
                }
                else
                {
                    throw new InvalidOperationException("Could not find the document key for " + instance);
                }
            }
            return(value);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Determines if the entity have changed.
        /// </summary>
        /// <param name="entity">The entity.</param>
        /// <param name="documentMetadata">The document metadata.</param>
        /// <returns></returns>
        protected bool EntityChanged(object entity, DocumentMetadata documentMetadata)
        {
            if (documentMetadata == null)
            {
                return(true);
            }

            string id;

            if (GenerateEntityIdOnTheClient.TryGetIdFromInstance(entity, out id) &&
                string.Equals(documentMetadata.Key, id, StringComparison.InvariantCultureIgnoreCase) == false)
            {
                return(true);
            }

            // prevent saves of a modified read only entity
            if (documentMetadata.OriginalMetadata.ContainsKey(Constants.RavenReadOnly) &&
                documentMetadata.OriginalMetadata.Value <bool>(Constants.RavenReadOnly) &&
                documentMetadata.Metadata.ContainsKey(Constants.RavenReadOnly) &&
                documentMetadata.Metadata.Value <bool>(Constants.RavenReadOnly))
            {
                return(false);
            }

            var newObj = EntityToJson.ConvertEntityToJson(documentMetadata.Key, entity, documentMetadata.Metadata);

            return(RavenJToken.DeepEquals(newObj, documentMetadata.OriginalValue) == false ||
                   RavenJToken.DeepEquals(documentMetadata.Metadata, documentMetadata.OriginalMetadata) == false);
        }
Exemplo n.º 8
0
		public BulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options)
		{
			this.documentStore = documentStore;
			databaseCommands = database == null
				                   ? documentStore.DatabaseCommands.ForSystemDatabase()
				                   : documentStore.DatabaseCommands.ForDatabase(database);

			generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(documentStore, entity => documentStore.Conventions.GenerateDocumentKey(database, databaseCommands, entity));
			operation = databaseCommands.GetBulkInsertOperation(options);
			entityToJson = new EntityToJson(documentStore, listeners);
		}
Exemplo n.º 9
0
        public BulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options)
        {
            this.documentStore = documentStore;
            databaseCommands   = database == null
                                                   ? documentStore.DatabaseCommands.ForSystemDatabase()
                                                   : documentStore.DatabaseCommands.ForDatabase(database);

            generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(documentStore, entity => documentStore.Conventions.GenerateDocumentKey(database, databaseCommands, entity));
            operation    = databaseCommands.GetBulkInsertOperation(options);
            entityToJson = new EntityToJson(documentStore, listeners);
        }
Exemplo n.º 10
0
 public ShardedBulkInsertOperation(string database, ShardedDocumentStore shardedDocumentStore)
 {
     this.database             = database;
     this.shardedDocumentStore = shardedDocumentStore;
     shards = shardedDocumentStore.ShardStrategy.Shards;
     Bulks  = new Dictionary <string, BulkInsertOperation>();
     generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(shardedDocumentStore.Conventions,
                                                                   entity => AsyncHelpers.RunSync(() => shardedDocumentStore.Conventions.GenerateDocumentKeyAsync(database, DatabaseCommands, entity)));
     shardResolutionStrategy = shardedDocumentStore.ShardStrategy.ShardResolutionStrategy;
     shardStrategy           = this.shardedDocumentStore.ShardStrategy;
 }
Exemplo n.º 11
0
 public ShardedBulkInsertOperation(string database, ShardedDocumentStore shardedDocumentStore, BulkInsertOptions options)
 {
     this.database = database;
     this.shardedDocumentStore = shardedDocumentStore;
     this.options = options;
     shards = shardedDocumentStore.ShardStrategy.Shards;
     Bulks = new Dictionary<string, BulkInsertOperation>();
     generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(shardedDocumentStore.Conventions,
         entity => AsyncHelpers.RunSync(() => shardedDocumentStore.Conventions.GenerateDocumentKeyAsync(database, DatabaseCommands, entity)));
     shardResolutionStrategy = shardedDocumentStore.ShardStrategy.ShardResolutionStrategy;
     shardStrategy = this.shardedDocumentStore.ShardStrategy;
 }
Exemplo n.º 12
0
        private void StoreInternal(object entity, Guid?etag, string id, bool forceConcurrencyCheck)
        {
            if (null == entity)
            {
                throw new ArgumentNullException("entity");
            }

            DocumentMetadata value;

            if (entitiesAndMetadata.TryGetValue(entity, out value))
            {
                value.ETag = etag ?? value.ETag;
                value.ForceConcurrencyCheck = forceConcurrencyCheck;
                return;
            }

            if (id == null)
            {
                if (GenerateDocumentKeysOnStore)
                {
                    id = GenerateEntityIdOnTheClient.GenerateDocumentKeyForStorage(entity);
                }
                else
                {
                    RememberEntityForDocumentKeyGeneration(entity);
                }
            }
            else
            {
                // Store it back into the Id field so the client has access to to it
                GenerateEntityIdOnTheClient.TrySetIdentity(entity, id);
            }

            // we make the check here even if we just generated the key
            // users can override the key generation behavior, and we need
            // to detect if they generate duplicates.
            AssertNoNonUniqueInstance(entity, id);

            var metadata = new RavenJObject();
            var tag      = documentStore.Conventions.GetTypeTagName(entity.GetType());

            if (tag != null)
            {
                metadata.Add(Constants.RavenEntityName, tag);
            }
            if (id != null)
            {
                knownMissingIds.Remove(id);
            }
            StoreEntityInUnitOfWork(id, entity, etag, metadata, forceConcurrencyCheck);
        }
Exemplo n.º 13
0
		public BulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options, IDatabaseChanges changes)
		{
			this.documentStore = documentStore;

			database = database ?? MultiDatabase.GetDatabaseName(documentStore.Url);

			// Fitzchak: Should not be ever null because of the above code, please refactor this.
			DatabaseCommands = database == null
				? documentStore.AsyncDatabaseCommands.ForSystemDatabase()
				: documentStore.AsyncDatabaseCommands.ForDatabase(database);

			generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(documentStore.Conventions, entity => documentStore.Conventions.GenerateDocumentKeyAsync(database, DatabaseCommands, entity).ResultUnwrap());
			Operation = GetBulkInsertOperation(options, DatabaseCommands, changes);
			entityToJson = new EntityToJson(documentStore, listeners);
		}
Exemplo n.º 14
0
        public BulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners, BulkInsertOptions options, IDatabaseChanges changes)
        {
            this.documentStore = documentStore;

            database = database ?? MultiDatabase.GetDatabaseName(documentStore.Url);

            // Fitzchak: Should not be ever null because of the above code, please refactor this.
            DatabaseCommands = database == null
                                ? documentStore.AsyncDatabaseCommands.ForSystemDatabase()
                                : documentStore.AsyncDatabaseCommands.ForDatabase(database);

            generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(documentStore, entity => documentStore.Conventions.GenerateDocumentKeyAsync(database, DatabaseCommands, entity).ResultUnwrap());
            Operation    = GetBulkInsertOperation(options, DatabaseCommands, changes);
            entityToJson = new EntityToJson(documentStore, listeners);
        }
Exemplo n.º 15
0
        internal Subscription(long id, string database, SubscriptionConnectionOptions options, IAsyncDatabaseCommands commands, IDatabaseChanges changes, DocumentConvention conventions, Func <Task> ensureOpenSubscription)
        {
            this.id                     = id;
            this.options                = options;
            this.commands               = commands;
            this.changes                = changes;
            this.conventions            = conventions;
            this.ensureOpenSubscription = ensureOpenSubscription;

            if (typeof(T) != typeof(RavenJObject))
            {
                isStronglyTyped             = true;
                generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(conventions, entity => conventions.GenerateDocumentKeyAsync(database, commands, entity).ResultUnwrap());
            }

            StartWatchingDocs();
            StartPullingTask = StartPullingDocs();
        }
Exemplo n.º 16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InMemoryDocumentSessionOperations"/> class.
 /// </summary>
 protected InMemoryDocumentSessionOperations(
     string dbName,
     DocumentStoreBase documentStore,
     DocumentSessionListeners listeners,
     Guid id)
 {
     Id                                 = id;
     this.dbName                        = dbName;
     this.documentStore                 = documentStore;
     this.listeners                     = listeners;
     ResourceManagerId                  = documentStore.ResourceManagerId;
     UseOptimisticConcurrency           = false;
     AllowNonAuthoritativeInformation   = true;
     NonAuthoritativeInformationTimeout = TimeSpan.FromSeconds(15);
     MaxNumberOfRequestsPerSession      = documentStore.Conventions.MaxNumberOfRequestsPerSession;
     GenerateEntityIdOnTheClient        = new GenerateEntityIdOnTheClient(documentStore, GenerateKey);
     EntityToJson                       = new EntityToJson(documentStore, listeners);
 }
Exemplo n.º 17
0
        public BulkInsertOperation(string database, IDocumentStore documentStore, DocumentSessionListeners listeners)
        {
            this.documentStore = documentStore;

            database = database ?? MultiDatabase.GetDatabaseName(documentStore.Url);

            // Fitzchak: Should not be ever null because of the above code, please refactor this.
            DatabaseCommands = database == null
                ? documentStore.AsyncDatabaseCommands.ForSystemDatabase()
                : documentStore.AsyncDatabaseCommands.ForDatabase(database);

            generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(documentStore.Conventions, entity =>
                                                                          AsyncHelpers.RunSync(() => documentStore.Conventions.GenerateDocumentKeyAsync(database, DatabaseCommands, entity)));

            // ReSharper disable once VirtualMemberCallInContructor
            Operation    = GetBulkInsertOperation(DatabaseCommands);
            entityToJson = new EntityToJson(documentStore, listeners);
        }
Exemplo n.º 18
0
        internal Subscription(SubscriptionConnectionOptions options,
                              AsyncServerClient commands, DocumentConvention conventions)
        {
            _options = options;
            if (_options.SubscriptionId == 0)
            {
                throw new ArgumentException("SubscriptionConnectionOptions must specify the SubscriptionId, but was set to zero.",
                                            nameof(options));
            }
            _commands    = commands;
            _conventions = conventions;

            if (typeof(T) != typeof(RavenJObject))
            {
                _isStronglyTyped             = true;
                _generateEntityIdOnTheClient = new GenerateEntityIdOnTheClient(conventions,
                                                                               entity => { throw new InvalidOperationException("Shouldn't be generating new ids here"); });
            }
        }
Exemplo n.º 19
0
        /// <summary>
        /// Updates the batch results.
        /// </summary>
        protected void UpdateBatchResults(IList <BatchResult> batchResults, SaveChangesData saveChangesData)
        {
            for (var i = saveChangesData.DeferredCommandsCount; i < batchResults.Count; i++)
            {
                var batchResult = batchResults[i];
                if (batchResult.Method != "PUT")
                {
                    continue;
                }

                var entity = saveChangesData.Entities[i - saveChangesData.DeferredCommandsCount];
                DocumentMetadata documentMetadata;
                if (entitiesAndMetadata.TryGetValue(entity, out documentMetadata) == false)
                {
                    continue;
                }

                batchResult.Metadata["@etag"]     = new RavenJValue(batchResult.Etag.ToString());
                entitiesByKey[batchResult.Key]    = entity;
                documentMetadata.ETag             = batchResult.Etag;
                documentMetadata.Key              = batchResult.Key;
                documentMetadata.OriginalMetadata = (RavenJObject)batchResult.Metadata.CloneToken();
                documentMetadata.Metadata         = batchResult.Metadata;
                documentMetadata.OriginalValue    = EntityToJson.ConvertEntityToJson(documentMetadata.Key, entity, documentMetadata.Metadata);

                GenerateEntityIdOnTheClient.TrySetIdentity(entity, batchResult.Key);

                foreach (var documentStoreListener in listeners.StoreListeners)
                {
                    documentStoreListener.AfterStore(batchResult.Key, entity, batchResult.Metadata);
                }
            }

            var lastPut = batchResults.LastOrDefault(x => x.Method == "PUT");

            if (lastPut == null)
            {
                return;
            }

            documentStore.LastEtagHolder.UpdateLastWrittenEtag(lastPut.Etag);
        }
Exemplo n.º 20
0
        protected Task <string> GetOrGenerateDocumentKeyAsync(object entity)
        {
            string id;

            GenerateEntityIdOnTheClient.TryGetIdFromInstance(entity, out id);

            Task <string> generator =
                id != null
                                ? CompletedTask.With(id)
                                : GenerateKeyAsync(entity);

            return(generator.ContinueWith(task =>
            {
                if (task.Result != null && task.Result.StartsWith("/"))
                {
                    throw new InvalidOperationException("Cannot use value '" + id + "' as a document id because it begins with a '/'");
                }

                return task.Result;
            }));
        }
Exemplo n.º 21
0
        /// <summary>
        /// Converts the json document to an entity.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">The id.</param>
        /// <param name="documentFound">The document found.</param>
        /// <param name="metadata">The metadata.</param>
        /// <returns></returns>
        protected object ConvertToEntity <T>(string id, RavenJObject documentFound, RavenJObject metadata)
        {
            if (typeof(T) == typeof(RavenJObject))
            {
                return((T)(object)documentFound.CloneToken());
            }

            var entity = default(T);

            EnsureNotReadVetoed(metadata);
            var documentType = Conventions.GetClrType(id, documentFound, metadata);

            if (documentType != null)
            {
                var type = Type.GetType(documentType);
                if (type != null)
                {
                    entity = (T)documentFound.Deserialize(type, Conventions);
                }
            }
            if (Equals(entity, default(T)))
            {
                entity = documentFound.Deserialize <T>(Conventions);
                var document = entity as RavenJObject;
                if (document != null)
                {
                    entity = (T)(object)(new DynamicJsonObject(document));
                }
            }
            GenerateEntityIdOnTheClient.TrySetIdentity(entity, id);

            foreach (var documentConversionListener in listeners.ConversionListeners)
            {
                documentConversionListener.DocumentToEntity(id, entity, documentFound, metadata);
            }

            return(entity);
        }