Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /sql /database.h
blob: ec0f79cb16b93e5e4b8db7dd0a095788e0ce6165 [file] [log] [blame]
Avi Drissman69b874f2022-09-15 19:11:14[diff] [blame]1// Copyright 2012 The Chromium Authors
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]5#ifndef SQL_DATABASE_H_
6#define SQL_DATABASE_H_
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]7
avi0b519202015-12-21 07:25:19[diff] [blame]8#include<stddef.h>
tfarina720d4f32015-05-11 22:31:26[diff] [blame]9#include<stdint.h>
Victor Costanab7a2452022-03-21 23:06:08[diff] [blame]10
mostynbd82cd9952016-04-11 20:05:34[diff] [blame]11#include<memory>
Arthur Sonzogni5bc3326c2024-02-29 19:39:05[diff] [blame]12#include<optional>
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]13#include<set>
mark@chromium.org7d6aee4e2009-09-12 01:12:33[diff] [blame]14#include<string>
Md Hasibul Hasan52ffeca62024-03-26 18:23:18[diff] [blame]15#include<string_view>
Victor Costan87cf8c72018-07-19 19:36:04[diff] [blame]16#include<utility>
shess@chromium.org80abf152013-05-22 12:42:42[diff] [blame]17#include<vector>
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]18
Dan McArdleb52665c2024-05-23 20:24:31[diff] [blame]19#include"base/check.h"
20#include"base/check_op.h"
Victor Costane56cc682018-12-27 01:53:46[diff] [blame]21#include"base/component_export.h"
Dmitry Skibaa9ad8fe42017-08-16 21:02:48[diff] [blame]22#include"base/containers/flat_map.h"
Austin Sullivan0593ef92023-05-17 20:46:30[diff] [blame]23#include"base/files/file_path.h"
Avi Drissman2e85357a2023-01-12 21:57:32[diff] [blame]24#include"base/functional/callback.h"
shessc8cd2a162015-10-22 20:30:46[diff] [blame]25#include"base/gtest_prod_util.h"
Dan McArdleb52665c2024-05-23 20:24:31[diff] [blame]26#include"base/location.h"
Keishi Hattori0e45c022021-11-27 09:25:52[diff] [blame]27#include"base/memory/raw_ptr.h"
levin@chromium.org3b63f8f42011-03-28 01:54:15[diff] [blame]28#include"base/memory/ref_counted.h"
Evan Stade9728e5a2025-06-05 18:51:27[diff] [blame]29#include"base/memory/ref_counted_memory.h"
Dan McArdleb52665c2024-05-23 20:24:31[diff] [blame]30#include"base/memory/scoped_refptr.h"
Dan McArdle49be9b02024-02-06 23:15:33[diff] [blame]31#include"base/memory/weak_ptr.h"
Anthony Vallée-Duboisdd2d9012024-12-18 23:25:28[diff] [blame]32#include"base/notreached.h"
Victor Costan12daa3ac92018-07-19 01:05:58[diff] [blame]33#include"base/sequence_checker.h"
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]34#include"base/strings/cstring_view.h"
Etienne Pierre-Doray0400dfb62018-12-03 19:12:25[diff] [blame]35#include"base/threading/scoped_blocking_call.h"
Dan McArdleb52665c2024-05-23 20:24:31[diff] [blame]36#include"base/time/time.h"
Victor Costanbc4285f2021-09-20 21:29:28[diff] [blame]37#include"base/types/pass_key.h"
Victor Costan7f6abbbe2018-07-29 02:57:27[diff] [blame]38#include"sql/internal_api_token.h"
Anthony Vallée-Duboisdd2d9012024-12-18 23:25:28[diff] [blame]39#include"sql/sql_name_variants.h"
Victor Costanab7a2452022-03-21 23:06:08[diff] [blame]40#include"sql/sqlite_result_code.h"
41#include"sql/sqlite_result_code_values.h"
Victor Costan12daa3ac92018-07-19 01:05:58[diff] [blame]42#include"sql/statement_id.h"
Evan Stade416f46f12025-06-18 15:42:39[diff] [blame]43#include"sql/streaming_blob_handle.h"
Dan McArdleb52665c2024-05-23 20:24:31[diff] [blame]44#include"third_party/perfetto/include/perfetto/tracing/traced_proto.h"
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]45
Victor Costanab7a2452022-03-21 23:06:08[diff] [blame]46// Forward declaration for SQLite structures. Headers in the public sql:: API
47// must NOT include sqlite3.h.
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]48struct sqlite3;
Victor Costandc72e8d2022-03-14 18:14:51[diff] [blame]49struct sqlite3_file;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]50struct sqlite3_stmt;
51
Austin Sullivan0593ef92023-05-17 20:46:30[diff] [blame]52namespacebase::trace_event{
ssid1f4e5362016-12-08 20:41:38[diff] [blame]53classProcessMemoryDump;
Austin Sullivan0593ef92023-05-17 20:46:30[diff] [blame]54}// namespace base::trace_event
brettw@chromium.orga3ef4832013-02-02 05:12:33[diff] [blame]55
Hans Wennborg5fcd6b872025-04-14 21:53:01[diff] [blame]56namespace perfetto{
57classNamedTrack;
58}
59
Tommy C. Li7803636c2022-07-27 21:47:22[diff] [blame]60namespace perfetto::protos::pbzero{
61classChromeSqlDiagnostics;
62}
63
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]64namespace sql{
65
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]66classDatabaseMemoryDumpProvider;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]67classStatement;
68
shess58b8df82015-06-03 00:19:32[diff] [blame]69namespace test{
shess976814402016-06-21 06:56:25[diff] [blame]70classScopedErrorExpecter;
Victor Costan87cf8c72018-07-19 19:36:04[diff] [blame]71}// namespace test
shess58b8df82015-06-03 00:19:32[diff] [blame]72
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]73struct COMPONENT_EXPORT(SQL)DatabaseOptions{
74// Default page size for newly created databases.
75//
76// Guaranteed to match SQLITE_DEFAULT_PAGE_SIZE.
77staticconstexprint kDefaultPageSize=4096;
78
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]79DatabaseOptions();
Etienne Bergeron9635e20f2025-02-11 17:52:38[diff] [blame]80DatabaseOptions(constDatabaseOptions&);
81DatabaseOptions(DatabaseOptions&&);
82DatabaseOptions&operator=(constDatabaseOptions&);
83DatabaseOptions&operator=(DatabaseOptions&&);
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]84~DatabaseOptions();
85
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]86// If true, the database can only be opened by one process at a time.
87//
Shubham Aggarwalb30a0cee2021-01-28 15:11:23[diff] [blame]88// SQLite supports a locking protocol that allows multiple processes to safely
89// operate on the same database at the same time. The locking protocol is used
90// on every transaction, and comes with a small performance penalty.
91//
92// Setting this to true causes the locking protocol to be used once, when the
Will Harris711a5ec2023-04-04 21:43:37[diff] [blame]93// database is opened. No other SQLite process will be able to access the
94// database at the same time. Note that this uses OS-level
95// advisory/cooperative locking, so this does not protect the database file
96// from uncooperative processes.
Shubham Aggarwalb30a0cee2021-01-28 15:11:23[diff] [blame]97//
98// More details at https://www.sqlite.org/pragma.html#pragma_locking_mode
99//
100// SQLite's locking protocol is summarized at
101// https://www.sqlite.org/c3ref/io_methods.html
102//
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]103// Exclusive mode is strongly recommended. It reduces the I/O cost of setting
104// up a transaction. It also removes the need of handling transaction failures
105// due to lock contention.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]106DatabaseOptions& set_exclusive_locking(bool exclusive_locking){
107 exclusive_locking_= exclusive_locking;
108return*this;
109}
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]110
Will Harris711a5ec2023-04-04 21:43:37[diff] [blame]111// If true, enables exclusive=true vfs URI parameter on the database file.
112// This is only supported on Windows.
113//
114// If this option is true then the database file cannot be opened by any
115// processes on the system until the database has been closed. Note, this is
116// not the same as `exclusive_locking` above, which refers to
117// advisory/cooperative locks. This option sets file handle sharing attributes
118// to prevent the database files from being opened from any process including
119// being opened a second time by the hosting process.
120//
Will Harris711a5ec2023-04-04 21:43:37[diff] [blame]121// This option is experimental and will be merged into the `exclusive_locking`
122// option above if proven to cause no OS compatibility issues.
Alison Gale81f4f2c72024-04-22 19:33:31[diff] [blame]123// TODO(crbug.com/40262539): Merge into above option, if possible.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]124DatabaseOptions& set_exclusive_database_file_lock(
125bool exclusive_database_file_lock){
126 exclusive_database_file_lock_= exclusive_database_file_lock;
127return*this;
128}
Will Harris711a5ec2023-04-04 21:43:37[diff] [blame]129
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]130// If true, enables SQLite's Write-Ahead Logging (WAL).
131//
132// WAL integration is under development, and should not be used in shipping
Evan Stade4c7d6b32024-03-12 16:50:27[diff] [blame]133// Chrome features yet.
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]134//
Shubham Aggarwalb30a0cee2021-01-28 15:11:23[diff] [blame]135// WAL mode is currently not fully supported on FuchsiaOS. It will only be
136// turned on if the database is also using exclusive locking mode.
137// (https://crbug.com/1082059)
138//
139// Note: Changing page size is not supported when in WAL mode. So running
140// 'PRAGMA page_size = <new-size>' will result in no-ops.
141//
Olivier Li0408c8c12025-04-30 14:29:35[diff] [blame]142// Note: This option is not supported in read-only mode.
143//
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]144// More details at https://www.sqlite.org/wal.html
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]145DatabaseOptions& set_wal_mode(bool wal_mode){
146 wal_mode_= wal_mode;
147return*this;
148}
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]149
Etienne Bergeron9635e20f2025-02-11 17:52:38[diff] [blame]150// If true, enables preloading the database before opening it.
151//
152// Hints the file system that the database will be accessed soon.
153//
154// This method should be called on databases that are on the critical path to
155// Chrome startup. Informing the filesystem about our expected access pattern
156// early on reduces the likelihood that we'll be blocked on disk I/O. This has
157// a high impact on startup time.
158DatabaseOptions& set_preload(bool preload){
159 preload_= preload;
160return*this;
161}
162
Victor Costanf2ed41f72022-03-16 04:04:38[diff] [blame]163// If true, transaction commit waits for data to reach persistent media.
164//
165// This is currently only meaningful on macOS. All other operating systems
166// only support flushing directly to disk.
167//
168// If both `flush_to_media` and `wal_mode` are false, power loss can lead to
169// database corruption.
170//
171// By default, SQLite considers that transactions commit when they reach the
172// disk controller's memory. This guarantees durability in the event of
173// software crashes, up to and including the operating system. In the event of
174// power loss, SQLite may lose data. If `wal_mode` is false (SQLite uses a
175// rollback journal), power loss can lead to database corruption.
176//
177// When this option is enabled, committing a transaction causes SQLite to wait
178// until the data is written to the persistent media. This guarantees
179// durability in the event of power loss, which is needed to guarantee the
180// integrity of non-WAL databases.
Olivier Li0408c8c12025-04-30 14:29:35[diff] [blame]181//
182// Note: This option is not supported in read-only mode.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]183DatabaseOptions& set_flush_to_media(bool flush_to_media){
184 flush_to_media_= flush_to_media;
185return*this;
186}
Victor Costanf2ed41f72022-03-16 04:04:38[diff] [blame]187
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]188// Database page size.
189//
Victor Costan9d1c8754b2021-07-13 02:53:29[diff] [blame]190// The value in this option is only applied to newly created databases. In
191// other words, changing the value doesn't impact the databases that have
192// already been created on the users' devices. So, changing the value in the
193// code without a lot of work (re-creating existing databases) will result in
194// inconsistent page sizes across the fleet of user devices, which will make
195// it (even) more difficult to reason about database performance.
196//
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]197// Larger page sizes result in shallower B-trees, because they allow an inner
198// page to hold more keys. On the flip side, larger page sizes may result in
199// more I/O when making small changes to existing records.
Shubham Aggarwalb30a0cee2021-01-28 15:11:23[diff] [blame]200//
201// Must be a power of two between 512 and 65536 inclusive.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]202DatabaseOptions& set_page_size(int page_size){
203 page_size_= page_size;
204return*this;
205}
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]206
207// The size of in-memory cache, in pages.
208//
209// SQLite's database cache will take up at most (`page_size` * `cache_size`)
210// bytes of RAM.
211//
212// 0 invokes SQLite's default, which is currently to size up the cache to use
213// exactly 2,048,000 bytes of RAM.
Olivier Li0408c8c12025-04-30 14:29:35[diff] [blame]214//
215// Note: This option is not supported in read-only mode.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]216DatabaseOptions& set_cache_size(int cache_size){
217 cache_size_= cache_size;
218return*this;
219}
Victor Costan8ec18ee42021-07-13 19:45:32[diff] [blame]220
221// Stores mmap failures in the SQL schema, instead of the meta table.
222//
223// This option is strongly discouraged for new databases, and will eventually
224// be removed.
225//
226// If this option is true, the mmap status is stored in the database schema.
227// Like any other schema change, changing the mmap status invalidates all
228// pre-compiled SQL statements.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]229DatabaseOptions& set_mmap_alt_status_discouraged(
230bool mmap_alt_status_discouraged){
231 mmap_alt_status_discouraged_= mmap_alt_status_discouraged;
232return*this;
233}
Victor Costan04fc9092021-07-17 00:09:34[diff] [blame]234
Victor Costanfe078f92021-07-19 20:02:59[diff] [blame]235// If true, enables SQL views (a discouraged feature) for this database.
Victor Costan04fc9092021-07-17 00:09:34[diff] [blame]236//
237// The use of views is discouraged for Chrome code. See README.md for details
238// and recommended replacements.
239//
Victor Costanfe078f92021-07-19 20:02:59[diff] [blame]240// If this option is false, CREATE VIEW and DROP VIEW succeed, but SELECT
241// statements targeting views fail.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]242DatabaseOptions& set_enable_views_discouraged(bool enable_views_discouraged){
243 enable_views_discouraged_= enable_views_discouraged;
244return*this;
245}
Olivier Li Shing Tat-Dupuise8a59fb12024-12-03 19:38:42[diff] [blame]246
Evan Stadeff25d2d2025-06-24 19:03:44[diff] [blame]247// If true, enables SQL triggers for this database.
248//
249// The use of triggers should be thoughtful. See README.md for details.
250//
251// If this option is false, CREATE TRIGGER and DROP TRIGGER succeed, but the
252// triggers won't fire.
253DatabaseOptions& set_enable_triggers(bool enable_triggers){
254 enable_triggers_= enable_triggers;
255return*this;
256}
257
Olivier Li Shing Tat-Dupuise8a59fb12024-12-03 19:38:42[diff] [blame]258// If non-null, specifies the vfs implementation for the database to look for.
259// Most use-cases do not require the use of a
260// VFS(https://www.sqlite.org/vfs.html). This option should only be used when
261// there is a clear need for it.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]262DatabaseOptions& set_vfs_name_discouraged(constchar* vfs_name_discouraged){
263 vfs_name_discouraged_= vfs_name_discouraged;
264return*this;
265}
266
Olivier Li3b4ef072025-02-12 19:37:00[diff] [blame]267// If true database attempts using memory mapped files. True by default. Only
268// set to false when a condition is known that prevents the use of memory
269// mapped files. See https://www.sqlite.org/mmap.html.
270DatabaseOptions& set_mmap_enabled(bool mmap_enabled){
271 mmap_enabled_= mmap_enabled;
272return*this;
273}
274
Olivier Li0408c8c12025-04-30 14:29:35[diff] [blame]275// If true, the database is opened in read-only mode. All operations requiring
276// write access will fail, including insert statements and some pragmas.
277// Queries on the database will fail in the presence of a hot journal since
278// the database file can't be modified to apply it. This must be used in the
279// VFS returns read-only file descriptors, but not otherwise.
280DatabaseOptions& set_read_only(bool read_only){
281 read_only_= read_only;
282return*this;
283}
284
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]285private:
286friendclassDatabase;
287 FRIEND_TEST_ALL_PREFIXES(DatabaseOptionsTest,
288EnableViewsDiscouraged_FalseByDefault);
289 FRIEND_TEST_ALL_PREFIXES(DatabaseOptionsTest,FlushToDisk_FalseByDefault);
290 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,ReOpenWithDifferentJournalMode);
291
292bool exclusive_locking_=true;
293bool exclusive_database_file_lock_=false;
Etienne Bergerone211c3d2025-05-01 13:12:43[diff] [blame]294bool wal_mode_=false;
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]295bool flush_to_media_=false;
296int page_size_= kDefaultPageSize;
297int cache_size_=0;
Etienne Bergeron9635e20f2025-02-11 17:52:38[diff] [blame]298bool preload_=false;
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]299bool mmap_alt_status_discouraged_=false;
300bool enable_views_discouraged_=false;
301constchar* vfs_name_discouraged_=nullptr;
Olivier Li3b4ef072025-02-12 19:37:00[diff] [blame]302bool mmap_enabled_=true;
Olivier Li0408c8c12025-04-30 14:29:35[diff] [blame]303bool read_only_=false;
Evan Stadeff25d2d2025-06-24 19:03:44[diff] [blame]304bool enable_triggers_=false;
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]305};
306
Tommy C. Li7803636c2022-07-27 21:47:22[diff] [blame]307// Holds database diagnostics in a structured format.
308struct COMPONENT_EXPORT(SQL)DatabaseDiagnostics{
309DatabaseDiagnostics();
310~DatabaseDiagnostics();
311
312usingTraceProto= perfetto::protos::pbzero::ChromeSqlDiagnostics;
313// Write a representation of this object into tracing proto.
314voidWriteIntoTrace(perfetto::TracedProto<TraceProto> context)const;
315
316// This was the original error code that triggered the error callback. Should
317// generally match `error_code`, but this isn't guaranteed by the code.
318int reported_sqlite_error_code=0;
319
320// Corresponds to `Database::GetErrorCode()`.
321int error_code=0;
322
323// Corresponds to `Database::GetLastErrno()`.
324int last_errno=0;
325
326// Corresponds to `Statement::GetSQLStatement()` of the problematic statement.
327// This doesn't include the bound values, and therefore is free of any PII.
328 std::string sql_statement;
329
330// The 'version' value stored in the user database's meta table, if it can be
331// read. If we fail to read the version of the user database, it's left as 0.
332int version=0;
333
334// Most rows in 'sql_schema' have a non-NULL 'sql' column. Those rows' 'sql'
335// contents are logged here, one element per row.
336 std::vector<std::string> schema_sql_rows;
337
338// Some rows of 'sql_schema' have a NULL 'sql' column. They are typically
339// autogenerated indices, like "sqlite_autoindex_downloads_slices_1". These
340// are also logged here by their 'name' column, one element per row.
341 std::vector<std::string> schema_other_row_names;
342
343// Sanity checks used for all errors.
344bool has_valid_header=false;
345bool has_valid_schema=false;
Tommy C. Li400c0f12022-09-13 22:39:28[diff] [blame]346
347// Corresponds to `Database::GetErrorMessage()`.
348 std::string error_message;
Tommy C. Li7803636c2022-07-27 21:47:22[diff] [blame]349};
350
Victor Costan87cf8c72018-07-19 19:36:04[diff] [blame]351// Handle to an open SQLite database.
352//
Dan McArdle44d62a12024-02-29 17:08:14[diff] [blame]353// Instances of this class are not thread-safe. With few exceptions, Database
354// instances should only be accessed from one sequence. Database instances may
355// be constructed on one sequence and safely used/destroyed on another. Callers
356// may explicitly use `DetachFromSequence()` before moving to another sequence.
Victor Costan9d1c8754b2021-07-13 02:53:29[diff] [blame]357//
358// When a Database instance goes out of scope, any uncommitted transactions are
359// rolled back.
Victor Costane56cc682018-12-27 01:53:46[diff] [blame]360class COMPONENT_EXPORT(SQL)Database{
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]361private:
362classStatementRef;// Forward declaration, see real one below.
363
364public:
Anthony Vallée-Duboisdd2d9012024-12-18 23:25:28[diff] [blame]365// A convenience struct to
366// 1. Convert (often implicitly) a static const char* string to a database tag
367// to pass to the Database constructors
368// 2. Check that the tag is in the DatabaseTag histogram variant list, at
369// compile time.
370//
371// There is nothing special to do to use this struct. For example, the
372// following works out of the box:
373//
374// Database db(DatabaseOptions{}, "TagName");
375//
376// However, if the database is a unique_ptr created with make_unique,
377// explicitly invoking the constructor is necessary:
378//
379// auto db = std::make_unique<Database>(
380// DatabaseOptions{},
381// Database::Tag("TagName"));
382structTag{
383// Purposely not explicit to avoid requiring callers to wrap their tag
384// string.
385 constevalTag(constchar* tag_value): value(tag_value){
386if(!sql_metrics::IsValidDatabaseTag(tag_value)){
387// This will never actually invoke what's under NOTREACHED(), but
388// NOTREACHED() is invalid in a consteval context so compilation will
389// fail iff the string is invalid.
390 NOTREACHED()<<"Invalid database tag. Did you add it to the "
Anthony Vallée-Duboiseb60f1b2024-12-20 16:37:12[diff] [blame]391"DatabaseTag variant in sql/histograms.xml?";
Anthony Vallée-Duboisdd2d9012024-12-18 23:25:28[diff] [blame]392}
393}
394
395 std::string_view value;
396};
397
Victor Costan9d1c8754b2021-07-13 02:53:29[diff] [blame]398// Creates an instance that can receive Open() / OpenInMemory() calls.
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]399//
Victor Costan9d1c8754b2021-07-13 02:53:29[diff] [blame]400// Some `options` members are only applied to newly created databases.
401//
402// Most operations on the new instance will fail until Open() / OpenInMemory()
403// is called.
Anthony Vallée-Duboise3c94912024-12-12 16:47:47[diff] [blame]404//
405// `tag` is a string uniquely identifying this database for metrics. This
406// class automatically uses `tag` to determine which histogram to record to
407// for timing and error histograms. Tests that don't care about those
408// histograms values can use `sql::test::kTestTag` from
409// sql/test/test_helpers.h.
Anthony Vallée-Duboisdd2d9012024-12-18 23:25:28[diff] [blame]410Database(DatabaseOptions options,Tag tag);
Victor Costan9d1c8754b2021-07-13 02:53:29[diff] [blame]411
Anthony Vallée-Dubois5508a342024-11-29 16:35:25[diff] [blame]412// Convenience constructor for callers that use default options.
Anthony Vallée-Duboisdd2d9012024-12-18 23:25:28[diff] [blame]413explicitDatabase(Tag tag);
Victor Costan9d1c8754b2021-07-13 02:53:29[diff] [blame]414
Victor Costan00c76432021-07-07 16:55:58[diff] [blame]415Database(constDatabase&)=delete;
416Database&operator=(constDatabase&)=delete;
Andrew Paseltiner7d512ddd2022-09-16 13:36:52[diff] [blame]417Database(Database&&)=delete;
418Database&operator=(Database&&)=delete;
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]419~Database();
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]420
421// Pre-init configuration ----------------------------------------------------
422
Victor Costan7f6abbbe2018-07-29 02:57:27[diff] [blame]423// The page size that will be used when creating a new database.
Anthony Vallée-Dubois9adf0bb2025-02-03 17:01:41[diff] [blame]424int page_size()const{return options_.page_size_;}
Victor Costan7f6abbbe2018-07-29 02:57:27[diff] [blame]425
Shubham Aggarwalbe4f97ce2020-06-19 15:58:57[diff] [blame]426// Returns whether a database will be opened in WAL mode.
427boolUseWALMode()const;
428
Victor Costan87cf8c72018-07-19 19:36:04[diff] [blame]429// Opt out of memory-mapped file I/O.
shess7dbd4dee2015-10-06 17:39:16[diff] [blame]430void set_mmap_disabled(){ mmap_disabled_=true;}
431
shess@chromium.orgc3881b372013-05-17 08:39:46[diff] [blame]432// Set an error-handling callback. On errors, the error number (and
433// statement, if available) will be passed to the callback.
434//
Victor Costance406da22021-09-20 21:01:38[diff] [blame]435// If no callback is set, the default error-handling behavior is invoked. The
436// default behavior is to LOGs the error and propagate the failure.
437//
438// In DCHECK-enabled builds, the default error-handling behavior currently
439// DCHECKs on errors. This is not correct, because DCHECKs are supposed to
440// cover invariants and never fail, whereas SQLite errors can surface even on
441// correct usage, due to I/O errors and data corruption. At some point in the
442// future, errors will not result in DCHECKs.
443//
444// The callback will be called on the sequence used for database operations.
445// The callback will never be called after the Database instance is destroyed.
Victor Costanc7e7f2e2018-07-18 20:07:55[diff] [blame]446usingErrorCallback=base::RepeatingCallback<void(int,Statement*)>;
Victor Costand09770c2022-03-08 23:14:46[diff] [blame]447void set_error_callback(ErrorCallback callback){
Victor Costan7d0b01a2022-03-15 19:56:49[diff] [blame]448 DCHECK(!callback.is_null())<<"Use reset_error_callback() explicitly";
449 DCHECK(error_callback_.is_null())
Victor Costand09770c2022-03-08 23:14:46[diff] [blame]450<<"Overwriting previously set error callback";
451 error_callback_= std::move(callback);
shess@chromium.orgc3881b372013-05-17 08:39:46[diff] [blame]452}
Victor Costan87cf8c72018-07-19 19:36:04[diff] [blame]453void reset_error_callback(){ error_callback_.Reset();}
Austin Sullivan2fbe496e2023-05-18 19:48:52[diff] [blame]454bool has_error_callback()const{return!error_callback_.is_null();}
shess@chromium.orgc3881b372013-05-17 08:39:46[diff] [blame]455
Etienne Bergeronf969727a2023-12-15 19:40:34[diff] [blame]456const std::string& histogram_tag()const{return histogram_tag_;}
shess@chromium.orgc088e3a32013-01-03 23:59:14[diff] [blame]457
Victor Costan8c3a9922022-02-26 03:50:52[diff] [blame]458// Asks SQLite to perform a full integrity check on the database.
459//
460// Returns true if the integrity check was completed successfully. Success
461// does not necessarily entail that the database is healthy. Finding
462// corruption and reporting it in `messages` counts as success.
463//
464// If the method returns true, `messages` is populated with a list of
465// diagnostic messages. If the integrity check finds no errors, `messages`
466// will contain exactly one "ok" string. This unusual API design is explained
467// by the fact that SQLite exposes integrity check functionality as a PRAGMA,
468// and the PRAGMA returns "ok" in case of success.
michaeln@chromium.org579446c2013-12-16 18:36:52[diff] [blame]469boolFullIntegrityCheck(std::vector<std::string>* messages);
470
afakhry7c9abe72016-08-05 17:33:19[diff] [blame]471// Meant to be called from a client error callback so that it's able to
Tommy C. Li7803636c2022-07-27 21:47:22[diff] [blame]472// get diagnostic information about the database. `diagnostics` is an optional
473// out parameter. If `diagnostics` is defined, this method populates all of
474// its fields.
475 std::stringGetDiagnosticInfo(int extended_error,
476Statement* statement,
477DatabaseDiagnostics* diagnostics=nullptr);
afakhry7c9abe72016-08-05 17:33:19[diff] [blame]478
ssid1f4e5362016-12-08 20:41:38[diff] [blame]479// Reports memory usage into provided memory dump with the given name.
480boolReportMemoryUsage(base::trace_event::ProcessMemoryDump* pmd,
481const std::string& dump_name);
dskibab4199f82016-11-21 20:16:13[diff] [blame]482
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]483// Initialization ------------------------------------------------------------
484
Victor Costan6de11461f2022-03-13 06:47:19[diff] [blame]485// Opens or creates a database on disk.
486//
487// `db_file_path` points to the file storing database pages. Other files
488// associated with the database (rollback journal, write-ahead log,
489// shared-memory file) may be created.
490//
Dan McArdle4feabeb52024-01-03 15:17:13[diff] [blame]491// Returns true in case of success, false in case of failure. If an error
492// occurs, this function will invoke the error callback if it is present and
493// then may attempt to open the database a second time. If the second attempt
494// succeeds, it will return true.
Victor Costan6de11461f2022-03-13 06:47:19[diff] [blame]495[[nodiscard]]boolOpen(constbase::FilePath& db_file_path);
brettw@chromium.org765b44502009-10-02 05:01:42[diff] [blame]496
Victor Costan6de11461f2022-03-13 06:47:19[diff] [blame]497// Alternative to Open() that creates an in-memory database.
498//
499// Returns true in case of success, false in case of failure.
500//
501// The memory associated with the database will be released when the database
502// is closed.
Daniel Cheng1ac0cad2022-01-14 00:19:53[diff] [blame]503[[nodiscard]]boolOpenInMemory();
brettw@chromium.org765b44502009-10-02 05:01:42[diff] [blame]504
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]505// Returns true if the database has been successfully opened.
Austin Sullivan6c6faa52023-08-16 18:32:37[diff] [blame]506bool is_open()const;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]507
Dan McArdle44d62a12024-02-29 17:08:14[diff] [blame]508// Detach from the currently-attached sequence. If already attached to a
509// sequence, this method must be called from that sequence.
510voidDetachFromSequence();
511
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]512// Closes the database. This is automatically performed on destruction for
513// you, but this allows you to close the database early. You must not call
514// any other functions after closing it. It is permissable to call Close on
515// an uninitialized or already-closed database.
516voidClose();
517
Victor Costan52bef812018-12-05 07:41:49[diff] [blame]518// Release all non-essential memory associated with this database connection.
519voidTrimMemory();
rmcilroy@chromium.orgbe7995f12013-07-18 18:49:14[diff] [blame]520
shess@chromium.org8e0c01282012-04-06 19:36:49[diff] [blame]521// Raze the database to the ground. This approximates creating a
522// fresh database from scratch, within the constraints of SQLite's
523// locking protocol (locks and open handles can make doing this with
524// filesystem operations problematic). Returns true if the database
525// was razed.
526//
527// false is returned if the database is locked by some other
Carlos Knippschild46800c9f2017-09-02 02:21:43[diff] [blame]528// process.
shess@chromium.org8e0c01282012-04-06 19:36:49[diff] [blame]529//
530// NOTE(shess): Raze() will DCHECK in the following situations:
531// - database is not open.
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]532// - the database has a transaction open.
shess@chromium.org8e0c01282012-04-06 19:36:49[diff] [blame]533// - a SQLite issue occurs which is structural in nature (like the
534// statements used are broken).
535// Since Raze() is expected to be called in unexpected situations,
536// these all return false, since it is unlikely that the caller
537// could fix them.
shess@chromium.org6d42f152012-11-10 00:38:24[diff] [blame]538//
Shubham Aggarwal7b60fe6e2020-10-15 06:00:28[diff] [blame]539// The database's page size is taken from |options_.page_size|. The
shess@chromium.org6d42f152012-11-10 00:38:24[diff] [blame]540// existing database's |auto_vacuum| setting is lost (the
541// possibility of corruption makes it unreliable to pull it from the
542// existing database). To re-enable on the empty database requires
543// running "PRAGMA auto_vacuum = 1;" then "VACUUM".
544//
545// NOTE(shess): For Android, SQLITE_DEFAULT_AUTOVACUUM is set to 1,
546// so Raze() sets auto_vacuum to 1.
547//
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]548// TODO(shess): Raze() needs a database so cannot clear SQLITE_NOTADB.
549// TODO(shess): Bake auto_vacuum into Database's API so it can
shess@chromium.org6d42f152012-11-10 00:38:24[diff] [blame]550// just pick up the default.
shess@chromium.org8e0c01282012-04-06 19:36:49[diff] [blame]551boolRaze();
shess@chromium.org8e0c01282012-04-06 19:36:49[diff] [blame]552
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]553// Breaks all outstanding transactions (as initiated by
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]554// BeginTransaction()), closes the SQLite database, and poisons the
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]555// object so that all future operations against the Database (or
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]556// its Statements) fail safely, without side effects.
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]557//
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]558// This is intended as an alternative to Close() in error callbacks.
559// Close() should still be called at some point.
560voidPoison();
561
Andrew Paseltinerb03bebe62023-03-27 13:08:24[diff] [blame]562// `Raze()` the database and `Poison()` the handle. Returns the return
563// value from `Raze()`.
564boolRazeAndPoison();
565
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]566// Delete the underlying database files associated with |path|. This should be
567// used on a database which is not opened by any Database instance. Open
568// Database instances pointing to the database can cause odd results or
569// corruption (for instance if a hot journal is deleted but the associated
570// database is not).
shess@chromium.org8d2e39e2013-06-24 05:55:08[diff] [blame]571//
572// Returns true if the database file and associated journals no
573// longer exist, false otherwise. If the database has never
574// existed, this will return true.
575staticboolDelete(constbase::FilePath& path);
576
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]577// Transactions --------------------------------------------------------------
578
579// Transaction management. We maintain a virtual transaction stack to emulate
580// nested transactions since sqlite can't do nested transactions. The
581// limitation is you can't roll back a sub transaction: if any transaction
582// fails, all transactions open will also be rolled back. Any nested
583// transactions after one has rolled back will return fail for Begin(). If
584// Begin() fails, you must not call Commit or Rollback().
585//
586// Normally you should use sql::Transaction to manage a transaction, which
587// will scope it to a C++ context.
Andrew Paseltinercbb14482024-05-20 13:24:06[diff] [blame]588[[nodiscard]]boolBeginTransaction(InternalApiToken);
589voidRollbackTransaction(InternalApiToken);
590[[nodiscard]]boolCommitTransaction(InternalApiToken);
591
592// These methods are deprecated and will be removed in the future: The
593// `Transaction` class should be used instead.
594boolBeginTransactionDeprecated();
595voidRollbackTransactionDeprecated();
596boolCommitTransactionDeprecated();
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]597
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]598// Rollback all outstanding transactions. Use with care, there may
599// be scoped transactions on the stack.
600voidRollbackAllTransactions();
601
Victor Costan628afca2021-09-21 02:36:09[diff] [blame]602boolHasActiveTransactions()const{
603 DCHECK_GE(transaction_nesting_,0);
Dan McArdle89348ed2024-02-26 20:50:08[diff] [blame]604return is_open()&& transaction_nesting_>0;
Victor Costan628afca2021-09-21 02:36:09[diff] [blame]605}
606
607// Deprecated in favor of HasActiveTransactions().
608//
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]609// Returns the current transaction nesting, which will be 0 if there are
610// no open transactions.
611int transaction_nesting()const{return transaction_nesting_;}
612
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]613// Attached databases---------------------------------------------------------
614
Victor Costan169ef032021-07-14 08:45:49[diff] [blame]615// Attaches an existing database to this connection.
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]616//
Victor Costan169ef032021-07-14 08:45:49[diff] [blame]617// `attachment_point` must only contain lowercase letters.
618//
Evan Stade1d80896e2024-02-28 18:40:26[diff] [blame]619// Use is generally discouraged in production code. The README has more
620// details.
Victor Costan8a87f7e52017-11-10 01:29:30[diff] [blame]621//
622// On the SQLite version shipped with Chrome (3.21+, Oct 2017), databases can
623// be attached while a transaction is opened. However, these databases cannot
Victor Costan70bedf22018-07-18 21:21:14[diff] [blame]624// be detached until the transaction is committed or aborted.
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]625boolAttachDatabase(constbase::FilePath& other_db_path,
Md Hasibul Hasan52ffeca62024-03-26 18:23:18[diff] [blame]626 std::string_view attachment_point);
Victor Costan169ef032021-07-14 08:45:49[diff] [blame]627
628// Detaches a database that was previously attached with AttachDatabase().
629//
630// `attachment_point` must match the argument of a previously successsful
631// AttachDatabase() call.
632//
633// Attachment APIs are only exposed for use in recovery. General use is
634// discouraged in Chrome. The README has more details.
Md Hasibul Hasan52ffeca62024-03-26 18:23:18[diff] [blame]635boolDetachDatabase(std::string_view attachment_point);
shess@chromium.org8d409412013-07-19 18:25:30[diff] [blame]636
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]637// Statements ----------------------------------------------------------------
638
Victor Costan205b96dc2021-07-21 20:27:46[diff] [blame]639// Executes a SQL statement. Returns true for success, and false for failure.
shess@chromium.org9fe37552011-12-23 17:07:20[diff] [blame]640//
Victor Costan205b96dc2021-07-21 20:27:46[diff] [blame]641// `sql` should be a single SQL statement. Production code should not execute
Victor Costan289f2c8b2021-07-22 06:33:47[diff] [blame]642// multiple SQL statements at once, to facilitate crash debugging. Test code
643// should use ExecuteScriptForTesting().
Victor Costan205b96dc2021-07-21 20:27:46[diff] [blame]644//
645// `sql` cannot have parameters. Statements with parameters can be handled by
646// sql::Statement. See GetCachedStatement() and GetUniqueStatement().
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]647[[nodiscard]]boolExecute(base::cstring_view sql);
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]648
Victor Costan289f2c8b2021-07-22 06:33:47[diff] [blame]649// Executes a sequence of SQL statements.
650//
651// Returns true if all statements execute successfully. If a statement fails,
652// stops and returns false. Calls should be wrapped in ASSERT_TRUE().
653//
654// The database's error handler is not invoked when errors occur. This method
655// is a convenience for setting up a complex on-disk database state, such as
656// an old schema version with test contents.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]657[[nodiscard]]boolExecuteScriptForTesting(base::cstring_view sql_script);
Victor Costan289f2c8b2021-07-22 06:33:47[diff] [blame]658
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]659// Returns a statement for the given SQL using the statement cache. It can
660// take a nontrivial amount of work to parse and compile a statement, so
661// keeping commonly-used ones around for future use is important for
662// performance.
663//
Victor Costan613b4302018-11-20 05:32:43[diff] [blame]664// The SQL_FROM_HERE macro is the recommended way of generating a StatementID.
665// Code that generates custom IDs must ensure that a StatementID is never used
666// for different SQL statements. Failing to meet this requirement results in
667// incorrect behavior, and should be caught by a DCHECK.
668//
669// The SQL statement passed in |sql| must match the SQL statement reported
670// back by SQLite. Mismatches are caught by a DCHECK, so any code that has
671// automated test coverage or that was manually tested on a DCHECK build will
672// not exhibit this problem. Mismatches generally imply that the statement
673// passed in has extra whitespace or comments surrounding it, which waste
674// storage and CPU cycles.
675//
shess@chromium.orgeff1fa522011-12-12 23:50:59[diff] [blame]676// If the |sql| has an error, an invalid, inert StatementRef is returned (and
677// the code will crash in debug). The caller must deal with this eventuality,
678// either by checking validity of the |sql| before calling, by correctly
679// handling the return of an inert statement, or both.
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]680//
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]681// Example:
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]682// sql::Statement stmt(database_.GetCachedStatement(
nick@chromium.org3273dce2010-01-27 16:08:08[diff] [blame]683// SQL_FROM_HERE, "SELECT * FROM foo"));
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]684// if (!stmt)
685// return false; // Error creating statement.
Victor Costan12daa3ac92018-07-19 01:05:58[diff] [blame]686 scoped_refptr<StatementRef>GetCachedStatement(StatementID id,
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]687base::cstring_view sql);
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]688
shess@chromium.orgeff1fa522011-12-12 23:50:59[diff] [blame]689// Used to check a |sql| statement for syntactic validity. If the statement is
690// valid SQL, returns true.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]691boolIsSQLValid(base::cstring_view sql);
shess@chromium.orgeff1fa522011-12-12 23:50:59[diff] [blame]692
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]693// Returns a non-cached statement for the given SQL. Use this for SQL that
694// is only executed once or only rarely (there is overhead associated with
695// keeping a statement cached).
696//
697// See GetCachedStatement above for examples and error information.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]698 scoped_refptr<StatementRef>GetUniqueStatement(base::cstring_view sql);
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]699
ssid583f55e2022-04-21 19:59:00[diff] [blame]700// Returns a non-cached statement same as `GetUniqueStatement()`, except
701// returns an invalid statement if the statement makes direct changes to the
702// database file. This readonly check does not include changes made by
703// application-defined functions. See more at:
704// https://www.sqlite.org/c3ref/stmt_readonly.html.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]705 scoped_refptr<Database::StatementRef>GetReadonlyStatement(
706base::cstring_view sql);
ssid583f55e2022-04-21 19:59:00[diff] [blame]707
Evan Stade416f46f12025-06-18 15:42:39[diff] [blame]708// Opens a blob for streaming. Returns nullopt on failure. Note that this
709// should only be called if the given table, column, and row is known to
710// exist --- everything else is an error. For a list of failure modes, see
711// https://www.sqlite.org/c3ref/blob_open.html
712//
713// See `StreamingBlobHandle` docs for notes on lifetime.
714 std::optional<StreamingBlobHandle>GetStreamingBlob(base::cstring_view table,
715base::cstring_view column,
716int64_t row_id,
717boolreadonly);
718
Shubham Aggarwalbe4f97ce2020-06-19 15:58:57[diff] [blame]719// Performs a passive checkpoint on the main attached database if it is in
720// WAL mode. Returns true if the checkpoint was successful and false in case
721// of an error. It is a no-op if the database is not in WAL mode.
722//
723// Note: Checkpointing is a very slow operation and will block any writes
724// until it is finished. Please use with care.
725boolCheckpointDatabase();
726
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]727// Info querying -------------------------------------------------------------
728
shessa62504d2016-11-07 19:26:12[diff] [blame]729// Returns true if the given structure exists. Instead of test-then-create,
730// callers should almost always prefer the "IF NOT EXISTS" version of the
731// CREATE statement.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]732// TODO(https://crbug.com/341639215): these should take a `base::cstring`.
Md Hasibul Hasan52ffeca62024-03-26 18:23:18[diff] [blame]733boolDoesIndexExist(std::string_view index_name);
734boolDoesTableExist(std::string_view table_name);
735boolDoesViewExist(std::string_view table_name);
michaeln@google.come2cadec82011-12-13 02:00:53[diff] [blame]736
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]737// Returns true if a column with the given name exists in the given table.
Victor Costan1ff47e92018-12-07 11:10:43[diff] [blame]738//
739// Calling this method on a VIEW returns an unspecified result.
740//
741// This should only be used by migration code for legacy features that do not
742// use MetaTable, and need an alternative way of figuring out the database's
743// current version.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]744boolDoesColumnExist(base::cstring_view table_name,
745base::cstring_view column_name);
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]746
747// Returns sqlite's internal ID for the last inserted row. Valid only
748// immediately after an insert.
tfarina720d4f32015-05-11 22:31:26[diff] [blame]749int64_tGetLastInsertRowId()const;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]750
brettw@chromium.org1ed78a32009-09-15 20:24:17[diff] [blame]751// Returns sqlite's count of the number of rows modified by the last
752// statement executed. Will be 0 if no statement has executed or the database
753// is closed.
Victor Costand4dfb4f2022-02-24 00:01:12[diff] [blame]754int64_tGetLastChangeCount();
brettw@chromium.org1ed78a32009-09-15 20:24:17[diff] [blame]755
Victor Costand6e73252020-10-14 21:11:25[diff] [blame]756// Approximates the amount of memory used by SQLite for this database.
757//
758// This measures the memory used for the page cache (most likely the biggest
759// consumer), database schema, and prepared statements.
760//
761// The memory used by the page cache can be recovered by calling TrimMemory(),
762// which will cause SQLite to drop the page cache.
763intGetMemoryUsage();
764
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]765// Errors --------------------------------------------------------------------
766
767// Returns the error code associated with the last sqlite operation.
768intGetErrorCode()const;
769
Vikram Pasupathy73c603912024-04-02 20:51:31[diff] [blame]770// Returns the errno associated with GetErrorCode(). See <errno.h>.
shess@chromium.org767718e52010-09-21 23:18:49[diff] [blame]771intGetLastErrno()const;
772
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]773// Returns a pointer to a statically allocated string associated with the
774// last sqlite operation.
775constchar*GetErrorMessage()const;
776
shess@chromium.org92cd00a2013-08-16 11:09:58[diff] [blame]777// Return a reproducible representation of the schema equivalent to
778// running the following statement at a sqlite3 command-line:
John Delaney86dbec62021-08-24 15:05:21[diff] [blame]779// SELECT type, name, tbl_name, sql FROM sqlite_schema ORDER BY 1, 2, 3, 4;
Victor Costan106e50072021-07-17 00:04:49[diff] [blame]780 std::stringGetSchema();
shess@chromium.org92cd00a2013-08-16 11:09:58[diff] [blame]781
shess976814402016-06-21 06:56:25[diff] [blame]782// Returns |true| if there is an error expecter (see SetErrorExpecter), and
783// that expecter returns |true| when passed |error|. Clients which provide an
784// |error_callback| should use IsExpectedSqliteError() to check for unexpected
Peter Boström29c761792024-01-18 23:05:29[diff] [blame]785// errors; if one is detected, DLOG(FATAL) is generally appropriate (see
shess976814402016-06-21 06:56:25[diff] [blame]786// OnSqliteError implementation).
Victor Costanedf48be2022-03-14 21:40:12[diff] [blame]787staticboolIsExpectedSqliteError(int sqlite_error_code);
shess@chromium.org74cdede2013-09-25 05:39:57[diff] [blame]788
Victor Costance678e72018-07-24 10:25:00[diff] [blame]789// Computes the path of a database's rollback journal.
790//
791// The journal file is created at the beginning of the database's first
792// transaction. The file may be removed and re-created between transactions,
793// depending on whether the database is opened in exclusive mode, and on
794// configuration options. The journal file does not exist when the database
795// operates in WAL mode.
796//
797// This is intended for internal use and tests. To preserve our ability to
798// iterate on our SQLite configuration, features must avoid relying on
799// the existence of specific files.
800staticbase::FilePathJournalPath(constbase::FilePath& db_path);
801
802// Computes the path of a database's write-ahead log (WAL).
803//
804// The WAL file exists while a database is opened in WAL mode.
805//
806// This is intended for internal use and tests. To preserve our ability to
807// iterate on our SQLite configuration, features must avoid relying on
808// the existence of specific files.
809staticbase::FilePathWriteAheadLogPath(constbase::FilePath& db_path);
810
811// Computes the path of a database's shared memory (SHM) file.
812//
813// The SHM file is used to coordinate between multiple processes using the
814// same database in WAL mode. Thus, this file only exists for databases using
815// WAL and not opened in exclusive mode.
816//
817// This is intended for internal use and tests. To preserve our ability to
818// iterate on our SQLite configuration, features must avoid relying on
819// the existence of specific files.
820staticbase::FilePathSharedMemoryFilePath(constbase::FilePath& db_path);
821
Victor Costan7f6abbbe2018-07-29 02:57:27[diff] [blame]822// Internal state accessed by other classes in //sql.
Dan McArdle44d62a12024-02-29 17:08:14[diff] [blame]823base::WeakPtr<Database>GetWeakPtr(InternalApiToken);
Victor Costan7f6abbbe2018-07-29 02:57:27[diff] [blame]824 sqlite3* db(InternalApiToken)const{return db_;}
825bool poisoned(InternalApiToken)const{return poisoned_;}
Austin Sullivan0593ef92023-05-17 20:46:30[diff] [blame]826base::FilePathDbPath(InternalApiToken)const{returnDbPath();}
Victor Costan7f6abbbe2018-07-29 02:57:27[diff] [blame]827
Victor Costanbc4285f2021-09-20 21:29:28[diff] [blame]828// Interface with sql::test::ScopedErrorExpecter.
829usingScopedErrorExpecterCallback=base::RepeatingCallback<bool(int)>;
830staticvoidSetScopedErrorExpecter(ScopedErrorExpecterCallback* expecter,
831base::PassKey<test::ScopedErrorExpecter>);
832staticvoidResetScopedErrorExpecter(
833base::PassKey<test::ScopedErrorExpecter>);
shess@chromium.org4350e322013-06-18 22:18:10[diff] [blame]834
Victor Costanbc4285f2021-09-20 21:29:28[diff] [blame]835private:
shess@chromium.orgeff1fa522011-12-12 23:50:59[diff] [blame]836// Statement accesses StatementRef which we don't want to expose to everybody
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]837// (they should go through Statement).
838friendclassStatement;
839
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]840 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,CachedStatement);
841 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,CollectDiagnosticInfo);
Victor Costandc72e8d2022-03-14 18:14:51[diff] [blame]842 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,ComputeMmapSizeForOpen);
843 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,ComputeMmapSizeForOpenAltStatus);
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]844 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,OnMemoryDump);
Etienne Bergeron1ee05fe2025-05-23 14:37:36[diff] [blame]845 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,
846RazeAndPoison_ComputeMmapSizeForOpen);
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]847 FRIEND_TEST_ALL_PREFIXES(SQLDatabaseTest,RegisterIntentToUpload);
shessf7fcc452017-04-19 22:10:41[diff] [blame]848 FRIEND_TEST_ALL_PREFIXES(SQLiteFeaturesTest,WALNoClose);
a20.singhb0ca1122022-05-26 03:32:45[diff] [blame]849 FRIEND_TEST_ALL_PREFIXES(SQLEmptyPathDatabaseTest,EmptyPathTest);
Evan Stade416f46f12025-06-18 15:42:39[diff] [blame]850 FRIEND_TEST_ALL_PREFIXES(StreamingBlobHandleTest,Basic);
shessc8cd2a162015-10-22 20:30:46[diff] [blame]851
Anthony Vallée-Duboisde37202582024-12-04 18:52:30[diff] [blame]852// A scoped utility to setup error reporting during the `Open()` operation
853classScopedOpenErrorReporter{
854public:
855// db: the database to instrument. Must outlive `this`
856// histogram: the histogram to record the error code into. Will
857// automatically be suffixed with `Database::histogram_tag()` if it's
858// specified, "NoTag" otherwise.
859ScopedOpenErrorReporter(Database* db, std::string_view histogram);
860~ScopedOpenErrorReporter();
861
862private:
863// The callback that will be invoked by the database in case of an error.
864voidOnErrorDuringOpen(SqliteResultCode code);
865
866 raw_ptr<Database> db_;
867 std::string_view histogram_;
868};
869
870// Invoke `open_error_reporting_callback_` if it's set.
871voidMaybeReportErrorDuringOpen(SqliteResultCode code);
872
Evan Stade4c7d6b32024-03-12 16:50:27[diff] [blame]873// Implements Open(), OpenInMemory().
shess@chromium.orgfed734a2013-07-17 04:45:13[diff] [blame]874//
Evan Stade4c7d6b32024-03-12 16:50:27[diff] [blame]875// `db_file_path` is a UTF-8 path to the file storing the database pages. If
876// `file_name` is the SQLite magic memory path :memory:, the database will be
877// opened in-memory.
878boolOpenInternal(const std::string& file_name);
brettw@chromium.org765b44502009-10-02 05:01:42[diff] [blame]879
Etienne Bergeron9635e20f2025-02-11 17:52:38[diff] [blame]880// Requests the operating system to preload the pages on disk into memory.
881voidPreloadInternal(constbase::FilePath& path);
882
Victor Costanf9832e32022-03-12 18:33:59[diff] [blame]883// Configures the underlying sqlite3* object via sqlite3_db_config().
884//
885// To minimize the number of possible SQLite code paths executed in Chrome,
886// this method must be called right after the underlying sqlite3* object is
887// obtained from sqlite3_open*(), before any other sqlite3_*() methods are
888// called on the object.
889voidConfigureSqliteDatabaseObject();
890
Andrew Paseltinerd309fec2023-03-28 16:59:55[diff] [blame]891// Internal close function used by Close() and RazeAndPoison().
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]892// |forced| indicates that orderly-shutdown checks should not apply.
893voidCloseInternal(bool forced);
894
Evan Stade416f46f12025-06-18 15:42:39[diff] [blame]895// Called when a blob opened with `GetStreamingBlob()` is closed. `result` may
896// or may not be an error; if it is, `error_source` identifies which sqlite3
897// call caused the error.
898voidOnStreamingBlobClosed(SqliteResultCode result,constchar* error_source);
899
Etienne Pierre-Doraya71d7af2019-02-07 02:07:54[diff] [blame]900// Construct a ScopedBlockingCall to annotate IO calls, but only if
Etienne Bergerone7681c72020-01-17 00:51:20[diff] [blame]901// database wasn't open in memory. ScopedBlockingCall uses |from_here| to
902// declare its blocking execution scope (see https://www.crbug/934302).
Etienne Pierre-Doraya71d7af2019-02-07 02:07:54[diff] [blame]903voidInitScopedBlockingCall(
Etienne Bergerone7681c72020-01-17 00:51:20[diff] [blame]904constbase::Location& from_here,
Arthur Sonzogni59ac8222023-11-10 09:46:54[diff] [blame]905 std::optional<base::ScopedBlockingCall>* scoped_blocking_call)const{
shess@chromium.org35f7e5392012-07-27 19:54:50[diff] [blame]906if(!in_memory_)
Etienne Bergerone7681c72020-01-17 00:51:20[diff] [blame]907 scoped_blocking_call->emplace(from_here,base::BlockingType::MAY_BLOCK);
shess@chromium.org35f7e5392012-07-27 19:54:50[diff] [blame]908}
909
shessa62504d2016-11-07 19:26:12[diff] [blame]910// Internal helper for Does*Exist() functions.
Md Hasibul Hasan52ffeca62024-03-26 18:23:18[diff] [blame]911boolDoesSchemaItemExist(std::string_view name, std::string_view type);
michaeln@google.come2cadec82011-12-13 02:00:53[diff] [blame]912
Victor Costanbc4285f2021-09-20 21:29:28[diff] [blame]913// Used to implement the interface with sql::test::ScopedErrorExpecter.
914staticScopedErrorExpecterCallback* current_expecter_cb_;
shess@chromium.org4350e322013-06-18 22:18:10[diff] [blame]915
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]916// A StatementRef is a refcounted wrapper around a sqlite statement pointer.
917// Refcounting allows us to give these statements out to sql::Statement
918// objects while also optionally maintaining a cache of compiled statements
919// by just keeping a refptr to these objects.
920//
921// A statement ref can be valid, in which case it can be used, or invalid to
922// indicate that the statement hasn't been created yet, has an error, or has
923// been destroyed.
924//
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]925// The Database may revoke a StatementRef in some error cases, so callers
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]926// should always check validity before using.
Victor Costane56cc682018-12-27 01:53:46[diff] [blame]927class COMPONENT_EXPORT(SQL)StatementRef
928:publicbase::RefCounted<StatementRef>{
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]929public:
Victor Costan3b02cdf2018-07-18 00:39:56[diff] [blame]930 REQUIRE_ADOPTION_FOR_REFCOUNTED_TYPE();
931
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]932// |database| is the sql::Database instance associated with
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]933// the statement, and is used for tracking outstanding statements
Victor Costan106e50072021-07-17 00:04:49[diff] [blame]934// and for error handling. Set to nullptr for invalid refs.
935// |stmt| is the actual statement, and should only be null
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]936// to create an invalid ref. |was_valid| indicates whether the
Etienne Bergeron95a01c2a2019-02-26 21:32:50[diff] [blame]937// statement should be considered valid for diagnostic purposes.
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]938// |was_valid| can be true for a null |stmt| if the Database has
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]939// been forcibly closed by an error handler.
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]940StatementRef(Database* database, sqlite3_stmt* stmt,bool was_valid);
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]941
Victor Costan00c76432021-07-07 16:55:58[diff] [blame]942StatementRef(constStatementRef&)=delete;
943StatementRef&operator=(constStatementRef&)=delete;
Andrew Paseltiner7d512ddd2022-09-16 13:36:52[diff] [blame]944StatementRef(StatementRef&&)=delete;
945StatementRef&operator=(StatementRef&&)=delete;
Victor Costan00c76432021-07-07 16:55:58[diff] [blame]946
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]947// When true, the statement can be used.
948bool is_valid()const{return!!stmt_;}
949
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]950// When true, the statement is either currently valid, or was
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]951// previously valid but the database was forcibly closed. Used
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]952// for diagnostic checks.
953bool was_valid()const{return was_valid_;}
954
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]955// If we've not been linked to a database, this will be null.
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]956Database* database()const{return database_;}
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]957
958// Returns the sqlite statement if any. If the statement is not active,
Victor Costanbd623112018-07-18 04:17:27[diff] [blame]959// this will return nullptr.
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]960 sqlite3_stmt* stmt()const{return stmt_;}
961
Evan Stade9728e5a2025-06-05 18:51:27[diff] [blame]962// Assumes ownership of `blob`.
963//
964// To be called BEFORE the data in `blob` will be bound to a SQLite
965// statement SQLite. SQLite assumes the pointer will remain valid until the
966// statement is finalized or the parameter is unbound.
967//
968// A span pointing to the newly owned memory is returned --- this is the
969// pointer that should be passed to sqlite3 functions.
970base::span<constuint8_t>TakeBlobMemory(
971int index,
972 scoped_refptr<base::RefCountedMemory> blob);
973
974// Releases memory passed by `TakeBlobMemory()`, if any. The caller should
975// also tell SQLite to unbind or rebind the parameter (i.e. update the
976// binding that was previously set with TakeBlobMemory's output).
977voidClearBlobMemory(int index);
978
979// Resets the statement and, if `clear_bound_variables` is true, drops
980// parameter bindings, including dropping `bound_blobs_`.
981voidReset(bool clear_bound_variables);
982
Victor Costanbd623112018-07-18 04:17:27[diff] [blame]983// Destroys the compiled statement and sets it to nullptr. The statement
984// will no longer be active. |forced| is used to indicate if
Andrew Paseltinerd309fec2023-03-28 16:59:55[diff] [blame]985// orderly-shutdown checks should apply (see Database::RazeAndPoison()).
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]986voidClose(bool forced);
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]987
Etienne Pierre-Doraya71d7af2019-02-07 02:07:54[diff] [blame]988// Construct a ScopedBlockingCall to annotate IO calls, but only if
Etienne Bergerone7681c72020-01-17 00:51:20[diff] [blame]989// database wasn't open in memory. ScopedBlockingCall uses |from_here| to
990// declare its blocking execution scope (see https://www.crbug/934302).
Etienne Pierre-Doraya71d7af2019-02-07 02:07:54[diff] [blame]991voidInitScopedBlockingCall(
Etienne Bergerone7681c72020-01-17 00:51:20[diff] [blame]992constbase::Location& from_here,
Arthur Sonzogni59ac8222023-11-10 09:46:54[diff] [blame]993 std::optional<base::ScopedBlockingCall>* scoped_blocking_call)const{
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]994if(database_)
Etienne Bergerone7681c72020-01-17 00:51:20[diff] [blame]995 database_->InitScopedBlockingCall(from_here, scoped_blocking_call);
Victor Costanc7e7f2e2018-07-18 20:07:55[diff] [blame]996}
shess@chromium.org35f7e5392012-07-27 19:54:50[diff] [blame]997
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]998private:
jam@chromium.org877d55d2009-11-05 21:53:08[diff] [blame]999friendclassbase::RefCounted<StatementRef>;
1000
1001~StatementRef();
1002
Evan Stade9728e5a2025-06-05 18:51:27[diff] [blame]1003// Holds onto memory that is to be used by the statement. These blobs have
1004// been bound with `SQLITE_STATIC`, see
1005// https://www.sqlite.org/c3ref/bind_blob.html for docs.
1006// Note that value pointer stability is important, and that's granted by
1007// scoped_refptr.
1008base::flat_map<int, scoped_refptr<base::RefCountedMemory>> bound_blobs_;
1009
Keishi Hattori0e45c022021-11-27 09:25:52[diff] [blame]1010 raw_ptr<Database> database_;
1011 raw_ptr<sqlite3_stmt> stmt_;
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]1012bool was_valid_;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1013};
1014friendclassStatementRef;
1015
1016// Executes a rollback statement, ignoring all transaction state. Used
1017// internally in the transaction management code.
1018voidDoRollback();
1019
1020// Called by a StatementRef when it's being created or destroyed. See
1021// open_statements_ below.
1022voidStatementRefCreated(StatementRef*ref);
1023voidStatementRefDeleted(StatementRef*ref);
1024
Victor Costanb9faa622022-03-10 16:08:29[diff] [blame]1025// Used by sql:: internals to report a SQLite error related to this database.
1026//
1027// `sqlite_error_code` contains the error code reported by SQLite. Possible
1028// values are documented at https://www.sqlite.org/rescode.html
1029//
1030// `statement` is non-null if the error is associated with a sql::Statement.
1031// Otherwise, `sql_statement` will be a non-null string pointing to a
1032// statically-allocated (valid for the entire duration of the process) buffer
1033// pointing to either a SQL statement or a SQL comment (starting with "-- ")
1034// pointing to a "sqlite3_" function name.
Victor Costanab7a2452022-03-21 23:06:08[diff] [blame]1035voidOnSqliteError(SqliteErrorCode sqlite_error_code,
Victor Costan378d9842022-03-10 22:08:25[diff] [blame]1036Statement* statement,
1037constchar* sql_statement);
cpu@chromium.orgfaa604e2009-09-25 22:38:59[diff] [blame]1038
Etienne Bergeronc34759492025-06-16 15:45:17[diff] [blame]1039// Raze the database to the ground. This is the internal version called by
1040// Raze(...).
1041boolRazeInternal();
1042
Victor Costanedf48be2022-03-14 21:40:12[diff] [blame]1043// Like Execute(), but returns a SQLite result code.
Victor Costan205b96dc2021-07-21 20:27:46[diff] [blame]1044//
Victor Costanab7a2452022-03-21 23:06:08[diff] [blame]1045// This method returns SqliteResultCode::kOk or a SQLite error code. In other
1046// words, it never returns SqliteResultCode::{kDone, kRow}.
Victor Costanedf48be2022-03-14 21:40:12[diff] [blame]1047//
1048// This method is only exposed to the Database implementation. Code that uses
1049// sql::Database should not be concerned with SQLite result codes.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]1050[[nodiscard]]SqliteResultCodeExecuteAndReturnResultCode(
1051base::cstring_view sql);
Victor Costan205b96dc2021-07-21 20:27:46[diff] [blame]1052
shess@chromium.org5b96f3772010-09-28 16:30:57[diff] [blame]1053// Like |Execute()|, but retries if the database is locked.
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]1054[[nodiscard]]boolExecuteWithTimeout(base::cstring_view sql,
Daniel Cheng1ac0cad2022-01-14 00:19:53[diff] [blame]1055base::TimeDelta ms_timeout);
shess@chromium.org5b96f3772010-09-28 16:30:57[diff] [blame]1056
Victor Costan106e50072021-07-17 00:04:49[diff] [blame]1057// Implementation helper for GetUniqueStatement() and GetCachedStatement().
Evan Stadee63b8342024-06-07 15:55:23[diff] [blame]1058 scoped_refptr<StatementRef>GetStatementImpl(base::cstring_view sql,
ssid583f55e2022-04-21 19:59:00[diff] [blame]1059bool is_readonly);
shess@chromium.org2eec0a22012-07-24 01:59:58[diff] [blame]1060
shess7dbd4dee2015-10-06 17:39:16[diff] [blame]1061// Release page-cache memory if memory-mapped I/O is enabled and the database
1062// was changed. Passing true for |implicit_change_performed| allows
1063// overriding the change detection for cases like DDL (CREATE, DROP, etc),
1064// which do not participate in the total-rows-changed tracking.
1065voidReleaseCacheMemoryIfNeeded(bool implicit_change_performed);
1066
shessc8cd2a162015-10-22 20:30:46[diff] [blame]1067// Returns the results of sqlite3_db_filename(), which should match the path
1068// passed to Open().
1069base::FilePathDbPath()const;
1070
shessc8cd2a162015-10-22 20:30:46[diff] [blame]1071// Helper to collect diagnostic info for a corrupt database.
1072 std::stringCollectCorruptionInfo();
1073
Tommy C. Li7803636c2022-07-27 21:47:22[diff] [blame]1074// Helper to collect diagnostic info for errors. `diagnostics` is an optional
1075// out parameter. If `diagnostics` is defined, this method populates SOME of
1076// its fields. Some of the fields are left unmodified for the caller.
1077 std::stringCollectErrorInfo(int sqlite_error_code,
1078Statement* stmt,
1079DatabaseDiagnostics* diagnostics)const;
shessc8cd2a162015-10-22 20:30:46[diff] [blame]1080
Victor Costandc72e8d2022-03-14 18:14:51[diff] [blame]1081// The size of the memory mapping that SQLite should use for this database.
shessd90aeea82015-11-13 02:24:31[diff] [blame]1082//
Victor Costandc72e8d2022-03-14 18:14:51[diff] [blame]1083// The return value follows the semantics of "PRAGMA mmap_size". In
1084// particular, zero (0) means memory-mapping should be disabled, and the value
1085// is capped by SQLITE_MAX_MMAP_SIZE. More details at
1086// https://www.sqlite.org/pragma.html#pragma_mmap_size
1087//
1088// "Memory-mapped access" is usually shortened to "mmap", which is the name of
1089// the POSIX system call used to implement. The same principles apply on
1090// Windows, but its more-descriptive API names don't make for good shorthands.
1091//
1092// When mmap is enabled, SQLite attempts to use the memory-mapped area (by
1093// calling xFetch() in the VFS file API) instead of requesting a database page
1094// buffer from the pager and reading (via xRead() in the VFS API) into it.
1095// When this works out, the database page cache ends up only storing pages
1096// whose contents has been modified. More details at
1097// https://sqlite.org/mmap.html
1098//
1099// I/O errors on memory-mapped files result in crashes in Chrome. POSIX
1100// systems signal SIGSEGV or SIGBUS on I/O errors in mmap-ed files. Windows
1101// raises the EXECUTE_IN_PAGE_ERROR strucuted exception in this case. Chrome
1102// does not catch signals or structured exceptions.
1103//
1104// In order to avoid crashes, this method attempts to read the file using
1105// regular I/O, and returns 0 (no mmap) if it encounters any error.
1106size_tComputeMmapSizeForOpen();
shessd90aeea82015-11-13 02:24:31[diff] [blame]1107
Victor Costandc72e8d2022-03-14 18:14:51[diff] [blame]1108// Helpers for ComputeMmapSizeForOpen().
shessa62504d2016-11-07 19:26:12[diff] [blame]1109boolGetMmapAltStatus(int64_t* status);
1110boolSetMmapAltStatus(int64_t status);
1111
Victor Costandc72e8d2022-03-14 18:14:51[diff] [blame]1112// Returns a SQLite VFS interface pointer to the file storing database pages.
1113//
1114// Returns null if the database is not backed by a VFS file. This is always
Evan Stade4c7d6b32024-03-12 16:50:27[diff] [blame]1115// the case for in-memory databases.
Victor Costandc72e8d2022-03-14 18:14:51[diff] [blame]1116//
1117// This method must only be called while the database is successfully opened.
1118 sqlite3_file*GetSqliteVfsFile();
1119
Anthony Vallée-Dubois4b2977912024-11-22 16:28:51[diff] [blame]1120// Records a histogram named `name_prefix` suffixed with this database's
Etienne Bergeron98f446ed2025-01-24 16:16:22[diff] [blame]1121// histogram tag. For instance, `RecordTimingHistogram("Foo.", ...)` called on
1122// a database with the tag "Bar" will record into "Foo.Bar". This function
1123// chooses reasonable bucketing parameters for typical database operations
1124// timing and reports in microseconds.
Anthony Vallée-Dubois4b2977912024-11-22 16:28:51[diff] [blame]1125voidRecordTimingHistogram(std::string_view name_prefix,
1126base::TimeDelta timing)const;
1127
1128// Returns the name of the track in which to record this database's events
1129// based on its histogram tag.
1130 perfetto::NamedTrackGetTracingNamedTrack()const;
1131
Victor Costan554f11e2022-03-16 17:00:09[diff] [blame]1132// Will eventually be checked on all methods. See https://crbug.com/1306694
1133 SEQUENCE_CHECKER(sequence_checker_);
1134
Victor Costanbd623112018-07-18 04:17:27[diff] [blame]1135// The actual sqlite database. Will be null before Init has been called or if
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1136// Init resulted in an error.
Evan Stadeae04e1972024-02-01 17:35:53[diff] [blame]1137 raw_ptr<sqlite3> db_=nullptr;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1138
Etienne Bergeron5cada0b2025-01-22 15:45:01[diff] [blame]1139// Immutable options for the database.
1140constDatabaseOptions options_;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1141
Victor Costanc7e7f2e2018-07-18 20:07:55[diff] [blame]1142// Holds references to all cached statements so they remain active.
1143//
1144// flat_map is appropriate here because the codebase has ~400 cached
1145// statements, and each statement is at most one insertion in the map
1146// throughout a process' lifetime.
1147base::flat_map<StatementID, scoped_refptr<StatementRef>> statement_cache_;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1148
1149// A list of all StatementRefs we've given out. Each ref must register with
1150// us when it's created or destroyed. This allows us to potentially close
1151// any open statements when we encounter an error.
Arthur Sonzogni68399392024-07-09 20:36:56[diff] [blame]1152 std::set<raw_ptr<StatementRef>> open_statements_;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1153
Evan Stade416f46f12025-06-18 15:42:39[diff] [blame]1154// The number of blobs open for streaming, tracked for debugging purposes.
1155size_t outstanding_blob_count_=0;
1156
1157// When non-zero, indicates that `this` is inside `OnSqliteError()`.
1158size_t handling_error_nesting_=0;
1159
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1160// Number of currently-nested transactions.
Shubham Aggarwale2d6b60d2020-10-22 04:41:48[diff] [blame]1161int transaction_nesting_=0;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1162
1163// True if any of the currently nested transactions have been rolled back.
1164// When we get to the outermost transaction, this will determine if we do
1165// a rollback instead of a commit.
Shubham Aggarwale2d6b60d2020-10-22 04:41:48[diff] [blame]1166bool needs_rollback_=false;
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1167
shess@chromium.org35f7e5392012-07-27 19:54:50[diff] [blame]1168// True if database is open with OpenInMemory(), False if database is open
1169// with Open().
Shubham Aggarwale2d6b60d2020-10-22 04:41:48[diff] [blame]1170bool in_memory_=false;
shess@chromium.org35f7e5392012-07-27 19:54:50[diff] [blame]1171
Andrew Paseltinerd309fec2023-03-28 16:59:55[diff] [blame]1172// |true| if the Database was closed using RazeAndPoison(). Used
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]1173// to enable diagnostics to distinguish calls to never-opened
1174// databases (incorrect use of the API) from calls to once-valid
1175// databases.
Shubham Aggarwale2d6b60d2020-10-22 04:41:48[diff] [blame]1176bool poisoned_=false;
shess@chromium.org41a97c812013-02-07 02:35:38[diff] [blame]1177
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]1178// |true| if SQLite memory-mapped I/O is not desired for this database.
shess7dbd4dee2015-10-06 17:39:16[diff] [blame]1179bool mmap_disabled_;
1180
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]1181// |true| if SQLite memory-mapped I/O was enabled for this database.
shess7dbd4dee2015-10-06 17:39:16[diff] [blame]1182// Used by ReleaseCacheMemoryIfNeeded().
Shubham Aggarwale2d6b60d2020-10-22 04:41:48[diff] [blame]1183bool mmap_enabled_=false;
shess7dbd4dee2015-10-06 17:39:16[diff] [blame]1184
1185// Used by ReleaseCacheMemoryIfNeeded() to track if new changes have happened
1186// since memory was last released.
Victor Costan3657e042022-03-12 18:47:30[diff] [blame]1187int64_t total_changes_at_last_release_=0;
shess7dbd4dee2015-10-06 17:39:16[diff] [blame]1188
Victor Costance406da22021-09-20 21:01:38[diff] [blame]1189// Called when a SQLite error occurs.
1190//
1191// This callback may be null, in which case errors are handled using a default
1192// behavior.
1193//
1194// This callback must never be exposed outside this Database instance. This is
1195// a straight-forward way to guarantee that this callback will not be called
1196// after the Database instance goes out of scope. set_error_callback() makes
1197// this guarantee.
shess@chromium.orgc3881b372013-05-17 08:39:46[diff] [blame]1198ErrorCallback error_callback_;
1199
Victor Costan90dae262021-06-01 21:01:08[diff] [blame]1200// Developer-friendly database ID used in logging output and memory dumps.
shess@chromium.org210ce0af2013-05-15 09:10:39[diff] [blame]1201 std::string histogram_tag_;
shess@chromium.orgc088e3a32013-01-03 23:59:14[diff] [blame]1202
Anthony Vallée-Dubois4b2977912024-11-22 16:28:51[diff] [blame]1203// Persist the track name as a member since perfetto needs the original string
1204// for the name to remain alive (without taking ownership of it).
1205 std::string tracing_track_name_;
1206
ssid3be5b1ec2016-01-13 14:21:57[diff] [blame]1207// Stores the dump provider object when db is open.
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]1208 std::unique_ptr<DatabaseMemoryDumpProvider> memory_dump_provider_;
Dan McArdle49be9b02024-02-06 23:15:33[diff] [blame]1209
Anthony Vallée-Duboisde37202582024-12-04 18:52:30[diff] [blame]1210// If set, this callback will be invoked when an sqlite error is triggered
1211// during `OpenInternal` or `Execute`s triggered from `Open`.
1212base::RepeatingCallback<void(SqliteResultCode)>
1213 open_error_reporting_callback_;
1214
Evan Stade416f46f12025-06-18 15:42:39[diff] [blame]1215// Weak factory for tracking lifetime of `this` (as opposed to
1216// `weak_factory_`, which will also invalidate pointers if the database is
1217// closed).
1218base::WeakPtrFactory<Database> weak_factory_lifetime_tracker_{this};
1219
Dan McArdle49be9b02024-02-06 23:15:33[diff] [blame]1220// Vends WeakPtr<Database> for internal scoping helpers.
1221base::WeakPtrFactory<Database> weak_factory_{this};
brettw@chromium.orge5ffd0e42009-09-11 21:30:56[diff] [blame]1222};
1223
1224}// namespace sql
1225
Victor Costancfbfa602018-08-01 23:24:46[diff] [blame]1226#endif// SQL_DATABASE_H_

[8]ページ先頭

©2009-2025 Movatter.jp