/// <summary> /// Compacts the SQL CE database. No action is taken for other databases. Besides compacting the database, the /// process performs a critical task of resetting the identity columns of all tables. Without this step the app /// is at risk of generating the error 'A duplicate value cannot be inserted into a unique index' during a subsequent /// insert. /// </summary> /// <param name="backupFile">The backup file.</param> /// <exception cref="CannotCompactSqlCeException">Thrown when the database could not be compacted.</exception> private static void CompactSqlCeDb(IBackupFile backupFile) { if (backupFile.GalleryDataStore != ProviderDataStore.SqlCe) { return; } try { var engine = new SqlCeEngine(backupFile.ConnectionString); engine.Compact(null); } catch (SqlCeException) { // During testing it was observed that calling Compact could result in the error "Could not load database compaction library". // But if we pause and try again it succeeds. Pause(); var engineSecondTry = new SqlCeEngine(backupFile.ConnectionString); try { engineSecondTry.Compact(null); } catch (SqlCeException ex) { throw new CannotCompactSqlCeException("The database was successfully restored, but it could not be compacted. Navigate to the Site Settings page and manually perform a compaction. Error: " + ex.Message, ex); } } }
/// <summary> /// Validates that the backup file specified in the <see cref="IBackupFile.FilePath"/> property of the <paramref name="backupFile"/> /// parameter is valid and populates the remaining properties with information about the file. /// </summary> /// <param name="backupFile">An instance of <see cref="IBackupFile"/> that with only the <see cref="IBackupFile.FilePath"/> /// property assigned. The remaining properties should be uninitialized since they will be assigned in this method.</param> /// <remarks>Note that this function attempts to extract the number of records from each table in the backup file. Any exceptions /// that occur during this process are caught and trigger the <see cref="IBackupFile.IsValid" /> property to be set to false. If the extraction is /// successful, then the file is assumed to be valid and the <see cref="IBackupFile.IsValid" /> property is set to <c>true</c>.</remarks> internal static void ValidateBackupFile(ref IBackupFile backupFile) { try { using (DataSet ds = GenerateDataSet(backupFile.FilePath)) { string[] tableNames = new string[] { "aspnet_Applications", "aspnet_Profile", "aspnet_Roles", "aspnet_Users", "aspnet_UsersInRoles", "gs_Gallery", "gs_Album", "gs_MediaObject", "gs_MediaObjectMetadata", "gs_Role_Album", "gs_Role", "gs_AppError" }; foreach (string tableName in tableNames) { DataTable table = ds.Tables[tableName]; backupFile.DataTableRecordCount.Add(tableName, table.Rows.Count); } const string schemaVersionTableName = "gs_SchemaVersion"; DataTable schemaTable = ds.Tables[schemaVersionTableName]; DataRow schemaRow = schemaTable.Rows[0]; backupFile.SchemaVersion = schemaRow["SchemaVersion"].ToString(); if (backupFile.SchemaVersion == ConvertGalleryDataSchemaVersionToString(GalleryDataSchemaVersion.V2_3_3421)) { backupFile.IsValid = true; } } } catch { backupFile.IsValid = false; } }
private static void ValidateRestoreFile(IBackupFile backupFile) { if (Path.GetExtension(backupFile.FilePath).ToLowerInvariant() == ".xml") { HelperFunctions.ValidateBackupFile(backupFile); } }
/// <summary> /// Validates that the backup file specified in the <see cref="IBackupFile.FilePath"/> property of the <paramref name="backupFile"/> /// parameter is valid and populates the remaining properties with information about the file. /// </summary> /// <param name="backupFile">An instance of <see cref="IBackupFile"/> that with only the <see cref="IBackupFile.FilePath"/> /// property assigned. The remaining properties should be uninitialized since they will be assigned in this method.</param> /// <remarks>Note that this function attempts to extract the number of records from each table in the backup file. Any exceptions /// that occur during this process are caught and trigger the <see cref="IBackupFile.IsValid" /> property to be set to false. If the extraction is /// successful, then the file is assumed to be valid and the <see cref="IBackupFile.IsValid" /> property is set to <c>true</c>.</remarks> internal static void ValidateBackupFile(ref IBackupFile backupFile) { try { using (DataSet ds = GenerateDataSet(backupFile.FilePath)) { string[] tableNames = new string[] { "aspnet_Applications", "aspnet_Profile", "aspnet_Roles", "aspnet_Membership", "aspnet_Users", "aspnet_UsersInRoles", "gs_Gallery", "gs_Album", "gs_MediaObject", "gs_MediaObjectMetadata", "gs_Role_Album", "gs_Role", "gs_AppError", "gs_AppSetting", "gs_GalleryControlSetting", "gs_GallerySetting", "gs_BrowserTemplate", "gs_MimeType", "gs_MimeTypeGallery", "gs_UserGalleryProfile" }; foreach (string tableName in tableNames) { DataTable table = ds.Tables[tableName]; backupFile.DataTableRecordCount.Add(tableName, table.Rows.Count); } backupFile.SchemaVersion = GetDataSchemaVersionString(); if (backupFile.SchemaVersion == GalleryDataSchemaVersionEnumHelper.ConvertGalleryDataSchemaVersionToString(GalleryDataSchemaVersion.V2_6_0)) { backupFile.IsValid = true; } } } catch { backupFile.IsValid = false; } }
public GeneratedPackagesService(IModeDeploimentService modeDeploimentService, IBackupFile backupFile, IConsoleService consoleService, IUpdateFileService updateFileService, ICmdCordovaService cmdCordovaService, IConfigurationService configurationService, ISelectPathDirectoryService selectPathDirectoryService, IEventAggregator eventAggregator, ILoggerService loggerService) { _modeDeploimentService = modeDeploimentService; _backupFile = backupFile; _consoleService = consoleService; _updateFileService = updateFileService; _cmdCordovaService = cmdCordovaService; _configurationService = configurationService; _selectPathDirectoryService = selectPathDirectoryService; _eventAggregator = eventAggregator; _loggerService = loggerService; _config = _configurationService.GetConfig(); if (!_eventAggregator.GetEvent <CmdIsFinishEvent>().Contains(OnFinishRecevied)) { _eventAggregator.GetEvent <CmdIsFinishEvent>().Subscribe(OnFinishRecevied, false); } }
public static byte[] GetFileHash(IBackupFile file) { using (var stream = file.OpenRead()) { return(GetFileHash(stream)); } }
public void OpenCatalog(IBackupFile catalogFile) { var formatter = new BinaryFormatter(); using (var inStream = catalogFile.OpenRead()) { Catalog = (Catalog)formatter.Deserialize(inStream); } }
public Node(IBackupFile file, byte[] hash) { Name = file.Name; CreationTime = file.CreationTime; ModifiedTime = file.ModifiedTime; ReadOnly = file.ReadOnly; FileAttributes = file.Attributes; Hash = hash; }
private static IEnumerable <string> GetTableNamesForValidation(IBackupFile backupFile) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0) { return(MembershipTables26.Concat(GalleryTableNames26)); } else { return(backupFile.MembershipTables.Concat(backupFile.GalleryTableNames)); } }
/// <summary> /// Restore the self referencing album relationship that was deleted in <see cref="DropSelfReferencingAlbumConstraint" />, /// but only for SQL CE. /// </summary> /// <param name="backupFile">The backup file.</param> /// <param name="cn">The SQL connection.</param> /// <param name="tran">The transaction.</param> private static void RestoreSelfReferencingAlbumConstraint(IBackupFile backupFile, DbConnection cn, DbTransaction tran) { if (backupFile.GalleryDataStore == ProviderDataStore.SqlCe) { using (var cmd = cn.CreateCommand()) { cmd.Transaction = tran; cmd.CommandText = "ALTER TABLE Album ADD CONSTRAINT [FK_gsp.Album_gsp.Album_FKAlbumParentId] FOREIGN KEY(FKAlbumParentId) REFERENCES Album (AlbumId)"; cmd.ExecuteNonQuery(); } } }
public async Task <bool> StoreFile(IBackupFile file, byte[] hash) { if (file == null || !file.Exists) { throw new ArgumentException(); } using (var inStream = file.OpenRead()) { return(await StoreFile(inStream, hash)); } }
/// <summary> /// Exports the Gallery Server data in the current database to an XML-formatted string. /// </summary> /// <returns>Returns an XML-formatted string containing the gallery data.</returns> private static string Export(IBackupFile backupFile) { using (var ds = new DataSet("GalleryServerData")) { var asm = System.Reflection.Assembly.GetExecutingAssembly(); using (var stream = asm.GetManifestResourceStream("GalleryServer.Data.Schema.GalleryServerSchema.xml")) { ds.ReadXmlSchema(stream); } using (var cn = GetDbConnection(backupFile)) { using (var cmd = cn.CreateCommand()) { cn.Open(); if (backupFile.IncludeMembershipData) { foreach (var tableName in backupFile.MembershipTables) { cmd.CommandText = String.Concat(@"SELECT * FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore, "dbo"), ";"); ds.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges, tableName); } } if (backupFile.IncludeGalleryData) { foreach (var tableName in backupFile.GalleryTableNames) { cmd.CommandText = String.Concat(@"SELECT * FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore), ";"); ds.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges, tableName); } } else { // We always want to export the AppSettings table because that contains the schema version, which we need during a restore. cmd.CommandText = String.Concat(@"SELECT * FROM ", Utils.GetSqlName("AppSetting", backupFile.GalleryDataStore), ";"); ds.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges, "AppSetting"); } using (var sw = new StringWriter(CultureInfo.InvariantCulture)) { ds.WriteXml(sw, XmlWriteMode.WriteSchema); //ds.WriteXmlSchema(@"E:\GalleryServerSchema.xml"); // Use to create new schema file after a database change return(sw.ToString()); } } } } }
private static void Import(IBackupFile backupFile) { switch (backupFile.GalleryDataStore) { case ProviderDataStore.SqlServer: ImportIntoSqlServer(backupFile); break; case ProviderDataStore.SqlCe: ImportIntoSqlCe(backupFile); break; default: throw new System.ComponentModel.InvalidEnumArgumentException(String.Format("The function was not designed to handle the enumeration value '{0}'", backupFile.GalleryDataStore)); } }
private void ValidateRestoreFile(IBackupFile backupFile) { var fileExt = Path.GetExtension(backupFile.FilePath); if (fileExt != null && fileExt.ToLowerInvariant() == ".xml") { try { backupFile.Validate(); } catch (Exception ex) { LogError(ex); throw; } } }
/// <summary> /// Gets a database connection to the data store specified in <paramref name="backupFile" />. /// </summary> /// <param name="backupFile">The backup file.</param> /// <returns>DbConnection.</returns> /// <exception cref="System.ComponentModel.InvalidEnumArgumentException">Thrown when the data store in <paramref name="backupFile" /> /// is not recognized.</exception> private static DbConnection GetDbConnection(IBackupFile backupFile) { DbConnection cn; switch (backupFile.GalleryDataStore) { case ProviderDataStore.SqlServer: cn = new SqlConnection(backupFile.ConnectionString); break; case ProviderDataStore.SqlCe: cn = new SqlCeConnection(backupFile.ConnectionString); break; default: throw new System.ComponentModel.InvalidEnumArgumentException(String.Format("The function was not designed to handle the enumeration value '{0}'", backupFile.GalleryDataStore)); } return(cn); }
/// <summary> /// Validates that the backup file specified is valid and populates the remaining properties with information about the file. /// </summary> /// <param name="backupFile">The backup file.</param> private static void Validate(IBackupFile backupFile) { using (var ds = GenerateDataSet(backupFile)) { backupFile.SchemaVersion = GetDataSchemaVersion(ds); foreach (var tableName in GetTableNamesForValidation(backupFile)) { var table = ds.Tables[tableName]; var v3TableName = (backupFile.SchemaVersion >= GalleryDataSchemaVersion.V3_0_0 ? tableName : TableName26To30Map[tableName]); backupFile.DataTableRecordCount.Add(v3TableName, table.Rows.Count); } if (backupFile.SchemaVersion >= GalleryDataSchemaVersion.V2_6_0) { backupFile.IsValid = true; } } }
/// <summary> /// Generates a DataSet from the XML file specified in <paramref name="backupFile" />. /// </summary> /// <param name="backupFile">The backup file.</param> /// <returns>DataSet.</returns> /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="backupFile" /> is null.</exception> /// <exception cref="System.ArgumentException">Thrown when the file specified in <paramref name="backupFile" /> is not /// specified or does not exist.</exception> private static DataSet GenerateDataSet(IBackupFile backupFile) { if (backupFile == null) { throw new ArgumentNullException("backupFile"); } if (String.IsNullOrWhiteSpace(backupFile.FilePath)) { throw new ArgumentException("A file path must be specified. (parameter backupFile, property FilePath)"); } if (!File.Exists(backupFile.FilePath)) { throw new ArgumentException(String.Format("The file {0} does not exist.", backupFile.FilePath)); } DataSet ds = null; try { ds = new DataSet("GalleryServerData") { Locale = CultureInfo.InvariantCulture }; ds.ReadXml(backupFile.FilePath, XmlReadMode.Auto); return(ds); } catch { if (ds != null) { ds.Dispose(); } throw; } }
/// <summary> /// Deletes the data in the database in prepration for a restore. Some tables may not be deleted per the business rules. /// </summary> /// <param name="backupFile">The backup file.</param> /// <param name="cn">The database connection.</param> /// <param name="tran">The transaction to use.</param> private static void ClearData(IBackupFile backupFile, DbConnection cn, DbTransaction tran) { using (var cmd = cn.CreateCommand()) { cmd.Transaction = tran; if (backupFile.GalleryDataStore == ProviderDataStore.SqlServer) { // Increase timeout to give SQL Server time to clear the tables. (SQL CE throws an exception for any non-zero values, so we apply only for SQL Server) cmd.CommandTimeout = 3600; // 1 hour } if (backupFile.IncludeMembershipData) { foreach (var tableName in backupFile.MembershipTables.Reverse()) { // Smoke the table contents. cmd.CommandText = String.Concat("DELETE FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore, "dbo"), ";"); cmd.ExecuteNonQuery(); Pause(); } } if (backupFile.IncludeGalleryData) { foreach (var tableName in backupFile.GalleryTableNames.Reverse()) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0 && Array.IndexOf(GalleryTableNamesToIgnoreDuringUpgrade, tableName) >= 0) { continue; // Don't delete certain tables when upgrading because we don't have any source data from earlier version } // Smoke the table contents. cmd.CommandText = String.Concat("DELETE FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore), ";"); cmd.ExecuteNonQuery(); Pause(); } } } }
public BackupManager(IStorageLocationFactory storageLocationFactory, IBackupIOFactory backupIOFactory, IBackupFile catalogFile, IBackupManagerSettings settings, ILogger logger) { StorageLocationFactory = storageLocationFactory; BackupIOFactory = backupIOFactory; CatalogFile = catalogFile; Settings = settings; Logger = logger; LoadSettings(settings); if (catalogFile.Exists) { OpenCatalog(catalogFile); } else { Catalog = new Catalog(); } }
/// <summary> /// Validates that the backup file specified in the <see cref="IBackupFile.FilePath"/> property of the <paramref name="backupFile"/> /// parameter is valid and populates the remaining properties with information about the file. /// </summary> /// <param name="backupFile">An instance of <see cref="IBackupFile"/> that with only the <see cref="IBackupFile.FilePath"/> /// property assigned. The remaining properties should be uninitialized since they will be assigned in this method.</param> public override void ValidateBackupFile(ref IBackupFile backupFile) { Util.ValidateBackupFile(ref backupFile); }
/// <summary> /// Validates that the current backup file is valid and populates the remaining properties with information about the file. /// </summary> public static void ValidateFile(IBackupFile backupFile) { Validate(backupFile); }
private void ConfigureBackupFileInfo(IBackupFile backupFile) { if (backupFile == null) { lblRestoreFilename.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Not_Uploaded_Msg; lblRestoreFilename.CssClass = "gsp_msgwarning"; lblNumApps.Text = String.Empty; lblNumProfiles.Text = String.Empty; lblNumRoles.Text = String.Empty; lblNumMembers.Text = String.Empty; lblNumUsers.Text = String.Empty; lblNumUsersInRoles.Text = String.Empty; lblNumGalleries.Text = String.Empty; lblNumAlbums.Text = String.Empty; lblNumMediaObjects.Text = String.Empty; lblNumMetadata.Text = String.Empty; lblNumRoleAlbums.Text = String.Empty; lblNumAppSettings.Text = String.Empty; lblNumGalleryControlSettings.Text = String.Empty; lblNumGallerySettings.Text = String.Empty; lblNumBrowserTemplates.Text = String.Empty; lblNumMimeTypes.Text = String.Empty; lblNumMimeTypeGalleries.Text = String.Empty; lblNumGalleryRoles.Text = String.Empty; lblNumAppErrors.Text = String.Empty; lblNumUserGalleryProfiles.Text = String.Empty; btnRestore.Enabled = false; imgValidationResult.Visible = false; lblValidationResult.Text = String.Empty; lblValidationResult.CssClass = String.Empty; lbRemoveRestoreFile.Visible = false; return; } lblRestoreFilename.Text = Path.GetFileName(backupFile.FilePath); string[] tableNames = new string[] { "aspnet_Applications", "aspnet_Profile", "aspnet_Roles", "aspnet_Membership", "aspnet_Users", "aspnet_UsersInRoles", "gs_Gallery", "gs_Album", "gs_MediaObject", "gs_MediaObjectMetadata", "gs_Role_Album", "gs_Role", "gs_AppError", "gs_AppSetting", "gs_GalleryControlSetting", "gs_GallerySetting", "gs_BrowserTemplate", "gs_MimeType", "gs_MimeTypeGallery", "gs_UserGalleryProfile" }; Dictionary<string, int> dataRecords = backupFile.DataTableRecordCount; foreach (string tableName in tableNames) { switch (tableName) { case "aspnet_Applications": lblNumApps.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); chkImportMembership.Checked = (dataRecords.ContainsKey(tableName) && backupFile.DataTableRecordCount[tableName] > 0); break; case "aspnet_Profile": lblNumProfiles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "aspnet_Roles": lblNumRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "aspnet_Membership": lblNumMembers.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "aspnet_Users": lblNumUsers.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "aspnet_UsersInRoles": lblNumUsersInRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_Gallery": lblNumGalleries.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); chkImportGalleryData.Checked = (dataRecords.ContainsKey(tableName) && backupFile.DataTableRecordCount[tableName] > 0); break; case "gs_Album": lblNumAlbums.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_MediaObject": lblNumMediaObjects.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_MediaObjectMetadata": lblNumMetadata.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_Role_Album": lblNumRoleAlbums.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_Role": lblNumGalleryRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_AppSetting": lblNumAppSettings.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_GalleryControlSetting": lblNumGalleryControlSettings.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_GallerySetting": lblNumGallerySettings.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_BrowserTemplate": lblNumBrowserTemplates.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_MimeType": lblNumMimeTypes.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_MimeTypeGallery": lblNumMimeTypeGalleries.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_AppError": lblNumAppErrors.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "gs_UserGalleryProfile": lblNumUserGalleryProfiles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; } } if (backupFile.IsValid) { btnRestore.Enabled = true && !AppSetting.Instance.License.IsInReducedFunctionalityMode; imgValidationResult.ImageUrl = Utils.GetUrl("/images/info.gif"); imgValidationResult.Visible = true; lblValidationResult.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Valid_Msg; lblValidationResult.CssClass = "gsp_msgsuccess"; lblRestoreFilename.CssClass = "gsp_msgattention"; lbRemoveRestoreFile.Visible = true; lblSchemaVersion.Text = backupFile.SchemaVersion; ViewState["FilePath"] = backupFile.FilePath; } else { btnRestore.Enabled = false; imgValidationResult.ImageUrl = Utils.GetUrl("/images/warning.gif"); imgValidationResult.Visible = true; lblValidationResult.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Not_Valid_Msg; lblValidationResult.CssClass = "gsp_msgfailure"; lblRestoreFilename.CssClass = "gsp_msgattention"; lbRemoveRestoreFile.Visible = false; lblSchemaVersion.Text = backupFile.SchemaVersion; } }
private void ConfigureBackupFileInfo(IBackupFile backupFile) { if (backupFile == null) { lblRestoreFilename.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Not_Uploaded_Msg; lblRestoreFilename.CssClass = "gsp_msgwarning"; lblNumApps.Text = String.Empty; lblNumProfiles.Text = String.Empty; lblNumRoles.Text = String.Empty; lblNumUsers.Text = String.Empty; lblNumUsersInRoles.Text = String.Empty; lblNumGalleries.Text = String.Empty; lblNumAlbums.Text = String.Empty; lblNumMediaObjects.Text = String.Empty; lblNumMetadata.Text = String.Empty; lblNumRoleAlbums.Text = String.Empty; lblNumGalleryRoles.Text = String.Empty; lblNumAppErrors.Text = String.Empty; btnRestore.Enabled = false; imgValidationResult.Visible = false; lblValidationResult.Text = String.Empty; lblValidationResult.CssClass = String.Empty; lbRemoveRestoreFile.Visible = false; return; } lblRestoreFilename.Text = Path.GetFileName(backupFile.FilePath); string[] tableNames = new string[] { "aspnet_Applications", "aspnet_Profile", "aspnet_Roles", "aspnet_Users", "aspnet_UsersInRoles", "gs_Gallery", "gs_Album", "gs_MediaObject", "gs_MediaObjectMetadata", "gs_Role_Album", "gs_Role", "gs_AppError" }; Dictionary <string, int> dataRecords = backupFile.DataTableRecordCount; foreach (string tableName in tableNames) { switch (tableName) { case "aspnet_Applications": lblNumApps.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "aspnet_Profile": lblNumProfiles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "aspnet_Roles": lblNumRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "aspnet_Users": lblNumUsers.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "aspnet_UsersInRoles": lblNumUsersInRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "gs_Gallery": lblNumGalleries.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "gs_Album": lblNumAlbums.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "gs_MediaObject": lblNumMediaObjects.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "gs_MediaObjectMetadata": lblNumMetadata.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "gs_Role_Album": lblNumRoleAlbums.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "gs_Role": lblNumGalleryRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; case "gs_AppError": lblNumAppErrors.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString() : String.Empty); break; } } if (backupFile.IsValid) { btnRestore.Enabled = true && !AppSetting.Instance.IsInReducedFunctionalityMode; imgValidationResult.ImageUrl = Util.GetUrl("/images/info.gif"); imgValidationResult.Visible = true; lblValidationResult.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Valid_Msg; lblValidationResult.CssClass = "gsp_msgsuccess"; lblRestoreFilename.CssClass = "gsp_msgattention"; lbRemoveRestoreFile.Visible = true; lblSchemaVersion.Text = backupFile.SchemaVersion; ViewState["FilePath"] = backupFile.FilePath; } else { btnRestore.Enabled = false; imgValidationResult.ImageUrl = Util.GetUrl("/images/warning.gif"); imgValidationResult.Visible = true; lblValidationResult.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Not_Valid_Msg; lblValidationResult.CssClass = "gsp_msgfailure"; lblRestoreFilename.CssClass = "gsp_msgattention"; lbRemoveRestoreFile.Visible = false; lblSchemaVersion.Text = backupFile.SchemaVersion; } }
public UpdateFileService(IBackupFile backupFile, IConsoleService consoleService) { _backupFile = backupFile; _consoleService = consoleService; }
/// <summary> /// Validates that the backup file specified in the <see cref="IBackupFile.FilePath"/> property of the <paramref name="backupFile"/> /// parameter is valid and populates the remaining properties with information about the file. /// </summary> /// <param name="backupFile">An instance of <see cref="IBackupFile"/> that with only the <see cref="IBackupFile.FilePath"/> /// property assigned. The remaining properties should be uninitialized since they will be assigned in this method.</param> public abstract void ValidateBackupFile(ref IBackupFile backupFile);
/// <summary> /// Imports the data into SQL CE. This is identical to <see cref="ImportIntoSqlServer" /> except for the names of the classes /// SqlCeConnection/SqlConnection, SqlCeBulkCopy/SqlBulkCopy, SqlCeBulkCopyOptions/SqlBulkCopyOptions /// </summary> /// <param name="backupFile">The backup file.</param> private static void ImportIntoSqlCe(IBackupFile backupFile) { using (var ds = GenerateDataSet(backupFile)) { backupFile.SchemaVersion = GetDataSchemaVersion(ds); using (var cn = new SqlCeConnection(backupFile.ConnectionString)) { cn.Open(); using (var tran = cn.BeginTransaction()) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0) { Migrate26Controller.UpgradeData(ds, GalleryDataSchemaVersion.V3_2_1, backupFile.GalleryDataStore, cn, tran); } if (backupFile.SchemaVersion < GalleryDataSchemaVersion.V4_0_0) { MigrateController.UpgradeToCurrentSchema(ds); } DropSelfReferencingAlbumConstraint(backupFile, cn, tran); ClearData(backupFile, cn, tran); if (backupFile.IncludeMembershipData) { // SqlBulkCopy requires SQL permissions equivalent to that provided in the db_ddladmin or db_owner roles. using (var bulkCopy = new SqlCeBulkCopy(cn, SqlCeBulkCopyOptions.KeepIdentity, tran)) { bulkCopy.BulkCopyTimeout = 3600; // 1 hour foreach (var tableName in backupFile.MembershipTables) { bulkCopy.ColumnMappings.Clear(); bulkCopy.DestinationTableName = Utils.GetSqlName(tableName, backupFile.GalleryDataStore, "dbo"); foreach (DataColumn dc in ds.Tables[tableName].Columns) { bulkCopy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName); } // Write from the source to the destination. try { bulkCopy.WriteToServer(ds.Tables[tableName]); } catch (Exception ex) { // Add a little info to exception and re-throw. if (!ex.Data.Contains("SQL Bulk copy error")) { ex.Data.Add("SQL Bulk copy error", String.Format(CultureInfo.CurrentCulture, "Error occurred while importing table {0}.", tableName)); } throw; } } } } if (backupFile.IncludeGalleryData) { // Tables to skip: Event, MediaQueue, Synchronize // SqlBulkCopy requires SQL permissions equivalent to that provided in the db_ddladmin or db_owner roles. using (var bulkCopy = new SqlCeBulkCopy(cn, SqlCeBulkCopyOptions.KeepIdentity, tran)) { bulkCopy.BulkCopyTimeout = 3600; // 1 hour foreach (var tableName in backupFile.GalleryTableNames) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0 && Array.IndexOf(GalleryTableNamesToIgnoreDuringUpgrade, tableName) >= 0) { continue; // Don't import certain tables when upgrading because we want to keep the 3.0 data } bulkCopy.DestinationTableName = Utils.GetSqlName(tableName, backupFile.GalleryDataStore); // Don't need to map the columns like we did in the membership section because it works without it. // Write from the source to the destination. try { bulkCopy.WriteToServer(ds.Tables[tableName]); } catch (Exception ex) { // Add a little info to exception and re-throw. if (!ex.Data.Contains("SQL Bulk copy error")) { ex.Data.Add("SQL Bulk copy error", String.Format(CultureInfo.CurrentCulture, "Error occurred while importing table {0}.", tableName)); } throw; } } } } if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0) { Migrate26Controller.AddMissingMeta(backupFile.GalleryDataStore, cn, tran); } RestoreSelfReferencingAlbumConstraint(backupFile, cn, tran); tran.Commit(); } } } CompactSqlCeDb(backupFile); }
private void ConfigureBackupFileInfo(IBackupFile backupFile) { if (backupFile == null) { lblRestoreFilename.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Not_Uploaded_Msg; lblRestoreFilename.CssClass = "gsp_msgwarning"; lblNumApps.Text = String.Empty; lblNumProfiles.Text = String.Empty; lblNumRoles.Text = String.Empty; lblNumMembers.Text = String.Empty; lblNumUsers.Text = String.Empty; lblNumUsersInRoles.Text = String.Empty; lblNumGalleries.Text = String.Empty; lblNumAlbums.Text = String.Empty; lblNumMediaObjects.Text = String.Empty; lblNumMetadata.Text = String.Empty; lblNumTag.Text = String.Empty; lblNumMetadataTag.Text = String.Empty; lblNumRoleAlbums.Text = String.Empty; lblNumAppSettings.Text = String.Empty; lblNumGalleryControlSettings.Text = String.Empty; lblNumGallerySettings.Text = String.Empty; lblNumBrowserTemplates.Text = String.Empty; lblNumMimeTypes.Text = String.Empty; lblNumMimeTypeGalleries.Text = String.Empty; lblNumGalleryRoles.Text = String.Empty; lblNumUiTemplates.Text = String.Empty; lblNumUiTemplateAlbums.Text = String.Empty; lblNumUserGalleryProfiles.Text = String.Empty; btnRestore.Enabled = false; imgValidationResult.Visible = false; lblValidationResult.Text = String.Empty; lblValidationResult.CssClass = String.Empty; lbRemoveRestoreFile.Visible = false; return; } lblRestoreFilename.Text = Path.GetFileName(backupFile.FilePath); var tableNames = backupFile.MembershipTables.Concat(backupFile.GalleryTableNames); var dataRecords = backupFile.DataTableRecordCount; foreach (var tableName in tableNames) { switch (tableName) { case "Applications": lblNumApps.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); chkImportMembership.Checked = (dataRecords.ContainsKey(tableName) && backupFile.DataTableRecordCount[tableName] > 0); break; case "Profiles": lblNumProfiles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "Roles": lblNumRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "Memberships": lblNumMembers.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "Users": lblNumUsers.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "UsersInRoles": lblNumUsersInRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "Gallery": lblNumGalleries.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); chkImportGalleryData.Checked = (dataRecords.ContainsKey(tableName) && backupFile.DataTableRecordCount[tableName] > 0); break; case "Album": lblNumAlbums.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "MediaObject": lblNumMediaObjects.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "Metadata": lblNumMetadata.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "Tag": //** lblNumTag.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "MetadataTag": //** lblNumMetadataTag.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "RoleAlbum": lblNumRoleAlbums.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "Role": lblNumGalleryRoles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "AppSetting": lblNumAppSettings.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "GalleryControlSetting": lblNumGalleryControlSettings.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "GallerySetting": lblNumGallerySettings.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "MediaTemplate": lblNumBrowserTemplates.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "MimeType": lblNumMimeTypes.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "MimeTypeGallery": lblNumMimeTypeGalleries.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "UiTemplate": lblNumUiTemplates.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "UiTemplateAlbum": lblNumUiTemplateAlbums.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; case "UserGalleryProfile": lblNumUserGalleryProfiles.Text = (dataRecords.ContainsKey(tableName) ? backupFile.DataTableRecordCount[tableName].ToString(CultureInfo.CurrentCulture) : String.Empty); break; } } if (backupFile.IsValid) { btnRestore.Enabled = true; imgValidationResult.ImageUrl = Utils.GetSkinnedUrl("/images/arrow-right-open-s.png"); imgValidationResult.Visible = true; lblValidationResult.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Valid_Msg; lblValidationResult.CssClass = "gsp_msgsuccess"; lblRestoreFilename.CssClass = "gsp_msgattention"; lbRemoveRestoreFile.Visible = true; lblSchemaVersion.Text = GalleryDataSchemaVersionEnumHelper.ConvertGalleryDataSchemaVersionToString(backupFile.SchemaVersion); ViewState["FilePath"] = backupFile.FilePath; } else { btnRestore.Enabled = false; imgValidationResult.ImageUrl = Utils.GetSkinnedUrl("/images/warning-s.png"); imgValidationResult.Visible = true; lblValidationResult.Text = Resources.GalleryServerPro.Admin_Backup_Restore_File_Not_Valid_Msg; lblValidationResult.CssClass = "gsp_msgfailure"; lblRestoreFilename.CssClass = "gsp_msgattention"; lbRemoveRestoreFile.Visible = false; lblSchemaVersion.Text = GalleryDataSchemaVersionEnumHelper.ConvertGalleryDataSchemaVersionToString(backupFile.SchemaVersion); } }
/// <summary> /// Exports the Gallery Server data in the current database to an XML-formatted string. Does not export the actual media files; /// they must be copied manually with a utility such as Windows Explorer. This method does not make any changes to the database tables /// or the files in the media objects directory. /// </summary> /// <returns>Returns an XML-formatted string containing the gallery data.</returns> public static string ExportToFile(IBackupFile backupFile) { return(Export(backupFile)); }
/// <summary> /// Imports the Gallery Server data into the current database, overwriting any existing data. Does not import the actual media /// files; they must be imported manually with a utility such as Windows Explorer. This method makes changes only to the database tables; /// no files in the media objects directory are affected. If both <see cref="IBackupFile.IncludeMembershipData" /> and /// <see cref="IBackupFile.IncludeGalleryData" /> are false, then no action is taken. /// </summary> public static void ImportFromFile(IBackupFile backupFile) { Import(backupFile); }
/// <summary> /// Deletes the data in the database in prepration for a restore. Some tables may not be deleted per the business rules. /// </summary> /// <param name="backupFile">The backup file.</param> /// <param name="cn">The database connection.</param> /// <param name="tran">The transaction to use.</param> private static void ClearData(IBackupFile backupFile, DbConnection cn, DbTransaction tran) { using (var cmd = cn.CreateCommand()) { cmd.Transaction = tran; if (backupFile.GalleryDataStore == ProviderDataStore.SqlServer) { // Increase timeout to give SQL Server time to clear the tables. (SQL CE throws an exception for any non-zero values, so we apply only for SQL Server) cmd.CommandTimeout = 3600; // 1 hour } if (backupFile.IncludeMembershipData) { foreach (var tableName in backupFile.MembershipTables.Reverse()) { // Smoke the table contents. cmd.CommandText = String.Concat("DELETE FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore, "dbo"), ";"); cmd.ExecuteNonQuery(); Pause(); } } if (backupFile.IncludeGalleryData) { foreach (var tableName in backupFile.GalleryTableNames.Reverse()) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0 && Array.IndexOf(GalleryTableNamesToIgnoreDuringUpgrade, tableName) >= 0) continue; // Don't delete certain tables when upgrading because we don't have any source data from earlier version // Smoke the table contents. cmd.CommandText = String.Concat("DELETE FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore), ";"); cmd.ExecuteNonQuery(); Pause(); } } } }
private static IEnumerable<string> GetTableNamesForValidation(IBackupFile backupFile) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0) { return MembershipTables26.Concat(GalleryTableNames26); } else { return backupFile.MembershipTables.Concat(backupFile.GalleryTableNames); } }
public async Task <bool> StoreFile(IBackupFile file, byte[] hash) { var success = false; await Communicator.SendMessage(new FileStartMessage(hash)); var totalBytes = file.Length; var buffer = new byte[BufferSize]; var position = 0L; var remainingBytes = totalBytes; var message = new FileChunckMessage() { FileHash = hash }; if (FileTransferResponse.ContainsKey(hash)) { FileTransferResponse.Remove(hash); } FileTransferResponse.Add(hash, false); using (var fileStream = file.OpenRead()) { while (position < totalBytes) { var bytesToRead = (int)((remainingBytes > BufferSize) ? BufferSize : remainingBytes); if (bytesToRead < BufferSize) { buffer = new byte[bytesToRead]; } position += fileStream.Read(buffer, 0, bytesToRead); remainingBytes = totalBytes - position; message.FileData = buffer; await Communicator.SendMessage(message); while (!FileTransferResponse[hash]) { await Task.Delay(1); } FileTransferResponse[hash] = false; } } await Communicator.SendMessage(new FileEndMessage(hash)); // Watch the inbound messages for a verification message var gotVerificationMessage = false; while (!gotVerificationMessage) { if (VerificationMessages.ContainsKey(hash)) { var verifyMessage = VerificationMessages[hash] as FileStoredVerificationMessage; success = verifyMessage?.Success ?? false; VerificationMessages.Remove(hash); gotVerificationMessage = true; } await Task.Delay(1); } return(success); }
/// <summary> /// Validates that the backup file specified in the <see cref="IBackupFile.FilePath" /> property of the <paramref name="backupFile"/> /// parameter is valid and populates the remaining properties with information about the file. /// </summary> /// <param name="backupFile">An instance of <see cref="IBackupFile" /> that with only the <see cref="IBackupFile.FilePath" /> /// property assigned. The remaining properties should be uninitialized since they will be assigned in this method.</param> public static void ValidateBackupFile(IBackupFile backupFile) { Factory.GetDataProvider().ValidateBackupFile(ref backupFile); }
/// <summary> /// Exports the Gallery Server Pro data in the current database to an XML-formatted string. /// </summary> /// <returns>Returns an XML-formatted string containing the gallery data.</returns> private static string Export(IBackupFile backupFile) { using (var ds = new DataSet("GalleryServerData")) { var asm = System.Reflection.Assembly.GetExecutingAssembly(); using (var stream = asm.GetManifestResourceStream("GalleryServerPro.Data.Schema.GalleryServerProSchema.xml")) { ds.ReadXmlSchema(stream); } using (var cn = GetDbConnection(backupFile)) { using (var cmd = cn.CreateCommand()) { cn.Open(); if (backupFile.IncludeMembershipData) { foreach (var tableName in backupFile.MembershipTables) { cmd.CommandText = String.Concat(@"SELECT * FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore, "dbo"), ";"); ds.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges, tableName); } } if (backupFile.IncludeGalleryData) { foreach (var tableName in backupFile.GalleryTableNames) { cmd.CommandText = String.Concat(@"SELECT * FROM ", Utils.GetSqlName(tableName, backupFile.GalleryDataStore), ";"); ds.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges, tableName); } } else { // We always want to export the AppSettings table because that contains the schema version, which we need during a restore. cmd.CommandText = String.Concat(@"SELECT * FROM ", Utils.GetSqlName("AppSetting", backupFile.GalleryDataStore), ";"); ds.Load(cmd.ExecuteReader(), LoadOption.OverwriteChanges, "AppSetting"); } using (var sw = new StringWriter(CultureInfo.InvariantCulture)) { ds.WriteXml(sw, XmlWriteMode.WriteSchema); //ds.WriteXmlSchema(@"E:\GalleryServerProSchema.xml"); // Use to create new schema file after a database change return sw.ToString(); } } } } }
/// <summary> /// Gets a database connection to the data store specified in <paramref name="backupFile" />. /// </summary> /// <param name="backupFile">The backup file.</param> /// <returns>DbConnection.</returns> /// <exception cref="System.ComponentModel.InvalidEnumArgumentException">Thrown when the data store in <paramref name="backupFile" /> /// is not recognized.</exception> private static DbConnection GetDbConnection(IBackupFile backupFile) { DbConnection cn; switch (backupFile.GalleryDataStore) { case ProviderDataStore.SqlServer: cn = new SqlConnection(backupFile.ConnectionString); break; case ProviderDataStore.SqlCe: cn = new SqlCeConnection(backupFile.ConnectionString); break; default: throw new System.ComponentModel.InvalidEnumArgumentException(String.Format("The function was not designed to handle the enumeration value '{0}'", backupFile.GalleryDataStore)); } return cn; }
/// <summary> /// Compacts the SQL CE database. No action is taken for other databases. Besides compacting the database, the /// process performs a critical task of resetting the identity columns of all tables. Without this step the app /// is at risk of generating the error 'A duplicate value cannot be inserted into a unique index' during a subsequent /// insert. /// </summary> /// <param name="backupFile">The backup file.</param> /// <exception cref="CannotCompactSqlCeException">Thrown when the database could not be compacted.</exception> private static void CompactSqlCeDb(IBackupFile backupFile) { if (backupFile.GalleryDataStore != ProviderDataStore.SqlCe) return; try { var engine = new SqlCeEngine(backupFile.ConnectionString); engine.Compact(null); } catch (SqlCeException) { // During testing it was observed that calling Compact could result in the error "Could not load database compaction library". // But if we pause and try again it succeeds. Pause(); var engineSecondTry = new SqlCeEngine(backupFile.ConnectionString); try { engineSecondTry.Compact(null); } catch (SqlCeException ex) { throw new CannotCompactSqlCeException("The database was successfully restored, but it could not be compacted. Navigate to the Site Settings page and manually perform a compaction. Error: " + ex.Message, ex); } } }
private static void ValidateRestoreFile(IBackupFile backupFile) { if (Path.GetExtension(backupFile.FilePath).ToLowerInvariant() == ".xml") HelperFunctions.ValidateBackupFile(backupFile); }
/// <summary> /// Generates a DataSet from the XML file specified in <paramref name="backupFile" />. /// </summary> /// <param name="backupFile">The backup file.</param> /// <returns>DataSet.</returns> /// <exception cref="System.ArgumentNullException">Thrown when <paramref name="backupFile" /> is null.</exception> /// <exception cref="System.ArgumentException">Thrown when the file specified in <paramref name="backupFile" /> is not /// specified or does not exist.</exception> private static DataSet GenerateDataSet(IBackupFile backupFile) { if (backupFile == null) throw new ArgumentNullException("backupFile"); if (String.IsNullOrWhiteSpace(backupFile.FilePath)) throw new ArgumentException("A file path must be specified. (parameter backupFile, property FilePath)"); if (!File.Exists(backupFile.FilePath)) throw new ArgumentException(String.Format("The file {0} does not exist.", backupFile.FilePath)); DataSet ds = null; try { ds = new DataSet("GalleryServerData") { Locale = CultureInfo.InvariantCulture }; ds.ReadXml(backupFile.FilePath, XmlReadMode.Auto); return ds; } catch { if (ds != null) ds.Dispose(); throw; } }
/// <summary> /// Validates that the backup file specified in the <see cref="IBackupFile.FilePath"/> property of the <paramref name="backupFile"/> /// parameter is valid and populates the remaining properties with information about the file. /// </summary> /// <param name="backupFile">An instance of <see cref="IBackupFile"/> that with only the <see cref="IBackupFile.FilePath"/> /// property assigned. The remaining properties should be uninitialized since they will be assigned in this method.</param> /// <remarks>Note that this function attempts to extract the number of records from each table in the backup file. Any exceptions /// that occur during this process are caught and trigger the <see cref="IBackupFile.IsValid" /> property to be set to false. If the extraction is /// successful, then the file is assumed to be valid and the <see cref="IBackupFile.IsValid" /> property is set to <c>true</c>.</remarks> internal static void ValidateBackupFile(ref IBackupFile backupFile) { try { using (DataSet ds = GenerateDataSet(backupFile.FilePath)) { string[] tableNames = new string[] { "aspnet_Applications", "aspnet_Profile", "aspnet_Roles", "aspnet_Membership", "aspnet_Users", "aspnet_UsersInRoles", "gs_Gallery", "gs_Album", "gs_MediaObject", "gs_MediaObjectMetadata", "gs_Role_Album", "gs_Role", "gs_AppError", "gs_AppSetting", "gs_GalleryControlSetting", "gs_GallerySetting", "gs_BrowserTemplate", "gs_MimeType", "gs_MimeTypeGallery", "gs_UserGalleryProfile" }; foreach (string tableName in tableNames) { DataTable table = ds.Tables[tableName]; backupFile.DataTableRecordCount.Add(tableName, table.Rows.Count); } backupFile.SchemaVersion = GetDataSchemaVersionString(); if (backupFile.SchemaVersion == GalleryDataSchemaVersionEnumHelper.ConvertGalleryDataSchemaVersionToString(GalleryDataSchemaVersion.V2_5_0)) { backupFile.IsValid = true; } } } catch { backupFile.IsValid = false; } }
/// <summary> /// Imports the data into SQL server. This is identical to <see cref="ImportIntoSqlCe" /> except for the names of the classes /// SqlCeConnection/SqlConnection, SqlCeBulkCopy/SqlBulkCopy, SqlCeBulkCopyOptions/SqlBulkCopyOptions /// </summary> /// <param name="backupFile">The backup file.</param> private static void ImportIntoSqlServer(IBackupFile backupFile) { using (var ds = GenerateDataSet(backupFile)) { backupFile.SchemaVersion = GetDataSchemaVersion(ds); using (var cn = new SqlConnection(backupFile.ConnectionString)) { cn.Open(); using (var tran = cn.BeginTransaction()) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0) { Migrate26Controller.UpgradeData(ds, GalleryDb.DataSchemaVersion, backupFile.GalleryDataStore, cn, tran); } DropSelfReferencingAlbumConstraint(backupFile, cn, tran); ClearData(backupFile, cn, tran); if (backupFile.IncludeMembershipData) { // SqlBulkCopy requires SQL permissions equivalent to that provided in the db_ddladmin or db_owner roles. using (var bulkCopy = new SqlBulkCopy(cn, SqlBulkCopyOptions.KeepIdentity, tran)) { bulkCopy.BulkCopyTimeout = 3600; // 1 hour foreach (var tableName in backupFile.MembershipTables) { bulkCopy.ColumnMappings.Clear(); bulkCopy.DestinationTableName = Utils.GetSqlName(tableName, backupFile.GalleryDataStore, "dbo"); foreach (DataColumn dc in ds.Tables[tableName].Columns) { bulkCopy.ColumnMappings.Add(dc.ColumnName, dc.ColumnName); } // Write from the source to the destination. try { bulkCopy.WriteToServer(ds.Tables[tableName]); } catch (Exception ex) { // Add a little info to exception and re-throw. if (!ex.Data.Contains("SQL Bulk copy error")) { ex.Data.Add("SQL Bulk copy error", String.Format(CultureInfo.CurrentCulture, "Error occurred while importing table {0}.", tableName)); } throw; } } } } if (backupFile.IncludeGalleryData) { // Tables to skip: Event, MediaQueue, Synchronize // SqlBulkCopy requires SQL permissions equivalent to that provided in the db_ddladmin or db_owner roles. using (var bulkCopy = new SqlBulkCopy(cn, SqlBulkCopyOptions.KeepIdentity, tran)) { bulkCopy.BulkCopyTimeout = 3600; // 1 hour foreach (var tableName in backupFile.GalleryTableNames) { if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0 && Array.IndexOf(GalleryTableNamesToIgnoreDuringUpgrade, tableName) >= 0) continue; // Don't import certain tables when upgrading because we want to keep the 3.0 data bulkCopy.DestinationTableName = Utils.GetSqlName(tableName, backupFile.GalleryDataStore); // Don't need to map the columns like we did in the membership section because it works without it. // Write from the source to the destination. try { bulkCopy.WriteToServer(ds.Tables[tableName]); } catch (Exception ex) { // Add a little info to exception and re-throw. if (!ex.Data.Contains("SQL Bulk copy error")) { ex.Data.Add("SQL Bulk copy error", String.Format(CultureInfo.CurrentCulture, "Error occurred while importing table {0}.", tableName)); } throw; } } } } if (backupFile.SchemaVersion == GalleryDataSchemaVersion.V2_6_0) { Migrate26Controller.AddMissingMeta(backupFile.GalleryDataStore, cn, tran); } RestoreSelfReferencingAlbumConstraint(backupFile, cn, tran); tran.Commit(); } } } CompactSqlCeDb(backupFile); }
/// <summary> /// Imports the Gallery Server Pro data into the current database, overwriting any existing data. Does not import the actual media /// files; they must be imported manually with a utility such as Windows Explorer. This method makes changes only to the database tables; /// no files in the media objects directory are affected. If both <see cref="IBackupFile.IncludeMembershipData" /> and /// <see cref="IBackupFile.IncludeGalleryData" /> are false, then no action is taken. /// </summary> public static void ImportFromFile(IBackupFile backupFile) { Import(backupFile); }
/// <summary> /// Exports the Gallery Server Pro data in the current database to an XML-formatted string. Does not export the actual media files; /// they must be copied manually with a utility such as Windows Explorer. This method does not make any changes to the database tables /// or the files in the media objects directory. /// </summary> /// <returns>Returns an XML-formatted string containing the gallery data.</returns> public static string ExportToFile(IBackupFile backupFile) { return Export(backupFile); }