announce("Start $start_time for all records");
}
+# Fetch leader/008 values for authority records. Filter out any whose
+# 008 14 or 15 field are not appropriate for the requested bib tag.
+# https://www.loc.gov/marc/authority/ad008.html
+sub authority_leaders_008_14_15 {
+ my ($e, $bib_tag, $auth_ids) = @_;
+
+ my $auth_leaders = $e->json_query({
+ select => {afr => ['record', 'value']},
+ from => 'afr',
+ where => {'+afr' => {tag => '008', record => $auth_ids}}
+ });
+
+ my $index;
+ $index = 14 if $bib_tag =~ /^[17]/; # author/name record
+ $index = 15 if $bib_tag =~ /^6/; # subject record
+
+ # avoid checking any other types of authority records.
+ return $auth_leaders unless $index;
+
+ my @keepers;
+ for my $leader (@$auth_leaders) {
+ my $value = $leader->{value} || '';
+ if (substr($value, $index, 1) eq 'a') {
+ push(@keepers, $leader);
+ } else {
+ announce("Skipping authority record ".$leader->{record}.
+ " on bib $bib_tag match; 008/#14|#15 not appropriate");
+ }
+ }
+
+ return \@keepers;
+}
+
# given a set of authority record ID's and a controlled bib field,
# returns the ID of the first authority record in the set that
# matches the thesaurus spec of the bib record.
sub find_matching_auth_for_thesaurus {
- my ($e, $bib_field, $auth_ids) = @_;
+ my ($e, $bib_field, $auth_leaders) = @_;
# bib field thesaurus spec
my $cfield_ind2 = $bib_field->indicator(2);
"remapped to ind2 value '$cfield_ind2'");
}
- my $auth_leaders = $e->json_query({
- select => {afr => ['record', 'value']},
- from => 'afr',
- where => {'+afr' => {tag => '008', record => $auth_ids}}
- });
-
my $authz_found = undef;
for my $leader (@$auth_leaders) {
my $value = $leader->{value};
# Find the best authority record to use for linking.
+ my $auth_leaders;
+ if ($bib_field->tag =~ /^[167]/) {
+ # For 1XX, 6XX, and 7XX bib fields, only link to
+ # authority records whose leader/008 positions
+ # 14 and 15 are coded to allow use as a name/author
+ # or subject record, depending.
+
+ $auth_leaders = authority_leaders_008_14_15(
+ $e, $bib_field->tag, $validates);
+
+ $validates = [map {$_->{record}} @$auth_leaders];
+ }
+
my $auth_id;
if ($bib_field->tag() =~ /^65[015]/) {
# validation API search call above.
$auth_id = find_matching_auth_for_thesaurus(
- $e, $bib_field, $validates) || '';
+ $e, $bib_field, $auth_leaders) || '';
} else {
+
# For all other controlled fields, use the first
# authority record in the result set.
$auth_id = $validates->[0];