]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/perlmods/lib/OpenILS/Application/Fielder.pm
Merge branch 'opac-tt-poc' of git+ssh://yeti.esilibrary.com/home/evergreen/evergreen...
[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 $parser = XML::LibXML->new();
40 my $xslt = XML::LibXSLT->new();
41
42 my $xpc = XML::LibXML::XPathContext->new();
43 $xpc->registerNs($_, $namespace_map{$_}{ns}) for ( keys %namespace_map );
44
45 my $idl;
46
47 sub initialize {
48
49     my $conf = OpenSRF::Utils::SettingsClient->new;
50     my $idl_file = $conf->config_value( 'IDL' );
51
52     $idl = $parser->parse_file( $idl_file );
53
54     $log->debug( 'IDL XML file loaded' );
55
56     $cache_timeout = $conf->config_value(
57             "apps", "open-ils.fielder", "app_settings", "cache_timeout" ) || 300;
58
59     generate_methods();
60
61 }
62 sub child_init {
63     $cache = OpenSRF::Utils::Cache->new('global');
64 }
65
66 sub fielder_fetch {
67     my $self = shift;
68     my $client = shift;
69     my $obj = shift;
70
71     my $query = $obj->{query};
72     my $nocache = $obj->{cache} ? 0 : 1;
73     my $fields = $obj->{fields};
74     my $distinct = $obj->{distinct} ? 1 : 0;
75
76     return undef unless $query;
77
78     my $obj_class = $self->{class_hint};
79     my $fm_class = $self->{class_name};
80
81     if (!$fields) {
82         $fields = [ $fm_class->real_fields ];
83     }
84
85     $fields = [$fields] if (!ref($fields));
86
87     my $qstring = OpenSRF::Utils::JSON->perl2JSON( $query );
88     my $fstring = OpenSRF::Utils::JSON->perl2JSON( [ sort { $a cmp $b } @$fields ] );
89
90     $log->debug( 'Query Class: '. $obj_class );
91     $log->debug( 'Field list: '. $fstring );
92     $log->debug( 'Query: '. $qstring );
93
94     my ($key,$res);
95     unless ($nocache) {
96         $key = 'open-ils.fielder_' . md5_hex(
97             $self->api_name . 
98             $qstring .
99             $fstring .
100             $distinct .
101             $obj_class
102         );
103
104         $res = $cache->get_cache( $key );
105
106         if ($res) {
107             $client->respond($_) for (@$res);
108             return undef;
109         }
110     }
111
112     $res = new_editor()->json_query({
113         select  => { $obj_class => $fields },
114         from    => $obj_class,
115         where   => $query,
116         distinct=> $distinct
117     });
118
119     for my $value (@$res) {
120         $client->respond($value);
121     }
122
123     $client->respond_complete();
124
125     $cache->put_cache( $key => $res => $cache_timeout ) unless ($nocache);
126     return undef;
127 }
128
129 sub generate_methods {
130     try {
131         for my $class_node ( $xpc->findnodes( '//idl:class[@oils_persist:field_safe="true"]', $idl->documentElement ) ) {
132             my $hint = $class_node->getAttribute('id');
133             my $fm = $class_node->getAttributeNS('http://open-ils.org/spec/opensrf/IDL/objects/v1','fieldmapper');
134             $log->debug("Fielder class_node $hint");
135         
136             __PACKAGE__->register_method(
137                 method          => 'fielder_fetch',
138                 api_name        => 'open-ils.fielder.' . $hint,
139                 class_hint      => $hint,
140                 class_name      => "Fieldmapper::$fm",
141                 stream          => 1,
142                 argc            => 1
143             );
144         }
145     } catch Error with {
146         my $e = shift;
147         $log->error("error generating Fielder methods: $e");
148     };
149 }
150
151
152 1;
153