/// <summary>
 /// Gets the enumeration of chunks for file id
 /// </summary>
 public static async Task<Cursor<Chunk>> EnumerateChunksAsync(Bucket bucket, Guid fileId, CancellationToken cancelToken = default(CancellationToken))
 {
     var index = new {index = bucket.chunkIndexName};
     return await bucket.chunkTable.Between(R.Array(fileId, R.Minval()), R.Array(fileId, R.Maxval()))[index]
         .OrderBy("n")[index]
         .RunCursorAsync<Chunk>(bucket.conn, cancelToken)
         .ConfigureAwait(false);
 }
        /// <summary>
        /// Enumerate all possible file system entries for a given filename
        /// </summary>
        public static async Task<Cursor<FileInfo>> EnumerateFileEntriesAsync(Bucket bucket, string filename, CancellationToken cancelToken = default(CancellationToken))
        {
            filename = filename.SafePath();

            var index = new {index = bucket.fileIndex};

            var cursor = await bucket.fileTable
                .Between(R.Array(R.Minval(), filename, R.Minval()), R.Array(R.Maxval(), filename, R.Maxval()))[index]
                .RunCursorAsync<FileInfo>(bucket.conn, cancelToken)
                .ConfigureAwait(false);

            return cursor;
        }
        public DownloadStreamForwardOnly(Bucket bucket, FileInfo fileInfo, DownloadOptions options)
            : base(bucket, fileInfo)
        {
            if( options.CheckSHA256 )
            {
                this.sha256 = new IncrementalSHA256();
                this.checkSHA256 = true;
            }

            lastChunkNumber = (int)((fileInfo.Length - 1) / fileInfo.ChunkSizeBytes);
            lastChunkSize = (int)(fileInfo.Length % fileInfo.ChunkSizeBytes);

            if( lastChunkSize == 0 )
            {
                lastChunkSize = fileInfo.ChunkSizeBytes;
            }
        }
 /// <summary>
 /// Gets the enumeration of chunks for file id
 /// </summary>
 public static Cursor<Chunk> EnumerateChunks(Bucket bucket, Guid fileId)
 {
     return EnumerateChunksAsync(bucket, fileId).WaitSync();
 }
 /// <summary>
 /// Enumerate all possible file system entries for a given filename.
 /// </summary>
 public static Cursor<FileInfo> EnumerateFileEntries(Bucket bucket, string filename)
 {
     return EnumerateFileEntriesAsync(bucket, filename).WaitSync();
 }
 /// <summary>
 /// Reclaims space from incomplete files.
 /// </summary>
 public static void CleanUp(Bucket bucket)
 {
 }
 /// <summary>
 /// Get a chunk in a bucket for file id.
 /// </summary>
 public static async Task<Chunk> GetChunkAsync(Bucket bucket, Guid fileId, long n, CancellationToken cancelToken = default(CancellationToken))
 {
     var index = new {index = bucket.chunkIndexName};
     return await bucket.chunkTable.GetAll(R.Array(fileId, n))[index]
         .Nth(0)
         .RunResultAsync<Chunk>(bucket.conn, cancelToken)
         .ConfigureAwait(false);
 }
 /// <summary>
 /// Constructs a new download stream
 /// </summary>
 /// <param name="bucket">The bucket the <paramref name="fileInfo"/> belongs to.</param>
 /// <param name="fileInfo"><see cref="FileInfo"/></param>
 protected DownloadStream(Bucket bucket, FileInfo fileInfo) : base(fileInfo)
 {
     this.bucket = bucket;
 }
 /// <summary>
 /// Gets the FileInfo for a given fileId
 /// </summary>
 public static FileInfo GetFileInfo(this Bucket bucket, Guid fileId)
 {
     return(GetFileInfoAsync(bucket, fileId).WaitSync());
 }
 /// <summary>
 /// Gets all 'completed' file revisions for a given file. Deleted and incomplete files are excluded.
 /// </summary>
 public static Cursor <FileInfo> GetAllRevisions(this Bucket bucket, string filename)
 {
     return(GetAllRevisionsAsync(bucket, filename).WaitSync());
 }
 /// <summary>
 /// Deletes a file and it's associated revisions. Iteratively deletes revisions for a file one by one.
 /// </summary>
 /// <param name="mode">Soft deletes are atomic. Hard are atomic on the file but not a file's chunks.</param>
 /// <param name="deleteOpts">Delete durability options. See ReQL API.</param>
 /// <param name="bucket"><see cref="Bucket"/></param>
 /// <param name="filename">The filename</param>
 public static void DeleteAllRevisions(this Bucket bucket, string filename, DeleteMode mode = DeleteMode.Soft, object deleteOpts = null)
 {
     DeleteAllRevisionsAsync(bucket, filename, mode, deleteOpts).WaitSync();
 }
 /// <summary>
 /// Deletes a file in the bucket.
 /// </summary>
 /// <param name="mode">Soft deletes are atomic. Hard are atomic on the file but not a file's chunks.</param>
 /// <param name="deleteOpts">Delete durability options. See ReQL API.</param>
 /// <param name="bucket"><see cref="Bucket"/></param>
 /// <param name="fileId"><see cref="FileInfo.Id"/></param>
 public static void DeleteRevision(this Bucket bucket, Guid fileId, DeleteMode mode = DeleteMode.Soft, object deleteOpts = null)
 {
     DeleteRevisionAsync(bucket, fileId, mode, deleteOpts).WaitSync();
 }
 /// <summary>
 /// List files with a given path.
 /// </summary>
 /// <param name="path">The path starting with /</param>
 /// <param name="bucket"><see cref="Bucket"/></param>
 public static Cursor <FileInfo> ListFilesByPrefix(this Bucket bucket, string path)
 {
     return(ListFilesByPrefixAsync(bucket, path).WaitSync());
 }
 /// <summary>
 /// Constructs a new download stream
 /// </summary>
 /// <param name="bucket">The bucket the <paramref name="fileInfo"/> belongs to.</param>
 /// <param name="fileInfo"><see cref="FileInfo"/></param>
 protected DownloadStream(Bucket bucket, FileInfo fileInfo) : base(fileInfo)
 {
     this.bucket = bucket;
 }
 /// <summary>
 /// Get a chunk in a bucket for file id.
 /// </summary>
 public static Chunk GetChunk(Bucket bucket, Guid fileId, long n)
 {
     return GetChunkAsync(bucket, fileId, n).WaitSync();
 }
 /// <summary>
 /// Gets a FileInfo for a given filename and revision. Considers only 'completed' uploads.
 /// </summary>
 /// <param name="revision">-1: The most recent revision. -2: The second most recent revision. -3: The third most recent revision. 0: The original stored file. 1: The first revision. 2: The second revision. etc...</param>
 /// <param name="bucket"><see cref="Bucket"/></param>
 /// <param name="filename">The filename</param>
 public static FileInfo GetFileInfoByName(this Bucket bucket, string filename, int revision = -1)
 {
     return(GetFileInfoByNameAsync(bucket, filename, revision).WaitSync());
 }
 // constructors
 public SeekableDownloadStream(Bucket bucket, FileInfo fileInfo)
     : base(bucket, fileInfo)
 {
 }