58{
59
60
61
62 int verbose_level = 1;
63 std::string connect_string;
64 std::string release;
65 std::string tag;
66 std::string working_schema;
67 std::string schema_file;
68 std::string data_file;
69 std::string query;
70 std::string class_name;
71 long ref_level = 0;
72 int schema_version = -1;
73 int data_version = -1;
74 bool remove_schema_file = false;
75 bool remove_data_file = false;
76
77 for(int i = 1; i < argc; i++) {
78 const char * cp = argv[i];
79
80 if(!strcmp(cp, "-h") || !strcmp(cp, "--help")) {
82 return (EXIT_SUCCESS);
83 }
84 else if(!strcmp(cp, "-v") || !strcmp(cp, "--verbose-level")) {
85 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { verbose_level = atoi(argv[i]); }
86 }
87 else if(!strcmp(cp, "-e") || !strcmp(cp, "--head-data-version")) {
88 if(data_version > 0) {
89 std::cerr << "ERROR: use either explicit data version (parameter -n) or HEAD version for provided release name (parameter -e ...)\n";
91 return EXIT_FAILURE;
92 }
93 data_version = 0;
94 if(argc > (i+1) && argv[i+1][0] != '-') {++i; release = argv[i]; }
95 }
96 else if(!strcmp(cp, "-t") || !strcmp(cp, "--tag")) {
97 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { tag = argv[i];}
98 }
99 else if(!strcmp(cp, "-s") || !strcmp(cp, "--schema-version")) {
100 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { schema_version = atoi(argv[i]); }
101 }
102 else if(!strcmp(cp, "-n") || !strcmp(cp, "--data-version")) {
103 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else {
104 if(!release.empty()) {
105 std::cerr << "ERROR: use either explicit data version (parameter -n) or HEAD version for provided release name (parameter -e ...)\n";
107 return EXIT_FAILURE;
108 }
109 data_version = atoi(argv[i]);
110 }
111 }
112 else if(!strcmp(cp, "-c") || !strcmp(cp, "--connect-string")) {
113 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { connect_string = argv[i]; }
114 }
115 else if(!strcmp(cp, "-w") || !strcmp(cp, "--working-schema")) {
116 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { working_schema = argv[i]; }
117 }
118 else if(!strcmp(cp, "-m") || !strcmp(cp, "--out-schema-file")) {
119 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { schema_file = argv[i]; }
120 }
121 else if(!strcmp(cp, "-f") || !strcmp(cp, "--out-data-file")) {
122 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { data_file = argv[i]; }
123 }
124 else if(!strcmp(cp, "-q") || !strcmp(cp, "--query")) {
125 if(i >= argc-2) {
no_param(cp);
return (EXIT_FAILURE); }
else { class_name = argv[++i]; query = argv[++i];}
126 }
127 else if(!strcmp(cp, "-r") || !strcmp(cp, "--reference-level")) {
128 if(++i == argc) {
no_param(cp);
return (EXIT_FAILURE); }
else { ref_level = atoi(argv[i]); }
129 }
130 else {
131 std::cerr << "ERROR: Unexpected parameter: \"" << cp << "\"\n\n";
133 return (EXIT_FAILURE);
134 }
135 }
136
137 if(data_version == -1 && tag.empty()) {
138 std::cerr << "ERROR: the data version or tag is required\n";
140 return EXIT_FAILURE;
141 }
142 else if(data_version > 0 && schema_version <= 0) {
143 std::cerr << "ERROR: an explicit data version cannot be used without schema version\n";
145 return EXIT_FAILURE;
146 }
147 else if(data_version != -1 && !tag.empty()) {
148 std::cerr << "ERROR: both schema version and tag are defined; only one can be used\n";
150 return EXIT_FAILURE;
151 }
152
153 if(connect_string.empty()) {
154 std::cerr << "ERROR: the connect string is required\n";
156 return EXIT_FAILURE;
157 }
158
159 if(working_schema.empty()) {
160 std::cerr << "ERROR: the working schema is required\n";
162 return EXIT_FAILURE;
163 }
164
165
166
167
169 ::OksKernel kernel;
170
171
172 try {
173
174
175
176 if(schema_file.empty()) {
177 schema_file = kernel.get_tmp_file("/tmp/unknown.schema.xml");
178 VerboseMsg2(
"The name of output schema file was not provided.\n * use file \'" << schema_file <<
'\'');
179 remove_schema_file = true;
180 }
181
183 ::OksFile * fh1 = kernel.new_schema(schema_file);
184
185
186
187
188 if(data_file.empty()) {
189 data_file = kernel.get_tmp_file("/tmp/unknown.data.xml");
190 VerboseMsg2(
"The name of output data file was not provided.\n * use file \'" << data_file <<
'\'');
191 remove_data_file = true;
192 }
193
195 ::OksFile * fh2 = kernel.new_data(data_file);
196
197 {
198 std::unique_ptr<coral::ConnectionService> connection;
199 {
201
202 if(!tag.empty() || data_version <= 0 || schema_version < 0) {
204 if(data_version <= 0 || schema_version < 0) {
205 throw std::runtime_error( (data_version == 0) ? "Cannot get head data" : "Cannot get given data" );
206 }
207 }
208
210
212 session->transaction().commit();
213
215 }
216
218 }
219
220 if(!query.empty()) {
221
222
223
224 OksObject::FSet objects;
225
226 if(OksClass * c = kernel.find_class(class_name)) {
227 OksQuery q(c, query);
228
229 if(q.good()) {
230 OksObject::List *
l =
c->execute_query(&q);
231 if(l && !
l->empty()) {
232 for(OksObject::List::iterator i =
l->begin(); i !=
l->end(); ++i) {
233 objects.insert(*i);
234 if(ref_level > 0) {
235 (*i)->references(objects, static_cast<unsigned long>(ref_level));
236 }
237 }
238 }
239 else {
240 std::cerr << "ERROR: failed to find any object of class \"" << class_name << "\" satisfying query \"" << query << "\", exiting...\n";
241 unlink(schema_file.c_str());
242 unlink(data_file.c_str());
243 return (EXIT_FAILURE);
244 }
245 }
246 else {
247 std::cerr << "ERROR: failed to parse query \"" << query << "\" for class class \"" << class_name << "\", exiting...\n";
248 unlink(schema_file.c_str());
249 unlink(data_file.c_str());
250 return (EXIT_FAILURE);
251 }
252 }
253 else {
254 std::cerr << "ERROR: cannot find class \"" << class_name << "\", exiting...\n";
255 unlink(schema_file.c_str());
256 unlink(data_file.c_str());
257 return (EXIT_FAILURE);
258 }
259
260 if(verbose_level > 2) {
261 std::cout << objects.size() << " objects to be saved as defined by query and reference-level parameters:\n";
262
263 for(OksObject::FSet::const_iterator i = objects.begin(); i != objects.end(); ++i) {
264 std::cout << " " << *i << std::endl;
265 }
266 }
267
268 std::string trash_data_file = kernel.get_tmp_file("/tmp/trash.data.xml");
269 OksFile * fh3 = kernel.new_data(trash_data_file);
270
271 if(!fh3) {
272 std::cerr << "ERROR: failed to create oks data file \'" << trash_data_file << "\'\n";
273 unlink(schema_file.c_str());
274 unlink(data_file.c_str());
275 return (EXIT_FAILURE);
276 }
277
278 VerboseMsg3(
"Filter out objects not satisfying query...");
279 for(OksObject::Set::const_iterator i = kernel.objects().begin(); i != kernel.objects().end(); ++i) {
280 if(objects.find(*i) == objects.end()) {
281 (*i)->set_file(fh3);
283 }
284 }
285
286 unlink(trash_data_file.c_str());
287 }
288
290
291 if(remove_schema_file) {
292 VerboseMsg2(
"Removing temporal schema file \'" << schema_file <<
"\'...");
293 unlink(schema_file.c_str());
294 }
295 else {
297 kernel.save_schema(fh1);
298 fh2->add_include_file(schema_file);
299 }
300
301 if(remove_data_file) {
302 VerboseMsg2(
"Removing temporal data file \'" << data_file <<
"\'...");
303 unlink(data_file.c_str());
304 }
305 else {
307 kernel.save_data(fh2, true);
308 }
309
311 }
312
313 catch ( coral::Exception& e ) {
314 std::cerr << "CORAL exception: " << e.what() << std::endl;
315 return 1;
316 }
317
318 catch ( oks::exception & ex) {
319 std::cerr << "OKS exception:\n" << ex << std::endl;
320 return 2;
321 }
322
323 catch ( std::exception& e ) {
324 std::cerr << "Standard C++ exception : " << e.what() << std::endl;
325 return 3;
326 }
327
328 catch ( ... ) {
329 std::cerr << "Exception caught (...)" << std::endl;
330 return 4;
331 }
332
333 return 0;
334}
coral::ISessionProxy * start_coral_session(const std::string &connect_string, int mode, std::unique_ptr< coral::ConnectionService > &connection, int verbose_level)
Start coral session.
void get_data_version(coral::ISessionProxy *session, const std::string &schema, const std::string &tag, int &schema_version, int &data_version, const char *release=0, int verbose_level=1, const char *dx="")
Get data version by tag.
unsigned long get_data(OksKernel &kernel, coral::ISessionProxy *session, const std::string &schema, int schema_version, int data_version, int verbose_level, const OksClass::Map *pattern=0)
Get data by version numbers.
static void no_param(const char *s)