]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/c-apps/oils_dataloader.c
basic C (non-Pg specific) dataloader
[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 "oils_idl.h"
10 #include "oils_utils.h"
11
12 #define CSTORE "open-ils.cstore"
13 #define APPNAME "oils_dataloader"
14
15 int sendCommand ( char* );
16 int startTransaction ( );
17 int endTransaction ( );
18
19
20 osrfHash* mnames = NULL;
21 osrfAppSession* session = NULL;
22 char* trans_id = NULL;
23
24 int main (int argc, char **argv) {
25         if( argc < 4 ) {
26                 fprintf( stderr, "Usage: %s <path_to_config_file> <config_context> <create|update|delete>\n", argv[0] );
27                 exit(0);
28         }
29
30         mnames = osrfNewHash();
31
32         char* config = strdup( argv[1] );
33         char* context = strdup( argv[2] );
34         char* method = strdup( argv[3] );
35
36         if (strcmp(method, "create") && strcmp(method, "update") && strcmp(method, "delete")) {
37                 osrfLogError(OSRF_LOG_MARK, "Bad method name!  Use create, update, or delete.");
38                 exit(1);
39         }
40
41         // connect to the network
42         osrfLogInfo(OSRF_LOG_MARK, "Launching data loader with config %s and config context %s", config, context );
43         if (!osrfSystemBootstrapClientResc( config, context, APPNAME )) {
44                 osrfLogError(OSRF_LOG_MARK, "Unable to bootstrap data loader!");
45                 exit(1);
46         }
47
48         // Load the IDL
49         osrfHash* idl;
50         char* idl_filename = osrfConfigGetValue(NULL, "/IDL");
51
52         if (!(idl = oilsIDLInit( idl_filename ))) {
53                 osrfLogError(OSRF_LOG_MARK, "Unable to load IDL!");
54                 exit(1);
55         }
56
57         // Generate "create" method name for each 
58         osrfStringArray* classes = osrfHashKeys(idl);
59         int c_index = 0;
60         char* classname;
61         char* st_tmp;
62
63         while ((classname = osrfStringArrayGetString(classes, c_index++))) {
64                 osrfHash* idlClass = oilsIDLFindPath("/%s", classname);
65
66                 char* _fm = strdup( (char*)osrfHashGet(idlClass, "fieldmapper") );
67                 char* part = strtok_r(_fm, ":", &st_tmp);
68
69                 growing_buffer* _method_name =  buffer_init(64);
70                 buffer_fadd(_method_name, "%s.direct.%s", CSTORE, part);
71
72                 while ((part = strtok_r(NULL, ":", &st_tmp))) {
73                         buffer_fadd(_method_name, ".%s", part);
74                 }
75                 buffer_fadd(_method_name, ".%s", method);
76
77                 char* m = buffer_data(_method_name);
78                 osrfHashSet( mnames, m, classname );
79
80                 osrfLogDebug(OSRF_LOG_MARK, "Constructed %s method named %s for %s", method, m, classname);
81
82                 buffer_free(_method_name);
83         }
84
85         free(config);
86         free(context);
87         free(idl_filename);
88
89         // Connect to open-ils.cstore
90         session = osrf_app_client_session_init(CSTORE);
91         osrfAppSessionConnect(session);
92
93         // Start a transaction
94         if (!startTransaction()) {
95                 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to start a transaction");
96         }
97
98         growing_buffer* json = buffer_init(128);
99         char* json_string;
100         char c;
101         int counter = 0;
102         while ((c = (char)getchar())) {
103                 switch(c) {
104                         case '\n':
105                         case EOF:
106                                 // End of a line
107                                 json_string = buffer_data(json);
108                                 buffer_reset(json);
109
110                                 if (!sendCommand(json_string)) {
111                                         osrfLogError(
112                                                 OSRF_LOG_MARK,
113                                                 "An error occured while attempting to %s an object: [%s]",
114                                                 method,
115                                                 json_string
116                                         );
117                                 }
118
119                                 counter++;
120
121                                 buffer_reset(json);
122                                 free(json_string);
123                                 break;
124
125                         default:
126                                 buffer_add_char( json, c );
127                                 break;
128                 }
129         }
130
131         // clean up, commit, go away
132         if (!endTransaction()) {
133                 osrfLogError(OSRF_LOG_MARK, "An error occured while attempting to complete a transaction");
134         }
135
136         osrfAppSessionFree(session);
137
138         return 0;
139 }
140
141 int endTransaction () {
142         int ret = 1;
143         jsonObject* data;
144         int req_id = osrfAppSessionMakeRequest( session, NULL, "open-ils.cstore.transaction.commit", 1, NULL );
145         osrf_message* res = osrfAppSessionRequestRecv( session, req_id, 5 );
146         if ( (data = jsonObjectClone(osrfMessageGetResult(res))) ) {
147                 if(!(trans_id = jsonObjectGetString(data))) {
148                         ret = 0;
149                 }
150                 jsonObjectFree(data);
151         } else {
152                 ret = 0;
153         }
154         osrfMessageFree(res);
155
156         return ret;
157 }
158
159 int startTransaction () {
160         int ret = 1;
161         jsonObject* data;
162         int req_id = osrfAppSessionMakeRequest( session, NULL, "open-ils.cstore.transaction.begin", 1, NULL );
163         osrf_message* res = osrfAppSessionRequestRecv( session, req_id, 5 );
164         if ( (data = osrfMessageGetResult(res)) ) {
165                 if(!(trans_id = jsonObjectToSimpleString(data))) {
166                         ret = 0;
167                 }
168         } else {
169                 ret = 0;
170         }
171         osrfMessageFree(res);
172
173         return ret;
174 }
175
176 int sendCommand ( char* json ) {
177         int ret = 1;
178         jsonObject* item = jsonParseString(json);
179
180         if (!item->classname) {
181                 osrfLogError(OSRF_LOG_MARK, "Data loader cannot handle unclassed objects.  Skipping [%s]!", json);
182                 jsonObjectFree(item);
183                 return 0;
184         }
185
186         // Get the method name...
187         char* method_name = osrfHashGet( mnames, item->classname );
188         osrfLogDebug(OSRF_LOG_MARK, "Calling %s -> %s for %s", CSTORE, method_name, item->classname);
189
190         // make the param array
191         jsonObject* params = jsonParseString("[]");
192         jsonObjectSetIndex( params, 0, item );
193         jsonObjectSetIndex( params, 1, jsonParseString("{\"quiet\":\"true\"}") );
194
195         jsonObject* data;
196         int req_id = osrfAppSessionMakeRequest( session, params, method_name, 1, NULL );
197         jsonObjectFree(params);
198
199         osrf_message* res = osrfAppSessionRequestRecv( session, req_id, 5 );
200
201         if (res) {
202                 if ( !(data = osrfMessageGetResult(res)) ) {
203                         ret = 0;
204                 }
205                 osrfMessageFree(res);
206         } else {
207                 ret = 0;
208         }
209
210         return ret;
211 }