| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "chrome/browser/extensions/activity_log/database_interned_string.h" |
| 6 |
| 7 #include "base/strings/stringprintf.h" |
| 8 #include "sql/connection.h" |
| 9 #include "sql/statement.h" |
| 10 |
| 11 using base::StringPrintf; |
| 12 |
| 13 namespace extensions { |
| 14 |
| 15 DatabaseStringTable::DatabaseStringTable(const std::string& table) |
| 16 : table_(table) {} |
| 17 |
| 18 DatabaseStringTable::~DatabaseStringTable() {} |
| 19 |
| 20 bool DatabaseStringTable::Initialize(sql::Connection* connection) { |
| 21 if (!connection->DoesTableExist(table_.c_str())) { |
| 22 return connection->Execute(StringPrintf( |
| 23 "CREATE TABLE %s (id INTEGER PRIMARY KEY, value TEXT NOT NULL); " |
| 24 "CREATE UNIQUE INDEX %s_index ON %s(value)", |
| 25 table_.c_str(), |
| 26 table_.c_str(), |
| 27 table_.c_str()).c_str()); |
| 28 } else { |
| 29 return true; |
| 30 } |
| 31 } |
| 32 |
| 33 bool DatabaseStringTable::StringToInt(sql::Connection* connection, |
| 34 const std::string& value, |
| 35 int64* id) { |
| 36 std::map<std::string, int64>::const_iterator lookup = |
| 37 value_to_id_.find(value); |
| 38 if (lookup != value_to_id_.end()) { |
| 39 *id = lookup->second; |
| 40 return true; |
| 41 } |
| 42 |
| 43 // Operate on the assumption that the cache does a good job on |
| 44 // frequently-used strings--if there is a cache miss, first act on the |
| 45 // assumption that the string is not in the database either. |
| 46 sql::Statement update(connection->GetUniqueStatement( |
| 47 StringPrintf("INSERT OR IGNORE INTO %s(value) VALUES (?)", table_.c_str()) |
| 48 .c_str())); |
| 49 update.BindString(0, value); |
| 50 if (!update.Run()) |
| 51 return false; |
| 52 |
| 53 if (connection->GetLastChangeCount() == 1) { |
| 54 *id = connection->GetLastInsertRowId(); |
| 55 id_to_value_[*id] = value; |
| 56 value_to_id_[value] = *id; |
| 57 return true; |
| 58 } |
| 59 |
| 60 // The specified string may have already existed in the database, in which |
| 61 // case the insert above will have been ignored. If this happens, do a |
| 62 // lookup to find the old value. |
| 63 sql::Statement query(connection->GetUniqueStatement( |
| 64 StringPrintf("SELECT id FROM %s WHERE value = ?", table_.c_str()) |
| 65 .c_str())); |
| 66 query.BindString(0, value); |
| 67 if (!query.Step()) |
| 68 return false; |
| 69 *id = query.ColumnInt64(0); |
| 70 id_to_value_[*id] = value; |
| 71 value_to_id_[value] = *id; |
| 72 return true; |
| 73 } |
| 74 |
| 75 bool DatabaseStringTable::IntToString(sql::Connection* connection, |
| 76 int64 id, |
| 77 std::string* value) { |
| 78 std::map<int64, std::string>::const_iterator lookup = |
| 79 id_to_value_.find(id); |
| 80 if (lookup != id_to_value_.end()) { |
| 81 *value = lookup->second; |
| 82 return true; |
| 83 } |
| 84 |
| 85 sql::Statement query(connection->GetUniqueStatement( |
| 86 StringPrintf("SELECT value FROM %s WHERE id = ?", table_.c_str()) |
| 87 .c_str())); |
| 88 query.BindInt64(0, id); |
| 89 if (!query.Step()) |
| 90 return false; |
| 91 |
| 92 *value = query.ColumnString(0); |
| 93 id_to_value_[id] = *value; |
| 94 value_to_id_[*value] = id; |
| 95 return true; |
| 96 } |
| 97 |
| 98 void DatabaseStringTable::ClearCache() { |
| 99 id_to_value_.clear(); |
| 100 value_to_id_.clear(); |
| 101 } |
| 102 |
| 103 } // namespace extensions |
| OLD | NEW |