OLD | NEW |
---|---|
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 Loading... | |
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 // Propagate the page size to the new database. | |
Greg Billock
2012/03/31 01:23:50
Maybe say that this gets the page_size from the cu
Scott Hess - ex-Googler
2012/04/04 01:28:25
OK.
| |
191 Statement s(GetUniqueStatement("PRAGMA page_size")); | |
192 if (!s.Step()) | |
193 return false; | |
194 | |
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 // At this point the null database has no pages. Force it to have | |
200 // one. The backup API tracks the original schema from the | |
Greg Billock
2012/03/31 01:23:50
so the new DB after the backup will have schema_ve
Scott Hess - ex-Googler
2012/04/04 01:28:25
The backup API restores the backup destination's s
| |
201 // destination database and writes it back (incremented once) after | |
202 // the backup. | |
203 if (!null_db.Execute("PRAGMA schema_version = 1")) | |
204 return false; | |
205 | |
206 sqlite3_backup* backup = sqlite3_backup_init(db_, "main", | |
207 null_db.db_, "main"); | |
208 if (!backup) { | |
209 DLOG(FATAL) << "Unable to start sqlite3_backup()."; | |
210 return false; | |
211 } | |
212 | |
213 ScopedBusyTimeout busy_timeout(db_); | |
214 busy_timeout.SetTimeout(base::TimeDelta::FromSeconds(1)); | |
Greg Billock
2012/03/31 01:23:50
Just rely on callers to use RazeWithTimeout here?
Scott Hess - ex-Googler
2012/04/04 01:28:25
That is a really good suggestion. I must have bee
| |
215 | |
216 int rc = sqlite3_backup_step(backup, 1); | |
Greg Billock
2012/03/31 01:23:50
doc says pass -1 to copy all remaining pages. Woul
Scott Hess - ex-Googler
2012/04/04 01:28:25
Partly because I must have missed the -1 setting.
Scott Hess - ex-Googler
2012/04/04 19:26:54
I modified this code to use sqlite3_backup_pagecou
| |
217 sqlite3_backup_finish(backup); | |
218 | |
219 // The destination database was locked. | |
220 if (rc == SQLITE_BUSY) { | |
Greg Billock
2012/03/31 01:23:50
Is there a way to force it open? Presumably someth
Scott Hess - ex-Googler
2012/04/04 01:28:25
Unfortunately, there's no way to force it open wit
| |
221 return false; | |
222 } | |
223 | |
224 // There should only be a single page to copy. | |
Greg Billock
2012/03/31 01:23:50
Using -1 would mean you don't need this, I think.
| |
225 if (rc != SQLITE_DONE) { | |
226 DLOG(FATAL) << "Unable to copy entire null database."; | |
227 return false; | |
228 } | |
229 | |
230 return true; | |
231 } | |
232 bool Connection::RazeWithTimout(base::TimeDelta timeout) { | |
233 if (!db_) { | |
234 DLOG(FATAL) << "Cannot raze null db"; | |
235 return false; | |
236 } | |
237 | |
238 ScopedBusyTimeout busy_timeout(db_); | |
239 busy_timeout.SetTimeout(timeout); | |
240 return Raze(); | |
241 } | |
242 | |
171 bool Connection::BeginTransaction() { | 243 bool Connection::BeginTransaction() { |
172 if (needs_rollback_) { | 244 if (needs_rollback_) { |
173 DCHECK_GT(transaction_nesting_, 0); | 245 DCHECK_GT(transaction_nesting_, 0); |
174 | 246 |
175 // When we're going to rollback, fail on this begin and don't actually | 247 // When we're going to rollback, fail on this begin and don't actually |
176 // mark us as entering the nested transaction. | 248 // mark us as entering the nested transaction. |
177 return false; | 249 return false; |
178 } | 250 } |
179 | 251 |
180 bool success = true; | 252 bool success = true; |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
484 | 556 |
485 int Connection::OnSqliteError(int err, sql::Statement *stmt) { | 557 int Connection::OnSqliteError(int err, sql::Statement *stmt) { |
486 if (error_delegate_.get()) | 558 if (error_delegate_.get()) |
487 return error_delegate_->OnError(err, this, stmt); | 559 return error_delegate_->OnError(err, this, stmt); |
488 // The default handling is to assert on debug and to ignore on release. | 560 // The default handling is to assert on debug and to ignore on release. |
489 DLOG(FATAL) << GetErrorMessage(); | 561 DLOG(FATAL) << GetErrorMessage(); |
490 return err; | 562 return err; |
491 } | 563 } |
492 | 564 |
493 } // namespace sql | 565 } // namespace sql |
OLD | NEW |