private void OnBeforeDelete(object sender, OnBeforeDeleteEventArgs e)
        {
            // We're effectively disabled during actual deletion
            if (e.IsCommitPhase)
            {
                return;
            }

            // If we get here, we're traversing the delete graph.
            // Traversing means we're looping round doing a depth first cascade through relations, and we add each 'leaf' instance to the ordered list of objects to be deleted
            // But we're not actually goind any deleting during this phase, so we flag isHandled to block the delete at DataProvider level (means it skips the actual Delete call)
            e.IsHandled = true;

            // Initialise
            Init(e.Parameters);

            // Get the instance (e.Entity is only used to pass through the PK)
            var instance = Data.Get(e.Entity as TEntity, parameters: e.Parameters, skipSecurity: true);

            if (instance == null)
            {
                return;
            }

            // Ripple the delete through relations / subtypes
            var settings = new DataProviderDeleteSettings(e);

            settings.SkipSecurity = true;
            Ripple(instance, settings, e.Parameters);
        }
        private void Ripple(TEntity instance, DataProviderDeleteSettings settings, Parameters parameters)
        {
            // Ripple each instance precisely once per DeleteStack traversal
            // (Note that this includes subtypes instances - i.e. the entire hierarchy is rippled from root call to RippleDelete)
            if (!DeleteStack.HasBeenRippledDuringCurrentTraversal(instance))
            {
                if (!DeleteStack.IsResolved(instance))
                {
                    // Remember we've seen this instance
                    DeleteStack.AddSeenObject(instance);

                    // Count blockers before and after rippling in order to determine if instance can be added to the resolved list
                    int numBlockers = DeleteStack.BlockersDuringCurrentTraversal.Count();

                    // Call virtual Ripple
                    RippleDelete(instance, parameters, settings);

                    // no errors => Can delete this object => Add to the resolved list
                    if (numBlockers == DeleteStack.BlockersDuringCurrentTraversal.Count() &&
                        !DeleteStack.HasUnresolvedDependencies(instance))
                    {
                        DeleteStack.MarkResolved(instance);

                        // Do any deferred deletes
                        DoDeferredDeletes(parameters, settings);
                    }
                }
            }
        }
 protected void Delete <T>(T item, Parameters parameters, DataProviderDeleteSettings settings, TEntity currentInstance) where T : IDataObject
 {
     if (!DeleteStack.IsResolved(item))
     {
         var db = ApplicationSettings.Container.Resolve <IDataProvider <T> >();
         db.Delete(item, settings.SecurityFilterExpression, settings.Context, parameters, settings.SkipSecurity);
         CheckResolved(currentInstance, item);
         NeedResync = true;
     }
 }
        private void DoDeferredDeletes(Parameters parameters, DataProviderDeleteSettings settings)
        {
            if (_deferredDeleteItems.Any())
            {
                try
                {
                    foreach (var obj in _deferredDeleteItems)
                    {
                        dynamic db = ApplicationSettings.Container.Resolve <IEntityDataProvider>().GetDataProviderForEntity(obj) as IDataProvider;
                        if (db != null)
                        {
                            db.Delete(obj, settings.SecurityFilterExpression, settings.Context, parameters, settings.SkipSecurity);
                        }
                    }
                }
                catch
                {
                    _deferredDeleteItems.Clear();
                    throw;
                }
            }

            _deferredDeleteItems.Clear();
        }
        public override void RippleDelete(GOUserDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
        {
            // Set resync flag initially so that if any processing is done, it's on the latest copy of the data
            NeedResync = true;

            // GOUser.UserGroupItems (Cascade)
            {
                instance = Resync(instance);
                instance.LoadUserGroupItems(parameters, skipSecurity: true);
                foreach (var item in instance.UserGroupItems)
                {
                    this.Delete(item, parameters, settings, instance);
                }
            }
            // GOUser.UserRoleItems (Cascade)
            {
                instance = Resync(instance);
                instance.LoadUserRoleItems(parameters, skipSecurity: true);
                foreach (var item in instance.UserRoleItems)
                {
                    this.Delete(item, parameters, settings, instance);
                }
            }
            // GOUser.UserProfile (Reference)
            {
                instance = Resync(instance);
                instance.LoadUserProfile(parameters, skipSecurity: true);
                // We are the FK side entity and the PK side is optional, so no action required here (because when we're deleted, any reference(s) to UserProfile(s) is (are) deleted with us)
            }
        }
 public abstract void RippleDelete(TEntity instance, Parameters parameters, DataProviderDeleteSettings settings);
 public override void RippleDelete(GOUserGroupDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
 {
 }
Exemplo n.º 8
0
 public override void RippleDelete(PlaceToLocationDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
 {
 }
Exemplo n.º 9
0
        public override void RippleDelete(GORoleDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
        {
            // Set resync flag initially so that if any processing is done, it's on the latest copy of the data
            NeedResync = true;

            // GORole.GroupRoleItems (Cascade)
            {
                instance = Resync(instance);
                instance.LoadGroupRoleItems(parameters, skipSecurity: true);
                foreach (var item in instance.GroupRoleItems)
                {
                    this.Delete(item, parameters, settings, instance);
                }
            }
            // GORole.UserRoleItems (Cascade)
            {
                instance = Resync(instance);
                instance.LoadUserRoleItems(parameters, skipSecurity: true);
                foreach (var item in instance.UserRoleItems)
                {
                    this.Delete(item, parameters, settings, instance);
                }
            }
        }
Exemplo n.º 10
0
 public override void RippleDelete(VisitedPlaceDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
 {
 }
        public override void RippleDelete(UserProfileDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
        {
            // Set resync flag initially so that if any processing is done, it's on the latest copy of the data
            NeedResync = true;

            // UserProfile.GOUser (Reference)
            {
                instance = Resync(instance);
                instance.LoadGOUser(parameters, skipSecurity: true);

                // We are the PK side entity in a OneToOne relationship, and the FK reference to us is optional.
                // So delete can proceed, but first we need to clear down the FK reference to us.
                var item = instance.GOUser;
                if (item != null && item.UserProfile != null)
                {
                    item.UserProfile = null;
                    Save(item);
                }
            }
            // UserProfile.VisitedPlaceItems (Protected) (i.e. Unable to delete UserProfile instances because VisitedPlaceItems.UserProfile is not optional and needs to be cleared first)
            {
                instance = Resync(instance);
                instance.LoadVisitedPlaceItems(parameters, skipSecurity: true);
                AddAnyBlockages("failDeleteProtected", instance, instance.VisitedPlaceItems);
            }
        }
Exemplo n.º 12
0
        public override void RippleDelete(PlaceDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
        {
            // Set resync flag initially so that if any processing is done, it's on the latest copy of the data
            NeedResync = true;

            // Place.PlaceToLocationItems (Protected) (i.e. Unable to delete Place instances because PlaceToLocationItems.Place is not optional and needs to be cleared first)
            {
                instance = Resync(instance);
                instance.LoadPlaceToLocationItems(parameters, skipSecurity: true);
                AddAnyBlockages("failDeleteProtected", instance, instance.PlaceToLocationItems);
            }
            // Place.VisitedPlaceItems (Reference)
            {
                instance = Resync(instance);
                instance.LoadVisitedPlaceItems(parameters, skipSecurity: true);
                foreach (var item in instance.VisitedPlaceItems)
                {
                    if (item.Place != null)
                    {
                        item.Place = null;
                        Save(item);
                    }
                }
            }
        }
        public override void RippleDelete(CountryDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
        {
            // Set resync flag initially so that if any processing is done, it's on the latest copy of the data
            NeedResync = true;

            // Country.VisitedPlaceItems (Reference)
            {
                instance = Resync(instance);
                instance.LoadVisitedPlaceItems(parameters, skipSecurity: true);
                foreach (var item in instance.VisitedPlaceItems)
                {
                    if (item.Country != null)
                    {
                        item.Country = null;
                        Save(item);
                    }
                }
            }
        }
 public override void RippleDelete(GOLoginHistoryDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
 {
 }
        public override void RippleDelete(LocationDataObject instance, Parameters parameters, DataProviderDeleteSettings settings)
        {
            // Set resync flag initially so that if any processing is done, it's on the latest copy of the data
            NeedResync = true;

            // Location.PlaceToLocationItems (Protected) (i.e. Unable to delete Location instances because PlaceToLocationItems.Location is not optional and needs to be cleared first)
            {
                instance = Resync(instance);
                instance.LoadPlaceToLocationItems(parameters, skipSecurity: true);
                AddAnyBlockages("failDeleteProtected", instance, instance.PlaceToLocationItems);
            }
        }