Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Map FOLIO data to the MARC leader #1387

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions lib/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -226,4 +226,34 @@ module Constants
852 853 863 866 867 868
901 910 918 923 924 930 935 940 948 949 950 955 960 962 980 981 983 990 993 998
]

INSTANCE_TYPE_LEADER_CODE = {
'cartographic dataset' => 'e',
'cartographic image' => 'e',
'cartographic moving image' => 'e',
'cartographic tactile image' => 'e',
'cartographic tactile three-dimensional form' => 'e',
'cartographic three-dimensional form' => 'e',
'computer dataset' => 'm',
'computer program' => 'm',
'notated music' => 'c',
'performed music' => 'j',
'sounds' => 'i',
'spoken word' => 'i',
'still image' => 'k',
'tactile image' => 'k',
'tactile notated music' => 'c',
'tactile three-dimensional form' => 'r',
'text' => 'a',
'three-dimensional form' => 'r',
'three-dimensional moving image' => 'r',
'two-dimensional moving image' => 'g'
}

MODE_OF_ISSUANCE_LEADER_CODE = {
'integrating resource' => 'i',
'multipart monograph' => 'a',
'serial' => 's',
'single unit' => 'm'
}
end
8 changes: 6 additions & 2 deletions lib/folio/marc_record_instance_mapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
module Folio
# Creates a Marc Record for an Folio instance
class MarcRecordInstanceMapper
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
# rubocop:disable Metrics/AbcSize, Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/MethodLength
def self.build(instance, holdings)
MARC::Record.new.tap do |marc|
# Add what we can to the leader from FOLIO data
marc.leader[6] = Constants::INSTANCE_TYPE_LEADER_CODE[instance.dig('instanceType', 'name')] || ' '
marc.leader[7] = Constants::MODE_OF_ISSUANCE_LEADER_CODE[instance.dig('modeOfIssuance', 'name')] || ' '

marc.append(MARC::ControlField.new('001', instance['hrid']))
# mode of issuance
# identifiers
Expand Down Expand Up @@ -129,7 +133,7 @@ def self.build(instance, holdings)
# date updated
end.to_hash
end
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
# rubocop:enable Metrics/AbcSize, Metrics/BlockLength, Metrics/CyclomaticComplexity, Metrics/MethodLength

# The FOLIO data can either be a plain string (pre-Poppy) or a hash (post-Poppy)
def self.folio_value(folio_data)
Expand Down
11 changes: 9 additions & 2 deletions lib/traject/readers/folio_postgres_reader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,9 @@ def contents_sql_query(conditions, addl_from: nil)
'[]'::jsonb
END,
'administrativeNotes', '[]'::jsonb,
'notes', COALESCE((SELECT jsonb_agg(e) FROM jsonb_array_elements(vi.jsonb -> 'notes') AS e WHERE NOT COALESCE((e ->> 'staffOnly')::bool, false)), '[]'::jsonb)

'notes', COALESCE((SELECT jsonb_agg(e) FROM jsonb_array_elements(vi.jsonb -> 'notes') AS e WHERE NOT COALESCE((e ->> 'staffOnly')::bool, false)), '[]'::jsonb),
'instanceType', COALESCE(jsonb_agg(jsonb_build_object('name', it.jsonb ->> 'name')) -> 0, '{}'::jsonb),
'modeOfIssuance', COALESCE(jsonb_agg(jsonb_build_object('name', moi.jsonb ->> 'name')) -> 0, '{}'::jsonb)
),
'source_record', COALESCE(jsonb_agg(DISTINCT mr."content"), '[]'::jsonb),
'items',
Expand Down Expand Up @@ -429,6 +430,12 @@ def contents_sql_query(conditions, addl_from: nil)
-- Holdings Ill policy relation
LEFT JOIN sul_mod_inventory_storage.ill_policy ilp
ON hr.illpolicyid = ilp.id
-- Instance Type (Resource type) relation
LEFT JOIN sul_mod_inventory_storage.instance_type it
ON vi.instancetypeid = it.id
-- Mode of Issuance relation
LEFT JOIN sul_mod_inventory_storage.mode_of_issuance moi
ON vi.modeofissuanceid = moi.id
LEFT JOIN sul_mod_source_record_storage.records_lb rs
ON rs.external_id = vi.id AND rs.state = 'ACTUAL'
LEFT JOIN sul_mod_source_record_storage.marc_records_lb mr
Expand Down
72 changes: 72 additions & 0 deletions spec/lib/folio/marc_record_instance_mapper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe Folio::MarcRecordInstanceMapper do
describe '.build' do
let(:instance) do
{
'id' => '8d3623d4-60ab-4aa6-8637-1c0bf6cfb297',
'hrid' => 'in00000003052',
'notes' => [],
'title' => "Akira Kurosawa's dreams",
'series' => [],
'source' => 'FOLIO',
'editions' => [],
'subjects' => [],
'languages' => [],
'identifiers' => [],
'publication' => [],
'contributors' => [],
'electronicAccess' => [],
'publicationRange' => [],
'physicalDescriptions' => [],
'publicationFrequency' => []
}
end

let(:holdings) { [{ 'electronicAccess' => [] }] }

context 'when instance type is not available' do
it 'leaves leader byte 6 unset' do
marc = described_class.build(instance, holdings)
expect(marc['leader'][6]).to eq(' ')
end
end

context 'when instance type is available' do
let(:instance_with_instance_type) do
instance.merge(
'instanceType' => {
'name' => 'two-dimensional moving image'
}
)
end
it 'sets leader byte 6' do
marc = described_class.build(instance_with_instance_type, holdings)
expect(marc['leader'][6]).to eq('g')
end
end

context 'when mode of issuance is not available' do
it 'leaves leader byte 7 unset' do
marc = described_class.build(instance, holdings)
expect(marc['leader'][7]).to eq(' ')
end
end

context 'when mode of issuance is available' do
let(:instance_with_mode_of_issuance) do
instance.merge(
'modeOfIssuance' => {
'name' => 'single unit'
}
)
end
it 'sets leader byte 7' do
marc = described_class.build(instance_with_mode_of_issuance, holdings)
expect(marc['leader'][7]).to eq('m')
end
end
end
end
Loading