iarovyi / testProject

0 stars 0 forks source link

one #1

Closed iarovyi closed 9 years ago

iarovyi commented 9 years ago

analysis

iarovyi commented 9 years ago

http://www.amazon.com/gp/product/0735665877/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0735665877&linkCode=as2&tag=stepheclearys-20

http://www.amazon.com/gp/product/0735648735/ref=as_li_ss_tl?ie=UTF8&camp=1789&creative=390957&creativeASIN=0735648735&linkCode=as2&tag=stepheclearys-20

iarovyi commented 9 years ago

http://www.inis.gov.ie/en/INIS/Visa%20Waiver%20Programme%20Information%20Note%20March%202012.pdf/Files/Visa%20Waiver%20Programme%20Information%20Note%20March%202012.pdf

iarovyi commented 9 years ago

http://mitpress.mit.edu/sicp/

iarovyi commented 9 years ago

http://mitpress.mit.edu/sicp/

iarovyi commented 9 years ago

Func<dynamic, Int32, Int32> fact = (f, x) => x * (x == 1 ? x : f(f, x - 1));

iarovyi commented 9 years ago

http://oxfordknight.co.uk/

iarovyi commented 9 years ago

http://www.quantfinancejobs.com/

iarovyi commented 9 years ago

event sourcing, CQRS https://msdn.microsoft.com/en-us/library/jj591559.aspx http://www.kenneth-truyers.net/2013/12/05/introduction-to-domain-driven-design-cqrs-and-event-sourcing/ https://cqrs.wordpress.com/documents/cqrs-and-event-sourcing-synergy/

iarovyi commented 9 years ago

http://blog.byndyu.ru/2014/07/command-and-query-responsibility.html DomainEvents

iarovyi commented 9 years ago

http://rutracker.org/forum/viewtopic.php?t=540135 Мартин фаулер - архитектура приложений - книга - маст хэв

iarovyi commented 9 years ago

http://martinfowler.com/eaaCatalog/

iarovyi commented 9 years ago

BLOCKING: A blocked thread immediately yields its processor time slice, and from then on consumes no processor time until its blocking condition is satisfied. When a thread blocks or unblocks, the operating system performs a context switch. This incurs an overhead of a few microseconds.

Unblocking happens when:
-the blocking condition being satisfied
-the operation timing out (if a timeout is specified)
-interrupted via Thread.Interrupt
-aborted via Thread.Abort

1) Blocking (doesn't use CPU resources) - A thread in Blocked state is put in a wait queue lock Thread.Speep(1000) - will schedule your thread to run again after the sleep time expires, thus much lower CPU utilization 2) Spinning (if you expect a condition to be satisfied soon - within a few microseconds) while (!proceed); while (DateTime.Now < nextStartTime); 3) Hybrid

while (!proceed) Thread.Sleep (10);

CONTEXT SWITCH - switch from one thread to another thread. Selects one of the thread kernel objects and loads the CPU's registers with the values that were last saved in the thread's context Context structure is maintained inside the thread's kernel object and it reflects the state of the thread's CPU registers when the thread was last executing.

context switch ocurrs every Every 20 ms(15ms-30ms) that is called a quantum and take few microseconds(100 nanoseconds-7microseconds or 30 microseconds) context switch cost is 4000+ cycles (2,000-8,000 cycles) thread creation - approximately 200,000 cycles thread destroy - approximately 100,000 cycles

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682105(v=vs.85).aspx http://www.codeproject.com/Articles/662735/Internals-of-Windows-Thread

http://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html

SPINNING AND YIELDING: Thread.Yield() - put it into WAIT mode so it may run again straight away. If there is no ready threads then our thread continue. +about twice as fast as Thread.Sleep(0) -yields only to threads on same processor

Thread.Sleep(0) - put a Thread into SLEEP mode +faster than Thread.Sleep(1) -yields only to threads of same or higher priority It's bad because we can wait other thread with lower priority and our thread will not let it run().

Thread.Sleep(1) +yields to any thread on any processor -slowest option (Thread.Sleep(1) will usually suspend the thread by about 15ms if

may remove the thread from the scheduler's queue for 10+ms timeBeginPeriod/timeEndPeriod [win32] are not used)

SPINWAIT - smart spinning to avoid context switches (spin and then yield). for high-concurrency. Thread.SpinWait(n) 20 times with increasing cycles amount and then Thread.Yield() with rare Thread.Sleep(0) and Thread.Sleep(1) 1) SpinWait wait = new SpinWait(); while (!p) { wait.SpinOnce(); }

2) Two-phase wait operation (spinning-then-waiting combination)
SpinWait wait = new SpinWait();
while (!p) {  if (wait.NextSpinWillYield) { /* block! */ } else { wait.SpinOnce(); }    }

1) Spin - wait without yielding the current timeslice (pointless on single core machine)

Thread.SpinWait(iterations) - bussy spin and if processor is hyperthreaded then let run other logical thread
                  Is useful on hyperthreaded processors. indicates to the processor that you are
                  not doing any useful work and that it should run code from a different logical CPU

2) Then Yild - yielding the current timeslice (force context switch)

Thread.Yield()  - yields to any thread on same processor
Thread.Sleep(0) - yields to any thread on any  processor of same or higher priority (we can be waiting for lower priority)
Thread.Sleep(1) - yields to any thread on any  processor

SPINLOCK (ALMOST NEVER) - mutual exclusion lock based on spinning and then on yilding https://msdn.microsoft.com/en-us/library/system.threading.spinlock(v=vs.110).aspx Use when lock hold-times are always extremely short and there are large number of locks (lock per node in a linked list). We can't use Monitor because of large number it will create many Monitor objects and increase garbase collection preassure.

bool gotLock = false;
try
{
    sl.Enter(ref gotLock);
    //...
}
finally
{
    if (gotLock) sl.Exit();
}

In SpinLock we shouldn't do:
-blocking,
-calling anything that itself may block,
-holding more than one spin lock at once,
-making dynamically dispatched calls (interface and virtuals),
-making statically dispatched calls into any code one doesn't own, or
-allocating memory.

iarovyi commented 9 years ago

BLOCKING: A blocked thread immediately yields its processor time slice, and from then on consumes no processor time until its blocking condition is satisfied. When a thread blocks or unblocks, the operating system performs a context switch. This incurs an overhead of a few microseconds.

Unblocking happens when:
-the blocking condition being satisfied
-the operation timing out (if a timeout is specified)
-interrupted via Thread.Interrupt
-aborted via Thread.Abort

1) Blocking (doesn't use CPU resources) - A thread in Blocked state is put in a wait queue lock Thread.Speep(1000) - will schedule your thread to run again after the sleep time expires, thus much lower CPU utilization 2) Spinning (if you expect a condition to be satisfied soon - within a few microseconds) while (!proceed); while (DateTime.Now < nextStartTime); 3) Hybrid

while (!proceed) Thread.Sleep (10);

CONTEXT SWITCH - switch from one thread to another thread. Selects one of the thread kernel objects and loads the CPU's registers with the values that were last saved in the thread's context Context structure is maintained inside the thread's kernel object and it reflects the state of the thread's CPU registers when the thread was last executing.

context switch ocurrs every Every 20 ms(15ms-30ms) that is called a quantum and take few microseconds(100 nanoseconds-7microseconds or 30 microseconds) context switch cost is 4000+ cycles (2,000-8,000 cycles) thread creation - approximately 200,000 cycles thread destroy - approximately 100,000 cycles

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682105(v=vs.85).aspx http://www.codeproject.com/Articles/662735/Internals-of-Windows-Thread

http://blog.tsunanet.net/2010/11/how-long-does-it-take-to-make-context.html

SPINNING AND YIELDING: Thread.Yield() - put it into WAIT mode so it may run again straight away. If there is no ready threads then our thread continue. +about twice as fast as Thread.Sleep(0) -yields only to threads on same processor

Thread.Sleep(0) - put a Thread into SLEEP mode +faster than Thread.Sleep(1) -yields only to threads of same or higher priority It's bad because we can wait other thread with lower priority and our thread will not let it run().

Thread.Sleep(1) +yields to any thread on any processor -slowest option (Thread.Sleep(1) will usually suspend the thread by about 15ms if

may remove the thread from the scheduler's queue for 10+ms timeBeginPeriod/timeEndPeriod [win32] are not used)

SPINWAIT - smart spinning to avoid context switches (spin and then yield). for high-concurrency. Thread.SpinWait(n) 20 times with increasing cycles amount and then Thread.Yield() with rare Thread.Sleep(0) and Thread.Sleep(1) 1) SpinWait wait = new SpinWait(); while (!p) { wait.SpinOnce(); }

2) Two-phase wait operation (spinning-then-waiting combination)
SpinWait wait = new SpinWait();
while (!p) {  if (wait.NextSpinWillYield) { /* block! */ } else { wait.SpinOnce(); }    }

1) Spin - wait without yielding the current timeslice (pointless on single core machine)

Thread.SpinWait(iterations) - bussy spin and if processor is hyperthreaded then let run other logical thread
                  Is useful on hyperthreaded processors. indicates to the processor that you are
                  not doing any useful work and that it should run code from a different logical CPU

2) Then Yild - yielding the current timeslice (force context switch)

Thread.Yield()  - yields to any thread on same processor
Thread.Sleep(0) - yields to any thread on any  processor of same or higher priority (we can be waiting for lower priority)
Thread.Sleep(1) - yields to any thread on any  processor

SPINLOCK (ALMOST NEVER) - mutual exclusion lock based on spinning and then on yilding https://msdn.microsoft.com/en-us/library/system.threading.spinlock(v=vs.110).aspx Use when lock hold-times are always extremely short and there are large number of locks (lock per node in a linked list). We can't use Monitor because of large number it will create many Monitor objects and increase garbase collection preassure.

bool gotLock = false;
try
{
    sl.Enter(ref gotLock);
    //...
}
finally
{
    if (gotLock) sl.Exit();
}

In SpinLock we shouldn't do:
-blocking,
-calling anything that itself may block,
-holding more than one spin lock at once,
-making dynamically dispatched calls (interface and virtuals),
-making statically dispatched calls into any code one doesn't own, or
-allocating memory.





1) First try use captured SynchronizationContext if not null (ConfigureAwait(false)-ognore context) 2) use TaskScheduler.Current

catch (AggregateException ex) { ex.Handle(exception => { Trace.WriteLine(exception); return true; }); } Tasks should not be extrememly short, nor extremely long.

If your tasks are too short, then the overhead of breaking up the data into tasks and scheduling those tasks on the thread pool becomes significant. If your tasks are too long, then the thread pool cannot dynamically adjust its work balancing efficiently.

https://msdn.microsoft.com/en-us/library/ff963553.aspx http://www.microsoft.com/en-us/download/details.aspx?id=14782 http://www.introtorx.com/ http://blogs.msdn.com/b/pfxteam/archive/2011/12/05/10244302.aspx

Rx observables are generally better than dataflow blocks when doing anything related to timing. Dataflow blocks are generally better than Rx observables when doing parallel processing

"Microsoft TPL Dataflow" nuget package "Microsoft Immutable Collections" nuget package

var task1 = Task.FromResult(55); var task2 = Task.FromResult(55); int[] results = await Task.WhenAll(task1, task2); //TODO: how get results from completed tasks if one was failed.

    Task allTasks = Task.WhenAll(task1, task2);
        try
        {
            await allTasks;
        }
        catch (Exception)
        {
            AggregateException allExceptions = allTasks.Exception; // Get all excepitons
            throw allExceptions;
        }

FOREACH TASKS AS THEY COMPLETE:

public static class TasksExtensions { //This method is avalable in AsyncEx library https://nitoasyncex.codeplex.com/ //http://blogs.msdn.com/b/pfxteam/archive/2012/08/02/processing-tasks-as-they-complete.aspx // foreach (Task<Task> bucket in tasks.OrderByCompletion()) // { // int result = await await bucket; // } public static Task<Task>[] OrderByCompletion(this IEnumerable<Task> tasks) { List<Task> inputTasks = tasks.ToList();

        var buckets = new TaskCompletionSource<Task<T>>[inputTasks.Count];
        var results = new Task<Task<T>>[buckets.Length];
        for (int i = 0; i < buckets.Length; i++)
        {
            buckets[i] = new TaskCompletionSource<Task<T>>();
            results[i] = buckets[i].Task;
        }

        int nextTaskIndex = -1;
        Action<Task<T>> continuation = completed =>
        {
            var bucket = buckets[Interlocked.Increment(ref nextTaskIndex)];
            bucket.TrySetResult(completed);
        };

        foreach (var inputTask in inputTasks)
        {
            inputTask.ContinueWith(continuation, CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
        }

        return results;
    }
}

ALTERNATIVE: await Task.WhenAll(new[] { taskA, taskB, taskC }.Select(async t => { var result = await t; //this is called as task complete, one by one.

        }).ToArray());

Parrallel - dynamically react to cahnging CPU conditions PLINQ - use all cores on machine (more expensive, but shorter)

    //From Nito library. It waits untill all async operations are complete!!!!!!!!!
        AsyncContext.Run(() => { 

        });

Rx - Reactive Extensions: IObservable - linq to events

   xxxx.ToObservable()

    var progress = new Progress<int>();
        var progressReports = Observable.FromEventPattern<int>(
            handler => progress.ProgressChanged += handler,
            handler => progress.ProgressChanged -= handler);

        progressReports.Subscribe(data => Trace.WriteLine("OnNext: " + data.EventArgs));

   Observable.Interval(TimeSpan.FromSeconds(1))
            //.ObserveOn(SynchronizationContext.Current)
            .ObserveOn(Scheduler.Default)
            .Select(time =>
            {
                Console.WriteLine("Do some work");
                Thread.Sleep(1000);
                return time;
            })
            .Where(time => time > 0)
            .ObserveOn(Scheduler.Default)
            .Buffer(2) //group events and give them all together
            .Subscribe(x => Console.WriteLine("Two buffered events for {0} and {1}", x[0], x[1]));

    Observable.Interval(TimeSpan.FromSeconds(1))
            .Window(5) //group events and give them as they coming
            .Subscribe(group => {
                Console.WriteLine("New group");
                group.Subscribe(x => Console.WriteLine("On next"),
                                x => Console.WriteLine("on error"));
            });

    Observable.Interval(TimeSpan.FromMilliseconds(50))
    //Good for capturing last mouse drag before mouse stop
            //Whenever event comes then timeous is reset.
            //.Throttle(TimeSpan.FromMilliseconds(55)) //sliding timeout window
            .Sample(TimeSpan.FromSeconds(1))           //publish the most recent value evry 1 minute
            .Subscribe(x => Console.WriteLine(x));

    new HttpClient().GetStringAsync("http://google.com")
            .ToObservable()
            .Timeout(TimeSpan.FromSeconds(1)) //sliding timeout - every event reset timeout
            .Subscribe(x => Console.WriteLine(x));

Microsoft TPL Dataflow:

    var bufferBlock = new BufferBlock<int>();

        bufferBlock.ReceiveAsync().ContinueWith(async (item) => Console.WriteLine(await item));
        bufferBlock.Post(55);

Immutable Collections: 1) code is more functional 2) small thread safe collections 3) large number of snapshots (they share memory)

    ImmutableDictionary<string, Man> dic = ImmutableDictionary<string, Man>.Empty;
        ImmutableInterlocked.AddOrUpdate<string, Man>(ref dic, "Jack", new Man("Jack"), updateValueFactory: (name, m) => m);
        ImmutableInterlocked.AddOrUpdate<string, Man>(ref dic, "Tom", new Man("Tom"), updateValueFactory: (name, m) => m);
        Man man;
        dic.TryGetValue("Jack", out man);

        ImmutableStack<int> stack = ImmutableStack<int>.Empty;
        ImmutableInterlocked.Push(ref stack, 1);
        ImmutableInterlocked.Push(ref stack, 2);
        ImmutableInterlocked.Push(ref stack, 3);
        int value;
        ImmutableInterlocked.TryPop(ref stack, out value);

iarovyi commented 9 years ago

https://www.upwork.com/o/profiles/users/_~0187cd88db7e6dfb55/

iarovyi commented 8 years ago

Letter of recommendation

To Whom it may concern: I had the pleasure of working with Sergii Iarovyi. Sergii is a dedicated team member with fascinating development skills. He always handled to deliver complex solutions in short period of time. He is also able to manage multiple tasks and address issues in a well-timed manner making him one of the key players of any team. Sergii is also an easy and fun person to work with. He willingly accepts challenging assignments and offers to contribute where ever he can. Also he has proved excellent analytical and programming skills that is very important to address the constantly changing business requirements. The best thing I noticed in him is his strong willingness to learn latest technical tools, technologies and offer better solutions. I can assure you that he will be an active member of your team and relevant asset in your organization.

iarovyi commented 8 years ago

http://stackoverflow.com/questions/3716492/what-does-expression-quote-do-that-expression-constant-can-t-already-do

iarovyi commented 8 years ago

using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection;

namespace Ubs.Raws.Expressions {

region Contracts

public class PropertyOrder
{
    private readonly string _property;
    private readonly bool _isAscending;
    public PropertyOrder(string property, bool isAscending)
    {
        if (string.IsNullOrWhiteSpace(property)) { throw new ArgumentException("property"); }

        _property = property;
        _isAscending = isAscending;
    }

    public string Property { get { return _property; } }

    public bool IsAscending { get { return _isAscending; } }
}

public class PropertyFilter
{
    private readonly string _property;
    private readonly FilterType _type;
    private readonly object _value;

    public PropertyFilter(string property, FilterType type, object value)
    {
        if (string.IsNullOrWhiteSpace(property)) { throw new ArgumentException("property"); }

        _property = property;
        _type = type;
        _value = value;
    }

    public string Property { get { return _property; } }

    public FilterType Type { get { return _type; } }

    public object Value { get { return _value; } }
}

public enum FilterType
{
    Equals,
    NotEquals,

    Contains,
    StartsWidth,
    EndsWith,

    LessThan,
    LessThanOrEqual,
    GreaterThan,
    GreaterThanOrEqual,
}

public class Page<T>
{
    private readonly IList<T> _items;
    private readonly int _page;
    private readonly int _pageSize;
    private readonly long _total;

    public Page(IList<T> items, int page, int pageSize, long total)
    {
        if (page < 1)     { throw new ArgumentOutOfRangeException("page"); }
        if (pageSize < 1) { throw new ArgumentOutOfRangeException("pageSize"); }
        if (total < 0)    { throw new ArgumentOutOfRangeException("total"); }

        _items = items;
        _page = page;
        _pageSize = pageSize;
        _total = total;
    }

    public static Page<T> FromPage<TOther>(IList<T> items, Page<TOther> page)
    {
        return new Page<T>(items, page.PageNumber, page._pageSize, page.TotalCount);
    }

    public IList<T> Items { get { return _items; } }

    public int PageNumber { get { return _page; } }

    public int Count { get { return _items.Count; } }

    public long TotalCount { get { return _total; } }

    public int TotalPages { get { return (int)Math.Ceiling(_total / (double)_pageSize); } }
}
#endregion

public static class PredicateBuilder
{
    #region Get Name
    public static string GetMemberName<TObj, TMember>(Expression<Func<TObj, TMember>> memberSelector)
    {
        return GetMemberName(memberSelector.Body);
    }
    #endregion

    #region Logical Operators
    public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b)
    {
        Expression body = Expression.AndAlso(a.Body, SubstExpressionVisitor.Replace(b.Body, b.Parameters[0], a.Parameters[0]));
        return Expression.Lambda<Func<T, bool>>(body, a.Parameters[0]);
    }

    public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> a, Expression<Func<T, bool>> b)
    {
        Expression body = Expression.OrElse(a.Body, SubstExpressionVisitor.Replace(b.Body, b.Parameters[0], a.Parameters[0]));
        return Expression.Lambda<Func<T, bool>>(body, a.Parameters[0]);
    }

    public static Expression<Func<T, bool>> ToOr<T>(this IEnumerable<Expression<Func<T, bool>>> expressions)
    {
        return expressions.Any() ? expressions.Aggregate((e1, e2) => e1.Or(e2)) : (p) => false;
    }

    public static Expression<Func<T, bool>> ToAnd<T>(this IEnumerable<Expression<Func<T, bool>>> expressions)
    {
        return expressions.Any() ? expressions.Aggregate((e1, e2) => e1.And(e2)) : (p) => true;
    }
    #endregion

    #region Paging
    public static Page<T> ToPage<T>(this IQueryable<T> query, int page, int pageSize)
    {
        if (page < 1) { throw new ArgumentOutOfRangeException("page"); }
        if (pageSize < 1) { throw new ArgumentOutOfRangeException("pageSize"); }

        long totalCount = query.LongCount();
        List<T> data = totalCount > 0 ? query.Skip(pageSize * (page - 1)).Take(pageSize).ToList()
                                      : new List<T>();

        return new Page<T>(data, page, pageSize, totalCount);
    }
    #endregion

    #region Filtering
    public static IQueryable<T> Where<T>(this IQueryable<T> source, IEnumerable<PropertyFilter> filters)
    {
        return source.Provider.CreateQuery<T>(Expression.Call(
                    typeof(Queryable),
                    "Where",
                    new[] { source.ElementType },
                    source.Expression,
                    filters.Select(f => ToFilterExpression<T>(f.Property, f.Type, f.Value)).ToAnd<T>()));
    }

    public static IQueryable<T> Where<T>(this IQueryable<T> source, string property, FilterType type, object filter)
    {
        return source.Provider.CreateQuery<T>(Expression.Call(
                    typeof(Queryable),
                    "Where",
                    new[] { source.ElementType },
                    source.Expression,
                    ToFilterExpression<T>(property, type, filter)));
    }
    #endregion

    #region Ordering
    public static IQueryable<T> OrderBy<T>(this IQueryable<T> source, IList<PropertyOrder> orders)
    {
        if (!orders.Any())
        {
            return source;
        }

        PropertyOrder order = orders.First();
        IOrderedQueryable<T> ordered = order.IsAscending ? source.OrderBy<T>(order.Property) : source.OrderByDescending<T>(order.Property);

        for (int i = 1; i < orders.Count; i++)
        {
            order = orders[i];
            ordered = order.IsAscending ? ordered.ThenBy<T>(order.Property) : ordered.ThenByDescending<T>(order.Property);
        }

        return ordered;
    }

    public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string property)
    {
        return ToOrderExpression<T>(source, property, "OrderBy");
    }

    public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> source, string property)
    {
        return ToOrderExpression<T>(source, property, "OrderByDescending");
    }

    public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string property)
    {
        return ToOrderExpression<T>(source, property, "ThenBy");
    }

    public static IOrderedQueryable<T> ThenByDescending<T>(this IOrderedQueryable<T> source, string property)
    {
        return ToOrderExpression<T>(source, property, "ThenByDescending");
    }
    #endregion

    private static IOrderedQueryable<T> ToOrderExpression<T>(this IQueryable<T> source, string propertyExpression, string methodName)
    {
        ParameterExpression arg = Expression.Parameter(typeof(T), "x");
        MemberExpression propExpression = ToPropertyExpression<T>(propertyExpression, arg);
        LambdaExpression expression = Expression.Lambda(Expression.Convert(propExpression, propExpression.Type), arg);

        return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(Expression.Call(
                    typeof(Queryable),
                    methodName,
                    new[] { source.ElementType, expression.Body.Type },
                    source.Expression,
                    expression));
    }

    private static Expression<Func<T, bool>> ToFilterExpression<T>(string property, FilterType type, object filter)
    {
        switch (type)
        {
            case (FilterType.Equals):               return Operation<T>((p, val) => Expression.Equal(p, val), property, filter);
            case (FilterType.NotEquals):            return Operation<T>((p, val) => Expression.NotEqual(p, val), property, filter);

            case (FilterType.Contains):             return StringMethod<T>(property, filter, "Contains");
            case (FilterType.StartsWidth):          return StringMethod<T>(property, filter, "StartsWith");
            case (FilterType.EndsWith):             return StringMethod<T>(property, filter, "EndsWith");

            case (FilterType.LessThan):             return Operation<T>((p, val) => LessThan(p, val), property, filter);
            case (FilterType.LessThanOrEqual):      return Operation<T>((p, val) => LessThanOrEqual(p, val), property, filter);
            case (FilterType.GreaterThan):          return Operation<T>((p, val) => GreaterThan(p, val), property, filter);
            case (FilterType.GreaterThanOrEqual):   return Operation<T>((p, val) => GreaterThanOrEqual(p, val), property, filter);

            default: throw new NotImplementedException(string.Format("Filter type is not implemented {0}", type));
        }
    }

    private static BinaryExpression LessThan(Expression left, Expression right)
    {
        return left.Type == typeof(string) ? Expression.LessThan(StringCompare(left, right), Expression.Constant(0))
                                           : Expression.LessThan(left, right);
    }

    private static BinaryExpression LessThanOrEqual(Expression left, Expression right)
    {
        return left.Type == typeof(string) ? Expression.LessThanOrEqual(StringCompare(left, right), Expression.Constant(0))
                                           : Expression.LessThanOrEqual(left, right);
    }

    private static BinaryExpression GreaterThan(Expression left, Expression right)
    {
        return left.Type == typeof(string) ? Expression.GreaterThan(StringCompare(left, right), Expression.Constant(0))
                                           : Expression.GreaterThan(left, right);
    }

    private static BinaryExpression GreaterThanOrEqual(Expression left, Expression right)
    {
        return left.Type == typeof(string) ? Expression.GreaterThanOrEqual(StringCompare(left, right), Expression.Constant(0))
                                           : Expression.GreaterThanOrEqual(left, right);
    }

    private static Expression StringCompare(Expression left, Expression right)
    {
        return Expression.Call(null, left.Type.GetMethod("Compare", new[] { left.Type, right.Type }), new[] { left, right });
    }

    private static Expression<Func<T, bool>> Operation<T>(Func<Expression, Expression, Expression> operation, string columnName, object value)
    {
        ParameterExpression param = Expression.Parameter(typeof(T), "x");
        MemberExpression property = ToPropertyExpression<T>(columnName, param);
        Expression body = operation(property, Expression.Convert(Expression.Constant(value), property.Type));

        return Expression.Lambda<Func<T, bool>>(body, param);
    }

    private static Expression<Func<T, bool>> StringMethod<T>(string member, object value, string methodName)
    {
        ParameterExpression param = Expression.Parameter(typeof(T), "x");
        MemberExpression property = ToPropertyExpression<T>(member, param);
        Expression valueExpr = Expression.Constant(value != null ? value.ToString().ToUpper() : string.Empty);

        //x => x.ToString().ToUpper().StartsWith("VALUE")
        var startsWith = Expression.Call(
                         //------------------------ ToUpper Start
                         Expression.Call(
                                //------------------------ ToString Start
                                Expression.Call(
                                    property,
                                    "ToString", null
                                    ),
                                //------------------------ ToString Start
                                "ToUpper", null
                                ),
                        //------------------------ ToUpper End
                        methodName, null,
                        valueExpr
                    );

        return Expression.Lambda<Func<T, bool>>(startsWith, param);
    }

    private static MemberExpression ToPropertyExpression<TContainer>(string propertyExpression, ParameterExpression arg)
    {
        Expression body = arg;
        foreach (var subMember in propertyExpression.Split('.'))
        {
            body = Expression.PropertyOrField(body, subMember);
        }

        return (MemberExpression)body;
    }

    private static string GetMemberName(Expression expression)
    {
        switch (expression.NodeType)
        {
            case ExpressionType.Parameter:
                return ((ParameterExpression)expression).Name;
            case ExpressionType.MemberAccess:
                return ((MemberExpression)expression).Member.Name;
            case ExpressionType.Call:
                return ((MethodCallExpression)expression).Method.Name;
            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
                return GetMemberName(((UnaryExpression)expression).Operand);
            case ExpressionType.Invoke:
                return GetMemberName(((InvocationExpression)expression).Expression);
            case ExpressionType.ArrayLength:
                return "Length";
            default:
                throw new Exception("not a proper member selector");
        }
    }

    #region Visitors
    private class SubstExpressionVisitor : ExpressionVisitor
    {
        private readonly Expression _oldExpr;
        private readonly Expression _newExpr;

        public static Expression Replace(Expression instance, Expression oldExpr, Expression newExpr)
        {
            var visitor = new SubstExpressionVisitor(oldExpr, newExpr);
            return visitor.Visit(instance);
        }

        public SubstExpressionVisitor(Expression oldExpr, Expression newExpr)
        {
            _oldExpr = oldExpr;
            _newExpr = newExpr;
        }

        protected override Expression VisitParameter(ParameterExpression node)
        {
            return _oldExpr == node ? _newExpr : node;
        }
    }

    //http://stackoverflow.com/questions/18976495/linq-to-entities-only-supports-casting-edm-primitive-or-enumeration-types-with-i
    /*public sealed class EntityCastRemoverVisitor : ExpressionVisitor
    {
        public static TExpression Convert<TExpression>(TExpression expression) where TExpression : Expression
        {
            var visitor = new EntityCastRemoverVisitor();
            var visitedExpression = visitor.Visit(expression);
            return (TExpression)visitedExpression;
        }

        protected override Expression VisitUnary(UnaryExpression node)
        {
            if (node.NodeType == ExpressionType.Convert && node.Type.IsSubclassOfGeneric(typeof(IEntity<>)))
            {
                return node.Operand;
            }

            return base.VisitUnary(node);
        }
    }*/
    #endregion
}

}

iarovyi commented 8 years ago

using NUnit.Framework; using System; using System.Collections.Generic; using System.Linq; using System.Text; using NHibernate.Linq; using FluentAssertions; using Ubs.Raws.DAL.Tests; using Ubs.Raws.Domain; using Ubs.Raws.DAL; using System.Linq.Expressions; using System.Collections;

namespace Ubs.Raws.Expressions.Tests.Extensions { [TestFixture] public class FilteringExtensionsDatabaseTests : BaseDatabaseTest { private static readonly Dictionary<Type, string> Properties = new Dictionary<Type, string>() { {typeof(int), TestEntityProp(e => e.Int)}, {typeof(int?), TestEntityProp(e => e.IntNullable)}, {typeof(float), TestEntityProp(e => e.Float)}, {typeof(float?), TestEntityProp(e => e.FloatNullable)}, {typeof(decimal), TestEntityProp(e => e.Decimal)}, {typeof(decimal?), TestEntityProp(e => e.DecimalNullable)}, {typeof(double), TestEntityProp(e => e.DoubleProp)}, {typeof(double?), TestEntityProp(e => e.DoubleNullable)}, {typeof(long), TestEntityProp(e => e.Long)}, {typeof(long?), TestEntityProp(e => e.LongNullable)}, {typeof(DateTime), TestEntityProp(e => e.DateTime)}, {typeof(DateTime?), TestEntityProp(e => e.DateTimeNullable)}, {typeof(TimeSpan), TestEntityProp(e => e.TimeSpan)}, {typeof(TimeSpan?), TestEntityProp(e => e.TimeSpanNullable)}, {typeof(string), TestEntityProp(e => e.String)},

    };

    public IEnumerable PropertyNames
    {
        get { return Properties.Select(p => new TestCaseData(p.Value)); }
    }

    public IEnumerable PropertyNamePairs
    {
        get
        {
            IList<string> propertyNames = Properties.Select(p => p.Value).ToList();
            for (int i = 0; i < propertyNames.Count; i++)
            {
                string prop1 = propertyNames[i];
                string prop2 = propertyNames[propertyNames.Count - 1 - i];
                if (prop1 != prop2)
                {
                    yield return new TestCaseData(prop1, prop2);
                }
            }
        }
    }

    public IEnumerable Filters
    {
        get
        {
            foreach (KeyValuePair<Type,string> property in Properties)
            {
                Type type = property.Key;
                bool isNullable = Nullable.GetUnderlyingType(type) != null;
                object value = FakeData.Value(type);
                string propertyName = property.Value;

                yield return new TestCaseData(FilterType.Equals,            propertyName, value);
                yield return new TestCaseData(FilterType.NotEquals,         propertyName, value);

                yield return new TestCaseData(FilterType.Contains,          propertyName, value);
                yield return new TestCaseData(FilterType.StartsWidth,       propertyName, value);
                yield return new TestCaseData(FilterType.EndsWith,          propertyName, value);

                yield return new TestCaseData(FilterType.GreaterThan, propertyName, value);
                yield return new TestCaseData(FilterType.GreaterThanOrEqual, propertyName, value);
                yield return new TestCaseData(FilterType.LessThan, propertyName, value);
                yield return new TestCaseData(FilterType.LessThanOrEqual, propertyName, value);

                if (isNullable)
                {
                    yield return new TestCaseData(FilterType.Equals,        propertyName, null);
                    yield return new TestCaseData(FilterType.NotEquals,     propertyName, null);

                    yield return new TestCaseData(FilterType.Contains,      propertyName, null);
                    yield return new TestCaseData(FilterType.StartsWidth,   propertyName, null);
                    yield return new TestCaseData(FilterType.EndsWith,      propertyName, null);
                }
            }
        }
    }

    [Test]
    [TestCaseSource("Filters")]
    public void ToFiltered_Doesnot_Throw_Exception_With_Database(FilterType type, string propertyName, object filterValue)
    {
        //Assign
        var filters = new List<PropertyFilter>()
        {
            new PropertyFilter(propertyName, type, filterValue)
        };

        //Act
        Action action = () => {
            Session.Query<TestEntity>().Where<TestEntity>(filters).ToList();
        };

        //Assert
        action.ShouldNotThrow();
    }

    [Test]
    [TestCaseSource("PropertyNames")]
    public void ToOrdered_Doesnot_Throw_Exception_WithDatabase_Asc(string propertyName)
    {
        //Assign
        var orders = new List<PropertyOrder>()
        {
            new PropertyOrder(propertyName, true),
        };

        //Act
        Action action = () =>
        {
            Session.Query<TestEntity>().OrderBy<TestEntity>(orders).ToList();
        };

        //Assert
        action.ShouldNotThrow();
    }

    [Test]
    [TestCaseSource("PropertyNamePairs")]
    public void ToOrdered_Doesnot_Throw_Exception_WithDatabase_With_Two_Columns(string propertyName, string otherPropertyName)
    {
        //Assign
        var orders = new List<PropertyOrder>()
        {
            new PropertyOrder(propertyName, true),
            new PropertyOrder(otherPropertyName, false),
        };

        //Act
        Action action = () =>
        {
            Session.Query<TestEntity>().OrderBy<TestEntity>(orders).ToList();
        };

        //Assert
        action.ShouldNotThrow();
    }

    private static string TestEntityProp(Expression<Func<TestEntity, object>> prop)
    {
        return PredicateBuilder.GetMemberName<TestEntity, object>(prop);
    }
}

}

iarovyi commented 8 years ago

using FluentAssertions; using NUnit.Framework; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using Ubs.Raws.Domain;

namespace Ubs.Raws.Expressions.Tests.Extensions { [TestFixture(typeof(int))] [TestFixture(typeof(int?))] [TestFixture(typeof(float))] [TestFixture(typeof(float?))] [TestFixture(typeof(decimal))] [TestFixture(typeof(decimal?))] [TestFixture(typeof(double))] [TestFixture(typeof(double?))] [TestFixture(typeof(long))] [TestFixture(typeof(long?))] [TestFixture(typeof(DateTime))] [TestFixture(typeof(DateTime?))] [TestFixture(typeof(TimeSpan))] [TestFixture(typeof(TimeSpan?))] [TestFixture(typeof(string))] public class FilteringExtensionsTests { public IEnumerable FilterTypes { get { yield return new TestCaseData(FilterType.Equals, Foo.Filter((v) => f => f.Id.Equals(v))); yield return new TestCaseData(FilterType.NotEquals, Foo.Filter((v) => f => !f.Id.Equals(v))); yield return new TestCaseData(FilterType.Contains, Foo.Filter((v) => f => f.Id.ToString().Contains(v.ToString()))); yield return new TestCaseData(FilterType.StartsWidth, Foo.Filter((v) => f => f.Id.ToString().StartsWith(v.ToString()))); yield return new TestCaseData(FilterType.EndsWith, Foo.Filter((v) => f => f.Id.ToString().EndsWith(v.ToString())));

            //TODO: remove this condition
            if (typeof(T) != typeof(string))
            {
                yield return new TestCaseData(FilterType.GreaterThan, Foo<T>.Filter((v) => f => Operators<T>.GreaterThen(f.Id, v)));
                yield return new TestCaseData(FilterType.GreaterThanOrEqual, Foo<T>.Filter((v) => f => Operators<T>.GreaterThenOrEqual(f.Id, v)));
                yield return new TestCaseData(FilterType.LessThan, Foo<T>.Filter((v) => f => Operators<T>.LessThen(f.Id, v)));
                yield return new TestCaseData(FilterType.LessThanOrEqual, Foo<T>.Filter((v) => f => Operators<T>.LessThanOrEqual(f.Id, v)));
            }
        }
    }

    [Test]
    public void ToOrdered_Sort_Correct_Descending()
    {
        //Assign
        var orders = new List<PropertyOrder>()
        {
            new PropertyOrder("Id", false)
        };
        List<Foo<T>> data = CreateList<T>();
        List<Foo<T>> expected = data.AsQueryable().OrderByDescending(f => f.Id).ToList();

        //Act
        var result = data.AsQueryable().OrderBy<Foo<T>>(orders).ToList();

        //Assert
        expected.SequenceEqual(result).Should().BeTrue();
    }

    [Test]
    public void ToOrdered_Sort_Correct_Ascending()
    {
        //Assign
        var orders = new List<PropertyOrder>()
        {
            new PropertyOrder("Id", true)
        };
        List<Foo<T>> data = CreateList<T>();
        List<Foo<T>> expected = data.AsQueryable().OrderBy(f => f.Id).ToList();

        //Act
        var result = data.AsQueryable().OrderBy<Foo<T>>(orders).ToList();

        //Assert
        expected.SequenceEqual(result).Should().BeTrue();
    }

    [Test]
    [TestCaseSource("FilterTypes")]
    public void ToFiltered_Filters_Correct_With_Different_Filter_Types(FilterType type, Func<T, Func<Foo<T>, bool>> filterSource)
    {
        //Assign
        List<Foo<T>> data = CreateList<T>();
        T average = AverageByIndex(data, f => f.Id);
        List<Foo<T>> expected = data.AsQueryable().Where(filterSource(average)).ToList();
        var filters = new List<PropertyFilter>()
        {
            new PropertyFilter("Id", type, average)
        };

        //Act
        var result = data.AsQueryable().Where<Foo<T>>(filters).ToList();

        //Assert
        expected.SequenceEqual(result).Should().BeTrue();
    }

    private static TResult AverageByIndex<TSource, TResult>(IEnumerable<TSource> collection, Func<TSource, TResult> prop)
    {
        IEnumerable<TSource> properties = collection.OrderBy<TSource, TResult>(prop);
        int index = properties.Count() / 2;
        TSource avarage = properties.Skip(index).Take(1).First();
        return prop(avarage);
    }

    private static List<Foo<T>> CreateList<T>()
    {
        var genericType = typeof(List<>).MakeGenericType(typeof(Foo<T>));
        var list = (List<Foo<T>>)Activator.CreateInstance(genericType);

        foreach (T item in FakeData.TenValues<T>())
        {
            list.Add(new Foo<T>() { Id = item });
        }

        return list;
    }
}

#region Foo class
public class Foo<T> : IEntity<T>
{
    public T Id { get; set; }

    public static Func<T, Func<Foo<T>, bool>> Filter(Func<T, Func<Foo<T>, bool>> filter)
    {
        return filter;
    }
}
#endregion

}

iarovyi commented 8 years ago

using FluentAssertions; using NUnit.Framework; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Ubs.Raws.Domain;

namespace Ubs.Raws.Expressions.Tests.Extensions { [TestFixture(typeof(int))] [TestFixture(typeof(int?))] [TestFixture(typeof(float))] [TestFixture(typeof(float?))] [TestFixture(typeof(decimal))] [TestFixture(typeof(decimal?))] [TestFixture(typeof(double))] [TestFixture(typeof(double?))] [TestFixture(typeof(long))] [TestFixture(typeof(long?))] [TestFixture(typeof(DateTime))] [TestFixture(typeof(DateTime?))] [TestFixture(typeof(TimeSpan))] [TestFixture(typeof(TimeSpan?))] [TestFixture(typeof(string))] public class MultiColumnFilteringExtensionsTests { private IEnumerable FilterTypes { get { yield return new TestCaseData(FilterType.Equals, Foo<T, T>.Filter((v) => f => f.Id.Equals(v))); yield return new TestCaseData(FilterType.NotEquals, Foo<T, T>.Filter((v) => f => !f.Id.Equals(v)));

            yield return new TestCaseData(FilterType.Contains, Foo<T, T>.Filter((v) => f => f.Id.ToString().Contains(v.ToString())));
            yield return new TestCaseData(FilterType.StartsWidth, Foo<T, T>.Filter((v) => f => f.Id.ToString().StartsWith(v.ToString())));
            yield return new TestCaseData(FilterType.EndsWith, Foo<T, T>.Filter((v) => f => f.Id.ToString().EndsWith(v.ToString())));

            //TODO: remove this condition
            if (typeof(T) != typeof(string))
            {
                yield return new TestCaseData(FilterType.GreaterThan, Foo<T, T>.Filter((v) => f => Operators<T>.GreaterThen(f.Id, v)));
                yield return new TestCaseData(FilterType.GreaterThanOrEqual, Foo<T, T>.Filter((v) => f => Operators<T>.GreaterThenOrEqual(f.Id, v)));
                yield return new TestCaseData(FilterType.LessThan, Foo<T, T>.Filter((v) => f => Operators<T>.LessThen(f.Id, v)));
                yield return new TestCaseData(FilterType.LessThanOrEqual, Foo<T, T>.Filter((v) => f => Operators<T>.LessThanOrEqual(f.Id, v)));
            }
        }
    }

    [Test]
    public void ToOrder_With_Two_Columns_Desc_Then_Desc()
    {
        //Assign
        var orders = new List<PropertyOrder>()
        {
            new PropertyOrder("Id", false),
            new PropertyOrder("Prop2", false)
        };
        List<Foo<T, T>> data = CreateList<T, T>();
        List<Foo<T, T>> expected = data.AsQueryable().OrderByDescending(f => f.Id).ThenByDescending(f => f.Prop2).ToList();

        //Act
        var result = data.AsQueryable().OrderBy<Foo<T, T>>(orders).ToList();

        //Assert
        expected.SequenceEqual(result).Should().BeTrue();
    }

    [Test]
    public void ToOrder_With_Two_Columns_Asc_Then_Asc()
    {
        //Assign
        var orders = new List<PropertyOrder>()
        {
            new PropertyOrder("Id", true),
            new PropertyOrder("Prop2", true)
        };
        List<Foo<T, T>> data = CreateList<T, T>();
        List<Foo<T, T>> expected = data.AsQueryable().OrderBy(f => f.Id).ThenBy(f => f.Prop2).ToList();

        //Act
        var result = data.AsQueryable().OrderBy<Foo<T, T>>(orders).ToList();

        //Assert
        expected.SequenceEqual(result).Should().BeTrue();
    }

    [Test]
    public void ToOrder_With_Two_Columns_Asc_Then_Desc()
    {
        //Assign
        var orders = new List<PropertyOrder>()
        {
            new PropertyOrder("Id", true),
            new PropertyOrder("Prop2", false)
        };
        List<Foo<T, T>> data = CreateList<T, T>();
        List<Foo<T, T>> expected = data.AsQueryable().OrderBy(f => f.Id).ThenByDescending(f => f.Prop2).ToList();

        //Act
        var result = data.AsQueryable().OrderBy<Foo<T, T>>(orders).ToList();

        //Assert
        expected.SequenceEqual(result).Should().BeTrue();
    }

    [Test]
    [TestCaseSource("FilterTypes")]
    public void ToFiltered_Filters_With_DuplicatedFilter(FilterType type, Func<T, Func<Foo<T, T>, bool>> filterSource)
    {
        //Assign
        List<Foo<T, T>> data = CreateList<T, T>();
        T average = AverageByIndex(data, f => f.Id);
        List<Foo<T, T>> expected = data.AsQueryable().Where(filterSource(average)).Where(filterSource(average)).ToList();
        var filters = new List<PropertyFilter>()
        {
            new PropertyFilter("Id", type, average),
            new PropertyFilter("Id", type, average),
        };

        //Act
        var result = data.AsQueryable().Where<Foo<T, T>>(filters).ToList();

        //Assert
        expected.SequenceEqual(result).Should().BeTrue();
    }

    private static TResult AverageByIndex<TSource, TResult>(IEnumerable<TSource> collection, Func<TSource, TResult> prop)
    {
        IEnumerable<TSource> properties = collection.OrderBy<TSource, TResult>(prop);
        int index = properties.Count() / 2;
        TSource avarage = properties.Skip(index).Take(1).First();
        return prop(avarage);
    }

    private static List<Foo<T, TProp2>> CreateList<T, TProp2>()
    {
        IList<T> prop1Data = FakeData.TenValues<T>();
        IList<TProp2> prop2Data = FakeData.TenValues<TProp2>();
        var genericType = typeof(List<>).MakeGenericType(typeof(Foo<T, TProp2>));
        var list = (List<Foo<T, TProp2>>)Activator.CreateInstance(genericType);

        for (int i = 0; i < 10; i++)
        {
            list.Add(new Foo<T, TProp2>()
            {
                Id = prop1Data[i],
                Prop2 = prop2Data[i]
            });
        }

        return list;
    }
}

public class Foo<T, TProp2> : IEntity<T>
{
    public T Id { get; set; }

    public TProp2 Prop2 { get; set; }

    public static Func<T, Func<Foo<T, TProp2>, bool>> Filter(Func<T, Func<Foo<T, TProp2>, bool>> filter)
    {
        return filter;
    }
}

}

iarovyi commented 8 years ago

public class TestEntity : IEntity { public virtual int Id { get; set; }

    public virtual int Int { get; set; }
    public virtual int? IntNullable { get; set; }
    public virtual float Float { get; set; }
    public virtual float? FloatNullable { get; set; }
    public virtual decimal Decimal { get; set; }
    public virtual decimal? DecimalNullable { get; set; }
    public virtual double DoubleProp { get; set; }
    public virtual double? DoubleNullable { get; set; }
    public virtual long Long { get; set; }
    public virtual long? LongNullable { get; set; }
    public virtual DateTime DateTime { get; set; }
    public virtual DateTime? DateTimeNullable { get; set; }
    public virtual TimeSpan TimeSpan { get; set; }
    public virtual TimeSpan? TimeSpanNullable { get; set; }
    public virtual string String { get; set; }
}
iarovyi commented 8 years ago

public static class Operators { public static readonly Func<T, T, bool> Equal; public static readonly Func<T, T, bool> NotEqual; public static readonly Func<T, T, bool> LessThen; public static readonly Func<T, T, bool> LessThanOrEqual; public static readonly Func<T, T, bool> GreaterThen; public static readonly Func<T, T, bool> GreaterThenOrEqual;

    public static readonly Expression<Func<T, T, bool>> EqualExpression;
    public static readonly Expression<Func<T, T, bool>> NotEqualExpression;
    public static readonly Expression<Func<T, T, bool>> LessThenExpression;
    public static readonly Expression<Func<T, T, bool>> LessThanOrEqualExpression;
    public static readonly Expression<Func<T, T, bool>> GreaterThenExpression;
    public static readonly Expression<Func<T, T, bool>> GreaterThenOrEqualExpression;

    static Operators()
    {
        var par1 = Expression.Parameter(typeof(T));
        var par2 = Expression.Parameter(typeof(T));

        var equals = Expression.Equal(par1, par2);
        EqualExpression = Expression.Lambda<Func<T, T, bool>>(equals, par1, par2);
        Equal = EqualExpression.Compile();

        var notEqual = Expression.NotEqual(par1, par2);
        NotEqualExpression = Expression.Lambda<Func<T, T, bool>>(notEqual, par1, par2);
        NotEqual = NotEqualExpression.Compile();

        var lessThen = Expression.LessThan(par1, par2);
        LessThenExpression = Expression.Lambda<Func<T, T, bool>>(lessThen, par1, par2);
        LessThen = LessThenExpression.Compile();

        var lessThanOrEqual = Expression.LessThanOrEqual(par1, par2);
        LessThanOrEqualExpression = Expression.Lambda<Func<T, T, bool>>(lessThanOrEqual, par1, par2);
        LessThanOrEqual = LessThanOrEqualExpression.Compile();

        var greaterThan = Expression.GreaterThan(par1, par2);
        GreaterThenExpression = Expression.Lambda<Func<T, T, bool>>(greaterThan, par1, par2);
        GreaterThen = GreaterThenExpression.Compile();

        var greaterThanOrEqual = Expression.GreaterThanOrEqual(par1, par2);
        GreaterThenOrEqualExpression = Expression.Lambda<Func<T, T, bool>>(greaterThanOrEqual, par1, par2);
        GreaterThenOrEqual = GreaterThenOrEqualExpression.Compile();
    }
}

public static class StringMethods<T>
{
    public static readonly Expression<Func<T, T, bool>> Contains;
    public static readonly Expression<Func<T, T, bool>> StartsWith;
    public static readonly Expression<Func<T, T, bool>> EndsWith;

    static StringMethods()
    {
        Contains =   (t1, t2) => t1.ToString().Contains(t2.ToString());
        StartsWith = (t1, t2) => t1.ToString().StartsWith(t2.ToString());
        EndsWith =   (t1, t2) => t1.ToString().EndsWith(t2.ToString());
    }
}
iarovyi commented 8 years ago

using NUnit.Framework; using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text;

namespace Ubs.Raws.Expressions.Tests { [TestFixture] public class PredicateBuilderTests { private Foo _foo;

    public static IEnumerable OneArgumentTestCases
    {
        get
        {
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("x"))).Returns(false);
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("Ja"))).Returns(true);
        }
    }

    public static IEnumerable AndTestCases
    {
        get
        {
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("x")), Foo.Expr(f => f.Name.Contains("y"))).Returns(false);
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("x")), Foo.Expr(f => f.Name.Contains("Ja"))).Returns(false);
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("Ja")), Foo.Expr(f => f.Name.Contains("ck"))).Returns(true);
        }
    }

    public static IEnumerable OrTestCases
    {
        get
        {
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("x")), Foo.Expr(f => f.Name.Contains("y"))).Returns(false);
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("x")), Foo.Expr(f => f.Name.Contains("Ja"))).Returns(true);
            yield return new TestCaseData(Foo.Expr(f => f.Name.Contains("Ja")), Foo.Expr(f => f.Name.Contains("ck"))).Returns(true);
        }
    }

    [SetUp]
    public void SetUp()
    {
        _foo = new Foo() { Name = "Jack" };
    }

    [Test]
    [TestCaseSource("AndTestCases")]
    public bool PredicateBuilder_Add_Is_Correct(Expression<Func<Foo, bool>> expr1, Expression<Func<Foo, bool>> expr2)
    {
        //Act
        return expr1.And(expr2).Compile()(_foo);
    }

    [Test]
    [TestCaseSource("OrTestCases")]
    public bool PredicateBuilder_Or_Is_Correct(Expression<Func<Foo, bool>> expr1, Expression<Func<Foo, bool>> expr2)
    {
        //Act
        return expr1.Or(expr2).Compile()(_foo);
    }

    [Test]
    [TestCaseSource("OrTestCases")]
    public bool PredicateBuilder_ToOr_Is_Correct(Expression<Func<Foo, bool>> expr1, Expression<Func<Foo, bool>> expr2)
    {
        //Assign
        var expressions = new List<Expression<Func<Foo, bool>>>() { expr1, expr2 };

        //Act
        return expressions.ToOr().Compile()(_foo);
    }

    [Test]
    [TestCaseSource("AndTestCases")]
    public bool PredicateBuilder_ToAnd_Is_Correct(Expression<Func<Foo, bool>> expr1, Expression<Func<Foo, bool>> expr2)
    {
        //Assign
        var expressions = new List<Expression<Func<Foo, bool>>>() { expr1, expr2 };

        //Act
        return expressions.ToAnd().Compile()(_foo);
    }

    [Test]
    [TestCaseSource("OneArgumentTestCases")]
    public bool PredicateBuilder_ToOr_Is_Correct_With_One_Argument(Expression<Func<Foo, bool>> expr)
    {
        //Assign
        var expressions = new List<Expression<Func<Foo, bool>>>() { expr };

        //Act
        return expressions.ToOr().Compile()(_foo);
    }

    [Test]
    [TestCaseSource("OneArgumentTestCases")]
    public bool PredicateBuilder_ToAnd_Is_Correct_With_One_Argument(Expression<Func<Foo, bool>> expr)
    {
        //Assign
        var expressions = new List<Expression<Func<Foo, bool>>>() { expr };

        //Act
        return expressions.ToAnd().Compile()(_foo);
    }

    public class Foo
    {
        public string Name { get; set; }

        public static Expression<Func<Foo, bool>> Expr(Expression<Func<Foo, bool>> expr)
        {
            return expr;
        }
    }
}

}

iarovyi commented 8 years ago

required: 'Пожалуйста, заполните это поле.', min: 'Пожалуйста, введите число большее или равное {0}.', max: 'Пожалуйста, введите число меньшее или равное {0}.', minLength: 'Пожалуйста, введите по крайней мере {0} символов.', maxLength: 'Пожалуйста, введите не больше чем {0} символов.', pattern: 'Пожалуйста, проверьте это поле.', step: 'Значение должно быть кратным {0}', email: 'Пожалуйста, укажите здесь правильный адрес электронной почты', date: 'Пожалуйста, введите правильную дату', dateISO: 'Пожалуйста, введите правильную дату в формате ISO', number: 'Пожалуйста, введите число', digit: 'Пожалуйста, введите цифры', phoneUS: 'Пожалуйста, укажите правильный телефонный номер', equal: 'Значения должны быть равны', notEqual: 'Пожалуйста, выберите другое значение.',

unique: 'Пожалуйста, укажите уникальное значение.'

required: 'Калі ласка, запоўніце гэтае поле.', min: 'Калі ласка, увядзіце лік большая ці роўнае {0}.', max: 'Калі ласка, увядзіце лік меншае або роўнае {0}.', minLength: 'Калі ласка, увядзіце прынамсі {0} знакаў.', maxLength: 'Калі ласка, увядзіце не болей чым {0} знакаў.', pattern: 'Калі ласка, праверце гэта поле.', step: 'Значэнне павінна быць кратным {0}', email: 'Калі ласка, пакажыце тут правільны адрас электроннай пошты', date: 'Калі ласка, увядзіце правільную дату', dateISO: 'Калі ласка, увядзіце правільную дату ў фармаце ISO', number: 'Калі ласка, увядзіце лік', digit: 'Калі ласка, увядзіце лічбы', phoneUS: 'Калі ласка, пакажыце правільны тэлефонны нумар', equal: 'Значэння павінны быць роўныя', notEqual: 'Калі ласка, абярыце іншае значэнне.', unique: 'Калі ласка, пакажыце унікальнае значэнне.'

iarovyi commented 8 years ago

define('navigation', ['exports'], function (exports) {

//TODO: add also this logic on url navigation
var handlers = [],
    params = {};

function applyParams(url) {
    var reg = url;
    $.each(params, function (key, value) { reg = reg.replace('{' + key + '}', value); })
    return reg;
}

function update() {
    $.each(handlers, function (i, handler) {
        var isExecuted = false;

        $.each(urls = $.isArray(handler.url) ? handler.url : [handler.url], function (j, url) {
            var reg = new RegExp(applyParams(url), 'i')
            if (reg.test(location.href)) {
                var handlerFunc = handler.handler;
                if ($.isFunction(handlerFunc)) {
                    try {
                        handlerFunc(location.href);
                    }
                    catch (e){
                        console.error('Error during module initialization', e);
                    }
                    finally {
                        isExecuted = true;
                        return false;
                    }
                } else {
                    console.error('handler is not a function for url like ' + url);
                }
            }
        });

        if (isExecuted) {
            return false;
        }
    });
}

exports.start = update;
exports.withParams = function(navagationParams){
    $.extend(params, navagationParams);
    return this;
};
exports.when = function (url, handler) {
    if (!handler) {
        console.error("navigation: empty action was supplies for url like " + url);
    }

    handlers.push({ url: url, handler: handler });
    return this;
}

});

iarovyi commented 8 years ago

большае по крайней мере - сразу хз как перевести

iarovyi commented 8 years ago

"по крайней мере"

iarovyi commented 8 years ago

min: 'Калі ласка, увядзіце лік большая ці роўнае {0}.'