2 * Retrieve, cache, and query MARC tag tables
4 angular.module('egCoreMod')
6 ['$q', 'egCore', 'egAuth',
7 function($q, egCore, egAuth) {
10 defaultTagTableSelector : {
11 marcFormat : 'marc21',
12 marcRecordType : 'biblio',
17 phys_char_type_map : null,
18 phys_char_sf_map : { },
19 phys_char_value_map : { },
20 authority_control_set : {
21 _remote_loaded : false,
24 _active_control_set : undefined
27 service.initialized = function() {
28 return service.authority_control_set._remote_loaded;
31 // allow 'bre' and 'biblio' to be synonyms, etc.
32 service.normalizeRecordType = function(recordType) {
33 if (recordType === 'sre') {
35 } else if (recordType === 'bre') {
37 } else if (recordType === 'are') {
44 service.loadTagTable = function(args) {
45 var fields = service.defaultTagTableSelector;
47 if (args.marcFormat) {
48 fields.marcFormat = args.marcFormat;
50 if (args.marcRecordType) {
51 fields.marcRecordType = service.normalizeRecordType(args.marcRecordType);
54 var tt_key = 'current_tag_table_' + fields.marcFormat + '_' +
55 fields.marcRecordType;
56 egCore.hatch.getItem(tt_key).then(function(tt) {
60 service.loadRemoteTagTable(fields, tt_key);
65 service.fetchFFPosTable = function(rtype) {
66 var deferred = $q.defer();
68 var hatch_pos_key = 'FFPosTable_'+rtype;
70 egCore.hatch.getItem(hatch_pos_key).then(function(cached_table) {
72 service.ff_pos_map[rtype] = cached_table;
73 deferred.resolve(cached_table);
77 egCore.net.request( // First, get the list of FFs (minus 006)
79 'open-ils.fielder.cmfpm.atomic',
80 { query : { tag : { '!=' : '006' } } }
81 ).then(function (data) {
82 service.ff_pos_map[rtype] = data;
83 egCore.hatch.setItem(hatch_pos_key, data);
84 deferred.resolve(data);
89 return deferred.promise;
92 service.fetchFFValueTable = function(rtype) {
93 var deferred = $q.defer();
95 var hatch_value_key = 'FFValueTable_'+rtype;
97 egCore.hatch.getItem(hatch_value_key).then(function(cached_table) {
99 service.ff_value_map[rtype] = cached_table;
100 deferred.resolve(cached_table);
106 'open-ils.cat.biblio.fixed_field_values.by_rec_type',
108 ).then(function (data) {
109 service.ff_value_map[rtype] = data;
110 egCore.hatch.setItem(hatch_value_key, data);
111 deferred.resolve(data);
116 return deferred.promise;
119 service.loadRemoteTagTable = function(fields, tt_key) {
122 'open-ils.cat.tag_table.all.retrieve.local',
123 egAuth.token(), fields.marcFormat, fields.marcRecordType
126 egCore.hatch.setItem(tt_key, service.fields);
128 function (err) { console.err('error fetch tag table: ' + err) },
131 service.fields[field.tag] = field;
136 service.getFieldTags = function() {
138 angular.forEach(service.fields, function(value, key) {
141 label: key + ': ' + value.name
147 service.getSubfieldCodes = function(tag) {
150 if (!service.fields[tag]) return;
151 angular.forEach(service.fields[tag].subfields, function(value) {
154 label: value.code + ': ' + value.description
160 service.getSubfieldValues = function(tag, sf_code) {
162 if (!tag) return list;
163 if (!service.fields[tag]) return;
164 if (!service.fields[tag]) return;
165 angular.forEach(service.fields[tag].subfields, function(sf) {
166 if (sf.code == sf_code && sf.hasOwnProperty('value_list')) {
167 angular.forEach(sf.value_list, function(value) {
168 var label = (value.code == value.description) ?
170 value.code + ': ' + value.description;
181 service.getIndicatorValues = function(tag, pos) {
183 if (!tag) return list;
184 if (!service.fields[tag]) return;
185 if (!service.fields[tag]["ind" + pos]) return;
186 angular.forEach(service.fields[tag]["ind" + pos], function(value) {
189 label: value.code + ': ' + value.description
195 service.authorityControlSet = function (kwargs) {
197 kwargs = kwargs || {};
199 this._fetch_class = function(hint, cache_key) {
200 return egCore.pcrud.retrieveAll(hint, {}, {atomic : true}).then(
202 egCore.env.absorbList(list, hint);
203 service.authority_control_set[cache_key] = list;
208 this._fetch = function(cmap) {
209 var deferred = $q.defer();
211 for (var hint in cmap) {
212 promises.push(this._fetch_class(hint, cmap[hint]));
214 $q.all(promises).then(function() {
217 return deferred.promise;
220 this._parse = function() {
221 service.authority_control_set._browse_axis_by_code = {};
222 service.authority_control_set._browse_axis_list.forEach(function (ba) {
224 service.authority_control_set._browse_field_map_list.filter(
225 function (m) { return m.axis() == ba.code() }
228 service.authority_control_set._browse_axis_by_code[ba.code()] = ba;
231 // loop over each acs
232 service.authority_control_set._control_set_list.forEach(function (cs) {
233 service.authority_control_set._controlsets[''+cs.id()] = {
236 description : cs.description(),
237 authority_tag_map : {},
243 // grab the authority fields
244 var acsaf_list = service.authority_control_set._authority_field_list.filter(
245 function (af) { return af.control_set() == cs.id() }
248 var at_list = service.authority_control_set._thesaurus_list.filter(
249 function (at) { return at.control_set() == cs.id() }
252 service.authority_control_set._controlsets[''+cs.id()].raw.authority_fields( acsaf_list );
253 service.authority_control_set._controlsets[''+cs.id()].raw.thesauri( at_list );
255 // and loop over each
256 acsaf_list.forEach(function (csaf) {
259 // link the main entry if we're subordinate
260 if (csaf.main_entry()) {
262 acsaf_list.filter(function (x) {
263 return x.id() == csaf.main_entry();
268 // link the sub entries if we're main
270 acsaf_list.filter(function (x) {
271 return x.main_entry() == csaf.id();
276 var acsbf_list = service.authority_control_set._bib_field_list.filter(
277 function (b) { return b.authority_field() == csaf.id() }
279 csaf.bib_fields( acsbf_list );
281 service.authority_control_set._controlsets[''+cs.id()].bib_fields = [].concat(
282 service.authority_control_set._controlsets[''+cs.id()].bib_fields,
286 acsbf_list.forEach(function (csbf) {
287 // link the authority field to the bib field
288 if (csbf.authority_field()) {
289 csbf.authority_field(
290 acsaf_list.filter(function (x) {
291 return x.id() == csbf.authority_field();
298 service.authority_control_set._browse_axis_list.forEach(
301 function (m) { return m.field() == csaf.id() }
303 function (fm) { fm.field( csaf ); csaf.axis_maps().push( fm ) } // and set the field
310 // build the authority_tag_map
311 service.authority_control_set._controlsets[''+cs.id()].bib_fields.forEach(function (bf) {
313 if (!service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()])
314 service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()] = {};
316 bf.authority_field().sf_list().split('').forEach(function (sf_code) {
318 if (!service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()][sf_code])
319 service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()][sf_code] = {};
321 service.authority_control_set._controlsets[''+cs.id()].control_map[bf.tag()][sf_code][bf.authority_field().tag()] = sf_code;
327 if (this.controlSetList().length > 0)
328 delete service.authority_control_set._controlsets['-1'];
332 this.controlSetId = function (x) {
333 if (x) this._controlset = ''+x;
334 return this._controlset;
337 this.controlSetList = function () {
339 for (var i in service.authority_control_set._controlsets) {
346 if (!service.authority_control_set._remote_loaded) {
348 // TODO -- push the raw tree into the oils cache for later reuse
350 // fetch everything up front...
353 "acs": "_control_set_list",
354 "at": "_thesaurus_list",
355 "acsaf": "_authority_field_list",
356 "acsbf": "_bib_field_list",
357 "aba": "_browse_axis_list",
358 "abaafm": "_browse_field_map_list"
360 service.authority_control_set._remote_loaded = true;
362 if (kwargs.controlSet) {
363 parent.controlSetId( kwargs.controlSet );
365 parent.controlSetId( parent.controlSetList().sort(function(a,b){return (a - b)}) );
370 this.controlSet = function (x) {
371 return service.authority_control_set._controlsets[''+this.controlSetId(x)];
374 this.controlSetByThesaurusCode = function (x) {
375 var thes = service.authority_control_set._thesaurus_list.filter(
376 function (at) { return at.code() == x }
379 return this.controlSet(thes.control_set());
382 this.browseAxisByCode = function(code) {
383 return service.authority_control_set._browse_axis_by_code[code];
386 this.bibFieldByTag = function (x) {
388 return me.controlSet().bib_fields.filter(
389 function (bf) { if (bf.tag() == x) return true }
393 this.bibFields = function (x) {
394 return this.controlSet(x).bib_fields;
397 this.bibFieldBrowseAxes = function (t) {
399 for (var bcode in service.authority_control_set._browse_axis_by_code) {
400 service.authority_control_set._browse_axis_by_code[bcode].maps().forEach(
402 if (m.field().bib_fields().filter(
403 function (b) { return b.tag() == t }
412 this.authorityFields = function (x) {
413 return this.controlSet(x).raw.authority_fields();
416 this.thesauri = function (x) {
417 return this.controlSet(x).raw.thesauri();
420 this.findControlSetsForTag = function (tag) {
422 var old_acs = this.controlSetId();
423 var acs_list = me.controlSetList().filter(
424 function(acs_id) { return (me.controlSet(acs_id).control_map[tag]) }
426 this.controlSetId(old_acs);
430 this.findControlSetsForAuthorityTag = function (tag) {
432 var old_acs = this.controlSetId();
434 var acs_list = me.controlSetList().filter(
436 var a = me.controlSet(acs_id);
437 for (var btag in a.control_map) {
438 for (var sf in a.control_map[btag]) {
439 if (a.control_map[btag][sf][tag]) return true;
445 this.controlSetId(old_acs);
449 this.bibToAuthority = function (field) {
450 var b_field = this.bibFieldByTag(field.tag);
452 if (b_field) { // construct an marc authority record
453 var af = b_field.authority_field();
456 for (var i = 0; i < field.subfields.length; i++) {
457 if (af.sf_list().indexOf(field.subfields[i][0]) > -1) {
458 sflist.push(field.subfields[i]);
462 var m = new MARC21.Record ({rtype:'AUT'});
472 return m.toXmlString();
478 this.bibToAuthorities = function (field) {
482 var old_acs = this.controlSetId();
483 me.controlSetList().forEach(
485 var acs = me.controlSet(acs_id);
486 var x = me.bibToAuthority(field);
487 if (x) { var foo = {}; foo[acs_id] = x; auth_list.push(foo); }
490 this.controlSetId(old_acs);
497 service.getAuthorityControlSet = function() {
498 if (!service._active_control_set) {
499 service.authority_control_set._remote_loaded = false;
500 service._active_control_set = new service.authorityControlSet();
502 return service._active_control_set;
505 // fetches and caches the full set of values from
506 // config.marc21_physical_characteristic_type_map
507 service.getPhysCharTypeMap = function() {
509 if (service.phys_char_type_map) {
510 return $q.when(service.phys_char_type_map);
513 return egCore.pcrud.retrieveAll('cmpctm', {}, {atomic : true})
514 .then(function(map) {return service.phys_char_type_map = map});
517 // Fetch+caches the config.marc21_physical_characteristic_subfield_map
518 // values for the requested ptype_key (i.e. type_map.ptype_key).
519 // Values are sorted by start_pos
520 service.getPhysCharSubfieldMap = function(ptype_key) {
522 if (service.phys_char_sf_map[ptype_key]) {
523 return $q.when(service.phys_char_sf_map[ptype_key]);
526 return egCore.pcrud.search('cmpcsm',
527 {ptype_key : ptype_key},
528 {order_by : {cmpcsm : ['start_pos']}},
530 ).then(function(maps) {
531 return service.phys_char_sf_map[ptype_key] = maps;
535 // Fetches + caches the config.marc21_physical_characteristic_value_map
536 // for the requested ptype_subfield (subfield_map.id).
537 // Maps are ordered by value.
538 service.getPhysCharValueMap = function(ptype_subfield) {
539 if (service.phys_char_value_map[ptype_subfield]) {
540 return $q.when(service.phys_char_value_map[ptype_subfield]);
543 return egCore.pcrud.search('cmpcvm',
544 {ptype_subfield : ptype_subfield},
545 {order_by : {cmpcsm : ['value']}},
547 ).then(function(maps) {
548 return service.phys_char_sf_map[ptype_subfield] = maps;