[Rt-commit] rt branch 5.0/dont-insert-duplicate-cfs-on-queue2 created. rt-5.0.3-250-g1c0bf42d7a

BPS Git Server git at git.bestpractical.com
Tue Feb 7 18:41:39 UTC 2023


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 5.0/dont-insert-duplicate-cfs-on-queue2 has been created
        at  1c0bf42d7a59f83683d5119b2fc717c2fed0d9f6 (commit)

- Log -----------------------------------------------------------------
commit 1c0bf42d7a59f83683d5119b2fc717c2fed0d9f6
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Feb 8 00:54:05 2023 +0800

    Update failed tests as now we skip duplicated custom fields from initialdata
    
    Besides capturing the warning of "Custom field ... is already applied",
    as article's "Content" cf is not duplicated, in SQLite, when we create
    the rest article cfs like "Tags" from initialdata, they get the same ids
    they had previously, which messes up OCFV cache, so we need to clear it
    accordingly.

diff --git a/t/api/initialdata-roundtrip.t b/t/api/initialdata-roundtrip.t
index e55223acc7..78594369de 100644
--- a/t/api/initialdata-roundtrip.t
+++ b/t/api/initialdata-roundtrip.t
@@ -1069,6 +1069,7 @@ for my $test (@tests) {
             qr/^Invalid value for Name$/,
             qr/^Queue already exists$/,
             qr/^Invalid Name \(names must be unique and may not be all digits\)$/,
+            qr/^Custom field .* is already applied/,
         );
 
         # Avoid reporting this anonymous call frame as the source of the warning
@@ -1101,6 +1102,9 @@ for my $test (@tests) {
         };
     }
 
+    # SQLite reuses deleted primary ids, which could break cache
+    RT::ObjectCustomFieldValues::ClearOCFVCache() if RT->Config->Get('DatabaseType') eq 'SQLite';
+
     subtest "$name (from export-$id/initialdata.json)" => sub {
         autorollback(sub {
             $absent->(1) if $absent;

commit d136865805a43f3208b9dcdd9441958192e11751
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Wed Feb 8 00:47:49 2023 +0800

    Avoid creating duplicated custom fields from initialdata
    
    Custom fields can have duplicated names, which makes sense considering
    they can be applied to different objects. On the other hand, it's weird
    and usually unintentional to apply multiple custom fields with the same
    name to the same object.
    
    This commit detects the latter case and refuses to create duplications
    like that.

diff --git a/lib/RT/Handle.pm b/lib/RT/Handle.pm
index 5b63911441..f68e1b375f 100644
--- a/lib/RT/Handle.pm
+++ b/lib/RT/Handle.pm
@@ -1342,8 +1342,55 @@ sub InsertData {
                     $RT::Logger->error("Unable to load CF $item->{BasedOn} because no LookupType was specified.  Skipping BasedOn");
                     delete $item->{'BasedOn'};
                 }
+            }
+
+            # Check if we already have the CF applied
+            my $cfs = RT::CustomFields->new($RT::SystemUser);
+            $cfs->Limit( FIELD => 'Name',       VALUE => $item->{Name},       CASESENSITIVE => 0 );
+            $cfs->Limit( FIELD => 'LookupType', VALUE => $item->{LookupType}, CASESENSITIVE => 0 );
+
+            # Use loop here in case there are duplicated CFs in db already
+            my $skip;
+            while ( my $cf = $cfs->Next ) {
+                my $cfid = $cf->Id;
+
+                if ( $cf->IsGlobal ) {
+                    $RT::Logger->warn("Custom field $item->{Name}(#$cfid) is already applied globally, skipping");
+                    $skip ||= 1;
+                }
+                else {
+                    my $class = $cf->RecordClassFromLookupType( $item->{LookupType} );
+                    if ($class) {
+                        my $object = $class->new( RT->SystemUser );
+                        $apply_to = [$apply_to] unless ref $apply_to;
+                        my @applied;
+
+                        for my $key ( @{$apply_to} ) {
+
+                            # $key could be 0 or even undef, which means to apply globally
+                            if ($key) {
+                                if ( $object->Load($key) ) {
+                                    push @applied, $key if $cf->IsAdded( $object->Id );
+                                }
+                                else {
+                                    $RT::Logger->warn("Could not find $class $key");
+                                }
+                            }
+                        }
+                        if (@applied) {
+                            $RT::Logger->warn(
+                                sprintf(
+                                    'Custom field %s(#%d) is already applied to %s, skipping',
+                                    $item->{Name}, $cfid, join ', ', @applied
+                                )
+                            );
+                            $skip ||= 1;
+                        }
+                    }
+                }
+            }
 
-            } 
+            next if $skip;
 
             my ( $return, $msg ) = $new_entry->Create(%$item);
             unless( $return ) {

-----------------------------------------------------------------------


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list