Esempio n. 1
0
        /// <summary>
        /// Gets the data from the file source.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="rowBuilder">
        /// The row builder.
        /// </param>
        /// <param name="query">
        /// The query.
        /// </param>
        /// <returns>
        /// The <see cref="IAsyncEnumerable{T}"/>.
        /// </returns>
        IAsyncEnumerable <Row> IDataSource.GetRows(IExecutionContext context, IRowBuilder rowBuilder, [NotNull] IQuery query)
        {
            var whereFilter       = query.GetFilter(context);
            var sortOrders        = query.GetSortOrders(context).ToArray();
            var fields            = query.RetrieveAllFields ? null : new HashSet <string>(query.Fields);
            var fileFormatContext = new FileFormatExecutionContext(context, this);

            IFileReader fileReader = null;

            return(context.CreateAsyncEnumerableAndRunOnce(
                       async() =>
            {
                var streamBuffer = await StreamBuffer.CreateAsync(await this.OpenStreamAsync(context, UriResolveMode.Read, this.Uri).ConfigureAwait(false), FileDataSource.PreviewByteCount).ConfigureAwait(false);

                fileReader = this.GetFileReader(context, streamBuffer);

                if (fileReader == null)
                {
                    throw new InvalidOperationException($"Unable to load file with extension '{Path.GetExtension(this.Uri)}', did you load the file format?");
                }

                return Tuple.Create(this.GetStreamReader(streamBuffer, fileReader), streamBuffer);
            },
                       stream => fileReader.Read(fileFormatContext, rowBuilder, stream.Item1, fields),
                       stream =>
            {
                stream?.Item1?.Dispose();
                stream?.Item2?.Dispose();
            })
                   .Where(whereFilter?.GetRowFilter())
                   .OrderBy(sortOrders));
        }
Esempio n. 2
0
        /// <summary>
        /// Writes the rowsToWrite to the specified target.
        /// </summary>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <param name="rowsToWrite">
        /// The rowsToWrite.
        /// </param>
        /// <param name="upsert">
        /// True to also update records, false to insert.
        /// </param>
        /// <returns>
        /// The <see cref="Task"/>.
        /// </returns>
        async Task <long> IDataTarget.WriteRowsAsync([NotNull] IExecutionContext context, IAsyncEnumerable <Row> rowsToWrite, bool upsert)
        {
            var fileWriter = context.FileFormats.OfType <IFileWriter>().FirstOrDefault(writer => writer.CanWriteThisFile(this.Uri));

            if (fileWriter == null)
            {
                throw new InvalidOperationException($"Unable to load file with extension '{Path.GetExtension(this.Uri)}', did you load the file format?");
            }

            if (fileWriter.ShouldMaterialize)
            {
                rowsToWrite = await rowsToWrite.MaterializeAsync().ConfigureAwait(false);
            }

            var result = 0L;

            var fileFormatContext = new FileFormatExecutionContext(context, this);

            using (var stream = await this.OpenStreamAsync(context, UriResolveMode.Write, this.Uri))
            {
                using (var writer = new StreamWriter(stream, (fileWriter as IOverrideEncoding)?.Encoding ?? this.encoding))
                {
                    using (var enumerator = rowsToWrite.GetAsyncEnumerator())
                    {
                        var emptyEnumerable = false;

                        while (!enumerator.MoveNext())
                        {
                            if (!enumerator.IsSynchronous && await enumerator.NextBatchAsync())
                            {
                                continue;
                            }

                            emptyEnumerable = true;
                            break;
                        }

                        if (!emptyEnumerable)
                        {
                            var done = false;

                            fileWriter.WriteHeader(fileFormatContext, writer, enumerator.Current.ColumnNames);

                            while (!done)
                            {
                                result += fileWriter.WriteRows(fileFormatContext, writer, FileDataSource.CurrentAndRest(enumerator), upsert);
                                done    = true;

                                if (enumerator.IsSynchronous)
                                {
                                    continue;
                                }

                                while (await enumerator.NextBatchAsync())
                                {
                                    if (!enumerator.MoveNext())
                                    {
                                        continue;
                                    }

                                    done = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            fileWriter.WriteHeader(fileFormatContext, writer, Enumerable.Empty <string>());
                        }
                    }

                    fileWriter.WriteFooter(fileFormatContext, writer);
                }
            }

            return(result);
        }