[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / sql / meta_table.cc
1 // Copyright 2012 The Chromium Authors
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 "sql/meta_table.h"
6
7 #include <cstdint>
8 #include <string>
9
10 #include "base/check_op.h"
11 #include "base/strings/string_piece.h"
12 #include "sql/database.h"
13 #include "sql/statement.h"
14 #include "sql/statement_id.h"
15 #include "sql/transaction.h"
16
17 namespace sql {
18
19 namespace {
20
21 // Keys understood directly by sql:MetaTable.
22 constexpr char kVersionKey[] = "version";
23 constexpr char kCompatibleVersionKey[] = "last_compatible_version";
24 constexpr char kMmapStatusKey[] = "mmap_status";
25
26 void PrepareSetStatement(base::StringPiece key,
27                          Database& db,
28                          Statement& insert_statement) {
29   insert_statement.Assign(db.GetCachedStatement(
30       SQL_FROM_HERE, "INSERT OR REPLACE INTO meta(key,value) VALUES(?,?)"));
31   insert_statement.BindString(0, key);
32 }
33
34 bool PrepareGetStatement(base::StringPiece key,
35                          Database& db,
36                          Statement& select_statement) {
37   select_statement.Assign(db.GetCachedStatement(
38       SQL_FROM_HERE, "SELECT value FROM meta WHERE key=?"));
39   if (!select_statement.is_valid())
40     return false;
41
42   select_statement.BindString(0, key);
43   return select_statement.Step();
44 }
45
46 }  // namespace
47
48 MetaTable::MetaTable() = default;
49
50 MetaTable::~MetaTable() = default;
51
52 // static
53 constexpr int64_t MetaTable::kMmapFailure;
54 constexpr int64_t MetaTable::kMmapSuccess;
55
56 // static
57 bool MetaTable::DoesTableExist(sql::Database* db) {
58   DCHECK(db);
59   return db->DoesTableExist("meta");
60 }
61
62 // static
63 bool MetaTable::DeleteTableForTesting(sql::Database* db) {
64   DCHECK(db);
65   return db->Execute("DROP TABLE IF EXISTS meta");
66 }
67
68 // static
69 bool MetaTable::GetMmapStatus(Database* db, int64_t* status) {
70   DCHECK(db);
71   DCHECK(status);
72
73   // It is fine for the status to be missing entirely, but any error prevents
74   // memory-mapping.
75   Statement select;
76   if (!PrepareGetStatement(kMmapStatusKey, *db, select)) {
77     *status = 0;
78     return true;
79   }
80
81   *status = select.ColumnInt64(0);
82   return select.Succeeded();
83 }
84
85 // static
86 bool MetaTable::SetMmapStatus(Database* db, int64_t status) {
87   DCHECK(db);
88   DCHECK(status == kMmapFailure || status == kMmapSuccess || status >= 0);
89
90   Statement insert;
91   PrepareSetStatement(kMmapStatusKey, *db, insert);
92   insert.BindInt64(1, status);
93   return insert.Run();
94 }
95
96 // static
97 void MetaTable::RazeIfIncompatible(Database* db,
98                                    int lowest_supported_version,
99                                    int current_version) {
100   DCHECK(db);
101
102   if (!DoesTableExist(db))
103     return;
104
105   sql::Statement select;
106   if (!PrepareGetStatement(kVersionKey, *db, select))
107     return;
108   int64_t on_disk_schema_version = select.ColumnInt64(0);
109
110   if (!PrepareGetStatement(kCompatibleVersionKey, *db, select))
111     return;
112   int64_t on_disk_compatible_version = select.ColumnInt(0);
113
114   select.Clear();  // Clear potential automatic transaction for Raze().
115
116   if ((lowest_supported_version != kNoLowestSupportedVersion &&
117        lowest_supported_version > on_disk_schema_version) ||
118       (current_version < on_disk_compatible_version)) {
119     db->Raze();
120     return;
121   }
122 }
123
124 bool MetaTable::Init(Database* db, int version, int compatible_version) {
125   DCHECK(!db_ && db);
126   db_ = db;
127
128   // If values stored are nullptr or missing entirely, 0 will be reported.
129   // Require new clients to start with a greater initial version.
130   DCHECK_GT(version, 0);
131   DCHECK_GT(compatible_version, 0);
132
133   // Make sure the table is created an populated atomically.
134   sql::Transaction transaction(db_);
135   if (!transaction.Begin())
136     return false;
137
138   if (!DoesTableExist(db)) {
139     if (!db_->Execute("CREATE TABLE meta"
140                       "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value "
141                       "LONGVARCHAR)")) {
142       return false;
143     }
144
145     // Newly-created databases start out with mmap'ed I/O, but have no place to
146     // store the setting.  Set here so that later opens don't need to validate.
147     SetMmapStatus(db_, kMmapSuccess);
148
149     // Note: there is no index over the meta table. We currently only have a
150     // couple of keys, so it doesn't matter. If we start storing more stuff in
151     // there, we should create an index.
152     SetVersionNumber(version);
153     SetCompatibleVersionNumber(compatible_version);
154   }
155   return transaction.Commit();
156 }
157
158 void MetaTable::Reset() {
159   db_ = nullptr;
160 }
161
162 void MetaTable::SetVersionNumber(int version) {
163   DCHECK_GT(version, 0);
164   SetValue(kVersionKey, version);
165 }
166
167 int MetaTable::GetVersionNumber() {
168   int64_t version = 0;
169   return GetValue(kVersionKey, &version) ? version : 0;
170 }
171
172 void MetaTable::SetCompatibleVersionNumber(int version) {
173   DCHECK_GT(version, 0);
174   SetValue(kCompatibleVersionKey, version);
175 }
176
177 int MetaTable::GetCompatibleVersionNumber() {
178   int version = 0;
179   return GetValue(kCompatibleVersionKey, &version) ? version : 0;
180 }
181
182 bool MetaTable::SetValue(base::StringPiece key, const std::string& value) {
183   DCHECK(db_);
184
185   Statement insert;
186   PrepareSetStatement(key, *db_, insert);
187   insert.BindString(1, value);
188   return insert.Run();
189 }
190
191 bool MetaTable::SetValue(base::StringPiece key, int64_t value) {
192   DCHECK(db_);
193
194   Statement insert;
195   PrepareSetStatement(key, *db_, insert);
196   insert.BindInt64(1, value);
197   return insert.Run();
198 }
199
200 bool MetaTable::GetValue(base::StringPiece key, std::string* value) {
201   DCHECK(value);
202   DCHECK(db_);
203
204   Statement select;
205   if (!PrepareGetStatement(key, *db_, select))
206     return false;
207
208   *value = select.ColumnString(0);
209   return true;
210 }
211
212 bool MetaTable::GetValue(base::StringPiece key, int* value) {
213   DCHECK(value);
214   DCHECK(db_);
215
216   Statement select;
217   if (!PrepareGetStatement(key, *db_, select))
218     return false;
219
220   *value = select.ColumnInt64(0);
221   return true;
222 }
223
224 bool MetaTable::GetValue(base::StringPiece key, int64_t* value) {
225   DCHECK(value);
226   DCHECK(db_);
227
228   Statement select;
229   if (!PrepareGetStatement(key, *db_, select))
230     return false;
231
232   *value = select.ColumnInt64(0);
233   return true;
234 }
235
236 bool MetaTable::DeleteKey(base::StringPiece key) {
237   DCHECK(db_);
238
239   Statement delete_statement(
240       db_->GetUniqueStatement("DELETE FROM meta WHERE key=?"));
241   delete_statement.BindString(0, key);
242   return delete_statement.Run();
243 }
244
245 }  // namespace sql