示例#1
0
        public VCALENDAR RandomlySchedule(VCALENDAR calendar, IEnumerable<VEVENT> events)
        {
            var max = events.Count();
            var evs = events as IList<VEVENT> ?? events.ToList();

            calendar.Events.AddRange(Pick<VEVENT>.UniqueRandomList(With.Between(1, max)).From(evs));
            return calendar;
        }
 public VCALENDAR Hydrate(VCALENDAR dry)
 {
     if (dry != null)
     {
         var revents = redis.As<REL_CALENDARS_EVENTS>().GetAll()
             .Where(x => x.CalendarId == dry.Id);
         if (!revents.NullOrEmpty())
         {
             var keys = revents.Select(x => x.EventId).ToList();
             var events = eventrepository.FindAll(keys);
             dry.Events.MergeRange(events);
         }
     }
     return dry;
 }
        /// <summary>
        /// Populates a sparse calendar entity with details from its consitutent entities
        /// </summary>
        /// <param name="dry">The sparse calendar entity to be populated</param>
        /// <returns>
        /// The populated calendar entity
        /// </returns>
        public VCALENDAR Hydrate(VCALENDAR dry)
        {
            using (var db = factory.OpenDbConnection())
            {
                var okey = db.SelectParam<VCALENDAR, Guid>(q => q.Id, p => p.Id == dry.Id).FirstOrDefault();
                if (okey != Guid.Empty)
                {
                    var revents = db.Select<REL_CALENDARS_EVENTS>(q => q.CalendarId == okey);
                    if (!revents.NullOrEmpty())
                    {
                        var events = eventrepository.FindAll(revents.Select(x => x.EventId).ToList());
                        dry.Events.MergeRange(eventrepository.HydrateAll(events));
                    }
                }

                return dry; 
            }
        }
 public VCALENDAR Dehydrate(VCALENDAR full)
 {
     throw new NotImplementedException();
 }
 public VCALENDAR Hydrate(VCALENDAR dry)
 {
     throw new NotImplementedException();
 }
 public void Patch(VCALENDAR source, IEnumerable<string> fields, IEnumerable<Guid> keys = null)
 {
     throw new NotImplementedException();
 }
 public void Save(VCALENDAR entity)
 {
     throw new NotImplementedException();
 }
        /// <summary> Patches the given request.</summary>
        /// <exception cref="ArgumentNullException">Thrown when one or more required arguments are null.</exception>
        /// <exception cref="InvalidOperationException"> Thrown when the requested operation is invalid.</exception>
        /// <exception cref="ApplicationException"> Thrown when an Application error condition occurs.</exception>
        /// <param name="request"> The request to patch iCalendar instances.</param>
        public void Post(PatchCalendars request)
        {
            try
            {
                var source = new VCALENDAR
                {
                    ProdId = request.ProductId,
                    Calscale = request.Scale,
                    Version = request.Version,
                    Method = request.Method,
                    Events = request.Events,
                    ToDos = request.ToDos,
                    FreeBusies = request.FreeBusies,
                    Journals = request.Journals,
                    TimeZones = request.TimeZones,
                };

                var fields = new List<string>();
                if (!string.IsNullOrEmpty(source.ProdId) || !string.IsNullOrWhiteSpace(source.ProdId))
                    fields.Add("ProdId");
                if (source.Calscale != default(CALSCALE)) fields.Add("Calscale");
                if (source.Method != default(METHOD)) fields.Add("Method");
                if (!source.Events.NullOrEmpty()) fields.Add("Events");
                if (!source.ToDos.NullOrEmpty()) fields.Add("ToDos");
                if (!source.FreeBusies.NullOrEmpty()) fields.Add("FreeBusies");
                if (!source.Journals.NullOrEmpty()) fields.Add("Journals");
                if (!source.TimeZones.NullOrEmpty()) fields.Add("TimeZones");

                var calendarIds = !request.CalendarIds.NullOrEmpty()
                    ? request.CalendarIds.Distinct()
                    : null;

                repository.Patch(source, fields, calendarIds);

                var key = keyBuilder.Build(request, x => calendarIds).ToString();
                RequestContext.RemoveFromCache(Cache, key, nullkey);

            }
            catch (ArgumentNullException ex)
            {
                logger.Error(ex.ToString());
                throw;
            }
            catch (InvalidOperationException ex)
            {
                logger.Error(ex.ToString());
                throw;
            }
            catch (ApplicationException ex)
            {
                logger.Error(ex.ToString());
                throw;
            }
            catch (Exception ex)
            {
                logger.Error(ex.ToString()); throw;
            }
        }
        /// <summary> Patches an iCalendar instance in the service repository.</summary>
        /// <exception cref="InvalidOperationException"> Thrown when the requested operation is invalid.</exception>
        /// <exception cref="ApplicationException"> Thrown when an Application error condition occurs.</exception>
        /// <param name="request"> The request to patch an iCalendar instance</param>
        public void Post(PatchCalendar request)
        {
            try
            {
                var source = new VCALENDAR
                {
                    ProdId = request.ProductId,
                    Calscale = request.Scale,
                    Version = request.Version,
                    Method = request.Method,
                    Events = request.Events,
                    ToDos = request.ToDos,
                    FreeBusies = request.FreeBusies,
                    Journals = request.Journals,
                    TimeZones = request.TimeZones,
                };

                var fields = new List<string>();
                if (!string.IsNullOrEmpty(source.ProdId) || !string.IsNullOrEmpty(source.ProdId))
                    fields.Add("ProdId");
                if (source.Calscale != CALSCALE.NONE) fields.Add("Calscale");
                if (source.Method != METHOD.NONE) fields.Add("Method");
                if (!source.Events.NullOrEmpty()) fields.Add("Events");
                if (!source.ToDos.NullOrEmpty()) fields.Add("ToDos");
                if (!source.FreeBusies.NullOrEmpty()) fields.Add("FreeBusies");
                if (!source.Journals.NullOrEmpty()) fields.Add("Journals");
                if (!source.TimeZones.NullOrEmpty()) fields.Add("TimeZones");

                repository.Patch(source, fields, request.CalendarId.ToSingleton());

                var key = keyBuilder.Build(request, x => x.CalendarId).ToString();
                RequestContext.RemoveFromCache(Cache, key);

            }
            catch (InvalidOperationException ex)
            {
                logger.Error(ex.ToString());
                throw;
            }
            catch (ApplicationException ex)
            {
                logger.Error(ex.ToString());
                throw;
            }
            catch (Exception ex)
            {
                logger.Error(ex.ToString()); 
                throw;
            }
        }
 public VCALENDAR Dehydrate(VCALENDAR full)
 {
     var dry = full;
     if (!dry.Events.NullOrEmpty()) dry.Events.Clear();
     if (!dry.ToDos.NullOrEmpty()) dry.ToDos.Clear();
     if (!dry.FreeBusies.NullOrEmpty()) dry.FreeBusies.Clear();
     if (!dry.Journals.NullOrEmpty()) dry.Journals.Clear();
     if (!dry.TimeZones.NullOrEmpty()) dry.TimeZones.Clear();
     return dry;
 }
        public void Patch(VCALENDAR source, IEnumerable<string> fields, IEnumerable<Guid> keys = null)
        {
            #region construct anonymous fields using expression lambdas

            var selection = fields as IList<string> ?? fields.ToList();

            Expression<Func<VCALENDAR, object>> primitives = x => new
            {
                x.ProdId,
                x.Method,
                x.Calscale,
                x.Version
            };

            Expression<Func<VCALENDAR, object>> relations = x => new
            {
                x.Events,
                x.ToDos,
                x.FreeBusies,
                x.Journals,
                x.TimeZones,
            };

            //4. Get list of selected relationals
            var srelation = relations.GetMemberNames().Intersect(selection);

            //5. Get list of selected primitives
            var sprimitives = primitives.GetMemberNames().Intersect(selection);

            #endregion construct anonymous fields using expression lambdas

            var cclient = redis.As<VCALENDAR>();
            var okeys = cclient.GetAllKeys().ToArray();
            if (!okeys.NullOrEmpty()) redis.Watch(okeys);

            #region save (insert or update) relational attributes

            if (!srelation.NullOrEmpty())
            {
                Expression<Func<VCALENDAR, object>> eventsexr = y => y.Events;
                if (selection.Contains(eventsexr.GetMemberName()))
                {
                    var events = source.Events;
                    manager.ExecTrans(transaction =>
                    {
                        var orevents = redis.As<REL_CALENDARS_EVENTS>().GetAll().Where(x => keys.Contains(x.CalendarId));
                        if (!events.NullOrEmpty())
                        {
                            eventrepository.SaveAll(events.Distinct());
                            var revents = keys.SelectMany(x => events.Select(y => new REL_CALENDARS_EVENTS
                            {
                                Id = keygenerator.GetNext(),
                                CalendarId = x,
                                EventId = y.Id
                            }));

                            redis.MergeAll(revents, orevents, transaction);
                        }
                        else redis.RemoveAll(orevents, transaction);
                    });
                }
            }

            #endregion save (insert or update) relational attributes

            #region update-only non-relational attributes

            if (!sprimitives.NullOrEmpty())
            {
                Expression<Func<VCALENDAR, object>> prodexpr = x => x.ProdId;
                Expression<Func<VCALENDAR, object>> versionexpr = x => x.Version;
                Expression<Func<VCALENDAR, object>> scaleexpr = x => x.Calscale;
                Expression<Func<VCALENDAR, object>> methodexpr = x => x.Method;

                var entities = cclient.GetByIds(keys).ToList();
                manager.ExecTrans(transaction =>
                {
                    entities.ForEach(x =>
                    {
                        if (selection.Contains(prodexpr.GetMemberName())) x.ProdId = source.ProdId;
                        if (selection.Contains(versionexpr.GetMemberName())) x.Version = source.Version;
                        if (selection.Contains(scaleexpr.GetMemberName())) x.Calscale = source.Calscale;
                        if (selection.Contains(methodexpr.GetMemberName())) x.Method = source.Method;
                    });
                    transaction.QueueCommand(x => x.StoreAll(DehydrateAll(entities)));
                });
            }

            #endregion update-only non-relational attributes
        }
        public void Save(VCALENDAR entity)
        {
            var keys = redis.As<VCALENDAR>().GetAllKeys();
            if (!keys.NullOrEmpty()) redis.Watch(keys.ToArray());
            manager.ExecTrans(transaction =>
            {
                var orevents = redis.As<REL_CALENDARS_EVENTS>().GetAll().Where(x => x.CalendarId == entity.Id);

                if (!entity.Events.NullOrEmpty())
                {
                    eventrepository.SaveAll(entity.Events.Distinct());
                    var revents = entity.Events.Select(x => new REL_CALENDARS_EVENTS
                    {
                        Id = keygenerator.GetNext(),
                        CalendarId = entity.Id,
                        EventId = x.Id
                    });

                    redis.MergeAll(revents, orevents, transaction);
                }
                else redis.RemoveAll(orevents, transaction);

                transaction.QueueCommand(x => x.Store(Dehydrate(entity)));
            });
        }
        /// <summary>
        /// Patches fields of an entity in the repository
        /// </summary>
        /// <param name="source">The source containing patch details</param>
        /// <param name="fields">Specfies which fields are used for the patching. The fields are specified in an anonymous variable</param>
        /// <param name="keys">Filters the entities to patch by keys. No filter implies all entities are patched</param>
        public void Patch(VCALENDAR source, IEnumerable<string> fields, IEnumerable<Guid> keys = null)
        {
            #region construct anonymous fields using expression lambdas

            Expression<Func<VCALENDAR, object>> primitives = x => new
            {
                x.Version,
                x.Method,
                x.Calscale
            };

            Expression<Func<VCALENDAR, object>> relations = x => new
            {
                x.Events,
                x.ToDos,
                x.FreeBusies,
                x.Journals,
                x.TimeZones,
            };

            var selection = fields as IList<string> ?? fields.ToList();

            //4. Get list of selected relationals
            var srelation = relations.GetMemberNames().Intersect(selection, StringComparer.OrdinalIgnoreCase);

            //5. Get list of selected primitives
            var sprimitives = primitives.GetMemberNames().Intersect(selection, StringComparer.OrdinalIgnoreCase);

            #endregion construct anonymous fields using expression lambdas

            using (var db = factory.OpenDbConnection())
            {
                using (var transaction = db.BeginTransaction())
                {
                    try
                    {
                        var okeys = (!keys.NullOrEmpty())
                            ? db.SelectParam<VCALENDAR, Guid>(q => q.Id, p => Sql.In(p.Id, keys))
                            : db.SelectParam<VCALENDAR, Guid>(q => q.Id);
                        if (!srelation.NullOrEmpty())
                        {
                            Expression<Func<VCALENDAR, object>> eventsexpr = y => y.Events;
                            if (selection.Contains(eventsexpr.GetMemberName()))
                            {
                                eventrepository.SaveAll(source.Events.Distinct());
                                var orevents = db.Select<REL_CALENDARS_EVENTS>(q => Sql.In(q.CalendarId, okeys));
                                if (!source.Events.NullOrEmpty())
                                {
                                    var revents =
                                        okeys.SelectMany(x => source.Events.Select(y => new REL_CALENDARS_EVENTS
                                        {
                                            Id = keygenerator.GetNext(),
                                            CalendarId = x,
                                            EventId = y.Id
                                        }));
                                    db.RemoveAll(orevents, transaction);
                                    db.SaveAll(revents, transaction);
                                }
                                else db.RemoveAll(orevents, transaction);
                            }
                        }

                        if (sprimitives.Any())
                        {
                            var patchstr = $"f => new {{ {string.Join(", ", sprimitives.Select(x => $"f.{x}"))} }}";

                            var patchexpr = patchstr.CompileToExpressionFunc<VCALENDAR, object>(
                                CodeDomLanguage.csharp,
                                "System.dll", 
                                "System.Core.dll", 
                                typeof(CalendarWriter).Assembly.Location,
                                typeof (VCALENDAR).Assembly.Location,
                                typeof (IContainsKey<Guid>).Assembly.Location);

                            if (okeys.Any())
                                db.UpdateOnly(source, patchexpr, q => Sql.In(q.Id, okeys));
                            else
                                db.UpdateOnly(source, patchexpr);
                        }

                        transaction.Commit();
                    }
                    catch (ArgumentNullException)
                    {
                        transaction.Rollback();
                        throw;
                    }
                    catch (InvalidOperationException)
                    {
                        transaction.Rollback();
                        throw;
                    }
                    catch (ApplicationException)
                    {
                        transaction.Rollback(); throw;
                    }
                } 
            }
        }
        /// <summary>
        /// Inserts a new entity or updates an existing one in the repository
        /// </summary>
        /// <param name="entity">The entity to save</param>
        public void Save(VCALENDAR entity)
        {
            using (var db = factory.OpenDbConnection())
            {
                using (var transaction = db.BeginTransaction())
                {
                    try
                    {
                        db.Save(entity, transaction);
                        if (!entity.Events.NullOrEmpty())
                        {
                            eventrepository.SaveAll(entity.Events.Distinct());
                            var revents = entity.Events.Select(x => new REL_CALENDARS_EVENTS
                            {
                                Id = keygenerator.GetNext(),
                                CalendarId = entity.Id,
                                EventId = x.Id
                            });
                            var orevents = db.Select<REL_CALENDARS_EVENTS>(q => q.CalendarId == entity.Id);
                            db.MergeAll<REL_CALENDARS_EVENTS, Guid>(revents, orevents, transaction);
                        }

                        transaction.Commit();
                    }
                    catch (ArgumentNullException) { transaction.Rollback(); throw; }
                    catch (InvalidOperationException) { transaction.Rollback(); throw; }
                    catch (ApplicationException) { transaction.Rollback(); throw; }
                } 
            }
        }