/// <summary> /// Exports the tenant. /// </summary> /// <param name="tenantName">Name of the tenant.</param> /// <param name="packagePath">The package path.</param> /// <param name="metadataOnly">If true, exclude user data.</param> /// <param name="context">The context.</param> /// <exception cref="System.ArgumentNullException"> /// tenantName /// or /// tenantStorePath /// </exception> public static void ExportTenant(string tenantName, string packagePath, bool metadataOnly, IProcessingContext context = null) { if (string.IsNullOrEmpty(tenantName)) { throw new ArgumentNullException("tenantName"); } if (string.IsNullOrEmpty(packagePath)) { throw new ArgumentNullException("packagePath"); } if (context == null) { context = new ProcessingContext( ); } context.Report.StartTime = DateTime.Now; long tenantId = TenantHelper.GetTenantId(tenantName, true); IDataSource source = metadataOnly ? (IDataSource) new TenantMetadataSource { TenantId = tenantId, TenantName = tenantName } : (IDataSource) new TenantSource { TenantId = tenantId, TenantName = tenantName }; ///// // Create source to load app data from tenant ///// using ( source ) { Format packageFormat = FileManager.GetExportFileFormat(packagePath); ///// // Create target to write to SQLite database ///// using (var target = FileManager.CreateDataTarget(packageFormat, packagePath)) { ///// // Copy the data ///// var processor = new CopyProcessor(source, target, context); processor.MigrateData( ); } } context.Report.EndTime = DateTime.Now; }
/// <summary> /// Imports the tenant. /// </summary> /// <param name="packagePath">The package path.</param> /// <param name="tenantName">Name of the tenant.</param> /// <param name="overwrite"> /// if set to <c>true</c> [overwrite]. /// </param> /// <param name="context">The context.</param> /// <exception cref="System.ArgumentNullException">tenantStorePath</exception> /// <exception cref="System.InvalidOperationException"> /// The package does not contain a tenant. /// or /// </exception> /// <exception cref="System.ArgumentException">The package is corrupt.</exception> /// <remarks> /// If a tenant with the same name already exists, an exception will be thrown. /// To overwrite an existing tenant with the same name, call OverwriteTenant. /// </remarks> /// <returns>the tenant id</returns> private static long ImportTenant_Impl(string packagePath, string tenantName, bool overwrite, IProcessingContext context) { if (string.IsNullOrEmpty(packagePath)) { throw new ArgumentNullException("packagePath"); } if (context == null) { context = new ProcessingContext( ); } context.Report.StartTime = DateTime.Now; try { ///// // Create source to load app data from tenant ///// using (var source = FileManager.CreateDataSource(packagePath)) { Metadata metadata = source.GetMetadata(context); if (metadata.Type == SourceType.AppPackage) { throw new InvalidOperationException("The package does not contain a tenant."); } if (string.IsNullOrEmpty(tenantName)) { tenantName = metadata.Name; } if (string.IsNullOrEmpty(tenantName)) { throw new ArgumentException("The package is corrupt."); } bool deleteExistingTenant = false; if (TenantExists(tenantName)) { if (overwrite) { deleteExistingTenant = true; } else { throw new InvalidOperationException(string.Format("The tenant '{0}' already exists.", tenantName)); } } long userId; RequestContext.TryGetUserId(out userId); ///// // Create target to write to SQLite database ///// using (var target = new TenantCopyTarget( )) { Tenant tenant; ///// // Create the tenant. ///// using (new GlobalAdministratorContext( )) { if (deleteExistingTenant) { Tenant existingTenant = Entity.GetByName <Tenant>(tenantName).FirstOrDefault( ); if (existingTenant != null) { using (DatabaseContextInfo.SetContextInfo("Delete existing tenant")) using (IDbCommand command = target.CreateCommand( )) { command.CommandText = "spDeleteTenant"; command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@tenantId", existingTenant.Id)); command.AddParameter("@context", DbType.AnsiString, DatabaseContextInfo.GetMessageChain(userId)); command.ExecuteNonQuery( ); } } } tenant = Entity.Create <Tenant>( ); tenant.Name = tenantName; tenant.Description = tenantName + " tenant"; tenant.Save( ); target.TenantId = tenant.Id; } ///// // Copy the data ///// var processor = new CopyProcessor(source, target, context); processor.MigrateData( ); ///// // Commit the changes. ///// target.Commit( ); return(tenant.Id); } } } finally { ForeignKeyHelper.Trust( ); context.Report.EndTime = DateTime.Now; } }
/// <summary> /// Imports the tenant. /// </summary> /// <returns>the tenant id</returns> public static void InstallGlobalTenant( ) { IProcessingContext context = new ProcessingContext( ); context.Report.Action = AppLibraryAction.InstallGlobal; context.Report.Arguments.Add(new KeyValuePair <string, string>("Tenant Id", "Global")); IDictionary <Guid, Guid> appToAppVer = new Dictionary <Guid, Guid>( ); // Get application versions // It is assumed that if there is no global tenant, then there is only one version of each of the core apps using (IDatabaseContext dbContext = DatabaseContext.GetContext(false)) using (IDbCommand command = dbContext.CreateCommand()) { command.CommandText = "select FromUid AppUid, AppVerUid from AppRelationship where ToUid = @solution and TypeUid = @isOfType"; command.AddParameterWithValue("@solution", Guids.Solution); command.AddParameterWithValue("@isOfType", Guids.IsOfType); using (IDataReader reader = command.ExecuteReader( )) { // Load appVerId for apps from app library while (reader.Read( )) { Guid appId = reader.GetGuid(0); Guid appVerId = reader.GetGuid(1); appToAppVer[appId] = appVerId; } } } // Install apps Guid[] coreApps = new[] { Guids.CoreSolution, Guids.ConsoleSolution, Guids.CoreDataSolution, Guids.SystemSolution }; // Copy system application content from the app library into the global tenant foreach (Guid appId in coreApps) { // Get the AppVerId Guid appVerId; if (!appToAppVer.TryGetValue(appId, out appVerId)) { throw new Exception($"Aborting: System app {0} was not present in app library."); } context.WriteInfo($"Installing app {appId} package {appVerId} to global tenant."); IDataSource empty = new EmptySource( ); IDataSource source = new LibraryAppSource { AppId = appId, AppVerId = appVerId, AppName = appId.ToString( ) }; TenantMergeTarget target = new TenantMergeTarget { TenantId = 0 }; using (empty) using (source) using ( target ) { MergeProcessor processor = new MergeProcessor(context) { OldVersion = empty, NewVersion = source, Target = target }; processor.MergeData( ); target.Commit( ); } } // Copy metadata from the tenant back into the application library foreach (Guid appId in coreApps) { Guid appVerId = appToAppVer[appId]; long solutionEntityId = Entity.GetIdFromUpgradeId(appId); IDataSource metadataSource = new TenantAppSource { SolutionId = solutionEntityId, TenantId = 0 }; LibraryAppTarget metadataTarget = new LibraryAppTarget { ApplicationVersionId = appVerId }; using (metadataSource) using ( metadataTarget ) { CopyProcessor processor = new CopyProcessor(metadataSource, metadataTarget, context); processor.CopyMetadataOnly = true; processor.MigrateData( ); metadataTarget.Commit( ); } context.WriteInfo($"Installed app {appId} to global tenant."); } }