Anonymous avatar Anonymous committed 9715796

finishing

Comments (0)

Files changed (2)

Usually/Resolve.cs

         private List<IResolverItem> items = new List<IResolverItem>();
         private IMetaInfo<T> info = null;
         private string group = null;
-        private Func<T, object[]> getRef = null;
         private IEnumerable<T> olds = null;
         private IEnumerable<T> news = null;
         private Dictionary<object[], List<TransactionJournal<T>>> _journals = null;
         protected Dictionary<object[], List<TransactionJournal<T>>> CreateJournals()
         {
-            var r = new Dictionary<object[], List<TransactionJournal<T>>>();
+            var r = new Dictionary<object[], List<TransactionJournal<T>>>(JonSkeet.ArrayEqualityComparer<object>.Default);
             var reconciler = new Reconciler<T>(this.info, this.olds, this.news);
             foreach (var j in reconciler.ReconcileNonDelete())
             {
-                var k = this.getRef(j.New);
+                var k = this.info.GetMasterRef(j.New);
                 List<TransactionJournal<T>> list = null;
                 if (! r.TryGetValue(k, out list)) 
                 {
             }
             foreach (var j in reconciler.ReconcileDelete())
             {
-                var k = this.getRef(j.Old);
+                var k = this.info.GetMasterRef(j.Old);
                 List<TransactionJournal<T>> list = null;
                 if (! r.TryGetValue(k, out list)) 
                 {
             Dictionary<string, object> dict = null;
             if (t is InsertRecord) dict = (t as InsertRecord).Values;
             if (t is UpdateRecord) dict = (t as InsertRecord).Values;
+            if (dict == null) throw new Exception("Unexpect type: " + t.GetType().Name);
             this.info.SetActualMasterKey(dict, actualKey);
         }
         IEnumerable<TransactionRecord> IResolverItem.ResolveForMasterInsert(object[] refKey, object[] actualKey)

UsuallyTests/TestResolve.cs

             m.Value("STATUS", (x) => x.Status);
         }
     }
-
     [Serializable]
     public class OrderLine
     {
             m.Value("UNIT", (x) => x.Unit);
         }
     }
-
     [Serializable]
     public class Shipment
     {
         }
     }
 
-    class TestResolve
+    public class TestResolve
     {
         private List<OrderLine> olds = null;
         private List<OrderLine> news = null;
         {
             this.Twist(this.news);
             Assert.AreEqual(8, this.news.Count);
-            var changes = Resolver.Resolve(OrderLine.Meta, olds, news);
-            Assert.AreEqual(8, changes.Count());
+            var changes = Resolver.Resolve(OrderLine.Meta, olds, news).ToArray();
+            Assert.AreEqual(8, changes.Length);
             var e = changes.GetEnumerator();
             Assert.True(e.MoveNext());
             Assert.IsInstanceOf(typeof(InsertRecord), e.Current);
             }
             Assert.False(e.MoveNext());
         }
+        public static Func<string, object> CreateGenerator()
+        {
+            var nextIds = new Dictionary<string, int>();
+            return (n) =>
+            {
+                int i = 0;
+                if (!nextIds.TryGetValue(n, out i))
+                {
+                    nextIds[n] = i = (n.Length * 100000) + 1;
+                }
+                nextIds[n] = i + 1;
+                return i;
+            };
+        }
         [Test]
         public void TestResolveWithGenerator()
         {
-            var nextIds = new Dictionary<string, int>();
-            var r = new Resolver((n) => 
-            {
-                int i = 0;
-                if (!nextIds.TryGetValue(n, out i)) 
-                {
-                    nextIds[n] = i = 1000001;
-                }
-                nextIds[n] = i + 1;
-                return i;
-            });
+            var r = new Resolver(TestResolve.CreateGenerator());
             r.Add(OrderLine.Meta, this.olds, this.news);
             this.Twist(this.news);
             Assert.AreEqual(8, this.news.Count);
                 var t = e.Current as InsertRecord;
                 Assert.AreEqual("ORDER_LINES", t.TableName);
                 Assert.AreEqual(7, t.Values.Count);
-                Assert.AreEqual(1000001, t.Values["LINE_ID"]);
+                Assert.AreEqual(1500001, t.Values["LINE_ID"]);
                 Assert.AreEqual(900, t.Values["LINE_UNIQUE_ID"]);
                 Assert.AreEqual(101, t.Values["ORDER_ID"]);
                 Assert.AreEqual(8008, t.Values["ITEM_ID"]);
                 Assert.AreEqual("ORDER_LINES", t.TableName);
                 Assert.AreEqual(7, t.Values.Count);
                 Assert.AreEqual(9, t.Values["LINE_ID"]);
-                Assert.AreEqual(1000001, t.Values["LINE_UNIQUE_ID"]);
+                Assert.AreEqual(1900001, t.Values["LINE_UNIQUE_ID"]);
                 Assert.AreEqual(101, t.Values["ORDER_ID"]);
                 Assert.AreEqual(9009, t.Values["ITEM_ID"]);
                 Assert.AreEqual("Nine Thousand Nine", t.Values["ITEM_NAME"]);
             var line = order.Add(OrderLine.Meta, lines, lines);
         }
     }
+
+    public class TestMultiLevelResolve
+    {
+        private List<Order> oldOrders = null;
+        private List<OrderLine> oldLines = null;
+        private List<Shipment> oldShips = null;
+        private List<Order> newOrders = null;
+        private List<OrderLine> newLines = null;
+        private List<Shipment> newShips = null;
+        private void ForMaster<M>(List<M> list, M master, Action<M> act)
+        {
+            list.Add(master);
+            act(master);
+        }
+        [SetUp]
+        public void SetUp()
+        {
+            this.oldOrders = new List<Order>();
+            this.oldLines = new List<OrderLine>();
+            this.oldShips = new List<Shipment>();
+            this.ForMaster(this.oldOrders,
+                new Order { OrderId = 1, OrderNumber = "N-001", OrderDate = new DateTime(2012, 2, 14), Status = "FINISHED", CustomerId = 1 },
+                (o) => 
+                {
+                    this.ForMaster(this.oldLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = 101, UniqueId = 1101, ItemId = 900001, ItemName = "One", Quantity = 10, Unit = "U1" },
+                        (ln) => 
+                        {
+                            this.oldShips.AddRange(new Shipment[] 
+                            {
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10101, Quantity = 2, ShipDate = new DateTime(2012, 2, 16) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10102, Quantity = 4, ShipDate = new DateTime(2012, 2, 18) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10103, Quantity = 3, ShipDate = new DateTime(2012, 2, 17) }
+                            });
+                        }
+                    );
+                    this.ForMaster(this.oldLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = 102, UniqueId = 1102, ItemId = 900002, ItemName = "Two", Quantity = 2, Unit = "U2" },
+                        (ln) =>
+                        {
+                            this.oldShips.AddRange(new Shipment[] 
+                            {
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10201, Quantity = 1, ShipDate = new DateTime(2012, 2, 26) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10202, Quantity = 1, ShipDate = new DateTime(2012, 2, 28) }
+                            });
+                        }
+                    );
+                    this.ForMaster(this.oldLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = 103, UniqueId = 1103, ItemId = 900003, ItemName = "Three", Quantity = 2, Unit = "U3" },
+                        (ln) =>
+                        {
+                            this.oldShips.AddRange(new Shipment[] 
+                            {
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10301, Quantity = 1, ShipDate = new DateTime(2012, 2, 26) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10302, Quantity = 1, ShipDate = new DateTime(2012, 2, 28) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10303, Quantity = 1, ShipDate = new DateTime(2012, 2, 28) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 10304, Quantity = 1, ShipDate = new DateTime(2012, 2, 28) }
+                            });
+                        }
+                    );
+                }
+            );
+            this.ForMaster(this.oldOrders,
+                new Order { OrderId = 2, OrderNumber = "N-002", OrderDate = new DateTime(2012, 2, 19), Status = "ACTIVE", CustomerId = 2 },
+                (o) =>
+                {
+                    this.ForMaster(this.oldLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = 201, UniqueId = 2201, ItemId = 900001, ItemName = "One", Quantity = 1, Unit = "U1" },
+                        (ln) =>
+                        {
+                            this.oldShips.AddRange(new Shipment[] 
+                            {
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 20101, Quantity = 1, ShipDate = new DateTime(2012, 2, 23) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 20102, Quantity = 1, ShipDate = new DateTime(2012, 2, 24) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 20103, Quantity = 1, ShipDate = new DateTime(2012, 2, 25) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 20104, Quantity = 1, ShipDate = new DateTime(2012, 2, 26) }
+                            });
+                        }
+                    );
+                    this.ForMaster(this.oldLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = 202, UniqueId = 2202, ItemId = 900002, ItemName = "Two", Quantity = 2, Unit = "U2" },
+                        (ln) =>
+                        {
+                            this.oldShips.AddRange(new Shipment[] 
+                            {
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 20201, Quantity = 1, ShipDate = new DateTime(2012, 3, 5) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = 20202, Quantity = 1, ShipDate = new DateTime(2012, 3, 6) },
+                            });
+                        }
+                    );
+                }
+            );
+            this.ForMaster(this.oldOrders,
+                new Order { OrderId = 3, OrderNumber = "N-003", OrderDate = new DateTime(2012, 3, 2), Status = "INCOMPLETED", CustomerId = 3 },
+                (o) => 
+                {
+                    this.ForMaster(this.oldLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = 301, UniqueId = 3301, ItemId = 900001, ItemName = "One", Quantity = 1, Unit = "U1" },
+                        (ln) => 
+                        {
+                        }
+                    );
+                }
+            );
+            this.newOrders = Use.SerializeClone(this.oldOrders);
+            this.newLines = Use.SerializeClone(this.oldLines);
+            this.newShips = Use.SerializeClone(this.oldShips);
+        }
+        private Resolver CreateResolver()
+        {
+            var r = new Resolver(TestResolve.CreateGenerator());
+            r.Add(Order.Meta, this.oldOrders, this.newOrders
+            ).Add(OrderLine.Meta, this.oldLines, this.newLines
+            ).Add(Shipment.Meta, this.oldShips, this.newShips);
+            return r;
+        }
+        [Test]
+        public void TestNoChange()
+        {
+            var r = this.CreateResolver();
+            Assert.AreEqual(0, r.Resolve().Count());
+        }
+        [Test]
+        public void TestChange()
+        {
+            this.newShips.RemoveAll((x) => x.ShipmentId == 10201);   // 1 deleted
+            this.newShips.RemoveAll((x) => x.ShipmentId == 10303);   // 1 deleted
+            this.newShips.RemoveAll((x) => x.ShipmentId == 20102);   // 1 deleted
+            this.newLines.RemoveAll((x) => x.LineId == 202);         // 3 deleted
+            this.newOrders.RemoveAll((x) => x.OrderId == 3);         // 2 deleted
+            this.ForMaster(                                          // 9 inserted
+                this.newOrders,
+                new Order() { OrderId = -4, OrderNumber = "N-004", OrderDate = new DateTime(2012, 3, 5), Status = "ACTIVE", CustomerId = 4 },
+                (o) =>
+                {
+                    this.ForMaster(this.newLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = -401, UniqueId = -4401, ItemId = 900001, ItemName = "One", Quantity = 1, Unit = "U1" },
+                        (ln) =>
+                        {
+                            this.newShips.AddRange(new Shipment[] 
+                            {
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = -40101, Quantity = 1, ShipDate = new DateTime(2012, 3, 5) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = -40102, Quantity = 1, ShipDate = new DateTime(2012, 3, 5) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = -40103, Quantity = 1, ShipDate = new DateTime(2012, 3, 5) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = -40104, Quantity = 1, ShipDate = new DateTime(2012, 3, 5) }
+                            });
+                        }
+                    );
+                    this.ForMaster(this.newLines,
+                        new OrderLine { OrderId = o.OrderId, LineId = -402, UniqueId = -4402, ItemId = 900002, ItemName = "Two", Quantity = 2, Unit = "U2" },
+                        (ln) =>
+                        {
+                            this.newShips.AddRange(new Shipment[] 
+                            {
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = -40201, Quantity = 1, ShipDate = new DateTime(2012, 3, 5) },
+                                new Shipment() { OrderLineId = ln.LineId, ShipmentId = -40202, Quantity = 1, ShipDate = new DateTime(2012, 3, 5) },
+                            });
+                        }
+                    );
+                }
+            );
+            this.newLines.Single((o) => o.LineId == 102).OrderId = 3;                             // 2 deleted
+            this.newOrders.Single((o) => o.OrderId == 1).Status = "ARCHIVED";                     // 1 updated
+            foreach (var ln in (from ln in this.newLines where ln.OrderId == 2 select ln))        // 1 updated
+                ln.Quantity = 12345;
+            foreach (var sh in (from sh in this.newShips where sh.OrderLineId == 103 select sh))  // 3 updated
+                sh.Quantity = 54321;
+            var changes = this.CreateResolver().Resolve().ToArray();
+            Assert.AreEqual(24, changes.Length);
+            var e = changes.GetEnumerator();
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(UpdateRecord), e.Current);
+            {
+                var t = e.Current as UpdateRecord;
+            }
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.True(e.MoveNext());
+            Assert.False(e.MoveNext());
+        }
+    }
 }
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.