Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: sql/connection_unittest.cc

Issue 9768006: Implement sql::Connection::Raze() in terms of sqlite3_backup API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: gbillock comments. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« sql/connection.cc ('K') | « sql/connection.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/file_util.h" 5 #include "base/file_util.h"
6 #include "base/scoped_temp_dir.h" 6 #include "base/scoped_temp_dir.h"
7 #include "sql/connection.h" 7 #include "sql/connection.h"
8 #include "sql/statement.h" 8 #include "sql/statement.h"
9 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "third_party/sqlite/sqlite3.h" 10 #include "third_party/sqlite/sqlite3.h"
11 11
12 class SQLConnectionTest : public testing::Test { 12 class SQLConnectionTest : public testing::Test {
13 public: 13 public:
14 SQLConnectionTest() {} 14 SQLConnectionTest() {}
15 15
16 void SetUp() { 16 void SetUp() {
17 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 17 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
18 ASSERT_TRUE(db_.Open(temp_dir_.path().AppendASCII("SQLConnectionTest.db"))); 18 ASSERT_TRUE(db_.Open(db_path()));
19 } 19 }
20 20
21 void TearDown() { 21 void TearDown() {
22 db_.Close(); 22 db_.Close();
23 } 23 }
24 24
25 sql::Connection& db() { return db_; } 25 sql::Connection& db() { return db_; }
26 26
27 FilePath db_path() {
28 return temp_dir_.path().AppendASCII("SQLConnectionTest.db");
29 }
30
27 private: 31 private:
28 ScopedTempDir temp_dir_; 32 ScopedTempDir temp_dir_;
29 sql::Connection db_; 33 sql::Connection db_;
30 }; 34 };
31 35
32 TEST_F(SQLConnectionTest, Execute) { 36 TEST_F(SQLConnectionTest, Execute) {
33 // Valid statement should return true. 37 // Valid statement should return true.
34 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)")); 38 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
35 EXPECT_EQ(SQLITE_OK, db().GetErrorCode()); 39 EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
36 40
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 } 126 }
123 127
124 TEST_F(SQLConnectionTest, Rollback) { 128 TEST_F(SQLConnectionTest, Rollback) {
125 ASSERT_TRUE(db().BeginTransaction()); 129 ASSERT_TRUE(db().BeginTransaction());
126 ASSERT_TRUE(db().BeginTransaction()); 130 ASSERT_TRUE(db().BeginTransaction());
127 EXPECT_EQ(2, db().transaction_nesting()); 131 EXPECT_EQ(2, db().transaction_nesting());
128 db().RollbackTransaction(); 132 db().RollbackTransaction();
129 EXPECT_FALSE(db().CommitTransaction()); 133 EXPECT_FALSE(db().CommitTransaction());
130 EXPECT_TRUE(db().BeginTransaction()); 134 EXPECT_TRUE(db().BeginTransaction());
131 } 135 }
136
137 // Test that sql::Connection::Raze() results in a database without the
138 // tables from the original database.
139 TEST_F(SQLConnectionTest, Raze) {
140 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
141 ASSERT_TRUE(db().Execute(kCreateSql));
142 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
143
144 {
145 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
146 ASSERT_TRUE(s.Step());
147 EXPECT_EQ(2, s.ColumnInt(0));
148 }
149
150 {
151 sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
152 ASSERT_TRUE(s.Step());
153 EXPECT_EQ("table", s.ColumnString(0));
154 EXPECT_EQ("foo", s.ColumnString(1));
155 EXPECT_EQ("foo", s.ColumnString(2));
156 EXPECT_EQ(2, s.ColumnInt(3));
157 EXPECT_EQ(kCreateSql, s.ColumnString(4));
158 }
159
160 ASSERT_TRUE(db().Raze());
161
162 {
163 sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
164 ASSERT_TRUE(s.Step());
165 EXPECT_EQ(1, s.ColumnInt(0));
166 }
167
168 {
169 sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
170 ASSERT_FALSE(s.Step());
171 }
172 }
173
174 // Test that Raze() maintains page_size.
175 TEST_F(SQLConnectionTest, RazePageSize) {
176 const int kPageSize = 4096;
177
178 // Make sure that the default size isn't already |kPageSize|.
179 // Scoped to release statement before Close().
180 {
181 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
182 ASSERT_TRUE(s.Step());
183 ASSERT_NE(kPageSize, s.ColumnInt(0));
184 }
185
186 // Re-open the database to allow setting the page size.
187 db().Close();
188 db().set_page_size(kPageSize);
189 ASSERT_TRUE(db().Open(db_path()));
190
191 // page_size should match the indicated value.
192 sql::Statement s(db().GetUniqueStatement("PRAGMA page_size"));
193 ASSERT_TRUE(s.Step());
194 ASSERT_EQ(kPageSize, s.ColumnInt(0));
195
196 // After raze, page_size should still match the indicated value.
197 ASSERT_TRUE(db().Raze());
198 s.Reset();
199 ASSERT_TRUE(s.Step());
200 ASSERT_EQ(kPageSize, s.ColumnInt(0));
201 }
202
203 // Test that Raze() results are seen in other connections.
204 TEST_F(SQLConnectionTest, RazeMultiple) {
205 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
206 ASSERT_TRUE(db().Execute(kCreateSql));
207
208 sql::Connection other_db;
209 ASSERT_TRUE(other_db.Open(db_path()));
210
211 // Check that the second connection sees the table.
212 const char *kTablesQuery = "SELECT COUNT(*) FROM sqlite_master";
213 sql::Statement s(other_db.GetUniqueStatement(kTablesQuery));
214 ASSERT_TRUE(s.Step());
215 ASSERT_EQ(1, s.ColumnInt(0));
216 ASSERT_FALSE(s.Step()); // Releases the shared lock.
217
218 ASSERT_TRUE(db().Raze());
219
220 // The second connection sees the updated database.
221 s.Reset();
222 ASSERT_TRUE(s.Step());
223 ASSERT_EQ(0, s.ColumnInt(0));
224 }
225
226 TEST_F(SQLConnectionTest, RazeLocked) {
227 const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
228 ASSERT_TRUE(db().Execute(kCreateSql));
229
230 // Open a transaction and write some data in a second connection.
231 // This will acquire a PENDING or EXCLUSIVE transaction, which will
232 // cause the raze to fail.
233 sql::Connection other_db;
234 ASSERT_TRUE(other_db.Open(db_path()));
235 ASSERT_TRUE(other_db.BeginTransaction());
236 const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')";
237 ASSERT_TRUE(other_db.Execute(kInsertSql));
238
239 ASSERT_FALSE(db().Raze());
240
241 // Works after COMMIT.
242 ASSERT_TRUE(other_db.CommitTransaction());
243 ASSERT_TRUE(db().Raze());
244
245 // Re-create the database.
246 ASSERT_TRUE(db().Execute(kCreateSql));
247 ASSERT_TRUE(db().Execute(kInsertSql));
248
249 // An unfinished read transaction in the other connection also
250 // blocks raze.
251 const char *kQuery = "SELECT COUNT(*) FROM foo";
252 sql::Statement s(other_db.GetUniqueStatement(kQuery));
253 ASSERT_TRUE(s.Step());
254 ASSERT_FALSE(db().Raze());
255
256 // Complete the statement unlocks the database.
257 ASSERT_FALSE(s.Step());
258 ASSERT_TRUE(db().Raze());
259 }
260
261 // TODO(shess): Spin up a background thread to hold other_db, to more
262 // closely match real life. That would also allow testing
263 // RazeWithTimeout().
OLDNEW
« sql/connection.cc ('K') | « sql/connection.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698