/// <summary> /// Create the database tables if /// </summary> /// <returns></returns> public ActionResult CreateDbTables() { // Get the versions so we can check if its a stright install // Or if its an upgrade var currentVersion = AppHelpers.GetCurrentVersionNo(); // Create an installer result so we know everything was successful var installerResult = new InstallerResult { Successful = true, Message = "Congratulations, MVC Forum has installed successfully" }; // Create the main database tables // NOTE: For testing you can overide the connectionstring and filepath to the sql // Just replace the nulls below installerResult = _installerService.CreateDbTables(null, null, currentVersion); if (installerResult.Successful) { // Create the base data //installerResult = _installerService.CreateInitialData(); installerResult = CreateInitialData(); // If error creating the base data then return the error if (!installerResult.Successful) { // There was an error creating the database return RedirectToCreateDb(installerResult, GenericMessages.danger); } } else { // There was an error creating the database return RedirectToCreateDb(installerResult, GenericMessages.danger); } // Install seems fine if (installerResult.Successful) { // Now we need to update the version in the web.config UpdateWebConfigVersionNo(installerResult, currentVersion); // This code will never be hit as the update to the web.config above will trigger the app restart and // it will find the version number and redircet them to the home page - Only way its hit is if the update doesn't work return RedirectToAction("Complete"); } // If we get here there was an error, so update the UI to tell them // If the message is empty then add one if (string.IsNullOrEmpty(installerResult.Message)) { installerResult.Message = @"There was an unkown error during the installer, please try again. If the problem continues then please let us know <a target='_blank' href='http://chat.mvcforum.com'>on the support forums</a>"; } // Add to temp data and show return RedirectToCreateDb(installerResult, GenericMessages.danger); }
internal ActionResult RedirectToCreateDb(InstallerResult installerResult, GenericMessages status) { // Add to temp data and show TempData[AppConstants.MessageViewBagName] = new GenericMessageViewModel { Message = installerResult.OnScreenMessage, MessageType = status }; // Fall back telling user they need a manual upgrade return RedirectToAction("CreateDb", "Install"); }
private void UpdateWebConfigVersionNo(InstallerResult installerResult, string currentVersion) { if (ConfigUtils.UpdateAppSetting("MVCForumVersion", currentVersion) == false) { Session[AppConstants.GoToInstaller] = "False"; installerResult.Message = string.Format(@"Database installed/updated. But there was an error updating the version number in the web.config, you need to manually update it to {0}", currentVersion); installerResult.Successful = false; TempData[AppConstants.InstallerName] = AppConstants.InstallerName; TempData[AppConstants.MessageViewBagName] = new GenericMessageViewModel { Message = installerResult.OnScreenMessage, MessageType = GenericMessages.error }; } }
private InstallerResult AddOrUpdateTheDefaultLanguageStrings(InstallerResult installerResult) { // Read in CSV and import like it does normally in the admin section using (var unitOfWork = _UnitOfWorkManager.NewUnitOfWork()) { var report = new CsvReport(); try { // Get the base language file var file = System.Web.HttpContext.Current.Server.MapPath(@"~/Installer/en-GB.csv"); // Verify that the user selected a file if (file != null) { // Unpack the data var allLines = new List<string>(); using (var streamReader = new StreamReader(file, System.Text.Encoding.UTF8, true)) { while (streamReader.Peek() >= 0) { allLines.Add(streamReader.ReadLine()); } } // Read the CSV file and generate a language report = _localizationService.FromCsv("en-GB", allLines); } unitOfWork.Commit(); } catch (Exception ex) { unitOfWork.Rollback(); //Loop through report errors and spit them out in the installer result message? var sb = new StringBuilder(); foreach (var error in report.Errors) { if (error.ErrorWarningType == CsvErrorWarningType.BadDataFormat || error.ErrorWarningType == CsvErrorWarningType.GeneralError) { sb.AppendFormat("{0}<br />", error.Message); } } installerResult.Exception = ex.InnerException; installerResult.Message = "Error creating the initial data >> Language Strings"; if (!string.IsNullOrEmpty(sb.ToString())) { installerResult.Message += string.Concat("<br />", sb.ToString()); } installerResult.Successful = false; } return installerResult; } }
private InstallerResult CreateInitialData() { var installerResult = new InstallerResult { Successful = true, Message = "Congratulations, MVC Forum has installed successfully" }; // I think this is all I need to call to kick EF into life //EFCachingProviderConfiguration.DefaultCache = new AspNetCache(); //EFCachingProviderConfiguration.DefaultCachingPolicy = CachingPolicy.CacheAll; // Now setup the services as we can't do it in the constructor InitialiseServices(); // First UOW to create the data needed for other saves using (var unitOfWork = _UnitOfWorkManager.NewUnitOfWork()) { try { // Check if category exists or not, we only do a single check for the first object within this // UOW because, if anything failed inside. Everything else would be rolled back to because of the // transaction const string exampleCatName = "Example Category"; if (_categoryService.GetAll().FirstOrDefault(x => x.Name == exampleCatName) == null) { // Doesn't exist so add the example category var exampleCat = new Category { Name = exampleCatName, ModeratePosts = false, ModerateTopics = false}; _categoryService.Add(exampleCat); // Add the default roles var standardRole = new MembershipRole { RoleName = "Standard Members" }; var guestRole = new MembershipRole { RoleName = "Guest" }; var moderatorRole = new MembershipRole { RoleName = "Moderator" }; var adminRole = new MembershipRole { RoleName = "Admin" }; _roleService.CreateRole(standardRole); _roleService.CreateRole(guestRole); _roleService.CreateRole(moderatorRole); _roleService.CreateRole(adminRole); unitOfWork.Commit(); } } catch (Exception ex) { unitOfWork.Rollback(); installerResult.Exception = ex.InnerException; installerResult.Message = "Error creating the initial data >> Category & Roles"; installerResult.Successful = false; return installerResult; } } // Add / Update the default language strings installerResult = AddOrUpdateTheDefaultLanguageStrings(installerResult); if (!installerResult.Successful) { return installerResult; } // Now we have saved the above we can create the rest of the data using (var unitOfWork = _UnitOfWorkManager.NewUnitOfWork()) { try { // if the settings already exist then do nothing if (_settingsService.GetSettings(false) == null) { // Get the default language var startingLanguage = _localizationService.GetLanguageByName("en-GB"); // Get the Standard Members role var startingRole = _roleService.GetRole("Standard Members"); // create the settings var settings = new Settings { ForumName = "MVC Forum", ForumUrl = "http://www.mydomain.com", IsClosed = false, EnableRSSFeeds = true, DisplayEditedBy = true, EnablePostFileAttachments = false, EnableMarkAsSolution = true, EnableSpamReporting = true, EnableMemberReporting = true, EnableEmailSubscriptions = true, ManuallyAuthoriseNewMembers = false, EmailAdminOnNewMemberSignUp = true, TopicsPerPage = 20, PostsPerPage = 20, EnablePrivateMessages = true, MaxPrivateMessagesPerMember = 50, PrivateMessageFloodControl = 1, EnableSignatures = false, EnablePoints = true, PointsAllowedToVoteAmount = 1, PointsAddedPerPost = 1, PointsAddedForSolution = 4, PointsDeductedNagativeVote = 2, AdminEmailAddress = "*****@*****.**", NotificationReplyEmail = "*****@*****.**", SMTPEnableSSL = false, Theme = "Metro", NewMemberStartingRole = startingRole, DefaultLanguage = startingLanguage, ActivitiesPerPage = 20, EnableAkisment = false, EnableSocialLogins = false, EnablePolls = true }; _settingsService.Add(settings); unitOfWork.Commit(); } } catch (Exception ex) { unitOfWork.Rollback(); installerResult.Exception = ex.InnerException; installerResult.Message = "Error creating the initial data >> Settings"; installerResult.Successful = false; return installerResult; } } // Now we have saved the above we can create the rest of the data using (var unitOfWork = _UnitOfWorkManager.NewUnitOfWork()) { try { // If the admin user exists then don't do anything else if (_membershipService.GetUser("admin") == null) { // Set up the initial permissions var readOnly = new Permission { Name = "Read Only" }; var deletePosts = new Permission { Name = "Delete Posts" }; var editPosts = new Permission { Name = "Edit Posts" }; var stickyTopics = new Permission { Name = "Sticky Topics" }; var lockTopics = new Permission { Name = "Lock Topics" }; var voteInPolls = new Permission { Name = "Vote In Polls" }; var createPolls = new Permission { Name = "Create Polls" }; var createTopics = new Permission { Name = "Create Topics" }; var attachFiles = new Permission { Name = "Attach Files" }; var denyAccess = new Permission { Name = "Deny Access" }; _permissionService.Add(readOnly); _permissionService.Add(deletePosts); _permissionService.Add(editPosts); _permissionService.Add(stickyTopics); _permissionService.Add(lockTopics); _permissionService.Add(voteInPolls); _permissionService.Add(createPolls); _permissionService.Add(createTopics); _permissionService.Add(attachFiles); _permissionService.Add(denyAccess); // create the admin user and put him in the admin role var admin = new MembershipUser { Email = "*****@*****.**", UserName = "******", Password = "******", IsApproved = true, DisableEmailNotifications = false, DisablePosting = false, DisablePrivateMessages = false }; _membershipService.CreateUser(admin); // Do a save changes just in case unitOfWork.SaveChanges(); // Put the admin in the admin role var adminRole = _roleService.GetRole("Admin"); admin.Roles = new List<MembershipRole> { adminRole }; unitOfWork.Commit(); } } catch (Exception ex) { unitOfWork.Rollback(); installerResult.Exception = ex.InnerException; installerResult.Message = "Error creating the initial data >> Admin user & Permissions"; installerResult.Successful = false; return installerResult; } } // Do this so search works and doesn't create a null reference. _luceneService.UpdateIndex(); return installerResult; }
private InstallerResult UpdateData(string currentVersion, string previousVersion, InstallerResult installerResult) { //TODO: Still need to write a more robust installer I think //Initialise the services InitialiseServices(); // Need to run the updater through all of the below, so we need to do // checks before we add anything to make sure it doesn't already exist and if, // update where necessary. // Whatever the version update the language strings as these are always the master ones // held in the en-GB.csv in the Installer folder root installerResult = AddOrUpdateTheDefaultLanguageStrings(installerResult); if (!installerResult.Successful) { return installerResult; } installerResult.Successful = true; installerResult.Message = "All data updated successfully"; //----------------------------------------------- //---------------- v1.3 to v1.4 ----------------- if (previousVersion.StartsWith("1.3") && currentVersion.StartsWith("1.4")) { try { // No extra data needed in this upgrade } catch (Exception ex) { installerResult.Successful = false; installerResult.Message = string.Format("Error updating from {0} to {1}", previousVersion, currentVersion); installerResult.Exception = ex; } } return installerResult; }
public ActionResult UpgradeDb() { // Work out this install can be upgraded, and if not redirect var previousVersionNo = AppHelpers.PreviousVersionNo(); var currentVersionNo = AppHelpers.GetCurrentVersionNo(); var installerResult = new InstallerResult{Successful = true, Message = string.Format("Upgrade to v{0} was successful", currentVersionNo)}; // Can't upgrade so redirect if (Convert.ToDouble(previousVersionNo) < 1.3d) { return RedirectToAction("ManualUpgradeNeeded"); } //***** Old version is v1.3 or greater so we can run the installer **** // Firstly add any new tables needed via the SQL // Get the SQL file and if it exists then run it var dbFilePath = Server.MapPath(InstallerHelper.GetUpdateDatabaseFilePath(currentVersionNo)); // See whether this version needs a table update if (System.IO.File.Exists(dbFilePath)) { // There is a file so update the database with the new tables installerResult = _installerService.CreateDbTables(null, dbFilePath, currentVersionNo); if (!installerResult.Successful) { // Was an error creating the tables return RedirectToCreateDb(installerResult, GenericMessages.error); } } // Tables created or updated - So now update all the data installerResult = UpdateData(currentVersionNo, previousVersionNo, installerResult); // See if upgrade was successful or not if (installerResult.Successful) { TempData[AppConstants.MessageViewBagName] = new GenericMessageViewModel { Message = installerResult.OnScreenMessage, MessageType = GenericMessages.success }; // Finally update the web.config to the new version UpdateWebConfigVersionNo(installerResult, currentVersionNo); return RedirectToAction("Complete"); } return RedirectToCreateDb(installerResult, GenericMessages.error); }
/// <summary> /// Creates database tables and reports back with an installer result /// </summary> /// <param name="connectionStringOveride">If you don't want to run this sql against the default DB then pass in a different connection string here</param> /// <param name="sqlFilePath">Overide what SQL you want to run, pass in the file path here i.e. /myfolder/myscript.sql</param> /// <param name="currentVersion">The current app version</param> /// <returns></returns> public InstallerResult CreateDbTables(string connectionStringOveride, string sqlFilePath, string currentVersion) { // Setup the installer result var insResult = new InstallerResult { Successful = true, Message = "Successfully created the database tables" }; // Sort the connection string out string connString; try { // Set the connection string connString = connectionStringOveride ?? ConfigurationManager.ConnectionStrings["MVCForumContext"].ConnectionString; } catch (Exception ex) { insResult.Exception = ex; insResult.Message = "Error trying to get the connection string"; insResult.Successful = false; return insResult; } // Get and open the SQL string script; var filePath = string.Empty; try { filePath = string.IsNullOrEmpty(sqlFilePath) ? HttpContext.Current.Server.MapPath(InstallerHelper.GetMainDatabaseFilePath(currentVersion)) : sqlFilePath; var file = new FileInfo(filePath); script = file.OpenText().ReadToEnd(); } catch (Exception ex) { insResult.Exception = ex; insResult.Message = string.Format("Error trying to read the SQL file '{0}' create db", filePath); insResult.Successful = false; return insResult; } using (var conn = new SqlConnection(connString)) { // split script on GO command IEnumerable<string> commandStrings = Regex.Split(script, "^\\s*GO\\s*$", RegexOptions.Multiline | RegexOptions.IgnoreCase); conn.Open(); foreach (var commandString in commandStrings) { if (commandString.Trim() != "") { try { new SqlCommand(commandString, conn).ExecuteNonQuery(); } catch (Exception ex) { //NOTE: Surpress errors where tables already exist, and just carry on if (!ex.Message.Contains("There is already an object named") && !ex.Message.Contains("Column already has a DEFAULT bound to it")) { insResult.Exception = ex; insResult.Message = "Error trying to create the database tables. Check you have correct permissions in SQL Server"; insResult.Successful = false; return insResult; } } } } } return insResult; }