Anonymous avatar Anonymous committed 628eded

remove all IRefBuilder, IRefInfo. add test with generate

Comments (0)

Files changed (2)

Usually/Resolve.cs

     {
         void Key(string name, Func<T, object> getKey, Func<object, string> generator = null);
     }
-    public interface IMetaBuilder<T>: IKeyBuilder<T>
+    public interface IMetaBuilder<T> : IKeyBuilder<T>
     {
         void Table(string name);
+        void MasterExtaKey(string group);
+        void Ref(string name, Func<T, object> getRef);
         void Value(string name, Func<T, object> getValue);
         IKeyBuilder<T> ExtraKey(string group);
     }
-    public interface IRefBuilder<T>
-    {
-        void MasterExtaKey(string group);
-        void Ref(string name, Func<T, object> getRef);
-    }
     public interface IMetaInfo<T>
     {
         string TableName { get; }
         void ForEachExtraKey(string group, T obj, Action<string, object> action);
         void ForEachInsertValue(T obj, Action<string, object> action);
         void ForEachValueChange(T o, T n, Action<string, object, object> action);
-    }
-    public interface IRefInfo<T>
-    {
-        string Group { get; }
+        string MasterKeyGroup { get; }
         object[] GetMasterRef(T obj);
-        void SetActualMasterKey(object[] actualKey, Dictionary<string, object> dict);
+        void SetActualMasterKey(Dictionary<string, object> dict, object[] actualKey);
     }
     public static class MetaBuilderExtension
     {
                     values[i] = this.getters[this.names[i]](obj);
                 return values;
             }
+            public object GetFrom(T obj, string name)
+            {
+                return this.getters[name](obj);
+            }
             public object[] GetFrom(Dictionary<string, object> dict)
             {
                 var values = new object[this.names.Count];
         private KeysDef keys = new KeysDef();
         private Dictionary<string, KeysDef> extraKeys = new Dictionary<string, KeysDef>();
         private ValuesDef values = new ValuesDef();
+        private List<string> refList = new List<string>();
+        private string group = null;
         #endregion
 
         #region Implement IMetaBuilder<T>
             this.extraKeys.Add(group, r);
             return r;
         }
+        void IMetaBuilder<T>.Ref(string name, Func<T, object> getRef)
+        {
+            this.values.Add(name, getRef);
+            this.refList.Add(name);
+        }
         void IMetaBuilder<T>.Value(string name, Func<T, object> getValue)
         {
             this.values.Add(name, getValue);
         }
+        void IMetaBuilder<T>.MasterExtaKey(string group)
+        {
+            this.group = @group;
+        }
         #endregion
 
         #region Implement IMetaInfo<T>
         {
             this.values.ForEachChange(o, n, action);
         }
+        string IMetaInfo<T>.MasterKeyGroup { get { return this.group; } }
+        object[] IMetaInfo<T>.GetMasterRef(T obj)
+        {
+            if (this.refList.Count <= 0) return null;
+            var r = new object[this.refList.Count];
+            for (int i = 0; i < this.refList.Count; i++)
+            {
+                r[i] = this.values.GetFrom(obj, this.refList[i]);
+            }
+            return r;
+        }
+        void IMetaInfo<T>.SetActualMasterKey(Dictionary<string, object> dict, object[] actualKey)
+        {
+            if (this.refList.Count <= 0) return;
+            for (int i = 0; i < actualKey.Length; i++)
+                dict[this.refList[i]] = actualKey;
+        }
         #endregion
     }
     public delegate void Meta<T>(IMetaBuilder<T> m);
-    public class RefInfoBuilder<T> : IRefBuilder<T>, IRefInfo<T>
-    {
-        private string _group = null;
-        private List<string> names = new List<string>();
-        private Dictionary<string, Func<T, object>> getRefs = new Dictionary<string, Func<T, object>>();
-        void IRefBuilder<T>.MasterExtaKey(string group)
-        {
-            this._group = @group;
-        }
-        void IRefBuilder<T>.Ref(string name, Func<T,object> getRef)
-        {
-            this.getRefs.Add(name, getRef);
-            this.names.Add(name);
-        }
-        string IRefInfo<T>.Group { get { return this._group; } }
-        object[] IRefInfo<T>.GetMasterRef(T obj)
-        {
-            var r = new object[this.names.Count];
-            for (int i = 0; i < this.names.Count; i++)
-                r[i] = this.getRefs[this.names[i]](obj);
-            return r;
-        }
-        void IRefInfo<T>.SetActualMasterKey(object[] actualKey, Dictionary<string, object> dict)
-        {
-            for (int i = 0; i < this.names.Count; i++)
-                dict[this.names[i]] = actualKey[i];
-        }
-    }
-    public delegate void RefMeta<T>(IRefBuilder<T> r);
     class Reconciler<T>
     {
         private IMetaInfo<T> info = null;
         }
         public ResolverItem<T> Add<T>(Meta<T> meta, IEnumerable<T> olds, IEnumerable<T> news) 
         {
-            var r = new ResolverItem<T>(this, meta, null, olds, news);
+            var r = new ResolverItem<T>(this, meta, olds, news);
             this.items.Add(r);
             return r;
         }
         private Resolver host = null;
         private List<IResolverItem> items = new List<IResolverItem>();
         private IMetaInfo<T> info = null;
-        private IRefInfo<T> refInfo = null;
         private string group = null;
         private Func<T, object[]> getRef = null;
         private IEnumerable<T> olds = null;
             return r;
         }
         string IResolverItem.Group { get { return this.group; } }
-        public ResolverItem(Resolver host, Meta<T> meta, RefMeta<T> refMeta, IEnumerable<T> olds, IEnumerable<T> news)
+        public ResolverItem(Resolver host, Meta<T> meta, IEnumerable<T> olds, IEnumerable<T> news)
         {
             this.host = @host;
             var m = new MetaInfoBuilder<T>();
             meta(m);
             this.info = m;
-            if (refMeta != null)
-            {
-                var r = new RefInfoBuilder<T>();
-                refMeta(r);
-                this.refInfo = r;
-            }
             this.olds = @olds;
             this.news = @news;
         }
-        public ResolverItem<D> Add<D>(Meta<D> meta, RefMeta<D> refMeta, IEnumerable<D> olds, IEnumerable<D> news)
+        public ResolverItem<D> Add<D>(Meta<D> meta, IEnumerable<D> olds, IEnumerable<D> news)
         {
-            var i = new ResolverItem<D>(this.host, meta, refMeta, olds, news);
+            var i = new ResolverItem<D>(this.host, meta, olds, news);
             this.items.Add(i);
             return i;
         }
         private void GenerateKey(InsertRecord ins)
         {
-            foreach (var i in ins.Values)
+            foreach (var i in ins.Values.ToArray())
             {
                 var expr = this.info.GeneratorExpr(i.Key, i.Value);
                 if (expr != null)
             Dictionary<string, object> dict = null;
             if (t is InsertRecord) dict = (t as InsertRecord).Values;
             if (t is UpdateRecord) dict = (t as InsertRecord).Values;
-            this.refInfo.SetActualMasterKey(actualKey, dict);
+            this.info.SetActualMasterKey(dict, actualKey);
         }
         IEnumerable<TransactionRecord> IResolverItem.ResolveForMasterInsert(object[] refKey, object[] actualKey)
         {

UsuallyTests/TestResolve.cs

             m.Table("ORDER_LINES");
             m.IntegerKey("LINE_ID", (x) => x.LineId, "SEQ_ORDER_LINES");
             m.ExtraKey("x").DecimalKey("LINE_UNIQUE_ID", (x) => x.UniqueId, "SEQ_ORDER_LINES_UNQ");
-            m.Value("ORDER_ID", (x) => x.OrderId);
+            m.Ref("ORDER_ID", (x) => x.OrderId);
             m.Value("ITEM_ID", (x) => x.ItemId);
             m.Value("ITEM_NAME", (x) => x.ItemName);
             m.Value("QUANTITY", (x) => x.Quantity);
         {
             m.Table("ORDER_SHIPMENTS");
             m.IntegerKey("SHIPMENT_ID", (x) => x.ShipmentId, "SEQ_ORDER_SHIPMENTS");
-            m.Value("ORDER_LINE_ID", (x) => x.OrderLineId);
+            m.Ref("ORDER_LINE_ID", (x) => x.OrderLineId);
             m.Value("QUANTITY", (x) => x.Quantity);
             m.Value("SHIP_DATE", (x) => x.ShipDate);
         }
 
     class TestResolve
     {
-        [Test]
-        public void TestReconcile()
+        private List<OrderLine> olds = null;
+        private List<OrderLine> news = null;
+        [SetUp]
+        public void SetUp()
         {
-            var olds = new OrderLine[] {
+            this.olds = new OrderLine[] {
                 new OrderLine { LineId=1, UniqueId=100, OrderId=101, ItemId=1001, ItemName="Thousand One", Quantity=1, Unit="Each" },
                 new OrderLine { LineId=2, UniqueId=200, OrderId=101, ItemId=1002, ItemName="Thousand Two", Quantity=3, Unit="Pair" },
                 new OrderLine { LineId=3, UniqueId=300, OrderId=101, ItemId=1003, ItemName="Thousand Three", Quantity=5, Unit="Box" },
                 new OrderLine { LineId=6, UniqueId=600, OrderId=101, ItemId=1006, ItemName="Thousand Six", Quantity=6, Unit="Kg" },
                 new OrderLine { LineId=7, UniqueId=700, OrderId=101, ItemId=1007, ItemName="Thousand Seven", Quantity=4, Unit="Litre" },
             }.ToList();
-            var news = Use.SerializeClone(olds);
-            news[2 - 1].ItemId = 2002;
-            news[2 - 1].ItemName = "Two Oo Oo Two";
-            news[5 - 1].Quantity = null;
-            news[7 - 1].Unit = "Gallon";
-            news.RemoveAt(6 - 1);
-            news.RemoveAt(3 - 1);
-            Assert.AreEqual(5, news.Count);
-            news.Insert(2 - 1, new OrderLine { LineId = 11, UniqueId=800, OrderId = 101, ItemId = 2001, ItemName = "Two Oo Oo One", Quantity = 2, Unit = null });
-            news.Add(new OrderLine { LineId = -1, UniqueId=900, OrderId = 101, ItemId = 8008, ItemName = "Eight Thousand Eight", Quantity = 8, Unit = "Piece" });
-            news.Add(new OrderLine { LineId = 9, UniqueId=-7, OrderId = 101, ItemId = 9009, ItemName = "Nine Thousand Nine", Quantity = 9, Unit = "Square Metre" });
-            Assert.AreEqual(8, news.Count);
+            this.news = Use.SerializeClone(olds);
+        }
+        private void Twist(List<OrderLine> lines)
+        {
+            lines[2 - 1].ItemId = 2002;
+            lines[2 - 1].ItemName = "Two Oo Oo Two";
+            lines[5 - 1].Quantity = null;
+            lines[7 - 1].Unit = "Gallon";
+            lines.RemoveAt(6 - 1);
+            lines.RemoveAt(3 - 1);
+            lines.Insert(2 - 1, new OrderLine { LineId = 11, UniqueId = 800, OrderId = 101, ItemId = 2001, ItemName = "Two Oo Oo One", Quantity = 2, Unit = null });
+            lines.Add(new OrderLine { LineId = -1, UniqueId = 900, OrderId = 101, ItemId = 8008, ItemName = "Eight Thousand Eight", Quantity = 8, Unit = "Piece" });
+            lines.Add(new OrderLine { LineId = 9, UniqueId = -7, OrderId = 101, ItemId = 9009, ItemName = "Nine Thousand Nine", Quantity = 9, Unit = "Square Metre" });
+        }
+        [Test]
+        public void TestSimpleResolve()
+        {
+            this.Twist(this.news);
+            Assert.AreEqual(8, this.news.Count);
             var changes = Resolver.Resolve(OrderLine.Meta, olds, news);
             Assert.AreEqual(8, changes.Count());
             var e = changes.GetEnumerator();
             Assert.False(e.MoveNext());
         }
         [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;
+            });
+            r.Add(OrderLine.Meta, this.olds, this.news);
+            this.Twist(this.news);
+            Assert.AreEqual(8, this.news.Count);
+            var changes = r.Resolve().ToArray();
+            Assert.AreEqual(8, changes.Length);
+            var e = changes.GetEnumerator();
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(InsertRecord), e.Current);
+            {
+                var t = e.Current as InsertRecord;
+                Assert.AreEqual("ORDER_LINES", t.TableName);
+                Assert.AreEqual(7, t.Values.Count);
+                Assert.AreEqual(11, t.Values["LINE_ID"]);
+                Assert.AreEqual(800, t.Values["LINE_UNIQUE_ID"]);
+                Assert.AreEqual(101, t.Values["ORDER_ID"]);
+                Assert.AreEqual(2001, t.Values["ITEM_ID"]);
+                Assert.AreEqual("Two Oo Oo One", t.Values["ITEM_NAME"]);
+                Assert.AreEqual(2, t.Values["QUANTITY"]);
+                Assert.AreEqual(null, t.Values["UNIT"]);
+            }
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(UpdateRecord), e.Current);
+            {
+                var t = e.Current as UpdateRecord;
+                Assert.True(t.AtMostOne);
+                Assert.AreEqual("ORDER_LINES", t.TableName);
+                Assert.AreEqual(1, t.Keys.Count);
+                Assert.AreEqual(2, t.Keys["LINE_ID"]);
+                Assert.AreEqual(2, t.Values.Count);
+                Assert.AreEqual(2002, t.Values["ITEM_ID"]);
+                Assert.AreEqual("Two Oo Oo Two", t.Values["ITEM_NAME"]);
+            }
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(UpdateRecord), e.Current);
+            {
+                var t = e.Current as UpdateRecord;
+                Assert.True(t.AtMostOne);
+                Assert.AreEqual("ORDER_LINES", t.TableName);
+                Assert.AreEqual(1, t.Keys.Count);
+                Assert.AreEqual(5, t.Keys["LINE_ID"]);
+                Assert.AreEqual(1, t.Values.Count);
+                Assert.AreEqual(null, t.Values["QUANTITY"]);
+            }
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(UpdateRecord), e.Current);
+            {
+                var t = e.Current as UpdateRecord;
+                Assert.True(t.AtMostOne);
+                Assert.AreEqual("ORDER_LINES", t.TableName);
+                Assert.AreEqual(1, t.Keys.Count);
+                Assert.AreEqual(7, t.Keys["LINE_ID"]);
+                Assert.AreEqual(1, t.Values.Count);
+                Assert.AreEqual("Gallon", t.Values["UNIT"]);
+            }
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(InsertRecord), e.Current);
+            {
+                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(900, t.Values["LINE_UNIQUE_ID"]);
+                Assert.AreEqual(101, t.Values["ORDER_ID"]);
+                Assert.AreEqual(8008, t.Values["ITEM_ID"]);
+                Assert.AreEqual("Eight Thousand Eight", t.Values["ITEM_NAME"]);
+                Assert.AreEqual(8, t.Values["QUANTITY"]);
+                Assert.AreEqual("Piece", t.Values["UNIT"]);
+            }
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(InsertRecord), e.Current);
+            {
+                var t = e.Current as InsertRecord;
+                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(101, t.Values["ORDER_ID"]);
+                Assert.AreEqual(9009, t.Values["ITEM_ID"]);
+                Assert.AreEqual("Nine Thousand Nine", t.Values["ITEM_NAME"]);
+                Assert.AreEqual(9, t.Values["QUANTITY"]);
+                Assert.AreEqual("Square Metre", t.Values["UNIT"]);
+            }
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(DeleteRecord), e.Current);
+            {
+                var t = e.Current as DeleteRecord;
+                Assert.True(t.AtMostOne);
+                Assert.AreEqual("ORDER_LINES", t.TableName);
+                Assert.AreEqual(1, t.Keys.Count);
+                Assert.AreEqual(3, t.Keys["LINE_ID"]);
+            }
+            Assert.True(e.MoveNext());
+            Assert.IsInstanceOf(typeof(DeleteRecord), e.Current);
+            {
+                var t = e.Current as DeleteRecord;
+                Assert.True(t.AtMostOne);
+                Assert.AreEqual("ORDER_LINES", t.TableName);
+                Assert.AreEqual(1, t.Keys.Count);
+                Assert.AreEqual(6, t.Keys["LINE_ID"]);
+            }
+            Assert.False(e.MoveNext());
+        }
+        [Test]
         public void TestResolverObject()
         {
             var r = new Resolver();
             var orders = new List<Order>();
             var lines = new List<OrderLine>();
             var order = r.Add(Order.Meta, orders, orders);
-            var line = order.Add(OrderLine.Meta, (b) => b.Ref("ORDER_ID", (x) => x.OrderId), lines, lines);
+            var line = order.Add(OrderLine.Meta, lines, lines);
         }
     }
 }
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.