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

Side by Side Diff: chrome/browser/sync/util/user_settings.cc

Issue 7528026: sync: Put sqlite_utils.* into sqlite_utils namespace. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 4 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 // This class isn't pretty. It's just a step better than globals, which is what 5 // This class isn't pretty. It's just a step better than globals, which is what
6 // these were previously. 6 // these were previously.
7 7
8 #include "chrome/browser/sync/util/user_settings.h" 8 #include "chrome/browser/sync/util/user_settings.h"
9 9
10 #include "build/build_config.h" 10 #include "build/build_config.h"
(...skipping 17 matching lines...) Expand all
28 28
29 using std::numeric_limits; 29 using std::numeric_limits;
30 using std::string; 30 using std::string;
31 using std::vector; 31 using std::vector;
32 32
33 using syncable::DirectoryManager; 33 using syncable::DirectoryManager;
34 34
35 namespace browser_sync { 35 namespace browser_sync {
36 36
37 void ExecOrDie(sqlite3* dbhandle, const char *query) { 37 void ExecOrDie(sqlite3* dbhandle, const char *query) {
38 SQLStatement statement; 38 sqlite_utils::SQLStatement statement;
39 statement.prepare(dbhandle, query); 39 statement.prepare(dbhandle, query);
40 if (SQLITE_DONE != statement.step()) { 40 if (SQLITE_DONE != statement.step()) {
41 LOG(FATAL) << query << "\n" << sqlite3_errmsg(dbhandle); 41 LOG(FATAL) << query << "\n" << sqlite3_errmsg(dbhandle);
42 } 42 }
43 } 43 }
44 44
45 // Useful for encoding any sequence of bytes into a string that can be used in 45 // Useful for encoding any sequence of bytes into a string that can be used in
46 // a table name. Kind of like hex encoding, except that A is zero and P is 15. 46 // a table name. Kind of like hex encoding, except that A is zero and P is 15.
47 string APEncode(const string& in) { 47 string APEncode(const string& in) {
48 string result; 48 string result;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 LOG(WARNING) << "UserSettings database version " << current_version << 107 LOG(WARNING) << "UserSettings database version " << current_version <<
108 " is too old to handle."; 108 " is too old to handle.";
109 return; 109 return;
110 case 10: 110 case 10:
111 { 111 {
112 // Scrape the 'shares' table to find the syncable DB. 'shares' had a 112 // Scrape the 'shares' table to find the syncable DB. 'shares' had a
113 // pair of string columns that mapped the username to the filename of 113 // pair of string columns that mapped the username to the filename of
114 // the sync data sqlite3 file. Version 11 switched to a constant 114 // the sync data sqlite3 file. Version 11 switched to a constant
115 // filename, so here we read the string, copy the file to the new name, 115 // filename, so here we read the string, copy the file to the new name,
116 // delete the old one, and then drop the unused shares table. 116 // delete the old one, and then drop the unused shares table.
117 SQLStatement share_query; 117 sqlite_utils::SQLStatement share_query;
118 share_query.prepare(handle, "SELECT share_name, file_name FROM shares"); 118 share_query.prepare(handle, "SELECT share_name, file_name FROM shares");
119 int query_result = share_query.step(); 119 int query_result = share_query.step();
120 CHECK(SQLITE_ROW == query_result); 120 CHECK(SQLITE_ROW == query_result);
121 FilePath::StringType share_name, file_name; 121 FilePath::StringType share_name, file_name;
122 #if defined(OS_POSIX) 122 #if defined(OS_POSIX)
123 share_name = share_query.column_string(0); 123 share_name = share_query.column_string(0);
124 file_name = share_query.column_string(1); 124 file_name = share_query.column_string(1);
125 #else 125 #else
126 share_name = share_query.column_wstring(0); 126 share_name = share_query.column_wstring(0);
127 file_name = share_query.column_wstring(1); 127 file_name = share_query.column_wstring(1);
(...skipping 30 matching lines...) Expand all
158 "CREATE TABLE cookies" 158 "CREATE TABLE cookies"
159 " (email, service_name, service_token, " 159 " (email, service_name, service_token, "
160 " PRIMARY KEY(email, service_name) ON CONFLICT REPLACE)"); 160 " PRIMARY KEY(email, service_name) ON CONFLICT REPLACE)");
161 } 161 }
162 162
163 static void MakeClientIDTable(sqlite3* const dbhandle) { 163 static void MakeClientIDTable(sqlite3* const dbhandle) {
164 // Stores a single client ID value that can be used as the client id, if 164 // Stores a single client ID value that can be used as the client id, if
165 // there's not another such ID provided on the install. 165 // there's not another such ID provided on the install.
166 ExecOrDie(dbhandle, "CREATE TABLE client_id (id) "); 166 ExecOrDie(dbhandle, "CREATE TABLE client_id (id) ");
167 { 167 {
168 SQLStatement statement; 168 sqlite_utils::SQLStatement statement;
169 statement.prepare(dbhandle, 169 statement.prepare(dbhandle,
170 "INSERT INTO client_id values ( ? )"); 170 "INSERT INTO client_id values ( ? )");
171 statement.bind_string(0, Generate128BitRandomBase64String()); 171 statement.bind_string(0, Generate128BitRandomBase64String());
172 if (SQLITE_DONE != statement.step()) { 172 if (SQLITE_DONE != statement.step()) {
173 LOG(FATAL) << "INSERT INTO client_id\n" << sqlite3_errmsg(dbhandle); 173 LOG(FATAL) << "INSERT INTO client_id\n" << sqlite3_errmsg(dbhandle);
174 } 174 }
175 } 175 }
176 } 176 }
177 177
178 bool UserSettings::Init(const FilePath& settings_path) { 178 bool UserSettings::Init(const FilePath& settings_path) {
179 { // Scope the handle. 179 { // Scope the handle.
180 ScopedDBHandle dbhandle(this); 180 ScopedDBHandle dbhandle(this);
181 if (dbhandle_) 181 if (dbhandle_)
182 sqlite3_close(dbhandle_); 182 sqlite3_close(dbhandle_);
183 183
184 if (SQLITE_OK != sqlite_utils::OpenSqliteDb(settings_path, &dbhandle_)) 184 if (SQLITE_OK != sqlite_utils::OpenSqliteDb(settings_path, &dbhandle_))
185 return false; 185 return false;
186 186
187 // In the worst case scenario, the user may hibernate his computer during 187 // In the worst case scenario, the user may hibernate his computer during
188 // one of our transactions. 188 // one of our transactions.
189 sqlite3_busy_timeout(dbhandle_, numeric_limits<int>::max()); 189 sqlite3_busy_timeout(dbhandle_, numeric_limits<int>::max());
190 ExecOrDie(dbhandle.get(), "PRAGMA fullfsync = 1"); 190 ExecOrDie(dbhandle.get(), "PRAGMA fullfsync = 1");
191 ExecOrDie(dbhandle.get(), "PRAGMA synchronous = 2"); 191 ExecOrDie(dbhandle.get(), "PRAGMA synchronous = 2");
192 192
193 SQLTransaction transaction(dbhandle.get()); 193 sqlite_utils::SQLTransaction transaction(dbhandle.get());
194 transaction.BeginExclusive(); 194 transaction.BeginExclusive();
195 SQLStatement table_query; 195 sqlite_utils::SQLStatement table_query;
196 table_query.prepare(dbhandle.get(), 196 table_query.prepare(dbhandle.get(),
197 "select count(*) from sqlite_master" 197 "select count(*) from sqlite_master"
198 " where type = 'table' and name = 'db_version'"); 198 " where type = 'table' and name = 'db_version'");
199 int query_result = table_query.step(); 199 int query_result = table_query.step();
200 CHECK(SQLITE_ROW == query_result); 200 CHECK(SQLITE_ROW == query_result);
201 int table_count = table_query.column_int(0); 201 int table_count = table_query.column_int(0);
202 table_query.reset(); 202 table_query.reset();
203 if (table_count > 0) { 203 if (table_count > 0) {
204 SQLStatement version_query; 204 sqlite_utils::SQLStatement version_query;
205 version_query.prepare(dbhandle.get(), 205 version_query.prepare(dbhandle.get(),
206 "SELECT version FROM db_version"); 206 "SELECT version FROM db_version");
207 query_result = version_query.step(); 207 query_result = version_query.step();
208 CHECK(SQLITE_ROW == query_result); 208 CHECK(SQLITE_ROW == query_result);
209 const int version = version_query.column_int(0); 209 const int version = version_query.column_int(0);
210 version_query.reset(); 210 version_query.reset();
211 if (version > kCurrentDBVersion) { 211 if (version > kCurrentDBVersion) {
212 LOG(WARNING) << "UserSettings database is too new."; 212 LOG(WARNING) << "UserSettings database is too new.";
213 return false; 213 return false;
214 } 214 }
215 215
216 MigrateOldVersionsAsNeeded(dbhandle.get(), version); 216 MigrateOldVersionsAsNeeded(dbhandle.get(), version);
217 } else { 217 } else {
218 // Create settings table. 218 // Create settings table.
219 { 219 {
220 SQLStatement statement; 220 sqlite_utils::SQLStatement statement;
221 statement.prepare(dbhandle.get(), 221 statement.prepare(dbhandle.get(),
222 "CREATE TABLE settings" 222 "CREATE TABLE settings"
223 " (email, key, value, " 223 " (email, key, value, "
224 " PRIMARY KEY(email, key) ON CONFLICT REPLACE)"); 224 " PRIMARY KEY(email, key) ON CONFLICT REPLACE)");
225 if (SQLITE_DONE != statement.step()) { 225 if (SQLITE_DONE != statement.step()) {
226 return false; 226 return false;
227 } 227 }
228 } 228 }
229 // Create and populate version table. 229 // Create and populate version table.
230 { 230 {
231 SQLStatement statement; 231 sqlite_utils::SQLStatement statement;
232 statement.prepare(dbhandle.get(), 232 statement.prepare(dbhandle.get(),
233 "CREATE TABLE db_version ( version )"); 233 "CREATE TABLE db_version ( version )");
234 if (SQLITE_DONE != statement.step()) { 234 if (SQLITE_DONE != statement.step()) {
235 return false; 235 return false;
236 } 236 }
237 } 237 }
238 { 238 {
239 SQLStatement statement; 239 sqlite_utils::SQLStatement statement;
240 statement.prepare(dbhandle.get(), 240 statement.prepare(dbhandle.get(),
241 "INSERT INTO db_version values ( ? )"); 241 "INSERT INTO db_version values ( ? )");
242 statement.bind_int(0, kCurrentDBVersion); 242 statement.bind_int(0, kCurrentDBVersion);
243 if (SQLITE_DONE != statement.step()) { 243 if (SQLITE_DONE != statement.step()) {
244 return false; 244 return false;
245 } 245 }
246 } 246 }
247 247
248 MakeSigninsTable(dbhandle.get()); 248 MakeSigninsTable(dbhandle.get());
249 MakeCookiesTable(dbhandle.get()); 249 MakeCookiesTable(dbhandle.get());
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
281 mask = mask >> 8; 281 mask = mask >> 8;
282 if (0 == mask) 282 if (0 == mask)
283 break; 283 break;
284 } 284 }
285 return hash; 285 return hash;
286 } 286 }
287 287
288 void UserSettings::StoreEmailForSignin(const string& signin, 288 void UserSettings::StoreEmailForSignin(const string& signin,
289 const string& primary_email) { 289 const string& primary_email) {
290 ScopedDBHandle dbhandle(this); 290 ScopedDBHandle dbhandle(this);
291 SQLTransaction transaction(dbhandle.get()); 291 sqlite_utils::SQLTransaction transaction(dbhandle.get());
292 int sqlite_result = transaction.BeginExclusive(); 292 int sqlite_result = transaction.BeginExclusive();
293 CHECK(SQLITE_OK == sqlite_result); 293 CHECK(SQLITE_OK == sqlite_result);
294 SQLStatement query; 294 sqlite_utils::SQLStatement query;
295 query.prepare(dbhandle.get(), 295 query.prepare(dbhandle.get(),
296 "SELECT COUNT(*) FROM signins" 296 "SELECT COUNT(*) FROM signins"
297 " WHERE signin = ? AND primary_email = ?"); 297 " WHERE signin = ? AND primary_email = ?");
298 query.bind_string(0, signin); 298 query.bind_string(0, signin);
299 query.bind_string(1, primary_email); 299 query.bind_string(1, primary_email);
300 int query_result = query.step(); 300 int query_result = query.step();
301 CHECK(SQLITE_ROW == query_result); 301 CHECK(SQLITE_ROW == query_result);
302 int32 count = query.column_int(0); 302 int32 count = query.column_int(0);
303 query.reset(); 303 query.reset();
304 if (0 == count) { 304 if (0 == count) {
305 // Migrate any settings the user might have from earlier versions. 305 // Migrate any settings the user might have from earlier versions.
306 { 306 {
307 SQLStatement statement; 307 sqlite_utils::SQLStatement statement;
308 statement.prepare(dbhandle.get(), 308 statement.prepare(dbhandle.get(),
309 "UPDATE settings SET email = ? WHERE email = ?"); 309 "UPDATE settings SET email = ? WHERE email = ?");
310 statement.bind_string(0, signin); 310 statement.bind_string(0, signin);
311 statement.bind_string(1, primary_email); 311 statement.bind_string(1, primary_email);
312 if (SQLITE_DONE != statement.step()) { 312 if (SQLITE_DONE != statement.step()) {
313 LOG(FATAL) << sqlite3_errmsg(dbhandle.get()); 313 LOG(FATAL) << sqlite3_errmsg(dbhandle.get());
314 } 314 }
315 } 315 }
316 // Store this signin:email mapping. 316 // Store this signin:email mapping.
317 { 317 {
318 SQLStatement statement; 318 sqlite_utils::SQLStatement statement;
319 statement.prepare(dbhandle.get(), 319 statement.prepare(dbhandle.get(),
320 "INSERT INTO signins(signin, primary_email)" 320 "INSERT INTO signins(signin, primary_email)"
321 " values ( ?, ? )"); 321 " values ( ?, ? )");
322 statement.bind_string(0, signin); 322 statement.bind_string(0, signin);
323 statement.bind_string(1, primary_email); 323 statement.bind_string(1, primary_email);
324 if (SQLITE_DONE != statement.step()) { 324 if (SQLITE_DONE != statement.step()) {
325 LOG(FATAL) << sqlite3_errmsg(dbhandle.get()); 325 LOG(FATAL) << sqlite3_errmsg(dbhandle.get());
326 } 326 }
327 } 327 }
328 } 328 }
329 transaction.Commit(); 329 transaction.Commit();
330 } 330 }
331 331
332 // string* signin is both the input and the output of this function. 332 // string* signin is both the input and the output of this function.
333 bool UserSettings::GetEmailForSignin(string* signin) { 333 bool UserSettings::GetEmailForSignin(string* signin) {
334 ScopedDBHandle dbhandle(this); 334 ScopedDBHandle dbhandle(this);
335 string result; 335 string result;
336 SQLStatement query; 336 sqlite_utils::SQLStatement query;
337 query.prepare(dbhandle.get(), 337 query.prepare(dbhandle.get(),
338 "SELECT primary_email FROM signins WHERE signin = ?"); 338 "SELECT primary_email FROM signins WHERE signin = ?");
339 query.bind_string(0, *signin); 339 query.bind_string(0, *signin);
340 int query_result = query.step(); 340 int query_result = query.step();
341 if (SQLITE_ROW == query_result) { 341 if (SQLITE_ROW == query_result) {
342 query.column_string(0, &result); 342 query.column_string(0, &result);
343 if (!result.empty()) { 343 if (!result.empty()) {
344 swap(result, *signin); 344 swap(result, *signin);
345 return true; 345 return true;
346 } 346 }
347 } 347 }
348 return false; 348 return false;
349 } 349 }
350 350
351 void UserSettings::StoreHashedPassword(const string& email, 351 void UserSettings::StoreHashedPassword(const string& email,
352 const string& password) { 352 const string& password) {
353 // Save one-way hashed password: 353 // Save one-way hashed password:
354 char binary_salt[kSaltSize]; 354 char binary_salt[kSaltSize];
355 base::RandBytes(binary_salt, sizeof(binary_salt)); 355 base::RandBytes(binary_salt, sizeof(binary_salt));
356 356
357 const string salt = APEncode(string(binary_salt, sizeof(binary_salt))); 357 const string salt = APEncode(string(binary_salt, sizeof(binary_salt)));
358 base::MD5Context md5_context; 358 base::MD5Context md5_context;
359 base::MD5Init(&md5_context); 359 base::MD5Init(&md5_context);
360 base::MD5Update(&md5_context, salt); 360 base::MD5Update(&md5_context, salt);
361 base::MD5Update(&md5_context, password); 361 base::MD5Update(&md5_context, password);
362 base::MD5Digest md5_digest; 362 base::MD5Digest md5_digest;
363 base::MD5Final(&md5_digest, &md5_context); 363 base::MD5Final(&md5_digest, &md5_context);
364 364
365 ScopedDBHandle dbhandle(this); 365 ScopedDBHandle dbhandle(this);
366 SQLTransaction transaction(dbhandle.get()); 366 sqlite_utils::SQLTransaction transaction(dbhandle.get());
367 transaction.BeginExclusive(); 367 transaction.BeginExclusive();
368 { 368 {
369 SQLStatement statement; 369 sqlite_utils::SQLStatement statement;
370 statement.prepare(dbhandle.get(), 370 statement.prepare(dbhandle.get(),
371 "INSERT INTO settings(email, key, value)" 371 "INSERT INTO settings(email, key, value)"
372 " values ( ?, ?, ? )"); 372 " values ( ?, ?, ? )");
373 statement.bind_string(0, email); 373 statement.bind_string(0, email);
374 statement.bind_string(1, PASSWORD_HASH); 374 statement.bind_string(1, PASSWORD_HASH);
375 statement.bind_int(2, GetHashFromDigest(md5_digest)); 375 statement.bind_int(2, GetHashFromDigest(md5_digest));
376 if (SQLITE_DONE != statement.step()) { 376 if (SQLITE_DONE != statement.step()) {
377 LOG(FATAL) << sqlite3_errmsg(dbhandle.get()); 377 LOG(FATAL) << sqlite3_errmsg(dbhandle.get());
378 } 378 }
379 } 379 }
380 { 380 {
381 SQLStatement statement; 381 sqlite_utils::SQLStatement statement;
382 statement.prepare(dbhandle.get(), 382 statement.prepare(dbhandle.get(),
383 "INSERT INTO settings(email, key, value)" 383 "INSERT INTO settings(email, key, value)"
384 " values ( ?, ?, ? )"); 384 " values ( ?, ?, ? )");
385 statement.bind_string(0, email); 385 statement.bind_string(0, email);
386 statement.bind_string(1, SALT); 386 statement.bind_string(1, SALT);
387 statement.bind_string(2, salt); 387 statement.bind_string(2, salt);
388 if (SQLITE_DONE != statement.step()) { 388 if (SQLITE_DONE != statement.step()) {
389 LOG(FATAL) << sqlite3_errmsg(dbhandle.get()); 389 LOG(FATAL) << sqlite3_errmsg(dbhandle.get());
390 } 390 }
391 } 391 }
392 transaction.Commit(); 392 transaction.Commit();
393 } 393 }
394 394
395 bool UserSettings::VerifyAgainstStoredHash(const string& email, 395 bool UserSettings::VerifyAgainstStoredHash(const string& email,
396 const string& password) { 396 const string& password) {
397 ScopedDBHandle dbhandle(this); 397 ScopedDBHandle dbhandle(this);
398 string salt_and_digest; 398 string salt_and_digest;
399 399
400 SQLStatement query; 400 sqlite_utils::SQLStatement query;
401 query.prepare(dbhandle.get(), 401 query.prepare(dbhandle.get(),
402 "SELECT key, value FROM settings" 402 "SELECT key, value FROM settings"
403 " WHERE email = ? AND (key = ? OR key = ?)"); 403 " WHERE email = ? AND (key = ? OR key = ?)");
404 query.bind_string(0, email); 404 query.bind_string(0, email);
405 query.bind_string(1, PASSWORD_HASH); 405 query.bind_string(1, PASSWORD_HASH);
406 query.bind_string(2, SALT); 406 query.bind_string(2, SALT);
407 int query_result = query.step(); 407 int query_result = query.step();
408 string salt; 408 string salt;
409 int32 hash = kInvalidHash; 409 int32 hash = kInvalidHash;
410 while (SQLITE_ROW == query_result) { 410 while (SQLITE_ROW == query_result) {
(...skipping 18 matching lines...) Expand all
429 429
430 void UserSettings::SwitchUser(const string& username) { 430 void UserSettings::SwitchUser(const string& username) {
431 { 431 {
432 base::AutoLock lock(mutex_); 432 base::AutoLock lock(mutex_);
433 email_ = username; 433 email_ = username;
434 } 434 }
435 } 435 }
436 436
437 string UserSettings::GetClientId() { 437 string UserSettings::GetClientId() {
438 ScopedDBHandle dbhandle(this); 438 ScopedDBHandle dbhandle(this);
439 SQLStatement statement; 439 sqlite_utils::SQLStatement statement;
440 statement.prepare(dbhandle.get(), "SELECT id FROM client_id"); 440 statement.prepare(dbhandle.get(), "SELECT id FROM client_id");
441 int query_result = statement.step(); 441 int query_result = statement.step();
442 string client_id; 442 string client_id;
443 if (query_result == SQLITE_ROW) 443 if (query_result == SQLITE_ROW)
444 client_id = statement.column_string(0); 444 client_id = statement.column_string(0);
445 return client_id; 445 return client_id;
446 } 446 }
447 447
448 void UserSettings::ClearAllServiceTokens() { 448 void UserSettings::ClearAllServiceTokens() {
449 ScopedDBHandle dbhandle(this); 449 ScopedDBHandle dbhandle(this);
450 ExecOrDie(dbhandle.get(), "DELETE FROM cookies"); 450 ExecOrDie(dbhandle.get(), "DELETE FROM cookies");
451 } 451 }
452 452
453 bool UserSettings::GetLastUser(string* username) { 453 bool UserSettings::GetLastUser(string* username) {
454 ScopedDBHandle dbhandle(this); 454 ScopedDBHandle dbhandle(this);
455 SQLStatement query; 455 sqlite_utils::SQLStatement query;
456 query.prepare(dbhandle.get(), "SELECT email FROM cookies"); 456 query.prepare(dbhandle.get(), "SELECT email FROM cookies");
457 if (SQLITE_ROW == query.step()) { 457 if (SQLITE_ROW == query.step()) {
458 *username = query.column_string(0); 458 *username = query.column_string(0);
459 return true; 459 return true;
460 } else { 460 } else {
461 return false; 461 return false;
462 } 462 }
463 } 463 }
464 464
465 } // namespace browser_sync 465 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/util/sqlite_utils.cc ('k') | chrome/browser/sync/util/user_settings_posix.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698