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"
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 );
53 snprintf(method, sizeof(method), "open-ils.fetch.%s.retrieve", apiname);
55 osrfAppRegisterMethod( MODULENAME,
56 method, "oilsFetchDoRetrieve", "", 1, 0 );
64 * Connects to the database
66 int osrfAppChildInit() {
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);
77 dbhandle = dbi_conn_new(driver);
80 osrfLogError(OSRF_LOG_MARK, "Error creating database driver %s", driver);
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 );
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 );
99 if (dbi_conn_connect(dbhandle) < 0) {
101 dbi_conn_error(dbhandle, &err);
102 osrfLogError( OSRF_LOG_MARK, "Error connecting to database: %s", err);
106 osrfLogInfo(OSRF_LOG_MARK, "%s successfully connected to the database", MODULENAME);
113 int oilsFetchDoRetrieve( osrfMethodContext* ctx ) {
115 OSRF_METHOD_VERIFY_CONTEXT(ctx);
117 char* id = jsonObjectToSimpleString(jsonObjectGetIndex(ctx->params, 0));
118 char* meth = strdup(ctx->method->name);
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);
126 osrfLogDebug(OSRF_LOG_MARK, "%s retrieving %s.%s "
127 "object with id %s", MODULENAME, schema, object, id );
129 /* construct the SQL */
131 snprintf( sql, sizeof(sql), "select * from %s.%s where id = %s;", schema, object, id );
133 /* find the object hint from the api name */
135 snprintf(hintbuf, sizeof(hintbuf), "%s.%s", schema, object );
136 char* hint = osrfHashGet( fmClassMap, hintbuf );
138 osrfLogDebug(OSRF_LOG_MARK, "%s SQL = %s", MODULENAME, sql);
140 dbi_result result = dbi_conn_queryf(dbhandle, sql);
144 /* there should be one row at the most */
145 dbi_result_next_row(result);
147 /* JSONify the result */
148 jsonObject* obj = oilsFetchMakeJSON( result, hint );
150 /* clean up the query */
151 dbi_result_free(result);
153 osrfAppRespondComplete( ctx, obj );
158 osrfLogDebug(OSRF_LOG_MARK, "%s returned no results for query %s", MODULENAME, sql);
159 osrfAppRespondComplete( ctx, oilsFetchNULL );
168 jsonObject* oilsFetchMakeJSON( dbi_result result, char* hint ) {
169 if(!(result && hint)) return NULL;
171 jsonObject* object = jsonParseString("[]");
172 jsonObjectSetClass(object, hint);
178 const char* columnName;
180 /* cycle through the column list */
181 while( (columnName = dbi_result_get_field_name(result, columnIndex++)) ) {
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);
187 /* fetch the fieldmapper index */
188 if( (fmIndex = fm_ntop(hint, (char*) columnName)) < 0 ) continue;
192 case DBI_TYPE_INTEGER :
194 if( attr & DBI_INTEGER_SIZE8 )
195 jsonObjectSetIndex( object, fmIndex,
196 jsonNewNumberObject(dbi_result_get_longlong(result, columnName)));
198 jsonObjectSetIndex( object, fmIndex,
199 jsonNewNumberObject(dbi_result_get_long(result, columnName)));
203 case DBI_TYPE_DECIMAL :
204 jsonObjectSetIndex( object, fmIndex,
205 jsonNewNumberObject(dbi_result_get_double(result, columnName)));
208 case DBI_TYPE_STRING :
209 jsonObjectSetIndex( object, fmIndex,
210 jsonNewObject(dbi_result_get_string(result, columnName)));
213 case DBI_TYPE_DATETIME :
214 jsonObjectSetIndex( object, fmIndex,
215 jsonNewNumberObject(dbi_result_get_datetime(result, columnName)));
218 case DBI_TYPE_BINARY :
219 osrfLogError( OSRF_LOG_MARK,
220 "Can't do binary at column %s : index %d", columnName, columnIndex - 1);