IODA Bundle
UnitTests.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 /// \file .h
12 ///
13 /// @author Piotr Kuchta, ECMWF, Feb 2009
14 
15 #include <fstream>
16 
17 #include "eckit/io/FileHandle.h"
18 #include "eckit/io/BufferedHandle.h"
19 #include "eckit/log/Number.h"
20 #include "eckit/log/Timer.h"
21 #include "eckit/exception/Exceptions.h"
22 #include "eckit/sql/SQLParser.h"
23 #include "eckit/sql/SQLSelectFactory.h"
24 
25 #include "odc/api/Odb.h"
26 #include "odc/Comparator.h"
27 #include "odc/core/TablesReader.h"
29 #include "odc/DispatchingWriter.h"
30 #include "odc/ODBAPISettings.h"
31 #include "odc/odccapi.h"
32 #include "odc/Reader.h"
33 #include "odc/Select.h"
34 #include "odc/tools/CountTool.h"
35 #include "odc/tools/SplitTool.h"
36 #include "odc/tools/TestCase.h"
37 #include "odc/Writer.h"
38 
39 using namespace std;
40 using namespace eckit;
41 using namespace odc;
42 using namespace odc::sql;
43 
44 
45 typedef long long llong;
46 
47 static void foobar()
48 {
49  Reader in("concatenated.odb");
50  Reader::iterator it = in.begin();
51  Reader::iterator end = in.end();
52 
53  Writer<> out("copy_of_concatenated.odb");
54  Writer<>::iterator o = out.begin();
55  o->pass1(it, end);
56 
57  Comparator().compare("concatenated.odb", "copy_of_concatenated.odb");
58 }
59 //TESTCASE(foobar);
60 
62 {
63  // See UnitTest.sql as well
64  const char *data =
65  "x:INTEGER,y:INTEGER,v:DOUBLE\n"
66  "1,1,0.3\n"
67  "1,1,0.2\n"
68  "2,2,0.4\n"
69  "2,2,0.1\n"
70  ;
71 
72  eckit::FileHandle dh("selectAggregatedAndNonAggregated.odb");
73  dh.openForWrite(0);
74  AutoClose close(dh);
75  odc::api::odbFromCSV(data, dh);
76 }
77 
78 TEST(selectAggregatedAndNonAggregated)
79 {
81 
82  odc::Select oda("select x,min(v),max(v) from \"selectAggregatedAndNonAggregated.odb\";");
83  odc::Select::iterator it = oda.begin();
84 
85  double r0 = (*it)[0], r1 = (*it)[1], r2 = (*it)[2];
86 
87  Log::info() << "selectAggregatedAndNonAggregated: " << r0 << ", " << r1 << ", " << r2 << std::endl;
88 
89  ASSERT(Comparator::same(r0, 1));
90  ASSERT(Comparator::same(r1, 0.2));
91  ASSERT(Comparator::same(r2, 0.3));
92 
93  ++it;
94 
95  r0 = (*it)[0];
96  r1 = (*it)[1];
97  r2 = (*it)[2];
98 
99  Log::info() << "selectAggregatedAndNonAggregated: " << r0 << ", " << r1 << ", " << r2 << std::endl;
100 
101  //ASSERT((*it)[0] == 2 && (*it)[1] == 0.1);
102  ASSERT(r0 == 2);
103  ASSERT(r1 == 0.1);
104  ASSERT(r2 == 0.4);
105  ++it;
106  ASSERT( ! (it != oda.end() ));
107 }
108 
109 
111 {
112  Writer<> out("selectAggregatedAndNonAggregated2.odb");
113  Writer<>::iterator o = out.begin();
114  MetaData md(o->columns());
115 
116  md.addColumn /* <DS> */("x", "INTEGER");//, true, .0);
117  md.addColumn /* <DS> */("y", "INTEGER");//, true, .0);
118  md.addColumn /* <DS> */("v", "DOUBLE");//, true, .0);
119  o->columns(md);
120  o->writeHeader();
121 
122  for (size_t row = 0; row < 1000; ++row)
123  for (size_t x = 0; x < 10; (*o)[0] = ++x)
124  for (size_t y = 0; y < 10; (*o)[1] = ++y)
125  for (double v = 0; v < 10; (*o)[2] = ++v)
126  ++o;
127 }
128 
129 TEST(selectAggregatedAndNonAggregated2)
130 {
132  odc::Select oda("select x,min(v),y,max(v) from \"selectAggregatedAndNonAggregated2.odb\";");
133  odc::Select::iterator it = oda.begin();
134  unsigned long counter = 0;
135  for ( ; it != oda.end(); ++it, ++counter)
136  {
137  //double r0 = (*it)[0], r1 = (*it)[1], r2 = (*it)[2], r3 = (*it)[3];
138  //Log::info() << "selectAggregatedAndNonAggregated2: " << r0 << ", " << r1 << ", " << r2 << ", " << r3 << std::endl;
139  }
140  Log::info() << "selectAggregatedAndNonAggregated2: counter= " << counter << std::endl;
141  ASSERT(counter == 110);
142 }
143 
145 {
146  // See UnitTest.sql as well
147  const char *data =
148  "x:STRING,y:INTEGER,v:DOUBLE\n"
149  "'A',1,0.3\n"
150  "'A',1,0.2\n"
151  "'B',2,0.4\n"
152  "'B',2,0.1\n"
153  ;
154 
155  FileHandle dh("selectAggregatedAndNonAggregated3.odb");
156  dh.openForWrite(0);
157  AutoClose close(dh);
158  odc::api::odbFromCSV(data, dh);
159 }
160 
161 TEST(selectAggregatedAndNonAggregated3)
162 {
164 
165  odc::Select oda("select x,count(*) from \"selectAggregatedAndNonAggregated3.odb\";");
166  odc::Select::iterator it = oda.begin();
167  unsigned long counter = 0;
168  for ( ; it != oda.end(); ++it, ++counter)
169  {
170  double r0 = (*it)[0], r1 = (*it)[1];
171  Log::info() << "selectAggregatedAndNonAggregated3: " << r0 << ", " << r1 << std::endl;
172  }
173  Log::info() << "selectAggregatedAndNonAggregated3: counter= " << counter << std::endl;
174  ASSERT(counter == 2);
175 }
176 
177 
179 {
180  // See UnitTest.sql as well
181  const char *data =
182  "x:REAL,y:INTEGER,v:DOUBLE\n"
183  "100,1,0.3\n"
184  "100,1,0.2\n"
185  "101,2,0.4\n"
186  "101,2,0.1\n"
187  "NULL,1,0.1\n"
188  "NULL,2,0.2\n"
189  "NULL,3,0.3\n"
190  ;
191 
192  FileHandle dh("selectAggregatedAndNonAggregatedNULL.odb");
193  dh.openForWrite(0);
194  AutoClose close(dh);
195  odc::api::odbFromCSV(data, dh);
196 }
197 
198 TEST(selectAggregatedAndNonAggregatedNULL)
199 {
201 
202  odc::Select oda("select x,count(*) from \"selectAggregatedAndNonAggregatedNULL.odb\";");
203  odc::Select::iterator it = oda.begin();
204  unsigned long counter = 0;
205  for ( ; it != oda.end(); ++it, ++counter)
206  {
207  double r0 = (*it)[0], r1 = (*it)[1];
208  Log::info() << "selectAggregatedAndNonAggregatedNULL: " << r0 << ", " << r1 << std::endl;
209  }
210  Log::info() << "selectAggregatedAndNonAggregatedNULL: counter= " << counter << std::endl;
211  ASSERT(counter == 3);
212 }
213 
214 
215 /////////////////////////////////////////
216 // Regular expressions on the select list
217 
218 static void createDataForRegex1()
219 {
220  // See UnitTest.sql as well
221  const char *data =
222  "aa:INTEGER,ab:INTEGER,ba:INTEGER,bb:INTEGER\n"
223  "1,2,3,4\n"
224  "10,20,30,40\n"
225  "11,22,33,44\n"
226  ;
227 
228  FileHandle dh("regex1.odb");
229  dh.openForWrite(0);
230  AutoClose close(dh);
231  odc::api::odbFromCSV(data, dh);
232 }
233 
234 static void regex1()
235 {
236  //createDataForRegex1();
237  odc::Select oda("select \"/a.*/\" from \"regex1.odb\";");
238  odc::Select::iterator it = oda.begin();
239 
240  Log::info() << "regex1: " << it->columns() << std::endl;
241 
242  ASSERT(it->columns().size() == 2);
243 }
244 //TESTCASE(regex1);
245 
246 TEST(vector_syntax)
247 {
248 
249  const char *data =
250  "a:INTEGER,b:INTEGER\n"
251  "1,1\n"
252  "2,2\n"
253  "3,3\n"
254  "4,4\n"
255  "5,5\n"
256  "6,6\n"
257  "7,7\n"
258  "8,8\n"
259  "9,9\n"
260  "10,10\n"
261  ;
262 
263  {
264  FileHandle dh("vector_syntax.odb");
265  dh.openForWrite(0);
266  AutoClose close(dh);
267  odc::api::odbFromCSV(data, dh);
268  }
269 
270  const char *sql =
271  "set $X = [1,2,3,4,5];"
272  "select * from \"vector_syntax.odb\" where a in $X;"
273  ;
274 
275  odc::Select oda(sql);
276  odc::Select::iterator it = oda.begin();
277  odc::Select::iterator end = oda.end();
278  unsigned long counter = 0;
279  for ( ; it != oda.end(); ++it, ++counter)
280  ;
281  ASSERT(counter == 5);
282 }
283 
284 
285 TEST(bitfieldsLength)
286 {
287  Log::info() << "sizeof(eckit::log::Number::W)" << sizeof(eckit::log::Number::W) << std::endl;
288  Log::info() << "sizeof(double)" << sizeof(double) << std::endl;
289 
290  //>>> int('0b11100110011',2)
291  //1843
292  //>>> len('0b11100110011')
293  //13
294  //>>>
295  //stringstream s;
296  //eckit::log::Number::printBinary(s, 1843);
297  //string r = s.str();
298  //Log::info() << "r: " << r << std::endl;
299 
300  ASSERT(eckit::log::Number::printBinary(1843).size() == 11);
301  ASSERT(eckit::log::Number::printBinary(1843) == "11100110011");
302 
303  ASSERT(eckit::log::Number::printBinary(0).size() == 1);
304  ASSERT(eckit::log::Number::printBinary(0) == "0");
305 }
306 
307 /// ODB-85
308 TEST(bitfieldsPrintHexadecimal)
309 {
310  ASSERT(eckit::log::Number::printHexadecimal(1843) == std::string("733"));
311 
312  //eckit::Log::info() << eckit::log::Number::printHexadecimal(15) << std::endl;
313  ASSERT(eckit::log::Number::printHexadecimal(10) == std::string("a"));
314  ASSERT(eckit::log::Number::printHexadecimal(11) == std::string("b"));
315  ASSERT(eckit::log::Number::printHexadecimal(15) == std::string("f"));
316  ASSERT(eckit::log::Number::printHexadecimal(255) == std::string("ff"));
317 }
318 
320 {
321  const char *data =
322  "a:STRING,b:INTEGER\n"
323  "'aaa',1\n"
324  "'aaaa',2\n"
325  "'bbb',2\n"
326  "'bbbc',2\n"
327  ;
328  FileHandle dh("stringInWhere.odb");
329  dh.openForWrite(0);
330  AutoClose close(dh);
331  odc::api::odbFromCSV(data, dh);
332 }
333 
334 TEST(stringInWhere)
335 {
337  odc::Select oda("select * from 'stringInWhere.odb' where a = 'aaa';");
338 
339  unsigned long counter = 0;
340  for (odc::Select::iterator it = oda.begin(); it != oda.end(); ++it, ++counter)
341  ;
342  ASSERT(counter == 1);
343 }
344 
345 TEST(vector_syntax2)
346 {
347  const char* sql = "set $y = 100; set $x = [$y, 'a', 'b', [1, 2]];";
348  eckit::sql::SQLSession session;
349  eckit::sql::SQLParser::parseString(session, sql);
350 }
351 
352 // DISABLED FOR odb-to-request
353 //TEST(blocksSizes)
354 //{
355 // size_t numberOfBlocks = 0;
356 // off_t* offsets = 0;
357 // size_t* sizes = 0;
358 
359 // int r = get_blocks_offsets("TestFastODA2Request2BIG.odb", &numberOfBlocks, &offsets, &sizes);
360 // ASSERT(r == 0);
361 
362 // Log::info() << "num of blocks: " << numberOfBlocks << std::endl;
363 // for (size_t i = 0; i < numberOfBlocks; ++i)
364 // {
365 // Log::info() << "UnitTest: #" << i << ": offset: " << offsets[i] << ", sizes: " << sizes[i] << std::endl;
366 // }
367 // Log::info() << "blocksSizes: numberOfBlocks=" << numberOfBlocks << std::endl;
368 // ASSERT(numberOfBlocks == 5);
369 
370 // release_blocks_offsets(&offsets);
371 // release_blocks_sizes(&sizes);
372 //}
373 
374 
375 TEST(rownumber1)
376 {
377  const char *inputData = "a:INTEGER,b:INTEGER\n" "1,1\n" "2,2\n" "3,3\n" "4,4\n" "5,5\n" "6,6\n" "7,7\n" "8,8\n" "9,9\n" "10,10\n";
378  string path("Test_rownumber1.odb");
379 
380  {
381  FileHandle dh(path);
382  dh.openForWrite(0);
383  AutoClose close(dh);
384  odc::api::odbFromCSV(inputData, dh);
385  }
386 
387  string query("SELECT rownumber() from \"" + path + "\";");
388 
389  odc::Select select(query);
390  odc::Select::iterator it = select.begin();
391  odc::Select::iterator end = select.end();
392 
393  llong i = 0;
394  for (; it != end; ++it)
395  {
396  ASSERT((*it)[0] == ++i);
397  }
398  ASSERT(i == 10);
399 }
400 
401 TEST(sqlOutputFormatting)
402 {
403  /*
404  // See UnitTest.sql as well
405  const char *data =
406  "x:REAL,y:INTEGER,v:DOUBLE\n"
407  "100,1,0.3\n"
408  "100,1,0.2\n"
409  "101,2,0.4\n"
410  "101,2,0.1\n"
411  "NULL,1,0.1\n"
412  "NULL,2,0.2\n"
413  "NULL,3,0.3\n"
414  ;
415 
416  const char* testFile("sqlOutputFormatting.odb");
417 
418  FileHandle dh(testFile);
419  dh.openForWrite(0);
420  AutoClose close(dh);
421  odc::api::odbFromCSV(data, dh);
422 
423  bool doNotWriteColumnNames(false); // -T
424  bool doNotWriteNULL(false); // -N
425  string delimiter(" "); // -delimiter
426  string inputFile(testFile); // -i
427  string outputFile; // -o
428  string outputFormat; // default is ascii
429 
430  odc::sql::SQLSelectFactory::instance()
431  .config(odc::sql::SQLOutputConfig(doNotWriteColumnNames, doNotWriteNULL, delimiter, outputFile, outputFormat));
432 
433  ostream& out = cout;
434  odc::sql::SQLInteractiveSession session(out);
435  odc::sql::SQLParser p;
436 
437  FileHandle fh(inputFile);
438  fh.openForRead();
439  //p.parseString(StringTool::readFile(fileName), &fh, odc::sql::SQLSelectFactory::instance().config());
440  p.parseString("select x,y,v;", &fh, odc::sql::SQLSelectFactory::instance().config());
441  */
442 
443 }
444 
446 {
447  const char *data =
448  "u:REAL,v:REAL\n"
449  "11.7,-5.8\n"
450  "0.0,0.0\n"
451  "0,5.4\n"
452  "5.4,0.0\n"
453  ;
454 
455  FileHandle dh("uv.odb");
456  dh.openForWrite(0);
457  AutoClose close(dh);
458  odc::api::odbFromCSV(data, dh);
459 }
460 
461 TEST(windSpeedWindDirection)
462 {
464  string path("uv.odb");
465  string query("SELECT ff(u,v), dd(u,v), speed(u,v),dir(u,v), sqrt(u*u+v*v), fmod(atan2(-u,-v)+360.,360.) from \"" + path + "\";");
466 
467  odc::Select select(query);
468  odc::Select::iterator it = select.begin();
469  odc::Select::iterator end = select.end();
470 
471  llong i = 0;
472  for (; it != end; ++it)
473  {
474  Log::info() << " ff = " << (*it)[0] << " speed sqrt= " << (*it)[4] << std::endl;
475  Log::info() << " dd = " << (*it)[1] << " direction atan= " << (*it)[5] << std::endl;
476  ASSERT((*it)[0] == (*it)[4]);
477  ASSERT((*it)[1] == (*it)[5]);
478  }
479 }
480 
481 //TEST(odbcapi)
482 //{
483 // odc::tool::test::test_odacapi_setup_in_C(0,0);
484 // odc::tool::test::test_odacapi3(0,0);
485 //}
486 
487 
488 static void SplitTool_chunks()
489 {
490  const char * fn = "selectAggregatedAndNonAggregated.odb";
491  size_t n = odc::tool::CountTool::rowCount(fn);
492  vector<pair<Offset,Length> > chunks = odc::tool::SplitTool::getChunks(fn);
493 
494  Log::info() << "chunks.size():" << chunks.size() << std::endl;
495  ASSERT(chunks.size() == 1 && chunks[0].first == Offset(0) && chunks[0].second == Length(357));
496 }
497 //TESTCASE(SplitTool_chunks);
498 
499 
500 static void FilePool1()
501 {
502  //FilePool<SimpleFilePoolTraits> pool(1);
503 }
504 //TESTCASE(FilePool1);
505 
506 static void copyVectorToArray()
507 {
508  const size_t size = 1024;
509  const size_t n = 1000000;
510 
511  vector<double> v(size);
512  double a[size];
513 
514  {
515  Timer timer("std::copy");
516  for (size_t i = 0; i < n; ++i)
517  std::copy(v.begin(), v.end(), a);
518  }
519 
520  {
521  Timer timer("for loop");
522  for (size_t i = 0; i < n; ++i)
523  for (size_t j = 0; j < size; ++j)
524  a[j] = v[j];
525  }
526 
527 }
528 //TESTCASE(copyVectorToArray);
529 
530 
531 static void count(void *counter, const double* data, size_t n) { ++*((llong*)counter); }
532 static void *create_counter()
533 {
534  llong* r = new llong;
535  *r = 0;
536  return r;
537 }
538 static void destroy_counter(void *counter) { delete (llong*) counter; }
539 static void *reduce_counter(void *left, void *right)
540 {
541  llong *result = new llong;
542  *result = (*(llong *) left) + (*(llong *) right);
543  return result;
544 }
545 
546 class TemporaryPathName : public PathName {
547 public:
548  TemporaryPathName(const string &fn) : PathName (fn) {}
549  ~TemporaryPathName() { unlink(); }
550 };
551 
553 
554 TEST(hash_operator_on_select_list)
555 {
556  const char *data =
557  "x:INTEGER,y:INTEGER\n"
558  "1,1\n"
559  "2,2\n"
560  "3,3\n"
561  "4,4\n"
562  "5,5\n"
563  "6,6\n"
564  "7,7\n"
565  "8,8\n"
566  "9,9\n"
567  "10,10\n"
568  ;
569 
570  ScratchFile f("hash_operator_on_select_list.odb");
571 
572  {
573  FileHandle dh(f);
574  dh.openForWrite(0);
575  AutoClose close(dh);
576  odc::api::odbFromCSV(data, dh);
577  }
578 
579  string sql("select x,x#-1,x#1 from \"" + f + "\";");
580  odc::Select select(sql);
581  odc::Select::iterator it = select.begin();
582  odc::Select::iterator end = select.end();
583  for (; it != end; ++it)
584  {
585  Log::info() << it << std::endl;
586  }
587 
588 }
589 
590 /// Shift or hash (#) operator doesn't work in the WHERE clause.
591 /// This test doesn't test anything yet.
592 TEST(hash_operator_in_where)
593 {
594  const char *data =
595  "x:INTEGER,y:INTEGER\n"
596  "1,1\n"
597  "2,2\n"
598  "3,3\n"
599  "4,4\n"
600  "5,5\n"
601  "6,6\n"
602  "7,7\n"
603  "8,8\n"
604  "9,9\n"
605  "10,10\n"
606  ;
607 
608  ScratchFile f("hash_operator_in_where.odb");
609 
610  {
611  FileHandle dh(f);
612  dh.openForWrite(0);
613  AutoClose close(dh);
614  odc::api::odbFromCSV(data, dh);
615  }
616 
617  string sql("select x,x#-1,x#1 from \"" + f + "\" where x=2 and x#1=3;");
618  odc::Select select(sql);
619  odc::Select::iterator it = select.begin();
620  odc::Select::iterator end = select.end();
621  for (; it != end; ++it)
622  {
623  Log::info() << it << std::endl;
624  }
625 }
626 
627 TEST(bitfields_hash_operator)
628 {
629  PathName f("2000010106.4.0.odb");
630  //odc::Select select("select lat,lat#1 from \"" + f + "\"");
631  odc::Select select("select anflag@body,anflag.final@body,anflag.*@body from \"" + f + "\";");
632  odc::Select::iterator it = select.begin();
633  odc::Select::iterator end = select.end();
634  for (; it != end; ++it)
635  {
636  Log::info() << it << std::endl;
637  }
638 
639 }
640 
641 TEST(select_constant_value)
642 {
643  const char *sql =
644  "set $foo = 27;"
645  "select $foo;"
646  ;
647 
648  odc::Select o(sql);
649 
650  odc::Select::iterator it = o.begin();
651  odc::Select::iterator end = o.end();
652  unsigned long counter = 0;
653  for ( ; it != o.end(); ++it, ++counter)
654  {
655  Log::info() << it << std::endl;
656  CHECK_EQUAL(it->data(0), 27);
657  }
658  CHECK_EQUAL(counter, 1);
659 }
660 
661 TEST(include)
662 {
663  ofstream f("stuff.sql");
664  f
665  //<< "select * from \"file1.odb\";" << endl
666  << "set $foo = 10;" << endl
667  << "set $bar = 20;" << std::endl;
668  f.close();
669 
670  const char *sql =
671  "#include \"stuff.sql\"\n"
672  "set $baz = $bar;"
673  "select $foo * $bar;"
674  ;
675 
676  unsigned long counter = 0;
677  odc::Select o(sql);
678  for (odc::Select::iterator it(o.begin()), end(o.end());
679  it != o.end();
680  ++it, ++counter)
681  {
682  Log::info() << it << std::endl;
683  }
684 }
685 
686 TEST(log_error)
687 {
688  Log::error() << "Just a logger test" << std::endl;
689  // TODO: test Log::error writes to stderr
690  // TODO: test Log::error has a prefirx with timestamp and other things
691 }
692 
693 /*
694 TEST(create_table_using_variable)
695 {
696 
697  const char *sql =
698  "SET $c = { 2 : \"foo\" };\n"
699  "SET $s = 2;\n"
700  "CREATE TABLE t AS (c[$s]);"
701  ;
702 
703  unsigned long counter = 0;
704  odc::Select o(sql);
705  for (odc::Select::iterator it(o.begin()), end(o.end());
706  it != o.end();
707  ++it, ++counter)
708  {
709  Log::info() << it << std::endl;
710  }
711 }
712 */
713 
714 TEST(meta_data_reader_checks_if_file_truncated)
715 {
716  ASSERT(0 == system("dd if=disp.7.1.odb of=disp.7.1.odb.truncated bs=1914000 count=1"));
717  core::TablesReader mdr("disp.7.1.odb.truncated");
718  try {
719  for(auto it(mdr.begin()), end(mdr.end()); it != end; ++it)
720  ;
721  ASSERT(0 && "Scanning of truncated file did not fail");
722  } catch (odc::core::ODBIncomplete ex) {
723  Log::info() << "Scanning of truncated file disp.7.1.odb.truncated failed as expected." << std::endl;
724  }
725 }
726 
727 TEST(meta_data_reader_fails_scanning_corrupted_file)
728 {
729  ASSERT(0 == system("cat disp.7.1.odb disp.7.1.odb.truncated >corrupted.odb"));
730  core::TablesReader mdr("corrupted.odb");
731  try {
732  for(auto it(mdr.begin()), end(mdr.end()); it != end; ++it)
733  ;
734  ASSERT(0 && "Scanning of corrupted.odb did not fail");
735  } catch (odc::core::ODBIncomplete ex) {
736  Log::info() << "Scanning of corrupted.odb failed as expected." << std::endl;
737  }
738 }
739 
740 TEST(operator_ge)
741 {
742  const char *data =
743  "a:INTEGER,b:INTEGER\n"
744  "1,1\n"
745  "2,2\n"
746  "3,3\n"
747  "4,4\n"
748  "5,5\n"
749  "6,6\n"
750  "7,7\n"
751  "8,8\n"
752  "9,9\n"
753  "10,10\n"
754  ;
755 
756  {
757  FileHandle dh("1to10.odb");
758  dh.openForWrite(0);
759  AutoClose close(dh);
760  odc::api::odbFromCSV(data, dh);
761  }
762 
763  odc::Select odb("select a,b from \"1to10.odb\" where a >= 3;");
764  unsigned long counter = 0;
765  for (odc::Select::iterator it = odb.begin(), end = odb.end();
766  it != end;
767  ++it, ++counter)
768  ;
769  ASSERT(counter == 8);
770 }
771 
772 static void create_1to10()
773 {
774  const char *data =
775  "a:INTEGER,b:INTEGER\n"
776  "1,1\n"
777  "2,2\n"
778  "3,3\n"
779  "4,4\n"
780  "5,5\n"
781  "6,6\n"
782  "7,7\n"
783  "8,8\n"
784  "9,9\n"
785  "10,10\n"
786  ;
787 
788  FileHandle dh("1to10.odb");
789  dh.openForWrite(0);
790  AutoClose close(dh);
791  odc::api::odbFromCSV(data, dh);
792 }
793 
794 /* FIXME
795 TEST(Select_isNewDataset)
796 {
797  create_1to10();
798  size_t blocks (0);
799 
800  odc::Select odb("select * from \"1to10.odb\";");
801  for (odc::Select::iterator it = odb.begin(), end = odb.end();
802  it != end;
803  ++it)
804  if (it->isNewDataset())
805  ++blocks;
806  ASSERT(blocks == 1);
807 }
808 */
809 
810 template<typename T>
811 static void test_isNewDataset()
812 {
813  create_1to10();
814  size_t blocks (0);
815 
816  blocks = 0;
817  T odb("1to10.odb");
818  for (typename T::iterator it = odb.begin(), end = odb.end();
819  it != end;
820  ++it)
821  if (it->isNewDataset())
822  ++blocks;
823  ASSERT(blocks == 1);
824 }
825 
826 /*
827 TEST(Gabor)
828 {
829  const char * cfg =
830  "CLASS: class\n"
831  "DATE: andate\n"
832  "TIME: antime\n"
833  "TYPE: type\n"
834  "OBSGROUP: groupid\n"
835  "REPORTYPE: reportype\n"
836  "STREAM: stream\n"
837  "EXPVER: expver\n"
838  ;
839  const string fileName("/tmp/gabor/massaged.odb");
840 
841  odc::FastODA2Request<odc::ODA2RequestClientTraits> o2r;
842  o2r.parseConfig(cfg);
843 
844  eckit::OffsetList offsets;
845  eckit::LengthList lengths;
846  vector<ODAHandle*> handles;
847  bool rc = o2r.scanFile(fileName, offsets, lengths, handles);
848  for (size_t i = 0; i < handles.size(); ++i)
849  delete handles[i];
850  handles.clear();
851  ASSERT(rc);
852 
853  ASSERT(lengths.size());
854  ASSERT(lengths.size() == offsets.size());
855  for(size_t i = 1; i < offsets.size(); i++)
856  ASSERT(offsets[i] > offsets[i-1]);
857  size_t last = offsets.size()-1;
858  ASSERT(PathName(fileName).size() == offsets[last] + lengths[last]);
859 
860  unsigned long long cnt = o2r.rowsNumber();
861 
862  string filesRequest = "ARCHIVE,\n";
863  filesRequest += o2r.genRequest();
864 }
865 // FIXME
866 TEST(Reader_isNewDataset) { test_isNewDataset<Reader>(); }
867 // FIXME
868 TEST(MetaDataReader_isNewDataset) { test_isNewDataset<odc::MetaDataReader<MetaDataReaderIterator> >(); }
869 
870 TEST(create_temporary_table)
871 {
872  const char* sql = "CREATE "
873  " TEMPORARY "
874  " TABLE foo AS (col1 pk9real, col2 pk9real,) INHERITS (bar,baz);";
875 
876  cout << "Trying to execute: '" << sql << "'" << std::endl;
877 
878  odc::Select o(sql);
879  odc::tool::SQLTool::execute(sql);
880 
881 }
882 */
883 
884 
885 TEST(JULIAN_SECONDS)
886 {
887  ASSERT(1 == (*odc::Select("select julian_seconds(19750311,0) < julian_seconds(20140210,0) from dual;").begin())[0]);
888 }
889 
890 TEST(CREATE_TABLE_and_SELECT_INTO)
891 {
892  const char *inputData =
893  R"(a:INTEGER,b:INTEGER
894  1,1
895  2,2
896  3,3
897  4,4
898  5,5
899  6,6
900  7,7
901  8,8
902  9,9
903  10,10)";
904 
905  {
906  FileHandle dh("CREATE_TABLE_and_SELECT_INTO.odb");
907  dh.openForWrite(0);
908  AutoClose close(dh);
909  odc::api::odbFromCSV(inputData, dh);
910  }
911 
912  const char* sql = R"(
913  CREATE TYPE mybitfield AS (
914  codetype bit9,
915  instype bit10,
916  retrtype bit6,
917  geoarea bit6,
918  );
919 
920  CREATE TABLE "foo.odb" AS (
921  lat real,
922  lon real,
923  status mybitfield,
924  );
925 
926  SELECT a,b,a*b INTO "foo.odb" FROM "CREATE_TABLE_and_SELECT_INTO.odb";
927  )";
928 
929  {
930  odc::Select o(sql);
931  odc::Select::iterator it = o.begin();
932  unsigned long counter = 0;
933  Log::info() << "Inside select" << std::endl;
934  for ( ; it != o.end(); ++it, ++counter) {
935  Log::info() << "Getting a line..." << std::endl;
936  ;
937  }
938  Log::info() << "CREATE_TABLE_and_SELECT_INTO: counter=" << counter << endl;
939  }
940  system("ls -l foo.odb; ");
941  system((eckit::PathName("~/bin/odc").asString() + " header foo.odb").c_str());
942  system((eckit::PathName("~/bin/odc").asString() + " ls foo.odb").c_str());
943 }
944 
945 /*
946 TEST(SELECT_ALL)
947 {
948  ostream& L(eckit::Log::info());
949  odc::api::odbFromCSV("a:INTEGER,b:INTEGER\n1,2\n", "select_all_1.odb");
950  odc::api::odbFromCSV("a:INTEGER,b:INTEGER,c:INTEGER\n1,2,3\n", "select_all_2.odb");
951  system("cat select_all_1.odb select_all_2.odb >select_all.odb");
952 
953  L << "--- Test_SELECT_ALL: open select_all.odb" << endl;
954  odc::Select o("SELECT ALL * FROM \"select_all.odb\";");
955  odc::Select::iterator it (o.begin()), end (o.end());
956  L << "--- Test_SELECT_ALL: row #0" << endl;
957  ++it;
958  ASSERT(it->columns().size() == 2);
959  L << "--- Test_SELECT_ALL: row #1" << endl;
960  ++it;
961  ASSERT(it->columns().size() == 3);
962 }
963 */
964 
965 // ODB-106
966 TEST(SELECT_WHERE_0)
967 {
968  {
969  FileHandle dh("select_where_0.odb");
970  dh.openForWrite(0);
971  AutoClose close(dh);
972  odc::api::odbFromCSV("a:INTEGER,b:INTEGER\n1,2\n3,4\n", dh);
973  }
974  odc::Select o("SELECT * FROM \"select_where_0.odb\" WHERE 0;");
975  odc::Select::iterator it (o.begin()), end (o.end());
976  ++it;
977 }
978 
979 TEST(QuestionMarkHandlingWhenSplittingByStringColumn_ODB235)
980 {
981  const char *inFile ("ODB_235.odb");
982  const char *data (
983  "a:INTEGER,b:INTEGER,expver:STRING\n"
984  "1,1,'?'\n"
985  "2,2,'?'\n"
986  "3,3,'?'\n"
987  );
988  const char* outFileTemplate ("ODB_235_{a}_{expver}.odb");
989 
990  {
991  FileHandle dh(inFile);
992  dh.openForWrite(0);
993  AutoClose close(dh);
994  odc::api::odbFromCSV(data, dh);
995  }
996 
997  odc::Reader in(inFile);
998  odc::DispatchingWriter out(outFileTemplate, /*maxOpenFiles*/ 3);
999 
1000  odc::DispatchingWriter::iterator outIt (out.begin());
1001  outIt->pass1(in.begin(), in.end());
1002 
1003  ASSERT(PathName("ODB_235_1_?.odb").exists());
1004  ASSERT(PathName("ODB_235_2_?.odb").exists());
1005  ASSERT(PathName("ODB_235_3_?.odb").exists());
1006 
1007  PathName("ODB_235_1_?.odb").unlink();
1008  PathName("ODB_235_2_?.odb").unlink();
1009  PathName("ODB_235_3_?.odb").unlink();
1010  PathName("ODB_235.odb").unlink();
1011 }
1012 
1013 TEST(LegacyAPIExecuteSelectTwice)
1014 {
1015  const std::string fn("legacy_execute_select_twice.odb");
1016  {
1017  FileHandle dh(fn);
1018  dh.openForWrite(0);
1019  AutoClose close(dh);
1020  odc::api::odbFromCSV("a:INTEGER,b:INTEGER\n1,2\n3,4\n", dh);
1021  }
1022  odc::Select o(std::string("SELECT * FROM \"") + fn + "\";");
1023 
1024  int i (0), j (0);
1025 
1026  for (odc::Select::iterator it (o.begin()), end (o.end()); it != end; ++it)
1027  ++i;
1028 
1029  ASSERT(i == 2);
1030 
1031  for (odc::Select::iterator it (o.begin()), end (o.end()); it != end; ++it)
1032  ++j;
1033 
1034  ASSERT(j == 2);
1035 }
1036 
1037 TEST(LegacyAPITraverseReaderTwice)
1038 {
1039  const std::string fn("legacy_traverse_reader_twice.odb");
1040  {
1041  FileHandle dh(fn);
1042  dh.openForWrite(0);
1043  AutoClose close(dh);
1044  odc::api::odbFromCSV("a:INTEGER,b:INTEGER\n1,2\n3,4\n", dh);
1045  }
1046  odc::Reader o(fn);
1047 
1048  int i (0), j (0);
1049 
1050  for (odc::Reader::iterator it (o.begin()), end (o.end()); it != end; ++it)
1051  ++i;
1052 
1053  ASSERT(i == 2);
1055  for (odc::Reader::iterator it (o.begin()), end (o.end()); it != end; ++it)
1056  ++j;
1057 
1058  ASSERT(j == 2);
1059 }
1060 
1061 
1062 //void buildMultiHandle(eckit::MultiHandle&, const std::vector<std::string>&);
1063 //void buildMultiHandle(eckit::MultiHandle&, const std::string&);
1065 {
1066  eckit::DataHandle* in (odc::DataHandleFactory::openForRead("http://localhost/conv.odb"));
1067  //eckit::DataHandle* out (DataHandleFactory::openForWrite(const std::string&, const eckit::Length& = eckit::Length(0)));
1068 
1069  odc::Select o("select *;", *in);
1070 
1071  for (odc::Select::iterator it (o.begin()); it != o.end(); ++it)
1072  {
1073  Log::info() << "." << std::endl;
1074  }
1075 }
1076 
void oda
#define CHECK_EQUAL(expected, actual)
Definition: TestCase.h:77
static void createDataForRegex1()
Definition: UnitTests.cc:218
static void FilePool1()
Definition: UnitTests.cc:500
static void count(void *counter, const double *data, size_t n)
Definition: UnitTests.cc:531
TEST(selectAggregatedAndNonAggregated)
Definition: UnitTests.cc:78
static void create_stringInWhere_file()
Definition: UnitTests.cc:319
static void createDataForMixedAggregated3()
Definition: UnitTests.cc:144
static void createDataForMixedAggregatedNULL()
Definition: UnitTests.cc:178
static void SplitTool_chunks()
Definition: UnitTests.cc:488
static void destroy_counter(void *counter)
Definition: UnitTests.cc:538
static void createDataForWindSpeedWindDirection()
Definition: UnitTests.cc:445
static void regex1()
Definition: UnitTests.cc:234
static void createDataForMixedAggregated2()
Definition: UnitTests.cc:110
static void test_isNewDataset()
Definition: UnitTests.cc:811
TemporaryPathName ScratchFile
Definition: UnitTests.cc:552
static void createDataForMixedAggregated()
Definition: UnitTests.cc:61
static void create_1to10()
Definition: UnitTests.cc:772
static void copyVectorToArray()
Definition: UnitTests.cc:506
static void * reduce_counter(void *left, void *right)
Definition: UnitTests.cc:539
static void foobar()
Definition: UnitTests.cc:47
static void * create_counter()
Definition: UnitTests.cc:532
long long llong
Definition: UnitTests.cc:45
TemporaryPathName(const string &fn)
Definition: UnitTests.cc:548
bool compare(T1 &it1, const T1 &end1, T2 &it2, const T2 &end2, const std::string &desc1, const std::string &desc2)
Definition: Comparator.h:108
static eckit::DataHandle * openForRead(const std::string &)
const iterator end() const
Definition: Reader.cc:81
iterator begin()
Definition: Reader.cc:74
void writeHeader()
unsigned long pass1(T b, const T e)
DATA * data()
Definition: IteratorProxy.h:77
const core::MetaData & columns() const
Definition: IteratorProxy.h:94
const iterator end()
Definition: Select.cc:77
iterator begin()
Definition: Select.cc:81
iterator begin(bool openDataHandle=true)
Definition: Writer.cc:92
MetaData & addColumn(const std::string &name, const std::string &type)
Definition: MetaData.cc:279
static size_t rowCount(const eckit::PathName &)
Definition: CountTool.cc:24
static std::vector< std::pair< eckit::Offset, eckit::Length > > getChunks(const eckit::PathName &, size_t maxExpandedSize=100 *1024 *1024)
Definition: SplitTool.cc:66
IODA_DL void copy(const ObjectSelection &from, ObjectSelection &to, const ScaleMapping &scale_map)
Generic data copying function.
Definition: Copying.cpp:63
size_t odbFromCSV(DataHandle &dh_in, DataHandle &dh_out, const std::string &delimiter)
odbFromCSV returns number of lines imported
Definition: Odb.cc:375
Definition: ColumnInfo.h:23
Definition: encode.cc:30