| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |