IODA Bundle
odccapi.cc
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 ///
12 /// \file odbcapi.cc
13 ///
14 /// @author Piotr Kuchta, March 2009
15 
16 #include "eckit/runtime/Main.h"
17 
18 #include "odc/core/MetaData.h"
19 #include "odc/core/TablesReader.h"
20 #include "odc/ODAHandle.h"
21 #include "odc/ODBAPISettings.h"
22 #include "odc/ODBAPIVersion.h"
23 #include "odc/odccapi.h"
24 #include "odc/Select.h"
25 #include "odc/SelectIterator.h"
26 #include "odc/Reader.h"
27 #include "odc/Writer.h"
28 #include "odc/api/odc.h"
29 
30 using namespace eckit;
31 using namespace odc;
32 using namespace odc::api;
33 using namespace odc::core;
34 
35 char *dummyCommandLineArgs[] = { const_cast<char*>("odbcapi"), 0 };
36 
37 //#include "odbcapi.h"
38 
39 template <typename T, typename I>
40 int get_bitfield(T it,
41  int index,
42  char** bitfield_names,
43  char** bitfield_sizes,
44  int* nSize,
45  int* sSize)
46 {
47  I* iter = reinterpret_cast<I*>(it);
48  const eckit::sql::BitfieldDef& bitfieldDef(iter->columns()[index]->bitfieldDef());
49  eckit::sql::FieldNames fieldNames(bitfieldDef.first);
50  eckit::sql::Sizes sizes(bitfieldDef.second);
51 
52  std::stringstream ns, ss;
53  for (size_t i = 0; i < fieldNames.size(); ++i)
54  {
55  ns << fieldNames[i] << ":";
56  ss << sizes[i] << ":";
57  }
58 
59  std::string names(ns.str());
60  std::string ssizes(ss.str());
61 
62  //FIXME: the memory allocated by strdup should be freed on Fortran side
63  // TODO: This is a memory leak!!!
64  *bitfield_names = strdup(names.c_str());
65  *bitfield_sizes = strdup(ssizes.c_str());
66 
67  *nSize = names.size();
68  *sSize = ssizes.size();
69  return 0;
70 }
71 
72 extern "C" {
73 
74 void odb_start()
75 {
76  static const char *argv[2] = {"odb_start", 0};
77 
78  odb_start_with_args(1, const_cast<char **>(argv));
79 }
80 
81 int odc_git_sha1(const char** o) {
82  return odc_vcs_version(o);
83 }
84 
85 void odb_start_with_args(int argc, char* argv[])
86 {
87  eckit::Main::initialise(argc, argv);
88 }
89 
90 double odb_count(const char * filename)
91 {
92  double n = 0;
93 
94  PathName path = filename;
95  core::TablesReader mdReader(path);
96  for (auto it(mdReader.begin()), end(mdReader.end()); it != end; ++it) {
97  n += it->rowCount();
98  }
99  return n;
100 }
101 
102 int get_blocks_offsets(const char* fileName, size_t* numberOfBlocks, off_t** offsets, size_t** sizes)
103 {
104  core::TablesReader reader(fileName);
105 
106  OffsetList offs;
107  LengthList lengths;
108 
109  for (const auto& table : reader) {
110  offs.push_back(table.startPosition());
111  lengths.push_back(table.nextPosition() - table.startPosition());
112  }
113 
114  ASSERT(offs.size() == lengths.size());
115  size_t n = offs.size();
116 
117  *numberOfBlocks = n;
118  *offsets = new off_t[n];
119  *sizes = new size_t[n];
120 
121  for (size_t i = 0; i < n; ++i) {
122  (*offsets)[i] = offs[i];
123  (*sizes)[i] = lengths[i];
124  }
125 
126  return 0;
127 }
128 
129 int release_blocks_offsets(off_t** offsets) { delete [] *offsets; *offsets = 0; return 0; }
130 int release_blocks_sizes(size_t** sizes) { delete [] *sizes; *sizes = 0; return 0; }
131 
132 unsigned int odb_get_headerBufferSize() { return ODBAPISettings::instance().headerBufferSize(); }
133 void odb_set_headerBufferSize(unsigned int n) { ODBAPISettings::instance().headerBufferSize(n); }
134 
135 unsigned int odb_get_setvbufferSize() { return ODBAPISettings::instance().setvbufferSize(); }
136 void odb_set_setvbufferSize(unsigned int n) { ODBAPISettings::instance().setvbufferSize(n); }
137 
140 
141 
142 
143 /// @param config ignored for now.
144 oda_ptr odb_read_create(const char *config, int *err)
145 {
146  Reader* o = new Reader;
147  *err = !o;
148  return oda_ptr(o);
149 }
150 
151 oda_ptr odb_create(const char *config, int *err)
152 {
153  return odb_read_create(config, err);
154 }
155 
156 /// @param config ignored for now.
157 oda_ptr odb_select_create(const char *config, int *err)
158 {
159  // n.b. We will provide the output buffer --> don't get the Select to
160  // allocate its own internally
161  Select* o = new Select("", /* manageOwnBuffer */ false);
162  *err = !o;
163  return oda_ptr(o);
164 }
165 
166 /// @param config ignored for now.
167 oda_writer_ptr odb_writer_create(const char *config, int *err)
168 {
169  //PathName path = filename;
170  Writer<>* o = new Writer<>; //(path);
171  *err = !o;
172  return oda_writer_ptr(o);
173 }
174 
176 {
177  delete reinterpret_cast<Reader *>(o);
178  return 0;
179 }
180 
182 {
183  return odb_read_destroy(o);
184 }
185 
187 {
188  delete reinterpret_cast<Select *>(o);
189  return 0;
190 }
191 
193 {
194  delete reinterpret_cast<Writer<> *>(o);
195  return 0;
196 }
197 
199 {
200  Reader *o (reinterpret_cast<Reader*>(co));
201  std::string fileName (filename);
202  PathName fn (fileName);
203  if (! fn.exists())
204  {
205  *err = 2; //TODO: define error codes
206  return 0;
207  }
208 
209  ReaderIterator* iter (o->createReadIterator(fn));
210  *err = !iter;
211  return oda_read_iterator_ptr(iter);
212 
213 }
214 
216 {
217  Select *o (reinterpret_cast<Select*>(co));
218  try {
219  SelectIterator* iter (o->createSelectIterator(sql));
220  *err = !iter;
221  return oda_select_iterator_ptr(iter);
222  }
223  catch (eckit::CantOpenFile e)
224  {
225  *err = 1;
226  return 0;
227  }
228  catch (eckit::ReadError e)
229  {
230  *err = 2;
231  return 0;
232  }
233  catch (eckit::Exception& e) {
234  *err = 3;
235  eckit::Log::error() << "Caught exception: " << e << std::endl;
236  return 0;
237  }
238 }
239 
240 oda_select_iterator_ptr odb_create_select_iterator_from_file(oda_ptr co, const char *sql, const char *filename, int *err)
241 {
242  Select *o (reinterpret_cast<Select*>(co));
243 
244  std::string full_sql (std::string(sql) + " from \"" + std::string(filename) + "\"");
245 
246  SelectIterator* iter (o->createSelectIterator(full_sql));
247  *err = !iter;
248  return oda_select_iterator_ptr(iter);
249 }
250 
251 
253 {
254  delete reinterpret_cast<ReaderIterator*>(it);
255  return 0;
256 }
257 
259 {
260  delete reinterpret_cast<SelectIterator*>(it);
261  return 0;
262 }
263 
265 {
266  ReaderIterator* iter (reinterpret_cast<ReaderIterator*>(it));
267  *numberOfColumns = iter->columns().size();
268  return 0;
269 }
270 
272 {
273  ReaderIterator* iter (reinterpret_cast<ReaderIterator*>(it));
274  *size = iter->columns()[n]->dataSizeDoubles();
275  return 0;
276 }
277 
279 {
280  ReaderIterator* iter (reinterpret_cast<ReaderIterator*>(it));
281  *offset = iter->dataOffset(n);
282  return 0;
283 }
284 
286 {
287  SelectIterator* iter (reinterpret_cast<SelectIterator*>(it));
288  *numberOfColumns = iter->columns().size();
289  return 0;
290 }
291 
293 {
294  SelectIterator* iter (reinterpret_cast<SelectIterator*>(it));
295  *size = iter->columns()[n]->dataSizeDoubles();
296  return 0;
297 }
298 
300 {
301  SelectIterator* iter (reinterpret_cast<SelectIterator*>(it));
302  *offset = iter->dataOffset(n);
303  return 0;
304 }
305 
307 {
308  ReaderIterator* iter (reinterpret_cast<ReaderIterator*>(it));
309  *type = iter->columns()[n]->type();
310  return 0;
311 }
312 
314 {
315  SelectIterator* iter (reinterpret_cast<SelectIterator*>(it));
316  *type = iter->columns()[n]->type();
317  return 0;
318 }
319 
320 int odb_read_iterator_get_column_name(oda_read_iterator_ptr it, int n, char **name, int *size_name)
321 {
322  ReaderIterator* iter (reinterpret_cast<ReaderIterator*>(it));
323  *name = const_cast<char*>(iter->columns()[n]->name().c_str());
324  *size_name = iter->columns()[n]->name().length();
325  return 0;
326 }
327 
329 {
330  SelectIterator* iter (reinterpret_cast<SelectIterator*>(it));
331  *name = const_cast<char*>(iter->columns()[n]->name().c_str());
332  *size_name = iter->columns()[n]->name().length();
333  return 0;
334 }
335 
336 int odb_read_iterator_get_next_row(oda_read_iterator_ptr it, int count, double* data, int *new_dataset)
337 {
338  ReaderIterator* iter (reinterpret_cast<ReaderIterator*>(it));
339  if (! iter->next())
340  return 1;
341 
342  if (iter->isNewDataset())
343  *new_dataset = 1;
344  else
345  *new_dataset = 0;
346 
347  ASSERT(count >= 0);
348 
349  if (count != static_cast<int>(iter->columns().size()))
350  return 2; // TDOO: define error codes
351 
352 // ::memcpy(data, iter->data(), count * sizeof(data[0]));
353  ::memcpy(data, iter->data(), iter->rowDataSizeDoubles()*sizeof(double));
354 
355  return 0;
356 }
357 
358 int odb_select_iterator_get_next_row(oda_select_iterator_ptr it, int count, double* data, int *new_dataset)
359 {
360  SelectIterator* iter (reinterpret_cast<SelectIterator*>(it));
361 
362  iter->setOutputRowBuffer(data);
363 
364  if (!iter->next()) return 1;
365 
366  if (iter->isNewDataset()) {
367  *new_dataset = 1;
368  } else {
369  *new_dataset = 0;
370  }
371 
372  return 0;
373 }
374 
376 {
377  Writer<> *o (reinterpret_cast<Writer<> *>(co));
378  eckit::Length estimatedLength(0);
379  DataHandle *fh = ODBAPISettings::instance().appendToFile(PathName(std::string(filename)), estimatedLength, true);
380 
381  // TODO: make sure there's no leaks (FileHandle)
382  Writer<>::iterator_class* w (new Writer<>::iterator_class(*o, fh, false));
383  *err = !w;
384  return oda_write_iterator_ptr(w);
385 }
386 
388 {
389  Writer<> *o (reinterpret_cast<Writer<> *>(co));
390  eckit::Length estimatedLength(0);
391  DataHandle *fh = ODBAPISettings::instance().writeToFile(PathName(std::string(filename)), estimatedLength, true);
392 
393  // TODO: make sure there's no leaks (FileHandle)
394  Writer<>::iterator_class* w (new Writer<>::iterator_class(*o, fh, true));
395  *err = !w;
396  return oda_write_iterator_ptr(w);
397 }
398 
400 {
401  delete reinterpret_cast<Writer<>::iterator_class *>(wi);
402  return 0;
403 }
404 
406 {
407  Writer<>::iterator_class *w (reinterpret_cast<Writer<>::iterator_class *>(wi));
408  w->setNumberOfColumns(n);
409  return 0;
410 }
411 
412 int odb_write_iterator_set_column(oda_write_iterator_ptr wi, int index, int type, const char *name)
413 {
414  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
415  return w->setColumn(index, std::string(name), ColumnType(type));
416 }
417 
418 int odb_write_iterator_set_bitfield(oda_write_iterator_ptr wi, int index, int type, const char *name, const char* bitfieldNames, const char *bitfieldSizes)
419 {
420  std::string bnames (bitfieldNames);
421  std::string bsizes (bitfieldSizes);
422  eckit::sql::FieldNames (bitfield_names);
423  eckit::sql::Sizes (bitfield_sizes);
424 
425 // std::cout << " columnName = " << name << " " << bnames << " " << bsizes << std::endl;
426  size_t iprev (0);
427  for (size_t i (0); i < bnames.size(); i++)
428  {
429  if (bnames[i] == ':')
430  {
431  std::string name (bnames.substr(iprev,i-iprev));
432  iprev = i+1;
433  bitfield_names.push_back(name);
434  }
435  }
436 
437  iprev = 0;
438  for (size_t i (0); i < bsizes.size(); i++)
439  {
440  if (bsizes[i] == ':')
441  {
442  std::string name (bsizes.substr(iprev, i-iprev));
443  size_t size (atof(name.c_str())); // bit[0-9]+
444  iprev = i+1;
445  bitfield_sizes.push_back(size);
446  }
447  }
448 
449  eckit::sql::BitfieldDef bitfieldType(make_pair(bitfield_names, bitfield_sizes));
450 
451  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
452  std::string columnName(name);
453 
454  int rc (w->setBitfieldColumn(index, columnName, ColumnType(type), bitfieldType));
455  return rc;
456 }
457 
459 
460  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
461  w->columns()[n]->dataSizeDoubles(size);
462  return 0;
463 }
464 
466 
467  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
468  *size = w->rowDataSizeDoubles();
469  return 0;
470 }
471 
473 
474  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
475  *offset = w->dataOffset(n);
476  return 0;
477 }
478 
480 {
481  ReaderIterator* r (reinterpret_cast<ReaderIterator*>(ri));
482  if (index < 0 || long(r->columns().size()) < index)
483  {
484  std::stringstream ss;
485  ss << "odb_read_iterator_get_missing_value: index " << index
486  << " out of range, should be between 0 and " << r->columns().size();
487  throw UserError(ss.str());
488  }
489  *value = r->columns()[index]->missingValue();
490  return 0;
491 }
492 
494 
495  ReaderIterator* r = reinterpret_cast<ReaderIterator*>(ri);
496  *size = r->rowDataSizeDoubles();
497  return 0;
498 }
499 
501 
502  SelectIterator* r = reinterpret_cast<SelectIterator*>(ri);
503  *size = r->rowDataSizeDoubles();
504  return 0;
505 }
506 
508 {
509  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
510  w->missingValue(index, value);
511  return 0;
512 }
513 
515 {
516  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
517  w->writeHeader();
518  return 0;
519 }
520 
522 {
523  Writer<>::iterator_class * w (reinterpret_cast<Writer<>::iterator_class *>(wi));
524  return w->writeRow(data, count);
525 }
526 
528  int index,
529  char** bitfield_names,
530  char** bitfield_sizes,
531  int* nSize,
532  int* sSize)
533 { return get_bitfield<oda_read_iterator_ptr,ReaderIterator>(it, index, bitfield_names, bitfield_sizes, nSize, sSize); }
534 
536  int index,
537  char** bitfield_names,
538  char** bitfield_sizes,
539  int* nSize,
540  int* sSize)
541 { return get_bitfield<oda_select_iterator_ptr,SelectIterator>(it, index, bitfield_names, bitfield_sizes, nSize, sSize); }
542 
543 } // extern "C"
544 
static void count(void *counter, const double *data, size_t n)
Definition: UnitTests.cc:531
int odc_vcs_version(const char **sha1)
Definition: api/odc.cc:275
static unsigned int formatVersionMinor()
static unsigned int formatVersionMajor()
const double * data() const
size_t dataOffset(size_t i) const
The offset of a given column in the doubles[] data array.
const core::MetaData & columns() const
size_t rowDataSizeDoubles() const
SelectIterator * createSelectIterator(const std::string &)
Definition: Select.cc:69
size_t rowDataSizeDoubles() const
const core::MetaData & columns() const
void setOutputRowBuffer(double *data, size_t count=0)
Set an output buffer for retrieving the next row(s)
size_t dataOffset(size_t i) const
The offset of a given column in the doubles[] data array.
ITERATOR iterator_class
Definition: Writer.h:34
Definition: ColumnInfo.h:23
char * dummyCommandLineArgs[]
Definition: odccapi.cc:35
oda_read_iterator_ptr odb_create_read_iterator(oda_ptr co, const char *filename, int *err)
Definition: odccapi.cc:198
int odb_write_iterator_write_header(oda_write_iterator_ptr wi)
Definition: odccapi.cc:514
int odb_read_iterator_destroy(oda_read_iterator_ptr it)
Definition: odccapi.cc:252
int odb_read_iterator_get_no_of_columns(oda_read_iterator_ptr it, int *numberOfColumns)
Definition: odccapi.cc:264
int odb_select_destroy(oda_ptr o)
Definition: odccapi.cc:186
double odb_count(const char *filename)
Definition: odccapi.cc:90
int odb_select_iterator_destroy(oda_select_iterator_ptr it)
Definition: odccapi.cc:258
int odb_write_iterator_set_column(oda_write_iterator_ptr wi, int index, int type, const char *name)
Definition: odccapi.cc:412
oda_ptr odb_read_create(const char *config, int *err)
Definition: odccapi.cc:144
oda_ptr odb_select_create(const char *config, int *err)
Definition: odccapi.cc:157
int odb_read_iterator_get_missing_value(oda_read_iterator_ptr ri, int index, double *value)
Definition: odccapi.cc:479
int get_blocks_offsets(const char *fileName, size_t *numberOfBlocks, off_t **offsets, size_t **sizes)
Definition: odccapi.cc:102
void odb_set_setvbufferSize(unsigned int n)
Definition: odccapi.cc:136
int odb_select_iterator_get_next_row(oda_select_iterator_ptr it, int count, double *data, int *new_dataset)
Definition: odccapi.cc:358
void odb_start()
Definition: odccapi.cc:74
int odb_write_iterator_set_no_of_columns(oda_write_iterator_ptr wi, int n)
Definition: odccapi.cc:405
oda_writer_ptr odb_writer_create(const char *config, int *err)
Definition: odccapi.cc:167
int release_blocks_sizes(size_t **sizes)
Definition: odccapi.cc:130
int odb_select_iterator_get_bitfield(oda_select_iterator_ptr it, int index, char **bitfield_names, char **bitfield_sizes, int *nSize, int *sSize)
Definition: odccapi.cc:535
int odb_writer_destroy(oda_writer_ptr o)
Definition: odccapi.cc:192
int odb_read_iterator_get_column_type(oda_select_iterator_ptr it, int n, int *type)
Definition: odccapi.cc:306
int odc_git_sha1(const char **o)
Definition: odccapi.cc:81
int odb_write_iterator_set_next_row(oda_write_iterator_ptr wi, double *data, int count)
Definition: odccapi.cc:521
int odb_read_iterator_get_bitfield(oda_read_iterator_ptr it, int index, char **bitfield_names, char **bitfield_sizes, int *nSize, int *sSize)
Definition: odccapi.cc:527
int odb_select_iterator_get_column_offset(oda_select_iterator_ptr it, int n, int *offset)
Definition: odccapi.cc:299
int odb_select_iterator_get_column_type(oda_select_iterator_ptr it, int n, int *type)
Definition: odccapi.cc:313
oda_write_iterator_ptr odb_create_write_iterator(oda_ptr co, const char *filename, int *err)
Definition: odccapi.cc:387
int odb_select_iterator_get_no_of_columns(oda_select_iterator_ptr it, int *numberOfColumns)
Definition: odccapi.cc:285
unsigned int odb_get_headerBufferSize()
Definition: odccapi.cc:132
oda_write_iterator_ptr odb_create_append_iterator(oda_ptr co, const char *filename, int *err)
Definition: odccapi.cc:375
unsigned int odc_format_version_major()
Definition: odccapi.cc:138
int release_blocks_offsets(off_t **offsets)
Definition: odccapi.cc:129
oda_select_iterator_ptr odb_create_select_iterator(oda_ptr co, const char *sql, int *err)
Definition: odccapi.cc:215
int odb_select_iterator_get_row_buffer_size_doubles(oda_select_iterator_ptr ri, int *size)
Definition: odccapi.cc:500
int get_bitfield(T it, int index, char **bitfield_names, char **bitfield_sizes, int *nSize, int *sSize)
Definition: odccapi.cc:40
oda_select_iterator_ptr odb_create_select_iterator_from_file(oda_ptr co, const char *sql, const char *filename, int *err)
Definition: odccapi.cc:240
void odb_start_with_args(int argc, char *argv[])
Definition: odccapi.cc:85
int odb_read_iterator_get_column_name(oda_read_iterator_ptr it, int n, char **name, int *size_name)
Definition: odccapi.cc:320
int odb_write_iterator_set_column_size_doubles(oda_write_iterator_ptr wi, int n, int size)
Definition: odccapi.cc:458
oda_ptr odb_create(const char *config, int *err)
Definition: odccapi.cc:151
int odb_destroy(oda_ptr o)
Definition: odccapi.cc:181
unsigned int odb_get_setvbufferSize()
Definition: odccapi.cc:135
unsigned int odc_format_version_minor()
Definition: odccapi.cc:139
int odb_read_iterator_get_row_buffer_size_doubles(oda_read_iterator_ptr ri, int *size)
Definition: odccapi.cc:493
int odb_write_iterator_set_missing_value(oda_write_iterator_ptr wi, int index, double value)
Definition: odccapi.cc:507
int odb_write_iterator_destroy(oda_write_iterator_ptr wi)
Definition: odccapi.cc:399
int odb_write_iterator_get_column_offset(oda_write_iterator_ptr wi, int n, int *offset)
Definition: odccapi.cc:472
int odb_read_destroy(oda_ptr o)
Definition: odccapi.cc:175
int odb_read_iterator_get_column_offset(oda_read_iterator_ptr it, int n, int *offset)
Definition: odccapi.cc:278
int odb_select_iterator_get_column_size_doubles(oda_select_iterator_ptr it, int n, int *size)
Definition: odccapi.cc:292
int odb_write_iterator_get_row_buffer_size_doubles(oda_write_iterator_ptr wi, int *size)
Definition: odccapi.cc:465
int odb_write_iterator_set_bitfield(oda_write_iterator_ptr wi, int index, int type, const char *name, const char *bitfieldNames, const char *bitfieldSizes)
Definition: odccapi.cc:418
void odb_set_headerBufferSize(unsigned int n)
Definition: odccapi.cc:133
int odb_read_iterator_get_column_size_doubles(oda_read_iterator_ptr it, int n, int *size)
Definition: odccapi.cc:271
int odb_select_iterator_get_column_name(oda_select_iterator_ptr it, int n, char **name, int *size_name)
Definition: odccapi.cc:328
int odb_read_iterator_get_next_row(oda_read_iterator_ptr it, int count, double *data, int *new_dataset)
Definition: odccapi.cc:336
void * oda_write_iterator_ptr
Definition: odccapi.h:35
void * oda_read_iterator_ptr
Definition: odccapi.h:31
void * oda_select_iterator_ptr
Definition: odccapi.h:32
void * oda_writer_ptr
Definition: odccapi.h:34
void * oda_ptr
Definition: odccapi.h:30