DatabaseUpdateScript.cs 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. using System.Linq.Expressions;
  2. using InABox.Core;
  3. namespace InABox.Database;
  4. public abstract class DatabaseUpdateScript
  5. {
  6. public abstract VersionNumber Version { get; }
  7. public abstract bool Update();
  8. protected struct Map<T>
  9. {
  10. public String Old;
  11. public Expression<Func<T, object>> New;
  12. public Map(String oldcolumn, Expression<Func<T, object>> newcolumn)
  13. {
  14. Old = oldcolumn;
  15. New = newcolumn;
  16. }
  17. }
  18. protected void Convert<T>(
  19. Filter<T> filter,
  20. params Map<T>[] maps
  21. ) where T : Entity, IPersistent, IRemotable, new()
  22. {
  23. Logger.Send(LogType.Information, "", $"Converting {typeof(T).EntityName().Split('.').Last()}...");
  24. List<T> updates = new List<T>();
  25. var columns = new Columns<T>(x => x.ID);
  26. foreach (var map in maps)
  27. {
  28. if (!columns.Items.Any(x=>String.Equals(x.Property,map.Old)))
  29. columns.Add(map.Old);
  30. if (!columns.Items.Any(x=>String.Equals(x.Property,CoreUtils.GetFullPropertyName<T, object>(map.New, "."))))
  31. columns.Add(map.New);
  32. }
  33. CoreTable table = DbFactory.Provider.Query<T>(filter,columns);
  34. int iCount = 0;
  35. foreach (var row in table.Rows)
  36. {
  37. var update = row.ToObject<T>();
  38. foreach (var map in maps)
  39. CoreUtils.SetPropertyValue(update, CoreUtils.GetFullPropertyName<T, object>(map.New, "."), CoreUtils.GetPropertyValue(update, map.Old));
  40. if (update.IsChanged())
  41. updates.Add(update);
  42. if (updates.Count == 100)
  43. {
  44. iCount += updates.Count;
  45. Logger.Send(LogType.Information, "", $"Converting {typeof(T).EntityName().Split('.').Last()} Times ({iCount}/{table.Rows.Count}");
  46. DbFactory.Provider.Save(updates);
  47. updates.Clear();
  48. }
  49. }
  50. if (updates.Count > 0)
  51. {
  52. iCount += updates.Count;
  53. Logger.Send(LogType.Information, "", $"Converting {typeof(T).EntityName().Split('.').Last()} Times ({iCount}/{table.Rows.Count})");
  54. DbFactory.Provider.Save(updates);
  55. updates.Clear();
  56. }
  57. }
  58. }