<!-- Virtual classes -->
- <class id="oai_biblio" controller="open-ils.cstore" oils_obj:fieldmapper="oai::biblio"
+ <class id="oaib" controller="open-ils.cstore" oils_obj:fieldmapper="oai::biblio"
oils_persist:readonly="true" reporter:core="false" reporter:label="OAI2 record list"
oils_persist:tablename="oai.biblio">
- <fields>
- <field reporter:label="Record ID\OAI identifier postfix" name="rec_id" reporter:datatype="number"/>
+ <fields oils_persist:primary="rec_id">
+ <field reporter:label="Record ID\OAI identifier postfix" name="rec_id" reporter:datatype="id"/>
<field reporter:label="Last edit date\OAI datestamp" name="datestamp" reporter:datatype="timestamp"/>
<field reporter:label="Is Deleted?" name="deleted" reporter:datatype="bool"/>
<field reporter:label="Setspec" name="set_spec" oils_persist:virtual="true"/>
</fields>
</class>
- <class id="oai_authority" controller="open-ils.cstore" oils_obj:fieldmapper="oai::authority"
+ <class id="oaia" controller="open-ils.cstore" oils_obj:fieldmapper="oai::authority"
oils_persist:readonly="true" reporter:core="false" reporter:label="OAI2 record list"
oils_persist:tablename="oai.authority">
- <fields>
- <field reporter:label="Record ID\OAI identifier postfix" name="rec_id" reporter:datatype="number"/>
+ <fields oils_persist:primary="rec_id">
+ <field reporter:label="Record ID\OAI identifier postfix" name="rec_id" reporter:datatype="id"/>
<field reporter:label="Last edit date\OAI datestamp" name="datestamp" reporter:datatype="timestamp"/>
<field reporter:label="Is Deleted?" name="deleted" reporter:datatype="bool"/>
<field reporter:label="Setspec" name="set_spec" oils_persist:virtual="true"/>
<oai_dc>
<namespace_uri>http://www.openarchives.org/OAI/2.0/oai_dc/</namespace_uri>
<schema_location>http://www.openarchives.org/OAI/2.0/oai_dc.xsd</schema_location>
- <xslt>OAI2_OAIDC.xsl</xslt>
+ <xslt>MARC21slim2OAIDC.xsl</xslt>
</oai_dc>
<marcxml>
<namespace_uri>http://www.loc.gov/MARC21/slim</namespace_uri>
<schema_location>http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd</schema_location>
- <xslt>OAI2_MARC21slim.xsl</xslt>
</marcxml>
</metadataformat> -->
OpenSRF::Utils::SettingsClient
->new
->config_value( dirs => 'xsl' ).
- "/OAI2_OAIDC.xsl"
+ "/MARC21slim2OAIDC.xsl"
);
# and stash a transformer
$record_xslt{oai_dc}{xslt} = $_xslt->parse_stylesheet( $xslt );
$record_xslt{oai_dc}{schema_location} = 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd';
}
- # If not defined, use the natural marcxml metadata setting
- unless ( exists $record_xslt{marcxml}) {
- $logger->info('Loading default marcxml schema') ;
- my $xslt = $_parser->parse_file(
- OpenSRF::Utils::SettingsClient
- ->new
- ->config_value( dirs => 'xsl' ).
- "/OAI2_MARC21slim.xsl"
- );
- # and stash a transformer
- $record_xslt{marcxml}{xslt} = $_xslt->parse_stylesheet( $xslt );
- $record_xslt{marcxml}{namespace_uri} = 'http://www.loc.gov/MARC21/slim';
- $record_xslt{marcxml}{docs} = 'http://www.loc.gov/MARC21/slim';
- $record_xslt{marcxml}{schema_location} = 'http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd';
- }
+ # Store info about the natural marcxml metadata setting. We don't actually use this to drive XSLT, but we can report support.
+ $logger->info('Loading default marcxml schema') ;
+ $record_xslt{marcxml}{namespace_uri} = 'http://www.loc.gov/MARC21/slim';
+ $record_xslt{marcxml}{docs} = 'http://www.loc.gov/MARC21/slim';
+ $record_xslt{marcxml}{schema_location} = 'http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd';
# Load the mapping of 852 holdings.
my $copies = OpenSRF::Utils::SettingsClient->new->config_value(apps => 'open-ils.supercat')->{'app_settings'}->{'oai'}->{'copies'} ;
if ( $copies ) {
foreach my $subfield_code (keys %$copies) {
my $value = $copies->{$subfield_code};
- $logger->info('Set 852 map ' . $subfield_code . '=' . $value );
+ $logger->debug('Set 852 map ' . $subfield_code . '=' . $value );
$copies{$subfield_code} = $value;
}
} else { # if not defined, fall back on these defaults.
my $client = shift;
my $rec_id = shift;
my $metadataPrefix = shift;
+ my $set = shift;
+ my $copy_org;
+ my %copy_org_filter;
+
+ (undef, $copy_org) = _set_spec_to_query('biblio',$set) if ($set);
+
+ my $flesh = {};
+ if ($copy_org) {
+ $U->walk_org_tree($copy_org, sub {
+ my $c = shift;
+ $copy_org_filter{$c->id} = 1;
+ });
+ }
# holdings hold an array of call numbers, which hold an array of copies
# holdings => [ label: { library, [ copies: { barcode, location, status, circ_lib } ] } ]
$rec_id,
{ flesh => 5,
flesh_fields => {
- bre => [qw/marc edit_date call_numbers/],
- acn => [qw/edit_date copies owning_lib prefix suffix/],
- acp => [qw/edit_date location status circ_lib parts/],
+ bre => [qw/call_numbers/],
+ acn => [qw/copies owning_lib prefix suffix uris/],
+ acp => [qw/location status circ_lib parts/],
}
}
)->gather(1);
+ $tree->call_numbers([]) if (!$tree->call_numbers);
+
# Create a MARC::Record object with the marc.
my $marc = MARC::Record->new_from_xml( $tree->marc, 'UTF8', 'XML');
for my $cn (@{$tree->call_numbers}) {
next unless ( $cn->deleted eq 'f' || !$cn->deleted );
- my $_visible = 0;
- for my $c (@{$cn->copies}) {
- $_visible = _cp_is_visible($cn, $c);
- last if ( $_visible );
+
+ my @visible_copies = @{$cn->copies};
+ if ($copy_org) {
+ @visible_copies = grep { $copy_org_filter{$_->circ_lib->id} } @visible_copies;
}
- next unless $_visible;
+ @visible_copies = grep { _cp_is_visible($cn, $_) } @visible_copies;
+ next unless @visible_copies;
my $cn_label = $cn->label;
$holdings{$cn_label}{'owning_lib'} = $cn->owning_lib->shortname;
$edit_date = most_recent_date( $cn->edit_date, $edit_date );
- for my $cp (@{$cn->copies}) {
+ for my $cp (@visible_copies) {
- next unless _cp_is_visible($cn, $cp);
$edit_date = most_recent_date( $cp->edit_date, $edit_date );
# find the corresponding serial.
barcode => $cp->barcode,
status => $cp->status->name,
location => $cp->location->name,
- circlib => $circlib,
+ circlib => $cp->circ_lib->shortname,
ser => $ser
};
}
}
+ $XML::LibXML::skipXMLDeclaration = 1;
+ return $marc->as_xml_record() if ($metadataPrefix eq 'marcxml');
+
my $xslt = $record_xslt{$metadataPrefix}{xslt} ;
my $xml = $xslt->transform( $_parser->parse_string( $marc->as_xml_record()) );
return $xslt->output_as_chars( $xml ) ;
);
}
+ local $XML::LibXML::skipXMLDeclaration = 1;
+ return $marc->as_xml_record() if ($metadataPrefix eq 'marcxml');
+
my $xslt = $record_xslt{$metadataPrefix}{xslt} ;
my $xml = $record_xslt{$metadataPrefix}{xslt}->transform(
$_parser->parse_string( $marc->as_xml_record())
my $max_count = shift;
my $deleted_record = shift || 'yes';
- my $query = $set ? _set_spec_to_query($set) : {};
+ my ($query) = _set_spec_to_query($record_class,$set) if ($set);
+
$query->{'rec_id'} = ($max_count eq 1) ? $rec_id : {'>=' => $rec_id} ;
$query->{'deleted'} = 'f' unless ( $deleted_record eq 'yes' );
$query->{'datestamp'} = {'>=', $from} if ( $from && !$until ) ;
);
sub _set_spec_to_query {
- my $self = shift;
- my $set_spec = shift;
-
- if (index($set_spec, 'ORG_UNIT:') == 0) {
- my $shortname = (split ':', $set_spec)[-1];
- my $org_unit = OpenSRF::AppSession
- ->create('open-ils.actor')
- ->request('open-ils.actor.org_unit.retrieve_by_shortname', $shortname)
- ->gather(1);
- if ($org_unit && ref($org_unit) ne 'HASH') {
- return {
- 'id' => {'=' => ['oai.bib_is_visible_at_org', 'id', $org_unit->id]}
- };
+ my $type = shift;
+ my $set_spec = shift;
+ my $query_part = {};
+ my $copy_org;
+
+ if ($type eq 'biblio') {
+ if ($set_spec =~ /COPIES:([^!]+)/) {
+ my $org_list = $1;
+ my $shortname = (split ':', $org_list)[-1];
+ my $org_unit = $U->find_org_by_shortname($U->get_org_tree, $shortname);
+ if ($org_unit) {
+ $copy_org = $org_unit;
+ $$query_part{'-or'} //= [];
+ push @{$$query_part{'-or'}}, {rec_id => {'=' => {
+ transform => 'oai.bib_is_visible_at_org_by_copy',
+ params => [$org_unit->id],
+ value => ['bool','1']
+ }}};
+ }
+ }
+
+ if ($set_spec =~ /LURIS:([^!]+)/) {
+ my $org_list = $1;
+ my $shortname = (split ':', $org_list)[-1];
+ my $org_unit = $U->find_org_by_shortname($U->get_org_tree, $shortname);
+ if ($org_unit) {
+ $copy_org = $org_unit;
+ $$query_part{'-or'} //= [];
+ push @{$$query_part{'-or'}}, {rec_id => {'=' => {
+ transform => 'oai.bib_is_visible_at_org_by_luri',
+ params => [$org_unit->id],
+ value => ['bool','1']
+ }}};
+ }
+ }
+
+ if ($set_spec =~ /SOURCES:([^!]+)/) {
+ my $list = $1;
+ my @sources = split ':', $list;
+ for my $source (@sources) {
+ $$query_part{'-or'} //= [];
+ push @{$$query_part{'-or'}}, {rec_id => {'=' => {
+ transform => 'oai.bib_is_visible_by_source',
+ params => [$source],
+ value => ['bool','1']
+ }}};
+ }
+ }
+ } elsif ($type eq 'authority') {
+ my @axes = split ':', $set_spec;
+ for my $axis (@axes) {
+ $$query_part{'-or'} //= [];
+ push @{$$query_part{'-or'}}, {rec_id => {'=' => {
+ transform => 'oai.auth_is_visible_by_axis',
+ params => [$axis],
+ value => ['bool','1']
+ }}};
}
}
- return {};
+
+ return ($query_part, $copy_org);
}
use MIME::Base64;
use OpenSRF::EX qw(:try);
use OpenSRF::Utils::Logger qw/$logger/;
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Utils::CStoreEditor;
+use OpenILS::Application::AppUtils;
use XML::LibXML;
use XML::LibXSLT;
+my $U = 'OpenILS::Application::AppUtils';
+
my (
$bootstrap,
$base_url,
$sample_identifier,
$oai_metadataformats,
$oai_sets,
- $oai,
$parser,
$xslt
);
my $idl = OpenSRF::Utils::SettingsClient->new->config_value('IDL');
Fieldmapper->import(IDL => $idl);
+ OpenILS::Utils::CStoreEditor->init; # just in case
- $oai = OpenSRF::AppSession->create('open-ils.supercat');
$parser = new XML::LibXML;
$xslt = new XML::LibXSLT;
$delimiter = $app_settings->{'delimiter'} || ':';
$sample_identifier = $app_settings->{'sample_identifier'} || $scheme . $delimiter . $repository_identifier . $delimiter . '12345' ;
- _load_oaisets_authority();
+ $logger->info('Default OAI repo settings in place, loading sets...');
+
_load_oaisets_biblio();
+ _load_oaisets_authority();
_load_oai_metadataformats();
+ $logger->info('... sets loaded.');
+
return Apache2::Const::OK;
}
$response = listSets( $record_class, $requestURL );
}
elsif ( $verb eq 'GetRecord' ) {
- $response = getRecord( $record_class, $requestURL, $identifier, $metadataPrefix);
+ $response = getRecord( $record_class, $requestURL, $identifier, $metadataPrefix, $set);
}
elsif ( $verb eq 'ListIdentifiers' ) {
$response = listIdentifiers( $record_class, $requestURL, $from, $until, $set, $metadataPrefix, $offset);
sub getRecord {
- my ($record_class, $requestURL, $identifier, $metadataPrefix ) = @_;
+ my ($record_class, $requestURL, $identifier, $metadataPrefix, $set ) = @_;
my $response ;
my @errors;
my $rec_id = $1 ;
# Do we have a record ?
- my $record = $oai->request('open-ils.supercat.oai.list.retrieve', $record_class, $rec_id, undef, undef, undef, 1, $deleted_record)->gather(1) ;
+ my $record = $U->simplereq('open-ils.supercat','open-ils.supercat.oai.list.retrieve', $record_class, $rec_id, undef, undef, undef, 1, $deleted_record);
if (@$record) {
$response = HTTP::OAI::GetRecord->new();
- my $o = "Fieldmapper::oai::$record_class"->new(@$record[0]);
- $response->record(_record($record_class, $o, $metadataPrefix));
+ $response->record(_record($record_class, $$record[0], $metadataPrefix, $set));
} else {
push @errors, new HTTP::OAI::Error(code=>'idDoesNotExist', message=>'The value of the identifier argument is unknown or illegal in this repository.') ;
}
my ($record_class, $requestURL, $from, $until, $set, $metadataPrefix, $offset ) = @_;
my $response;
- my $r = $oai->request('open-ils.supercat.oai.list.retrieve', $record_class, $offset, $from, $until, $set, $max_count, $deleted_record)->gather(1) ;
+ my $r = $U->simplereq('open-ils.supercat','open-ils.supercat.oai.list.retrieve', $record_class, $offset, $from, $until, $oai_sets->{$set}->{setSpec}, $max_count, $deleted_record);
if (@$r) {
my $cursor = 0 ;
$response = HTTP::OAI::ListIdentifiers->new();
for my $record (@$r) {
- my $o = "Fieldmapper::oai::$record_class"->new($record) ;
if ( $cursor++ == $max_count ) {
- my $token = new HTTP::OAI::ResumptionToken( resumptionToken => encode_base64(join( '$', $metadataPrefix, $from, $until, $oai_sets->{$set}->{setSpec}, $o->rec_id ), '' ) ) ;
+ my $token = new HTTP::OAI::ResumptionToken( resumptionToken => encode_base64(join( '$', $metadataPrefix, $from, $until, $oai_sets->{$set}->{setSpec}, $record->rec_id ), '' ) ) ;
$token->cursor($offset);
$response->resumptionToken($token) ;
} else {
- $response->identifier( _header($record_class, $o)) ;
+ $response->identifier( _header($record_class, $record)) ;
}
}
} else {
my ($record_class, $requestURL, $from, $until, $set, $metadataPrefix, $offset ) = @_;
my $response;
- my $r = $oai->request('open-ils.supercat.oai.list.retrieve', $record_class, $offset, $from, $until, $set, $max_count, $deleted_record)->gather(1) ;
+ my $r = $U->simplereq('open-ils.supercat','open-ils.supercat.oai.list.retrieve', $record_class, $offset, $from, $until, $oai_sets->{$set}->{setSpec}, $max_count, $deleted_record);
if (@$r) {
my $cursor = 0 ;
$response = HTTP::OAI::ListRecords->new();
for my $record (@$r) {
- my $o = "Fieldmapper::oai::$record_class"->new($record) ;
if ( $cursor++ == $max_count ) {
- my $token = new HTTP::OAI::ResumptionToken( resumptionToken => encode_base64(join( '$', $metadataPrefix, $from, $until, $oai_sets->{$set}->{setSpec}, $o->rec_id ), '' ) ) ;
+ my $token = new HTTP::OAI::ResumptionToken( resumptionToken => encode_base64(join( '$', $metadataPrefix, $from, $until, $oai_sets->{$set}->{setSpec}, $record->rec_id ), '' ) ) ;
$token->cursor($offset);
$response->resumptionToken($token) ;
} else {
- $response->record(_record($record_class, $o, $metadataPrefix));
+ $response->record(_record($record_class, $record, $metadataPrefix, $set));
}
}
} else {
sub _record {
- my ($record_class, $o, $metadataPrefix ) = @_;
+ my ($record_class, $o, $metadataPrefix, $set ) = @_;
my $record = HTTP::OAI::Record->new();
$record->header( _header($record_class, $o) );
if ( $o->deleted eq 'f' ) {
my $md = new HTTP::OAI::Metadata() ;
- my $xml = $oai->request('open-ils.supercat.oai.' . $record_class . '.retrieve', $o->rec_id, $metadataPrefix)->gather(1) ;
+ my $xml = $U->simplereq('open-ils.supercat','open-ils.supercat.oai.' . $record_class . '.retrieve', $o->rec_id, $metadataPrefix, $oai_sets->{$set}->{setSpec});
+ $xml =~ s/^<\?xml[^?]+?\?>//;
$md->dom( $parser->parse_string('<metadata>' . $xml . '</metadata>') ); # Not sure why I need to add the metadata element,
$record->metadata( $md ); # because I expect ->metadata() would provide the wrapper for it.
}
# oai_sets = {id\setSpec => {id, setSpec, setName, record_class = 'authority' }}
sub _load_oaisets_authority {
- my $ses = OpenSRF::AppSession->create('open-ils.cstore');
- my $r = $ses->request('open-ils.cstore.direct.authority.browse_axis.search.atomic',
- {code => {'!=' => undef } } )->gather(1);
+ my $axes = $U->simplereq('open-ils.cstore','open-ils.cstore.direct.authority.browse_axis.search.atomic', {code => {'!=' => undef } } );
- for my $record (@$r) {
- my $o = Fieldmapper::authority::browse_axis->new($record) ;
+ for my $o (@$axes) {
$oai_sets->{$o->code} = {
id => $o->code,
setSpec => $o->code,
# _load_oaisets_biblio
# Populate the $oai_sets hash with the sets for bibliographic records. Those are org_type records
# oai_sets = {id\setSpec => {id, setSpec, setName, record_class = 'biblio' }}
+my $org_tree;
+my $bib_sources;
sub _load_oaisets_biblio {
my $node = shift;
- my $types = shift;
my $parent = shift;
- unless ( $node ) {
- my $ses = OpenSRF::AppSession->create('open-ils.actor');
- $node = $ses->request('open-ils.actor.org_tree.retrieve')->gather(1);
- my $aout = $ses->request('open-ils.actor.org_types.retrieve')->gather(1);
- $ses->disconnect;
- return unless ($node) ;
-
- my @_types;
- foreach my $type (@$aout) {
- $_types[int($type->id)] = $type;
- }
- $types = \@_types;
+ if (!$node) {
+ $org_tree ||= $U->get_org_tree;
+ $bib_sources ||= $U->simplereq('open-ils.cat','open-ils.cat.bib_sources.retrieve.all');
+
+ $node = $org_tree;
}
return unless ($node->opac_visible =~ /^[y1t]+/i);
+
my $ou_hierarchy_string = ($parent) ? $parent . ':' . $node->shortname : $node->shortname ;
- my $spec = 'ORG_UNIT:'.$ou_hierarchy_string;
- $oai_sets->{$spec} = {id => $node->id, record_class => 'biblio' };
- $oai_sets->{$node->id} = {setSpec => $spec, setName => $node->name, record_class => 'biblio' };
+ $logger->info('Registering setSpec list for ' . $ou_hierarchy_string);
+
+ my $cspec = 'COPIES:'.$ou_hierarchy_string;
+ $oai_sets->{$cspec} = {id => 'C'.$node->id, record_class => 'biblio' };
+ $oai_sets->{'C'.$node->id} = {setSpec => $cspec, setName => $node->name . ' / by copies', record_class => 'biblio' };
+
+ my $lspec = 'LURIS:'.$ou_hierarchy_string;
+ $oai_sets->{$lspec} = {id => 'L'.$node->id, record_class => 'biblio' };
+ $oai_sets->{'L'.$node->id} = {setSpec => $lspec, setName => $node->name . ' / by LURIs', record_class => 'biblio' };
+
+ my $clspec = $cspec . '!' . $lspec;
+ $oai_sets->{$clspec} = {id => 'CL'.$node->id, record_class => 'biblio' };
+ $oai_sets->{'CL'.$node->id} = {setSpec => $clspec, setName => $node->name . ' / by copies and LURIs', record_class => 'biblio' };
+
+
+ my $source_string;
+ for my $s (@$bib_sources) {
+
+ my $sspec = 'SOURCES:'.$s->source;
+ $oai_sets->{$sspec} = {id => 'S'.$s->id, record_class => 'biblio' };
+ $oai_sets->{'S'.$s->id} = {setSpec => $sspec, setName => $s->source . ' / by source', record_class => 'biblio' };
+
+ my $csspec = $cspec . '!' . $sspec;
+ $oai_sets->{$csspec} = {id => $s->id.'CS'.$node->id, record_class => 'biblio' };
+ $oai_sets->{$s->id.'CS'.$node->id} = {setSpec => $csspec, setName => $node->name . ' / by copies and source', record_class => 'biblio' };
+
+ my $lsspec = $lspec . '!' . $sspec;
+ $oai_sets->{$lsspec} = {id => $s->id.'LS'.$node->id, record_class => 'biblio' };
+ $oai_sets->{$s->id.'LS'.$node->id} = {setSpec => $lsspec, setName => $node->name . ' / by LURIs and source', record_class => 'biblio' };
+
+ my $clsspec = $clspec . '!' . $sspec;
+ $oai_sets->{$clsspec} = {id => $s->id.'CLS'.$node->id, record_class => 'biblio' };
+ $oai_sets->{$s->id.'CLS'.$node->id} = {setSpec => $clsspec, setName => $node->name . ' / by copies, LURIs, and source', record_class => 'biblio' };
+
+ }
my $kids = $node->children;
- _load_oaisets_biblio($_, $types, $ou_hierarchy_string) for (@$kids);
+ _load_oaisets_biblio($_, $ou_hierarchy_string) for (@$kids);
}
# oai_metadataformats = { metadataPrefix => { schema, metadataNamespace } }
sub _load_oai_metadataformats {
- my $list = $oai->request('open-ils.supercat.oai.record.formats')->gather(1);
+ my $list = $U->simplereq('open-ils.supercat','open-ils.supercat.oai.record.formats');
for my $record_browse_format ( @$list ) {
my %h = %$record_browse_format ;
my $metadataPrefix = (keys %h)[0] ;
CREATE VIEW oai.biblio AS
SELECT
bre.id AS rec_id,
- bre.edit_date AS datestamp,
+ bre.edit_date AT TIME ZONE 'UTC' AS datestamp,
bre.deleted AS deleted
FROM
biblio.record_entry bre
-- The view presents a lean table with unique are.tc-numbers for oai paging;
CREATE VIEW oai.authority AS
SELECT
- are.id AS rec_id,
- are.edit_date AS datestamp,
- are.deleted AS deleted
+ are.id AS rec_id,
+ are.edit_date AT TIME ZONE 'UTC' AS datestamp,
+ are.deleted AS deleted
FROM
authority.record_entry AS are
ORDER BY
are.id;
-CREATE OR REPLACE function oai.bib_is_visible_at_org(bib BIGINT, org INT) RETURNS BOOL AS $F$
-WITH orgs AS (SELECT array_accum(id) id FROM actor.org_unit_descendants(org))
-SELECT EXISTS (SELECT 1 FROM asset.copy_vis_attr_cache, orgs WHERE vis_attr_vector @@ search.calculate_visibility_attribute_test('circ_lib', orgs.id)::query_int AND bib=record)
+CREATE OR REPLACE function oai.bib_is_visible_at_org_by_copy(bib BIGINT, org INT) RETURNS BOOL AS $F$
+WITH corgs AS (SELECT array_accum(id) AS list FROM actor.org_unit_descendants(org))
+ SELECT EXISTS (SELECT 1 FROM asset.copy_vis_attr_cache, corgs WHERE vis_attr_vector @@ search.calculate_visibility_attribute_test('circ_lib', corgs.list)::query_int AND bib=record)
+$F$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE function oai.bib_is_visible_at_org_by_luri(bib BIGINT, org INT) RETURNS BOOL AS $F$
+WITH lorgs AS(SELECT array_accum(id) AS list FROM actor.org_unit_ancestors(org))
+ SELECT EXISTS (SELECT 1 FROM biblio.record_entry, lorgs WHERE vis_attr_vector @@ search.calculate_visibility_attribute_test('luri_org', lorgs.list)::query_int AND bib=id)
+$F$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE function oai.bib_is_visible_by_source(bib BIGINT, src TEXT) RETURNS BOOL AS $F$
+ SELECT EXISTS (SELECT 1 FROM biblio.record_entry b JOIN config.bib_source s ON (b.source = s.id) WHERE transcendant AND s.source = src AND bib=b.id)
+$F$ LANGUAGE SQL STABLE;
+
+CREATE OR REPLACE function oai.auth_is_visible_by_axis(auth BIGINT, ax TEXT) RETURNS BOOL AS $F$
+ SELECT EXISTS (SELECT 1 FROM authority.browse_axis_authority_field_map m JOIN authority.simple_heading r on (r.atag = m.field AND r.record = auth AND m.axis = ax))
$F$ LANGUAGE SQL STABLE;
COMMIT;
+++ /dev/null
-<xsl:stylesheet version="1.0"
- xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
- xmlns:marc="http://www.loc.gov/MARC21/slim">
- <xsl:output omit-xml-declaration="yes"/>
-
- <xsl:template match="node()|@*">
- <xsl:copy>
- <xsl:apply-templates select="node()|@*"/>
- </xsl:copy>
- </xsl:template>
-
- <xsl:template match="*">
- <xsl:element name="marc:{name()}" namespace="http://www.loc.gov/MARC21/slim">
- <xsl:copy-of select="namespace::*"/>
- <xsl:apply-templates select="node()|@*"/>
- </xsl:element>
- </xsl:template>
-</xsl:stylesheet>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0" xmlns:oai_dc="http://www.openarchives.org/OAI/2.0/oai_dc/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
- <xsl:import href="MARC21slim2OAIDC.xsl"/>
- <xsl:output omit-xml-declaration="yes"/>
-
- <xsl:template match="/">
- <oai_dc:dc xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai_dc/ http://www.openarchives.org/OAI/2.0/oai_dc.xsd"
- xmlns:dc="http://purl.org/dc/elements/1.1/">
- <xsl:apply-templates/>
- </oai_dc:dc>
- </xsl:template>
-
-</xsl:stylesheet>
\ No newline at end of file