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