basic C (non-Pg specific) dataloader
authormiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 2 Aug 2006 01:18:35 +0000 (01:18 +0000)
committermiker <miker@dcc99617-32d9-48b4-a31d-7c20da2025e4>
Wed, 2 Aug 2006 01:18:35 +0000 (01:18 +0000)
git-svn-id: svn://svn.open-ils.org/ILS/trunk@5221 dcc99617-32d9-48b4-a31d-7c20da2025e4

Open-ILS/src/c-apps/oils_dataloader.c [new file with mode: 0644]

diff --git a/Open-ILS/src/c-apps/oils_dataloader.c b/Open-ILS/src/c-apps/oils_dataloader.c
new file mode 100644 (file)
index 0000000..7a647dc
--- /dev/null
@@ -0,0 +1,211 @@
+#include <opensrf/osrf_app_session.h>
+#include <opensrf/osrf_system.h>
+#include <opensrf/osrfConfig.h>
+#include <opensrf/utils.h>
+#include <opensrf/osrf_hash.h>
+
+#include <stdio.h>
+
+#include "oils_idl.h"
+#include "oils_utils.h"
+
+#define CSTORE "open-ils.cstore"
+#define APPNAME "oils_dataloader"
+
+int sendCommand ( char* );
+int startTransaction ( );
+int endTransaction ( );
+
+
+osrfHash* mnames = NULL;
+osrfAppSession* session = NULL;
+char* trans_id = NULL;
+
+int main (int argc, char **argv) {
+       if( argc < 4 ) {
+               fprintf( stderr, "Usage: %s <path_to_config_file> <config_context> <create|update|delete>\n", argv[0] );
+               exit(0);
+       }
+
+       mnames = osrfNewHash();
+
+       char* config = strdup( argv[1] );
+       char* context = strdup( argv[2] );
+       char* method = strdup( argv[3] );
+
+       if (strcmp(method, "create") && strcmp(method, "update") && strcmp(method, "delete")) {
+               osrfLogError(OSRF_LOG_MARK, "Bad method name!  Use create, update, or delete.");
+               exit(1);
+       }
+
+       // connect to the network
+       osrfLogInfo(OSRF_LOG_MARK, "Launching data loader with config %s and config context %s", config, context );
+       if (!osrfSystemBootstrapClientResc( config, context, APPNAME )) {
+               osrfLogError(OSRF_LOG_MARK, "Unable to bootstrap data loader!");
+               exit(1);
+       }
+
+       // Load the IDL
+       osrfHash* idl;
+       char* idl_filename = osrfConfigGetValue(NULL, "/IDL");
+
+       if (!(idl = oilsIDLInit( idl_filename ))) {
+               osrfLogError(OSRF_LOG_MARK, "Unable to load IDL!");
+               exit(1);
+       }
+
+       // Generate "create" method name for each 
+       osrfStringArray* classes = osrfHashKeys(idl);
+       int c_index = 0;
+       char* classname;
+       char* st_tmp;
+
+       while ((classname = osrfStringArrayGetString(classes, c_index++))) {
+               osrfHash* idlClass = oilsIDLFindPath("/%s", classname);
+
+               char* _fm = strdup( (char*)osrfHashGet(idlClass, "fieldmapper") );
+               char* part = strtok_r(_fm, ":", &st_tmp);
+
+               growing_buffer* _method_name =  buffer_init(64);
+               buffer_fadd(_method_name, "%s.direct.%s", CSTORE, part);
+
+               while ((part = strtok_r(NULL, ":", &st_tmp))) {
+                       buffer_fadd(_method_name, ".%s", part);
+               }
+               buffer_fadd(_method_name, ".%s", method);
+
+               char* m = buffer_data(_method_name);
+               osrfHashSet( mnames, m, classname );
+
+               osrfLogDebug(OSRF_LOG_MARK, "Constructed %s method named %s for %s", method, m, classname);
+
+               buffer_free(_method_name);
+       }
+
+       free(config);
+       free(context);
+       free(idl_filename);
+
+       // Connect to open-ils.cstore
+       session = osrf_app_client_session_init(CSTORE);
+       osrfAppSessionConnect(session);
+
+       // Start a transaction
+       if (!startTransaction()) {
+               osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to start a transaction");
+       }
+
+       growing_buffer* json = buffer_init(128);
+       char* json_string;
+       char c;
+       int counter = 0;
+       while ((c = (char)getchar())) {
+               switch(c) {
+                       case '\n':
+                       case EOF:
+                               // End of a line
+                               json_string = buffer_data(json);
+                               buffer_reset(json);
+
+                               if (!sendCommand(json_string)) {
+                                       osrfLogError(
+                                               OSRF_LOG_MARK,
+                                               "An error occured while attempting to %s an object: [%s]",
+                                               method,
+                                               json_string
+                                       );
+                               }
+
+                               counter++;
+
+                               buffer_reset(json);
+                               free(json_string);
+                               break;
+
+                       default:
+                               buffer_add_char( json, c );
+                               break;
+               }
+       }
+
+       // clean up, commit, go away
+       if (!endTransaction()) {
+               osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to complete a transaction");
+       }
+
+       osrfAppSessionFree(session);
+
+       return 0;
+}
+
+int endTransaction () {
+       int ret = 1;
+       jsonObject* data;
+       int req_id = osrfAppSessionMakeRequest( session, NULL, "open-ils.cstore.transaction.commit", 1, NULL );
+       osrf_message* res = osrfAppSessionRequestRecv( session, req_id, 5 );
+       if ( (data = jsonObjectClone(osrfMessageGetResult(res))) ) {
+               if(!(trans_id = jsonObjectGetString(data))) {
+                       ret = 0;
+               }
+               jsonObjectFree(data);
+       } else {
+               ret = 0;
+       }
+       osrfMessageFree(res);
+
+       return ret;
+}
+
+int startTransaction () {
+       int ret = 1;
+       jsonObject* data;
+       int req_id = osrfAppSessionMakeRequest( session, NULL, "open-ils.cstore.transaction.begin", 1, NULL );
+       osrf_message* res = osrfAppSessionRequestRecv( session, req_id, 5 );
+       if ( (data = osrfMessageGetResult(res)) ) {
+               if(!(trans_id = jsonObjectToSimpleString(data))) {
+                       ret = 0;
+               }
+       } else {
+               ret = 0;
+       }
+       osrfMessageFree(res);
+
+       return ret;
+}
+
+int sendCommand ( char* json ) {
+       int ret = 1;
+       jsonObject* item = jsonParseString(json);
+
+       if (!item->classname) {
+               osrfLogError(OSRF_LOG_MARK, "Data loader cannot handle unclassed objects.  Skipping [%s]!", json);
+               jsonObjectFree(item);
+               return 0;
+       }
+
+       // Get the method name...
+       char* method_name = osrfHashGet( mnames, item->classname );
+       osrfLogDebug(OSRF_LOG_MARK, "Calling %s -> %s for %s", CSTORE, method_name, item->classname);
+
+       // make the param array
+       jsonObject* params = jsonParseString("[]");
+       jsonObjectSetIndex( params, 0, item );
+       jsonObjectSetIndex( params, 1, jsonParseString("{\"quiet\":\"true\"}") );
+
+       jsonObject* data;
+       int req_id = osrfAppSessionMakeRequest( session, params, method_name, 1, NULL );
+       jsonObjectFree(params);
+
+       osrf_message* res = osrfAppSessionRequestRecv( session, req_id, 5 );
+
+       if (res) {
+               if ( !(data = osrfMessageGetResult(res)) ) {
+                       ret = 0;
+               }
+               osrfMessageFree(res);
+       } else {
+               ret = 0;
+       }
+
+       return ret;
+}