Commits

sake  committed 0dd6ec4

Resolver done without testing

  • Participants
  • Parent commits 71e875a

Comments (0)

Files changed (2)

File Usually/Resolve.cs

         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; }
         object[] GetKey(Dictionary<string, object> dict);
         object[] GetExtraKey(string group, T obj);
         object[] GetExtraKey(string group, Dictionary<string, object> dict);
+        string GeneratorExpr(string name, object value);
         void ForEachKey(T obj, Action<string, object> action);
         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; }
+        object[] GetMasterRef(T obj);
+        void SetActualMasterKey(object[] actualKey, Dictionary<string, object> dict);
+    }
     public static class MetaBuilderExtension
     {
         public static void Key<T>(this IKeyBuilder<T> m, string name, Func<T, object> getKey, string sequence, Func<object, bool> isDummy)
             {
                 this.Add(name, getKey, generator);
             }
-            public string GeneratingExpr(string name, object value)
+            public string GeneratorExpr(string name, object value)
             {
                 Func<object, string> g = null;
                 if (! this.generators.TryGetValue(name, out g)) return null;
         {
             return this.extraKeys[group].GetFrom(dict);
         }
+        string IMetaInfo<T>.GeneratorExpr(string name, object value)
+        {
+            var r = this.keys.GeneratorExpr(name, value);
+            if (r != null) return r;
+            foreach (var x in this.extraKeys)
+            {
+                r = x.Value.GeneratorExpr(name, value);
+                if (r != null) return r;
+            }
+            return null;
+        }
         void IMetaInfo<T>.ForEachKey(T obj, Action<string, object> action)
         {
             this.keys.ForEach(obj, action);
         #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;
             this.info = @info;
             this.olds = @olds;
             this.news = @news;
-            this.oldLookup = CreateLookup(this.info, olds);
-            this.newLookup = CreateLookup(this.info, news);
+            this.oldLookup = CreateLookup(this.info, @olds);
+            this.newLookup = CreateLookup(this.info, @news);
         }
         private static Dictionary<object[], T> CreateLookup(IMetaInfo<T> info, IEnumerable<T> list)
         {
     {
         public const int DEFAULT_DUMMY_START = -1;
         private List<IResolverItem> items = new List<IResolverItem>();
-        public ResolverItem<T> Add<T>(Meta<T> meta, IEnumerable<T> olds, IEnumerable<T> news) where T : class 
+        private Func<string, object> generator = null;
+        public Resolver(Func<string, object> generator = null)
         {
-            var r = new ResolverItem<T>(meta, null, null, olds, news);
+            this.generator = @generator;
+        }
+        public ResolverItem<T> Add<T>(Meta<T> meta, IEnumerable<T> olds, IEnumerable<T> news) 
+        {
+            var r = new ResolverItem<T>(this, meta, null, olds, news);
             this.items.Add(r);
             return r;
         }
+        public object Generate(string expr)
+        {
+            return (this.generator == null) ? null : this.generator(expr);
+        }
         public IEnumerable<TransactionRecord> Resolve()
         {
             return this.items.SelectMany((i) => i.ResolveForRoot());
         }
-        public static IEnumerable<TransactionRecord> Resolve<T>(Meta<T> meta, IEnumerable<T> olds, IEnumerable<T> news) where T: class
+        public static IEnumerable<TransactionRecord> Resolve<T>(Meta<T> meta, IEnumerable<T> olds, IEnumerable<T> news) 
         {
             var r = new Resolver();
             r.Add(meta, olds, news);
         IEnumerable<TransactionRecord> ResolveForMasterStatic(object[] refKey);
         IEnumerable<TransactionRecord> ResolveForMasterDelete(object[] refKey);
     }
-    public class ResolverItem<T> : IResolverItem where T: class
+    public class ResolverItem<T> : IResolverItem 
     {
+        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(Meta<T> meta, string group, Func<T, object[]> getRef, IEnumerable<T> olds, IEnumerable<T> news)
+        public ResolverItem(Resolver host, Meta<T> meta, RefMeta<T> refMeta, IEnumerable<T> olds, IEnumerable<T> news)
         {
+            this.host = @host;
             var m = new MetaInfoBuilder<T>();
             meta(m);
             this.info = m;
-            this.group = @group;
-            this.getRef = @getRef;
+            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, Func<D, object[]> getRef, IEnumerable<D> olds, IEnumerable<D> news) where D: class
+        public ResolverItem<D> Add<D>(Meta<D> meta, RefMeta<D> refMeta, IEnumerable<D> olds, IEnumerable<D> news) where D : class
         {
-            return this.Add(meta, null, getRef, olds, news);
-        }
-        public ResolverItem<D> Add<D>(Meta<D> meta, Func<D, object> getRef, IEnumerable<D> olds, IEnumerable<D> news) where D : class
-        {
-            return this.Add(meta, null, (x) => new object[] { getRef(x) }, olds, news);
-        }
-        public ResolverItem<D> Add<D>(Meta<D> meta, string group, Func<D, object[]> getRef, IEnumerable<D> olds, IEnumerable<D> news) where D : class
-        {
-            var i = new ResolverItem<D>(meta, group, getRef, olds, news);
+            var i = new ResolverItem<D>(this.host, meta, refMeta, olds, news);
             this.items.Add(i);
             return i;
         }
         }        
         private void GenerateKey(InsertRecord ins)
         {
+            foreach (var i in ins.Values)
+            {
+                var expr = this.info.GeneratorExpr(i.Key, i.Value);
+                if (expr != null)
+                {
+                    var g = this.host.Generate(expr);
+                    if (g != null) ins.Values[i.Key] = g;
+                }
+            }
         }
         private object[] GetKeyForDetail(IResolverItem i, T obj)
         {
         }
         protected void SetActualMasterKey(TransactionRecord t, object[] actualKey)
         {
+            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);
         }
         IEnumerable<TransactionRecord> IResolverItem.ResolveForMasterInsert(object[] refKey, object[] actualKey)
         {
                 {
                     var del = new DeleteRecord(this.info.TableName);
                     this.info.ForEachKey(j.Old, del.Keys.Add);
-                    var jdel = new TransactionJournal<T> { Record = del, Old = j.Old, New = null };
+                    var jdel = new TransactionJournal<T> { Record = del, Old = j.Old, New = default(T) };
                     details = this.ResolveForDelete(jdel);
                 }
                 foreach (var t in details) yield return t;

File UsuallyTests/TestResolve.cs

             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, (ln) => ln.OrderId, lines, lines);
+            var order = r.Add(Order.Meta, orders, orders);
+            var line = order.Add(OrderLine.Meta, (b) => b.Ref("ORDER_ID", (x) => x.OrderId), lines, lines);
         }
     }
 }