public byte[] ReadRandom(BlobStorageContext context, long offset, int count)
 {
     using (var ctx = new MsSqlDataContext(_connectionString, DataOptions, CancellationToken.None))
     {
         return((byte[])ctx.ExecuteScalarAsync(LoadBinaryFragmentScript, cmd =>
         {
             cmd.Parameters.AddRange(new[]
             {
                 ctx.CreateParameter("@FileId", SqlDbType.Int, context.FileId),
                 ctx.CreateParameter("@Position", SqlDbType.BigInt, offset + 1),
                 ctx.CreateParameter("@Count", SqlDbType.Int, count),
             });
         }).GetAwaiter().GetResult());
     }
 }
Beispiel #2
0
        /// <summary>
        /// Returns a context object that holds MsSql-specific data for blob storage operations.
        /// </summary>
        /// <param name="fileId">File identifier.</param>
        /// <param name="clearStream">Whether the blob provider should clear the stream during assembling the context.</param>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="cancellationToken">The token to monitor for cancellation requests.</param>
        public async Task <BlobStorageContext> GetBlobStorageContextAsync(int fileId, bool clearStream, int versionId, int propertyTypeId,
                                                                          CancellationToken cancellationToken)
        {
            var sql = GetBlobStorageContextScript;

            if (clearStream)
            {
                sql = ClearStreamByFileIdScript + sql;
            }

            cancellationToken.ThrowIfCancellationRequested();
            using (var ctx = new MsSqlDataContext(ConnectionStrings.ConnectionString, DataOptions, cancellationToken))
            {
                return(await ctx.ExecuteReaderAsync(sql, cmd =>
                {
                    cmd.Parameters.Add(ctx.CreateParameter("@FileId", DbType.Int32, fileId));
                    if (clearStream)
                    {
                        cmd.Parameters.Add(ctx.CreateParameter("@VersionId", DbType.Int32, versionId));
                        cmd.Parameters.Add(ctx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId));
                    }
                }, async (reader, cancel) =>
                {
                    cancel.ThrowIfCancellationRequested();
                    if (!await reader.ReadAsync(cancel).ConfigureAwait(false))
                    {
                        return null;
                    }

                    var length = reader.GetSafeInt64(0);
                    var providerName = reader.GetSafeString(1);
                    var providerData = reader.GetSafeString(2);
                    var provider = Providers.GetProvider(providerName);

                    return new BlobStorageContext(provider, providerData)
                    {
                        VersionId = versionId,
                        PropertyTypeId = propertyTypeId,
                        FileId = fileId,
                        Length = length,
                        BlobProviderData = provider is IBuiltInBlobProvider
                            ? new BuiltinBlobProviderData()
                            : provider.ParseData(providerData)
                    };
                }).ConfigureAwait(false));
            }
        }
 /// <inheritdoc />
 public async Task WriteAsync(BlobStorageContext context, long offset, byte[] buffer, CancellationToken cancellationToken)
 {
     using (var ctx = new MsSqlDataContext(_connectionString, DataOptions, cancellationToken))
     {
         await ctx.ExecuteNonQueryAsync(UpdateStreamWriteChunkScript, cmd =>
         {
             cmd.Parameters.AddRange(new[]
             {
                 ctx.CreateParameter("@FileId", SqlDbType.Int, context.FileId),
                 ctx.CreateParameter("@VersionId", SqlDbType.Int, context.VersionId),
                 ctx.CreateParameter("@PropertyTypeId", SqlDbType.Int, context.PropertyTypeId),
                 ctx.CreateParameter("@Data", SqlDbType.VarBinary, buffer),
                 ctx.CreateParameter("@Offset", SqlDbType.BigInt, offset),
             });
         }).ConfigureAwait(false);
     }
 }
Beispiel #4
0
        public async Task CommitChunkAsync(int versionId, int propertyTypeId, int fileId, long fullSize, BinaryDataValue source,
                                           CancellationToken cancellationToken)
        {
            try
            {
                using (var ctx = new MsSqlDataContext(ConnectionStrings.ConnectionString, DataOptions, cancellationToken))
                {
                    using (var transaction = ctx.BeginTransaction())
                    {
                        await ctx.ExecuteNonQueryAsync(CommitChunkScript, cmd =>
                        {
                            cmd.Parameters.AddRange(new[]
                            {
                                ctx.CreateParameter("@FileId", DbType.Int32, fileId),
                                ctx.CreateParameter("@VersionId", DbType.Int32, versionId),
                                ctx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId),
                                ctx.CreateParameter("@Size", DbType.Int64, fullSize),
                                ctx.CreateParameter("@Checksum", DbType.AnsiString, 200, DBNull.Value),
                                ctx.CreateParameter("@ContentType", DbType.String, 50, source != null ? source.ContentType : string.Empty),
                                ctx.CreateParameter("@FileNameWithoutExtension", DbType.String, 450, source != null
                                    ? source.FileName.FileNameWithoutExtension == null
                                        ? DBNull.Value
                                        : (object)source.FileName.FileNameWithoutExtension
                                    : DBNull.Value),

                                ctx.CreateParameter("@Extension", DbType.String, 50,
                                                    source != null ? ValidateExtension(source.FileName.Extension) : string.Empty),
                            });
                        }).ConfigureAwait(false);

                        transaction.Commit();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new DataException("Error during committing binary chunk to file stream.", ex);
            }
        }
Beispiel #5
0
        public async Task <string> StartChunkAsync(IBlobProvider blobProvider, int versionId, int propertyTypeId, long fullSize,
                                                   CancellationToken cancellationToken)
        {
            var ctx = new BlobStorageContext(blobProvider)
            {
                VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = 0, Length = fullSize
            };
            string blobProviderName = null;
            string blobProviderData = null;

            if (!(blobProvider is IBuiltInBlobProvider))
            {
                await blobProvider.AllocateAsync(ctx, cancellationToken).ConfigureAwait(false);

                blobProviderName = blobProvider.GetType().FullName;
                blobProviderData = BlobStorageContext.SerializeBlobProviderData(ctx.BlobProviderData);
            }
            try
            {
                using (var dctx = new MsSqlDataContext(ConnectionStrings.ConnectionString, DataOptions, cancellationToken))
                {
                    using (var transaction = dctx.BeginTransaction())
                    {
                        var result = await dctx.ExecuteReaderAsync(InsertStagingBinaryScript, cmd =>
                        {
                            cmd.Parameters.AddRange(new[]
                            {
                                dctx.CreateParameter("@VersionId", DbType.Int32, versionId),
                                dctx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId),
                                dctx.CreateParameter("@Size", DbType.Int64, fullSize),
                                dctx.CreateParameter("@BlobProvider", DbType.String, 450, blobProviderName != null ? (object)blobProviderName : DBNull.Value),
                                dctx.CreateParameter("@BlobProviderData", DbType.String, int.MaxValue, blobProviderData != null ? (object)blobProviderData : DBNull.Value),
                            });
                        }, async (reader, cancel) =>
                        {
                            int binaryPropertyId;
                            int fileId;
                            cancel.ThrowIfCancellationRequested();
                            if (await reader.ReadAsync(cancel).ConfigureAwait(false))
                            {
                                binaryPropertyId = reader.GetSafeInt32(0);
                                fileId           = reader.GetSafeInt32(1);
                            }
                            else
                            {
                                throw new DataException("File row could not be inserted.");
                            }
                            ctx.FileId = fileId;

                            return(new ChunkToken
                            {
                                VersionId = versionId,
                                PropertyTypeId = propertyTypeId,
                                BinaryPropertyId = binaryPropertyId,
                                FileId = fileId
                            }.GetToken());
                        }).ConfigureAwait(false);

                        transaction.Commit();
                        return(result);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new DataException("Error during saving binary chunk to SQL Server.", ex);
            }
        }