]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/c-apps/oils_dataloader.c
Stamping upgrade for relaxing rank_ou sorting
[working/Evergreen.git] / Open-ILS / src / c-apps / oils_dataloader.c
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>
6
7 #include <stdio.h>
8
9 #include "openils/oils_idl.h"
10 #include "openils/oils_utils.h"
11
12 #define CSTORE "open-ils.cstore"
13 #define APPNAME "oils_dataloader"
14
15 #define E_SUCCESS 0
16 #define E_COMMITERROR -1
17 #define E_COMMANDERROR -2
18 #define E_ROLLBACKERROR -3
19
20 static int sendCommand ( const char* );
21 static int startTransaction ( );
22 static int commitTransaction ( );
23 static int rollbackTransaction ( );
24
25
26 static osrfHash* mnames = NULL;
27 static osrfAppSession* session = NULL;
28 static const char* trans_id = NULL;
29
30 int main (int argc, char **argv) {
31         if( argc < 4 ) {
32                 fprintf( stderr,
33                         "Usage: %s <path_to_config_file> <config_context> <create|update|delete>\n", argv[0] );
34                 exit(0);
35         }
36
37         mnames = osrfNewHash();
38
39         char* config = strdup( argv[1] );
40         char* context = strdup( argv[2] );
41         char* method = strdup( argv[3] );
42
43         if (strcmp(method, "create") && strcmp(method, "update") && strcmp(method, "delete")) {
44                 osrfLogError(OSRF_LOG_MARK, "Bad method name!  Use create, update, or delete.");
45                 exit(1);
46         }
47
48         // connect to the network
49         osrfLogInfo(OSRF_LOG_MARK, "Launching data loader with config %s and config context %s",
50                 config, context );
51         if (!osrfSystemBootstrapClientResc( config, context, APPNAME )) {
52                 osrfLogError(OSRF_LOG_MARK, "Unable to bootstrap data loader!");
53                 exit(1);
54         }
55
56         // Load the IDL
57         osrfHash* idl;
58         char* idl_filename = osrfConfigGetValue(NULL, "/IDL");
59
60         if (!(idl = oilsIDLInit( idl_filename ))) {
61                 osrfLogError(OSRF_LOG_MARK, "Unable to load IDL!");
62                 exit(1);
63         }
64
65         // Generate "create" method name for each
66         osrfStringArray* classes = osrfHashKeys(idl);
67         int c_index = 0;
68         const char* classname;
69         char* st_tmp = NULL;
70
71         while ((classname = osrfStringArrayGetString(classes, c_index++))) {
72                 osrfHash* idlClass = oilsIDLFindPath("/%s", classname);
73
74                 char* _fm = strdup( (char*)osrfHashGet(idlClass, "fieldmapper") );
75                 char* part = strtok_r(_fm, ":", &st_tmp);
76
77                 growing_buffer* _method_name =  buffer_init(64);
78                 buffer_fadd(_method_name, "%s.direct.%s", CSTORE, part);
79
80                 while ((part = strtok_r(NULL, ":", &st_tmp))) {
81                         buffer_fadd(_method_name, ".%s", part);
82                 }
83                 buffer_fadd(_method_name, ".%s", method);
84
85                 char* m = buffer_release(_method_name);
86                 osrfHashSet( mnames, m, classname );
87
88                 osrfLogDebug(OSRF_LOG_MARK, "Constructed %s method named %s for %s", method, m, classname);
89
90                 free(_fm);
91         }
92
93         free(config);
94         free(context);
95         free(idl_filename);
96
97         // Connect to open-ils.cstore
98         session = osrfAppSessionClientInit(CSTORE);
99         osrfAppSessionConnect(session);
100
101         // Start a transaction
102         if (!startTransaction()) {
103                 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to start a transaction");
104         }
105
106         growing_buffer* json = buffer_init(128);
107         char* json_string;
108         int c;
109         int counter = 0;
110         while ((c = getchar())) {
111                 switch(c) {
112                         case '\n':
113                         case EOF:
114                                 // End of a line
115                                 json_string = buffer_data(json);
116                                 buffer_reset(json);
117
118                                 if (!sendCommand(json_string)) {
119                                         osrfLogError(
120                                                 OSRF_LOG_MARK,
121                                                 "An error occured while attempting to %s an object: [%s]",
122                                                 method,
123                                                 json_string
124                                         );
125
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;
131                                         }
132
133                                         osrfAppSessionFree(session);
134                                         return E_COMMANDERROR;
135                                 }
136
137                                 counter++;
138
139                                 buffer_reset(json);
140                                 free(json_string);
141                                 break;
142
143                         default:
144                                 buffer_add_char( json, c );
145                                 break;
146                 }
147         }
148
149         buffer_free(json);
150
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;
156         }
157
158         osrfAppSessionFree(session);
159         free(method);
160
161         return E_SUCCESS;
162 }
163
164 static int commitTransaction () {
165         int ret = 1;
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))) {
172                         ret = 0;
173                 }
174         } else {
175                 ret = 0;
176         }
177         osrfMessageFree(res);
178
179         return ret;
180 }
181
182 static int rollbackTransaction () {
183         int ret = 1;
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))) {
190                         ret = 0;
191                 }
192         } else {
193                 ret = 0;
194         }
195         osrfMessageFree(res);
196
197         return ret;
198 }
199
200 static int startTransaction () {
201         int ret = 1;
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))) {
208                         ret = 0;
209                 }
210         } else {
211                 ret = 0;
212         }
213         osrfMessageFree(res);
214
215         return ret;
216 }
217
218 static int sendCommand ( const char* json ) {
219         int ret = 1;
220         jsonObject* item = jsonParse(json);
221
222         if (!item->classname) {
223                 osrfLogError(OSRF_LOG_MARK,
224                         "Data loader cannot handle unclassed objects.  Skipping [%s]!", json);
225                 jsonObjectFree(item);
226                 return 0;
227         }
228
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);
232
233         // make the param array
234         jsonObject* params = jsonNewObjectType( JSON_ARRAY );
235         jsonObjectSetIndex( params, 0, item );
236         jsonObjectSetIndex( params, 1, jsonParse("{\"quiet\":\"true\"}") );
237
238         const jsonObject* data;
239         int req_id = osrfAppSessionSendRequest( session, params, method_name, 1 );
240         jsonObjectFree(params);
241
242         osrfMessage* res = osrfAppSessionRequestRecv( session, req_id, 5 );
243
244         if (res) {
245                 if ( !(data = osrfMessageGetResult(res)) ) {
246                         ret = 0;
247                 }
248                 osrfMessageFree(res);
249         } else {
250                 ret = 0;
251         }
252
253         return ret;
254 }