protected internal void Backup(IRepository backupRepository) { BackupRepository = backupRepository; DaoTypes.Each(t => { // TODO: fix this so that it doesn't use LoadAll, if there are too many records we'll run out of memory IEnumerable daos = t.InvokeStatic <IEnumerable>("LoadAll", DatabaseToBackup); foreach (object o in daos) { SaveToBackupRepository((Dao)o); } }); }
private HashSet <OldToNewIdMapping> RestoreData(Database restoreTo, ILogger logger) { HashSet <OldToNewIdMapping> result = new HashSet <OldToNewIdMapping>(); DatabaseToRestoreTo = restoreTo; DatabaseToRestoreTo.TryEnsureSchema(DaoTypes.First(), logger); Dictionary <string, Dao> tempForeignKeyTargets = InsertTempForeignKeyTargets(); // for all the poco types load them all from the repo foreach (Type pocoType in BackupRepository.StorableTypes) { // copy the poco as a dao and save it into the restoreTo IEnumerable <object> all = BackupRepository.RetrieveAll(pocoType); Type daoType = DaoTypes.FirstOrDefault(t => t.Name.Equals(pocoType.Name)); Args.ThrowIf <InvalidOperationException>(daoType == null, "The Dto of type {0} didn't have a corresponding Dao type", pocoType.Name); foreach (object poco in all) { string uuid = Meta.GetUuid(poco, true); Dao dao = (Dao)poco.CopyAs(daoType); dao.IdValue = null; dao.DataRow = null; dao.ForceInsert = true; dao.UniqueFilterProvider = () => { return(Query.Where("Uuid") == uuid); }; ForceUpdateIfExistsInTarget(uuid, dao); SetTemporaryForeignKeys(dao, tempForeignKeyTargets); dao.Save(DatabaseToRestoreTo); OldToNewIdMapping idMapping = new OldToNewIdMapping { PocoType = pocoType, DaoType = daoType, OldId = (long)poco.Property("Id"), NewId = (long)dao.IdValue, Uuid = uuid }; result.Add(idMapping); } } return(result); }
protected internal void CorrectForeignKeys(HashSet <OldToNewIdMapping> oldToNewIdMappings, Database source, Database destination) { Dictionary <string, OldToNewIdMapping> byUuid = oldToNewIdMappings.ToDictionary(otn => otn.Uuid); IParameterBuilder oldParameterBuilder = source.GetService <IParameterBuilder>(); SqlStringBuilder committer = destination.GetService <SqlStringBuilder>(); List <Type> tableTypes = DaoAssembly.GetTypes().Where(type => type.HasCustomAttributeOfType <TableAttribute>()).ToList(); List <PropertyInfo> foreignKeyProperties = new List <PropertyInfo>(); foreach (Type type in tableTypes) { foreignKeyProperties.AddRange(type.GetProperties().Where(prop => prop.HasCustomAttributeOfType <ForeignKeyAttribute>()).ToList()); } // for every foreign key foreach (PropertyInfo prop in foreignKeyProperties) { ForeignKeyAttribute fk = prop.GetCustomAttributeOfType <ForeignKeyAttribute>(); // get the old Dao instances that represents the referenced table Type referencedDaoType = DaoTypes.First(t => { TableAttribute table; t.HasCustomAttributeOfType <TableAttribute>(out table); return(table.TableName.Equals(fk.ReferencedTable)); }); SqlStringBuilder oldSelector = source.GetService <SqlStringBuilder>(); oldSelector.Select(fk.ReferencedTable); List <object> oldReferencedDaos = source.GetDataTable(oldSelector, CommandType.Text, oldParameterBuilder.GetParameters(oldSelector)).ToListOf(referencedDaoType); foreach (object oldReferenced in oldReferencedDaos) { Dao oldReferencedDao = (Dao)oldReferenced; // get the old Dao instances that represent the referencing table where the referencing column value = the old table id Type referencingDaoType = DaoTypes.First(t => { TableAttribute table; t.HasCustomAttributeOfType <TableAttribute>(out table); return(table.TableName.Equals(fk.Table)); }); SqlStringBuilder oldReferencerSelector = source.GetService <SqlStringBuilder>(); oldReferencerSelector.Select(fk.Table).Where(new AssignValue(fk.Name, oldReferencedDao.IdValue)); List <object> oldReferencingDaoInstances = source.GetDataTable(oldReferencerSelector, CommandType.Text, oldParameterBuilder.GetParameters(oldReferencerSelector)).ToListOf(referencingDaoType); if (oldReferencingDaoInstances.Count > 0) { List <string> oldReferencingDaoInstanceUuids = oldReferencingDaoInstances.Select(o => o.Property <string>("Uuid")).ToList(); long oldReferencedId = oldReferencedDao.IdValue.Value; // get the new referenced id long whatItShouldBeNow = byUuid[oldReferencedDao.Property <string>("Uuid")].NewId; // update the new referencing column to match the newId in the destination where the uuids in oldDaoInstances committer.Update(fk.Table, new AssignValue(fk.Name, whatItShouldBeNow)).Where(Query.Where("Uuid").In(oldReferencingDaoInstanceUuids.ToArray())); committer.Go(); } } } destination.ExecuteSql(committer, oldParameterBuilder); }