]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/OpenILS/Utils/Fieldmapper.pm
new magic fieldmapper and updated SQL stuff
[working/Evergreen.git] / Open-ILS / src / perlmods / OpenILS / Utils / Fieldmapper.pm
1 package Fieldmapper;
2 use JSON;
3 use Data::Dumper;
4 use OpenILS::Application::Storage::CDBI::actor;
5 use OpenILS::Application::Storage::CDBI::biblio;
6 use OpenILS::Application::Storage::CDBI::config;
7 use OpenILS::Application::Storage::CDBI::metabib;
8
9 use vars qw/$fieldmap @class_name_list $VERSION/;
10
11 _init();
12
13 #
14 # To dump the Javascript version of the fieldmapper struct use the command:
15 #
16 #       PERL5LIB=~/cvs/ILS/OpenSRF/src/perlmods/:~/cvs/ILS/Open-ILS/src/perlmods/ GEN_JS=1 perl -MOpenILS::Utils::Fieldmapper -e 'print "\n";'
17 #
18 # ... adjusted for your CVS sandbox, of course.
19 #
20
21 sub _init {
22         return if (defined $fieldmap);
23
24         $fieldmap = 
25         {
26                 'Fieldmapper::actor::user'                      => { hint => 'au'   },
27                 'Fieldmapper::actor::org_unit'                  => { hint => 'aou'  },
28                 'Fieldmapper::actor::org_unit_type'             => { hint => 'aout' },
29                 'Fieldmapper::biblio::record_node'              => { hint => 'brn'  },
30                 'Fieldmapper::biblio::record_entry'             => { hint => 'bre'  },
31                 'Fieldmapper::config::bib_source'               => { hint => 'cbs'  },
32                 'Fieldmapper::config::metabib_field'            => { hint => 'cmf'  },
33                 'Fieldmapper::metabib::metarecord'              => { hint => 'mmr'  },
34                 'Fieldmapper::metabib::title_field_entry'       => { hint => 'mmr'  },
35                 'Fieldmapper::metabib::author_field_entry'      => { hint => 'mmr'  },
36                 'Fieldmapper::metabib::subject_field_entry'     => { hint => 'mmr'  },
37                 'Fieldmapper::metabib::keyword_field_entry'     => { hint => 'mmr'  },
38                 'Fieldmapper::metabib::full_rec'                => { hint => 'mmr'  },
39         };
40
41         #-------------------------------------------------------------------------------
42         # Now comes the evil!  Generate classes
43
44         for my $pkg ( keys %$fieldmap ) {
45                 (my $cdbi = $pkg) =~ s/^Fieldmapper:://o;
46
47                 eval <<"                PERL";
48                         package $pkg;
49                         use base 'Fieldmapper';
50                 PERL
51
52                 push @class_name_list, $pkg;
53
54                 $$fieldmapp{$pkg}{cdbi} = $cdbi;
55
56                 my $pos = 0;
57                 for my $vfield ( qw/isnew ischanged isdeleted/ ) {
58                         $$fieldmap{$pkg}{fields}{$vfield} = { position => $pos, virtual => 1 };
59                         $pos++;
60                 }
61
62                 for my $col ( $cdbi->columns('All') ) {
63                         $$fieldmap{$pkg}{fields}{$col} = { position => $pos, virtual => 0 };
64                         $pos++;
65                 }
66
67                 JSON->register_class_hint(
68                         hint => $pkg->json_hint,
69                         name => $pkg,
70                         type => 'array',
71                 );
72
73         }
74
75         print Fieldmapper->javascript() if ($ENV{GEN_JS});
76 }
77
78 sub new {
79         my $self = shift;
80         my $value = shift;
81         $value = [] unless (defined $value);
82         return bless $value => $self->class_name;
83 }
84
85 sub javascript {
86         my $class_name = shift;
87         return 'var fieldmap = ' . JSON->perl2JSON($fieldmap) . ';'
88 }
89
90 sub DESTROY {}
91
92 sub AUTOLOAD {
93         my $obj = shift;
94         my $value = shift;
95         (my $field = $AUTOLOAD) =~ s/^.*://o;
96         my $class_name = $obj->class_name;
97
98         die "No field by the name $field in $class_name!"
99                 unless (exists $$fieldmap{$class_name}{fields}{$field});
100
101         my $pos = $$fieldmap{$class_name}{fields}{$field}{position};
102
103         {       no strict 'subs';
104                 *{$obj->class_name."::$field"} = sub {
105                         my $self = shift;
106                         my $new_val = shift;
107                         $self->[$pos] = $new_val if (defined $new_val);
108                         return $self->[$pos];
109                 };
110         }
111
112         return $obj->$field($value);
113 }
114
115 sub class_name {
116         my $class_name = shift;
117         return ref($class_name) || $class_name;
118 }
119
120 sub real_fields {
121         my $self = shift;
122         my $class_name = $self->class_name;
123         my $fields = $$fieldmap{$class_name}{fields};
124
125         my @f = grep {
126                         !$$fields{$_}{virtual}
127                 } sort {$$fields{$a}{position} <=> $$fields{$b}{position}} keys %$fields;
128
129         return @f;
130 }
131
132 sub api_level {
133         my $self = shift;
134         return $fieldmap->{$self->class_name}->{api_level};
135 }
136
137 sub api_level {
138         my $self = shift;
139         return $fieldmap->{$self->class_name}->{api_level};
140 }
141
142 sub json_hint {
143         my $self = shift;
144         return $fieldmap->{$self->class_name}->{hint};
145 }
146
147
148 1;