comparison UnitTestsSources/SQLite.cpp @ 632:17815b9d4280

rename the UnitTests directory to avoid clashes in filenames
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 28 Oct 2013 16:26:51 +0100
parents UnitTests/SQLite.cpp@0e97abc7b950
children 96a2d2da0fee
comparison
equal deleted inserted replaced
631:fc6ad5b97219 632:17815b9d4280
1 #include "gtest/gtest.h"
2
3 #include "../Core/Toolbox.h"
4 #include "../Core/SQLite/Connection.h"
5 #include "../Core/SQLite/Statement.h"
6 #include "../Core/SQLite/Transaction.h"
7
8 #include <sqlite3.h>
9
10 using namespace Orthanc;
11
12
13 TEST(SQLite, Configuration)
14 {
15 ASSERT_EQ(1, sqlite3_threadsafe());
16 }
17
18
19 TEST(SQLite, Connection)
20 {
21 Toolbox::RemoveFile("coucou");
22 SQLite::Connection c;
23 c.Open("coucou");
24 c.Execute("CREATE TABLE c(k INTEGER PRIMARY KEY AUTOINCREMENT, v INTEGER)");
25 c.Execute("INSERT INTO c VALUES(NULL, 42);");
26 }
27
28
29 TEST(SQLite, StatementReferenceBasic)
30 {
31 sqlite3* db;
32 sqlite3_open(":memory:", &db);
33
34 {
35 SQLite::StatementReference r(db, "SELECT * FROM sqlite_master");
36 ASSERT_EQ(0u, r.GetReferenceCount());
37
38 {
39 SQLite::StatementReference r1(r);
40 ASSERT_EQ(1u, r.GetReferenceCount());
41 ASSERT_EQ(0u, r1.GetReferenceCount());
42
43 {
44 SQLite::StatementReference r2(r);
45 ASSERT_EQ(2u, r.GetReferenceCount());
46 ASSERT_EQ(0u, r1.GetReferenceCount());
47 ASSERT_EQ(0u, r2.GetReferenceCount());
48
49 SQLite::StatementReference r3(r2);
50 ASSERT_EQ(3u, r.GetReferenceCount());
51 ASSERT_EQ(0u, r1.GetReferenceCount());
52 ASSERT_EQ(0u, r2.GetReferenceCount());
53 ASSERT_EQ(0u, r3.GetReferenceCount());
54 }
55
56 ASSERT_EQ(1u, r.GetReferenceCount());
57 ASSERT_EQ(0u, r1.GetReferenceCount());
58
59 {
60 SQLite::StatementReference r2(r);
61 ASSERT_EQ(2u, r.GetReferenceCount());
62 ASSERT_EQ(0u, r1.GetReferenceCount());
63 ASSERT_EQ(0u, r2.GetReferenceCount());
64 }
65
66 ASSERT_EQ(1u, r.GetReferenceCount());
67 ASSERT_EQ(0u, r1.GetReferenceCount());
68 }
69
70 ASSERT_EQ(0u, r.GetReferenceCount());
71 }
72
73 sqlite3_close(db);
74 }
75
76 TEST(SQLite, StatementBasic)
77 {
78 SQLite::Connection c;
79 c.OpenInMemory();
80
81 SQLite::Statement s(c, "SELECT * from sqlite_master");
82 s.Run();
83
84 for (unsigned int i = 0; i < 5; i++)
85 {
86 SQLite::Statement cs(c, SQLITE_FROM_HERE, "SELECT * from sqlite_master");
87 cs.Step();
88 }
89 }
90
91
92 namespace
93 {
94 static bool destroyed;
95
96 class MyFunc : public SQLite::IScalarFunction
97 {
98 public:
99 MyFunc()
100 {
101 destroyed = false;
102 }
103
104 virtual ~MyFunc()
105 {
106 destroyed = true;
107 }
108
109 virtual const char* GetName() const
110 {
111 return "MYFUNC";
112 }
113
114 virtual unsigned int GetCardinality() const
115 {
116 return 2;
117 }
118
119 virtual void Compute(SQLite::FunctionContext& context)
120 {
121 context.SetIntResult(1000 + context.GetIntValue(0) * context.GetIntValue(1));
122 }
123 };
124
125 class MyDelete : public SQLite::IScalarFunction
126 {
127 public:
128 std::set<int> deleted_;
129
130 virtual const char* GetName() const
131 {
132 return "MYDELETE";
133 }
134
135 virtual unsigned int GetCardinality() const
136 {
137 return 1;
138 }
139
140 virtual void Compute(SQLite::FunctionContext& context)
141 {
142 deleted_.insert(context.GetIntValue(0));
143 context.SetNullResult();
144 }
145 };
146 }
147
148 TEST(SQLite, ScalarFunction)
149 {
150 {
151 SQLite::Connection c;
152 c.OpenInMemory();
153 c.Register(new MyFunc());
154 c.Execute("CREATE TABLE t(id INTEGER PRIMARY KEY, v1 INTEGER, v2 INTEGER);");
155 c.Execute("INSERT INTO t VALUES(NULL, 2, 3);");
156 c.Execute("INSERT INTO t VALUES(NULL, 4, 4);");
157 c.Execute("INSERT INTO t VALUES(NULL, 6, 5);");
158 SQLite::Statement t(c, "SELECT MYFUNC(v1, v2), v1, v2 FROM t");
159 int i = 0;
160 while (t.Step())
161 {
162 ASSERT_EQ(t.ColumnInt(0), 1000 + t.ColumnInt(1) * t.ColumnInt(2));
163 i++;
164 }
165 ASSERT_EQ(3, i);
166 ASSERT_FALSE(destroyed);
167 }
168 ASSERT_TRUE(destroyed);
169 }
170
171 TEST(SQLite, CascadedDeleteCallback)
172 {
173 SQLite::Connection c;
174 c.OpenInMemory();
175 MyDelete *func = new MyDelete();
176 c.Register(func);
177 c.Execute("CREATE TABLE parent(id INTEGER PRIMARY KEY, dummy INTEGER);");
178 c.Execute("CREATE TABLE child("
179 " id INTEGER PRIMARY KEY, "
180 " parent INTEGER REFERENCES parent(id) ON DELETE CASCADE, "
181 " value INTEGER);");
182 c.Execute("CREATE TRIGGER childRemoved "
183 "AFTER DELETE ON child "
184 "FOR EACH ROW BEGIN "
185 " SELECT MYDELETE(old.value); "
186 "END;");
187
188 c.Execute("INSERT INTO parent VALUES(42, 100);");
189 c.Execute("INSERT INTO parent VALUES(43, 101);");
190
191 c.Execute("INSERT INTO child VALUES(NULL, 42, 4200);");
192 c.Execute("INSERT INTO child VALUES(NULL, 42, 4201);");
193
194 c.Execute("INSERT INTO child VALUES(NULL, 43, 4300);");
195 c.Execute("INSERT INTO child VALUES(NULL, 43, 4301);");
196
197 // The following command deletes "parent(43, 101)", then in turns
198 // "child(NULL, 43, 4300/4301)", then calls the MyDelete on 4300 and
199 // 4301
200 c.Execute("DELETE FROM parent WHERE dummy=101");
201
202 ASSERT_EQ(2u, func->deleted_.size());
203 ASSERT_TRUE(func->deleted_.find(4300) != func->deleted_.end());
204 ASSERT_TRUE(func->deleted_.find(4301) != func->deleted_.end());
205 }
206
207
208 TEST(SQLite, EmptyTransactions)
209 {
210 try
211 {
212 SQLite::Connection c;
213 c.OpenInMemory();
214
215 c.Execute("CREATE TABLE a(id INTEGER PRIMARY KEY);");
216 c.Execute("INSERT INTO a VALUES(NULL)");
217
218 {
219 SQLite::Transaction t(c);
220 t.Begin();
221 {
222 SQLite::Statement s(c, SQLITE_FROM_HERE, "SELECT * FROM a");
223 s.Step();
224 }
225 //t.Commit();
226 }
227
228 {
229 SQLite::Statement s(c, SQLITE_FROM_HERE, "SELECT * FROM a");
230 s.Step();
231 }
232 }
233 catch (OrthancException& e)
234 {
235 fprintf(stderr, "Exception: [%s]\n", e.What());
236 throw e;
237 }
238 }