6726bc2409a2231e014c11e3411780b439970795
[framework/web/wrt-commons.git] / tests / db / test_orm.cpp
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 #include <dpl/test/test_runner.h>
17 #include <dpl/foreach.h>
18 #include <dpl/db/thread_database_support.h>
19 #include <dpl/optional_typedefs.h>
20 #include <generator_dpl_orm_test.h>
21 #include <sstream>
22
23 const char* PATH_DB = "/opt/share/wrt/wrt-commons/tests/db/dpl_orm_test.db";
24
25 //utils
26
27 #define TEST_REPETITION 16
28
29 class SmartAttach
30 {
31   public:
32
33     SmartAttach(bool autoattach = true) :
34         m_interface(PATH_DB,
35                     DPL::DB::SqlConnection::Flag::UseLucene),
36         m_autoattach(autoattach)
37     {
38         if (m_autoattach) {
39             m_interface.AttachToThread(DPL::DB::SqlConnection::Flag::RW);
40         }
41     }
42
43     ~SmartAttach()
44     {
45         if (m_autoattach) {
46             m_interface.DetachFromThread();
47         }
48     }
49
50     DPL::DB::ThreadDatabaseSupport* get()
51     {
52         return &m_interface;
53     }
54
55   private:
56     DPL::DB::ThreadDatabaseSupport m_interface;
57     bool m_autoattach;
58 };
59
60 template<typename ContainerType1, typename ContainerType2>
61 bool ContainerContentsEqual(const ContainerType1& container1,
62                             const ContainerType2& container2)
63 {
64     using namespace DPL::DB::ORM::dpl_orm_test::TestTableInsert;
65     typedef std::set<typename ContainerType1::value_type> Set1;
66     typedef std::set<typename ContainerType2::value_type> Set2;
67     Set1 set1(container1.begin(), container1.end());
68     Set2 set2(container2.begin(), container2.end());
69
70     for (typename Set1::iterator it = set1.begin();
71          it != set1.end();
72          it++)
73     {
74         std::stringstream ss;
75         ss << *it;
76         WrtLogD("Set1 element: %s", ss.str().c_str());
77     }
78
79     for (typename Set2::iterator it = set2.begin(); it != set2.end(); it++)
80     {
81         std::stringstream ss;
82         ss << *it;
83         WrtLogD("Set2 element: %s", ss.str().c_str());
84     }
85
86     return set1 == set2;
87 }
88
89 template<typename T>
90 std::list<T> makeList(const T& a, const T& b)
91 {
92     std::list<T> list;
93     list.push_back(a);
94     list.push_back(b);
95     return list;
96 }
97
98 //tests
99
100 RUNNER_TEST_GROUP_INIT(DPL)
101
102 /*
103 Name: ORM_SelectSingleValue
104 Description: tests quering single value of single row from database
105 Expected: Values should match those which were prepared
106 */
107 RUNNER_TEST(ORM_SelectSingleValue)
108 {
109     SmartAttach interface;
110     using namespace DPL::DB::ORM;
111     using namespace DPL::DB::ORM::dpl_orm_test;
112     //Getting each column
113     {
114         TestTable::Select select(interface.get());
115         select.Where(Equals<TestTable::ColumnInt>(8));
116         int result;
117         RUNNER_ASSERT_MSG((result =
118                                *select.GetSingleValue<TestTable::ColumnOptInt>())
119                           == 6, "Got " <<
120                           result);
121     }
122     {
123         TestTable::Select select(interface.get());
124         select.Where(Equals<TestTable::ColumnInt>(8));
125         DPL::String result;
126         RUNNER_ASSERT_MSG((result =
127                                *select.GetSingleValue<TestTable::ColumnOptText>(
128                                    )) == L"seven",
129                           "Got " << result);
130     }
131     {
132         TestTable::Select select(interface.get());
133         select.Where(Equals<TestTable::ColumnInt>(8));
134         int result;
135         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>(
136                                    )) == 8, "Got " << result);
137     }
138     {
139         TestTable::Select select(interface.get());
140         select.Where(Equals<TestTable::ColumnInt>(8));
141         int result;
142         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
143                                    )) == 9, "Got " << result);
144     }
145     {
146         TestTable::Select select(interface.get());
147         select.Where(Equals<TestTable::ColumnInt>(8));
148         DPL::String result;
149         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>(
150                                    )) == L"ten", "Got " << result);
151     }
152
153     //Where on each column
154     {
155         TestTable::Select select(interface.get());
156         select.Where(Equals<TestTable::ColumnOptInt>(6));
157         int result;
158         RUNNER_ASSERT_MSG((result =
159                                *select.GetSingleValue<TestTable::ColumnOptInt>())
160                           == 6, "Got " <<
161                           result);
162     }
163     {
164         TestTable::Select select(interface.get());
165         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
166         DPL::String result;
167         RUNNER_ASSERT_MSG((result =
168                                *select.GetSingleValue<TestTable::ColumnOptText>(
169                                    )) == L"seven",
170                           "Got " << result);
171     }
172     {
173         TestTable::Select select(interface.get());
174         select.Where(Equals<TestTable::ColumnInt>(8));
175         int result;
176         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>(
177                                    )) == 8, "Got " << result);
178     }
179     {
180         TestTable::Select select(interface.get());
181         select.Where(Equals<TestTable::ColumnInt2>(9));
182         int result;
183         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
184                                    )) == 9, "Got " << result);
185     }
186     {
187         TestTable::Select select(interface.get());
188         select.Where(Equals<TestTable::ColumnText>(L"ten"));
189         DPL::String result;
190         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>(
191                                    )) == L"ten", "Got " << result);
192     }
193 }
194
195 /*
196 Name: ORM_SelectSingleRow
197 Description: tests quering single row from database
198 Expected: Values should match those which were prepared
199 */
200 RUNNER_TEST(ORM_SelectSingleRow)
201 {
202     SmartAttach interface;
203     using namespace DPL::DB::ORM;
204     using namespace DPL::DB::ORM::dpl_orm_test;
205     {
206         TestTable::Select select(interface.get());
207         select.Where(Equals<TestTable::ColumnInt>(3));
208         TestTable::Row result = select.GetSingleRow();
209         TestTable::Row expected;
210         expected.Set_ColumnOptInt(1);
211         expected.Set_ColumnOptText(DPL::String(L"two"));
212         expected.Set_ColumnInt(3);
213         expected.Set_ColumnInt2(4);
214         expected.Set_ColumnText(L"five");
215         RUNNER_ASSERT_MSG(result == expected, "Got " << result);
216     }
217
218     {
219         TestTable::Select select(interface.get());
220         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
221         TestTable::Row result = select.GetSingleRow();
222         TestTable::Row expected;
223         expected.Set_ColumnOptInt(6);
224         expected.Set_ColumnOptText(DPL::String(L"seven"));
225         expected.Set_ColumnInt(8);
226         expected.Set_ColumnInt2(9);
227         expected.Set_ColumnText(L"ten");
228         RUNNER_ASSERT_MSG(result == expected, "Got " << result);
229     }
230 }
231
232 /*
233 Name: ORM_SelectRowList
234 Description: tests quering multiple row from database
235 Expected: Values should match those which were prepared
236 */
237 RUNNER_TEST(ORM_SelectRowList)
238 {
239     SmartAttach interface;
240     using namespace DPL::DB::ORM;
241     using namespace DPL::DB::ORM::dpl_orm_test;
242     {
243         TestTable::Select select(interface.get());
244         select.Where(Equals<TestTable::ColumnInt>(3));
245         std::list<TestTable::Row> result = select.GetRowList();
246         RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size());
247
248         TestTable::Row expected;
249         expected.Set_ColumnOptInt(1);
250         expected.Set_ColumnOptText(DPL::String(L"two"));
251         expected.Set_ColumnInt(3);
252         expected.Set_ColumnInt2(4);
253         expected.Set_ColumnText(L"five");
254         RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " <<
255                           *(result.begin()) );
256     }
257
258     {
259         TestTable::Select select(interface.get());
260         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
261         std::list<TestTable::Row> result = select.GetRowList();
262         RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size());
263
264         TestTable::Row expected;
265         expected.Set_ColumnOptInt(6);
266         expected.Set_ColumnOptText(DPL::String(L"seven"));
267         expected.Set_ColumnInt(8);
268         expected.Set_ColumnInt2(9);
269         expected.Set_ColumnText(L"ten");
270         RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " <<
271                           *(result.begin()) );
272     }
273
274     {
275         TestTable::Select select(interface.get());
276         select.Where(Equals<TestTable::ColumnInt>(99));
277         std::list<TestTable::Row> result = select.GetRowList();
278
279         TestTable::Row expected1;
280         expected1.Set_ColumnInt(99);
281         expected1.Set_ColumnInt2(11);
282         expected1.Set_ColumnText(L"twelve");
283
284         TestTable::Row expected2;
285         expected2.Set_ColumnInt(99);
286         expected2.Set_ColumnInt2(13);
287         expected2.Set_ColumnText(L"fourteen");
288
289         RUNNER_ASSERT(ContainerContentsEqual(makeList(expected1,
290                                                       expected2), result));
291     }
292 }
293
294 /*
295 Name: ORM_SelectValueList
296 Description: tests quering single column from multiple row from database
297 Expected: Values should match those which were prepared
298 */
299 RUNNER_TEST(ORM_SelectValueList)
300 {
301     SmartAttach interface;
302     using namespace DPL::DB::ORM;
303     using namespace DPL::DB::ORM::dpl_orm_test;
304     //Getting each column
305     {
306         TestTable::Select select(interface.get());
307         select.Where(Is<TestTable::ColumnOptInt>(DPL::OptionalInt()));
308         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
309                                                                      ColumnInt>(),
310                                              makeList(99, 99)));
311     }
312     {
313         TestTable::Select select(interface.get());
314         select.Where(Is<TestTable::ColumnOptInt>(DPL::OptionalInt()));
315         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
316                                                                      ColumnInt2>(),
317                                              makeList(11, 13)));
318     }
319     {
320         TestTable::Select select(interface.get());
321         select.Where(Is<TestTable::ColumnOptInt>(DPL::OptionalInt()));
322         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
323                                                                      ColumnText>(),
324                                              makeList(DPL::String(L"twelve"),
325                                                       DPL::String(L"fourteen"))));
326     }
327     {
328         TestTable::Select select(interface.get());
329         select.Where(Is<TestTable::ColumnOptInt>(DPL::OptionalInt()));
330         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
331                                                                      ColumnOptText>(),
332                                              makeList(DPL::OptionalString(),
333                                                       DPL::OptionalString())));
334     }
335
336     //Where on each column
337     {
338         TestTable::Select select(interface.get());
339         select.Where(Is<TestTable::ColumnOptInt>(DPL::OptionalInt()));
340         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
341                                                                      ColumnInt2>(),
342                                              makeList(11, 13)));
343     }
344     {
345         TestTable::Select select(interface.get());
346         select.Where(Is<TestTable::ColumnOptText>(DPL::OptionalString()));
347         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
348                                                                      ColumnInt2>(),
349                                              makeList(11, 13)));
350     }
351     {
352         TestTable::Select select(interface.get());
353         select.Where(Is<TestTable::ColumnInt>(99));
354         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::
355                                                                      ColumnInt2>(),
356                                              makeList(11, 13)));
357     }
358 }
359
360 /*
361 Name: ORM_MultipleCalls
362 Description: tests sequnece of different queries
363 Expected: Values should match those which were prepared
364 */
365 RUNNER_TEST(ORM_MultipleCalls)
366 {
367     for (int j = 0; j < TEST_REPETITION; j++) {
368         for (int i = 0; i < TEST_REPETITION; i++) {
369             ORM_SelectSingleValue();
370         }
371
372         for (int i = 0; i < TEST_REPETITION; i++) {
373             ORM_SelectSingleRow();
374         }
375
376         for (int i = 0; i < TEST_REPETITION; i++) {
377             ORM_SelectRowList();
378         }
379
380         for (int i = 0; i < TEST_REPETITION; i++) {
381             ORM_SelectValueList();
382         }
383     }
384 }
385
386 /*
387 Name: ORM_Insert
388 Description: tests insering rows into database
389 Expected: Values should be inserted
390 */
391 RUNNER_TEST(ORM_Insert)
392 {
393     SmartAttach interface;
394     using namespace DPL::DB::ORM;
395     using namespace DPL::DB::ORM::dpl_orm_test;
396
397     TestTableInsert::Select select1(interface.get());
398     std::list<int> resultList = select1.GetValueList<TestTableInsert::ColumnInt>();
399     RUNNER_ASSERT_MSG(resultList.empty(),
400                       "Returned list has wrong size: " << resultList.size());
401
402     std::list<TestTableInsert::Row> list;
403
404     TestTableInsert::Insert insert(interface.get());
405     TestTableInsert::Row row;
406     row.Set_ColumnOptInt(1);
407     row.Set_ColumnInt2(2);
408     row.Set_ColumnText(L"three");
409     insert.Values(row);
410     insert.Execute();
411
412     row.Set_ColumnInt(99);
413     list.push_back(row);
414     {
415         TestTableInsert::Select select2(interface.get());
416         RUNNER_ASSERT_MSG(ContainerContentsEqual(
417                               select2.GetRowList(),
418                               list), "Returned list doesn't match.");
419     }
420
421     TestTableInsert::Insert insert2(interface.get());
422     TestTableInsert::Row row2;
423     row2.Set_ColumnInt(4);
424     row2.Set_ColumnInt2(5);
425     row2.Set_ColumnText(L"six");
426     insert2.Values(row2);
427     insert2.Execute();
428
429     list.push_back(row2);
430     {
431         TestTableInsert::Select select(interface.get());
432         RUNNER_ASSERT_MSG(ContainerContentsEqual(
433                               select.GetRowList(),
434                               list), "Returned list doesn't match.");
435     }
436
437     TestTableInsert::Insert insert3(interface.get());
438     TestTableInsert::Row row3;
439     row3.Set_ColumnOptInt(1);
440     row3.Set_ColumnInt2(7);
441     row3.Set_ColumnText(L"eight");
442     insert3.Values(row3);
443     insert3.Execute();
444
445     row3.Set_ColumnInt(99);
446     list.push_back(row3);
447     {
448         TestTableInsert::Select select3(interface.get());
449         RUNNER_ASSERT_MSG(ContainerContentsEqual(
450                               select3.GetRowList(),
451                               list), "Returned list doesn't match.");
452     }
453
454     TestTableInsert::Insert insert4(interface.get());
455     TestTableInsert::Row row4;
456     row4.Set_ColumnOptInt(9);
457     row4.Set_ColumnInt2(10);
458     row4.Set_ColumnText(L"eleven");
459     insert4.Values(row4);
460     insert4.Execute();
461
462     row4.Set_ColumnInt(99);
463     list.push_back(row4);
464     {
465         TestTableInsert::Select select4(interface.get());
466         RUNNER_ASSERT_MSG(ContainerContentsEqual(
467                               select4.GetRowList(),
468                               list), "Returned list doesn't match.");
469     }
470
471     // restore original table state
472     {
473         TestTableInsert::Delete del(interface.get());
474         del.Execute();
475
476         TestTableInsert::Select select(interface.get());
477         RUNNER_ASSERT(select.GetRowList().size() == 0);
478     }
479 }
480
481 /*
482 Name: ORM_MultipleBindInsert
483 Description: repeats ORM_Insert test several times
484 Expected: Values should be inserted
485 */
486 RUNNER_TEST(ORM_MultipleBindInsert)
487 {
488     for (int i = 0; i < TEST_REPETITION; i++) {
489         ORM_Insert();
490     }
491 }
492
493 /*
494 Name: ORM_Delete
495 Description: tests deleting rows from database
496 Expected: deleted rows should not exist
497 */
498 RUNNER_TEST(ORM_Delete)
499 {
500     SmartAttach interface;
501     using namespace DPL::DB::ORM;
502     using namespace DPL::DB::ORM::dpl_orm_test;
503     TestTableDelete::Select selectStart(interface.get());
504     selectStart.OrderBy(DPL::TypeListDecl<OrderingAscending<TestTableDelete::
505                                                                 ColumnInt2> >());
506     std::list<TestTableDelete::Row> list = selectStart.GetRowList();
507     std::list<TestTableDelete::Row> originalList = list;
508
509     std::vector<TestTableDelete::Row> vector(list.begin(), list.end());
510     RUNNER_ASSERT_MSG(
511         list.size() == 4, "Returned list has wrong size: " << list.size());
512
513     typedef DPL::String S;
514
515     //no-act deletes
516     {
517         TestTableDelete::Delete del(interface.get());
518         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(1),
519                       Equals<TestTableDelete::ColumnOptText>(S(L"seven"))));
520         del.Execute();
521
522         TestTableDelete::Select select(interface.get());
523         RUNNER_ASSERT_MSG(ContainerContentsEqual(
524                               select.GetRowList(),
525                               list), "Returned list doesn't match.");
526     }
527
528     {
529         TestTableDelete::Delete del(interface.get());
530         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(6),
531                       Equals<TestTableDelete::ColumnOptText>(S(L"two"))));
532         del.Execute();
533
534         TestTableDelete::Select select(interface.get());
535         RUNNER_ASSERT_MSG(ContainerContentsEqual(
536                               select.GetRowList(),
537                               list), "Returned list doesn't match.");
538     }
539
540     {
541         TestTableDelete::Delete del(interface.get());
542         del.Where(Equals<TestTableDelete::ColumnInt2>(10));
543         del.Execute();
544
545         TestTableDelete::Select select(interface.get());
546         RUNNER_ASSERT_MSG(ContainerContentsEqual(
547                               select.GetRowList(),
548                               list), "Returned list doesn't match.");
549     }
550
551     //act deletes
552     {
553         list.remove(vector[1]);
554
555         TestTableDelete::Delete del(interface.get());
556         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(6),
557                       Equals<TestTableDelete::ColumnText>(L"ten")));
558         del.Execute();
559
560         TestTableDelete::Select select(interface.get());
561         RUNNER_ASSERT_MSG(ContainerContentsEqual(
562                               select.GetRowList(),
563                               list), "Returned list doesn't match.");
564     }
565
566     {
567         list.remove(vector[2]);
568         list.remove(vector[3]);
569
570         TestTableDelete::Delete del(interface.get());
571         del.Where(Is<TestTableDelete::ColumnOptText>(DPL::OptionalString()));
572         del.Execute();
573
574         TestTableDelete::Select select(interface.get());
575         RUNNER_ASSERT_MSG(ContainerContentsEqual(
576                               select.GetRowList(),
577                               list), "Returned list doesn't match.");
578     }
579
580     {
581         TestTableDelete::Delete del(interface.get());
582         del.Execute();
583
584         TestTableDelete::Select select(interface.get());
585         RUNNER_ASSERT_MSG(
586             select.GetRowList().size() == 0, "Returned list is not empty");
587     }
588
589     // Restore original table state
590     // This also tests if multiple different binds for Insert are working
591     // properly
592     for (std::list<TestTableDelete::Row>::iterator i = originalList.begin();
593          i != originalList.end();
594          ++i)
595     {
596         TestTableDelete::Insert insert(interface.get());
597         insert.Values(*i);
598         insert.Execute();
599     }
600
601     {
602         TestTableDelete::Select select(interface.get());
603         RUNNER_ASSERT_MSG(ContainerContentsEqual(
604                               select.GetRowList(),
605                               originalList),
606                           "Returned list doesn't match.");
607     }
608 }
609
610 /*
611 Name: ORM_MultipleBindDelete
612 Description: repeats ORM_Delete test several times
613 Expected: Values should be deleted
614 */
615 RUNNER_TEST(ORM_MultipleBindDelete)
616 {
617     for (int i = 0; i < TEST_REPETITION; i++) {
618         ORM_Delete();
619     }
620 }
621
622 /*
623 Name: ORM_MultipleBindWhere
624 Description: tests if multiple bind of same query obejct works
625 Expected: Each bind and execution of query should be correct
626 */
627 RUNNER_TEST(ORM_MultipleBindWhere)
628 {
629     SmartAttach interface;
630     using namespace DPL::DB::ORM;
631     using namespace DPL::DB::ORM::dpl_orm_test;
632     {
633         TestTable::Select select(interface.get());
634         int result;
635         select.Where(Equals<TestTable::ColumnInt>(8));
636         RUNNER_ASSERT_MSG((result =
637                                *select.GetSingleValue<TestTable::ColumnOptInt>())
638                           == 6, "Got " <<
639                           result);
640
641         select.Where(Equals<TestTable::ColumnInt>(3));
642         RUNNER_ASSERT_MSG((result =
643                                *select.GetSingleValue<TestTable::ColumnOptInt>())
644                           == 1, "Got " <<
645                           result);
646
647         select.Where(Equals<TestTable::ColumnInt>(8));
648         RUNNER_ASSERT_MSG((result =
649                                *select.GetSingleValue<TestTable::ColumnOptInt>())
650                           == 6, "Got " <<
651                           result);
652
653         select.Where(Equals<TestTable::ColumnInt>(3));
654         RUNNER_ASSERT_MSG((result =
655                                *select.GetSingleValue<TestTable::ColumnOptInt>())
656                           == 1, "Got " <<
657                           result);
658     }
659
660     {
661         TestTable::Select select(interface.get());
662         int result;
663         select.Where(And(Equals<TestTable::ColumnInt>(99),
664                          Equals<TestTable::ColumnText>(L"fourteen")));
665         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
666                                    )) == 13, "Got " << result);
667
668         select.Where(And(Equals<TestTable::ColumnInt>(99),
669                          Equals<TestTable::ColumnText>(L"twelve")));
670         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
671                                    )) == 11, "Got " << result);
672
673         select.Where(And(Equals<TestTable::ColumnInt>(99),
674                          Equals<TestTable::ColumnText>(L"fourteen")));
675         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
676                                    )) == 13, "Got " << result);
677
678         select.Where(And(Equals<TestTable::ColumnInt>(99),
679                          Equals<TestTable::ColumnText>(L"twelve")));
680         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
681                                    )) == 11, "Got " << result);
682     }
683
684     {
685         TestTable::Select select(interface.get());
686         int result;
687         select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
688                          Equals<TestTable::ColumnInt>(99)));
689         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
690                                    )) == 13, "Got " << result);
691
692         select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
693                          Equals<TestTable::ColumnInt>(99)));
694         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
695                                    )) == 11, "Got " << result);
696
697         select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
698                          Equals<TestTable::ColumnInt>(99)));
699         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
700                                    )) == 13, "Got " << result);
701
702         select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
703                          Equals<TestTable::ColumnInt>(99)));
704         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>(
705                                    )) == 11, "Got " << result);
706     }
707 }
708
709 /*
710 Name: ORM_Update
711 Description: tests rows update in database
712 Expected: Successful update
713 */
714 RUNNER_TEST(ORM_Update)
715 {
716     SmartAttach interface;
717     using namespace DPL::DB::ORM;
718     using namespace DPL::DB::ORM::dpl_orm_test;
719
720     std::list<TestTableInsert::Row> list;
721
722     TestTableInsert::Delete del(interface.get());
723     del.Execute();
724
725     // INSERT
726     {
727         TestTableInsert::Insert insert(interface.get());
728         TestTableInsert::Row row;
729         row.Set_ColumnOptInt(5);
730         row.Set_ColumnInt2(2);
731         row.Set_ColumnText(L"two");
732         insert.Values(row);
733         insert.Execute();
734
735         row.Set_ColumnInt(99);
736         list.push_back(row);
737     }
738     {
739         TestTableInsert::Insert insert(interface.get());
740         TestTableInsert::Row row;
741         row.Set_ColumnOptInt(1);
742         row.Set_ColumnInt2(2);
743         row.Set_ColumnText(L"three");
744         insert.Values(row);
745         insert.Execute();
746
747         row.Set_ColumnInt(99);
748         list.push_back(row);
749     }
750     {
751         TestTableInsert::Insert insert(interface.get());
752         TestTableInsert::Row row;
753         row.Set_ColumnOptInt(2);
754         row.Set_ColumnInt2(3);
755         row.Set_ColumnText(L"three");
756         insert.Values(row);
757         insert.Execute();
758
759         row.Set_ColumnInt(99);
760         list.push_back(row);
761
762         // CHECK
763         TestTableInsert::Select select(interface.get());
764         RUNNER_ASSERT_MSG(ContainerContentsEqual(
765                               select.GetRowList(),
766                               list), "Returned list doesn't match.");
767     }
768     {
769         // UPDATE - no rows
770         TestTableInsert::Update update(interface.get());
771         TestTableInsert::Row row;
772         row.Set_ColumnInt2(4);
773         row.Set_ColumnText(L"four");
774         update.Values(row);
775         update.Where(Equals<TestTableInsert::ColumnInt2>(12));
776         update.Execute();
777
778         // CHECK
779         TestTableInsert::Select select(interface.get());
780         RUNNER_ASSERT_MSG(ContainerContentsEqual(
781                               select.GetRowList(),
782                               list), "Returned list doesn't match.");
783     }
784     {
785         // UPDATE - one row
786         TestTableInsert::Update update(interface.get());
787         TestTableInsert::Row row;
788         row.Set_ColumnInt2(2);
789         row.Set_ColumnText(L"four");
790         update.Values(row);
791         update.Where(Equals<TestTableInsert::ColumnInt2>(3));
792         update.Execute();
793
794         list.back().Set_ColumnInt2(2);
795         list.back().Set_ColumnText(L"four");
796
797         // CHECK
798         TestTableInsert::Select select(interface.get());
799         RUNNER_ASSERT_MSG(ContainerContentsEqual(
800                               select.GetRowList(),
801                               list), "Returned list doesn't match.");
802     }
803
804     {
805         // UPDATE - multiple rows
806         TestTableInsert::Update update(interface.get());
807         TestTableInsert::Row row;
808         row.Set_ColumnText(L"dup");
809         update.Values(row);
810         update.Where(Equals<TestTableInsert::ColumnInt2>(2));
811         update.Execute();
812
813         FOREACH(it, list)
814         {
815             it->Set_ColumnText(L"dup");
816         }
817
818         // CHECK
819         TestTableInsert::Select select(interface.get());
820         RUNNER_ASSERT_MSG(ContainerContentsEqual(
821                               select.GetRowList(),
822                               list), "Returned list doesn't match.");
823     }
824
825     // restore original table state
826     {
827         TestTableInsert::Delete del2(interface.get());
828         del2.Execute();
829
830         TestTableInsert::Select select(interface.get());
831         RUNNER_ASSERT(select.GetRowList().size() == 0);
832     }
833 }
834
835 /*
836 Name: ORM_MultipleBindUpdate
837 Description: repeats ORM_Update severl times
838 Expected: Successful update
839 */
840 RUNNER_TEST(ORM_MultipleBindUpdate)
841 {
842     for (int i = 0; i < TEST_REPETITION; i++) {
843         ORM_Update();
844     }
845 }
846
847 /*
848 Name: ORM_transactions
849 Description: checks creation of transation object
850 Expected: Successful creation of transaction object
851 */
852 RUNNER_TEST(ORM_transactions)
853 {
854     SmartAttach interface;
855     DPL::DB::ORM::dpl_orm_test::ScopedTransaction transaction(interface.get());
856 }
857
858 /*
859 Name: ORM_MultiAttach
860 Description: checks correct behaviou in case of multiple tries to attach to database
861 Expected: Methods attaching/dettaching should be prepared for multiple calling
862 */
863 RUNNER_TEST(ORM_MultiAttach)
864 {
865     SmartAttach interface(false);
866     RUNNER_ASSERT_MSG(
867         !interface.get()->IsAttached(), "Is attached, but shouldn't be.");
868     interface.get()->AttachToThread();
869     RUNNER_ASSERT_MSG(
870         interface.get()->IsAttached(), "Isn't attached, but should be.");
871     interface.get()->AttachToThread();
872     RUNNER_ASSERT_MSG(
873         interface.get()->IsAttached(), "Isn't attached, but should be.");
874     interface.get()->DetachFromThread();
875     RUNNER_ASSERT_MSG(
876         interface.get()->IsAttached(), "Isn't attached, but should be.");
877     interface.get()->DetachFromThread();
878     RUNNER_ASSERT_MSG(
879         !interface.get()->IsAttached(), "Is attached, but shouldn't be.");
880 }
881
882 /*
883 Name: ORM_Join
884 Description: tests ORM's join operation
885 Expected: values should insist correct join operation
886 */
887 RUNNER_TEST(ORM_Join)
888 {
889     SmartAttach interface;
890     using namespace DPL::DB::ORM;
891     using namespace DPL::DB::ORM::dpl_orm_test;
892
893     typedef DPL::TypeListDecl<TestTableJoin1::TestText,
894                               TestTableJoin2::TestText2,
895                               DPL::TypeListGuard>::Type JoinColumns;
896
897     /* Test for correct join:
898      * 5 ids from first table matches 5 ids from second table thus join result
899      * contains 5 rows */
900     TestTableJoin1::Select select(interface.get());
901     select.Join<JoinColumns>(Equal<TestTableJoin1::TestID,
902                                    TestTableJoin2::TestID>());
903     std::list<CustomRow<JoinColumns> > rowlist =
904         select.GetCustomRowList<JoinColumns, CustomRow<JoinColumns> >();
905
906     RUNNER_ASSERT_MSG(
907         rowlist.size() == 5, "Invalid number of rows fetched: " << rowlist.size());
908
909     std::string text;
910     std::ostringstream oss;
911     int cnt = 0;
912     FOREACH(rowit, rowlist)
913     {
914         cnt++;
915
916         text =
917             DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
918         oss << "text val " << cnt;
919         RUNNER_ASSERT_MSG(text.compare(
920                               oss.str()) == 0,
921                           "Invalid value from first column: "
922                           << text << " expected: " << oss.str());
923         oss.str(std::string());
924
925         text =
926             DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin2::TestText2>());
927         oss << "text2 " << cnt;
928         RUNNER_ASSERT_MSG(text.compare(
929                               oss.str()) == 0,
930                           "Invalid value from second column: "
931                           << text << " expected: " << oss.str());
932         oss.str(std::string());
933     }
934     /* Test for empty join:
935      * None of number values from first table matches ids from second table
936      * - join result should be empty */
937     TestTableJoin1::Select select2(interface.get());
938     select2.Join<JoinColumns>(Equal<TestTableJoin1::TestNumber,
939                                     TestTableJoin2::TestID>());
940     rowlist = select2.GetCustomRowList<JoinColumns, CustomRow<JoinColumns> >();
941
942     RUNNER_ASSERT_MSG(rowlist.empty(), "Result should be empty but it is not!");
943
944     /* Test for "converted" join:
945      * - join made with int column and text column as keys
946      * - expected 5 matching rows (one row of 6 should not be matched)*/
947     TestTableJoin1::Select select3(interface.get());
948     select3.Join<JoinColumns>(Equal<TestTableJoin1::TestID,
949                                     TestTableJoin2::TestText1>());
950     rowlist = select3.GetCustomRowList<JoinColumns, CustomRow<JoinColumns> >();
951     RUNNER_ASSERT_MSG(
952         rowlist.size() == 5, "Expected 5 rows while received: " << rowlist.size());
953     cnt = 0;
954     FOREACH(rowit, rowlist)
955     {
956         cnt++;
957         // look at last two insertions into TestTableJoin2
958         // for this skip understanding
959         if (cnt == 5) {
960             cnt = 6;
961         }
962         text =
963             DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
964         oss << "text val " << cnt;
965         RUNNER_ASSERT_MSG(text.compare(
966                               oss.str()) == 0,
967                           "Invalid value from first column: "
968                           << text << " expected: " << oss.str() <<
969                           " iteration: " << cnt);
970         oss.str(std::string());
971
972         text =
973             DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin2::TestText2>());
974         oss << "text2 " << cnt;
975         RUNNER_ASSERT_MSG(text.compare(
976                               oss.str()) == 0,
977                           "Invalid value from second column: "
978                           << text << " expected: " << oss.str() <<
979                           " iteration: " << cnt);
980         oss.str(std::string());
981     }
982
983     /* Test for join with non-unique nullable columns given as keys*/
984     typedef DPL::TypeListDecl<TestTableJoin1::TestText,
985                               TestTableJoin3::TestText33,
986                               DPL::TypeListGuard>::Type JoinTables2;
987     TestTableJoin1::Select select4(interface.get());
988     select4.Join<JoinTables2>(Equal<TestTableJoin1::TestNumber,
989                                     TestTableJoin3::Value3>());
990     std::list<CustomRow<JoinTables2> > rowlist2 =
991         select4.GetCustomRowList<JoinTables2, CustomRow<JoinTables2> >();
992     RUNNER_ASSERT_MSG(
993         rowlist2.size() == 4, "Expected 4 rows while received: " <<
994         rowlist.size());
995     cnt = 0;
996     DPL::OptionalString optext;
997     FOREACH(rowit, rowlist2)
998     {
999         cnt++;
1000
1001         text =
1002             DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
1003         // values expected in subsequent (1,2,3,4) iterations: 1 1 2 2
1004         oss << "text val " << (1 + (int)(cnt / 3));
1005         RUNNER_ASSERT_MSG(text.compare(
1006                               oss.str()) == 0,
1007                           "Invalid value from first column: "
1008                           << text << " expected: " << oss.str() <<
1009                           " iteration: " << cnt);
1010         oss.str(std::string());
1011
1012         optext = (*rowit).GetColumnData<TestTableJoin3::TestText33>();
1013         text = DPL::ToUTF8String(*optext);
1014         oss << "test " << cnt;
1015         RUNNER_ASSERT_MSG(text.compare(
1016                               oss.str()) == 0,
1017                           "Invalid value from second column: "
1018                           << text << " expected: " << oss.str() <<
1019                           " iteration: " << cnt);
1020         oss.str(std::string());
1021     }
1022
1023     /* Test for join made on three tables:
1024      * - 3 text columns selected for join
1025      * - Equal made for TestID of (table1 and table2) and (table1 and table3) */
1026     typedef DPL::TypeListDecl<TestTableJoin1::TestText,
1027                               TestTableJoin2::TestText2,
1028                               TestTableJoin3::TestText33,
1029                               DPL::TypeListGuard>::Type Join3Tables;
1030     TestTableJoin1::Select select5(interface.get());
1031     select5.Join<Join3Tables>(Equal<TestTableJoin1::TestID,
1032                                     TestTableJoin2::TestID>());
1033     select5.Join<Join3Tables>(Equal<TestTableJoin1::TestID,
1034                                     TestTableJoin3::TestID>());
1035     std::list<CustomRow<Join3Tables> > rowlist3tab =
1036         select5.GetCustomRowList<Join3Tables, CustomRow<Join3Tables> >();
1037     RUNNER_ASSERT_MSG(
1038         rowlist3tab.size() == 3, "Expected 3 rows while received: " <<
1039         rowlist3tab.size());
1040     cnt = 0;
1041     FOREACH(rowit, rowlist3tab)
1042     {
1043         cnt++;
1044
1045         text =
1046             DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
1047         oss << "text val " << cnt;
1048         RUNNER_ASSERT_MSG(text.compare(
1049                               oss.str()) == 0,
1050                           "Invalid value from first column: "
1051                           << text << " expected: " << oss.str() <<
1052                           " iteration: " << cnt);
1053         oss.str(std::string());
1054
1055         text =
1056             DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin2::TestText2>());
1057         oss << "text2 " << cnt;
1058         RUNNER_ASSERT_MSG(text.compare(
1059                               oss.str()) == 0,
1060                           "Invalid value from first column: "
1061                           << text << " expected: " << oss.str() <<
1062                           " iteration: " << cnt);
1063         oss.str(std::string());
1064
1065         optext = (*rowit).GetColumnData<TestTableJoin3::TestText33>();
1066         text = DPL::ToUTF8String(*optext);
1067         oss << "test " << cnt;
1068         RUNNER_ASSERT_MSG(text.compare(
1069                               oss.str()) == 0,
1070                           "Invalid value from second column: "
1071                           << text << " expected: " << oss.str() <<
1072                           " iteration: " << cnt);
1073         oss.str(std::string());
1074     }
1075 }
1076
1077 RUNNER_TEST(ORM_SelectOrderByMultipleColumns)
1078 {
1079     SmartAttach interface;
1080     using namespace DPL::DB::ORM;
1081     using namespace DPL::DB::ORM::dpl_orm_test;
1082     {
1083         TestTableJoin3::Select select(interface.get());
1084
1085         // testing: " ORDER BY Value3 ASC, TestID DESC, TestID ASC"
1086         select.OrderBy(DPL::TypeListDecl<OrderingAscending<TestTableJoin3::
1087                                                                Value3>,
1088                                          OrderingDescending<TestTableJoin3::
1089                                                                 TestText33>,
1090                                          OrderingAscending<TestTableJoin3::
1091                                                                TestID> >());
1092
1093         std::list<TestTableJoin3::Row> result = select.GetRowList();
1094         std::list<TestTableJoin3::Row>::const_iterator iter = result.begin();
1095         { //1 row
1096             RUNNER_ASSERT_MSG(*iter->Get_TestText33() ==
1097                               DPL::FromASCIIString(
1098                                   "test 6"), "Wrong row 1 order");
1099             RUNNER_ASSERT_MSG(iter->Get_TestID() == 10, "Wrong row 1 order");
1100             ++iter;
1101         }
1102         { //2 row
1103             RUNNER_ASSERT_MSG(*iter->Get_TestText33() ==
1104                               DPL::FromASCIIString(
1105                                   "test 5"), "Wrong row 2 order");
1106             RUNNER_ASSERT_MSG(iter->Get_TestID() == 7, "Wrong row 2 order");
1107             ++iter;
1108         }
1109         { //3 row
1110             RUNNER_ASSERT_MSG(iter->Get_Value3() == 111, "Wrong row 3 order");
1111             RUNNER_ASSERT_MSG(*iter->Get_TestText33() ==
1112                               DPL::FromASCIIString(
1113                                   "test 2"), "Wrong row 3 order");
1114             RUNNER_ASSERT_MSG(iter->Get_TestID() == 2, "Wrong row 3 order");
1115             ++iter;
1116         }
1117         { //4 row
1118             RUNNER_ASSERT_MSG(iter->Get_Value3() == 111, "Wrong row 4 order");
1119             RUNNER_ASSERT_MSG(*iter->Get_TestText33() ==
1120                               DPL::FromASCIIString(
1121                                   "test 1"), "Wrong row 4 order");
1122             RUNNER_ASSERT_MSG(iter->Get_TestID() == 1, "Wrong row 4 order");
1123             ++iter;
1124         }
1125         { //5 row
1126             RUNNER_ASSERT_MSG(iter->Get_Value3() == 222, "Wrong row 5 order");
1127             RUNNER_ASSERT_MSG(*iter->Get_TestText33() ==
1128                               DPL::FromASCIIString(
1129                                   "test 4"), "Wrong row 5 order");
1130             RUNNER_ASSERT_MSG(iter->Get_TestID() == 6, "Wrong row 5 order");
1131             ++iter;
1132         }
1133         { //6 row
1134             RUNNER_ASSERT_MSG(iter->Get_Value3() == 222, "Wrong row 6 order");
1135             RUNNER_ASSERT_MSG(*iter->Get_TestText33() ==
1136                               DPL::FromASCIIString(
1137                                   "test 3"), "Wrong row 6 order");
1138             RUNNER_ASSERT_MSG(iter->Get_TestID() == 3, "Wrong row 6 order");
1139             ++iter;
1140         }
1141     }
1142 }