[M120 Migration][VD] Enable direct rendering for TVPlus
[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 bool MetaTable::RazeIfIncompatible(Database* db,
98                                    int lowest_supported_version,
99                                    int current_version) {
100   DCHECK(db);
101
102   if (!DoesTableExist(db)) {
103     return true;
104   }
105
106   sql::Statement select;
107   if (!PrepareGetStatement(kVersionKey, *db, select)) {
108     return false;
109   }
110   int64_t on_disk_schema_version = select.ColumnInt64(0);
111
112   if (!PrepareGetStatement(kCompatibleVersionKey, *db, select)) {
113     return false;
114   }
115   int64_t on_disk_compatible_version = select.ColumnInt(0);
116
117   select.Clear();  // Clear potential automatic transaction for Raze().
118
119   if ((lowest_supported_version != kNoLowestSupportedVersion &&
120        lowest_supported_version > on_disk_schema_version) ||
121       (current_version < on_disk_compatible_version)) {
122     return db->Raze();
123   }
124   return true;
125 }
126
127 bool MetaTable::Init(Database* db, int version, int compatible_version) {
128   DCHECK(!db_ && db);
129   db_ = db;
130
131   // If values stored are nullptr or missing entirely, 0 will be reported.
132   // Require new clients to start with a greater initial version.
133   DCHECK_GT(version, 0);
134   DCHECK_GT(compatible_version, 0);
135
136   // Make sure the table is created and populated atomically.
137   sql::Transaction transaction(db_);
138   if (!transaction.Begin())
139     return false;
140
141   if (!DoesTableExist(db)) {
142     if (!db_->Execute("CREATE TABLE meta"
143                       "(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value "
144                       "LONGVARCHAR)")) {
145       return false;
146     }
147
148     // Newly-created databases start out with mmap'ed I/O, but have no place to
149     // store the setting.  Set here so that later opens don't need to validate.
150     if (!SetMmapStatus(db_, kMmapSuccess)) {
151       return false;
152     }
153
154     // Note: there is no index over the meta table. We currently only have a
155     // couple of keys, so it doesn't matter. If we start storing more stuff in
156     // there, we should create an index.
157
158     // If setting either version number fails, return early to avoid likely
159     // crashes or incorrect behavior with respect to migrations.
160     if (!SetVersionNumber(version) ||
161         !SetCompatibleVersionNumber(compatible_version)) {
162       return false;
163     }
164   }
165   return transaction.Commit();
166 }
167
168 void MetaTable::Reset() {
169   db_ = nullptr;
170 }
171
172 bool MetaTable::SetVersionNumber(int version) {
173   DCHECK_GT(version, 0);
174   return SetValue(kVersionKey, version);
175 }
176
177 int MetaTable::GetVersionNumber() {
178   int64_t version = 0;
179   return GetValue(kVersionKey, &version) ? version : 0;
180 }
181
182 bool MetaTable::SetCompatibleVersionNumber(int version) {
183   DCHECK_GT(version, 0);
184   return SetValue(kCompatibleVersionKey, version);
185 }
186
187 int MetaTable::GetCompatibleVersionNumber() {
188   int version = 0;
189   return GetValue(kCompatibleVersionKey, &version) ? version : 0;
190 }
191
192 bool MetaTable::SetValue(base::StringPiece key, const std::string& value) {
193   DCHECK(db_);
194
195   Statement insert;
196   PrepareSetStatement(key, *db_, insert);
197   insert.BindString(1, value);
198   return insert.Run();
199 }
200
201 bool MetaTable::SetValue(base::StringPiece key, int64_t value) {
202   DCHECK(db_);
203
204   Statement insert;
205   PrepareSetStatement(key, *db_, insert);
206   insert.BindInt64(1, value);
207   return insert.Run();
208 }
209
210 bool MetaTable::GetValue(base::StringPiece key, std::string* value) {
211   DCHECK(value);
212   DCHECK(db_);
213
214   Statement select;
215   if (!PrepareGetStatement(key, *db_, select))
216     return false;
217
218   *value = select.ColumnString(0);
219   return true;
220 }
221
222 bool MetaTable::GetValue(base::StringPiece key, int* value) {
223   DCHECK(value);
224   DCHECK(db_);
225
226   Statement select;
227   if (!PrepareGetStatement(key, *db_, select))
228     return false;
229
230   *value = select.ColumnInt64(0);
231   return true;
232 }
233
234 bool MetaTable::GetValue(base::StringPiece key, int64_t* value) {
235   DCHECK(value);
236   DCHECK(db_);
237
238   Statement select;
239   if (!PrepareGetStatement(key, *db_, select))
240     return false;
241
242   *value = select.ColumnInt64(0);
243   return true;
244 }
245
246 bool MetaTable::DeleteKey(base::StringPiece key) {
247   DCHECK(db_);
248
249   Statement delete_statement(
250       db_->GetUniqueStatement("DELETE FROM meta WHERE key=?"));
251   delete_statement.BindString(0, key);
252   return delete_statement.Run();
253 }
254
255 }  // namespace sql