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.
5 #include "chrome/browser/extensions/activity_log/database_string_table.h"
7 #include "base/strings/stringprintf.h"
8 #include "sql/connection.h"
9 #include "sql/statement.h"
11 using base::StringPrintf
;
13 namespace extensions
{
15 // A target maximum size (in number of entries) for the mapping tables. If the
16 // cache would grow larger than this, the size should be reduced.
17 static const size_t kMaximumCacheSize
= 1000;
19 DatabaseStringTable::DatabaseStringTable(const std::string
& table
)
22 DatabaseStringTable::~DatabaseStringTable() {}
24 bool DatabaseStringTable::Initialize(sql::Connection
* connection
) {
25 if (!connection
->DoesTableExist(table_
.c_str())) {
26 return connection
->Execute(StringPrintf(
27 "CREATE TABLE %s (id INTEGER PRIMARY KEY, value TEXT NOT NULL); "
28 "CREATE UNIQUE INDEX %s_index ON %s(value)",
31 table_
.c_str()).c_str());
37 bool DatabaseStringTable::StringToInt(sql::Connection
* connection
,
38 const std::string
& value
,
40 std::map
<std::string
, int64
>::const_iterator lookup
=
41 value_to_id_
.find(value
);
42 if (lookup
!= value_to_id_
.end()) {
47 // We will be adding data to the cache below--check the cache size now and
48 // reduce it if needed.
51 // Operate on the assumption that the cache does a good job on
52 // frequently-used strings--if there is a cache miss, first act on the
53 // assumption that the string is not in the database either.
54 sql::Statement
update(connection
->GetUniqueStatement(
55 StringPrintf("INSERT OR IGNORE INTO %s(value) VALUES (?)", table_
.c_str())
57 update
.BindString(0, value
);
61 if (connection
->GetLastChangeCount() == 1) {
62 *id
= connection
->GetLastInsertRowId();
63 id_to_value_
[*id
] = value
;
64 value_to_id_
[value
] = *id
;
68 // The specified string may have already existed in the database, in which
69 // case the insert above will have been ignored. If this happens, do a
70 // lookup to find the old value.
71 sql::Statement
query(connection
->GetUniqueStatement(
72 StringPrintf("SELECT id FROM %s WHERE value = ?", table_
.c_str())
74 query
.BindString(0, value
);
77 *id
= query
.ColumnInt64(0);
78 id_to_value_
[*id
] = value
;
79 value_to_id_
[value
] = *id
;
83 bool DatabaseStringTable::IntToString(sql::Connection
* connection
,
86 std::map
<int64
, std::string
>::const_iterator lookup
=
87 id_to_value_
.find(id
);
88 if (lookup
!= id_to_value_
.end()) {
89 *value
= lookup
->second
;
93 // We will be adding data to the cache below--check the cache size now and
94 // reduce it if needed.
97 sql::Statement
query(connection
->GetUniqueStatement(
98 StringPrintf("SELECT value FROM %s WHERE id = ?", table_
.c_str())
100 query
.BindInt64(0, id
);
104 *value
= query
.ColumnString(0);
105 id_to_value_
[id
] = *value
;
106 value_to_id_
[*value
] = id
;
110 void DatabaseStringTable::ClearCache() {
111 id_to_value_
.clear();
112 value_to_id_
.clear();
115 void DatabaseStringTable::PruneCache() {
116 if (id_to_value_
.size() <= kMaximumCacheSize
&&
117 value_to_id_
.size() <= kMaximumCacheSize
)
120 // TODO(mvrable): Perhaps implement a more intelligent caching policy. For
121 // now, to limit memory usage we simply clear the entire cache when it would
122 // become too large. Data will be brought back in from the database as
127 } // namespace extensions