/// <summary> /// Load file data with the given hash from the given repository. /// </summary> /// <param name="fileRepository"></param> /// <param name="token"></param> /// <param name="context"></param> /// <returns></returns> internal static byte[] LoadFileData(IFileRepository fileRepository, string token, IProcessingContext context) { byte[] data; if (string.IsNullOrWhiteSpace(token)) { return(null); } using (var stream = new MemoryStream( )) { try { using (var sourceStream = fileRepository.Get(token)) { sourceStream.CopyTo(stream); } data = stream.ToArray( ); } catch (FileNotFoundException) { context.WriteWarning($"File not found. (Hash: {token})"); data = null; } catch (Exception ex) { context.WriteWarning($"An error occurred getting the file from file repository. DataHash: {token}. Error {ex}."); data = null; } } return(data); }
/// <summary> /// Load entities. /// </summary> /// <param name="context"></param> /// <returns></returns> public virtual IEnumerable <EntityEntry> GetEntities(IProcessingContext context) { ///// // Query entities that are part of the solution ///// const string sql = @"select EntityUid from AppEntity e where e.AppVerUid = @appVer"; using (IDbCommand command = CreateCommand( )) { command.CommandText = sql; command.AddParameterWithValue("@appVer", AppVerId); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } var entry = new EntityEntry { EntityId = reader.GetGuid(0) }; yield return(entry); } } } }
/// <summary> /// Load entities. /// </summary> /// <param name="context"></param> /// <returns></returns> public IEnumerable <EntityEntry> GetEntities(IProcessingContext context) { ///// // Query entities that are part of the solution ///// const string sql = @"select Uid from _Entity"; using (IDbCommand command = CreateCommand( )) { command.CommandText = sql; using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } var entry = new EntityEntry { EntityId = reader.GetGuid(0) }; yield return(entry); } } } }
/// <summary> /// Gets the entities that should not be removed as part of an upgrade operation. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> public virtual IEnumerable <Guid> GetDoNotRemove(IProcessingContext context) { ///// // Query entities that have been marked as do-not-remove during upgrade of a solution. ///// const string sql = @"select EntityUid from AppDoNotRemove d where d.AppVerUid = @appVer"; using (IDbCommand command = CreateCommand( )) { command.CommandText = sql; command.AddParameterWithValue("@appVer", AppVerId); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context.WriteWarning("Unexpected null EntityUid in AppDoNotRemove."); continue; } Guid entityUid = reader.GetGuid(0); yield return(entityUid); } } } }
/// <summary> /// Writes the binary data. /// </summary> /// <param name="data">The data.</param> /// <param name="context">The context.</param> void IDataTarget.WriteBinaryData(IEnumerable <BinaryDataEntry> data, IProcessingContext context) { int rowCount = 0; using (var command = CreateCommand( ) as SQLiteCommand) { Debug.Assert(command != null, "command != null"); const string sql = "insert into _Filestream_Binary (FileExtension, DataHash, Data) values (@fileExtension, @dataHash, @data)"; command.CommandType = CommandType.Text; command.CommandText = sql; foreach (BinaryDataEntry dataEntry in data) { if (dataEntry.Data == null) { context.WriteWarning($"Unexpected null values when updating binary table. DataHash:{dataEntry.DataHash}"); continue; } if (!IsBinaryDataValid(dataEntry.Data, dataEntry.DataHash)) { context.WriteWarning($"The binary data is corrupt. It will be skipped. The data hash does not match the expected value. DataHash:{dataEntry.DataHash}"); continue; } command.Parameters.Clear( ); command.Parameters.Add("@fileExtension", DbType.String).Value = dataEntry.FileExtension; command.Parameters.Add("@dataHash", DbType.String).Value = dataEntry.DataHash; byte[] compressedData = CompressionHelper.Compress(dataEntry.Data); command.Parameters.Add("@data", DbType.Binary, compressedData.Length).Value = compressedData; rowCount += command.ExecuteNonQuery( ); if (rowCount % 100 == 0) { context.WriteInfo($"Copying binary data... {rowCount} rows"); } } } }
public void WriteDocumentData(IEnumerable <DocumentDataEntry> data, IProcessingContext context) { Func <DataColumn[]> getColumnsAction = () => new[] { new DataColumn("DataHash", typeof(string)) { AllowDBNull = false } }; Func <DocumentDataEntry, DataRow, PopulateRowResult> populateRowAction = (entry, row) => { if (entry.Data == null) { return(PopulateRowResult.InvalidData); } using (var source = new MemoryStream(entry.Data)) { try { Factory.DocumentFileRepository.Put(source); } catch (Exception ex) { context.WriteWarning($"An error occurred putting document into file repository. DataHash: {entry.DataHash}. Error {ex.ToString( )}."); return(PopulateRowResult.InvalidData); } } return(PopulateRowResult.Ignore); }; var executionArguments = new ExecutionArguments <DocumentDataEntry> { Entries = data, GetColumnsAction = getColumnsAction, TableName = "Document", Context = context, PopulateRowAction = populateRowAction, SkipCommandExec = true, ExecuteAction = ExecuteAction.Writing, }; Execute(executionArguments); }
/// <summary> /// Writes the binary data. /// </summary> /// <param name="data">The data.</param> /// <param name="context">The context.</param> void IDataTarget.WriteBinaryData(IEnumerable <BinaryDataEntry> data, IProcessingContext context) { Func <DataColumn[]> getColumnsAction = () => new[] { new DataColumn("DataHash", typeof(string)) { AllowDBNull = false } }; Func <BinaryDataEntry, DataRow, PopulateRowResult> populateRowAction = (entry, row) => { if (entry.Data == null) { return(PopulateRowResult.InvalidData); } using (var source = new MemoryStream(entry.Data)) { try { Factory.BinaryFileRepository.Put(source); } catch (Exception ex) { context.WriteWarning(string.Format("An error occurred copying binary file into file repository. DataHash: {0}. Error {1}.", entry.DataHash, ex.ToString())); return(PopulateRowResult.InvalidData); } } return(PopulateRowResult.Ignore); }; var executionArguments = new ExecutionArguments <BinaryDataEntry> { Entries = data, GetColumnsAction = getColumnsAction, TableName = "Binary", SkipCommandExec = true, Context = context, PopulateRowAction = populateRowAction, ExecuteAction = ExecuteAction.Writing }; Execute(executionArguments); }
/// <summary> /// Load entities. /// </summary> /// <param name="context"></param> /// <returns></returns> IEnumerable <EntityEntry> IDataSource.GetEntities(IProcessingContext context) { if (_entityCache == null) { var data = new List <EntityEntry>( ); ///// // Query entities that are part of the solution ///// using (IDbCommand command = CreateCommand( )) { command.CommandText = "spGetTenantAppEntities"; command.CommandType = CommandType.StoredProcedure; command.AddParameterWithValue("@solutionId", SolutionId); command.AddParameterWithValue("@tenant", TenantId); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context?.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } var entry = new EntityEntry { EntityId = reader.GetGuid(0) }; data.Add(entry); } } } _entityCache = data; } return(_entityCache); }
/// <summary> /// Load relationships. /// </summary> /// <param name="context"></param> /// <returns></returns> IEnumerable <RelationshipEntry> IDataSource.GetRelationships(IProcessingContext context) { if (_relationshipCache == null) { var data = new List <RelationshipEntry>( ); ///// // Query entities that are part of the solution ///// using (IDbCommand command = CreateCommand( )) { command.CommandText = CommandText.TenantSourceGetRelationshipsCommandText; command.CommandType = CommandType.Text; command.AddParameterWithValue("@tenant", TenantId); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context?.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } Guid typeId = reader.GetGuid(0); Guid fromId = reader.GetGuid(1); Guid toId = reader.GetGuid(2); RelationshipEntry entry = new RelationshipEntry(typeId, fromId, toId); data.Add(entry); } } } _relationshipCache = data; } return(_relationshipCache); }
void IDataTarget.WriteSecureData(IEnumerable <SecureDataEntry> data, IProcessingContext context) { int rowCount = 0; using (var command = CreateCommand() as SQLiteCommand) { Debug.Assert(command != null, "command != null"); const string sql = "insert into _SecureData (SecureId, Context, Data) values (@secureId, @context, @data)"; command.CommandType = CommandType.Text; command.CommandText = sql; foreach (SecureDataEntry dataEntry in data) { if (dataEntry.Data == null) { context.WriteWarning($"Unexpected null values when updating SecureData table. SecuredId:{dataEntry.SecureId}"); continue; } command.Parameters.Clear(); command.Parameters.Add("@secureId", DbType.String).Value = dataEntry.SecureId; command.Parameters.Add("@context", DbType.AnsiString).Value = dataEntry.Context; var encodedData = Convert.ToBase64String(dataEntry.Data); // encrypted so no point in compressing command.Parameters.Add("@data", DbType.String).Value = encodedData; rowCount += command.ExecuteNonQuery(); if (rowCount % 100 == 0) { context.WriteInfo($"Copying SecureData... {rowCount} rows"); } } } }
/// <summary> /// Return the decrypted secure data stored with the tenant. /// </summary> public IEnumerable <SecureDataEntry> GetSecureData(IProcessingContext context) { var result = new List <SecureDataEntry>(); ///// // Query entities that are part of the solution ///// using (IDbCommand command = CreateCommand()) { command.CommandText = "spSecuredDataReadTenant"; command.CommandType = CommandType.StoredProcedure; command.AddParameterWithValue("@tenantId", TenantId); using (IDataReader reader = command.ExecuteReader()) { while (reader.Read()) { if (reader.IsDBNull(0)) { context?.WriteWarning("Unexpected null SecureDataEntry."); continue; } var secureId = reader.GetGuid(0); var secureContext = reader.GetString(1); var data = reader.GetString(2); var entry = new SecureDataEntry(secureId, secureContext, EncryptString(data)); result.Add(entry); } } } return(result); }
/// <summary> /// Reads the relationships. /// </summary> /// <param name="context">The context.</param> /// <param name="reader">The reader.</param> /// <param name="cardinality">The cardinality.</param> /// <param name="dict">The dictionary.</param> /// <param name="toOne">To one.</param> /// <param name="fromOne">From one.</param> /// <param name="droppedRelationships">if set to <c>true</c> [dropped relationships].</param> private void ReadRelationships(IProcessingContext context, IDataReader reader, Dictionary <long, CardinalityEnum_Enumeration> cardinality, Dictionary <RelationshipEntryKey, RelationshipEntry> dict, Dictionary <RelationshipEntryCardinalityKey, RelationshipEntry> toOne, Dictionary <RelationshipEntryCardinalityKey, RelationshipEntry> fromOne, bool droppedRelationships) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context?.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } Guid typeId = reader.GetGuid(0); Guid fromId = reader.GetGuid(1); Guid toId = reader.GetGuid(2); CardinalityEnum_Enumeration?card = null; if (reader.FieldCount > 3 && !reader.IsDBNull(3)) { CardinalityEnum_Enumeration cardValue; if (cardinality.TryGetValue(reader.GetInt64(3), out cardValue)) { card = cardValue; } } RelationshipEntry entry = card == null ? new RelationshipEntry(typeId, fromId, toId) : new RelationshipEntry(typeId, fromId, toId, card.Value); if (RelationshipRestrictions != null) { if (RelationshipRestrictions.Any(restriction => !restriction.IsAllowed(entry))) { continue; } } var key = entry.GetKey( ); RelationshipEntry value; bool violation = false; Action addFrom = null; Action addTo = null; if (entry.Cardinality != null && (entry.Cardinality == CardinalityEnum_Enumeration.ManyToOne || entry.Cardinality == CardinalityEnum_Enumeration.OneToOne)) { var cardinalityKey = new RelationshipEntryCardinalityKey(entry.TypeId, entry.FromId); if (toOne.TryGetValue(cardinalityKey, out value)) { if (entry.TypeId != value.TypeId || entry.FromId != value.FromId || entry.ToId != value.ToId) { ///// // Cardinality violation. ///// EventLog.Application.WriteWarning(string.Format("Detected cardinality violation {7}({0}).\n\nExisting Type: {1}\nExisting From: {2}\nExisting To: {3}\n\nDropped Type: {4}\nDropped From: {5}\nDropped To: {6}\n", entry.Cardinality, value.TypeId.ToString("B"), value.FromId.ToString("B"), value.ToId.ToString("B"), entry.TypeId.ToString("B"), entry.FromId.ToString("B"), entry.ToId.ToString("B"), droppedRelationships ? "processing previously dropped relationship " : "")); } violation = true; } else { RelationshipEntry relationshipEntry = entry; addFrom = () => toOne.Add(cardinalityKey, relationshipEntry); } } if (!violation && entry.Cardinality != null && (entry.Cardinality == CardinalityEnum_Enumeration.OneToMany || entry.Cardinality == CardinalityEnum_Enumeration.OneToOne)) { var cardinalityKey = new RelationshipEntryCardinalityKey(entry.TypeId, entry.ToId); if (fromOne.TryGetValue(cardinalityKey, out value)) { if (entry.TypeId != value.TypeId || entry.FromId != value.FromId || entry.ToId != value.ToId) { ///// // Cardinality violation. ///// EventLog.Application.WriteWarning(string.Format("Detected cardinality violation {7}({0}).\n\nExisting Type: {1}\nExisting From: {2}\nExisting To: {3}\n\nDropped Type: {4}\nDropped From: {5}\nDropped To: {6}\n", entry.Cardinality, value.TypeId.ToString("B"), value.FromId.ToString("B"), value.ToId.ToString("B"), entry.TypeId.ToString("B"), entry.FromId.ToString("B"), entry.ToId.ToString("B"), droppedRelationships ? "processing previously dropped relationship " : "")); } violation = true; } else { RelationshipEntry relationshipEntry = entry; addTo = () => fromOne.Add(cardinalityKey, relationshipEntry); } } if (violation) { continue; } addFrom?.Invoke( ); addTo?.Invoke( ); if (!dict.TryGetValue(key, out value)) { dict.Add(key, entry); } else { if (entry.Cardinality != CardinalityEnum_Enumeration.ManyToMany) { if (entry.TypeId != value.TypeId || entry.FromId != value.FromId || entry.ToId != value.ToId) { ///// // Cardinality violation. ///// EventLog.Application.WriteWarning(string.Format("Detected cardinality violation {7}({0}).\n\nExisting Type: {1}\nExisting From: {2}\nExisting To: {3}\n\nDropped Type: {4}\nDropped From: {5}\nDropped To: {6}\n", entry.Cardinality, value.TypeId.ToString("B"), value.FromId.ToString("B"), value.ToId.ToString("B"), entry.TypeId.ToString("B"), entry.FromId.ToString("B"), entry.ToId.ToString("B"), droppedRelationships ? "processing previously dropped relationship " : "")); } } } } }
/// <summary> /// Load entities. /// </summary> /// <param name="context"></param> /// <returns></returns> public override IEnumerable <EntityEntry> GetEntities(IProcessingContext context) { ///// // Query entities that are part of the solution ///// const string sql = @" DECLARE @name UNIQUEIDENTIFIER DECLARE @isOfType UNIQUEIDENTIFIER SELECT @name = EntityUid FROM AppData_Alias WHERE Data = 'name' AND Namespace = 'core' SELECT @isOfType = EntityUid FROM AppData_Alias WHERE Data = 'isOfType' AND Namespace = 'core' SELECT DISTINCT e.EntityUid, en.Data, etn.Data FROM AppEntity e LEFT JOIN AppData_NVarChar en ON e.EntityUid = en.EntityUid AND e.AppVerUid = en.AppVerUid AND en.FieldUid = @name LEFT JOIN AppRelationship et ON e.EntityUid = et.FromUid AND e.AppVerUid = et.AppVerUid AND et.TypeUid = @isOfType LEFT JOIN AppData_NVarChar etn ON et.ToUid = etn.EntityUid AND etn.FieldUid = @name WHERE e.AppVerUid = @appVer"; var map = new Dictionary <Guid, EntityStagingEntry>( ); using (IDbCommand command = CreateCommand( )) { command.CommandText = sql; command.AddParameterWithValue("@appVer", AppVerId); using (IDataReader reader = command.ExecuteReader( )) { if (reader != null) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } EntityStagingEntry entry; if (!map.TryGetValue(reader.GetGuid(0), out entry)) { entry = new EntityStagingEntry { EntityId = reader.GetGuid(0), EntityName = reader.IsDBNull(1) ? null : reader.GetString(1), EntityTypeName = reader.IsDBNull(2) ? null : reader.GetString(2) }; map[entry.EntityId] = entry; } else { if (entry.EntityTypeName != null && !reader.IsDBNull(2)) { string[] split = entry.EntityTypeName.Split(new[] { ',' }); string type = reader.GetString(2); if (split.All(s => s.Trim( ).ToLowerInvariant( ) != type)) { entry.EntityTypeName += ", " + type; } } } } } } } return(map.Values); }
/// <summary> /// Writes the binary data. /// </summary> /// <param name="data">The data.</param> /// <param name="context">The context.</param> void IDataTarget.WriteBinaryData(IEnumerable <BinaryDataEntry> data, IProcessingContext context) { Func <DataColumn[]> getColumnsAction = () => new[] { new DataColumn("OldDataHash", typeof(string)) { AllowDBNull = false }, new DataColumn("NewDataHash", typeof(string)) { AllowDBNull = false }, new DataColumn("FileExtension", typeof(string)) { AllowDBNull = true } }; Func <BinaryDataEntry, DataRow, PopulateRowResult> populateRowAction = (entry, row) => { if (entry.Data == null) { return(PopulateRowResult.InvalidData); } using (var source = new MemoryStream(entry.Data)) { try { // Add the file to the repository string newDataHash = Factory.AppLibraryFileRepository.Put(source); row[0] = entry.DataHash; row[1] = newDataHash; row[2] = string.IsNullOrWhiteSpace(entry.FileExtension) ? null : entry.FileExtension; } catch (Exception ex) { context.WriteWarning(string.Format("An error occurred putting binary file into file repository. DataHash: {0}. Error {1}.", entry.DataHash, ex.ToString())); return(PopulateRowResult.InvalidData); } } return(PopulateRowResult.Success); }; Func <IDbCommand, int> customCommandExecuteAction = command => { // Upgrade datahashes and file extensions command.CommandText = string.Format(CommandText.AppLibraryUpgradeFileDataHashesAndFileExtensions, "#Binary"); command.CommandType = CommandType.Text; command.AddParameterWithValue("@appVerId", ApplicationVersionId); command.AddParameterWithValue("@fileDataHashFieldId", Helpers.FileDataHashFieldUpgradeId); command.AddParameterWithValue("@fileExtensionFieldId", Helpers.FileExtensionFieldUpgradeId); command.ExecuteNonQuery(); return(0); }; Action <int> setCopiedCountAction = count => { if (context != null) { context.Report.Counts.Add(new StatisticsCount("Copied Binary Data", count, StatisticsCountType.Copied)); } }; var executionArguments = new LibraryAppTargetExecutionArguments <BinaryDataEntry> { Entries = data, GetColumnsAction = getColumnsAction, TableName = "#Binary", Context = context, SetCopiedCountAction = setCopiedCountAction, PopulateRowAction = populateRowAction, ClearExistingData = false, CustomCommandExecuteAction = customCommandExecuteAction }; Execute(executionArguments); }
/// <summary> /// Set the application metadata. /// </summary> /// <param name="metadata"></param> /// <param name="context"></param> void IDataTarget.SetMetadata(Metadata metadata, IProcessingContext context) { if (SkipMetadata) { context.WriteInfo("Skipping app library metadata"); return; } ///// // Write the application ///// App app = Entity.GetByField <App>(metadata.AppId.ToString( ), new EntityRef("core:applicationId")).FirstOrDefault( ); if (app == null) { app = new App { Name = metadata.AppName, Description = metadata.Description, ApplicationId = metadata.AppId, Publisher = metadata.Publisher, PublisherUrl = metadata.PublisherUrl, ReleaseDate = metadata.ReleaseDate == DateTime.MinValue.ToUniversalTime() ? ( DateTime? )null : metadata.ReleaseDate.ToUniversalTime() }; app.Save( ); } ///// // Write the app-package ///// AppPackage package = app.ApplicationPackages.FirstOrDefault(ap => ap.AppVerId == metadata.AppVerId); if (package == null) { package = new AppPackage( ); var version = new Version(metadata.Version); AppPackage existingVersion = app.ApplicationPackages.FirstOrDefault(ap => ap.AppVersionString == version.ToString( )); bool versionExists = false; while (existingVersion != null) { versionExists = true; version = new Version(version.Major, version.Minor + 1); existingVersion = app.ApplicationPackages.FirstOrDefault(ap => ap.AppVersionString == version.ToString( )); } metadata.Version = version.ToString( ); if (versionExists) { context.WriteWarning("Version already exists.. incrementing"); } } else { package = package.AsWritable <AppPackage>( ); context.WriteWarning("Already installed.. overwriting"); } string solutionNames = app.InSolution?.Name; ///// // Localize the string values. ///// package.Name = string.Format("{0} Application Package {1}", solutionNames ?? app.Name, metadata.Version); package.Description = string.Format("Application Package for version {1} of {0}.", app.Name, metadata.Version); package.AppVersionString = metadata.Version; package.AppVerId = metadata.AppVerId; package.PackageForApplication = app; if (metadata.PublishDate != DateTime.MinValue && metadata.PublishDate > SqlDateTime.MinValue.Value) { package.PublishDate = metadata.PublishDate; } if (metadata.Dependencies != null) { IEntityCollection <AppPackageDependency> dependencies = new EntityCollection <AppPackageDependency>( ); foreach (SolutionDependency dependency in metadata.Dependencies) { AppPackageDependency appPackageDependency = new AppPackageDependency { Name = dependency.Name, AppPackageDependencyName = dependency.DependencyName, AppPackageDependencyId = dependency.DependencyApplication, AppPackageMinimumVersion = dependency.MinimumVersion == null ? null : dependency.MinimumVersion.ToString(4), AppPackageMaximumVersion = dependency.MaximumVersion == null ? null : dependency.MaximumVersion.ToString(4), AppPackageIsRequired = dependency.IsRequired }; dependencies.Add(appPackageDependency); } package.DependentAppPackageDetails = dependencies; } package.Save( ); }
/// <summary> /// Load relationships. /// </summary> /// <param name="context"></param> /// <returns></returns> IEnumerable <RelationshipEntry> IDataSource.GetRelationships(IProcessingContext context) { if (_relationshipCache == null) { var data = new List <RelationshipEntry>( ); ///// // Query the relationship types that are lookups. ///// string lookups = $@" DECLARE @cardinalityId BIGINT DECLARE @oneToOneId BIGINT DECLARE @manyToOneId BIGINT DECLARE @oneToManyId BIGINT DECLARE @manyToManyId BIGINT SELECT @cardinalityId = EntityId FROM Data_Alias WHERE Data = 'cardinality' AND Namespace = 'core' AND TenantId = @tenant SELECT @oneToOneId = EntityId FROM Data_Alias WHERE Data = 'oneToOne' AND Namespace = 'core' AND TenantId = @tenant SELECT @oneToManyId = EntityId FROM Data_Alias WHERE Data = 'oneToMany' AND Namespace = 'core' AND TenantId = @tenant SELECT @manyToOneId = EntityId FROM Data_Alias WHERE Data = 'manyToOne' AND Namespace = 'core' AND TenantId = @tenant SELECT @manyToManyId = EntityId FROM Data_Alias WHERE Data = 'manyToMany' AND Namespace = 'core' AND TenantId = @tenant SELECT e.UpgradeId, {( short ) CardinalityEnum_Enumeration.OneToOne} FROM Entity e JOIN Relationship r ON r.TenantId = e.TenantId AND e.Id = r.FromId AND r.TypeId = @cardinalityId AND ToId = @oneToOneId WHERE e.TenantId = @tenant UNION ALL SELECT e.UpgradeId, {( short ) CardinalityEnum_Enumeration.OneToMany} FROM Entity e JOIN Relationship r ON r.TenantId = e.TenantId AND e.Id = r.FromId AND r.TypeId = @cardinalityId AND ToId = @oneToManyId WHERE e.TenantId = @tenant UNION ALL SELECT e.UpgradeId, {( short ) CardinalityEnum_Enumeration.ManyToOne} FROM Entity e JOIN Relationship r ON r.TenantId = e.TenantId AND e.Id = r.FromId AND r.TypeId = @cardinalityId AND ToId = @manyToOneId WHERE e.TenantId = @tenant UNION ALL SELECT e.UpgradeId, {( short ) CardinalityEnum_Enumeration.ManyToMany} FROM Entity e JOIN Relationship r ON r.TenantId = e.TenantId AND e.Id = r.FromId AND r.TypeId = @cardinalityId AND ToId = @manyToManyId WHERE e.TenantId = @tenant "; var lookupTypes = new Dictionary <Guid, CardinalityEnum_Enumeration>( ); ///// // Query entities that are part of the solution ///// using (IDbCommand command = CreateCommand( )) { command.CommandText = lookups; command.CommandType = CommandType.Text; command.AddParameterWithValue("@tenant", TenantId); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { Guid id = reader.GetGuid(0); var cardinalityType = ( CardinalityEnum_Enumeration )reader.GetInt32(1); lookupTypes[id] = cardinalityType; } } command.CommandText = "spGetTenantAppRelationships"; command.CommandType = CommandType.StoredProcedure; command.AddParameterWithValue("@solutionId", SolutionId); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context?.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } Guid typeId = reader.GetGuid(0); Guid fromId = reader.GetGuid(1); Guid toId = reader.GetGuid(2); CardinalityEnum_Enumeration cardinality; var entry = lookupTypes.TryGetValue(typeId, out cardinality) ? new RelationshipEntry(typeId, fromId, toId, cardinality) : new RelationshipEntry(typeId, fromId, toId); data.Add(entry); } } } _relationshipCache = data; } return(_relationshipCache); }
/// <summary> /// Load entities. /// </summary> /// <param name="context"></param> /// <returns></returns> IEnumerable <EntityEntry> IDataSource.GetEntities(IProcessingContext context) { if (_entityCache == null) { var data = new Dictionary <Guid, EntityEntry>( ); ///// // Query entities that are part of the solution ///// using (IDbCommand command = CreateCommand( )) { command.CommandText = "spGetTenantAppStagedEntities"; command.CommandType = CommandType.StoredProcedure; command.AddParameterWithValue("@solutionId", SolutionId); command.AddParameterWithValue("@tenant", TenantId); using (IDataReader reader = command.ExecuteReader( )) { while (reader.Read( )) { if (reader.IsDBNull(0)) { context?.WriteWarning("Unexpected null UpgradeId in Entity."); continue; } int depth = reader.GetInt32(0); Guid entityUpgradeId = reader.GetGuid(1); long entityId = reader.GetInt64(2); string entityName = reader.IsDBNull(3) ? null : reader.GetString(3); long entityTypeId = reader.IsDBNull(4) ? 0 : reader.GetInt64(4); string entityTypeName = reader.IsDBNull(5) ? null : reader.GetString(5); EntityEntry entry; if (!data.TryGetValue(entityUpgradeId, out entry)) { entry = new EntityStagingEntry { EntityId = entityUpgradeId, Id = entityId, EntityName = entityName, EntityTypeId = entityTypeId, EntityTypeName = entityTypeName }; data[entityUpgradeId] = entry; } var castEntry = entry as EntityStagingEntry; if (depth > 0 && castEntry != null) { if (castEntry.Parents == null) { castEntry.Parents = new List <EntityParentEntry>( ); } castEntry.Parents.Add(new EntityParentEntry { Depth = depth, ParentEntityUpgradeId = reader.GetGuid(6), RelationshipTypeUpgradeId = reader.GetGuid(7), RelationshipTypeId = reader.IsDBNull(8) ? 0 : reader.GetInt64(8), RelationshipTypeName = reader.IsDBNull(9) ? null : reader.GetString(9), Reason = ( InclusionReason )Enum.Parse(typeof(InclusionReason), reader.GetString(10), true), }); } } } } _entityCache = data.Values.ToList( ); } return(_entityCache); }