public T[] LoadInternal <T>(string[] ids, KeyValuePair <string, Type>[] includes, string transformer, Dictionary <string, object> transformerParameters = null)
        {
            if (transformer == null)
            {
                throw new ArgumentNullException("transformer");
            }
            if (ids.Length == 0)
            {
                return(new T[0]);
            }

            var loadTransformerOeration = new LoadTransformerOperation(this);

            loadTransformerOeration.ByIds(ids);
            loadTransformerOeration.WithTransformer(transformer, transformerParameters);
            loadTransformerOeration.WithIncludes(includes?.Select(x => x.Key).ToArray());

            var command = loadTransformerOeration.CreateRequest();

            if (command != null)
            {
                RequestExecuter.Execute(command, Context);
                loadTransformerOeration.SetResult(command.Result);
            }

            return(loadTransformerOeration.GetTransformedDocuments <T>(command?.Result));
        }
 public LazyTransformerLoadOperation(string[] ids, string transformer, LoadTransformerOperation loadTransformerOperation, bool singleResult)
 {
     this.ids         = ids;
     this.transformer = transformer;
     this.loadTransformerOperation = loadTransformerOperation;
     this.singleResult             = singleResult;
 }
 public LazyTransformerLoadOperation(string[] ids, string transformer, Dictionary <string, RavenJToken> transformerParameters, LoadTransformerOperation loadTransformerOperation, bool singleResult)
 {
     this.ids                      = ids;
     this.transformer              = transformer;
     this.transformerParameters    = transformerParameters;
     this.loadTransformerOperation = loadTransformerOperation;
     this.singleResult             = singleResult;
 }
Example #4
0
        Lazy <TResult[]> ILazySessionOperations.Load <TTransformer, TResult>(params string[] ids)
        {
            var cmds = GetCommandsToOperateOn(new ShardRequestData
            {
                Keys       = ids,
                EntityType = typeof(TTransformer)
            });
            var transformer = new TTransformer().TransformerName;
            var op          = new LoadTransformerOperation(this, transformer, ids);

            var lazyLoadOperation = new LazyTransformerLoadOperation <TResult>(ids, transformer, op, false);

            return(AddLazyOperation <TResult[]>(lazyLoadOperation, null, cmds));
        }
Example #5
0
        Lazy <TResult[]> ILazySessionOperations.Load <TResult>(IEnumerable <string> ids, Type transformerType, Action <TResult> onEval)
        {
            var idsArray = ids.ToArray();
            var cmds     = GetCommandsToOperateOn(new ShardRequestData
            {
                Keys       = idsArray,
                EntityType = transformerType
            });

            var transformer = ((AbstractTransformerCreationTask)Activator.CreateInstance(transformerType)).TransformerName;
            var op          = new LoadTransformerOperation(this, transformer, idsArray);

            var lazyLoadOperation = new LazyTransformerLoadOperation <TResult>(idsArray, transformer, op, false);

            return(AddLazyOperation <TResult[]>(lazyLoadOperation, null, cmds));
        }
        public async Task <T[]> LoadUsingTransformerInternalAsync <T>(string[] ids, KeyValuePair <string, Type>[] includes, string transformer,
                                                                      Dictionary <string, RavenJToken> transformerParameters = null, CancellationToken token = default(CancellationToken))
        {
            token.ThrowIfCancellationRequested(); //if cancel already requested prevent incrementing request count
            var results      = new T[ids.Length];
            var includePaths = includes != null?includes.Select(x => x.Key).ToArray() : null;

            var idsToLoad = GetIdsThatNeedLoading <T>(ids, includePaths, transformer).ToList();

            if (!idsToLoad.Any())
            {
                return(results);
            }

            IncrementRequestCount();

            if (typeof(T).IsArray)
            {
                foreach (var shard in idsToLoad)
                {
                    token.ThrowIfCancellationRequested();
                    var currentShardIds = shard.Select(x => x.Id).ToArray();
                    var shardResults    = await shardStrategy.ShardAccessStrategy.ApplyAsync(shard.Key,
                                                                                             new ShardRequestData { EntityType = typeof(T), Keys = currentShardIds.ToList() },
                                                                                             async (dbCmd, i) =>
                    {
                        // Returns array of arrays, public APIs don't surface that yet though as we only support Transform
                        // With a single Id
                        var arrayOfArrays = (await dbCmd.GetAsync(currentShardIds, includePaths, transformer, transformerParameters, token: token).ConfigureAwait(false))
                                            .Results
                                            .Select(x => x.Value <RavenJArray>("$values").Cast <RavenJObject>())
                                            .Select(values =>
                        {
                            var array = values.Select(y =>
                            {
                                HandleInternalMetadata(y);
                                return(ConvertToEntity(typeof(T), null, y, new RavenJObject()));
                            }).ToArray();
                            var newArray = Array.CreateInstance(typeof(T).GetElementType(), array.Length);
                            Array.Copy(array, newArray, array.Length);
                            return(newArray);
                        })
                                            .Cast <T>()
                                            .ToArray();

                        return(arrayOfArrays);
                    }).WithCancellation(token).ConfigureAwait(false);

                    return(shardResults.SelectMany(x => x).ToArray());
                }
            }

            foreach (var shard in idsToLoad)
            {
                token.ThrowIfCancellationRequested();
                var currentShardIds = shard.Select(x => x.Id).ToArray();
                var shardResults    = await shardStrategy.ShardAccessStrategy.ApplyAsync(shard.Key,
                                                                                         new ShardRequestData { EntityType = typeof(T), Keys = currentShardIds.ToList() },
                                                                                         async (dbCmd, i) =>
                {
                    var multiLoadResult = await dbCmd.GetAsync(currentShardIds, includePaths, transformer, transformerParameters).ConfigureAwait(false);

                    var items = new LoadTransformerOperation(this, transformer, ids).Complete <T>(multiLoadResult);

                    if (items.Length > currentShardIds.Length)
                    {
                        throw new InvalidOperationException(
                            String.Format(
                                "A load was attempted with transformer {0}, and more than one item was returned per entity - please use {1}[] as the projection type instead of {1}",
                                transformer,
                                typeof(T).Name));
                    }

                    return(items);
                }).WithCancellation(token).ConfigureAwait(false);

                foreach (var shardResult in shardResults)
                {
                    for (int i = 0; i < shardResult.Length; i++)
                    {
                        token.ThrowIfCancellationRequested();
                        if (ReferenceEquals(shardResult[i], null))
                        {
                            continue;
                        }
                        var id           = currentShardIds[i];
                        var itemPosition = Array.IndexOf(ids, id);
                        if (ReferenceEquals(results[itemPosition], default(T)) == false)
                        {
                            throw new InvalidOperationException("Found document with id: " + id + " on more than a single shard, which is not allowed. Document keys have to be unique cluster-wide.");
                        }

                        results[itemPosition] = shardResult[i];
                    }
                }
            }

            return(results);
        }