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 "oils_utils.h"
7 #include "oils_constants.h"
8 #include "oils_event.h"
10 #include <openils/fieldmapper_lookup.h>
12 #define OILS_AUTH_CACHE_PRFX "oils_fetch_"
14 #define MODULENAME "open-ils.fetch"
15 dbi_conn dbhandle; /* our db connection */
17 /* handy NULL json object to have around */
18 static jsonObject* oilsFetchNULL = NULL;
20 int osrfAppChildInit();
22 /* turns a singal db result row into a jsonObject */
23 jsonObject* oilsFetchMakeJSON( dbi_result result, char* hint );
25 osrfHash* fmClassMap = NULL;
28 int osrfAppInitialize() {
29 osrfLogInfo(OSRF_LOG_MARK, "Initializing Fetch Server...");
31 oilsFetchNULL = jsonNewObject(NULL);
32 fmClassMap = osrfNewHash();
38 osrfList* keys = fm_classes();
41 /* cycle through all of the classes and register a
42 * retrieve method for each */
43 for( i = 0; i < keys->size; i++ ) {
45 hint = OSRF_LIST_GET_INDEX(keys, i);
47 apiname = OSRF_LIST_GET_INDEX(keys, i);
48 if(!(hint && apiname)) break;
50 osrfHashSet( fmClassMap, hint, apiname );
54 snprintf(method, 256, "open-ils.fetch.%s.retrieve", apiname);
56 osrfAppRegisterMethod( MODULENAME,
57 method, "oilsFetchDoRetrieve", "", 1, 0 );
65 * Connects to the database
67 int osrfAppChildInit() {
71 char* driver = osrf_settings_host_value("/apps/%s/app_settings/databases/driver", MODULENAME);
72 char* user = osrf_settings_host_value("/apps/%s/app_settings/databases/database/user", MODULENAME);
73 char* host = osrf_settings_host_value("/apps/%s/app_settings/databases/database/host", MODULENAME);
74 char* port = osrf_settings_host_value("/apps/%s/app_settings/databases/database/port", MODULENAME);
75 char* db = osrf_settings_host_value("/apps/%s/app_settings/databases/database/db", MODULENAME);
76 char* pw = osrf_settings_host_value("/apps/%s/app_settings/databases/database/pw", MODULENAME);
78 dbhandle = dbi_conn_new(driver);
81 osrfLogError(OSRF_LOG_MARK, "Error creating database driver %s", driver);
85 osrfLogInfo(OSRF_LOG_MARK, "oils_fetch connecting to database. host=%s, "
86 "port=%s, user=%s, pw=%s, db=%s", host, port, user, pw, db );
88 if(host) dbi_conn_set_option(dbhandle, "host", host );
89 if(port) dbi_conn_set_option_numeric( dbhandle, "port", atoi(port) );
90 if(user) dbi_conn_set_option(dbhandle, "username", user);
91 if(pw) dbi_conn_set_option(dbhandle, "password", pw );
92 if(db) dbi_conn_set_option(dbhandle, "dbname", db );
100 if (dbi_conn_connect(dbhandle) < 0) {
102 dbi_conn_error(dbhandle, &err);
103 osrfLogError( OSRF_LOG_MARK, "Error connecting to database: %s", err);
107 osrfLogInfo(OSRF_LOG_MARK, "%s successfully connected to the database", MODULENAME);
114 int oilsFetchDoRetrieve( osrfMethodContext* ctx ) {
116 OSRF_METHOD_VERIFY_CONTEXT(ctx);
118 char* id = jsonObjectToSimpleString(jsonObjectGetIndex(ctx->params, 0));
119 char* meth = strdup(ctx->method->name);
122 strtok_r(meth, ".", &strtk); /* open-ils */
123 strtok_r(NULL, ".", &strtk); /* fetch */
124 char* schema = strtok_r(NULL, ".", &strtk);
125 char* object = strtok_r(NULL, ".", &strtk);
127 osrfLogDebug(OSRF_LOG_MARK, "%s retrieving %s.%s "
128 "object with id %s", MODULENAME, schema, object, id );
130 /* construct the SQL */
133 snprintf( sql, 255, "select * from %s.%s where id = %s;", schema, object, id );
135 /* find the object hint from the api name */
138 snprintf(hintbuf, 255, "%s.%s", schema, object );
139 char* hint = osrfHashGet( fmClassMap, hintbuf );
141 osrfLogDebug(OSRF_LOG_MARK, "%s SQL = %s", MODULENAME, sql);
143 dbi_result result = dbi_conn_queryf(dbhandle, sql);
147 /* there should be one row at the most */
148 dbi_result_next_row(result);
150 /* JSONify the result */
151 jsonObject* obj = oilsFetchMakeJSON( result, hint );
153 /* clean up the query */
154 dbi_result_free(result);
156 osrfAppRespondComplete( ctx, obj );
161 osrfLogDebug(OSRF_LOG_MARK, "%s returned no results for query %s", MODULENAME, sql);
162 osrfAppRespondComplete( ctx, oilsFetchNULL );
171 jsonObject* oilsFetchMakeJSON( dbi_result result, char* hint ) {
172 if(!(result && hint)) return NULL;
174 jsonObject* object = jsonParseString("[]");
175 jsonObjectSetClass(object, hint);
181 const char* columnName;
183 /* cycle through the column list */
184 while( (columnName = dbi_result_get_field_name(result, columnIndex++)) ) {
186 /* determine the field type and storage attributes */
187 type = dbi_result_get_field_type(result, columnName);
188 attr = dbi_result_get_field_attribs(result, columnName);
190 /* fetch the fieldmapper index */
191 if( (fmIndex = fm_ntop(hint, (char*) columnName)) < 0 ) continue;
195 case DBI_TYPE_INTEGER :
197 if( attr & DBI_INTEGER_SIZE8 )
198 jsonObjectSetIndex( object, fmIndex,
199 jsonNewNumberObject(dbi_result_get_longlong(result, columnName)));
201 jsonObjectSetIndex( object, fmIndex,
202 jsonNewNumberObject(dbi_result_get_long(result, columnName)));
206 case DBI_TYPE_DECIMAL :
207 jsonObjectSetIndex( object, fmIndex,
208 jsonNewNumberObject(dbi_result_get_double(result, columnName)));
211 case DBI_TYPE_STRING :
212 jsonObjectSetIndex( object, fmIndex,
213 jsonNewObject(dbi_result_get_string(result, columnName)));
216 case DBI_TYPE_DATETIME :
217 jsonObjectSetIndex( object, fmIndex,
218 jsonNewNumberObject(dbi_result_get_datetime(result, columnName)));
221 case DBI_TYPE_BINARY :
222 osrfLogError( OSRF_LOG_MARK,
223 "Can't do binary at column %s : index %d", columnName, columnIndex - 1);