]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/c-apps/oils_cstore.c
time mangling
[Evergreen.git] / Open-ILS / src / c-apps / oils_cstore.c
1 #include "opensrf/osrf_application.h"
2 #include "opensrf/osrf_settings.h"
3 #include "opensrf/utils.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"
9 #include <dbi/dbi.h>
10
11 #include <time.h>
12 #include <string.h>
13 #include <libxml/globals.h>
14 #include <libxml/xmlerror.h>
15 #include <libxml/parser.h>
16 #include <libxml/tree.h>
17 #include <libxml/debugXML.h>
18 #include <libxml/xmlmemory.h>
19 //#include <openils/fieldmapper_lookup.h>
20
21 #define OILS_AUTH_CACHE_PRFX "oils_cstore_"
22 #define MODULENAME "open-ils.cstore"
23 #define PERSIST_NS "http://open-ils.org/spec/opensrf/IDL/persistance/v1"
24 #define OBJECT_NS "http://open-ils.org/spec/opensrf/IDL/objects/v1"
25 #define BASE_NS "http://opensrf.org/spec/IDL/base/v1"
26
27 int osrfAppChildInit();
28 int osrfAppInitialize();
29
30 int dispatchCRUDMethod ( osrfMethodContext* ctx );
31 jsonObject* doCreate ( osrfHash* metadata, jsonObject* params );
32 jsonObject* doRetrieve ( osrfHash* metadata, jsonObject* params );
33 jsonObject* doUpdate ( osrfHash* metadata, jsonObject* params );
34 jsonObject* doDelete ( osrfHash* metadata, jsonObject* params );
35 jsonObject* oilsMakeJSONFromResult( dbi_result result, osrfHash* meta);
36
37 dbi_conn dbhandle; /* our db connection */
38 xmlDocPtr idlDoc = NULL; // parse and store the IDL here
39
40
41 /* parse and store the IDL here */
42 osrfHash* idlHash;
43
44 /* handy NULL json object to have around */
45 static jsonObject* oilsNULL = NULL;
46
47 int osrfAppInitialize() {
48
49         idlHash = osrfNewHash();
50
51         osrfLogInfo(OSRF_LOG_MARK, "Initializing the CStore Server...");
52         osrfLogInfo(OSRF_LOG_MARK, "Finding XML file...");
53
54         char * idl_filename = osrf_settings_host_value("/apps/%s/app_settings/IDL", MODULENAME);
55         osrfLogInfo(OSRF_LOG_MARK, "Found file:");
56         osrfLogInfo(OSRF_LOG_MARK, idl_filename);
57
58         osrfLogInfo(OSRF_LOG_MARK, "Parsing the IDL XML...");
59         idlDoc = xmlReadFile( idl_filename, NULL, XML_PARSE_XINCLUDE );
60         
61         if (!idlDoc) {
62                 osrfLogError(OSRF_LOG_MARK, "Could not load or parse the IDL XML file!");
63                 exit(1);
64         }
65
66         osrfLogInfo(OSRF_LOG_MARK, "...IDL XML parsed");
67
68         osrfStringArray* global_methods = osrfNewStringArray(1);
69
70         //osrfStringArrayAdd( global_methods, "create" );
71         osrfStringArrayAdd( global_methods, "retrieve" );
72         //osrfStringArrayAdd( global_methods, "update" );
73         //osrfStringArrayAdd( global_methods, "delete" );
74
75         xmlNodePtr docRoot = xmlDocGetRootElement(idlDoc);
76         xmlNodePtr kid = docRoot->children;
77         while (kid) {
78                 if (!strcmp( (char*)kid->name, "class" )) {
79                         int i = 0; 
80                         char* method_type;
81                         while ( (method_type = osrfStringArrayGetString(global_methods, i++)) ) {
82
83                                 osrfHash * usrData = osrfNewHash();
84                                 osrfHashSet( usrData, xmlGetProp(kid, "id"), "classname");
85                                 osrfHashSet( usrData, xmlGetNsProp(kid, "tablename", PERSIST_NS), "tablename");
86                                 osrfHashSet( usrData, xmlGetNsProp(kid, "fieldmapper", OBJECT_NS), "fieldmapper");
87
88                                 if(!strcmp(method_type, "retrieve"))
89                                         osrfHashSet( idlHash, usrData, (char*)osrfHashGet(usrData, "classname") );
90
91                                 osrfLogInfo(OSRF_LOG_MARK, "Generating class methods for %s", osrfHashGet(usrData, "fieldmapper") );
92
93                                 osrfHash* _tmp;
94                                 osrfHash* links = osrfNewHash();
95                                 osrfHash* fields = osrfNewHash();
96
97                                 osrfHashSet( usrData, fields, "fields" );
98                                 osrfHashSet( usrData, links, "links" );
99
100                                 xmlNodePtr _cur = kid->children;
101
102                                 while (_cur) {
103                                         char* string_tmp = NULL;
104
105                                         if (!strcmp( (char*)_cur->name, "fields" )) {
106
107                                                 if( (string_tmp = (char*)xmlGetNsProp(_cur, "primary", PERSIST_NS)) ) {
108                                                         osrfHashSet(
109                                                                 usrData,
110                                                                 strdup( string_tmp ),
111                                                                 "primarykey"
112                                                         );
113                                                 }
114                                                 string_tmp = NULL;
115
116                                                 xmlNodePtr _f = _cur->children;
117
118                                                 while(_f) {
119                                                         if (strcmp( (char*)_f->name, "field" )) {
120                                                                 _f = _f->next;
121                                                                 continue;
122                                                         }
123
124                                                         _tmp = osrfNewHash();
125
126                                                         if( (string_tmp = (char*)xmlGetNsProp(_f, "array_position", OBJECT_NS)) ) {
127                                                                 osrfHashSet(
128                                                                         _tmp,
129                                                                         strdup( string_tmp ),
130                                                                         "array_position"
131                                                                 );
132                                                         }
133                                                         string_tmp = NULL;
134
135                                                         if( (string_tmp = (char*)xmlGetNsProp(_f, "virtual", PERSIST_NS)) ) {
136                                                                 osrfHashSet(
137                                                                         _tmp,
138                                                                         strdup( string_tmp ),
139                                                                         "virtual"
140                                                                 );
141                                                         }
142                                                         string_tmp = NULL;
143
144                                                         if( (string_tmp = (char*)xmlGetProp(_f, "name")) ) {
145                                                                 osrfHashSet(
146                                                                         _tmp,
147                                                                         strdup( string_tmp ),
148                                                                         "name"
149                                                                 );
150                                                         }
151
152                                                         osrfLogInfo(OSRF_LOG_MARK, "Found field %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
153
154                                                         osrfHashSet(
155                                                                 fields,
156                                                                 _tmp,
157                                                                 strdup( string_tmp )
158                                                         );
159                                                         _f = _f->next;
160                                                 }
161                                         }
162
163                                         if (!strcmp( (char*)_cur->name, "links" )) {
164                                                 xmlNodePtr _l = _cur->children;
165
166                                                 while(_l) {
167                                                         if (strcmp( (char*)_l->name, "link" )) {
168                                                                 _l = _l->next;
169                                                                 continue;
170                                                         }
171
172                                                         _tmp = osrfNewHash();
173
174                                                         if( (string_tmp = (char*)xmlGetProp(_l, "reltype")) ) {
175                                                                 osrfHashSet(
176                                                                         _tmp,
177                                                                         strdup( string_tmp ),
178                                                                         "reltype"
179                                                                 );
180                                                         }
181                                                         osrfLogInfo(OSRF_LOG_MARK, "Adding link with reltype %s", string_tmp );
182                                                         string_tmp = NULL;
183
184                                                         if( (string_tmp = (char*)xmlGetProp(_l, "key")) ) {
185                                                                 osrfHashSet(
186                                                                         _tmp,
187                                                                         strdup( string_tmp ),
188                                                                         "key"
189                                                                 );
190                                                         }
191                                                         osrfLogInfo(OSRF_LOG_MARK, "Link fkey is %s", string_tmp );
192                                                         string_tmp = NULL;
193
194                                                         if( (string_tmp = (char*)xmlGetProp(_l, "class")) ) {
195                                                                 osrfHashSet(
196                                                                         _tmp,
197                                                                         strdup( string_tmp ),
198                                                                         "class"
199                                                                 );
200                                                         }
201                                                         osrfLogInfo(OSRF_LOG_MARK, "Link fclass is %s", string_tmp );
202                                                         string_tmp = NULL;
203
204                                                         osrfStringArray* map = osrfNewStringArray(0);
205
206                                                         if( (string_tmp = (char*)xmlGetProp(_l, "map") )) {
207                                                                 char* map_list = strdup( string_tmp );
208                                                                 osrfLogInfo(OSRF_LOG_MARK, "Link mapping list is %s", string_tmp );
209
210                                                                 if (strlen( map_list ) > 0) {
211                                                                         char* st_tmp;
212                                                                         char* _map_class = strtok_r(map_list, " ", &st_tmp);
213                                                                         osrfStringArrayAdd(map, strdup(_map_class));
214                                                         
215                                                                         while ((_map_class = strtok_r(NULL, " ", &st_tmp))) {
216                                                                                 osrfStringArrayAdd(map, strdup(_map_class));
217                                                                         }
218                                                                 }
219                                                         }
220                                                         osrfHashSet( _tmp, map, "map");
221
222                                                         if( (string_tmp = (char*)xmlGetProp(_l, "field")) ) {
223                                                                 osrfHashSet(
224                                                                         _tmp,
225                                                                         strdup( string_tmp ),
226                                                                         "field"
227                                                                 );
228                                                         }
229
230                                                         osrfHashSet(
231                                                                 links,
232                                                                 _tmp,
233                                                                 strdup( string_tmp )
234                                                         );
235
236                                                         osrfLogInfo(OSRF_LOG_MARK, "Found link %s for class %s", string_tmp, osrfHashGet(usrData, "classname") );
237
238                                                         _l = _l->next;
239                                                 }
240                                         }
241
242                                         _cur = _cur->next;
243                                 }
244
245
246                                 char* st_tmp;
247                                 char* _fm;
248                                 if (!osrfHashGet(usrData, "fieldmapper")) continue;
249
250                                 _fm = strdup( (char*)osrfHashGet(usrData, "fieldmapper") );
251                                 char* part = strtok_r(_fm, ":", &st_tmp);
252
253                                 growing_buffer* method_name =  buffer_init(64);
254                                 buffer_fadd(method_name, "%s.direct.%s", MODULENAME, part);
255
256                                 while ((part = strtok_r(NULL, ":", &st_tmp))) {
257                                         buffer_fadd(method_name, ".%s", part);
258                                 }
259                                 buffer_fadd(method_name, ".%s", method_type);
260
261                                 char* method = buffer_data(method_name);
262                                 buffer_free(method_name);
263
264                                 osrfHashSet( usrData, method, "methodname" );
265                                 osrfHashSet( usrData, strdup(method_type), "methodtype" );
266
267                                 osrfAppRegisterExtendedMethod(
268                                         MODULENAME,
269                                         method,
270                                         "dispatchCRUDMethod",
271                                         "",
272                                         1,
273                                         0,
274                                         (void*)usrData
275                                 );
276                         }
277                 }
278                 kid = kid->next;
279         }
280
281         return 0;
282 }
283
284 /**
285  * Connects to the database 
286  */
287 int osrfAppChildInit() {
288
289         osrfLogDebug(OSRF_LOG_MARK, "Attempting to initialize libdbi...");
290         dbi_initialize(NULL);
291         osrfLogDebug(OSRF_LOG_MARK, "... libdbi initialized.");
292
293         char* driver    = osrf_settings_host_value("/apps/%s/app_settings/driver", MODULENAME);
294         char* user      = osrf_settings_host_value("/apps/%s/app_settings/database/user", MODULENAME);
295         char* host      = osrf_settings_host_value("/apps/%s/app_settings/database/host", MODULENAME);
296         char* port      = osrf_settings_host_value("/apps/%s/app_settings/database/port", MODULENAME);
297         char* db        = osrf_settings_host_value("/apps/%s/app_settings/database/db", MODULENAME);
298         char* pw        = osrf_settings_host_value("/apps/%s/app_settings/database/pw", MODULENAME);
299
300         osrfLogDebug(OSRF_LOG_MARK, "Attempting to load the database driver [%s]...", driver);
301         dbhandle = dbi_conn_new(driver);
302
303         if(!dbhandle) {
304                 osrfLogError(OSRF_LOG_MARK, "Error loading database driver [%s]", driver);
305                 return -1;
306         }
307         osrfLogDebug(OSRF_LOG_MARK, "Database driver [%s] seems OK", driver);
308
309         osrfLogInfo(OSRF_LOG_MARK, "%s connecting to database.  host=%s, "
310                 "port=%s, user=%s, pw=%s, db=%s", MODULENAME, host, port, user, pw, db );
311
312         if(host) dbi_conn_set_option(dbhandle, "host", host );
313         if(port) dbi_conn_set_option_numeric( dbhandle, "port", atoi(port) );
314         if(user) dbi_conn_set_option(dbhandle, "username", user);
315         if(pw) dbi_conn_set_option(dbhandle, "password", pw );
316         if(db) dbi_conn_set_option(dbhandle, "dbname", db );
317
318         free(user);
319         free(host);
320         free(port);
321         free(db);
322         free(pw);
323
324         const char* err;
325         if (dbi_conn_connect(dbhandle) < 0) {
326                 dbi_conn_error(dbhandle, &err);
327                 osrfLogError( OSRF_LOG_MARK, "Error connecting to database: %s", err);
328                 return -1;
329         }
330
331         osrfLogInfo(OSRF_LOG_MARK, "%s successfully connected to the database", MODULENAME);
332
333         int attr;
334         unsigned short type;
335         int i = 0; 
336         char* classname;
337         osrfStringArray* classes = osrfHashKeys( idlHash );
338         
339         while ( (classname = osrfStringArrayGetString(classes, i++)) ) {
340                 osrfHash* class = osrfHashGet( idlHash, classname );
341                 osrfHash* fields = osrfHashGet( class, "fields" );
342                 
343                 growing_buffer* sql_buf = buffer_init(32);
344                 buffer_fadd( sql_buf, "SELECT * FROM %s WHERE 1=0;", osrfHashGet(class, "tablename") );
345
346                 char* sql = buffer_data(sql_buf);
347                 buffer_free(sql_buf);
348                 osrfLogDebug(OSRF_LOG_MARK, "%s Investigatory SQL = %s", MODULENAME, sql);
349
350                 dbi_result result = dbi_conn_query(dbhandle, sql);
351                 free(sql);
352
353                 if (result) {
354
355                         int columnIndex = 1;
356                         const char* columnName;
357                         osrfHash* _f;
358                         while( (columnName = dbi_result_get_field_name(result, columnIndex++)) ) {
359
360                                 osrfLogDebug(OSRF_LOG_MARK, "Looking for column named [%s]...", (char*)columnName);
361
362                                 /* fetch the fieldmapper index */
363                                 if( (_f = osrfHashGet(fields, (char*)columnName)) ) {
364
365                                         osrfLogDebug(OSRF_LOG_MARK, "Found [%s] in IDL hash...", (char*)columnName);
366
367                                         /* determine the field type and storage attributes */
368                                         type = dbi_result_get_field_type(result, columnName);
369                                         attr = dbi_result_get_field_attribs(result, columnName);
370
371                                         switch( type ) {
372
373                                                 case DBI_TYPE_INTEGER :
374
375                                                         osrfHashSet(_f,"number", "primitive");
376
377                                                         if( attr & DBI_INTEGER_SIZE8 ) 
378                                                                 osrfHashSet(_f,"INT8", "datatype");
379                                                         else 
380                                                                 osrfHashSet(_f,"INT", "datatype");
381                                                         break;
382
383                                                 case DBI_TYPE_DECIMAL :
384                                                         osrfHashSet(_f,"number", "primitive");
385                                                         osrfHashSet(_f,"NUMERIC", "datatype");
386                                                         break;
387
388                                                 case DBI_TYPE_STRING :
389                                                         osrfHashSet(_f,"string", "primitive");
390                                                         osrfHashSet(_f,"TEXT", "datatype");
391                                                         break;
392
393                                                 case DBI_TYPE_DATETIME :
394                                                         osrfHashSet(_f,"string", "primitive");
395                                                         osrfHashSet(_f,"TIMESTAMP", "datatype");
396                                                         break;
397
398                                                 case DBI_TYPE_BINARY :
399                                                         osrfHashSet(_f,"string", "primitive");
400                                                         osrfHashSet(_f,"BYTEA", "datatype");
401                                         }
402
403                                         osrfLogDebug(
404                                                 OSRF_LOG_MARK,
405                                                 "Setting [%s] to primitive [%s] and datatype [%s]...",
406                                                 (char*)columnName,
407                                                 osrfHashGet(_f, "primitive"),
408                                                 osrfHashGet(_f, "datatype")
409                                         );
410                                 }
411                         }
412                         dbi_result_free(result);
413                 } else {
414                         osrfLogDebug(OSRF_LOG_MARK, "No data found for class [%s]...", (char*)classname);
415                 }
416         }
417
418         osrfStringArrayFree(classes);
419
420         return 0;
421 }
422
423
424 int dispatchCRUDMethod ( osrfMethodContext* ctx ) {
425         OSRF_METHOD_VERIFY_CONTEXT(ctx);
426
427         osrfHash* meta = (osrfHash*) ctx->method->userData;
428
429         jsonObject * obj = NULL;
430         if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "create"))
431                 obj = doCreate(meta, ctx->params);
432
433         if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "retrieve"))
434                 obj = doRetrieve(meta, ctx->params);
435
436         if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "update"))
437                 obj = doUpdate(meta, ctx->params);
438
439         if (!strcmp( (char*)osrfHashGet(meta, "methodtype"), "delete"))
440                 obj = doDelete(meta, ctx->params);
441
442         osrfAppRespondComplete( ctx, obj );
443
444         jsonObjectFree(obj);
445
446         return 0;
447 }
448
449 jsonObject* doCreate( osrfHash* meta, jsonObject* params ) { return NULL; }
450
451 jsonObject* doRetrieve( osrfHash* meta, jsonObject* params ) {
452
453         char* id        = jsonObjectToSimpleString(jsonObjectGetIndex(params, 0));
454
455         osrfLogDebug(
456                 OSRF_LOG_MARK,
457                 "%s retrieving %s object with id %s",
458                 MODULENAME,
459                 osrfHashGet(meta, "fieldmapper"),
460                 id
461         );
462
463
464
465         growing_buffer* sql_buf = buffer_init(128);
466         buffer_fadd(
467                 sql_buf,
468                 "SELECT * FROM %s WHERE %s = %d;",
469                 osrfHashGet(meta, "tablename"),
470                 osrfHashGet(meta, "primarykey"),
471                 atoi(id)
472         );
473
474         char* sql = buffer_data(sql_buf);
475         buffer_free(sql_buf);
476         
477         osrfLogDebug(OSRF_LOG_MARK, "%s SQL =  %s", MODULENAME, sql);
478
479         dbi_result result = dbi_conn_query(dbhandle, sql);
480
481         jsonObject* obj = NULL;
482         if(result) {
483
484                 /* there should be one row at the most  */
485                 if (!dbi_result_first_row(result)) {
486                         osrfLogDebug(OSRF_LOG_MARK, "%s: Error retrieving %s with key %s", MODULENAME, osrfHashGet(meta, "fieldmapper"), id);
487                         dbi_result_free(result); 
488                         return oilsNULL;
489                 }
490
491                 /* JSONify the result */
492                 obj = oilsMakeJSONFromResult( result, meta );
493
494                 /* clean up the query */
495                 dbi_result_free(result); 
496
497         } else {
498                 osrfLogDebug(OSRF_LOG_MARK, "%s returned no results for query %s", MODULENAME, sql);
499         }
500
501         free(id);
502
503         return obj;
504 }
505
506
507 jsonObject* doUpdate( osrfHash* meta, jsonObject* params ) { return NULL; }
508
509 jsonObject* doDelete( osrfHash* meta, jsonObject* params ) { return NULL; }
510
511
512 jsonObject* oilsMakeJSONFromResult( dbi_result result, osrfHash* meta) {
513         if(!(result && meta)) return NULL;
514
515         jsonObject* object = jsonParseString("[]");
516         jsonObjectSetClass(object, osrfHashGet(meta, "classname"));
517
518         osrfHash* fields = osrfHashGet(meta, "fields");
519
520         osrfLogDebug(OSRF_LOG_MARK, "Setting object class to %s ", object->classname);
521
522         osrfHash* _f;
523         struct tm _tmp_tm;
524         time_t _tmp_dt;
525         char dt_string[256];
526         int fmIndex;
527         int columnIndex = 1;
528         int attr;
529         unsigned short type;
530         const char* columnName;
531
532         /* cycle through the column list */
533         while( (columnName = dbi_result_get_field_name(result, columnIndex++)) ) {
534
535                 osrfLogDebug(OSRF_LOG_MARK, "Looking for column named [%s]...", (char*)columnName);
536
537                 fmIndex = -1; // reset the position
538                 
539                 /* determine the field type and storage attributes */
540                 type = dbi_result_get_field_type(result, columnName);
541                 attr = dbi_result_get_field_attribs(result, columnName);
542
543                 /* fetch the fieldmapper index */
544                 if( (_f = osrfHashGet(fields, (char*)columnName)) ) {
545                         char* virt = (char*)osrfHashGet(_f, "virtual");
546                         char* pos = (char*)osrfHashGet(_f, "array_position");
547
548                         if ( !virt || !pos || !(strcmp( virt, "true" )) ) continue;
549
550                         fmIndex = atoi( pos );
551                         osrfLogDebug(OSRF_LOG_MARK, "... Found column at position [%s]...", pos);
552                 }
553
554                 if (dbi_result_field_is_null(result, columnName)) {
555                         jsonObjectSetIndex( object, fmIndex, jsonNewObject(NULL) );
556                 } else {
557
558                         switch( type ) {
559
560                                 case DBI_TYPE_INTEGER :
561
562                                         if( attr & DBI_INTEGER_SIZE8 ) 
563                                                 jsonObjectSetIndex( object, fmIndex, 
564                                                         jsonNewNumberObject(dbi_result_get_longlong(result, columnName)));
565                                         else 
566                                                 jsonObjectSetIndex( object, fmIndex, 
567                                                         jsonNewNumberObject(dbi_result_get_long(result, columnName)));
568
569                                         break;
570
571                                 case DBI_TYPE_DECIMAL :
572                                         jsonObjectSetIndex( object, fmIndex, 
573                                                         jsonNewNumberObject(dbi_result_get_double(result, columnName)));
574                                         break;
575
576                                 case DBI_TYPE_STRING :
577                                         jsonObjectSetIndex( object, fmIndex, 
578                                                 jsonNewObject(dbi_result_get_string(result, columnName)));
579                                         break;
580
581                                 case DBI_TYPE_DATETIME :
582                                         _tmp_dt = dbi_result_get_datetime(result, columnName);
583
584                                         struct tm* gmdt = gmtime_r( &_tmp_dt, &_tmp_tm );
585                                         _tmp_dt = mktime( gmdt );
586                                         gmdt = gmtime_r( &_tmp_dt, &_tmp_tm );
587
588
589                                         if (!(attr & DBI_DATETIME_DATE)) {
590                                                 snprintf(dt_string, 255,
591                                                         "%02d:%02d:%02d",
592                                                         gmdt->tm_hour,
593                                                         gmdt->tm_min,
594                                                         gmdt->tm_sec
595                                                 );
596                                         } else if (!(attr & DBI_DATETIME_TIME)) {
597                                                 snprintf(dt_string, 255,
598                                                         "%4d-%02d-%02d",
599                                                         gmdt->tm_year + 1900,
600                                                         gmdt->tm_mon + 1,
601                                                         gmdt->tm_mday
602                                                 );
603                                         } else {
604                                                 snprintf(dt_string, 255,
605                                                         "%4d-%02d-%02dT%02d:%02d:%02dZ",
606                                                         gmdt->tm_year + 1900,
607                                                         gmdt->tm_mon + 1,
608                                                         gmdt->tm_mday,
609                                                         gmdt->tm_hour,
610                                                         gmdt->tm_min,
611                                                         gmdt->tm_sec
612                                                 );
613                                         }
614
615                                         jsonObjectSetIndex( object, fmIndex, jsonNewObject(dt_string) );
616
617                                         break;
618
619                                 case DBI_TYPE_BINARY :
620                                         osrfLogError( OSRF_LOG_MARK, 
621                                                 "Can't do binary at column %s : index %d", columnName, columnIndex - 1);
622                         }
623                 }
624         }
625
626         return object;
627 }
628
629
630
631