public async Task InsertBinaryPropertyWithFileIdAsync(BinaryDataValue value, int versionId, int propertyTypeId, bool isNewNode, SnDataContext dataContext) { var sql = isNewNode ? InsertBinaryPropertyWithKnownFileIdScript : DeleteAndInsertBinaryPropertyWithKnownFileIdScript; if (!isNewNode) { dataContext.NeedToCleanupFiles = true; } 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); }
public void DC_Dispose() { SnDataContext dataContext = null; TestConnection testConnection = null; TestTransaction testTransaction = null; try { using (dataContext = new TestDataContext(CancellationToken.None)) { Assert.IsFalse(dataContext.IsDisposed); using (var transaction = dataContext.BeginTransaction(IsolationLevel.ReadCommitted, TimeSpan.FromMinutes(10))) { testConnection = (TestConnection)dataContext.Connection; testTransaction = (TestTransaction)dataContext.Transaction.Transaction; throw new SnNotSupportedException(); } } } catch (SnNotSupportedException) { // do nothing } Assert.IsTrue(testConnection.State == ConnectionState.Closed); Assert.IsTrue(testTransaction.IsRollbackCalled); Assert.IsTrue(dataContext.IsDisposed); }
internal static void DropPackagesTable(SnDataContext ctx) { var sql = @" IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Packages]') AND type in (N'U')) DROP TABLE [dbo].[Packages] "; ctx.ExecuteNonQueryAsync(sql).GetAwaiter().GetResult(); }
public STT.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 }; // blob operation blobProvider.AllocateAsync(ctx, CancellationToken.None).GetAwaiter().GetResult(); 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) { DeleteBinaryPropertyAsync(versionId, propertyTypeId, dataContext).GetAwaiter().GetResult(); } 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 binaryPropertyId = db.BinaryProperties.GetNextId(); db.BinaryProperties.Insert(new BinaryPropertyDoc { BinaryPropertyId = binaryPropertyId, FileId = fileId, PropertyTypeId = propertyTypeId, VersionId = versionId }); value.Id = binaryPropertyId; value.FileId = fileId; value.Timestamp = 0L; //TODO: file row timestamp return(STT.Task.CompletedTask); }
public STT.Task DeleteBinaryPropertiesAsync(IEnumerable <int> versionIds, SnDataContext dataContext) { var db = DataProvider.DB; foreach (var item in db.BinaryProperties .Where(x => versionIds.Contains(x.VersionId)) .ToArray()) { db.BinaryProperties.Remove(item); } return(STT.Task.CompletedTask); }
public STT.Task DeleteBinaryPropertyAsync(int versionId, int propertyTypeId, SnDataContext dataContext) { var db = DataProvider.DB; foreach (var item in db.BinaryProperties .Where(x => x.VersionId == versionId && x.PropertyTypeId == propertyTypeId) .ToArray()) { db.BinaryProperties.Remove(item); } return(STT.Task.CompletedTask); }
public async Task DeleteBinaryPropertiesAsync(IEnumerable <int> versionIds, SnDataContext dataContext) { if (!(dataContext is MsSqlDataContext sqlCtx)) { throw new PlatformNotSupportedException(); } await sqlCtx.ExecuteNonQueryAsync(DeleteBinaryPropertiesScript, cmd => { var idsParam = string.Join(",", versionIds.Select(x => x.ToString())); cmd.Parameters.Add(sqlCtx.CreateParameter("@VersionIds", DbType.String, idsParam.Length, idsParam)); }).ConfigureAwait(false); }
internal static void InstallPackagesTable(SnDataContext ctx) { var sql = @" CREATE TABLE [dbo].[Packages]( [Id] [int] IDENTITY(1,1) NOT NULL, [PackageType] [varchar](50) NOT NULL, [ComponentId] [nvarchar](450) NULL, [ComponentVersion] [varchar](50) NULL, [ReleaseDate] [datetime2](7) NOT NULL, [ExecutionDate] [datetime2](7) NOT NULL, [ExecutionResult] [varchar](50) NOT NULL, [ExecutionError] [nvarchar](max) NULL, [Description] [nvarchar](1000) NULL, [Manifest] [nvarchar](max) NULL, CONSTRAINT [PK_Packages] PRIMARY KEY CLUSTERED ( [Id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] "; ctx.ExecuteNonQueryAsync(sql).GetAwaiter().GetResult(); }
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 async Task <BinaryCacheEntity> LoadBinaryCacheEntityAsync(int versionId, int propertyTypeId, SnDataContext dataContext) { if (!(dataContext is MsSqlDataContext sqlCtx)) { throw new PlatformNotSupportedException(); } return(await sqlCtx.ExecuteReaderAsync(LoadBinaryCacheEntityScript, cmd => { cmd.Parameters.AddRange(new[] { sqlCtx.CreateParameter("@MaxSize", DbType.Int32, BlobStorageOptions.BinaryCacheSize), sqlCtx.CreateParameter("@VersionId", DbType.Int32, versionId), sqlCtx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId), }); }, async (reader, cancel) => { cancel.ThrowIfCancellationRequested(); if (!reader.HasRows || !await reader.ReadAsync(cancel).ConfigureAwait(false)) { return null; } var length = reader.GetInt64(0); var binaryPropertyId = reader.GetInt32(1); var fileId = reader.GetInt32(2); var providerName = reader.GetSafeString(3); var providerTextData = reader.GetSafeString(4); byte[] rawData = null; var provider = Providers.GetProvider(providerName); var context = new BlobStorageContext(provider, providerTextData) { VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = fileId, Length = length }; if (provider is IBuiltInBlobProvider) { context.BlobProviderData = new BuiltinBlobProviderData(); if (!reader.IsDBNull(5)) { rawData = (byte[])reader.GetValue(5); } } return new BinaryCacheEntity { Length = length, RawData = rawData, BinaryPropertyId = binaryPropertyId, FileId = fileId, Context = context }; }).ConfigureAwait(false)); }
public Task <BinaryCacheEntity> LoadBinaryCacheEntityAsync(int versionId, int propertyTypeId, SnDataContext dataContext) { 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 == binaryDoc.FileId); if (fileDoc == null) { return(null); } if (fileDoc.Staging) { return(null); } var length = fileDoc.Size; var binaryPropertyId = binaryDoc.BinaryPropertyId; var fileId = fileDoc.FileId; var providerName = fileDoc.BlobProvider; var providerTextData = fileDoc.BlobProviderData; var rawData = fileDoc.Buffer; var provider = BlobStorageBase.GetProvider(providerName); var context = new BlobStorageContext(provider, providerTextData) { VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = fileId, Length = length, }; var result = new BinaryCacheEntity { Length = length, RawData = rawData, BinaryPropertyId = binaryPropertyId, FileId = fileId, Context = context }; return(STT.Task.FromResult(result)); }
public Task <BinaryDataValue> LoadBinaryPropertyAsync(int versionId, int propertyTypeId, SnDataContext dataContext) { var db = DataProvider.DB; BinaryDataValue result = null; var binaryDoc = db.BinaryProperties.FirstOrDefault(x => x.VersionId == versionId && x.PropertyTypeId == propertyTypeId); if (binaryDoc == null) { return(STT.Task.FromResult(result)); } var fileDoc = db.Files.FirstOrDefault(x => x.FileId == binaryDoc.FileId); if (fileDoc == null) { return(STT.Task.FromResult(result)); } if (fileDoc.Staging) { return(STT.Task.FromResult(result)); } result = CreateBinaryDataValue(db, binaryDoc, fileDoc); return(STT.Task.FromResult(result)); }
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); }
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); } }
public async Task <BinaryDataValue> LoadBinaryPropertyAsync(int versionId, int propertyTypeId, SnDataContext dataContext) { if (!(dataContext is MsSqlDataContext sqlCtx)) { throw new PlatformNotSupportedException(); } return(await sqlCtx.ExecuteReaderAsync(LoadBinaryPropertyScript, cmd => { cmd.Parameters.AddRange(new[] { sqlCtx.CreateParameter("@VersionId", DbType.Int32, versionId), sqlCtx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId), }); }, async (reader, cancel) => { cancel.ThrowIfCancellationRequested(); if (!await reader.ReadAsync(cancel).ConfigureAwait(false)) { return null; } var size = reader.GetInt64("Size"); var binaryPropertyId = reader.GetInt32("BinaryPropertyId"); var fileId = reader.GetInt32("FileId"); var providerName = reader.GetSafeString("BlobProvider"); var providerTextData = reader.GetSafeString("BlobProviderData"); var provider = Providers.GetProvider(providerName); var context = new BlobStorageContext(provider, providerTextData) { VersionId = versionId, PropertyTypeId = propertyTypeId, FileId = fileId, Length = size }; Stream stream = null; if (provider is IBuiltInBlobProvider) { context.BlobProviderData = new BuiltinBlobProviderData(); var streamIndex = reader.GetOrdinal("Stream"); if (!reader.IsDBNull(streamIndex)) { var rawData = (byte[])reader.GetValue(streamIndex); stream = new MemoryStream(rawData); } } return new BinaryDataValue { Id = binaryPropertyId, FileId = fileId, ContentType = reader.GetSafeString("ContentType"), FileName = new BinaryFileName( reader.GetSafeString("FileNameWithoutExtension") ?? "", reader.GetSafeString("Extension") ?? ""), Size = size, Checksum = reader.GetSafeString("Checksum"), BlobProviderName = providerName, BlobProviderData = providerTextData, Timestamp = reader.GetSafeLongFromBytes("Timestamp"), Stream = stream }; }).ConfigureAwait(false)); }
public async Task DeleteBinaryPropertyAsync(int versionId, int propertyTypeId, SnDataContext dataContext) { if (!(dataContext is MsSqlDataContext sqlCtx)) { throw new PlatformNotSupportedException(); } await sqlCtx.ExecuteNonQueryAsync(DeleteBinaryPropertyScript, cmd => { cmd.Parameters.AddRange(new[] { sqlCtx.CreateParameter("@VersionId", DbType.Int32, versionId), sqlCtx.CreateParameter("@PropertyTypeId", DbType.Int32, propertyTypeId), }); }).ConfigureAwait(false); }
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); } } }