/// <summary> /// Do the actual leg-work of removing a package. Optionally make it /// a forceful removal (used during a failed system install, or possibly /// a future system un-install). A forceful removal means that dependency /// checks are ignored and an error while deleting the database record /// is ignored (since the table may no longer exist). /// </summary> /// <param name="packageName">The name of the package to remove.</param> /// <param name="forceRemove">Wether or not to force the removal.</param> private void RemovePackage(String packageName, Boolean forceRemove) { PackageInstaller installer = new PackageInstaller(this); Database db; Package package; Migration mig; Boolean LocalTransaction = false; // // Check if the package is installed. // package = GetInstalledPackage(packageName); if (package == null) { throw new PackageNotInstalledException(String.Format("The package {0} is not currently installed.", packageName)); } // // Check if there are any packages that depend on the package // we are about to remove. // if (forceRemove == false) { if (PackagesRequiring(packageName).Count > 0) { throw new PackageDependencyException(String.Format("The package {0} as dependencies and cannot be removed.", packageName)); } } // // Begin the SQL Transaction. // if (Command.Transaction == null) { Command.Transaction = Connection.BeginTransaction(); LocalTransaction = true; } db = new Database(Command); // // Begin the actual removal process. // try { // // Unconfigure all packages that recommend this one. // try { foreach (String name in PackagesRecommending(packageName)) { mig = installer.MigrationForPackage(GetInstalledPackage(name)); if (mig != null) { mig.Unconfigure(db, null, packageName); } } } catch (Exception e) { throw new DatabaseMigrationException("Unable to re-configure dependent packages.", e); } // // Unconfigure this package. // try { // // Load the migration object from the package. // mig = installer.MigrationForPackage(package); if (mig != null) { // // Unconfigure this package from its recommendations. // foreach (PackageRecommendation pkg in package.Info.Recommends) { mig.Unconfigure(db, null, pkg.Name); } // // Unconfigure this package from its requirements. // foreach (PackageRequirement pkg in package.Info.Requires) { mig.Unconfigure(db, null, pkg.Name); } // // Do a general unconfigure of this package. // mig.Unconfigure(db, null, null); } } catch (Exception e) { throw new DatabaseMigrationException("Unable to unconfigure package.", e); } // // Remove all the new files, pages, modules, etc. // try { installer.RemovePackagePages(package); installer.RemovePackageModules(package); installer.RemovePackageFiles(package); } catch (IOException) { throw; } catch (Exception) { throw; } // // Migrate the database to a completely non-existant state. // if (mig != null) { try { mig.Downgrade(db, null); } catch (Exception e) { throw new DatabaseMigrationException("Error while trying to migrate database.", e); } } // // Remove the package from the database. // try { Command.CommandType = CommandType.Text; Command.CommandText = "DELETE FROM [cust_rc_packager_packages] WHERE [name] = @Name"; Command.Parameters.Clear(); Command.Parameters.Add(new SqlParameter("@Name", package.Info.PackageName)); Command.ExecuteNonQuery(); } catch { if (forceRemove == false) { throw; } } // // Commit database changes, we are all done. // if (LocalTransaction) { Command.Transaction.Commit(); Command.Transaction = null; db.Command.Transaction = null; } } catch (Exception) { // // Rollback file system changes. // try { installer.RevertFileChanges(); } catch { } // // Rollback database changes. // if (LocalTransaction) { Command.Transaction.Rollback(); Command.Transaction = null; db.Command.Transaction = null; } // // Throw the exception again. // throw; } }
/// <summary> /// Do the actual leg-work of installing a package. /// </summary> /// <param name="package">The package to be installed or upgraded.</param> /// <param name="systemInstall">Specifies if this is a system install. If true certain safety checks are bypassed.</param> private void InstallPackage(Package package, Boolean systemInstall) { PackageInstaller installer = new PackageInstaller(this); PackageVersion version = null; Package oldPackage = null; Database db; Migration mig; Boolean LocalTransaction = false; // // Verify package dependencies. // try { if (systemInstall == false) { installer.VerifyDependenciesForInstall(package); } } catch (PackageVersionException) { throw; } catch (PackageDependencyException) { throw; } // // Begin the SQL Transaction. // if (Command.Transaction == null) { Command.Transaction = Connection.BeginTransaction(); LocalTransaction = true; } db = new Database(Command); // // Begin the install process. // try { if (systemInstall == false) { // // Get the previous package and the previous package version. // oldPackage = GetInstalledPackage(package.Info.PackageName); version = (oldPackage != null ? oldPackage.Info.Version : null); } // // Migrate the database to the new version. // try { mig = installer.MigrationForPackage(package); if (mig != null) { mig.Upgrade(db, version); } } catch (Exception e) { throw new DatabaseMigrationException("Unable to install the database changes.", e); } // // Install all the new files, pages, modules, etc. // try { installer.InstallPackageFiles(package, oldPackage); installer.InstallPackageModules(package, oldPackage); installer.InstallPackagePages(package, oldPackage); } catch (IOException) { throw; } catch (Exception) { throw; } // // Configure this package first by itself and then for each // dependency it has. // if (mig != null) { try { mig.Configure(db, version, null); foreach (PackageRequirement pkg in package.Info.Requires) { mig.Configure(db, version, pkg.Name); } foreach (PackageRecommendation pkg in package.Info.Recommends) { mig.Configure(db, version, pkg.Name); } } catch (Exception e) { throw new DatabaseMigrationException("Unable to configure the database changes.", e); } } // // Configure all packages that recommend this package. // try { foreach (String dependantName in PackagesRecommending(package.Info.PackageName)) { Migration mi2 = installer.MigrationForPackage(GetInstalledPackage(dependantName)); if (mi2 != null) { mi2.Configure(db, null, package.Info.PackageName); } } } catch (Exception e) { throw new DatabaseMigrationException("Unable to re-configure dependent packages.", e); } // // Store the Package information in the database. // if (oldPackage != null) { Command.CommandType = CommandType.Text; Command.CommandText = "DELETE FROM [cust_rc_packager_packages] WHERE [name] = @Name"; Command.Parameters.Clear(); Command.Parameters.Add(new SqlParameter("@Name", package.Info.PackageName)); Command.ExecuteNonQuery(); } Command.CommandType = CommandType.Text; Command.CommandText = "INSERT INTO [cust_rc_packager_packages] ([created_by], [modified_by], [name], [package]) VALUES ('Package Manager', 'Package Manager', @Name, @Package)"; Command.Parameters.Clear(); Command.Parameters.Add(new SqlParameter("@Name", package.Info.PackageName)); Command.Parameters.Add(new SqlParameter("@Package", new SqlXml(new XmlNodeReader(package.XmlPackage)))); Command.ExecuteNonQuery(); // // Commit database changes, we are all done. // if (LocalTransaction) { Command.Transaction.Commit(); Command.Transaction = null; db.Command.Transaction = null; } } catch (Exception e) { // // Rollback file system changes. // try { installer.RevertFileChanges(); } catch { } // // Rollback database changes. // if (LocalTransaction) { Command.Transaction.Rollback(); Command.Transaction = null; db.Command.Transaction = null; } // // Throw the exception again. // throw e; } }