Tizen 2.0 Release
[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 private:
54     DPL::DB::ThreadDatabaseSupport m_interface;
55     bool m_autoattach;
56 };
57
58 template<typename ContainerType1, typename ContainerType2>
59 bool ContainerContentsEqual(const ContainerType1& container1, const ContainerType2& container2)
60 {
61     using namespace DPL::DB::ORM::dpl_orm_test::TestTableInsert;
62     typedef std::set<typename ContainerType1::value_type> Set1;
63     typedef std::set<typename ContainerType2::value_type> Set2;
64     Set1 set1(container1.begin(), container1.end());
65     Set2 set2(container2.begin(), container2.end());
66
67     for (typename Set1::iterator it = set1.begin();
68             it != set1.end();
69             it++)
70     {
71         LogDebug("Set1 element: " << *it);
72     }
73
74     for (typename Set2::iterator it = set2.begin(); it != set2.end(); it++)
75     {
76         LogDebug("Set2 element: " << *it);
77     }
78
79     return set1 == set2;
80 }
81
82 template<typename T>
83 std::list<T> makeList(const T& a, const T& b)
84 {
85     std::list<T> list;
86     list.push_back(a);
87     list.push_back(b);
88     return list;
89 }
90
91 //tests
92
93 RUNNER_TEST_GROUP_INIT(DPL)
94
95 RUNNER_TEST(ORM_SelectSingleValue)
96 {
97     SmartAttach interface;
98     using namespace DPL::DB::ORM;
99     using namespace DPL::DB::ORM::dpl_orm_test;
100     //Getting each column
101     {
102         TestTable::Select select(interface.get());
103         select.Where(Equals<TestTable::ColumnInt>(8));
104         int result;
105         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
106     }
107     {
108         TestTable::Select select(interface.get());
109         select.Where(Equals<TestTable::ColumnInt>(8));
110         DPL::String result;
111         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptText>()) == L"seven", "Got " << result);
112     }
113     {
114         TestTable::Select select(interface.get());
115         select.Where(Equals<TestTable::ColumnInt>(8));
116         int result;
117         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>()) == 8, "Got " << result);
118     }
119     {
120         TestTable::Select select(interface.get());
121         select.Where(Equals<TestTable::ColumnInt>(8));
122         int result;
123         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 9, "Got " << result);
124     }
125     {
126         TestTable::Select select(interface.get());
127         select.Where(Equals<TestTable::ColumnInt>(8));
128         DPL::String result;
129         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>()) == L"ten", "Got " << result);
130     }
131
132     //Where on each column
133     {
134         TestTable::Select select(interface.get());
135         select.Where(Equals<TestTable::ColumnOptInt>(6));
136         int result;
137         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
138     }
139     {
140         TestTable::Select select(interface.get());
141         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
142         DPL::String result;
143         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptText>()) == L"seven", "Got " << result);
144     }
145     {
146         TestTable::Select select(interface.get());
147         select.Where(Equals<TestTable::ColumnInt>(8));
148         int result;
149         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>()) == 8, "Got " << result);
150     }
151     {
152         TestTable::Select select(interface.get());
153         select.Where(Equals<TestTable::ColumnInt2>(9));
154         int result;
155         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 9, "Got " << result);
156     }
157     {
158         TestTable::Select select(interface.get());
159         select.Where(Equals<TestTable::ColumnText>(L"ten"));
160         DPL::String result;
161         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>()) == L"ten", "Got " << result);
162     }
163 }
164
165 RUNNER_TEST(ORM_SelectSingleRow)
166 {
167     SmartAttach interface;
168     using namespace DPL::DB::ORM;
169     using namespace DPL::DB::ORM::dpl_orm_test;
170     {
171         TestTable::Select select(interface.get());
172         select.Where(Equals<TestTable::ColumnInt>(3));
173         TestTable::Row result = select.GetSingleRow();
174         TestTable::Row expected;
175         expected.Set_ColumnOptInt(1);
176         expected.Set_ColumnOptText(DPL::String(L"two"));
177         expected.Set_ColumnInt(3);
178         expected.Set_ColumnInt2(4);
179         expected.Set_ColumnText(L"five");
180         RUNNER_ASSERT_MSG(result == expected, "Got " << result);
181     }
182
183     {
184         TestTable::Select select(interface.get());
185         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
186         TestTable::Row result = select.GetSingleRow();
187         TestTable::Row expected;
188         expected.Set_ColumnOptInt(6);
189         expected.Set_ColumnOptText(DPL::String(L"seven"));
190         expected.Set_ColumnInt(8);
191         expected.Set_ColumnInt2(9);
192         expected.Set_ColumnText(L"ten");
193         RUNNER_ASSERT_MSG(result == expected, "Got " << result);
194     }
195 }
196
197 RUNNER_TEST(ORM_SelectRowList)
198 {
199     SmartAttach interface;
200     using namespace DPL::DB::ORM;
201     using namespace DPL::DB::ORM::dpl_orm_test;
202     {
203         TestTable::Select select(interface.get());
204         select.Where(Equals<TestTable::ColumnInt>(3));
205         std::list<TestTable::Row> result = select.GetRowList();
206         RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size());
207
208         TestTable::Row expected;
209         expected.Set_ColumnOptInt(1);
210         expected.Set_ColumnOptText(DPL::String(L"two"));
211         expected.Set_ColumnInt(3);
212         expected.Set_ColumnInt2(4);
213         expected.Set_ColumnText(L"five");
214         RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " << *(result.begin()) );
215     }
216
217     {
218         TestTable::Select select(interface.get());
219         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
220         std::list<TestTable::Row> result = select.GetRowList();
221         RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size());
222
223         TestTable::Row expected;
224         expected.Set_ColumnOptInt(6);
225         expected.Set_ColumnOptText(DPL::String(L"seven"));
226         expected.Set_ColumnInt(8);
227         expected.Set_ColumnInt2(9);
228         expected.Set_ColumnText(L"ten");
229         RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " << *(result.begin()) );
230     }
231
232     {
233         TestTable::Select select(interface.get());
234         select.Where(Equals<TestTable::ColumnInt>(99));
235         std::list<TestTable::Row> result = select.GetRowList();
236
237         TestTable::Row expected1;
238         expected1.Set_ColumnInt(99);
239         expected1.Set_ColumnInt2(11);
240         expected1.Set_ColumnText(L"twelve");
241
242         TestTable::Row expected2;
243         expected2.Set_ColumnInt(99);
244         expected2.Set_ColumnInt2(13);
245         expected2.Set_ColumnText(L"fourteen");
246
247         RUNNER_ASSERT(ContainerContentsEqual(makeList(expected1, expected2), result));
248     }
249 }
250
251 RUNNER_TEST(ORM_SelectValueList)
252 {
253     SmartAttach interface;
254     using namespace DPL::DB::ORM;
255     using namespace DPL::DB::ORM::dpl_orm_test;
256     //Getting each column
257     {
258         TestTable::Select select(interface.get());
259         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
260         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt>(),
261                       makeList(99, 99)));
262     }
263     {
264         TestTable::Select select(interface.get());
265         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
266         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
267                       makeList(11, 13)));
268     }
269     {
270         TestTable::Select select(interface.get());
271         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
272         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnText>(),
273                       makeList(DPL::String(L"twelve"), DPL::String(L"fourteen"))));
274     }
275     {
276         TestTable::Select select(interface.get());
277         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
278         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnOptText>(),
279                       makeList(DPL::Optional<DPL::String>::Null,DPL::Optional<DPL::String>::Null)));
280     }
281
282     //Where on each column
283     {
284         TestTable::Select select(interface.get());
285         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
286         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
287                       makeList(11, 13)));
288     }
289     {
290         TestTable::Select select(interface.get());
291         select.Where(Is<TestTable::ColumnOptText>(DPL::Optional<DPL::String>::Null));
292         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
293                       makeList(11, 13)));
294     }
295     {
296         TestTable::Select select(interface.get());
297         select.Where(Is<TestTable::ColumnInt>(99));
298         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
299                       makeList(11, 13)));
300     }
301 }
302
303 RUNNER_TEST(ORM_MultipleCalls)
304 {
305     for (int j = 0 ; j < TEST_REPETITION ; j++ )
306     {
307         for (int i = 0 ; i < TEST_REPETITION ; i++ )
308             ORM_SelectSingleValue();
309
310         for (int i = 0 ; i < TEST_REPETITION ; i++ )
311             ORM_SelectSingleRow();
312
313         for (int i = 0 ; i < TEST_REPETITION ; i++ )
314             ORM_SelectRowList();
315
316         for (int i = 0 ; i < TEST_REPETITION ; i++ )
317             ORM_SelectValueList();
318     }
319 }
320
321 RUNNER_TEST(ORM_Insert)
322 {
323     SmartAttach interface;
324     using namespace DPL::DB::ORM;
325     using namespace DPL::DB::ORM::dpl_orm_test;
326
327     TestTableInsert::Select select1(interface.get());
328     std::list<int> resultList = select1.GetValueList<TestTableInsert::ColumnInt>();
329     RUNNER_ASSERT_MSG(resultList.size() == 0, "Returned list has wrong size: " << resultList.size());
330     std::list<TestTableInsert::Row> list;
331
332     TestTableInsert::Insert insert(interface.get());
333     TestTableInsert::Row row;
334     row.Set_ColumnOptInt(1);
335     row.Set_ColumnInt2(2);
336     row.Set_ColumnText(L"three");
337     insert.Values(row);
338     insert.Execute();
339
340     row.Set_ColumnInt(99);
341     list.push_back(row);
342     {
343         TestTableInsert::Select select2(interface.get());
344         RUNNER_ASSERT_MSG(ContainerContentsEqual(select2.GetRowList(), list), "Returned list doesn't match.");
345     }
346
347     TestTableInsert::Insert insert2(interface.get());
348     TestTableInsert::Row row2;
349     row2.Set_ColumnInt(4);
350     row2.Set_ColumnInt2(5);
351     row2.Set_ColumnText(L"six");
352     insert2.Values(row2);
353     insert2.Execute();
354
355     list.push_back(row2);
356     {
357         TestTableInsert::Select select(interface.get());
358         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
359     }
360
361     TestTableInsert::Insert insert3(interface.get());
362     TestTableInsert::Row row3;
363     row3.Set_ColumnOptInt(1);
364     row3.Set_ColumnInt2(7);
365     row3.Set_ColumnText(L"eight");
366     insert3.Values(row3);
367     insert3.Execute();
368
369     row3.Set_ColumnInt(99);
370     list.push_back(row3);
371     {
372         TestTableInsert::Select select3(interface.get());
373         RUNNER_ASSERT_MSG(ContainerContentsEqual(select3.GetRowList(), list), "Returned list doesn't match.");
374     }
375
376     TestTableInsert::Insert insert4(interface.get());
377     TestTableInsert::Row row4;
378     row4.Set_ColumnOptInt(9);
379     row4.Set_ColumnInt2(10);
380     row4.Set_ColumnText(L"eleven");
381     insert4.Values(row4);
382     insert4.Execute();
383
384     row4.Set_ColumnInt(99);
385     list.push_back(row4);
386     {
387         TestTableInsert::Select select4(interface.get());
388         RUNNER_ASSERT_MSG(ContainerContentsEqual(select4.GetRowList(), list), "Returned list doesn't match.");
389     }
390
391     // restore original table state
392     {
393         TestTableInsert::Delete del(interface.get());
394         del.Execute();
395
396         TestTableInsert::Select select(interface.get());
397         RUNNER_ASSERT(select.GetRowList().size() == 0);
398     }
399 }
400
401 RUNNER_TEST(ORM_MultipleBindInsert)
402 {
403     for ( int i = 0 ; i < TEST_REPETITION ; i++ )
404     {
405         ORM_Insert();
406     }
407 }
408
409 RUNNER_TEST(ORM_Delete)
410 {
411     SmartAttach interface;
412     using namespace DPL::DB::ORM;
413     using namespace DPL::DB::ORM::dpl_orm_test;
414     TestTableDelete::Select selectStart(interface.get());
415     selectStart.OrderBy("ColumnInt2 ASC");
416     std::list<TestTableDelete::Row> list = selectStart.GetRowList();
417     std::list<TestTableDelete::Row> originalList = list;
418
419     std::vector<TestTableDelete::Row> vector(list.begin(), list.end());
420     RUNNER_ASSERT_MSG(list.size() == 4, "Returned list has wrong size: " << list.size());
421
422     typedef DPL::String S;
423
424     //no-act deletes
425     {
426         TestTableDelete::Delete del(interface.get());
427         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(1), Equals<TestTableDelete::ColumnOptText>(S(L"seven"))));
428         del.Execute();
429
430         TestTableDelete::Select select(interface.get());
431         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
432     }
433
434     {
435         TestTableDelete::Delete del(interface.get());
436         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(6), Equals<TestTableDelete::ColumnOptText>(S(L"two"))));
437         del.Execute();
438
439         TestTableDelete::Select select(interface.get());
440         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
441     }
442
443     {
444         TestTableDelete::Delete del(interface.get());
445         del.Where(Equals<TestTableDelete::ColumnInt2>(10));
446         del.Execute();
447
448         TestTableDelete::Select select(interface.get());
449         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
450     }
451
452     //act deletes
453     {
454         list.remove(vector[1]);
455
456         TestTableDelete::Delete del(interface.get());
457         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(6), Equals<TestTableDelete::ColumnText>(L"ten")));
458         del.Execute();
459
460         TestTableDelete::Select select(interface.get());
461         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
462     }
463
464     {
465         list.remove(vector[2]);
466         list.remove(vector[3]);
467
468         TestTableDelete::Delete del(interface.get());
469         del.Where(Is<TestTableDelete::ColumnOptText>(DPL::Optional<DPL::String>::Null));
470         del.Execute();
471
472         TestTableDelete::Select select(interface.get());
473         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
474     }
475
476     {
477         TestTableDelete::Delete del(interface.get());
478         del.Execute();
479
480         TestTableDelete::Select select(interface.get());
481         RUNNER_ASSERT_MSG(select.GetRowList().size() == 0, "Returned list is not empty");
482     }
483
484     // Restore original table state
485     // This also tests if multiple different binds for Insert are working properly
486     for (std::list<TestTableDelete::Row>::iterator i = originalList.begin(); i != originalList.end(); i++)
487     {
488         TestTableDelete::Insert insert(interface.get());
489         insert.Values(*i);
490         insert.Execute();
491     }
492
493     {
494         TestTableDelete::Select select(interface.get());
495         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), originalList), "Returned list doesn't match.");
496     }
497
498 }
499
500 RUNNER_TEST(ORM_MultipleBindDelete)
501 {
502     for ( int i = 0 ; i < TEST_REPETITION ; i++ )
503     {
504         ORM_Delete();
505     }
506 }
507
508 RUNNER_TEST(ORM_MultipleBindWhere)
509 {
510     SmartAttach interface;
511     using namespace DPL::DB::ORM;
512     using namespace DPL::DB::ORM::dpl_orm_test;
513     {
514         TestTable::Select select(interface.get());
515         int result;
516         select.Where(Equals<TestTable::ColumnInt>(8));
517         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
518
519         select.Where(Equals<TestTable::ColumnInt>(3));
520         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 1, "Got " << result);
521
522         select.Where(Equals<TestTable::ColumnInt>(8));
523         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
524
525         select.Where(Equals<TestTable::ColumnInt>(3));
526         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 1, "Got " << result);
527     }
528
529     {
530         TestTable::Select select(interface.get());
531         int result;
532         select.Where(And(Equals<TestTable::ColumnInt>(99),
533                          Equals<TestTable::ColumnText>(L"fourteen")));
534         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
535
536         select.Where(And(Equals<TestTable::ColumnInt>(99),
537                          Equals<TestTable::ColumnText>(L"twelve")));
538         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
539
540         select.Where(And(Equals<TestTable::ColumnInt>(99),
541                          Equals<TestTable::ColumnText>(L"fourteen")));
542         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
543
544         select.Where(And(Equals<TestTable::ColumnInt>(99),
545                          Equals<TestTable::ColumnText>(L"twelve")));
546         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
547     }
548
549     {
550         TestTable::Select select(interface.get());
551         int result;
552         select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
553                          Equals<TestTable::ColumnInt>(99)));
554         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
555
556         select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
557                          Equals<TestTable::ColumnInt>(99)));
558         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
559
560         select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
561                          Equals<TestTable::ColumnInt>(99)));
562         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
563
564         select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
565                          Equals<TestTable::ColumnInt>(99)));
566         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
567
568     }
569
570 }
571
572 RUNNER_TEST(ORM_Update)
573 {
574     SmartAttach interface;
575     using namespace DPL::DB::ORM;
576     using namespace DPL::DB::ORM::dpl_orm_test;
577
578     std::list<TestTableInsert::Row> list;
579
580     TestTableInsert::Delete del(interface.get());
581     del.Execute();
582
583     // INSERT
584     {
585         TestTableInsert::Insert insert(interface.get());
586         TestTableInsert::Row row;
587         row.Set_ColumnOptInt(5);
588         row.Set_ColumnInt2(2);
589         row.Set_ColumnText(L"two");
590         insert.Values(row);
591         insert.Execute();
592
593         row.Set_ColumnInt(99);
594         list.push_back(row);
595     }
596     {
597         TestTableInsert::Insert insert(interface.get());
598         TestTableInsert::Row row;
599         row.Set_ColumnOptInt(1);
600         row.Set_ColumnInt2(2);
601         row.Set_ColumnText(L"three");
602         insert.Values(row);
603         insert.Execute();
604
605         row.Set_ColumnInt(99);
606         list.push_back(row);
607     }
608     {
609         TestTableInsert::Insert insert(interface.get());
610         TestTableInsert::Row row;
611         row.Set_ColumnOptInt(2);
612         row.Set_ColumnInt2(3);
613         row.Set_ColumnText(L"three");
614         insert.Values(row);
615         insert.Execute();
616
617         row.Set_ColumnInt(99);
618         list.push_back(row);
619
620         // CHECK
621         TestTableInsert::Select select(interface.get());
622         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
623     }
624     {
625         // UPDATE - no rows
626         TestTableInsert::Update update(interface.get());
627         TestTableInsert::Row row;
628         row.Set_ColumnInt2(4);
629         row.Set_ColumnText(L"four");
630         update.Values(row);
631         update.Where(Equals<TestTableInsert::ColumnInt2>(12));
632         update.Execute();
633
634         // CHECK
635         TestTableInsert::Select select(interface.get());
636         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
637     }
638     {
639         // UPDATE - one row
640         TestTableInsert::Update update(interface.get());
641         TestTableInsert::Row row;
642         row.Set_ColumnInt2(2);
643         row.Set_ColumnText(L"four");
644         update.Values(row);
645         update.Where(Equals<TestTableInsert::ColumnInt2>(3));
646         update.Execute();
647
648         list.back().Set_ColumnInt2(2);
649         list.back().Set_ColumnText(L"four");
650
651         // CHECK
652         TestTableInsert::Select select(interface.get());
653         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
654     }
655
656     {
657         // UPDATE - multiple rows
658         TestTableInsert::Update update(interface.get());
659         TestTableInsert::Row row;
660         row.Set_ColumnText(L"dup");
661         update.Values(row);
662         update.Where(Equals<TestTableInsert::ColumnInt2>(2));
663         update.Execute();
664
665         FOREACH(it, list)
666         {
667             it->Set_ColumnText(L"dup");
668         }
669
670         // CHECK
671         TestTableInsert::Select select(interface.get());
672         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
673     }
674
675     // restore original table state
676     {
677         TestTableInsert::Delete del2(interface.get());
678         del2.Execute();
679
680         TestTableInsert::Select select(interface.get());
681         RUNNER_ASSERT(select.GetRowList().size() == 0);
682     }
683 }
684
685 RUNNER_TEST(ORM_MultipleBindUpdate)
686 {
687     for ( int i = 0 ; i < TEST_REPETITION ; i++ )
688     {
689         ORM_Update();
690     }
691 }
692
693 RUNNER_TEST(ORM_transactions)
694 {
695     SmartAttach interface;
696     DPL::DB::ORM::dpl_orm_test::ScopedTransaction transaction(interface.get());
697 }
698
699 RUNNER_TEST(ORM_MultiAttach)
700 {
701     SmartAttach interface(false);
702     RUNNER_ASSERT_MSG(!interface.get()->IsAttached(), "Is attached, but shouldn't be.");
703     interface.get()->AttachToThread();
704     RUNNER_ASSERT_MSG(interface.get()->IsAttached(), "Isn't attached, but should be.");
705     interface.get()->AttachToThread();
706     RUNNER_ASSERT_MSG(interface.get()->IsAttached(), "Isn't attached, but should be.");
707     interface.get()->DetachFromThread();
708     RUNNER_ASSERT_MSG(interface.get()->IsAttached(), "Isn't attached, but should be.");
709     interface.get()->DetachFromThread();
710     RUNNER_ASSERT_MSG(!interface.get()->IsAttached(), "Is attached, but shouldn't be.");
711 }
712
713 RUNNER_TEST(ORM_Join)
714 {
715     SmartAttach interface;
716     using namespace DPL::DB::ORM;
717     using namespace DPL::DB::ORM::dpl_orm_test;
718
719     typedef DPL::TypeListDecl<TestTableJoin1::TestText, TestTableJoin2::TestText2,
720             DPL::TypeListGuard>::Type JoinColumns;
721
722     /* Test for correct join:
723      * 5 ids from first table matches 5 ids from second table thus join result
724      * contains 5 rows */
725     TestTableJoin1::Select select(interface.get());
726     select.Join<JoinColumns>(Equal<TestTableJoin1::TestID, TestTableJoin2::TestID>());
727     std::list<CustomRow<JoinColumns>> rowlist =
728             select.GetCustomRowList<JoinColumns, CustomRow<JoinColumns>>();
729
730     RUNNER_ASSERT_MSG(rowlist.size() == 5, "Invalid number of rows fetched: " << rowlist.size());
731
732     std::string text;
733     std::ostringstream oss;
734     int cnt = 0;
735     FOREACH(rowit, rowlist)
736     {
737         cnt++;
738
739         text = DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
740         oss << "text val " << cnt;
741         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from first column: "
742                 << text << " expected: " << oss.str());
743         oss.str(std::string());
744
745         text = DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin2::TestText2>());
746         oss << "text2 " << cnt;
747         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from second column: "
748                 << text << " expected: " << oss.str());
749         oss.str(std::string());
750     }
751     /* Test for empty join:
752      * None of number values from first table matches ids from second table
753      * - join result should be empty */
754     TestTableJoin1::Select select2(interface.get());
755     select2.Join<JoinColumns>(Equal<TestTableJoin1::TestNumber, TestTableJoin2::TestID>());
756     rowlist = select2.GetCustomRowList<JoinColumns, CustomRow<JoinColumns>>();
757
758     RUNNER_ASSERT_MSG(rowlist.empty(), "Result should be empty but it is not!");
759
760     /* Test for "converted" join:
761      * - join made with int column and text column as keys
762      * - expected 5 matching rows (one row of 6 should not be matched)*/
763     TestTableJoin1::Select select3(interface.get());
764     select3.Join<JoinColumns>(Equal<TestTableJoin1::TestID, TestTableJoin2::TestText1>());
765     rowlist = select3.GetCustomRowList<JoinColumns, CustomRow<JoinColumns>>();
766     RUNNER_ASSERT_MSG(rowlist.size() == 5, "Expected 5 rows while received: " << rowlist.size());
767     cnt = 0;
768     FOREACH(rowit, rowlist)
769     {
770         cnt++;
771         // look at last two insertions into TestTableJoin2
772         // for this skip understanding
773         if(cnt == 5) {
774             cnt = 6;
775         }
776         text = DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
777         oss << "text val " << cnt;
778         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from first column: "
779                 << text << " expected: " << oss.str() << " iteration: " <<cnt);
780         oss.str(std::string());
781
782         text = DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin2::TestText2>());
783         oss << "text2 " << cnt;
784         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from second column: "
785                 << text << " expected: " << oss.str() << " iteration: " <<cnt);
786         oss.str(std::string());
787     }
788
789     /* Test for join with non-unique nullable columns given as keys*/
790     typedef DPL::TypeListDecl<TestTableJoin1::TestText, TestTableJoin3::TestText33,
791             DPL::TypeListGuard>::Type JoinTables2;
792     TestTableJoin1::Select select4(interface.get());
793     select4.Join<JoinTables2>(Equal<TestTableJoin1::TestNumber, TestTableJoin3::Value3>());
794     std::list<CustomRow<JoinTables2>> rowlist2 = select4.GetCustomRowList<JoinTables2, CustomRow<JoinTables2>>();
795     RUNNER_ASSERT_MSG(rowlist2.size() == 4, "Expected 4 rows while received: " << rowlist.size());
796     cnt = 0;
797     DPL::Optional<DPL::String> optext;
798     FOREACH(rowit, rowlist2)
799     {
800         cnt++;
801
802         text = DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
803         // values expected in subsequent (1,2,3,4) iterations: 1 1 2 2
804         oss << "text val " << (1+(int)(cnt/3));
805         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from first column: "
806                 << text << " expected: " << oss.str() << " iteration: " <<cnt);
807         oss.str(std::string());
808
809         optext = (*rowit).GetColumnData<TestTableJoin3::TestText33>();
810         text = DPL::ToUTF8String(*optext);
811         oss << "test " << cnt;
812         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from second column: "
813                 << text << " expected: " << oss.str() << " iteration: " <<cnt);
814         oss.str(std::string());
815     }
816
817     /* Test for join made on three tables:
818      * - 3 text columns selected for join
819      * - Equal made for TestID of (table1 and table2) and (table1 and table3) */
820     typedef DPL::TypeListDecl<TestTableJoin1::TestText, TestTableJoin2::TestText2,
821             TestTableJoin3::TestText33, DPL::TypeListGuard>::Type Join3Tables;
822     TestTableJoin1::Select select5(interface.get());
823     select5.Join<Join3Tables>(Equal<TestTableJoin1::TestID, TestTableJoin2::TestID>());
824     select5.Join<Join3Tables>(Equal<TestTableJoin1::TestID, TestTableJoin3::TestID>());
825     std::list<CustomRow<Join3Tables>> rowlist3tab = select5.GetCustomRowList<Join3Tables, CustomRow<Join3Tables>>();
826     RUNNER_ASSERT_MSG(rowlist3tab.size() == 3, "Expected 3 rows while received: " << rowlist3tab.size());
827     cnt = 0;
828     FOREACH(rowit, rowlist3tab)
829     {
830         cnt++;
831
832         text = DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin1::TestText>());
833         oss << "text val " << cnt;
834         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from first column: "
835                 << text << " expected: " << oss.str() << " iteration: " <<cnt);
836         oss.str(std::string());
837
838         text = DPL::ToUTF8String((*rowit).GetColumnData<TestTableJoin2::TestText2>());
839         oss << "text2 " << cnt;
840         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from first column: "
841                 << text << " expected: " << oss.str() << " iteration: " <<cnt);
842         oss.str(std::string());
843
844         optext = (*rowit).GetColumnData<TestTableJoin3::TestText33>();
845         text = DPL::ToUTF8String(*optext);
846         oss << "test " << cnt;
847         RUNNER_ASSERT_MSG(text.compare(oss.str()) == 0, "Invalid value from second column: "
848                 << text << " expected: " << oss.str() << " iteration: " <<cnt);
849         oss.str(std::string());
850     }
851 }