/// <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; } }