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) {
33 "Usage: %s <path_to_config_file> <config_context> <create|update|delete>\n", argv[0] );
37 mnames = osrfNewHash();
39 char* config = strdup( argv[1] );
40 char* context = strdup( argv[2] );
41 char* method = strdup( argv[3] );
43 if (strcmp(method, "create") && strcmp(method, "update") && strcmp(method, "delete")) {
44 osrfLogError(OSRF_LOG_MARK, "Bad method name! Use create, update, or delete.");
48 // connect to the network
49 osrfLogInfo(OSRF_LOG_MARK, "Launching data loader with config %s and config context %s",
51 if (!osrfSystemBootstrapClientResc( config, context, APPNAME )) {
52 osrfLogError(OSRF_LOG_MARK, "Unable to bootstrap data loader!");
58 char* idl_filename = osrfConfigGetValue(NULL, "/IDL");
60 if (!(idl = oilsIDLInit( idl_filename ))) {
61 osrfLogError(OSRF_LOG_MARK, "Unable to load IDL!");
65 // Generate "create" method name for each
66 osrfStringArray* classes = osrfHashKeys(idl);
68 const char* classname;
71 while ((classname = osrfStringArrayGetString(classes, c_index++))) {
72 osrfHash* idlClass = oilsIDLFindPath("/%s", classname);
74 char* _fm = strdup( (char*)osrfHashGet(idlClass, "fieldmapper") );
75 char* part = strtok_r(_fm, ":", &st_tmp);
77 growing_buffer* _method_name = buffer_init(64);
78 buffer_fadd(_method_name, "%s.direct.%s", CSTORE, part);
80 while ((part = strtok_r(NULL, ":", &st_tmp))) {
81 buffer_fadd(_method_name, ".%s", part);
83 buffer_fadd(_method_name, ".%s", method);
85 char* m = buffer_release(_method_name);
86 osrfHashSet( mnames, m, classname );
88 osrfLogDebug(OSRF_LOG_MARK, "Constructed %s method named %s for %s", method, m, classname);
97 // Connect to open-ils.cstore
98 session = osrfAppSessionClientInit(CSTORE);
99 osrfAppSessionConnect(session);
101 // Start a transaction
102 if (!startTransaction()) {
103 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to start a transaction");
106 growing_buffer* json = buffer_init(128);
110 while ((c = getchar())) {
115 json_string = buffer_data(json);
118 if (!sendCommand(json_string)) {
121 "An error occured while attempting to %s an object: [%s]",
126 if (!rollbackTransaction()) {
127 osrfAppSessionFree(session);
128 osrfLogError(OSRF_LOG_MARK,
129 "An error occured while attempting to complete a transaction");
130 return E_ROLLBACKERROR;
133 osrfAppSessionFree(session);
134 return E_COMMANDERROR;
144 buffer_add_char( json, c );
151 // clean up, commit, go away
152 if (!commitTransaction()) {
153 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to complete a transaction");
154 osrfAppSessionFree(session);
155 return E_COMMITERROR;
158 osrfAppSessionFree(session);
164 static int commitTransaction () {
166 const jsonObject* data;
167 int req_id = osrfAppSessionSendRequest( session, NULL,
168 "open-ils.cstore.transaction.commit", 1 );
169 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
170 if ( (data = osrfMessageGetResult(res)) ) {
171 if(!(trans_id = jsonObjectGetString(data))) {
177 osrfMessageFree(res);
182 static int rollbackTransaction () {
184 const jsonObject* data;
185 int req_id = osrfAppSessionSendRequest( session, NULL,
186 "open-ils.cstore.transaction.rollback", 1 );
187 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
188 if ( (data = osrfMessageGetResult(res)) ) {
189 if(!(trans_id = jsonObjectGetString(data))) {
195 osrfMessageFree(res);
200 static int startTransaction () {
202 const jsonObject* data;
203 int req_id = osrfAppSessionSendRequest( session, NULL,
204 "open-ils.cstore.transaction.begin", 1 );
205 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
206 if ( (data = osrfMessageGetResult(res)) ) {
207 if(!(trans_id = jsonObjectToSimpleString(data))) {
213 osrfMessageFree(res);
218 static int sendCommand ( const char* json ) {
220 jsonObject* item = jsonParse(json);
222 if (!item->classname) {
223 osrfLogError(OSRF_LOG_MARK,
224 "Data loader cannot handle unclassed objects. Skipping [%s]!", json);
225 jsonObjectFree(item);
229 // Get the method name...
230 char* method_name = osrfHashGet( mnames, item->classname );
231 osrfLogDebug(OSRF_LOG_MARK, "Calling %s -> %s for %s", CSTORE, method_name, item->classname);
233 // make the param array
234 jsonObject* params = jsonNewObjectType( JSON_ARRAY );
235 jsonObjectSetIndex( params, 0, item );
236 jsonObjectSetIndex( params, 1, jsonParse("{\"quiet\":\"true\"}") );
238 const jsonObject* data;
239 int req_id = osrfAppSessionSendRequest( session, params, method_name, 1 );
240 jsonObjectFree(params);
242 osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
245 if ( !(data = osrfMessageGetResult(res)) ) {
248 osrfMessageFree(res);