Beispiel #1
0
        public async Task UpdateBinaryPropertyAsync(IBlobProvider blobProvider, BinaryDataValue value, SnDataContext dataContext)
        {
            var streamLength = value.Stream?.Length ?? 0;
            var isExternal   = false;

            if (!(blobProvider is IBuiltInBlobProvider))
            {
                // BlobProviderData parameter is irrelevant because it will be overridden in the Allocate method
                var ctx = new BlobStorageContext(blobProvider)
                {
                    VersionId      = 0,
                    PropertyTypeId = 0,
                    FileId         = value.FileId,
                    Length         = streamLength,
                };

                await blobProvider.AllocateAsync(ctx, dataContext.CancellationToken).ConfigureAwait(false);

                isExternal = true;

                value.BlobProviderName = ctx.Provider.GetType().FullName;
                value.BlobProviderData = BlobStorageContext.SerializeBlobProviderData(ctx.BlobProviderData);
            }
            else
            {
                value.BlobProviderName = null;
                value.BlobProviderData = null;
            }

            if (blobProvider is IBuiltInBlobProvider)
            {
                // MS-SQL does not support stream size over [Int32.MaxValue].
                if (streamLength > int.MaxValue)
                {
                    throw new NotSupportedException();
                }
            }

            var isRepositoryStream = value.Stream is RepositoryStream;
            var hasStream          = isRepositoryStream || value.Stream is MemoryStream;

            if (!isExternal && !hasStream)
            {
                // do not do any database operation if the stream is not modified
                return;
            }

            if (!(dataContext is MsSqlDataContext sqlCtx))
            {
                throw new PlatformNotSupportedException();
            }

            var sql = blobProvider is IBuiltInBlobProvider
                ? UpdateBinaryPropertyScript
                : UpdateBinaryPropertyNewFilerowScript;
            var fileId = (int)await sqlCtx.ExecuteScalarAsync(sql, cmd =>
            {
                cmd.Parameters.AddRange(new[]
                {
                    sqlCtx.CreateParameter("@BinaryPropertyId", DbType.Int32, value.Id),
                    sqlCtx.CreateParameter("@ContentType", DbType.String, 450, value.ContentType),
                    sqlCtx.CreateParameter("@FileNameWithoutExtension", DbType.String, 450, value.FileName.FileNameWithoutExtension == null ? DBNull.Value : (object)value.FileName.FileNameWithoutExtension),
                    sqlCtx.CreateParameter("@Extension", DbType.String, 50, ValidateExtension(value.FileName.Extension)),
                    sqlCtx.CreateParameter("@Size", DbType.Int64, value.Size),
                    sqlCtx.CreateParameter("@Checksum", DbType.AnsiString, 200, value.Checksum != null ? (object)value.Checksum : DBNull.Value),
                    sqlCtx.CreateParameter("@BlobProvider", DbType.String, 450, value.BlobProviderName != null ? (object)value.BlobProviderName : DBNull.Value),
                    sqlCtx.CreateParameter("@BlobProviderData", DbType.String, int.MaxValue, value.BlobProviderData != null ? (object)value.BlobProviderData : DBNull.Value),
                });
            }).ConfigureAwait(false);

            if (fileId > 0 && fileId != value.FileId)
            {
                value.FileId = fileId;
            }

            if (blobProvider is IBuiltInBlobProvider)
            {
                // Stream exists and is loaded -> write it
                var ctx = new BlobStorageContext(blobProvider, value.BlobProviderData)
                {
                    VersionId        = 0,
                    PropertyTypeId   = 0,
                    FileId           = value.FileId,
                    Length           = streamLength,
                    BlobProviderData = new BuiltinBlobProviderData()
                };

                await BuiltInBlobProvider.UpdateStreamAsync(ctx, value.Stream, sqlCtx).ConfigureAwait(false);
            }
            else
            {
                var ctx = new BlobStorageContext(blobProvider, value.BlobProviderData)
                {
                    VersionId      = 0,
                    PropertyTypeId = 0,
                    FileId         = value.FileId,
                    Length         = streamLength,
                };
                if (streamLength == 0)
                {
                    await blobProvider.ClearAsync(ctx, dataContext.CancellationToken).ConfigureAwait(false);
                }
                else
                {
                    using (var stream = blobProvider.GetStreamForWrite(ctx))
                        value.Stream?.CopyTo(stream);
                }
            }
        }
Beispiel #2
0
        public STT.Task UpdateBinaryPropertyAsync(IBlobProvider blobProvider, BinaryDataValue value, SnDataContext dataContext)
        {
            var streamLength = value.Stream?.Length ?? 0;
            var isExternal   = false;

            if (streamLength > 0)
            {
                // BlobProviderData parameter is irrelevant because it will be overridden in the Allocate method
                var ctx = new BlobStorageContext(blobProvider)
                {
                    VersionId      = 0,
                    PropertyTypeId = 0,
                    FileId         = value.FileId,
                    Length         = streamLength,
                };

                blobProvider.AllocateAsync(ctx, CancellationToken.None).GetAwaiter().GetResult();
                isExternal = true;

                value.BlobProviderName = ctx.Provider.GetType().FullName;
                value.BlobProviderData = BlobStorageContext.SerializeBlobProviderData(ctx.BlobProviderData);
            }

            var isRepositoryStream = value.Stream is RepositoryStream;
            var hasStream          = isRepositoryStream || value.Stream is MemoryStream;

            if (!isExternal && !hasStream)
            {
                // do not do any database operation if the stream is not modified
                return(STT.Task.CompletedTask);
            }

            var db     = DataProvider.DB;
            var fileId = db.Files.GetNextId();

            db.Files.Insert(new FileDoc
            {
                FileId      = fileId,
                ContentType = value.ContentType,
                Extension   = value.FileName.Extension,
                FileNameWithoutExtension = value.FileName.FileNameWithoutExtension,
                Size             = Math.Max(0, value.Size),
                BlobProvider     = value.BlobProviderName,
                BlobProviderData = value.BlobProviderData
            });
            var binaryPropertyDoc = db.BinaryProperties.FirstOrDefault(x => x.BinaryPropertyId == value.Id);

            if (binaryPropertyDoc != null)
            {
                binaryPropertyDoc.FileId = fileId;
            }

            if (fileId > 0 && fileId != value.FileId)
            {
                value.FileId = fileId;
            }

            // update stream with a new context
            var newCtx = new BlobStorageContext(blobProvider, value.BlobProviderData)
            {
                VersionId      = 0,
                PropertyTypeId = 0,
                FileId         = value.FileId,
                Length         = streamLength,
            };

            if (streamLength == 0)
            {
                blobProvider.ClearAsync(newCtx, dataContext.CancellationToken)
                .ConfigureAwait(false).GetAwaiter().GetResult();
            }
            else
            {
                using (var stream = blobProvider.GetStreamForWrite(newCtx))
                    value.Stream?.CopyTo(stream);
            }

            return(STT.Task.CompletedTask);
        }