Example #1
0
        public void InsertBinaryProperty(IBlobProvider blobProvider, BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode)
        {
            var streamLength = value.Stream?.Length ?? 0;
            var ctx          = new BlobStorageContext(blobProvider)
            {
                VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = 0, Length = streamLength, UseFileStream = false
            };

            // blob operation

            blobProvider.Allocate(ctx);

            using (var stream = blobProvider.GetStreamForWrite(ctx))
                value.Stream?.CopyTo(stream);

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

            // metadata operation
            var db = _dataProvider.DB;

            if (!isNewNode)
            {
                db.BinaryProperties.RemoveAll(r => r.VersionId == versionId && r.PropertyTypeId == propertyTypeId);
            }

            var fileId = db.Files.Count == 0 ? 1 : db.Files.Max(r => r.FileId) + 1;

            db.Files.Add(new InMemoryDataProvider.FileRecord
            {
                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 binaryPropertyId = db.BinaryProperties.Count == 0 ? 1 : db.BinaryProperties.Max(r => r.BinaryPropertyId) + 1;

            db.BinaryProperties.Add(new InMemoryDataProvider.BinaryPropertyRecord
            {
                BinaryPropertyId = binaryPropertyId,
                FileId           = fileId,
                PropertyTypeId   = propertyTypeId,
                VersionId        = versionId
            });

            value.Id        = binaryPropertyId;
            value.FileId    = fileId;
            value.Timestamp = 0L; //TODO: file row timestamp
        }
Example #2
0
        /// <summary>
        /// Inserts a new binary record into the metadata database containing a new or an already existing file id,
        /// removing the previous record if the content is not new.
        /// </summary>
        /// <param name="value">Binary data to insert.</param>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="isNewNode">Whether this value belongs to a new or an existing node.</param>
        /// <param name="dataContext">Database accessor object.</param>
        /// <returns>A Task that represents the asynchronous operation.</returns>
        public Task InsertBinaryPropertyAsync(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode, SnDataContext dataContext)
        {
            var blobProvider = ProviderSelector.GetProvider(value.Size);

            if (value.FileId > 0 && value.Stream == null)
            {
                return(DataProvider.InsertBinaryPropertyWithFileIdAsync(value, versionId, propertyTypeId, isNewNode, dataContext));
            }
            else
            {
                return(DataProvider.InsertBinaryPropertyAsync(blobProvider, value, versionId, propertyTypeId, isNewNode, dataContext));
            }
        }
Example #3
0
        /// <summary>
        /// Inserts a new binary record into the metadata database containing a new or an already exising file id,
        /// removing the previous record if the content is not new.
        /// </summary>
        /// <param name="value">Binary data to insert.</param>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="isNewNode">Whether this value belongs to a new or an existing node.</param>
        /// <param name="dataContext">Database accessor object.</param>
        /// <returns>A Task that represents the asynchronous operation.</returns>
        protected internal static Task InsertBinaryPropertyAsync(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode, SnDataContext dataContext)
        {
            var blobProvider = GetProvider(value.Size);

            if (value.FileId > 0 && value.Stream == null)
            {
                return(BlobStorageComponents.DataProvider.InsertBinaryPropertyWithFileIdAsync(value, versionId, propertyTypeId, isNewNode, dataContext));
            }
            else
            {
                return(BlobStorageComponents.DataProvider.InsertBinaryPropertyAsync(blobProvider, value, versionId, propertyTypeId, isNewNode, dataContext));
            }
        }
        /// <summary>
        /// Inserts a new binary record into the metadata database containing a new or an already exising file id,
        /// removing the previous record if the content is not new.
        /// </summary>
        /// <param name="value">Binary data to insert.</param>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="isNewNode">Whether this value belongs to a new or an existing node.</param>
        protected internal static void InsertBinaryProperty(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode)
        {
            var blobProvider = GetProvider(value.Size);

            if (value.FileId > 0 && value.Stream == null)
            {
                BlobStorageComponents.DataProvider.InsertBinaryPropertyWithFileId(value, versionId, propertyTypeId, isNewNode);
            }
            else
            {
                BlobStorageComponents.DataProvider.InsertBinaryProperty(blobProvider, value, versionId, propertyTypeId, isNewNode);
            }
        }
Example #5
0
        public int InsertBinaryProperty(int versionId, int propertyTypeId, BinaryDataValue value, bool isNewNode)
        {
            if (value.Stream != null && value.Stream.Length > Int32.MaxValue)
            {
                throw new NotSupportedException(); // MS-SQL does not support stream size over [Int32.MaxValue]
            }
            SqlProcedure cmd = null;
            int          id;

            try
            {
                cmd = new SqlProcedure {
                    CommandText = (isNewNode ? INSERT_BINARY_PROPERTY : DELETE_AND_INSERT_BINARY_PROPERTY), CommandType = CommandType.Text
                };
                cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value           = (versionId != 0) ? (object)versionId : DBNull.Value;
                cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value      = (propertyTypeId != 0) ? (object)propertyTypeId : DBNull.Value;
                cmd.Parameters.Add("@ContentType", SqlDbType.VarChar, 50).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.VarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.VarChar, 50).Value = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value           = value.Size;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = (value.Checksum != null) ? (object)value.Checksum : DBNull.Value;

                if (value.Stream != null && value.Stream.Length > 0)
                {
                    var streamSize = Convert.ToInt32(value.Stream.Length);
                    var buffer     = new byte[streamSize];
                    value.Stream.Seek(0, SeekOrigin.Begin);
                    value.Stream.Read(buffer, 0, streamSize);

                    cmd.Parameters.Add(new SqlParameter("@Value", SqlDbType.VarBinary)).Value = buffer;
                }
                else
                {
                    cmd.Parameters.Add(new SqlParameter("@Value", SqlDbType.VarBinary)).Value = DBNull.Value;
                }

                id = Convert.ToInt32(cmd.ExecuteScalar(), CultureInfo.CurrentCulture);
            }
            finally
            {
                if (cmd != null)
                {
                    cmd.Dispose();
                }
            }

            return(id);
        }
Example #6
0
        public void UpdateBinaryProperty(int binaryDataId, BinaryDataValue value)
        {
            if (value.Stream != null && value.Stream.Length > Int32.MaxValue)
            {
                throw new NotSupportedException(); // MS-SQL does not support stream size over [Int32.MaxValue]
            }
            bool isRepositoryStream = value.Stream is RepositoryStream;

            SqlProcedure cmd = null;

            //object pointer;
            try
            {
                cmd = new SqlProcedure {
                    CommandText = "proc_BinaryProperty_Update"
                };
                cmd.Parameters.Add("@BinaryPropertyId", SqlDbType.Int).Value    = binaryDataId;
                cmd.Parameters.Add("@ContentType", SqlDbType.VarChar, 50).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.VarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? (object)DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.VarChar, 50).Value = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value           = value.Size;
                // Do not update the stream field in the database if that is not loaded (other change happened)
                cmd.Parameters.Add("@IsStreamModified", SqlDbType.TinyInt).Value = isRepositoryStream ? 0 : 1;
                //cmd.Parameters.Add("@IsStreamModified", SqlDbType.TinyInt).Value = isLoaded ? 1 : 0;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = (value.Checksum != null) ? (object)value.Checksum : DBNull.Value;;

                //SqlParameter pointerParameter = cmd.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
                //pointerParameter.Direction = ParameterDirection.Output;

                cmd.ExecuteNonQuery();
                //pointer = pointerParameter.Value;
            }
            finally
            {
                cmd.Dispose();
            }

            if (!isRepositoryStream && value.Stream != null && value.Stream.Length > 0)
            //if(isLoaded && stream != null && stream.Length > 0)
            {
                // Stream isloaded, exists -> write it
                WriteBinaryStream(value.Stream, binaryDataId);
            }
        }
Example #7
0
        public int InsertBinaryPropertyOld(int versionId, int propertyTypeId, BinaryDataValue value)
        {
            if (value.Stream != null && value.Stream.Length > Int32.MaxValue)
            {
                throw new NotSupportedException(); // MS-SQL does not support stream size over [Int32.MaxValue]
            }
            SqlProcedure cmd = null;
            //object pointer;
            int id = 0;

            try
            {
                cmd = new SqlProcedure {
                    CommandText = "proc_BinaryProperty_Insert"
                };
                cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value           = (versionId != 0) ? (object)versionId : DBNull.Value;
                cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value      = (propertyTypeId != 0) ? (object)propertyTypeId : DBNull.Value;
                cmd.Parameters.Add("@ContentType", SqlDbType.VarChar, 50).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.VarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? (object)DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.VarChar, 50).Value = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value           = value.Size;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = (value.Checksum != null) ? (object)value.Checksum : DBNull.Value;;

                //SqlParameter pointerParameter = cmd.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
                //pointerParameter.Direction = ParameterDirection.Output;

                id = Convert.ToInt32(cmd.ExecuteScalar(), CultureInfo.CurrentCulture);
                //pointer = pointerParameter.Value;
            }
            finally
            {
                cmd.Dispose();
            }

            if (value.Stream != null && value.Stream.Length > 0)
            {
                // Stream exists -> write it
                WriteBinaryStream(value.Stream, id);
            }

            return(id);
        }
        public async Task InsertBinaryPropertyWithFileIdAsync(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode,
                                                              SnDataContext dataContext)
        {
            var sql = isNewNode ? InsertBinaryPropertyWithKnownFileIdScript : DeleteAndInsertBinaryPropertyWithKnownFileIdScript;

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

            value.Id = (int)await sqlCtx.ExecuteScalarAsync(sql, cmd =>
            {
                cmd.Parameters.AddRange(new[]
                {
                    sqlCtx.CreateParameter("@VersionId", DbType.Int32, versionId != 0 ? (object)versionId : DBNull.Value),
                    sqlCtx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId != 0 ? (object)propertyTypeId : DBNull.Value),
                    sqlCtx.CreateParameter("@FileId", DbType.Int32, value.FileId),
                });
            }).ConfigureAwait(false);
        }
        /// <summary>
        /// Inserts a new binary record into the metadata database containing an already exising file id,
        /// removing the previous record if the content is not new.
        /// </summary>
        /// <param name="value">Binary data to insert.</param>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="isNewNode">Whether this value belongs to a new or an existing node.</param>
        public void InsertBinaryPropertyWithFileId(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode)
        {
            SqlProcedure cmd = null;
            int          id;

            try
            {
                cmd = new SqlProcedure
                {
                    CommandText = isNewNode ? InsertBinaryPropertyWithKnownFileIdScript : DeleteAndInsertBinaryPropertyWithKnownFileId,
                    CommandType = CommandType.Text
                };
                cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value      = versionId != 0 ? (object)versionId : DBNull.Value;
                cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value = propertyTypeId != 0 ? (object)propertyTypeId : DBNull.Value;
                cmd.Parameters.Add("@FileId", SqlDbType.Int).Value         = value.FileId;
                id = (int)cmd.ExecuteScalar();
            }
            finally
            {
                cmd?.Dispose();
            }

            value.Id = id;
        }
        public STT.Task InsertBinaryPropertyWithFileIdAsync(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode,
                                                            SnDataContext dataContext)
        {
            var db = DataProvider.DB;

            if (!isNewNode)
            {
                DeleteBinaryPropertyAsync(versionId, propertyTypeId, dataContext).GetAwaiter().GetResult();
            }

            var binaryPropertyId = db.BinaryProperties.GetNextId();

            db.BinaryProperties.Insert(new BinaryPropertyDoc
            {
                BinaryPropertyId = binaryPropertyId,
                FileId           = value.FileId,
                PropertyTypeId   = propertyTypeId,
                VersionId        = versionId
            });

            value.Id = binaryPropertyId;

            return(STT.Task.CompletedTask);
        }
        public STT.Task CommitChunkAsync(int versionId, int propertyTypeId, int fileId, long fullSize, BinaryDataValue source,
                                         CancellationToken cancellationToken)
        {
            // Get related objects
            var db = DataProvider.DB;

            var binaryDoc =
                db.BinaryProperties.FirstOrDefault(r => r.VersionId == versionId && r.PropertyTypeId == propertyTypeId);

            if (binaryDoc == null)
            {
                return(null);
            }

            var fileDoc = db.Files.FirstOrDefault(x => x.FileId == fileId);

            if (fileDoc == null)
            {
                return(null);
            }

            // Switch to the new file
            binaryDoc.FileId = fileId;

            // Reset staging and set metadata
            fileDoc.Staging = false;
            fileDoc.Size    = fullSize;

            if (source != null)
            {
                fileDoc.ContentType = source.ContentType;
                fileDoc.Extension   = source.FileName.Extension;
                fileDoc.FileNameWithoutExtension = source.FileName.FileNameWithoutExtension;
            }

            // Done
            return(STT.Task.CompletedTask);
        }
        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,
            };

            using (var stream = blobProvider.GetStreamForWrite(newCtx))
                value.Stream?.CopyTo(stream);

            return(STT.Task.CompletedTask);
        }
Example #13
0
 public void InsertBinaryPropertyWithFileId(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode)
 {
     throw new NotImplementedException();
 }
Example #14
0
        public void UpdateBinaryProperty(int binaryDataId, BinaryDataValue value)
        {
            if (value.Stream != null && value.Stream.Length > Int32.MaxValue)
                throw new NotSupportedException(); // MS-SQL does not support stream size over [Int32.MaxValue]

            bool isRepositoryStream = value.Stream is RepositoryStream;

            SqlProcedure cmd = null;
            //object pointer;
            try
            {
                cmd = new SqlProcedure { CommandText = "proc_BinaryProperty_Update" };
                cmd.Parameters.Add("@BinaryPropertyId", SqlDbType.Int).Value = binaryDataId;
                cmd.Parameters.Add("@ContentType", SqlDbType.VarChar, 50).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.VarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? (object)DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.VarChar, 50).Value = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value = value.Size;
                // Do not update the stream field in the database if that is not loaded (other change happened)
                cmd.Parameters.Add("@IsStreamModified", SqlDbType.TinyInt).Value = isRepositoryStream ? 0 : 1;
                //cmd.Parameters.Add("@IsStreamModified", SqlDbType.TinyInt).Value = isLoaded ? 1 : 0;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = (value.Checksum != null) ? (object)value.Checksum : DBNull.Value; ;

                //SqlParameter pointerParameter = cmd.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
                //pointerParameter.Direction = ParameterDirection.Output;

                cmd.ExecuteNonQuery();
                //pointer = pointerParameter.Value;
            }
            finally
            {
                cmd.Dispose();
            }

            if (!isRepositoryStream && value.Stream != null && value.Stream.Length > 0)
            //if(isLoaded && stream != null && stream.Length > 0)
            {
                // Stream isloaded, exists -> write it
                WriteBinaryStream(value.Stream, binaryDataId);
            }
        }
Example #15
0
        public async Task InsertBinaryPropertyAsync(IBlobProvider blobProvider, BinaryDataValue value, int versionId, int propertyTypeId,
                                                    bool isNewNode, SnDataContext dataContext)
        {
            var streamLength = value.Stream?.Length ?? 0;
            var ctx          = new BlobStorageContext(blobProvider)
            {
                VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = 0, Length = streamLength
            };

            // In case of an external provider allocate the place for bytes and
            // write the stream beforehand and get the generated provider data.
            // Note that the external provider does not need an existing record
            // in the Files table to work, it just stores the bytes.
            if (!(blobProvider is IBuiltInBlobProvider))
            {
                await blobProvider.AllocateAsync(ctx, dataContext.CancellationToken).ConfigureAwait(false);

                using (var stream = blobProvider.GetStreamForWrite(ctx))
                    value.Stream?.CopyTo(stream);

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

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

            var sql = isNewNode ? InsertBinaryPropertyScript : DeleteAndInsertBinaryPropertyScript;

            if (!isNewNode)
            {
                dataContext.NeedToCleanupFiles = true;
            }

            await sqlCtx.ExecuteReaderAsync(sql, cmd =>
            {
                cmd.Parameters.AddRange(new[]
                {
                    sqlCtx.CreateParameter("@VersionId", DbType.Int32, versionId != 0 ? (object)versionId : DBNull.Value),
                    sqlCtx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId != 0 ? (object)propertyTypeId : DBNull.Value),
                    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, Math.Max(0, value.Size)),
                    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),
                    sqlCtx.CreateParameter("@Checksum", DbType.AnsiString, 200, value.Checksum != null ? (object)value.Checksum : DBNull.Value),
                });
            }, async (reader, cancel) =>
            {
                if (await reader.ReadAsync(cancel).ConfigureAwait(false))
                {
                    value.Id        = Convert.ToInt32(reader[0]);
                    value.FileId    = Convert.ToInt32(reader[1]);
                    value.Timestamp = Utility.Convert.BytesToLong((byte[])reader.GetValue(2));
                }
                return(true);
            }).ConfigureAwait(false);

            // The BuiltIn blob provider saves the stream after the record
            // was saved into the Files table, because simple varbinary
            // column must exist before we can write a stream into the record.
            // ReSharper disable once InvertIf
            if (blobProvider is IBuiltInBlobProvider && value.Stream != null)
            {
                ctx.FileId           = value.FileId;
                ctx.BlobProviderData = new BuiltinBlobProviderData();

                await BuiltInBlobProvider.AddStreamAsync(ctx, value.Stream, sqlCtx).ConfigureAwait(false);
            }
        }
Example #16
0
 protected internal override void CommitChunk(int versionId, int propertyTypeId, string token, long fullSize, BinaryDataValue source = null)
 {
     WriteLog(MethodInfo.GetCurrentMethod(), versionId, propertyTypeId, token, fullSize, source);
     base.CommitChunk(versionId, propertyTypeId, token, fullSize, source);
 }
Example #17
0
 public void UpdateBinaryProperty(int binaryDataId, BinaryDataValue value)
 {
     WriteLog(MethodInfo.GetCurrentMethod(), binaryDataId, value);
     _writer.UpdateBinaryProperty(binaryDataId, value);
 }
        /// <summary>
        /// Inserts a new binary property value into the metadata database and the blob storage,
        /// removing the previous one if the content is not new.
        /// </summary>
        /// <param name="blobProvider">Blob storage provider.</param>
        /// <param name="value">Binary data to insert.</param>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="isNewNode">Whether this value belongs to a new or an existing node.</param>
        public void InsertBinaryProperty(IBlobProvider blobProvider, BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode)
        {
            var streamLength = value.Stream?.Length ?? 0;
            var ctx          = new BlobStorageContext(blobProvider)
            {
                VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = 0, Length = streamLength
            };

            // In case of an external provider allocate the place for bytes and
            // write the stream beforehand and get the generated provider data.
            // Note that the external provider does not need an existing record
            // in the Files table to work, it just stores the bytes.
            if (blobProvider != BlobStorageBase.BuiltInProvider && streamLength > 0)
            {
                blobProvider.Allocate(ctx);

                using (var stream = blobProvider.GetStreamForWrite(ctx))
                    value.Stream?.CopyTo(stream);

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

            SqlProcedure cmd = null;

            try
            {
                cmd = new SqlProcedure {
                    CommandText = isNewNode ? InsertBinaryPropertyScript : DeleteAndInsertBinaryProperty, CommandType = CommandType.Text
                };

                cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value             = versionId != 0 ? (object)versionId : DBNull.Value;
                cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value        = propertyTypeId != 0 ? (object)propertyTypeId : DBNull.Value;
                cmd.Parameters.Add("@ContentType", SqlDbType.NVarChar, 450).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.NVarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.NVarChar, 50).Value     = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value                = Math.Max(0, value.Size);
                cmd.Parameters.Add("@BlobProvider", SqlDbType.NVarChar, 450).Value = value.BlobProviderName != null ? (object)value.BlobProviderName : DBNull.Value;
                cmd.Parameters.Add("@BlobProviderData", SqlDbType.NVarChar, int.MaxValue).Value = value.BlobProviderData != null ? (object)value.BlobProviderData : DBNull.Value;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = value.Checksum != null ? (object)value.Checksum : DBNull.Value;

                // insert binary and file rows and retrieve new ids.
                using (var reader = cmd.ExecuteReader())
                {
                    reader.Read();

                    value.Id        = Convert.ToInt32(reader[0]);
                    value.FileId    = Convert.ToInt32(reader[1]);
                    value.Timestamp = Utility.Convert.BytesToLong((byte[])reader.GetValue(2));
                }
            }
            finally
            {
                cmd.Dispose();
            }

            // The BuiltIn blob provider saves the stream after the record
            // was saved into the Files table, because simple varbinary
            // column must exist before we can write a stream into the record.
            // ReSharper disable once InvertIf
            if (blobProvider == BlobStorageBase.BuiltInProvider && value.Stream != null && value.Stream.Length > 0)
            {
                ctx.FileId           = value.FileId;
                ctx.BlobProviderData = new BuiltinBlobProviderData();

                BuiltInBlobProvider.AddStream(ctx, value.Stream);
            }
        }
Example #19
0
 protected internal virtual void CommitChunk(int versionId, int propertyTypeId, string token, long fullSize, BinaryDataValue source = null)
 {
     throw new NotSupportedException("Chunk upload is not supported in this data provider.");
 }
Example #20
0
        //protected internal override INodeQueryCompiler CreateNodeQueryCompiler()
        //{
        //    return new SqlCompiler();
        //}
        //protected internal override List<NodeToken> ExecuteQuery(NodeQuery query)
        //{
        //    List<NodeToken> result = new List<NodeToken>();
        //    SqlCompiler compiler = new SqlCompiler();

        //    NodeQueryParameter[] parameters;
        //    string compiledCommandText = compiler.Compile(query, out parameters);

        //    SqlProcedure command = null;
        //    SqlDataReader reader = null;
        //    try
        //    {
        //        command = new SqlProcedure { CommandText = compiledCommandText };
        //        command.CommandType = CommandType.Text;
        //        foreach (var parameter in parameters)
        //            command.Parameters.Add(new SqlParameter(parameter.Name, parameter.Value));

        //        reader = command.ExecuteReader();

        //        ReadNodeTokens(reader, result);
        //    }
        //    finally
        //    {
        //        if (reader != null && !reader.IsClosed)
        //            reader.Close();

        //        command.Dispose();
        //    }

        //    return result;
        //}

        protected internal override void LoadNodes(Dictionary<int, NodeBuilder> buildersByVersionId)
        {
            List<string> versionInfo = new List<string>();
            versionInfo.Add(String.Concat("VersionsId[count: ", buildersByVersionId.Count, "]"));

            if (buildersByVersionId.Keys.Count > 20)
            {
                versionInfo.AddRange(buildersByVersionId.Keys.Take(20).Select(x => x.ToString()));
                versionInfo.Add("...");
            }
            else
                versionInfo.AddRange(buildersByVersionId.Keys.Select(x => x.ToString()).ToArray());
            var operationTitle = String.Join(", ", versionInfo.ToArray());

            using (var traceOperation = Logger.TraceOperation("SqlProvider.LoadNodes" + operationTitle))
            {
                var builders = buildersByVersionId; // Shortcut
                SqlProcedure cmd = null;
                SqlDataReader reader = null;
                try
                {
                    cmd = new SqlProcedure { CommandText = "proc_Node_LoadData_Batch" };
                    string xmlIds = CreateIdXmlForNodeInfoBatchLoad(builders);
                    cmd.Parameters.Add("@IdsInXml", SqlDbType.Xml).Value = xmlIds;
                    reader = cmd.ExecuteReader();

                    //-- #1: FlatProperties
                    //SELECT * FROM FlatProperties
                    //    WHERE VersionId IN (select id from @versionids)
                    var versionIdIndex = reader.GetOrdinal("VersionId");
                    var pageIndex = reader.GetOrdinal("Page");

                    while (reader.Read())
                    {
                        int versionId = reader.GetInt32(versionIdIndex);
                        int page = reader.GetInt32(pageIndex);
                        NodeBuilder builder = builders[versionId];
                        foreach (PropertyType pt in builder.Token.AllPropertyTypes)
                        {
                            string mapping = PropertyMap.GetValidMapping(page, pt);
                            if (mapping.Length != 0)
                            {
                                // Mapped property appears in the given page
                                object val = reader[mapping];
                                builder.AddDynamicProperty(pt, (val == DBNull.Value) ? null : val);
                            }
                        }
                    }

                    reader.NextResult();


                    //-- #2: BinaryProperties
                    //SELECT BinaryPropertyId, VersionId, PropertyTypeId, ContentType, FileNameWithoutExtension,
                    //    Extension, [Size], [Checksum], NULL AS Stream, 0 AS Loaded
                    //FROM dbo.BinaryProperties
                    //WHERE PropertyTypeId IN (select id from @binids) AND VersionId IN (select id from @versionids)
                    var binaryPropertyIdIndex = reader.GetOrdinal("BinaryPropertyId");
                    versionIdIndex = reader.GetOrdinal("VersionId");
                    var checksumPropertyIndex = reader.GetOrdinal("Checksum");
                    var propertyTypeIdIndex = reader.GetOrdinal("PropertyTypeId");
                    var contentTypeIndex = reader.GetOrdinal("ContentType");
                    var fileNameWithoutExtensionIndex = reader.GetOrdinal("FileNameWithoutExtension");
                    var extensionIndex = reader.GetOrdinal("Extension");
                    var sizeIndex = reader.GetOrdinal("Size");

                    while (reader.Read())
                    {
                        string ext = reader.GetString(extensionIndex);
                        if (ext.Length != 0)
                            ext = ext.Remove(0, 1); // Remove dot from the start if extension is not empty

                        string fn = reader.GetSafeString(fileNameWithoutExtensionIndex); // reader.IsDBNull(fileNameWithoutExtensionIndex) ? null : reader.GetString(fileNameWithoutExtensionIndex);

                        var x = new BinaryDataValue
                        {
                            Id = reader.GetInt32(binaryPropertyIdIndex),
                            Checksum = reader.GetSafeString(checksumPropertyIndex), //reader.IsDBNull(checksumPropertyIndex) ? null : reader.GetString(checksumPropertyIndex),
                            FileName = new BinaryFileName(fn, ext),
                            ContentType = reader.GetString(contentTypeIndex),
                            Size = reader.GetInt64(sizeIndex)
                        };

                        var versionId = reader.GetInt32(versionIdIndex);
                        var propertyTypeId = reader.GetInt32(propertyTypeIdIndex);
                        builders[versionId].AddDynamicProperty(propertyTypeId, x);
                    }

                    reader.NextResult();


                    //-- #3: ReferencePropertyInfo + Referred NodeToken
                    //SELECT VersionId, PropertyTypeId, ReferredNodeId
                    //FROM dbo.ReferenceProperties ref
                    //WHERE ref.VersionId IN (select id from @versionids)
                    versionIdIndex = reader.GetOrdinal("VersionId");
                    propertyTypeIdIndex = reader.GetOrdinal("PropertyTypeId");
                    var nodeIdIndex = reader.GetOrdinal("ReferredNodeId");

                    //-- Collect references to Dictionary<versionId, Dictionary<propertyTypeId, List<referredNodeId>>>
                    var referenceCollector = new Dictionary<int, Dictionary<int, List<int>>>();
                    while (reader.Read())
                    {
                        var versionId = reader.GetInt32(versionIdIndex);
                        var propertyTypeId = reader.GetInt32(propertyTypeIdIndex);
                        var referredNodeId = reader.GetInt32(nodeIdIndex);

                        if (!referenceCollector.ContainsKey(versionId))
                            referenceCollector.Add(versionId, new Dictionary<int, List<int>>());
                        var referenceCollectorPerVersion = referenceCollector[versionId];
                        if (!referenceCollectorPerVersion.ContainsKey(propertyTypeId))
                            referenceCollectorPerVersion.Add(propertyTypeId, new List<int>());
                        referenceCollectorPerVersion[propertyTypeId].Add(referredNodeId);
                    }
                    //-- Set references to NodeData
                    foreach (var versionId in referenceCollector.Keys)
                    {
                        var referenceCollectorPerVersion = referenceCollector[versionId];
                        foreach (var propertyTypeId in referenceCollectorPerVersion.Keys)
                            builders[versionId].AddDynamicProperty(propertyTypeId, referenceCollectorPerVersion[propertyTypeId]);
                    }

                    reader.NextResult();


                    //-- #4: TextPropertyInfo (NText:Lazy, NVarchar(4000):loaded)
                    //SELECT VersionId, PropertyTypeId, NULL AS Value, 0 AS Loaded
                    //FROM dbo.TextPropertiesNText
                    //WHERE VersionId IN (select id from @versionids)
                    //UNION ALL
                    //SELECT VersionId, PropertyTypeId, Value, 1 AS Loaded
                    //FROM dbo.TextPropertiesNVarchar
                    //WHERE VersionId IN (select id from @versionids)
                    versionIdIndex = reader.GetOrdinal("VersionID");
                    propertyTypeIdIndex = reader.GetOrdinal("PropertyTypeId");
                    var valueIndex = reader.GetOrdinal("Value");
                    var loadedIndex = reader.GetOrdinal("Loaded");

                    while (reader.Read())
                    {
                        int versionId = reader.GetInt32(versionIdIndex);
                        int propertyTypeId = reader.GetInt32(propertyTypeIdIndex);
                        string value = reader.GetSafeString(valueIndex); // (reader[valueIndex] == DBNull.Value) ? null : reader.GetString(valueIndex);
                        bool loaded = Convert.ToBoolean(reader.GetInt32(loadedIndex));

                        if (loaded)
                            builders[versionId].AddDynamicProperty(propertyTypeId, value);
                    }

                    reader.NextResult();


                    //-- #5: BaseData
                    //SELECT N.NodeId, N.NodeTypeId, N.ContentListTypeId, N.ContentListId, N.IsDeleted, N.IsInherited, 
                    //    N.ParentNodeId, N.[Name], N.[Path], N.[Index], N.Locked, N.LockedById, 
                    //    N.ETag, N.LockType, N.LockTimeout, N.LockDate, N.LockToken, N.LastLockUpdate,
                    //    N.CreationDate AS NodeCreationDate, N.CreatedById AS NodeCreatedById, 
                    //    N.ModificationDate AS NodeModificationDate, N.ModifiedById AS NodeModifiedById,
                    //    V.VersionId, V.MajorNumber, V.MinorNumber, V.CreationDate, V.CreatedById, 
                    //    V.ModificationDate, V.ModifiedById, V.[Status]
                    //FROM dbo.Nodes AS N 
                    //    INNER JOIN dbo.Versions AS V ON N.NodeId = V.NodeId ON N.NodeId = V.NodeId
                    //WHERE V.VersionId IN (select id from @versionids)
                    nodeIdIndex = reader.GetOrdinal("NodeId");
                    var nodeTypeIdIndex = reader.GetOrdinal("NodeTypeId");
                    var contentListTypeIdIndex = reader.GetOrdinal("ContentListTypeId");
                    var contentListIdIndex = reader.GetOrdinal("ContentListId");
                    var isDeletedIndex = reader.GetOrdinal("IsDeleted");
                    var isInheritedIndex = reader.GetOrdinal("IsInherited");
                    var parentNodeIdIndex = reader.GetOrdinal("ParentNodeId");
                    var nameIndex = reader.GetOrdinal("Name");
                    var displayNameIndex = reader.GetOrdinal("DisplayName");
                    var pathIndex = reader.GetOrdinal("Path");
                    var indexIndex = reader.GetOrdinal("Index");
                    var lockedIndex = reader.GetOrdinal("Locked");
                    var lockedByIdIndex = reader.GetOrdinal("LockedById");
                    var eTagIndex = reader.GetOrdinal("ETag");
                    var lockTypeIndex = reader.GetOrdinal("LockType");
                    var lockTimeoutIndex = reader.GetOrdinal("LockTimeout");
                    var lockDateIndex = reader.GetOrdinal("LockDate");
                    var lockTokenIndex = reader.GetOrdinal("LockToken");
                    var lastLockUpdateIndex = reader.GetOrdinal("LastLockUpdate");
                    var nodeCreationDateIndex = reader.GetOrdinal("NodeCreationDate");
                    var nodeCreatedByIdIndex = reader.GetOrdinal("NodeCreatedById");
                    var nodeModificationDateIndex = reader.GetOrdinal("NodeModificationDate");
                    var nodeModifiedByIdIndex = reader.GetOrdinal("NodeModifiedById");
                    var nodeTimestampIndex = reader.GetOrdinal("NodeTimestamp");

                    versionIdIndex = reader.GetOrdinal("VersionId");
                    var majorNumberIndex = reader.GetOrdinal("MajorNumber");
                    var minorNumberIndex = reader.GetOrdinal("MinorNumber");
                    var creationDateIndex = reader.GetOrdinal("CreationDate");
                    var createdByIdIndex = reader.GetOrdinal("CreatedById");
                    var modificationDateIndex = reader.GetOrdinal("ModificationDate");
                    var modifiedByIdIndex = reader.GetOrdinal("ModifiedById");
                    var status = reader.GetOrdinal("Status");
                    var versionTimestampIndex = reader.GetOrdinal("VersionTimestamp");

                    while (reader.Read())
                    {
                        int versionId = reader.GetInt32(versionIdIndex);

                        VersionNumber versionNumber = new VersionNumber(
                            reader.GetInt16(majorNumberIndex),
                            reader.GetInt16(minorNumberIndex),
                            (VersionStatus)reader.GetInt16(status));

                        builders[versionId].SetCoreAttributes(
                            reader.GetInt32(nodeIdIndex),
                            reader.GetInt32(nodeTypeIdIndex),
                            TypeConverter.ToInt32(reader.GetValue(contentListIdIndex)),
                            TypeConverter.ToInt32(reader.GetValue(contentListTypeIdIndex)),
                            Convert.ToBoolean(reader.GetByte(isDeletedIndex)),
                            Convert.ToBoolean(reader.GetByte(isInheritedIndex)),
                            reader.GetSafeInt32(parentNodeIdIndex), // reader.GetValue(parentNodeIdIndex) == DBNull.Value ? 0 : reader.GetInt32(parentNodeIdIndex), //parent,
                            reader.GetString(nameIndex),
                            reader.GetSafeString(displayNameIndex),
                            reader.GetString(pathIndex),
                            reader.GetInt32(indexIndex),
                            Convert.ToBoolean(reader.GetByte(lockedIndex)),
                            reader.GetSafeInt32(lockedByIdIndex), // reader.GetValue(lockedByIdIndex) == DBNull.Value ? 0 : reader.GetInt32(lockedByIdIndex),
                            reader.GetString(eTagIndex),
                            reader.GetInt32(lockTypeIndex),
                            reader.GetInt32(lockTimeoutIndex),
                            reader.GetDateTime(lockDateIndex),
                            reader.GetString(lockTokenIndex),
                            reader.GetDateTime(lastLockUpdateIndex),
                            versionId,
                            versionNumber,
                            reader.GetDateTime(creationDateIndex),
                            reader.GetInt32(createdByIdIndex),
                            reader.GetDateTime(modificationDateIndex),
                            reader.GetInt32(modifiedByIdIndex),
                            reader.GetDateTime(nodeCreationDateIndex),
                            reader.GetInt32(nodeCreatedByIdIndex),
                            reader.GetDateTime(nodeModificationDateIndex),
                            reader.GetInt32(nodeModifiedByIdIndex),
                            GetLongFromBytes((byte[])reader.GetValue(nodeTimestampIndex)),
                            GetLongFromBytes((byte[])reader.GetValue(versionTimestampIndex))
                            );
                    }
                    foreach (var builder in builders.Values)
                        builder.Finish();
                }
                finally
                {
                    if (reader != null && !reader.IsClosed)
                        reader.Close();

                    cmd.Dispose();
                }
                traceOperation.IsSuccessful = true;
            }
        }
Example #21
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);
            }
        }
Example #22
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);
                }
            }
        }
Example #23
0
 protected internal abstract void CommitChunk(int versionId, int propertyTypeId, string token, long fullSize, BinaryDataValue source = null);
Example #24
0
        public int InsertBinaryProperty(int versionId, int propertyTypeId, BinaryDataValue value, bool isNewNode)
        {
            if (value.Stream != null && value.Stream.Length > Int32.MaxValue)
                throw new NotSupportedException(); // MS-SQL does not support stream size over [Int32.MaxValue]

            SqlProcedure cmd = null;
            int id;

            try
            {
                cmd = new SqlProcedure { CommandText = (isNewNode ? INSERT_BINARY_PROPERTY : DELETE_AND_INSERT_BINARY_PROPERTY), CommandType = CommandType.Text };
                cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value = (versionId != 0) ? (object)versionId : DBNull.Value;
                cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value = (propertyTypeId != 0) ? (object)propertyTypeId : DBNull.Value;
                cmd.Parameters.Add("@ContentType", SqlDbType.VarChar, 50).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.VarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.VarChar, 50).Value = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value = value.Size;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = (value.Checksum != null) ? (object)value.Checksum : DBNull.Value;

                if (value.Stream != null && value.Stream.Length > 0)
                {
                    var streamSize = Convert.ToInt32(value.Stream.Length);
                    var buffer = new byte[streamSize];
                    value.Stream.Seek(0, SeekOrigin.Begin);
                    value.Stream.Read(buffer, 0, streamSize);

                    cmd.Parameters.Add(new SqlParameter("@Value", SqlDbType.VarBinary)).Value = buffer;
                }
                else
                {
                    cmd.Parameters.Add(new SqlParameter("@Value", SqlDbType.VarBinary)).Value = DBNull.Value;
                }

                id = Convert.ToInt32(cmd.ExecuteScalar(), CultureInfo.CurrentCulture);
            }
            finally
            {
                if (cmd != null)
                    cmd.Dispose();
            }

            return id;
        }
Example #25
0
 public int InsertBinaryProperty(int versionId, int propertyTypeId, BinaryDataValue value, bool isNewNode)
 {
     WriteLog(MethodInfo.GetCurrentMethod(), versionId, propertyTypeId, value, isNewNode);
     return(_writer.InsertBinaryProperty(versionId, propertyTypeId, value, isNewNode));
 }
Example #26
0
        public void UpdateBinaryProperty(IBlobProvider blobProvider, BinaryDataValue value)
        {
            var streamLength = value.Stream?.Length ?? 0;
            var isExternal   = false;

            if (streamLength > 0)
            {
                var ctx = new BlobStorageContext(blobProvider, value.BlobProviderData)
                {
                    VersionId      = 0,
                    PropertyTypeId = 0,
                    FileId         = value.FileId,
                    Length         = streamLength,
                };

                blobProvider.Allocate(ctx);
                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;
            }

            var db     = _dataProvider.DB;
            var fileId = db.Files.Count == 0 ? 1 : db.Files.Max(r => r.FileId) + 1;

            db.Files.Add(new InMemoryDataProvider.FileRecord
            {
                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 binaryPropertyRow = db.BinaryProperties.FirstOrDefault(r => r.BinaryPropertyId == value.Id);

            if (binaryPropertyRow != null)
            {
                binaryPropertyRow.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,
            };

            using (var stream = blobProvider.GetStreamForWrite(newCtx))
                value.Stream?.CopyTo(stream);
        }
Example #27
0
 public void UpdateBinaryProperty(BinaryDataValue value)
 {
     WriteLog(MethodBase.GetCurrentMethod(), value);
     _writer.UpdateBinaryProperty(value);
 }
Example #28
0
 public void CommitChunk(int versionId, int propertyTypeId, int fileId, long fullSize, BinaryDataValue source)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Updates an existing binary property value in the database and the blob storage.
        /// </summary>
        /// <param name="blobProvider">Blob storage provider.</param>
        /// <param name="value">Binary data to update.</param>
        public void UpdateBinaryProperty(IBlobProvider blobProvider, BinaryDataValue value)
        {
            var streamLength = value.Stream?.Length ?? 0;

            if (blobProvider != BlobStorageBase.BuiltInProvider && streamLength > 0)
            {
                var ctx = new BlobStorageContext(blobProvider, value.BlobProviderData)
                {
                    VersionId      = 0,
                    PropertyTypeId = 0,
                    FileId         = value.FileId,
                    Length         = streamLength,
                };

                blobProvider.Allocate(ctx);
                using (var stream = blobProvider.GetStreamForWrite(ctx))
                    value.Stream?.CopyTo(stream);

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

            if (blobProvider == BlobStorageBase.BuiltInProvider)
            {
                // 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 (!hasStream)
            {
                // do not do any database operation if the stream is not modified
                return;
            }

            SqlProcedure cmd = null;

            try
            {
                string      sql;
                CommandType commandType;
                if (blobProvider == BlobStorageBase.BuiltInProvider)
                {
                    commandType = CommandType.StoredProcedure;
                    sql         = "proc_BinaryProperty_Update";
                }
                else
                {
                    commandType = CommandType.Text;
                    sql         = UpdateBinaryPropertyNewFilerowScript;
                }

                cmd = new SqlProcedure {
                    CommandText = sql, CommandType = commandType
                };
                cmd.Parameters.Add("@BinaryPropertyId", SqlDbType.Int).Value      = value.Id;
                cmd.Parameters.Add("@ContentType", SqlDbType.NVarChar, 450).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.NVarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.NVarChar, 50).Value     = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value                = value.Size;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value      = value.Checksum != null ? (object)value.Checksum : DBNull.Value;
                cmd.Parameters.Add("@BlobProvider", SqlDbType.NVarChar, 450).Value = value.BlobProviderName != null ? (object)value.BlobProviderName : DBNull.Value;
                cmd.Parameters.Add("@BlobProviderData", SqlDbType.NVarChar, int.MaxValue).Value = value.BlobProviderData != null ? (object)value.BlobProviderData : DBNull.Value;

                var fileId = (int)cmd.ExecuteScalar();
                if (fileId > 0 && fileId != value.FileId)
                {
                    value.FileId = fileId;
                }
            }
            finally
            {
                cmd.Dispose();
            }

            // ReSharper disable once InvertIf
            if (blobProvider == BlobStorageBase.BuiltInProvider && !isRepositoryStream && streamLength > 0)
            {
                // 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()
                };

                BuiltInBlobProvider.UpdateStream(ctx, value.Stream);
            }
        }
Example #30
0
 private static void SetBinaryPropertyRow(DataRow row, int versionId, int propertyTypeId, BinaryDataValue data)
 {
     row["BinaryPropertyId"] = data.Id;
     row["VersionId"]        = versionId;
     row["PropertyTypeId"]   = propertyTypeId;
     row["FileId"]           = data.FileId;
 }
        /// <summary>
        /// Finalizes a chunked save operation.
        /// </summary>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="token">Blob token provided by a preliminary request.</param>
        /// <param name="fullSize">Full size (stream length) of the binary value.</param>
        /// <param name="source">Binary data containing metadata (e.g. content type).</param>
        protected internal static void CommitChunk(int versionId, int propertyTypeId, string token, long fullSize, BinaryDataValue source = null)
        {
            var tokenData = ChunkToken.Parse(token, versionId);

            BlobStorageComponents.DataProvider.CommitChunk(versionId, propertyTypeId, tokenData.FileId, fullSize, source);
        }
        /// <summary>
        /// Finalizes a chunked save operation.
        /// </summary>
        /// <param name="versionId">Content version id.</param>
        /// <param name="propertyTypeId">Binary property type id.</param>
        /// <param name="fileId">File identifier.</param>
        /// <param name="fullSize">Full size (stream length) of the binary value.</param>
        /// <param name="source">Binary data containing metadata (e.g. content type).</param>
        public void CommitChunk(int versionId, int propertyTypeId, int fileId, long fullSize, BinaryDataValue source = null)
        {
            // start a new transaction here if needed
            var isLocalTransaction = !TransactionScope.IsActive;

            if (isLocalTransaction)
            {
                TransactionScope.Begin();
            }

            try
            {
                // commit the process: set the final full size and checksum
                using (var cmd = new SqlProcedure {
                    CommandText = CommitChunkScript, CommandType = CommandType.Text
                })
                {
                    cmd.Parameters.Add("@FileId", SqlDbType.Int).Value            = fileId;
                    cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value         = versionId;
                    cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value    = propertyTypeId;
                    cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value           = fullSize;
                    cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = DBNull.Value;

                    cmd.Parameters.Add("@ContentType", SqlDbType.NVarChar, 50).Value = source != null ? source.ContentType : string.Empty;
                    cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.NVarChar, 450).Value = source != null
                        ? source.FileName.FileNameWithoutExtension == null
                            ? DBNull.Value
                            : (object)source.FileName.FileNameWithoutExtension
                        : DBNull.Value;

                    cmd.Parameters.Add("@Extension", SqlDbType.NVarChar, 50).Value = source != null?ValidateExtension(source.FileName.Extension) : string.Empty;

                    cmd.ExecuteNonQuery();
                }
            }
            catch (Exception ex)
            {
                // rollback the transaction if it was opened locally
                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Rollback();
                }

                throw new DataException("Error during committing binary chunk to file stream.", ex);
            }
            finally
            {
                // commit the transaction if it was opened locally
                if (isLocalTransaction && TransactionScope.IsActive)
                {
                    TransactionScope.Commit();
                }
            }
        }
        /// <summary>
        /// Updates an existing binary property value in the database and the blob storage.
        /// </summary>
        /// <param name="value">Binary data to update.</param>
        protected internal static void UpdateBinaryProperty(BinaryDataValue value)
        {
            var blobProvider = GetProvider(value.Size);

            BlobStorageComponents.DataProvider.UpdateBinaryProperty(blobProvider, value);
        }
Example #34
0
        public int InsertBinaryPropertyOld(int versionId, int propertyTypeId, BinaryDataValue value)
        {
            if (value.Stream != null && value.Stream.Length > Int32.MaxValue)
                throw new NotSupportedException(); // MS-SQL does not support stream size over [Int32.MaxValue]

            SqlProcedure cmd = null;
            //object pointer;
            int id = 0;
            try
            {
                cmd = new SqlProcedure { CommandText = "proc_BinaryProperty_Insert" };
                cmd.Parameters.Add("@VersionId", SqlDbType.Int).Value = (versionId != 0) ? (object)versionId : DBNull.Value;
                cmd.Parameters.Add("@PropertyTypeId", SqlDbType.Int).Value = (propertyTypeId != 0) ? (object)propertyTypeId : DBNull.Value;
                cmd.Parameters.Add("@ContentType", SqlDbType.VarChar, 50).Value = value.ContentType;
                cmd.Parameters.Add("@FileNameWithoutExtension", SqlDbType.VarChar, 450).Value = value.FileName.FileNameWithoutExtension == null ? (object)DBNull.Value : (object)value.FileName.FileNameWithoutExtension;
                cmd.Parameters.Add("@Extension", SqlDbType.VarChar, 50).Value = ValidateExtension(value.FileName.Extension);
                cmd.Parameters.Add("@Size", SqlDbType.BigInt).Value = value.Size;
                cmd.Parameters.Add("@Checksum", SqlDbType.VarChar, 200).Value = (value.Checksum != null) ? (object)value.Checksum : DBNull.Value; ;

                //SqlParameter pointerParameter = cmd.Parameters.Add("@Pointer", SqlDbType.Binary, 16);
                //pointerParameter.Direction = ParameterDirection.Output;

                id = Convert.ToInt32(cmd.ExecuteScalar(), CultureInfo.CurrentCulture);
                //pointer = pointerParameter.Value;
            }
            finally
            {
                cmd.Dispose();
            }

            if (value.Stream != null && value.Stream.Length > 0)
            {
                // Stream exists -> write it
                WriteBinaryStream(value.Stream, id);
            }

            return id;
        }