ddcbe796243916a7f7e47f2dbe5d458167d357f6
[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 <generator_dpl_orm_test.h>
20
21 namespace {
22 const char* PATH_DB = "/opt/apps/wrt/wrt-commons/tests/db/dpl_orm_test.db";
23 }
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();
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 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, const ContainerType2& container2)
61 {
62     using namespace DPL::DB::ORM::dpl_orm_test::TestTableInsert;
63     typedef std::set<typename ContainerType1::value_type> Set1;
64     typedef std::set<typename ContainerType2::value_type> Set2;
65     Set1 set1(container1.begin(), container1.end());
66     Set2 set2(container2.begin(), container2.end());
67
68     for (typename Set1::iterator it = set1.begin();
69             it != set1.end();
70             it++)
71     {
72         LogDebug("Set1 element: " << *it);
73     }
74
75     for (typename Set2::iterator it = set2.begin(); it != set2.end(); it++)
76     {
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 = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
107     }
108     {
109         TestTable::Select select(interface.get());
110         select.Where(Equals<TestTable::ColumnInt>(8));
111         DPL::String result;
112         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptText>()) == L"seven", "Got " << result);
113     }
114     {
115         TestTable::Select select(interface.get());
116         select.Where(Equals<TestTable::ColumnInt>(8));
117         int result;
118         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>()) == 8, "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::ColumnInt2>()) == 9, "Got " << result);
125     }
126     {
127         TestTable::Select select(interface.get());
128         select.Where(Equals<TestTable::ColumnInt>(8));
129         DPL::String result;
130         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>()) == L"ten", "Got " << result);
131     }
132
133     //Where on each column
134     {
135         TestTable::Select select(interface.get());
136         select.Where(Equals<TestTable::ColumnOptInt>(6));
137         int result;
138         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
139     }
140     {
141         TestTable::Select select(interface.get());
142         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
143         DPL::String result;
144         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptText>()) == L"seven", "Got " << result);
145     }
146     {
147         TestTable::Select select(interface.get());
148         select.Where(Equals<TestTable::ColumnInt>(8));
149         int result;
150         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt>()) == 8, "Got " << result);
151     }
152     {
153         TestTable::Select select(interface.get());
154         select.Where(Equals<TestTable::ColumnInt2>(9));
155         int result;
156         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 9, "Got " << result);
157     }
158     {
159         TestTable::Select select(interface.get());
160         select.Where(Equals<TestTable::ColumnText>(L"ten"));
161         DPL::String result;
162         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnText>()) == L"ten", "Got " << result);
163     }
164 }
165
166 RUNNER_TEST(ORM_SelectSingleRow)
167 {
168     SmartAttach interface;
169     using namespace DPL::DB::ORM;
170     using namespace DPL::DB::ORM::dpl_orm_test;
171     {
172         TestTable::Select select(interface.get());
173         select.Where(Equals<TestTable::ColumnInt>(3));
174         TestTable::Row result = select.GetSingleRow();
175         TestTable::Row expected;
176         expected.Set_ColumnOptInt(1);
177         expected.Set_ColumnOptText(DPL::String(L"two"));
178         expected.Set_ColumnInt(3);
179         expected.Set_ColumnInt2(4);
180         expected.Set_ColumnText(L"five");
181         RUNNER_ASSERT_MSG(result == expected, "Got " << result);
182     }
183
184     {
185         TestTable::Select select(interface.get());
186         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
187         TestTable::Row result = select.GetSingleRow();
188         TestTable::Row expected;
189         expected.Set_ColumnOptInt(6);
190         expected.Set_ColumnOptText(DPL::String(L"seven"));
191         expected.Set_ColumnInt(8);
192         expected.Set_ColumnInt2(9);
193         expected.Set_ColumnText(L"ten");
194         RUNNER_ASSERT_MSG(result == expected, "Got " << result);
195     }
196 }
197
198 RUNNER_TEST(ORM_SelectRowList)
199 {
200     SmartAttach interface;
201     using namespace DPL::DB::ORM;
202     using namespace DPL::DB::ORM::dpl_orm_test;
203     {
204         TestTable::Select select(interface.get());
205         select.Where(Equals<TestTable::ColumnInt>(3));
206         std::list<TestTable::Row> result = select.GetRowList();
207         RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size());
208
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.begin()) == expected, "Got " << *(result.begin()) );
216     }
217
218     {
219         TestTable::Select select(interface.get());
220         select.Where(Equals<TestTable::ColumnOptText>(DPL::String(L"seven")));
221         std::list<TestTable::Row> result = select.GetRowList();
222         RUNNER_ASSERT_MSG(result.size() == 1, "Got " << result.size());
223
224         TestTable::Row expected;
225         expected.Set_ColumnOptInt(6);
226         expected.Set_ColumnOptText(DPL::String(L"seven"));
227         expected.Set_ColumnInt(8);
228         expected.Set_ColumnInt2(9);
229         expected.Set_ColumnText(L"ten");
230         RUNNER_ASSERT_MSG(*(result.begin()) == expected, "Got " << *(result.begin()) );
231     }
232
233     {
234         TestTable::Select select(interface.get());
235         select.Where(Equals<TestTable::ColumnInt>(99));
236         std::list<TestTable::Row> result = select.GetRowList();
237
238         TestTable::Row expected1;
239         expected1.Set_ColumnInt(99);
240         expected1.Set_ColumnInt2(11);
241         expected1.Set_ColumnText(L"twelve");
242
243         TestTable::Row expected2;
244         expected2.Set_ColumnInt(99);
245         expected2.Set_ColumnInt2(13);
246         expected2.Set_ColumnText(L"fourteen");
247
248         RUNNER_ASSERT(ContainerContentsEqual(makeList(expected1, expected2), result));
249     }
250 }
251
252 RUNNER_TEST(ORM_SelectValueList)
253 {
254     SmartAttach interface;
255     using namespace DPL::DB::ORM;
256     using namespace DPL::DB::ORM::dpl_orm_test;
257     //Getting each column
258     {
259         TestTable::Select select(interface.get());
260         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
261         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt>(),
262                       makeList(99, 99)));
263     }
264     {
265         TestTable::Select select(interface.get());
266         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
267         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
268                       makeList(11, 13)));
269     }
270     {
271         TestTable::Select select(interface.get());
272         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
273         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnText>(),
274                       makeList(DPL::String(L"twelve"), DPL::String(L"fourteen"))));
275     }
276     {
277         TestTable::Select select(interface.get());
278         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
279         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnOptText>(),
280                       makeList(DPL::Optional<DPL::String>::Null,DPL::Optional<DPL::String>::Null)));
281     }
282
283     //Where on each column
284     {
285         TestTable::Select select(interface.get());
286         select.Where(Is<TestTable::ColumnOptInt>(DPL::Optional<int>::Null));
287         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
288                       makeList(11, 13)));
289     }
290     {
291         TestTable::Select select(interface.get());
292         select.Where(Is<TestTable::ColumnOptText>(DPL::Optional<DPL::String>::Null));
293         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
294                       makeList(11, 13)));
295     }
296     {
297         TestTable::Select select(interface.get());
298         select.Where(Is<TestTable::ColumnInt>(99));
299         RUNNER_ASSERT(ContainerContentsEqual(select.GetValueList<TestTable::ColumnInt2>(),
300                       makeList(11, 13)));
301     }
302 }
303
304 RUNNER_TEST(ORM_MultipleCalls)
305 {
306     for (int j = 0 ; j < TEST_REPETITION ; j++ )
307     {
308         for (int i = 0 ; i < TEST_REPETITION ; i++ )
309             ORM_SelectSingleValue();
310
311         for (int i = 0 ; i < TEST_REPETITION ; i++ )
312             ORM_SelectSingleRow();
313
314         for (int i = 0 ; i < TEST_REPETITION ; i++ )
315             ORM_SelectRowList();
316
317         for (int i = 0 ; i < TEST_REPETITION ; i++ )
318             ORM_SelectValueList();
319     }
320 }
321
322 RUNNER_TEST(ORM_Insert)
323 {
324     SmartAttach interface;
325     using namespace DPL::DB::ORM;
326     using namespace DPL::DB::ORM::dpl_orm_test;
327
328     TestTableInsert::Select select1(interface.get());
329     std::list<int> resultList = select1.GetValueList<TestTableInsert::ColumnInt>();
330     RUNNER_ASSERT_MSG(resultList.size() == 0, "Returned list has wrong size: " << resultList.size());
331     std::list<TestTableInsert::Row> list;
332
333     TestTableInsert::Insert insert(interface.get());
334     TestTableInsert::Row row;
335     row.Set_ColumnOptInt(1);
336     row.Set_ColumnInt2(2);
337     row.Set_ColumnText(L"three");
338     insert.Values(row);
339     insert.Execute();
340
341     row.Set_ColumnInt(99);
342     list.push_back(row);
343     {
344         TestTableInsert::Select select2(interface.get());
345         RUNNER_ASSERT_MSG(ContainerContentsEqual(select2.GetRowList(), list), "Returned list doesn't match.");
346     }
347
348     TestTableInsert::Insert insert2(interface.get());
349     TestTableInsert::Row row2;
350     row2.Set_ColumnInt(4);
351     row2.Set_ColumnInt2(5);
352     row2.Set_ColumnText(L"six");
353     insert2.Values(row2);
354     insert2.Execute();
355
356     list.push_back(row2);
357     {
358         TestTableInsert::Select select(interface.get());
359         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
360     }
361
362     TestTableInsert::Insert insert3(interface.get());
363     TestTableInsert::Row row3;
364     row3.Set_ColumnOptInt(1);
365     row3.Set_ColumnInt2(7);
366     row3.Set_ColumnText(L"eight");
367     insert3.Values(row3);
368     insert3.Execute();
369
370     row3.Set_ColumnInt(99);
371     list.push_back(row3);
372     {
373         TestTableInsert::Select select3(interface.get());
374         RUNNER_ASSERT_MSG(ContainerContentsEqual(select3.GetRowList(), list), "Returned list doesn't match.");
375     }
376
377     TestTableInsert::Insert insert4(interface.get());
378     TestTableInsert::Row row4;
379     row4.Set_ColumnOptInt(9);
380     row4.Set_ColumnInt2(10);
381     row4.Set_ColumnText(L"eleven");
382     insert4.Values(row4);
383     insert4.Execute();
384
385     row4.Set_ColumnInt(99);
386     list.push_back(row4);
387     {
388         TestTableInsert::Select select4(interface.get());
389         RUNNER_ASSERT_MSG(ContainerContentsEqual(select4.GetRowList(), list), "Returned list doesn't match.");
390     }
391
392     // restore original table state
393     {
394         TestTableInsert::Delete del(interface.get());
395         del.Execute();
396
397         TestTableInsert::Select select(interface.get());
398         RUNNER_ASSERT(select.GetRowList().size() == 0);
399     }
400 }
401
402 RUNNER_TEST(ORM_MultipleBindInsert)
403 {
404     for ( int i = 0 ; i < TEST_REPETITION ; i++ )
405     {
406         ORM_Insert();
407     }
408 }
409
410 RUNNER_TEST(ORM_Delete)
411 {
412     SmartAttach interface;
413     using namespace DPL::DB::ORM;
414     using namespace DPL::DB::ORM::dpl_orm_test;
415     TestTableDelete::Select selectStart(interface.get());
416     selectStart.OrderBy("ColumnInt2 ASC");
417     std::list<TestTableDelete::Row> list = selectStart.GetRowList();
418     std::list<TestTableDelete::Row> originalList = list;
419
420     std::vector<TestTableDelete::Row> vector(list.begin(), list.end());
421     RUNNER_ASSERT_MSG(list.size() == 4, "Returned list has wrong size: " << list.size());
422
423     typedef DPL::String S;
424
425     //no-act deletes
426     {
427         TestTableDelete::Delete del(interface.get());
428         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(1), Equals<TestTableDelete::ColumnOptText>(S(L"seven"))));
429         del.Execute();
430
431         TestTableDelete::Select select(interface.get());
432         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
433     }
434
435     {
436         TestTableDelete::Delete del(interface.get());
437         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(6), Equals<TestTableDelete::ColumnOptText>(S(L"two"))));
438         del.Execute();
439
440         TestTableDelete::Select select(interface.get());
441         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
442     }
443
444     {
445         TestTableDelete::Delete del(interface.get());
446         del.Where(Equals<TestTableDelete::ColumnInt2>(10));
447         del.Execute();
448
449         TestTableDelete::Select select(interface.get());
450         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
451     }
452
453     //act deletes
454     {
455         list.remove(vector[1]);
456
457         TestTableDelete::Delete del(interface.get());
458         del.Where(And(Equals<TestTableDelete::ColumnOptInt>(6), Equals<TestTableDelete::ColumnText>(L"ten")));
459         del.Execute();
460
461         TestTableDelete::Select select(interface.get());
462         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
463     }
464
465     {
466         list.remove(vector[2]);
467         list.remove(vector[3]);
468
469         TestTableDelete::Delete del(interface.get());
470         del.Where(Is<TestTableDelete::ColumnOptText>(DPL::Optional<DPL::String>::Null));
471         del.Execute();
472
473         TestTableDelete::Select select(interface.get());
474         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
475     }
476
477     {
478         TestTableDelete::Delete del(interface.get());
479         del.Execute();
480
481         TestTableDelete::Select select(interface.get());
482         RUNNER_ASSERT_MSG(select.GetRowList().size() == 0, "Returned list is not empty");
483     }
484
485     // Restore original table state
486     // This also tests if multiple different binds for Insert are working properly
487     for (std::list<TestTableDelete::Row>::iterator i = originalList.begin(); i != originalList.end(); i++)
488     {
489         TestTableDelete::Insert insert(interface.get());
490         insert.Values(*i);
491         insert.Execute();
492     }
493
494     {
495         TestTableDelete::Select select(interface.get());
496         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), originalList), "Returned list doesn't match.");
497     }
498
499 }
500
501 RUNNER_TEST(ORM_MultipleBindDelete)
502 {
503     for ( int i = 0 ; i < TEST_REPETITION ; i++ )
504     {
505         ORM_Delete();
506     }
507 }
508
509 RUNNER_TEST(ORM_MultipleBindWhere)
510 {
511     SmartAttach interface;
512     using namespace DPL::DB::ORM;
513     using namespace DPL::DB::ORM::dpl_orm_test;
514     {
515         TestTable::Select select(interface.get());
516         int result;
517         select.Where(Equals<TestTable::ColumnInt>(8));
518         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
519
520         select.Where(Equals<TestTable::ColumnInt>(3));
521         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 1, "Got " << result);
522
523         select.Where(Equals<TestTable::ColumnInt>(8));
524         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 6, "Got " << result);
525
526         select.Where(Equals<TestTable::ColumnInt>(3));
527         RUNNER_ASSERT_MSG((result = *select.GetSingleValue<TestTable::ColumnOptInt>()) == 1, "Got " << result);
528     }
529
530     {
531         TestTable::Select select(interface.get());
532         int result;
533         select.Where(And(Equals<TestTable::ColumnInt>(99),
534                          Equals<TestTable::ColumnText>(L"fourteen")));
535         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
536
537         select.Where(And(Equals<TestTable::ColumnInt>(99),
538                          Equals<TestTable::ColumnText>(L"twelve")));
539         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
540
541         select.Where(And(Equals<TestTable::ColumnInt>(99),
542                          Equals<TestTable::ColumnText>(L"fourteen")));
543         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
544
545         select.Where(And(Equals<TestTable::ColumnInt>(99),
546                          Equals<TestTable::ColumnText>(L"twelve")));
547         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
548     }
549
550     {
551         TestTable::Select select(interface.get());
552         int result;
553         select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
554                          Equals<TestTable::ColumnInt>(99)));
555         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
556
557         select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
558                          Equals<TestTable::ColumnInt>(99)));
559         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
560
561         select.Where(And(Equals<TestTable::ColumnText>(L"fourteen"),
562                          Equals<TestTable::ColumnInt>(99)));
563         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 13, "Got " << result);
564
565         select.Where(And(Equals<TestTable::ColumnText>(L"twelve"),
566                          Equals<TestTable::ColumnInt>(99)));
567         RUNNER_ASSERT_MSG((result = select.GetSingleValue<TestTable::ColumnInt2>()) == 11, "Got " << result);
568
569     }
570
571 }
572
573 RUNNER_TEST(ORM_Update)
574 {
575     SmartAttach interface;
576     using namespace DPL::DB::ORM;
577     using namespace DPL::DB::ORM::dpl_orm_test;
578
579     std::list<TestTableInsert::Row> list;
580
581     TestTableInsert::Delete del(interface.get());
582     del.Execute();
583
584     // INSERT
585     {
586         TestTableInsert::Insert insert(interface.get());
587         TestTableInsert::Row row;
588         row.Set_ColumnOptInt(5);
589         row.Set_ColumnInt2(2);
590         row.Set_ColumnText(L"two");
591         insert.Values(row);
592         insert.Execute();
593
594         row.Set_ColumnInt(99);
595         list.push_back(row);
596     }
597     {
598         TestTableInsert::Insert insert(interface.get());
599         TestTableInsert::Row row;
600         row.Set_ColumnOptInt(1);
601         row.Set_ColumnInt2(2);
602         row.Set_ColumnText(L"three");
603         insert.Values(row);
604         insert.Execute();
605
606         row.Set_ColumnInt(99);
607         list.push_back(row);
608     }
609     {
610         TestTableInsert::Insert insert(interface.get());
611         TestTableInsert::Row row;
612         row.Set_ColumnOptInt(2);
613         row.Set_ColumnInt2(3);
614         row.Set_ColumnText(L"three");
615         insert.Values(row);
616         insert.Execute();
617
618         row.Set_ColumnInt(99);
619         list.push_back(row);
620
621         // CHECK
622         TestTableInsert::Select select(interface.get());
623         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
624     }
625     {
626         // UPDATE - no rows
627         TestTableInsert::Update update(interface.get());
628         TestTableInsert::Row row;
629         row.Set_ColumnInt2(4);
630         row.Set_ColumnText(L"four");
631         update.Values(row);
632         update.Where(Equals<TestTableInsert::ColumnInt2>(12));
633         update.Execute();
634
635         // CHECK
636         TestTableInsert::Select select(interface.get());
637         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
638     }
639     {
640         // UPDATE - one row
641         TestTableInsert::Update update(interface.get());
642         TestTableInsert::Row row;
643         row.Set_ColumnInt2(2);
644         row.Set_ColumnText(L"four");
645         update.Values(row);
646         update.Where(Equals<TestTableInsert::ColumnInt2>(3));
647         update.Execute();
648
649         list.back().Set_ColumnInt2(2);
650         list.back().Set_ColumnText(L"four");
651
652         // CHECK
653         TestTableInsert::Select select(interface.get());
654         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
655     }
656
657     {
658         // UPDATE - multiple rows
659         TestTableInsert::Update update(interface.get());
660         TestTableInsert::Row row;
661         row.Set_ColumnText(L"dup");
662         update.Values(row);
663         update.Where(Equals<TestTableInsert::ColumnInt2>(2));
664         update.Execute();
665
666         FOREACH(it, list)
667         {
668             it->Set_ColumnText(L"dup");
669         }
670
671         // CHECK
672         TestTableInsert::Select select(interface.get());
673         RUNNER_ASSERT_MSG(ContainerContentsEqual(select.GetRowList(), list), "Returned list doesn't match.");
674     }
675
676     // restore original table state
677     {
678         TestTableInsert::Delete del2(interface.get());
679         del2.Execute();
680
681         TestTableInsert::Select select(interface.get());
682         RUNNER_ASSERT(select.GetRowList().size() == 0);
683     }
684 }
685
686 RUNNER_TEST(ORM_MultipleBindUpdate)
687 {
688     for ( int i = 0 ; i < TEST_REPETITION ; i++ )
689     {
690         ORM_Update();
691     }
692 }
693
694 RUNNER_TEST(ORM_transactions)
695 {
696     SmartAttach interface;
697     DPL::DB::ORM::dpl_orm_test::ScopedTransaction transaction(interface.get());
698 }
699
700 RUNNER_TEST(ORM_MultiAttach)
701 {
702     SmartAttach interface(false);
703     RUNNER_ASSERT_MSG(!interface.get()->IsAttached(), "Is attached, but shouldn't be.");
704     interface.get()->AttachToThread();
705     RUNNER_ASSERT_MSG(interface.get()->IsAttached(), "Isn't attached, but should be.");
706     interface.get()->AttachToThread();
707     RUNNER_ASSERT_MSG(interface.get()->IsAttached(), "Isn't attached, but should be.");
708     interface.get()->DetachFromThread();
709     RUNNER_ASSERT_MSG(interface.get()->IsAttached(), "Isn't attached, but should be.");
710     interface.get()->DetachFromThread();
711     RUNNER_ASSERT_MSG(!interface.get()->IsAttached(), "Is attached, but shouldn't be.");
712 }