Bug 16431: Use Koha::Cache to cache marc subfield structure
authorJonathan Druart <jonathan.druart@bugs.koha-community.org>
Tue, 3 May 2016 13:34:33 +0000 (14:34 +0100)
committerKyle M Hall <kyle@bywatersolutions.com>
Fri, 8 Jul 2016 12:44:58 +0000 (12:44 +0000)
The marc subfield structure is currently cached using a global variable
of C4::Context. The infos are retrieved every time a new context is
created.
This patch suggests to use Koha::Cache instead.

To achieve this goal, a new subroutine is created
C4::Biblio::GetMarcSubfieldStructure, it will be called from code which
needs to get the marc subfield structure. GetMarcFromKohaField,
GetMarcSubfieldStructureFromKohaField, TransformKohaToMarc and
_get_inverted_marc_field_map are modified accordingly and the cache is cleared
when the table is updated (from the 3 pl scripts modified by this patch).

The caching done in C4::Context (marcfromkohafield) is removed.

Test plan:
Play with the marc subfield structure (in the administration module),
then add and edit records and make sure everything went fine.

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Everything works as expected on my functional tests. I'm really happy to see the
patch introduces relevant tests for previously untested functions.

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
C4/AuthoritiesMarc.pm
C4/Biblio.pm
C4/Context.pm
admin/biblio_framework.pl
admin/marc_subfields_structure.pl
admin/marctagstructure.pl
t/db_dependent/Biblio.t
t/db_dependent/Items.t

index 4332c67..e14c85f 100644 (file)
@@ -88,7 +88,6 @@ sub GetAuthMARCFromKohaField {
   my $dbh=C4::Context->dbh;
   return 0, 0 unless $kohafield;
   $authtypecode="" unless $authtypecode;
-  my $marcfromkohafield;
   my $sth = $dbh->prepare("select tagfield,tagsubfield from auth_subfield_structure where kohafield= ? and authtypecode=? ");
   $sth->execute($kohafield,$authtypecode);
   my ($tagfield,$tagsubfield) = $sth->fetchrow;
index ae1f2f3..2798325 100644 (file)
@@ -1209,18 +1209,44 @@ C<$frameworkcode> is the framework code.
 
 sub GetUsedMarcStructure {
     my $frameworkcode = shift || '';
-    my $query = qq/
+    my $query = q{
         SELECT *
         FROM   marc_subfield_structure
         WHERE   tab > -1 
             AND frameworkcode = ?
         ORDER BY tagfield, tagsubfield
-    /;
+    };
     my $sth = C4::Context->dbh->prepare($query);
     $sth->execute($frameworkcode);
     return $sth->fetchall_arrayref( {} );
 }
 
+=head2 GetMarcSubfieldStructure
+
+=cut
+
+sub GetMarcSubfieldStructure {
+    my ( $frameworkcode ) = @_;
+
+    $frameworkcode //= '';
+
+    my $cache     = Koha::Cache->get_instance();
+    my $cache_key = "MarcSubfieldStructure-$frameworkcode";
+    my $cached    = $cache->get_from_cache($cache_key);
+    return $cached if $cached;
+
+    my $dbh = C4::Context->dbh;
+    my $subfield_structure = $dbh->selectall_hashref( q|
+        SELECT *
+        FROM marc_subfield_structure
+        WHERE frameworkcode = ?
+        AND kohafield > ''
+    |, 'kohafield', {}, $frameworkcode );
+
+    $cache->set_in_cache( $cache_key, $subfield_structure );
+    return $subfield_structure;
+}
+
 =head2 GetMarcFromKohaField
 
   ($MARCfield,$MARCsubfield)=GetMarcFromKohaField($kohafield,$frameworkcode);
@@ -1231,14 +1257,10 @@ for the given frameworkcode or default framework if $frameworkcode is missing
 =cut
 
 sub GetMarcFromKohaField {
-    my $kohafield = shift;
-    my $frameworkcode = shift || '';
+    my ( $kohafield, $frameworkcode ) = @_;
     return (0, undef) unless $kohafield;
-    my $relations = C4::Context->marcfromkohafield;
-    if ( my $mf = $relations->{$frameworkcode}->{$kohafield} ) {
-        return @$mf;
-    }
-    return (0, undef);
+    my $mss = GetMarcSubfieldStructure( $frameworkcode );
+    return ( $mss->{$kohafield}{tagfield}, $mss->{$kohafield}{tagsubfield} );
 }
 
 =head2 GetMarcSubfieldStructureFromKohaField
@@ -1253,24 +1275,14 @@ $frameworkcode is optional. If not given, then the default framework is used.
 =cut
 
 sub GetMarcSubfieldStructureFromKohaField {
-    my ($kohafield, $frameworkcode) = @_;
+    my ( $kohafield, $frameworkcode ) = @_;
 
-    return undef unless $kohafield;
-    $frameworkcode //= '';
+    return unless $kohafield;
 
-    my $dbh = C4::Context->dbh;
-    my $query = qq{
-        SELECT *
-        FROM marc_subfield_structure
-        WHERE kohafield = ?
-          AND frameworkcode = ?
-    };
-    my $sth = $dbh->prepare($query);
-    $sth->execute($kohafield, $frameworkcode);
-    my $result = $sth->fetchrow_hashref;
-    $sth->finish;
-
-    return $result;
+    my $mss = GetMarcSubfieldStructure( $frameworkcode );
+    return exists $mss->{$kohafield}
+        ? $mss->{$kohafield}
+        : undef;
 }
 
 =head2 GetMarcBiblio
@@ -2231,17 +2243,18 @@ sub TransformKohaToMarc {
     my $hash = shift;
     my $record = MARC::Record->new();
     SetMarcUnicodeFlag( $record, C4::Context->preference("marcflavour") );
-    my $db_to_marc = C4::Context->marcfromkohafield;
+    # FIXME Do not we want to get the marc subfield structure for the biblio framework?
+    my $mss = GetMarcSubfieldStructure();
     my $tag_hr = {};
-    while ( my ($name, $value) = each %$hash ) {
-        next unless my $dtm = $db_to_marc->{''}->{$name};
-        next unless ( scalar( @$dtm ) );
-        my ($tag, $letter) = @$dtm;
-        $tag .= '';
+    while ( my ($kohafield, $value) = each %$hash ) {
+        next unless exists $mss->{$kohafield};
+        next unless $mss->{$kohafield};
+        my $tagfield    = $mss->{$kohafield}{tagfield} . '';
+        my $tagsubfield = $mss->{$kohafield}{tagsubfield};
         foreach my $value ( split(/\s?\|\s?/, $value, -1) ) {
             next if $value eq '';
-            $tag_hr->{$tag} //= [];
-            push @{$tag_hr->{$tag}}, [($letter, $value)];
+            $tag_hr->{$tagfield} //= [];
+            push @{$tag_hr->{$tagfield}}, [($tagsubfield, $value)];
         }
     }
     foreach my $tag (sort keys %$tag_hr) {
@@ -2606,9 +2619,6 @@ sub TransformHtmlToMarc {
     return $record;
 }
 
-# cache inverted MARC field map
-our $inverted_field_map;
-
 =head2 TransformMarcToKoha
 
   $result = TransformMarcToKoha( $record, $frameworkcode )
@@ -2632,9 +2642,7 @@ sub TransformMarcToKoha {
     $limit_table = $limit_table || 0;
     $frameworkcode = '' unless defined $frameworkcode;
 
-    unless ( defined $inverted_field_map ) {
-        $inverted_field_map = _get_inverted_marc_field_map();
-    }
+    my $inverted_field_map = _get_inverted_marc_field_map($frameworkcode);
 
     my %tables = ();
     if ( defined $limit_table && $limit_table eq 'items' ) {
@@ -2648,9 +2656,9 @@ sub TransformMarcToKoha {
     # traverse through record
   MARCFIELD: foreach my $field ( $record->fields() ) {
         my $tag = $field->tag();
-        next MARCFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag};
+        next MARCFIELD unless exists $inverted_field_map->{$tag};
         if ( $field->is_control_field() ) {
-            my $kohafields = $inverted_field_map->{$frameworkcode}->{$tag}->{list};
+            my $kohafields = $inverted_field_map->{$tag}->{list};
           ENTRY: foreach my $entry ( @{$kohafields} ) {
                 my ( $subfield, $table, $column ) = @{$entry};
                 next ENTRY unless exists $tables{$table};
@@ -2668,9 +2676,9 @@ sub TransformMarcToKoha {
             # deal with subfields
           MARCSUBFIELD: foreach my $sf ( $field->subfields() ) {
                 my $code = $sf->[0];
-                next MARCSUBFIELD unless exists $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code};
+                next MARCSUBFIELD unless exists $inverted_field_map->{$tag}->{sfs}->{$code};
                 my $value = $sf->[1];
-              SFENTRY: foreach my $entry ( @{ $inverted_field_map->{$frameworkcode}->{$tag}->{sfs}->{$code} } ) {
+              SFENTRY: foreach my $entry ( @{ $inverted_field_map->{$tag}->{sfs}->{$code} } ) {
                     my ( $table, $column ) = @{$entry};
                     next SFENTRY unless exists $tables{$table};
                     my $key = _disambiguate( $table, $column );
@@ -2713,18 +2721,17 @@ sub TransformMarcToKoha {
 }
 
 sub _get_inverted_marc_field_map {
+    my ( $frameworkcode ) = @_;
     my $field_map = {};
-    my $relations = C4::Context->marcfromkohafield;
-
-    foreach my $frameworkcode ( keys %{$relations} ) {
-        foreach my $kohafield ( keys %{ $relations->{$frameworkcode} } ) {
-            next unless @{ $relations->{$frameworkcode}->{$kohafield} };    # not all columns are mapped to MARC tag & subfield
-            my $tag      = $relations->{$frameworkcode}->{$kohafield}->[0];
-            my $subfield = $relations->{$frameworkcode}->{$kohafield}->[1];
-            my ( $table, $column ) = split /[.]/, $kohafield, 2;
-            push @{ $field_map->{$frameworkcode}->{$tag}->{list} }, [ $subfield, $table, $column ];
-            push @{ $field_map->{$frameworkcode}->{$tag}->{sfs}->{$subfield} }, [ $table, $column ];
-        }
+    my $mss = GetMarcSubfieldStructure( $frameworkcode );
+
+    foreach my $kohafield ( keys %{ $mss } ) {
+        next unless exists $mss->{$kohafield};    # not all columns are mapped to MARC tag & subfield
+        my $tag      = $mss->{$kohafield}{tagfield};
+        my $subfield = $mss->{$kohafield}{tagsubfield};
+        my ( $table, $column ) = split /[.]/, $kohafield, 2;
+        push @{ $field_map->{$tag}->{list} }, [ $subfield, $table, $column ];
+        push @{ $field_map->{$tag}->{sfs}->{$subfield} }, [ $table, $column ];
     }
     return $field_map;
 }
index c80647a..1bf23c2 100644 (file)
@@ -373,7 +373,6 @@ sub new {
     return if !defined($self->{"config"});
 
     $self->{"Zconn"} = undef;    # Zebra Connections
-    $self->{"marcfromkohafield"} = undef; # the hash with relations between koha table fields and MARC field/subfield
     $self->{"userenv"} = undef;        # User env
     $self->{"activeuser"} = undef;        # current active user
     $self->{"shelves"} = undef;
@@ -931,45 +930,6 @@ sub _new_queryparser {
     return;
 }
 
-=head2 marcfromkohafield
-
-  $dbh = C4::Context->marcfromkohafield;
-
-Returns a hash with marcfromkohafield.
-
-This hash is cached for future use: if you call
-C<C4::Context-E<gt>marcfromkohafield> twice, you will get the same hash without real DB access
-
-=cut
-
-#'
-sub marcfromkohafield
-{
-    my $retval = {};
-
-    # If the hash already exists, return it.
-    return $context->{"marcfromkohafield"} if defined($context->{"marcfromkohafield"});
-
-    # No hash. Create one.
-    $context->{"marcfromkohafield"} = &_new_marcfromkohafield();
-
-    return $context->{"marcfromkohafield"};
-}
-
-# _new_marcfromkohafield
-sub _new_marcfromkohafield
-{
-    my $dbh = C4::Context->dbh;
-    my $marcfromkohafield;
-    my $sth = $dbh->prepare("select frameworkcode,kohafield,tagfield,tagsubfield from marc_subfield_structure where kohafield > ''");
-    $sth->execute;
-    while (my ($frameworkcode,$kohafield,$tagfield,$tagsubfield) = $sth->fetchrow) {
-        my $retval = {};
-        $marcfromkohafield->{$frameworkcode}->{$kohafield} = [$tagfield,$tagsubfield];
-    }
-    return $marcfromkohafield;
-}
-
 =head2 userenv
 
   C4::Context->userenv;
index 6f8fb6c..3aeb0ca 100755 (executable)
@@ -81,6 +81,7 @@ if ( $op eq 'add_form' ) {
     $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
     $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
     $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+    $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
     $op = 'list';
 } elsif ( $op eq 'delete_confirm' ) {
     my $framework = Koha::BiblioFrameworks->find($frameworkcode);
@@ -111,6 +112,7 @@ if ( $op eq 'add_form' ) {
     $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
     $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
     $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+    $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
     $op = 'list';
 }
 
index bfaa3dc..096b9ec 100755 (executable)
@@ -342,6 +342,7 @@ elsif ( $op eq 'add_validate' ) {
     $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
     $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
     $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+    $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
 
     print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&amp;frameworkcode=$frameworkcode");
     exit;
@@ -386,6 +387,7 @@ elsif ( $op eq 'delete_confirmed' ) {
     $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
     $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
     $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+    $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
     print $input->redirect("/cgi-bin/koha/admin/marc_subfields_structure.pl?tagfield=$tagfield&amp;frameworkcode=$frameworkcode");
     exit;
 
index 7298d6a..27d9592 100755 (executable)
@@ -165,6 +165,7 @@ if ($op eq 'add_form') {
         $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
         $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
         $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+        $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
     }
     print $input->redirect("/cgi-bin/koha/admin/marctagstructure.pl?searchfield=$tagfield&frameworkcode=$frameworkcode");
     exit;
@@ -192,6 +193,7 @@ if ($op eq 'add_form') {
         $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
         $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
         $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+        $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
        }
        $template->param(
           searchfield => $searchfield,
@@ -358,5 +360,6 @@ sub duplicate_framework {
     $cache->clear_from_cache("MarcStructure-0-$newframeworkcode");
     $cache->clear_from_cache("MarcStructure-1-$newframeworkcode");
     $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+    $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
 }
 
index 517c8e5..951288c 100755 (executable)
@@ -33,10 +33,63 @@ my $dbh = C4::Context->dbh;
 $dbh->{AutoCommit} = 0;
 $dbh->{RaiseError} = 1;
 
-# Mocking variables
-my $context = new Test::MockModule('C4::Context');
+subtest 'GetMarcSubfieldStructureFromKohaField' => sub {
+    plan tests => 23;
+
+    my @columns = qw(
+        tagfield tagsubfield liblibrarian libopac repeatable mandatory kohafield tab
+        authorised_value authtypecode value_builder isurl hidden frameworkcode
+        seealso link defaultvalue maxlength
+    );
+
+    # biblio.biblionumber must be mapped so this should return something
+    my $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('biblio.biblionumber', '');
+
+    ok(defined $marc_subfield_structure, "There is a result");
+    is(ref $marc_subfield_structure, "HASH", "Result is a hashref");
+    foreach my $col (@columns) {
+        ok(exists $marc_subfield_structure->{$col}, "Hashref contains key '$col'");
+    }
+    is($marc_subfield_structure->{kohafield}, 'biblio.biblionumber', "Result is the good result");
+    like($marc_subfield_structure->{tagfield}, qr/^\d{3}$/, "tagfield is a valid tagfield");
 
-mock_marcfromkohafield();
+    # foo.bar does not exist so this should return undef
+    $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('foo.bar', '');
+    is($marc_subfield_structure, undef, "invalid kohafield returns undef");
+};
+
+
+# Mocking variables
+my $biblio_module = new Test::MockModule('C4::Biblio');
+$biblio_module->mock(
+    'GetMarcSubfieldStructure',
+    sub {
+        my ($self) = shift;
+
+        if (   C4::Context->preference('marcflavour') eq 'MARC21'
+            || C4::Context->preference('marcflavour') eq 'NORMARC' ) {
+
+            return {
+                'biblio.title'                 => { tagfield => '245', tagsubfield => 'a' },
+                'biblio.biblionumber'          => { tagfield => '999', tagsubfield => 'c' },
+                'biblioitems.isbn'             => { tagfield => '020', tagsubfield => 'a' },
+                'biblioitems.issn'             => { tagfield => '022', tagsubfield => 'a' },
+                'biblioitems.biblioitemnumber' => { tagfield => '999', tagsubfield => 'd' },
+                'items.itemnumber'             => { tagfield => '952', tagsubfield => '9' },
+            };
+        } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
+
+            return {
+                'biblio.title'                 => { tagfield => '200', tagsubfield => 'a' },
+                'biblio.biblionumber'          => { tagfield => '999', tagsubfield => 'c' },
+                'biblioitems.isbn'             => { tagfield => '010', tagsubfield => 'a' },
+                'biblioitems.issn'             => { tagfield => '011', tagsubfield => 'a' },
+                'biblioitems.biblioitemnumber' => { tagfield => '090', tagsubfield => 'a' },
+                'items.itemnumber'             => { tagfield => '995', tagsubfield => '9' },
+            };
+        }
+    }
+);
 
 my $currency = new Test::MockModule('Koha::Acquisition::Currencies');
 $currency->mock(
@@ -54,10 +107,6 @@ $currency->mock(
 
 sub run_tests {
 
-    # Undef C4::Biblio::inverted_field_map to avoid problems introduced
-    # by caching in TransformMarcToKoha
-    undef $C4::Biblio::inverted_field_map;
-
     my $marcflavour = shift;
     t::lib::Mocks::mock_preference('marcflavour', $marcflavour);
 
@@ -226,39 +275,6 @@ sub run_tests {
         'Check the number of returned notes of GetMarcNotes' );
 }
 
-sub mock_marcfromkohafield {
-
-    $context->mock('marcfromkohafield',
-        sub {
-            my ( $self ) = shift;
-
-            if ( C4::Context->preference('marcflavour') eq 'MARC21' ||
-                 C4::Context->preference('marcflavour') eq 'NORMARC' ) {
-
-                return  {
-                '' => {
-                    'biblio.title' => [ '245', 'a' ],
-                    'biblio.biblionumber' => [ '999', 'c' ],
-                    'biblioitems.isbn' => [ '020', 'a' ],
-                    'biblioitems.issn' => [ '022', 'a' ],
-                    'biblioitems.biblioitemnumber' => [ '999', 'd' ]
-                    }
-                };
-            } elsif ( C4::Context->preference('marcflavour') eq 'UNIMARC' ) {
-
-                return {
-                '' => {
-                    'biblio.title' => [ '200', 'a' ],
-                    'biblio.biblionumber' => [ '999', 'c' ],
-                    'biblioitems.isbn' => [ '010', 'a' ],
-                    'biblioitems.issn' => [ '011', 'a' ],
-                    'biblioitems.biblioitemnumber' => [ '090', 'a' ]
-                    }
-                };
-            }
-        });
-}
-
 sub create_title_field {
     my ( $title, $marcflavour ) = @_;
 
@@ -307,31 +323,6 @@ subtest 'NORMARC' => sub {
     $dbh->rollback;
 };
 
-subtest 'GetMarcSubfieldStructureFromKohaField' => sub {
-    plan tests => 23;
-
-    my @columns = qw(
-        tagfield tagsubfield liblibrarian libopac repeatable mandatory kohafield tab
-        authorised_value authtypecode value_builder isurl hidden frameworkcode
-        seealso link defaultvalue maxlength
-    );
-
-    # biblio.biblionumber must be mapped so this should return something
-    my $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('biblio.biblionumber', '');
-
-    ok(defined $marc_subfield_structure, "There is a result");
-    is(ref $marc_subfield_structure, "HASH", "Result is a hashref");
-    foreach my $col (@columns) {
-        ok(exists $marc_subfield_structure->{$col}, "Hashref contains key '$col'");
-    }
-    is($marc_subfield_structure->{kohafield}, 'biblio.biblionumber', "Result is the good result");
-    like($marc_subfield_structure->{tagfield}, qr/^\d{3}$/, "tagfield is a valid tagfield");
-
-    # foo.bar does not exist so this should return undef
-    $marc_subfield_structure = GetMarcSubfieldStructureFromKohaField('foo.bar', '');
-    is($marc_subfield_structure, undef, "invalid kohafield returns undef");
-};
-
 subtest 'IsMarcStructureInternal' => sub {
     plan tests => 6;
     my $tagslib = GetMarcStructure();
index eec8fa3..b494a70 100755 (executable)
@@ -372,15 +372,19 @@ subtest 'SearchItems test' => sub {
     }
     ok($found, "item1 found");
 
-    my ($itemfield) = GetMarcFromKohaField('items.itemnumber', '');
+    my $frameworkcode = q||;
+    my ($itemfield) = GetMarcFromKohaField('items.itemnumber', $frameworkcode);
 
     # Create item subfield 'z' without link
-    $dbh->do('DELETE FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=""', undef, $itemfield);
-    $dbh->do('INSERT INTO marc_subfield_structure (tagfield, tagsubfield, frameworkcode) VALUES (?, "z", "")', undef, $itemfield);
+    $dbh->do('DELETE FROM marc_subfield_structure WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=?', undef, $itemfield, $frameworkcode);
+    $dbh->do('INSERT INTO marc_subfield_structure (tagfield, tagsubfield, frameworkcode) VALUES (?, "z", ?)', undef, $itemfield, $frameworkcode);
 
     # Clear cache
-    $C4::Context::context->{marcfromkohafield} = undef;
-    $C4::Biblio::inverted_field_map = undef;
+    my $cache = Koha::Cache->get_instance();
+    $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
+    $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
+    $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+    $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
 
     my $item3_record = new MARC::Record;
     $item3_record->append_fields(
@@ -400,12 +404,14 @@ subtest 'SearchItems test' => sub {
 
     # Link $z to items.itemnotes (and make sure there is no other subfields
     # linked to it)
-    $dbh->do('DELETE FROM marc_subfield_structure WHERE kohafield="items.itemnotes" AND frameworkcode=""', undef, $itemfield);
-    $dbh->do('UPDATE marc_subfield_structure SET kohafield="items.itemnotes" WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=""', undef, $itemfield);
+    $dbh->do('DELETE FROM marc_subfield_structure WHERE kohafield="items.itemnotes" AND frameworkcode=?', undef, $itemfield, $frameworkcode);
+    $dbh->do('UPDATE marc_subfield_structure SET kohafield="items.itemnotes" WHERE tagfield=? AND tagsubfield="z" AND frameworkcode=?', undef, $itemfield, $frameworkcode);
 
     # Clear cache
-    $C4::Context::context->{marcfromkohafield} = undef;
-    $C4::Biblio::inverted_field_map = undef;
+    $cache->clear_from_cache("MarcStructure-0-$frameworkcode");
+    $cache->clear_from_cache("MarcStructure-1-$frameworkcode");
+    $cache->clear_from_cache("default_value_for_mod_marc-$frameworkcode");
+    $cache->clear_from_cache("MarcSubfieldStructure-$frameworkcode");
 
     ModItemFromMarc($item3_record, $biblionumber, $item3_itemnumber);
 
@@ -559,10 +565,6 @@ subtest 'C4::Items::_build_default_values_for_mod_marc' => sub {
 
     $schema->storage->txn_begin();
 
-    # Clear cache
-    $C4::Context::context->{marcfromkohafield} = undef;
-    $C4::Biblio::inverted_field_map = undef;
-
     my $builder = t::lib::TestBuilder->new;
     my $framework = $builder->build({
         source => 'BiblioFramework',
@@ -642,10 +644,11 @@ subtest 'C4::Items::_build_default_values_for_mod_marc' => sub {
     |, undef, $framework->{frameworkcode} );
 
     # And make sure the caches are cleared
-    $C4::Context::context->{marcfromkohafield} = undef;
-    $C4::Biblio::inverted_field_map = undef;
-    my $cache     = Koha::Cache->get_instance();
-    $cache->clear_from_cache("default_value_for_mod_marc-" . $framework->{frameworkcode} );
+    my $cache = Koha::Cache->get_instance();
+    $cache->clear_from_cache("MarcStructure-0-" . $framework->{frameworkcode});
+    $cache->clear_from_cache("MarcStructure-1-" . $framework->{frameworkcode});
+    $cache->clear_from_cache("default_value_for_mod_marc-" . $framework->{frameworkcode});
+    $cache->clear_from_cache("MarcSubfieldStructure-" . $framework->{frameworkcode});
 
     # Update the MARC field with another value
     $item_record->delete_fields( $barcode_field );