4 use base 'OpenSRF::Application';
6 use OpenSRF::Utils::Logger;
7 my $log = 'OpenSRF::Utils::Logger';
9 use OpenILS::Application::Storage::CDBI;
10 use OpenILS::Application::Storage::CDBI::actor;
11 use OpenILS::Application::Storage::CDBI::action;
12 use OpenILS::Application::Storage::CDBI::asset;
13 use OpenILS::Application::Storage::CDBI::biblio;
14 use OpenILS::Application::Storage::CDBI::config;
15 use OpenILS::Application::Storage::CDBI::metabib;
16 use OpenILS::Application::Storage::CDBI::money;
18 use vars qw/$fieldmap $VERSION/;
22 sub publish_fieldmapper {
23 my ($self,$client,$class) = @_;
25 return $fieldmap unless (defined $class);
26 return undef unless (exists($$fieldmap{$class}));
27 return {$class => $$fieldmap{$class}};
29 __PACKAGE__->register_method(
30 api_name => 'opensrf.open-ils.system.fieldmapper',
32 method => 'publish_fieldmapper',
36 # To dump the Javascript version of the fieldmapper struct use the command:
38 # PERL5LIB=~/cvs/ILS/OpenSRF/src/perlmods/:~/cvs/ILS/Open-ILS/src/perlmods/ GEN_JS=1 perl -MOpenILS::Utils::Fieldmapper -e 'print "\n";'
40 # ... adjusted for your CVS sandbox, of course.
44 return () unless (defined $fieldmap);
45 return keys %$fieldmap;
49 return if (keys %$fieldmap);
53 'Fieldmapper::action::survey' => { hint => 'asv',
54 proto_fields => { questions => 1,
56 'Fieldmapper::action::survey_question' => { hint => 'asvq',
57 proto_fields => { answers => 1,
59 'Fieldmapper::action::survey_answer' => { hint => 'asva',
60 proto_fields => { responses => 1 } },
61 'Fieldmapper::action::survey_response' => { hint => 'asvr' },
62 'Fieldmapper::action::circulation' => { hint => 'circ',
63 proto_fields => { due_date => 1 } },
64 'Fieldmapper::actor::user' => { hint => 'au',
65 proto_fields => { cards => 1,
66 survey_responses => 1,
67 stat_cat_entries => 1,
69 'Fieldmapper::actor::user_address' => { hint => 'aua' },
70 'Fieldmapper::actor::org_address' => { hint => 'aoa' },
71 'Fieldmapper::actor::profile' => { hint => 'ap' },
72 'Fieldmapper::actor::card' => { hint => 'ac' },
73 'Fieldmapper::config::standing' => { hint => 'cst' },
74 'Fieldmapper::config::copy_status' => { hint => 'ccs' },
75 'Fieldmapper::actor::stat_cat' => { hint => 'actsc',
76 proto_fields => { entries => 1 } },
77 'Fieldmapper::actor::stat_cat_entry' => { hint => 'actsce' },
78 'Fieldmapper::actor::stat_cat_entry_user_map' => { hint => 'actscecm' },
79 'Fieldmapper::actor::org_unit' => { hint => 'aou',
80 proto_fields => { children => 1 } },
81 'Fieldmapper::actor::org_unit_type' => { hint => 'aout',
82 proto_fields => { children => 1 } },
84 'Fieldmapper::biblio::record_node' => { hint => 'brn',
86 proto_fields => { children => 1,
97 'Fieldmapper::metabib::virtual_record' => { hint => 'mvr',
99 proto_fields => { title => 1,
108 types_of_resource => 1,
116 'Fieldmapper::biblio::record_entry' => { hint => 'bre',
117 proto_fields => { call_numbers => 1,
118 fixed_fields => 1 } },
119 #'Fieldmapper::biblio::record_marc' => { hint => 'brx' }, # now it's inside record_entry
121 'Fieldmapper::money::cash_payment' => { hint => 'mcp' },
122 'Fieldmapper::money::billing' => { hint => 'mb' },
124 'Fieldmapper::config::identification_type' => { hint => 'cit' },
125 'Fieldmapper::config::bib_source' => { hint => 'cbs' },
126 'Fieldmapper::config::metabib_field' => { hint => 'cmf' },
127 'Fieldmapper::config::rules::recuring_fine' => { hint => 'crrf' },
128 'Fieldmapper::config::rules::circ_duration' => { hint => 'crcd' },
129 'Fieldmapper::config::rules::max_fine' => { hint => 'crmf' },
131 'Fieldmapper::metabib::metarecord' => { hint => 'mmr' },
132 'Fieldmapper::metabib::title_field_entry' => { hint => 'mtfe' },
133 'Fieldmapper::metabib::author_field_entry' => { hint => 'mafe' },
134 'Fieldmapper::metabib::subject_field_entry' => { hint => 'msfe' },
135 'Fieldmapper::metabib::keyword_field_entry' => { hint => 'mkfe' },
136 'Fieldmapper::metabib::series_field_entry' => { hint => 'msefe' },
137 'Fieldmapper::metabib::full_rec' => { hint => 'mfr' },
138 'Fieldmapper::metabib::record_descriptor' => { hint => 'mrd' },
139 'Fieldmapper::metabib::metarecord_source_map' => { hint => 'mmrsm'},
141 'Fieldmapper::asset::copy' => { hint => 'acp',
142 proto_fields => { stat_cat_entries => 1 } },
143 'Fieldmapper::asset::stat_cat' => { hint => 'asc',
144 proto_fields => { entries => 1 } },
145 'Fieldmapper::asset::stat_cat_entry' => { hint => 'asce' },
146 'Fieldmapper::asset::stat_cat_entry_copy_map' => { hint => 'ascecm' },
147 'Fieldmapper::asset::copy_note' => { hint => 'acpn' },
148 'Fieldmapper::asset::copy_location' => { hint => 'acpl' },
149 'Fieldmapper::asset::call_number' => { hint => 'acn',
150 proto_fields => { copies => 1 } },
151 'Fieldmapper::asset::call_number_note' => { hint => 'acnn' },
153 'Fieldmapper::ex' => { hint => 'ex',
163 #-------------------------------------------------------------------------------
164 # Now comes the evil! Generate classes
166 for my $pkg ( __PACKAGE__->classes ) {
167 (my $cdbi = $pkg) =~ s/^Fieldmapper:://o;
171 use base 'Fieldmapper';
175 for my $vfield ( qw/isnew ischanged isdeleted/ ) {
176 $$fieldmap{$pkg}{fields}{$vfield} = { position => $pos, virtual => 1 };
180 if (exists $$fieldmap{$pkg}{proto_fields}) {
181 for my $pfield ( sort keys %{ $$fieldmap{$pkg}{proto_fields} } ) {
182 $$fieldmap{$pkg}{fields}{$pfield} = { position => $pos, virtual => $$fieldmap{$pkg}{proto_fields}{$pfield} };
187 unless ( $$fieldmap{$pkg}{virtual} ) {
188 $$fieldmap{$pkg}{cdbi} = $cdbi;
189 for my $col ( sort $cdbi->columns('All') ) {
190 $$fieldmap{$pkg}{fields}{$col} = { position => $pos, virtual => 0 };
195 JSON->register_class_hint(
196 hint => $pkg->json_hint,
207 $value = [] unless (defined $value);
208 return bless $value => $self->class_name;
221 (my $field = $AUTOLOAD) =~ s/^.*://o;
222 my $class_name = $obj->class_name;
225 $fpos =~ s/^clear_//og ;
227 my $pos = $$fieldmap{$class_name}{fields}{$fpos}{position};
229 if ($field =~ /^clear_/o) {
231 *{$obj->class_name."::$field"} = sub {
233 $self->[$pos] = undef;
237 return $obj->$field();
240 die "No field by the name $field in $class_name!"
241 unless (exists $$fieldmap{$class_name}{fields}{$field});
245 *{$obj->class_name."::$field"} = sub {
248 $self->[$pos] = $new_val if (defined $new_val);
249 return $self->[$pos];
252 return $obj->$field($value);
256 my $class_name = shift;
257 return ref($class_name) || $class_name;
262 my $class_name = $self->class_name;
263 my $fields = $$fieldmap{$class_name}{fields};
266 !$$fields{$_}{virtual}
267 } sort {$$fields{$a}{position} <=> $$fields{$b}{position}} keys %$fields;
274 return $fieldmap->{$self->class_name}->{api_level};
280 return $fieldmap->{$self->class_name}->{virtual};
285 return $fieldmap->{$self->class_name}->{hint};