1 #include <opensrf/osrf_app_session.h>
2 #include <opensrf/osrf_system.h>
3 #include <opensrf/osrfConfig.h>
4 #include <opensrf/utils.h>
5 #include <opensrf/osrf_hash.h>
9 #include "openils/oils_idl.h"
10 #include "openils/oils_utils.h"
12 #define CSTORE "open-ils.cstore"
13 #define APPNAME "oils_dataloader"
16 #define E_COMMITERROR -1
17 #define E_COMMANDERROR -2
18 #define E_ROLLBACKERROR -3
20 static int sendCommand ( const char* );
21 static int startTransaction ( );
22 static int commitTransaction ( );
23 static int rollbackTransaction ( );
26 static osrfHash* mnames = NULL;
27 static osrfAppSession* session = NULL;
28 static const char* trans_id = NULL;
30 int main (int argc, char **argv) {
32 fprintf( stderr, "Usage: %s <path_to_config_file> <config_context> <create|update|delete>\n", argv[0] );
36 mnames = osrfNewHash();
38 char* config = strdup( argv[1] );
39 char* context = strdup( argv[2] );
40 char* method = strdup( argv[3] );
42 if (strcmp(method, "create") && strcmp(method, "update") && strcmp(method, "delete")) {
43 osrfLogError(OSRF_LOG_MARK, "Bad method name! Use create, update, or delete.");
47 // connect to the network
48 osrfLogInfo(OSRF_LOG_MARK, "Launching data loader with config %s and config context %s", config, context );
49 if (!osrfSystemBootstrapClientResc( config, context, APPNAME )) {
50 osrfLogError(OSRF_LOG_MARK, "Unable to bootstrap data loader!");
56 char* idl_filename = osrfConfigGetValue(NULL, "/IDL");
58 if (!(idl = oilsIDLInit( idl_filename ))) {
59 osrfLogError(OSRF_LOG_MARK, "Unable to load IDL!");
63 // Generate "create" method name for each
64 osrfStringArray* classes = osrfHashKeys(idl);
66 const char* classname;
69 while ((classname = osrfStringArrayGetString(classes, c_index++))) {
70 osrfHash* idlClass = oilsIDLFindPath("/%s", classname);
72 char* _fm = strdup( (char*)osrfHashGet(idlClass, "fieldmapper") );
73 char* part = strtok_r(_fm, ":", &st_tmp);
75 growing_buffer* _method_name = buffer_init(64);
76 buffer_fadd(_method_name, "%s.direct.%s", CSTORE, part);
78 while ((part = strtok_r(NULL, ":", &st_tmp))) {
79 buffer_fadd(_method_name, ".%s", part);
81 buffer_fadd(_method_name, ".%s", method);
83 char* m = buffer_release(_method_name);
84 osrfHashSet( mnames, m, classname );
86 osrfLogDebug(OSRF_LOG_MARK, "Constructed %s method named %s for %s", method, m, classname);
95 // Connect to open-ils.cstore
96 session = osrfAppSessionClientInit(CSTORE);
97 osrfAppSessionConnect(session);
99 // Start a transaction
100 if (!startTransaction()) {
101 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to start a transaction");
104 growing_buffer* json = buffer_init(128);
108 while ((c = getchar())) {
113 json_string = buffer_data(json);
116 if (!sendCommand(json_string)) {
119 "An error occured while attempting to %s an object: [%s]",
124 if (!rollbackTransaction()) {
125 osrfAppSessionFree(session);
126 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to complete a transaction");
127 return E_ROLLBACKERROR;
130 osrfAppSessionFree(session);
131 return E_COMMANDERROR;
141 buffer_add_char( json, c );
148 // clean up, commit, go away
149 if (!commitTransaction()) {
150 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to complete a transaction");
151 osrfAppSessionFree(session);
152 return E_COMMITERROR;
155 osrfAppSessionFree(session);
161 static int commitTransaction () {
163 const jsonObject* data;
164 int req_id = osrfAppSessionSendRequest( session, NULL, "open-ils.cstore.transaction.commit", 1 );
165 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
166 if ( (data = osrfMessageGetResult(res)) ) {
167 if(!(trans_id = jsonObjectGetString(data))) {
173 osrfMessageFree(res);
178 static int rollbackTransaction () {
180 const jsonObject* data;
181 int req_id = osrfAppSessionSendRequest( session, NULL, "open-ils.cstore.transaction.rollback", 1 );
182 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
183 if ( (data = osrfMessageGetResult(res)) ) {
184 if(!(trans_id = jsonObjectGetString(data))) {
190 osrfMessageFree(res);
195 static int startTransaction () {
198 int req_id = osrfAppSessionSendRequest( session, NULL, "open-ils.cstore.transaction.begin", 1 );
199 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
200 if ( (data = osrfMessageGetResult(res)) ) {
201 if(!(trans_id = jsonObjectToSimpleString(data))) {
207 osrfMessageFree(res);
212 static int sendCommand ( const char* json ) {
214 jsonObject* item = jsonParse(json);
216 if (!item->classname) {
217 osrfLogError(OSRF_LOG_MARK, "Data loader cannot handle unclassed objects. Skipping [%s]!", json);
218 jsonObjectFree(item);
222 // Get the method name...
223 char* method_name = osrfHashGet( mnames, item->classname );
224 osrfLogDebug(OSRF_LOG_MARK, "Calling %s -> %s for %s", CSTORE, method_name, item->classname);
226 // make the param array
227 jsonObject* params = jsonNewObjectType( JSON_ARRAY );
228 jsonObjectSetIndex( params, 0, item );
229 jsonObjectSetIndex( params, 1, jsonParse("{\"quiet\":\"true\"}") );
232 int req_id = osrfAppSessionSendRequest( session, params, method_name, 1 );
233 jsonObjectFree(params);
235 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
238 if ( !(data = osrfMessageGetResult(res)) ) {
241 osrfMessageFree(res);