]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/c-apps/oils_fetch.c
4babd2569e98a64665adfd5e7a364652e703bc5a
[Evergreen.git] / Open-ILS / src / c-apps / oils_fetch.c
1 #include "opensrf/osrf_app_session.h"
2 #include "opensrf/osrf_application.h"
3 #include "opensrf/osrf_settings.h"
4 #include "objson/object.h"
5 #include "opensrf/log.h"
6 #include "openils/oils_utils.h"
7 #include "openils/oils_constants.h"
8 #include "openils/oils_event.h"
9 #include <dbi/dbi.h>
10 #include <openils/fieldmapper_lookup.h>
11
12 #define OILS_AUTH_CACHE_PRFX "oils_fetch_"
13
14 #define MODULENAME "open-ils.fetch"
15 dbi_conn dbhandle; /* our db connection */
16
17 /* handy NULL json object to have around */
18 static jsonObject* oilsFetchNULL = NULL;
19
20 int osrfAppChildInit();
21
22 /* turns a singal db result row into a jsonObject */
23 jsonObject* oilsFetchMakeJSON( dbi_result result, char* hint );
24
25 osrfHash* fmClassMap = NULL;
26
27
28 int osrfAppInitialize() {
29         osrfLogInfo(OSRF_LOG_MARK, "Initializing Fetch Server...");
30
31         oilsFetchNULL = jsonNewObject(NULL);
32         fmClassMap = osrfNewHash();
33
34         int i;
35         char* hint;
36         char* apiname;
37
38         osrfList* keys = fm_classes();
39         if(!keys) return 0;
40
41         /* cycle through all of the classes and register a 
42          * retrieve method for each */
43         for( i = 0; i < keys->size; i++ ) {
44
45                 hint = OSRF_LIST_GET_INDEX(keys, i);    
46                 i++;
47                 apiname = OSRF_LIST_GET_INDEX(keys, i); 
48                 if(!(hint && apiname)) break;
49
50                 osrfHashSet( fmClassMap, hint, apiname );
51
52                 char method[256];
53                 snprintf(method, sizeof(method), "open-ils.fetch.%s.retrieve", apiname);
54
55                 osrfAppRegisterMethod( MODULENAME, 
56                                 method, "oilsFetchDoRetrieve", "", 1, 0 );
57         }
58
59         return 0;
60 }
61
62
63 /**
64  * Connects to the database 
65  */
66 int osrfAppChildInit() {
67
68         dbi_initialize(NULL);
69
70         char* driver = osrf_settings_host_value("/apps/%s/app_settings/databases/driver", MODULENAME);
71         char* user       = osrf_settings_host_value("/apps/%s/app_settings/databases/database/user", MODULENAME);
72         char* host       = osrf_settings_host_value("/apps/%s/app_settings/databases/database/host", MODULENAME);
73         char* port       = osrf_settings_host_value("/apps/%s/app_settings/databases/database/port", MODULENAME);
74         char* db                 = osrf_settings_host_value("/apps/%s/app_settings/databases/database/db", MODULENAME);
75         char* pw                 = osrf_settings_host_value("/apps/%s/app_settings/databases/database/pw", MODULENAME);
76
77         dbhandle = dbi_conn_new(driver);
78
79         if(!dbhandle) {
80                 osrfLogError(OSRF_LOG_MARK, "Error creating database driver %s", driver);
81                 return -1;
82         }
83
84         osrfLogInfo(OSRF_LOG_MARK, "oils_fetch connecting to database.  host=%s, "
85                 "port=%s, user=%s, pw=%s, db=%s", host, port, user, pw, db );
86
87         if(host) dbi_conn_set_option(dbhandle, "host", host );
88         if(port) dbi_conn_set_option_numeric( dbhandle, "port", atoi(port) );
89         if(user) dbi_conn_set_option(dbhandle, "username", user);
90         if(pw) dbi_conn_set_option(dbhandle, "password", pw );
91         if(db) dbi_conn_set_option(dbhandle, "dbname", db );
92
93         free(user);
94         free(host);
95         free(port);
96         free(db);
97         free(pw);
98
99         if (dbi_conn_connect(dbhandle) < 0) {
100                 const char* err;
101                 dbi_conn_error(dbhandle, &err);
102                 osrfLogError( OSRF_LOG_MARK, "Error connecting to database: %s", err);
103                 return -1;
104         }
105
106         osrfLogInfo(OSRF_LOG_MARK, "%s successfully connected to the database", MODULENAME);
107
108         return 0;
109 }
110
111
112
113 int oilsFetchDoRetrieve( osrfMethodContext* ctx ) {
114
115         OSRF_METHOD_VERIFY_CONTEXT(ctx); 
116
117         char* id                = jsonObjectToSimpleString(jsonObjectGetIndex(ctx->params, 0));
118         char* meth      = strdup(ctx->method->name);
119         char* strtk;
120
121         strtok_r(meth, ".", &strtk); /* open-ils */
122         strtok_r(NULL, ".", &strtk); /* fetch */
123         char* schema    = strtok_r(NULL, ".", &strtk); 
124         char* object    = strtok_r(NULL, ".", &strtk);
125
126         osrfLogDebug(OSRF_LOG_MARK, "%s retrieving %s.%s "
127                         "object with id %s", MODULENAME, schema, object, id );
128
129         /* construct the SQL */
130         char sql[256];
131         snprintf( sql, sizeof(sql), "select * from %s.%s where id = %s;", schema, object, id );
132
133         /* find the object hint from the api name */
134         char hintbuf[256];
135         snprintf(hintbuf, sizeof(hintbuf), "%s.%s", schema, object );
136         char* hint = osrfHashGet( fmClassMap, hintbuf );
137
138         osrfLogDebug(OSRF_LOG_MARK, "%s SQL =  %s", MODULENAME, sql);
139
140         dbi_result result = dbi_conn_queryf(dbhandle, sql);
141
142         if(result) {
143
144                 /* there should be one row at the most  */
145                 dbi_result_next_row(result); 
146
147                 /* JSONify the result */
148                 jsonObject* obj = oilsFetchMakeJSON( result, hint );
149
150                 /* clean up the query */
151                 dbi_result_free(result); 
152
153                 osrfAppRespondComplete( ctx, obj ); 
154                 jsonObjectFree(obj);
155
156         } else {
157
158                 osrfLogDebug(OSRF_LOG_MARK, "%s returned no results for query %s", MODULENAME, sql);
159                 osrfAppRespondComplete( ctx, oilsFetchNULL );
160         }
161
162         free(id);
163         free(meth);
164         return 0;
165 }
166
167
168 jsonObject* oilsFetchMakeJSON( dbi_result result, char* hint ) {
169         if(!(result && hint)) return NULL;
170
171         jsonObject* object = jsonParseString("[]");
172         jsonObjectSetClass(object, hint);
173
174         int attr;  
175         int fmIndex; 
176         int columnIndex = 1; 
177         unsigned short type;
178         const char* columnName; 
179
180         /* cycle through the column list */
181         while( (columnName = dbi_result_get_field_name(result, columnIndex++)) ) {
182
183                 /* determine the field type and storage attributes */
184                 type = dbi_result_get_field_type(result, columnName);
185                 attr = dbi_result_get_field_attribs(result, columnName);
186
187                 /* fetch the fieldmapper index */
188                 if( (fmIndex = fm_ntop(hint, (char*) columnName)) < 0 ) continue;
189
190                 switch( type ) {
191
192                         case DBI_TYPE_INTEGER :
193
194                                 if( attr & DBI_INTEGER_SIZE8 ) 
195                                         jsonObjectSetIndex( object, fmIndex, 
196                                                 jsonNewNumberObject(dbi_result_get_longlong(result, columnName)));
197                                 else 
198                                         jsonObjectSetIndex( object, fmIndex, 
199                                                 jsonNewNumberObject(dbi_result_get_long(result, columnName)));
200
201                                 break;
202
203                         case DBI_TYPE_DECIMAL :
204                                 jsonObjectSetIndex( object, fmIndex, 
205                                                 jsonNewNumberObject(dbi_result_get_double(result, columnName)));
206                                 break;
207
208                         case DBI_TYPE_STRING :
209                                 jsonObjectSetIndex( object, fmIndex, 
210                                         jsonNewObject(dbi_result_get_string(result, columnName)));
211                                 break;
212
213                         case DBI_TYPE_DATETIME :
214                                 jsonObjectSetIndex( object, fmIndex, 
215                                         jsonNewNumberObject(dbi_result_get_datetime(result, columnName)));
216                                 break;
217
218                         case DBI_TYPE_BINARY :
219                                 osrfLogError( OSRF_LOG_MARK, 
220                                         "Can't do binary at column %s : index %d", columnName, columnIndex - 1);
221                 }
222         }
223
224         return object;
225 }
226
227
228