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

Side by Side Diff: sql/connection.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
« no previous file with comments | « sql/connection.h ('k') | sql/connection_unittest.cc » ('j') | 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 "sql/connection.h" 5 #include "sql/connection.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include "base/file_path.h" 9 #include "base/file_path.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
161 if (!dummy.Step()) 161 if (!dummy.Step())
162 return; 162 return;
163 163
164 #if !defined(USE_SYSTEM_SQLITE) 164 #if !defined(USE_SYSTEM_SQLITE)
165 // This function is only defined in Chromium's version of sqlite. 165 // This function is only defined in Chromium's version of sqlite.
166 // Do not call it when using system sqlite. 166 // Do not call it when using system sqlite.
167 sqlite3_preload(db_); 167 sqlite3_preload(db_);
168 #endif 168 #endif
169 } 169 }
170 170
171 // Create an in-memory database with the existing database's page
172 // size, then backup that database over the existing database.
173 bool Connection::Raze() {
174 if (!db_) {
175 DLOG(FATAL) << "Cannot raze null db";
176 return false;
177 }
178
179 if (transaction_nesting_ > 0) {
180 DLOG(FATAL) << "Cannot raze within a transaction";
181 return false;
182 }
183
184 sql::Connection null_db;
185 if (!null_db.OpenInMemory()) {
186 DLOG(FATAL) << "Unable to open in-memory database.";
187 return false;
188 }
189
190 // Get the page size from the current connection, then propagate it
191 // to the null database.
192 Statement s(GetUniqueStatement("PRAGMA page_size"));
193 if (!s.Step())
194 return false;
195 const std::string sql = StringPrintf("PRAGMA page_size=%d", s.ColumnInt(0));
196 if (!null_db.Execute(sql.c_str()))
197 return false;
198
199 // The page size doesn't take effect until a database has pages, and
200 // at this point the null database has none. Changing the schema
201 // version will create the first page. This will not affect the
202 // schema version in the resulting database, as SQLite's backup
203 // implementation propagates the schema version from the original
204 // connection to the new version of the database, incremented by one
205 // so that other readers see the schema change and act accordingly.
206 if (!null_db.Execute("PRAGMA schema_version = 1"))
207 return false;
208
209 sqlite3_backup* backup = sqlite3_backup_init(db_, "main",
210 null_db.db_, "main");
211 if (!backup) {
212 DLOG(FATAL) << "Unable to start sqlite3_backup().";
213 return false;
214 }
215
216 // -1 backs up the entire database.
217 int rc = sqlite3_backup_step(backup, -1);
218 int pages = sqlite3_backup_pagecount(backup);
219 sqlite3_backup_finish(backup);
220
221 // The destination database was locked.
222 if (rc == SQLITE_BUSY) {
223 return false;
224 }
225
226 // The entire database should have been backed up.
227 if (rc != SQLITE_DONE) {
228 DLOG(FATAL) << "Unable to copy entire null database.";
229 return false;
230 }
231
232 // Exactly one page should have been backed up. If this breaks,
233 // check this function to make sure assumptions aren't being broken.
234 DCHECK_EQ(pages, 1);
Greg Billock 2012/04/04 19:49:21 Likes it. That should get the attention of a versi
235
236 return true;
237 }
238
239 bool Connection::RazeWithTimout(base::TimeDelta timeout) {
240 if (!db_) {
241 DLOG(FATAL) << "Cannot raze null db";
242 return false;
243 }
244
245 ScopedBusyTimeout busy_timeout(db_);
246 busy_timeout.SetTimeout(timeout);
247 return Raze();
248 }
249
171 bool Connection::BeginTransaction() { 250 bool Connection::BeginTransaction() {
172 if (needs_rollback_) { 251 if (needs_rollback_) {
173 DCHECK_GT(transaction_nesting_, 0); 252 DCHECK_GT(transaction_nesting_, 0);
174 253
175 // When we're going to rollback, fail on this begin and don't actually 254 // When we're going to rollback, fail on this begin and don't actually
176 // mark us as entering the nested transaction. 255 // mark us as entering the nested transaction.
177 return false; 256 return false;
178 } 257 }
179 258
180 bool success = true; 259 bool success = true;
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 564
486 int Connection::OnSqliteError(int err, sql::Statement *stmt) { 565 int Connection::OnSqliteError(int err, sql::Statement *stmt) {
487 if (error_delegate_.get()) 566 if (error_delegate_.get())
488 return error_delegate_->OnError(err, this, stmt); 567 return error_delegate_->OnError(err, this, stmt);
489 // The default handling is to assert on debug and to ignore on release. 568 // The default handling is to assert on debug and to ignore on release.
490 DLOG(FATAL) << GetErrorMessage(); 569 DLOG(FATAL) << GetErrorMessage();
491 return err; 570 return err;
492 } 571 }
493 572
494 } // namespace sql 573 } // namespace sql
OLDNEW
« no previous file with comments | « sql/connection.h ('k') | sql/connection_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698