/// <summary> /// Basic request from primary key (quick) /// SQL equivalent: SELECT * FROM [topic] WHERE (primary key) IN ([pkValues]); /// </summary> /// <param name="topic">Database topic</param> /// <param name="pkValues">Array of primary key values to search</param> public static List <DB.Entry> SelectAllCellsFromTopicWherePrimaryKey(DB topic, params string[] pkValues) { List <DB.Entry> result = new List <DB.Entry>(); if (pkValues == null) { return(result); } // Searching for specified primary key values foreach (string anotherPk in pkValues) { if (topic.EntriesByPrimaryKey.ContainsKey(anotherPk)) { DB.Entry currentEntry = topic.EntriesByPrimaryKey[anotherPk]; if (!result.Contains(currentEntry)) { result.Add(currentEntry); } } } return(result); }
/// <summary> /// Ensures PK cache is correctly updated /// </summary> /// <param name="topic"></param> /// <param name="anotherEntry"></param> private static void _UpdatePKCache(DB topic, DB.Entry anotherEntry) { if (topic != null && anotherEntry.primaryKey != null) { topic.EntriesByPrimaryKey[anotherEntry.primaryKey] = anotherEntry; } }
/// <summary> /// Replaces specified value from any column with provided default value /// No SQL equivalent known. /// </summary> /// <param name="topic"></param> /// <param name="value">value to remove</param> /// <param name="defaultValue">default value to set</param> public static void RemoveValueFromAnyColumn(DB topic, string value, string defaultValue) { if (!string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(defaultValue)) { // Parsing all entries for (int i = 0; i < topic.Entries.Count; i++) { DB.Entry currentEntry = topic.Entries[i]; bool isModified = false; // Parsing all columns for (int j = 0; j < currentEntry.cells.Count; j++) { DB.Cell currentCell = currentEntry.cells[j]; if (value.Equals(currentCell.value)) { currentCell.value = defaultValue; currentEntry.cells[j] = currentCell; isModified = true; } } if (isModified) { topic.Entries[i] = currentEntry; } } } }
/// <summary> /// Updates the whole specified entry with provided value /// </summary> /// <param name="entryToUpdate">Entry to update</param> /// <param name="newValue">All values, separated by default separator (TAB)</param> /// <returns></returns> private static DB.Entry _UpdateFullEntryWithValue(DB.Entry entryToUpdate, string newValue) { DB.Entry returnedEntry = new DB.Entry(); // Parsing provided value string[] allValues = newValue.Split(_SYMBOL_FIELD_SEPARATOR); if (allValues.Length == entryToUpdate.cells.Count) { // Updating all cells int cellIndex = 0; foreach (string anotherValue in allValues) { DB.Cell currentCell = entryToUpdate.cells[cellIndex]; currentCell.value = anotherValue; entryToUpdate.cells[cellIndex] = currentCell; cellIndex++; } returnedEntry = entryToUpdate; } else { Log.Error("Value to update is not compatible with target table.", null); } return(returnedEntry); }
/// <summary> /// Deletion (technical-fast) /// No SQL equivalent. /// </summary> /// <param name="topic">Database topic</param> /// <param name="entryId">Id of entries to delete (value of first column)</param> public static void DeleteFromTopicWithEntryId(DB topic, int entryId) { if (entryId < 0 || entryId >= topic.EntryCount) { return; } // Removing entry DB.Entry currentEntry = topic.Entries[entryId]; topic.Entries.Remove(currentEntry); if (currentEntry.primaryKey != null) { topic.EntriesByPrimaryKey.Remove(currentEntry.primaryKey); } // Updating following entry ids for (int index = entryId; index < topic.Entries.Count; index++) { DB.Entry anotherEntry = topic.Entries[index]; anotherEntry.index--; // BUG_95: update entry id in all cells anotherEntry = _UpdateAllCellEntryIds(anotherEntry); // _UpdatePKCache(topic, anotherEntry); topic.Entries[anotherEntry.index] = anotherEntry; } }
/// <summary> /// Exchanges specified entries /// </summary> /// <param name="topic"></param> /// <param name="entryId1"></param> /// <param name="entryId2"></param> public static void SwapEntriesWithEntryId(DB topic, int entryId1, int entryId2) { if (topic != null && entryId1 >= 0 && entryId2 >= 0 && entryId1 < topic.EntryCount && entryId2 < topic.EntryCount && entryId1 != entryId2) { DB.Entry entry1 = topic.Entries[entryId1]; DB.Entry entry2 = topic.Entries[entryId2]; // Entryies update entry1.index = entryId2; entry2.index = entryId1; // Cells update _UpdateAllCellEntryIds(entry1); _UpdateAllCellEntryIds(entry2); // PK update _UpdatePKCache(topic, entry1); _UpdatePKCache(topic, entry2); // Entry cache update topic.Entries[entryId1] = entry2; topic.Entries[entryId2] = entry1; } }
/// <summary> /// Defines window contents /// </summary> private void _InitializeContents() { // Getting cooresponding line... DB.Entry setEntry = DatabaseHelper.SelectAllCellsFromTopicWherePrimaryKey(_InteriorTable, _InteriorSetId)[0]; _UpdateSetList(setEntry); }
/// <summary> /// Full insert. PK value is not checked. /// SQL equivalent: INSERT INTO [topic] (column list) VALUES ([value]); /// </summary> /// <param name="topic">Database topic</param> /// <param name="value">Values to add (=list of values separated by tab)</param> public static void InsertAllCellsIntoTopic(DB topic, string value) { if (topic != null && !string.IsNullOrEmpty(value)) { // Parsing provided value string[] allValues = value.Split(_SYMBOL_FIELD_SEPARATOR); if (allValues.Length == topic.ColumnCount) { // Creating entry int entryIndex = topic.EntryCount; DB.Entry newEntry = new DB.Entry(); newEntry.index = entryIndex; newEntry.cells = new List <DB.Cell>(); // Creating all cells int cellIndex = 0; foreach (string anotherValue in allValues) { DB.Cell currentCell = topic._CreateEmptyCell(cellIndex); currentCell.entryIndex = entryIndex; currentCell.value = anotherValue; newEntry.cells.Add(currentCell); // BUG_78: updating primary key in entry if (currentCell.valueType == DB.ValueType.PrimaryKey) { newEntry.primaryKey = currentCell.value; } cellIndex++; } // Adding entry topic.Entries.Add(newEntry); // Updating index DB.Cell pkCell = GetCellFromEntry(topic, newEntry, DatabaseConstants.REF_DB_COLUMN); if (pkCell.value != null) { newEntry.primaryKey = pkCell.value; topic._UpdateEntryCache(pkCell.value, newEntry, false); } } else { Log.Error("Value to insert is not compatible with target table.", null); } } }
/// <summary> /// Full insert (technical, fast). Entry must not exists already ! /// No SQL equivalent. /// </summary> /// <param name="topic">Database topic</param> /// <param name="entry">Entry to add</param> public static void InsertAllCellsIntoTopic(DB topic, DB.Entry entry) { if (topic != null && entry.cells.Count == topic.Structure.Count) { topic.Entries.Add(entry); _UpdateAllCellEntryIds(entry); _UpdatePKCache(topic, entry); } else { Log.Error("Value to insert is not compatible with target table.", null); } }
/// <summary> /// Retrieves a cell with given name in specified entry /// </summary> /// <param name="topic">Table providing data</param> /// <param name="entry">Entry to parse</param> /// <param name="colName">Column name of searched cell</param> /// <returns></returns> public static DB.Cell GetCellFromEntry(DB topic, DB.Entry entry, string colName) { DB.Cell result = new DB.Cell(); // Using index if (colName != null && topic.ColumnIndexByName.ContainsKey(colName)) { int columnIndex = topic.ColumnIndexByName[colName]; result = entry.cells[columnIndex]; } return(result); }
/// <summary> /// Full update. /// No SQL equivalent known. Replaces specified entry with provided value. Cell values must be separated by tab /// </summary> /// <param name="topic">Database topic</param> /// <param name="pkValue">Value identifying line to update; REF column, typically</param> /// <param name="value">New value</param> public static void UpdateAllCellsFromTopicWherePrimaryKey(DB topic, string pkValue, string value) { if (pkValue == null || value == null) { return; } DB.Entry currentEntry = topic.EntriesByPrimaryKey[pkValue]; DB.Entry newEntry = _UpdateFullEntryWithValue(currentEntry, value); if (currentEntry.cells != null && newEntry.cells != null) { topic.Entries[currentEntry.index] = newEntry; topic._UpdateEntryCache(pkValue, newEntry, false); } }
/// <summary> /// Basic update (technical-fast) /// No SQL equivalent. /// </summary> /// <param name="topic">Database topic</param> /// <param name="colName">Column name</param> /// <param name="newValue">New value to write into database</param> /// <param name="entryId">Technical id of entry to modify</param> public static void UpdateCellFromTopicWithEntryId(DB topic, string colName, string newValue, int entryId) { if (colName == null || newValue == null || entryId < 0 || entryId >= topic.EntryCount) { return; } // Getting entry DB.Entry currentEntry = topic.Entries[entryId]; // Getting cell... DB.Cell cell = GetCellFromEntry(topic, currentEntry, colName); // Update _UpdateCell(topic, cell, newValue); }
/// <summary> /// Updates spot vehicle list according to current spot /// </summary> private void _RefreshDealerVehicleList() { if (!string.IsNullOrEmpty(_CurrentAvailabilitySpot)) { spotVehiclesListView.Items.Clear(); // Getting spot reference if (_CurrentAvailabilitySpot.Contains(Tools.SYMBOL_VALUE_SEPARATOR.ToString())) { _CurrentAvailabilitySpot = _CurrentAvailabilitySpot.Split(Tools.SYMBOL_VALUE_SEPARATOR)[1]; } // Vehicles from this spot DB.Entry allVehicles = DatabaseHelper.SelectAllCellsFromTopicWherePrimaryKey(_CarShopsTable, _CurrentAvailabilitySpot)[0]; for (int col = 3; col < 18; col++) { int slotIndex = col - 2; ListViewItem li = new ListViewItem(slotIndex.ToString()); string vehicleRef = allVehicles.cells[col].value; string vehicleName; // Compact 1 == free slot if (DatabaseConstants.COMPACT1_PHYSICS_DB_RESID.Equals(vehicleRef)) { vehicleName = _FREE_SLOT_NAME; } else { vehicleName = NamesHelper.GetVehicleFullName(allVehicles.cells[col].value, true, _PhysicsTable, _PhysicsResource, _BrandsTable, _BrandsResource); } // Current vehicle line is in bold li.Font = (vehicleRef.Equals(_CurrentVehicle) ? new Font(spotVehiclesListView.Font, FontStyle.Bold) : new Font(spotVehiclesListView.Font, FontStyle.Regular)); li.Tag = vehicleRef; li.SubItems.Add(vehicleName); spotVehiclesListView.Items.Add(li); } } }
/// <summary> /// Deletion. /// SQL equivalent: DELETE FROM [topic] WHERE [first column]=[id]; /// </summary> /// <param name="topic">Database topic</param> /// <param name="id">Id of lines to delete (value of first column)</param> public static void DeleteFromTopicWhereIdentifier(DB topic, string id) { if (string.IsNullOrEmpty(id)) { return; } // Browsing all entries int deletedCount = 0; int entryIndex = 0; while (entryIndex < topic.Entries.Count) { DB.Entry anotherEntry = topic.Entries[entryIndex]; DB.Cell firstCell = anotherEntry.cells[0]; if (id.Equals(firstCell.value)) { topic.Entries.Remove(anotherEntry); if (anotherEntry.primaryKey != null) { topic.EntriesByPrimaryKey.Remove(anotherEntry.primaryKey); } deletedCount++; } else { if (deletedCount > 0) { anotherEntry.index -= deletedCount; // BUG_95: update entry id in all cells anotherEntry = _UpdateAllCellEntryIds(anotherEntry); // _UpdatePKCache(topic, anotherEntry); topic.Entries[anotherEntry.index] = anotherEntry; } entryIndex++; } } }
/// <summary> /// Utility method to directly update specified cell with newValue /// </summary> /// <param name="topic"></param> /// <param name="cell"></param> /// <param name="newValue"></param> private static void _UpdateCell(DB topic, DB.Cell cell, string newValue) { if (topic != null && newValue != null) { if (cell.valueType == DB.ValueType.Undefined) { throw new Exception("Unable to access to specified location."); } cell.value = newValue; // Getting entry DB.Entry modifiedEntry = topic.Entries[cell.entryIndex]; // Setting cell in entry modifiedEntry.cells[cell.index] = cell; // Setting entry in topic topic.Entries[modifiedEntry.index] = modifiedEntry; } }
private void interiorColorsRemoveSetButton_Click(object sender, EventArgs e) { // Click on 'Remove' button try { if (_RemoveInteriorSet()) { // Reloading DB.Entry setEntry = DatabaseHelper.SelectAllCellsFromTopicWherePrimaryKey(_InteriorTable, SharedConstants.NO_COLOR_INTERIOR_DB_VAL)[0]; _UpdateSetList(setEntry); } } catch (Exception ex) { MessageBoxes.ShowError(this, ex); } finally { Cursor = Cursors.Default; } }
private void interiorColorsAddSetButton_Click(object sender, EventArgs e) { // Click on Add button try { if (_AddInteriorSet()) { // Reloading DB.Entry setEntry = DatabaseHelper.SelectAllCellsFromTopicWherePrimaryKey(_InteriorTable, _InteriorSetId)[0]; _UpdateSetList(setEntry); } } catch (Exception ex) { MessageBoxes.ShowError(this, ex); } finally { Cursor = Cursors.Default; } }
/// <summary> /// Checks for bugs in entry structure /// </summary> /// <param name="topic"></param> /// <param name="entry"></param> /// <param name="issues"></param> private static void _CheckStructure(DB topic, DB.Entry entry, Collection <DatabaseFixer.Corruption> issues) { if (topic != null) { // Cell count if (topic.Structure.Count != entry.cells.Count) { DatabaseFixer.Corruption newCorruption = new DatabaseFixer.Corruption { culture = DB.Culture.Global, entryId = entry.index, kind = DatabaseFixer.CorruptionKind.StructureMissingColumns, referencedTopic = DB.Topic.None, topic = topic.CurrentTopic, comment = "Missing columns: " + (topic.Structure.Count - entry.cells.Count) }; issues.Add(newCorruption); } } }
/// <summary> /// Technical request (fast) /// No SQL equivalent known. /// </summary> /// <param name="colName"></param> /// <param name="topic"></param> /// <param name="entryIds"></param> /// <returns></returns> public static List <DB.Cell> SelectCellsFromTopicWithEntryId(string colName, DB topic, params int[] entryIds) { List <DB.Cell> returnedCells = new List <DB.Cell>(); if (colName != null && topic != null && entryIds != null) { foreach (int anotherId in entryIds) { if (anotherId >= 0 && anotherId < topic.EntryCount) { // Getting entry DB.Entry currentEntry = topic.Entries[anotherId]; // Getting cell... DB.Cell currentCell = GetCellFromEntry(topic, currentEntry, colName); returnedCells.Add(currentCell); } } } return(returnedCells); }
/// <summary> /// Technical request (fast) to get full entries /// No SQL equivalent known. /// </summary> /// <param name="topic">Database topic</param> /// <param name="entryIds"></param> public static List <DB.Entry> SelectAllCellsFromTopicWhereId(DB topic, params int[] entryIds) { List <DB.Entry> result = new List <DB.Entry>(); if (topic != null && entryIds != null) { // Searching for specified id values foreach (int anotherId in entryIds) { DB.Entry resultEntry = new DB.Entry(); if (anotherId < topic.Entries.Count) { resultEntry = topic.Entries[anotherId]; } result.Add(resultEntry); } } return(result); }
/// <summary> /// Updates interior color set list /// </summary> /// <param name="currentSetEntry"></param> private void _UpdateSetList(DB.Entry currentSetEntry) { interiorColorSetsComboBox.Items.Clear(); // Getting all sets List <DB.Entry> allEntries = DatabaseHelper.SelectAllCellsFromTopic(_InteriorTable); string selectedItem = null; foreach (DB.Entry anotherEntry in allEntries) { string entryRef = DatabaseHelper.GetCellFromEntry(_InteriorTable, anotherEntry, DatabaseConstants.REF_DB_COLUMN).value; DB.Cell nameRefCell = DatabaseHelper.GetCellFromEntry(_InteriorTable, anotherEntry, SharedConstants.INTERIOR_NAME_INTERIOR_DB_COLUMN); string setName = DatabaseHelper.GetResourceValueFromCell(nameRefCell, _InteriorResource); DB.Cell manufacturerCell = DatabaseHelper.GetCellFromEntry(_InteriorTable, anotherEntry, SharedConstants.MANUFACTURER_ID_INTERIOR_DB_COLUMN); string manufacturerName = DatabaseHelper.GetResourceValueFromCell(manufacturerCell, _BrandsResource); string itemText = string.Format(VehicleManagerForm._FORMAT_COLOR_INT_SET_ITEM, setName, manufacturerName, entryRef); interiorColorSetsComboBox.Items.Add(itemText); if (currentSetEntry.primaryKey.Equals(entryRef)) { selectedItem = itemText; } } // Current set is selected if (selectedItem != null) { interiorColorSetsComboBox.SelectedItem = selectedItem; } }
/// <summary> /// Basic request from primary key (quick) /// SQL equivalent: SELECT [colName] FROM [topic] WHERE (primary key) IN ([pkValues]); /// </summary> /// <param name="colName">Column name</param> /// <param name="topic">Database topic</param> /// <param name="pkValues">Array of primary key values to search</param> public static List <DB.Cell> SelectCellsFromTopicWherePrimaryKey(string colName, DB topic, params string[] pkValues) { List <DB.Cell> result = new List <DB.Cell>(); if (colName != null && pkValues != null) { // Searching for specified primary key values foreach (string anotherPk in pkValues) { if (topic.EntriesByPrimaryKey.ContainsKey(anotherPk)) { DB.Entry currentEntry = topic.EntriesByPrimaryKey[anotherPk]; // Searching for value in current entry DB.Cell resultCell = GetCellFromEntry(topic, currentEntry, colName); result.Add(resultCell); } } } return(result); }
/// <summary> /// Ensures entry ids in child cells are correctly set /// </summary> /// <param name="anotherEntry"></param> /// <returns></returns> private static DB.Entry _UpdateAllCellEntryIds(DB.Entry anotherEntry) { List <DB.Cell> allCells = anotherEntry.cells; int updatedCount = 0; for (int cellIndex = 0; cellIndex < allCells.Count; cellIndex++) { DB.Cell currentCell = allCells[cellIndex]; if (currentCell.entryIndex != anotherEntry.index) { currentCell.entryIndex = anotherEntry.index; allCells[cellIndex] = currentCell; updatedCount++; } } if (updatedCount > 0) { anotherEntry.cells = allCells; } return(anotherEntry); }
/// <summary> /// Refreshes information about current interior set /// </summary> /// <param name="setRef"></param> private void _UpdateInteriorSetInformation(string setRef) { DB.Entry setEntry = DatabaseHelper.SelectAllCellsFromTopicWherePrimaryKey(_InteriorTable, setRef)[0]; // Name DB.Cell nameRefCell = DatabaseHelper.GetCellFromEntry(_InteriorTable, setEntry, SharedConstants.INTERIOR_NAME_INTERIOR_DB_COLUMN); _SetNameCode = nameRefCell.value; // Manufacturer DB.Cell manufacturerRefCell = DatabaseHelper.GetCellFromEntry(_InteriorTable, setEntry, SharedConstants.MANUFACTURER_ID_INTERIOR_DB_COLUMN); string manufacturerCode = DatabaseHelper.GetResourceValueFromCell(manufacturerRefCell, _BrandsResource); interiorManufacturerLinkLabel.Text = manufacturerCode; _BrandCode = manufacturerRefCell.value; // Price string setPrice = DatabaseHelper.GetCellFromEntry(_InteriorTable, setEntry, SharedConstants.PRICE_DOLLAR_INTERIOR_DB_COLUMN).value; interiorPriceTextBox.Text = setPrice; // Color 1 DB.Cell mainColorRefCell = DatabaseHelper.GetCellFromEntry(_InteriorTable, setEntry, SharedConstants.INTERIOR_COLOR_1_INTERIOR_DB_COLUMN); string colorCode = DatabaseHelper.GetResourceValueFromCell(mainColorRefCell, _InteriorResource); colorsMainLinkLabel.Text = _GetColorLabel(colorCode); _Color1Code = mainColorRefCell.value; // Color 2 DB.Cell secColorRefCell = DatabaseHelper.GetCellFromEntry(_InteriorTable, setEntry, SharedConstants.INTERIOR_COLOR_2_INTERIOR_DB_COLUMN); colorCode = DatabaseHelper.GetResourceValueFromCell(secColorRefCell, _InteriorResource); colorsSecondaryLinkLabel.Text = _GetColorLabel(colorCode); _Color2Code = secColorRefCell.value; // Material DB.Cell materialRefCell = DatabaseHelper.GetCellFromEntry(_InteriorTable, setEntry, SharedConstants.MATERIAL_INTERIOR_DB_COLUMN); string materialCode = DatabaseHelper.GetResourceValueFromCell(materialRefCell, _InteriorResource); materialLinkLabel.Text = _GetColorLabel(materialCode); _MaterialCode = materialRefCell.value; // If 'None' set is selected, all controls are locked bool isToBeEnabled = !(SharedConstants.NO_COLOR_INTERIOR_DB_VAL.Equals(setRef)); interiorColorsRemoveSetButton.Enabled = interiorManufacturerLinkLabel.Enabled = interiorPriceTextBox.Enabled = colorsMainLinkLabel.Enabled = colorsSecondaryLinkLabel.Enabled = materialLinkLabel.Enabled = isToBeEnabled; }
/// <summary> /// Fixes specified corruption /// </summary> /// <param name="corruptionEntry"></param> public static void Fix(Corruption corruptionEntry) { // Has topic been loaded yet ? if (_Data.ContainsKey(corruptionEntry.topic)) { // Data access TduFile[] files = _Data[corruptionEntry.topic]; DB db = files[0] as DB; DBResource res = files[1] as DBResource; TduFile[] refFiles = _Data[corruptionEntry.referencedTopic]; DB refDb = refFiles[0] as DB; DBResource refRes = refFiles[1] as DBResource; TduFile[] backupFiles = _BackupData[corruptionEntry.topic]; DB backupDb = backupFiles[0] as DB; DBResource backupRes = backupFiles[1] as DBResource; TduFile[] backupRefFiles = _BackupData[corruptionEntry.referencedTopic]; DB backupRefDb = backupRefFiles[0] as DB; DBResource backupRefRes = backupRefFiles[1] as DBResource; // Integrity checks if (db == null || res == null || refDb == null || refRes == null) { throw new Exception("Database loading error."); } if (backupDb == null || backupRes == null || backupRefDb == null || backupRefRes == null) { throw new Exception("Database backup loading error."); } string colName = corruptionEntry.corruptedCell.name; // According to corruption kind switch (corruptionEntry.kind) { case CorruptionKind.UnknownReferencedTopic: throw new Exception("UnknownReferencedTopic issue can't be solved yet."); case CorruptionKind.StructureMissingColumns: throw new Exception("StructureMissingColumns issue can't be solved yet."); case CorruptionKind.MissingReference: // If referenced entry does not exist in backup, restore referenced id from backup // else restore entry string referencedEntryPk = corruptionEntry.corruptedValue; List <DB.Entry> entries = DatabaseHelper.SelectAllCellsFromTopicWherePrimaryKey(backupRefDb, new[] { referencedEntryPk }); if (entries.Count == 0) { DB.Entry currentEntry = DatabaseHelper.SelectAllCellsFromTopicWhereId(db, corruptionEntry.entryId)[0]; string entryPk = currentEntry.primaryKey; List <DB.Cell> backupCells = DatabaseHelper.SelectCellsFromTopicWherePrimaryKey(colName, backupDb, new[] { entryPk }); if (backupCells.Count == 0) { // Worst case : referenced item not found in backup > must restore original reference DB.Cell cleanCell = DatabaseHelper.SelectCellsFromTopicWithEntryId(colName, backupDb, new[] { corruptionEntry.entryId })[0]; DatabaseHelper.UpdateCellFromTopicWithEntryId(db, colName, cleanCell.value, corruptionEntry.entryId); Log.Info("Fixed issue : " + corruptionEntry.kind + " by setting new reference: " + cleanCell.value + " in " + colName + ", line " + corruptionEntry.entryId); } else { DatabaseHelper.UpdateCellFromTopicWherePrimaryKey(db, colName, entryPk, backupCells[0].value); Log.Info("Fixed issue : " + corruptionEntry.kind + " by setting new reference: " + backupCells[0].value + " in " + colName + ", line " + corruptionEntry.entryId); } db.Save(); } else { DatabaseHelper.InsertAllCellsIntoTopic(refDb, entries[0]); refDb.Save(); Log.Info("Fixed issue : " + corruptionEntry.kind + " by creating new line."); } break; case CorruptionKind.MissingResource: // If resource exists in backup, restore resource id // else restore referenced resource id from backup DBResource backupResource; DBResource resource; if (corruptionEntry.topic == corruptionEntry.referencedTopic) { // Resource is in the same topic backupResource = backupRes; resource = res; } else { // Resource is in another topic backupResource = backupRefRes; resource = refRes; } DBResource.Entry backupResEntry = backupResource.GetEntryFromId(corruptionEntry.corruptedValue); if (backupResEntry.isValid) { resource.InsertEntry(backupResEntry); resource.Save(); Log.Info("Fixed issue : " + corruptionEntry.kind + " by creating new resource: " + backupResEntry.value + " in " + resource.CurrentTopic + ", id=" + backupResEntry.id); } else { DB.Cell backupCell = DatabaseHelper.SelectCellsFromTopicWithEntryId(colName, backupDb, corruptionEntry.entryId)[0]; // Trying to get resource from backup backupResEntry = backupResource.GetEntryFromId(backupCell.value); if (backupResEntry.isValid) { DatabaseHelper.UpdateCellFromTopicWithEntryId(db, colName, backupCell.value, corruptionEntry.entryId); db.Save(); Log.Info("Fixed issue : " + corruptionEntry.kind + " by setting new reference to resource: " + backupCell.value + " in " + colName + ", line " + corruptionEntry.entryId); } else { // Applying default resource value backupResEntry.id = new ResourceIdentifier(backupCell.value, backupResource.CurrentTopic); backupResEntry.isValid = true; backupResEntry.value = _DEFAULT_RESOURCE_VALUE; backupResEntry.index = resource.EntryList.Count; resource.InsertEntry(backupResEntry); resource.Save(); Log.Info("Fixed issue : " + corruptionEntry.kind + " by creating new resource: " + backupResEntry.value + " in " + resource.CurrentTopic + ", id=" + backupResEntry.id); } } break; } } else { throw new Exception("Please load corresponding data and resource first!"); } }