]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/Fielder.pm
341b569ed35761bc97f96c6e94229ea1e3f898cd
[working/Evergreen.git] / Open-ILS / src / perlmods / lib / OpenILS / Application / Fielder.pm
1 # vim:et:ts=4:sw=4:
2
3 package OpenILS::Application::Fielder;
4 use OpenILS::Application;
5 use base qw/OpenILS::Application/;
6
7 use Unicode::Normalize;
8 use OpenSRF::EX qw/:try/;
9
10 use OpenSRF::AppSession;
11 use OpenSRF::Utils::SettingsClient;
12 use OpenSRF::Utils::Cache;
13 use OpenSRF::Utils::Logger qw/:level/;
14
15 use OpenILS::Utils::Fieldmapper;
16 use OpenSRF::Utils::JSON;
17
18 use OpenILS::Utils::CStoreEditor qw/:funcs/;
19
20 use Digest::MD5 qw(md5_hex);
21
22 use XML::LibXML;
23 use XML::LibXML::XPathContext;
24 use XML::LibXSLT;
25
26 our %namespace_map = (
27     oils_persist=> {ns => 'http://open-ils.org/spec/opensrf/IDL/persistence/v1'},
28     oils_obj    => {ns => 'http://open-ils.org/spec/opensrf/IDL/objects/v1'},
29     idl         => {ns => 'http://opensrf.org/spec/IDL/base/v1'},
30     reporter    => {ns => 'http://open-ils.org/spec/opensrf/IDL/reporter/v1'},
31     perm        => {ns => 'http://open-ils.org/spec/opensrf/IDL/permacrud/v1'},
32 );
33
34
35 my $log = 'OpenSRF::Utils::Logger';
36
37 my $cache;
38 my $cache_timeout;
39 my $default_locale;
40 my $parser = XML::LibXML->new();
41 my $xslt = XML::LibXSLT->new();
42
43 my $xpc = XML::LibXML::XPathContext->new();
44 $xpc->registerNs($_, $namespace_map{$_}{ns}) for ( keys %namespace_map );
45
46 my $idl;
47
48 sub initialize {
49
50     my $conf = OpenSRF::Utils::SettingsClient->new;
51     my $idl_file = $conf->config_value( 'IDL' );
52
53     $idl = $parser->parse_file( $idl_file );
54
55     $log->debug( 'IDL XML file loaded' );
56
57     $cache_timeout = $conf->config_value(
58             "apps", "open-ils.fielder", "app_settings", "cache_timeout" ) || 300;
59
60     $default_locale = $conf->config_value("default", "default_locale") || 'en-US';
61
62     generate_methods();
63
64 }
65 sub child_init {
66     $cache = OpenSRF::Utils::Cache->new('global');
67 }
68
69 sub fielder_fetch {
70     my $self = shift;
71     my $client = shift;
72     my $obj = shift;
73
74     my $locale = $self->session->session_locale || $default_locale;
75     my $query = $obj->{query};
76     my $nocache = $obj->{cache} ? 0 : 1;
77     my $fields = $obj->{fields};
78     my $distinct = $obj->{distinct} ? 1 : 0;
79
80     return undef unless $query;
81
82     my $obj_class = $self->{class_hint};
83     my $fm_class = $self->{class_name};
84
85     if (!$fields) {
86         $fields = [ $fm_class->real_fields ];
87     }
88
89     $fields = [$fields] if (!ref($fields));
90
91     my $qstring = OpenSRF::Utils::JSON->perl2JSON( $query );
92     my $fstring = OpenSRF::Utils::JSON->perl2JSON( [ sort { $a cmp $b } @$fields ] );
93
94     $log->debug( 'Query Class: '. $obj_class );
95     $log->debug( 'Field list: '. $fstring );
96     $log->debug( 'Query: '. $qstring );
97
98     my ($key,$res);
99     unless ($nocache) {
100         $key = 'open-ils.fielder_' . md5_hex(
101             $self->api_name . 
102             $qstring .
103             $fstring .
104             $distinct .
105             $obj_class .
106             $locale
107         );
108
109         $res = $cache->get_cache( $key );
110
111         if ($res) {
112             $client->respond($_) for (@$res);
113             return undef;
114         }
115     }
116
117     $res = new_editor()->json_query({
118         select  => { $obj_class => $fields },
119         from    => $obj_class,
120         where   => $query,
121         distinct=> $distinct
122     });
123
124     for my $value (@$res) {
125         $client->respond($value);
126     }
127
128     $client->respond_complete();
129
130     $cache->put_cache( $key => $res => $cache_timeout ) unless ($nocache);
131     return undef;
132 }
133
134 sub generate_methods {
135     try {
136         for my $class_node ( $xpc->findnodes( '//idl:class[@oils_persist:field_safe="true"]', $idl->documentElement ) ) {
137             my $hint = $class_node->getAttribute('id');
138             my $fm = $class_node->getAttributeNS('http://open-ils.org/spec/opensrf/IDL/objects/v1','fieldmapper');
139             $log->debug("Fielder class_node $hint");
140         
141             __PACKAGE__->register_method(
142                 method          => 'fielder_fetch',
143                 api_name        => 'open-ils.fielder.' . $hint,
144                 class_hint      => $hint,
145                 class_name      => "Fieldmapper::$fm",
146                 stream          => 1,
147                 argc            => 1
148             );
149         }
150     } catch Error with {
151         my $e = shift;
152         $log->error("error generating Fielder methods: $e");
153     };
154 }
155
156
157 1;
158