summaryrefslogtreecommitdiff
path: root/chromium/sql
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-09-03 13:32:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-01 14:31:55 +0200
commit21ba0c5d4bf8fba15dddd97cd693bad2358b77fd (patch)
tree91be119f694044dfc1ff9fdc054459e925de9df0 /chromium/sql
parent03c549e0392f92c02536d3f86d5e1d8dfa3435ac (diff)
downloadqtwebengine-chromium-21ba0c5d4bf8fba15dddd97cd693bad2358b77fd.tar.gz
BASELINE: Update Chromium to 92.0.4515.166
Change-Id: I42a050486714e9e54fc271f2a8939223a02ae364
Diffstat (limited to 'chromium/sql')
-rw-r--r--chromium/sql/BUILD.gn2
-rw-r--r--chromium/sql/DIR_METADATA4
-rw-r--r--chromium/sql/README.md399
-rw-r--r--chromium/sql/database.cc24
-rw-r--r--chromium/sql/database.h6
-rw-r--r--chromium/sql/database_unittest.cc910
-rw-r--r--chromium/sql/initialization.cc2
-rw-r--r--chromium/sql/meta_table_unittest.cc120
-rw-r--r--chromium/sql/recover_module/module_unittest.cc443
-rw-r--r--chromium/sql/recover_module/parsing.cc12
-rw-r--r--chromium/sql/recover_module/record.cc4
-rw-r--r--chromium/sql/recover_module/table.cc16
-rw-r--r--chromium/sql/recover_module/table.h2
-rw-r--r--chromium/sql/recovery_unittest.cc562
-rw-r--r--chromium/sql/sandboxed_vfs.cc2
-rw-r--r--chromium/sql/sandboxed_vfs.h4
-rw-r--r--chromium/sql/sql_memory_dump_provider.h6
-rw-r--r--chromium/sql/sql_memory_dump_provider_unittest.cc32
-rw-r--r--chromium/sql/sqlite_features_unittest.cc172
-rw-r--r--chromium/sql/statement.cc4
-rw-r--r--chromium/sql/statement_unittest.cc53
-rw-r--r--chromium/sql/transaction_unittest.cc68
22 files changed, 1720 insertions, 1127 deletions
diff --git a/chromium/sql/BUILD.gn b/chromium/sql/BUILD.gn
index c7fd00f9950..e589f9a0994 100644
--- a/chromium/sql/BUILD.gn
+++ b/chromium/sql/BUILD.gn
@@ -121,8 +121,6 @@ test("sql_unittests") {
"test/paths.cc",
"test/paths.h",
"test/run_all_unittests.cc",
- "test/sql_test_base.cc",
- "test/sql_test_base.h",
"test/sql_test_suite.cc",
"test/sql_test_suite.h",
"transaction_unittest.cc",
diff --git a/chromium/sql/DIR_METADATA b/chromium/sql/DIR_METADATA
index 35767266bdf..0e619390a7a 100644
--- a/chromium/sql/DIR_METADATA
+++ b/chromium/sql/DIR_METADATA
@@ -1,10 +1,10 @@
# Metadata information for this directory.
#
# For more information on DIR_METADATA files, see:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/README.md
#
# For the schema of this file, see Metadata message:
-# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+# https://source.chromium.org/chromium/infra/infra/+/main:go/src/infra/tools/dirmd/proto/dir_metadata.proto
monorail {
component: "Internals>Storage"
diff --git a/chromium/sql/README.md b/chromium/sql/README.md
new file mode 100644
index 00000000000..3303502f8dd
--- /dev/null
+++ b/chromium/sql/README.md
@@ -0,0 +1,399 @@
+# SQLite abstraction layer
+
+
+## SQLite for system designers
+
+[SQLite](https://www.sqlite.org/) is a
+[relational database management system (RDBMS)](https://en.wikipedia.org/wiki/Relational_database#RDBMS)
+that [supports most of SQL](https://www.sqlite.org/lang.html).
+
+SQLite is architected as a library that can be embedded in another application,
+such as Chrome. SQLite runs in the application's process, and shares its memory
+and other resources. This is similar to embedded databases like
+[LevelDB](https://github.com/google/leveldb) and
+[BerkeleyDB](https://en.wikipedia.org/wiki/Berkeley_DB). By contrast, most
+popular RDMBSes, like [PostgreSQL](https://www.postgresql.org/) and
+[MySQL](https://www.mysql.com/), are structured as standalone server processes
+that accept queries from client processes.
+
+TODO: Explain the process model and locking
+
+TODO: Explain Chrome decisions -- exclusive locking, full per-feature isolation
+(separate databases and page caches)
+
+
+## SQLite for database designers
+
+The section summarizes aspects of SQLite that are relevant to schema and
+query design, and may be surprising to readers with prior experience in other
+popular SQL database systems, such as
+[PostgreSQL](https://www.postgresql.org/) and [MySQL](https://www.mysql.com/).
+
+
+### Data types
+
+SQLite stores data using [5 major types](https://www.sqlite.org/datatype3.html),
+which are summarized below.
+
+1. NULL is a special type for the `NULL` value.
+
+2. INTEGER represents big-endian twos-complement integers. Boolean values
+ (`TRUE` and `FALSE`) are represented as the integer values 1 and 0.
+
+3. REAL represents IEEE 754-2008 64-bit floating point numbers.
+
+4. TEXT represents strings (sequences of characters) encoded using a
+ [supported SQLite encoding](https://www.sqlite.org/c3ref/c_any.html). These
+ values are
+ [sorted](https://www.sqlite.org/datatype3.html#sort_order) according to
+ [a collating sequence](https://www.sqlite.org/datatype3.html#collation) or
+ [a collating function](https://www.sqlite.org/c3ref/create_collation.html).
+
+5. BLOB represents sequences of bytes that are opaque to SQLite. These values are
+ sorted using the bitwise binary comparison offered by
+ [memcmp](https://en.cppreference.com/w/cpp/string/byte/memcmp).
+
+SQLite stores index keys and row values (records / tuples) using
+[a tightly packed format](https://sqlite.org/fileformat2.html#record_format)
+that makes heavy use of [varints](https://sqlite.org/fileformat2.html#varint)
+and variable-length fields. The column types have almost no influence on the
+encoding of values. This has the following consequences.
+
+* All SQL integer types, such as `TINYINT` and `BIGINT`, are treated as aliases
+ for `INTEGER`.
+* All SQL non-integer numeric types, such as `DECIMAL`, `FLOAT`, and
+ `DOUBLE PRECISION` are treated as aliases for `REAL`.
+* Numeric precision and scale specifiers, such as `DECIMAL(5,2)` are ignored.
+* All string types, such as `CHAR`, `CHARACTER VARYING`, `VARCHAR`, and `CLOB`,
+ are treated as aliases for `TEXT`.
+* Maximum string length specifiers, such as `CHAR(255)` are ignored.
+
+SQLite uses clever heuristics, called
+[type affinity](https://www.sqlite.org/datatype3.html#type_affinity),
+to map SQL column types such as `VARCHAR` to the major types above.
+
+Chrome database schemas should avoid type affinity, and should not include any
+information ignored by SQLite.
+
+
+### Indexing
+
+SQLite [uses B-trees](https://www.sqlite.org/fileformat2.html#pages) to store
+both table and index data.
+
+The exclusive use of B-trees reduces the amount of schema design decisions.
+Notable examples:
+
+* There is no equivalent to
+ [PostgreSQL's index types](https://www.postgresql.org/docs/13/indexes-types.html).
+ In particular, since there are no hashed indexes, the design does not need to
+ consider whether the index only needs to support equality queries, as opposed
+ to greater/smaller than comparisons.
+
+* There is no equivalent to
+ [PostgreSQL's table access methods](https://www.postgresql.org/docs/13/tableam.html).
+ Each table is clustered by a primary key index, which is implicitly stored in
+ the table's B-tree.
+
+By default, table rows (records / tuples) are stored in a B-tree keyed by
+[rowid](https://sqlite.org/lang_createtable.html#rowid), an automatically
+assigned 64-bit integer key. Effectively, these tables are clustered by rowid,
+which acts as an implicit primary key. Opting out of this SQLite-specific
+default requires appending
+[`WITHOUT ROWID`](https://sqlite.org/withoutrowid.html) to the `CREATE TABLE`
+instruction.
+
+SQLite's [B-tree page format](https://sqlite.org/fileformat2.html#b_tree_pages)
+has optimized special cases for tables clustered by rowid. This makes rowid the
+most efficient [surrogate key](https://en.wikipedia.org/wiki/Surrogate_key)
+implementation in SQLite. To make this optimization easier to use, any column
+that is a primary key and has an `INTEGER` type is considered an alias for
+rowid.
+
+
+### Query processing
+
+[At a high level](https://www.sqlite.org/arch.html), SQLite compiles SQL queries
+into bytecode executed by a virtual machine called the VDBE, or
+[the bytecode engine](https://www.sqlite.org/opcode.html). A compiled query can
+be executed multiple times, amortizing the costs of query parsing and planning.
+Chrome's SQLite abstraction layer makes it easy to use compiled queries.
+
+The following SQLite documentation pages cover the query planner and
+optimizer.
+
+1. [query planner overview](https://www.sqlite.org/queryplanner.html)
+2. [query optimizer overview](https://www.sqlite.org/optoverview.html)
+3. [`EXPLAIN QUERY PLAN` output description](https://www.sqlite.org/eqp.html)
+
+TODO: Present a simplified model that's sufficient for most database design.
+
+
+## General advice
+
+The following pieces of advice usually come up in code reviews.
+
+### SQL style
+
+SQLite queries are usually embedded as string literals in C++ code. The
+advice here has the following goals.
+
+1. Easy to read queries. The best defense against subtle bugs is making the
+ queries very easy to read, so that any bugs become obvious at code review
+ time. SQL string literals don't benefit from our code analysis
+ infrastructure, so the only lines of defense against bugs are testing and
+ code review.
+
+2. Simplify crash debugging. We will always have a low volume of non-actionable
+ crash reports, because Chrome runs on billions of devices, some of which have
+ faulty RAM or processors.
+
+3. No unnecessary performance overheads. The C++ optimizer doesn't understand
+ SQL query literals, so the queries end up as written in the Chrome binary.
+ Extra characters cost binary size, as well as CPU time (which turns into
+ battery usage) during query parsing.
+
+4. Match the embedding language (C++) style guide. This reduces the mental
+ context switch overhead for folks who write and/or review C++ code that
+ contains SQL.
+
+Format statements like so.
+
+```cc
+ static constexpr char kOriginInfoSql[] =
+ // clang-format off
+ "CREATE TABLE origin_infos("
+ "origin TEXT NOT NULL,"
+ "last_modified INTEGER NOT NULL,"
+ "secure INTEGER NOT NULL)";
+ // clang-format on
+
+ static constexpr char kInsertSql[] =
+ // clang-format off
+ "INSERT INTO infos(origin,last_modified,secure) "
+ "VALUES (?,?,?)";
+ // clang-format on
+
+ static constexpr char kSelectSql[] =
+ // clang-format off
+ "SELECT origin,last_modified,secure FROM origins "
+ "WHERE last_modified > ? "
+ "ORDER BY last_modified";
+ // clang-format on
+```
+
+* SQLite keywords should use ALL CAPS. This makes SQL query literals easier to
+ distinguish and search for.
+
+* Identifiers, such as table and row names, should use snake_case.
+
+* Identifiers, keywords, and parameter placeholders (`?`) should be separated by
+ exactly one character. Separators may be spaces (` `), commas (`,`), or
+ parentheses (`(`, `)`).
+
+* Statement-ending semicolons (`;`) are omitted.
+
+* SQL statements are stored in variables typed `static constexpr char[]`, or in
+ string literals passed directly to methods.
+
+* [`INSERT` statements](https://sqlite.org/lang_insert.html) should list all the
+ table columns by name, in the same order as the corresponding `CREATE TABLE`
+ statements.
+
+* [`SELECT` statements](https://sqlite.org/lang_select.html) should list the
+ desired table columns by name, in the same order as the corresponding
+ `CREATE TABLE` statements. `SELECT *` is strongly discouraged, at least until
+ we have schema checks on database opens.
+
+* [`SELECT` statements](https://sqlite.org/lang_select.html) that retrieve more
+ than one row should include an
+ [`ORDER BY` clause](https://sqlite.org/lang_select.html#the_order_by_clause)
+ to clarify the implicit ordering.
+ * SELECTs whose outer loop is a table search or table scan implicitly order
+ results by [rowid](https://sqlite.org/lang_createtable.html#rowid) or, in
+ the case of [`WITHOUT ROWID`](https://sqlite.org/withoutrowid.html) tables,
+ by the table's primary key.
+ * SELECTs whose outer loop is an index scan or index search order results
+ according to that index.
+
+* [`CREATE INDEX` statements](https://sqlite.org/lang_createindex.html) should
+ immediately follow the
+ [`CREATE TABLE` statement](https://sqlite.org/lang_createtable.html) for the
+ indexed table.
+
+* Explicit `CREATE UNIQUE INDEX` statements should be preferred to
+ [`UNIQUE` constraints on `CREATE TABLE`](https://sqlite.org/lang_createtable.html#unique_constraints).
+
+* Values must either be embedded in the SQL statement string literal, or bound
+ using [parameters](https://www.sqlite.org/lang_expr.html#varparam).
+
+* Parameter placeholders should always use the `?` syntax. Alternative syntaxes,
+ such as `?NNN` or `:AAAA`, have few benefits in a codebase where the `Bind`
+ statements are right next to the queries, and are less known to readers.
+
+* Do not execute multiple SQL statements (e.g., by calling `Step()` or `Run()`
+ on `sql::Statement`) on the same C++ line. It's difficult to get more than
+ line numbers from crash reports' stack traces.
+
+
+### Schema style
+
+Column types should only be one of the the SQLite storage types (`INTEGER`,
+`REAL`, `TEXT`, `BLOB`), so readers can avoid reasoning about SQLite's type
+affinity.
+
+Columns that will store boolean values should have the `INTEGER` type.
+
+Columns that will store `base::Time` values should have the `INTEGER` type.
+Values should be serialized using `sql::Statement::BindTime()` and deserialized
+using `sql::Statement::ColumnTime()`.
+
+Column types should not include information ignored by SQLite, such as numeric
+precision or scale specifiers, or string length specifiers.
+
+Columns should have the `NOT NULL` constraint whenever possible. This saves
+maintainers from having to reason about the less intuitive cases of
+[`NULL` handling](https://sqlite.org/nulls.html).
+
+Columns should avoid `DEFAULT` values. This moves the burden of checking that
+`INSERT` statements aren't missing any columns from the code reviewer to SQLite.
+
+Surrogate primary keys should use the column type `INTEGER PRIMARY KEY`, to take
+advantage of SQLite's rowid optimizations.
+[`AUTOINCREMENT`](https://www.sqlite.org/autoinc.html) should only be used where
+primary key reuse would be unacceptable.
+
+
+### Discouraged features
+
+#### PRAGMA statements
+
+[`PRAGMA` statements](https://www.sqlite.org/pragma.html) should never be used
+directly. Chrome's SQLite abstraction layer should be modified to support the
+desired effects instead.
+
+Direct `PRAGMA` use limits our ability to customize and secure our SQLite build.
+`PRAGMA` statements may turn on code paths with less testing / fuzzing coverage.
+Furthermore, some `PRAGMA` statements invalidate previously compiled queries,
+reducing the efficiency of Chrome's compiled query cache.
+
+#### Virtual tables
+
+[`CREATE VIRTUAL TABLE` statements](https://www.sqlite.org/vtab.html) should not
+be used. The desired functionality should be implemented in C++, and access
+storage using standard SQL statements.
+
+Virtual tables are [SQLite's module system](https://www.sqlite.org/vtab.html).
+SQL statements on virtual tables are essentially running arbitrary code, which
+makes them very difficult to reason about and maintain. Furthermore, the virtual
+table implementations don't receive the same level of fuzzing coverage as the
+SQLite core.
+
+Chrome's SQLite build has virtual table functionality reduced to the minimum
+needed to support [FTS3](https://www.sqlite.org/fts3.html) in WebSQL, and an
+internal feature.
+[SQLite's run-time loading mechanism](https://www.sqlite.org/loadext.html) is
+disabled, and most
+[built-in virtual tables](https://www.sqlite.org/vtablist.html) are disabled as
+well.
+
+After
+[WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we plan
+to disable SQLite's virtual table support using
+[SQLITE_OMIT_VIRTUALTABLE](https://sqlite.org/compile.html#omit_virtualtable).
+
+#### Foreign key constraints
+
+[SQL foreign key constraints](https://sqlite.org/foreignkeys.html) should not be
+used. All data validation should be performed using explicit `SELECT` statements
+(generally wrapped as helper methods) inside transactions. Cascading deletions
+should be performed using explicit `DELETE` statements inside transactions.
+
+Chrome features cannot rely on foreign key enforcement, due to the
+possibility of data corruption. Furthermore, foreign key constraints make it
+more difficult to reason about system behavior (Chrome feature code + SQLite)
+when the database gets corrupted. Foreign key constraints also make it more
+difficult to reason about query performance.
+
+After
+[WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we plan
+to disable SQLite's foreign key support using
+[SQLITE_OMIT_FOREIGN_KEY](https://sqlite.org/compile.html#omit_foreign_key).
+
+#### CHECK constraints
+
+[SQL CHECK constraints](https://sqlite.org/lang_createtable.html#check_constraints)
+should not be used, for the same reasons as foreign key constraints. The
+equivalent checks should be performed in C++, typically using `DCHECK`.
+
+After
+[WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we plan
+to disable SQLite's CHECK constraint support using
+[SQLITE_OMIT_CHECK](https://sqlite.org/compile.html#omit_check).
+
+#### Triggers
+
+[SQL triggers](https://sqlite.org/lang_createtrigger.html) should not be used.
+
+Triggers significantly increase the difficulty of reviewing and maintaining
+Chrome features that use them.
+
+After [WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we
+plan to disable SQLite's trigger support using
+[SQLITE_OMIT_TRIGGER](https://sqlite.org/compile.html#omit_trigger).
+
+#### Common Table Expressions
+
+[SQL Common Table Expressions (CTEs)](https://sqlite.org/lang_with.html) should
+not be used. Chrome's SQL schemas and queries should be simple enough that
+the factoring afforded by
+[ordinary CTEs](https://sqlite.org/lang_with.html#ordinary_common_table_expressions)
+is not necessary.
+[Recursive CTEs](https://sqlite.org/lang_with.html#recursive_common_table_expressions)
+should be implemented in C++.
+
+Common Table Expressions do not open up any query optimizations that would not
+be available otherwise, and make it more difficult to review / analyze queries.
+
+#### Views
+
+SQL views, managed by the
+[`CREATE VIEW` statement](https://www.sqlite.org/lang_createview.html) and the
+[`DROP VIEW` statement](https://www.sqlite.org/lang_dropview.html), should not
+be used. Chrome's SQL schemas and queries should be simple enough that the
+factoring afforded by views is not necessary.
+
+Views are syntactic sugar, and do not open up any new SQL capabilities. SQL
+statements on views are more difficult to understand and maintain, because of
+the extra layer of indirection.
+
+After
+[WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we plan
+to disable SQLite's VIEW support using
+[SQLITE_OMIT_VIEW](https://www.sqlite.org/compile.html#omit_view).
+
+#### Compound SELECT statements
+
+[Compound SELECT statements](https://www.sqlite.org/lang_select.html#compound_select_statements)
+should not be used. Such statements should be broken down into
+[simple SELECT statements](https://www.sqlite.org/lang_select.html#simple_select_processing),
+and the operators `UNION`, `UNION ALL`, `INTERSECT` and `EXCEPT` should be
+implemented in C++.
+
+A single compound SELECT statement is more difficult to review and properly
+unit-test than the equivalent collection of simple SELECT statements.
+Furthermore, the compound SELECT statement operators can be implemented more efficiently in C++ than in SQLite's bytecode interpreter (VDBE).
+
+After
+[WebSQL](https://www.w3.org/TR/webdatabase/) is removed from Chrome, we plan
+to disable SQLite's compound SELECT support using
+[SQLITE_OMIT_COMPOUND_SELECT](https://www.sqlite.org/compile.html#omit_compound_select).
+
+#### ATTACH DATABASE statements
+
+[`ATTACH DATABASE` statements](https://www.sqlite.org/lang_attach.html) should
+not be used. Each Chrome feature should store its data in a single database.
+Chrome code should not assume that transactions across multiple databases are
+atomic.
+
+We plan to remove all existing `ATTACH DATABASE` use from Chrome.
diff --git a/chromium/sql/database.cc b/chromium/sql/database.cc
index 73fff33cd6e..46ce567cfe6 100644
--- a/chromium/sql/database.cc
+++ b/chromium/sql/database.cc
@@ -222,7 +222,7 @@ void Database::StatementRef::Close(bool forced) {
// allowing disk access.
// TODO(paivanof@gmail.com): This should move to the beginning
// of the function. http://crbug.com/136655.
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
sqlite3_finalize(stmt_);
stmt_ = nullptr;
@@ -315,7 +315,7 @@ void Database::CloseInternal(bool forced) {
// will happen on thread not allowing disk access.
// TODO(paivanof@gmail.com): This should move to the beginning
// of the function. http://crbug.com/136655.
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
// Resetting acquires a lock to ensure no dump is happening on the database
@@ -359,7 +359,7 @@ void Database::Preload() {
return;
}
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
// Maximum number of bytes that will be prefetched from the database.
@@ -649,7 +649,7 @@ bool Database::SetMmapAltStatus(int64_t status) {
size_t Database::GetAppropriateMmapSize() {
TRACE_EVENT0("sql", "Database::GetAppropriateMmapSize");
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
// How much to map if no errors are found. 50MB encompasses the 99th
@@ -794,7 +794,7 @@ void Database::TrimMemory() {
bool Database::Raze() {
TRACE_EVENT0("sql", "Database::Raze");
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
if (!db_) {
@@ -1147,7 +1147,7 @@ int Database::ExecuteAndReturnErrorCode(const char* sql) {
return SQLITE_ERROR;
}
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
int rc = SQLITE_OK;
@@ -1270,7 +1270,7 @@ scoped_refptr<Database::StatementRef> Database::GetStatementImpl(
if (!db_)
return base::MakeRefCounted<StatementRef>(nullptr, nullptr, poisoned_);
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
// TODO(pwnall): Cached statements (but not unique statements) should be
@@ -1319,7 +1319,7 @@ std::string Database::GetSchema() const {
}
bool Database::IsSQLValid(const char* sql) {
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
if (!db_) {
DCHECK(poisoned_) << "Illegal use of Database without a db";
@@ -1383,7 +1383,9 @@ int64_t Database::GetLastInsertRowId() const {
DCHECK(poisoned_) << "Illegal use of Database without a db";
return 0;
}
- return sqlite3_last_insert_rowid(db_);
+ int64_t last_rowid = sqlite3_last_insert_rowid(db_);
+ DCHECK(last_rowid != 0) << "No successful INSERT in a table with ROWID";
+ return last_rowid;
}
int Database::GetLastChangeCount() const {
@@ -1453,7 +1455,7 @@ bool Database::OpenInternal(const std::string& file_name,
return false;
}
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
EnsureSqliteInitialized();
@@ -1822,7 +1824,7 @@ bool Database::UseWALMode() const {
}
bool Database::CheckpointDatabase() {
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
static const char* kMainDb = "main";
diff --git a/chromium/sql/database.h b/chromium/sql/database.h
index 35601a48e1d..93906e65b32 100644
--- a/chromium/sql/database.h
+++ b/chromium/sql/database.h
@@ -21,12 +21,12 @@
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
-#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/threading/scoped_blocking_call.h"
#include "sql/internal_api_token.h"
#include "sql/sql_features.h"
#include "sql/statement_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
struct sqlite3;
struct sqlite3_stmt;
@@ -580,7 +580,7 @@ class COMPONENT_EXPORT(SQL) Database {
// declare its blocking execution scope (see https://www.crbug/934302).
void InitScopedBlockingCall(
const base::Location& from_here,
- base::Optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
+ absl::optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
if (!in_memory_)
scoped_blocking_call->emplace(from_here, base::BlockingType::MAY_BLOCK);
}
@@ -650,7 +650,7 @@ class COMPONENT_EXPORT(SQL) Database {
// declare its blocking execution scope (see https://www.crbug/934302).
void InitScopedBlockingCall(
const base::Location& from_here,
- base::Optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
+ absl::optional<base::ScopedBlockingCall>* scoped_blocking_call) const {
if (database_)
database_->InitScopedBlockingCall(from_here, scoped_blocking_call);
}
diff --git a/chromium/sql/database_unittest.cc b/chromium/sql/database_unittest.cc
index 9ae6a176e67..c2d65167d96 100644
--- a/chromium/sql/database_unittest.cc
+++ b/chromium/sql/database_unittest.cc
@@ -2,21 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "sql/database.h"
+
#include <stddef.h>
#include <stdint.h>
#include "base/bind.h"
#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "base/logging.h"
-#include "base/macros.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/gtest_util.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
-#include "sql/database.h"
#include "sql/database_memory_dump_provider.h"
#include "sql/meta_table.h"
#include "sql/sql_features.h"
@@ -24,7 +23,6 @@
#include "sql/test/database_test_peer.h"
#include "sql/test/error_callback_support.h"
#include "sql/test/scoped_error_expecter.h"
-#include "sql/test/sql_test_base.h"
#include "sql/test/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
@@ -37,9 +35,9 @@ using sql::test::ExecuteWithResult;
// Helper to return the count of items in sqlite_master. Return -1 in
// case of error.
-int SqliteMasterCount(sql::Database* db) {
+int SqliteMasterCount(Database* db) {
const char* kMasterCount = "SELECT COUNT(*) FROM sqlite_master";
- sql::Statement s(db->GetUniqueStatement(kMasterCount));
+ Statement s(db->GetUniqueStatement(kMasterCount));
return s.Step() ? s.ColumnInt(0) : -1;
}
@@ -48,7 +46,7 @@ int SqliteMasterCount(sql::Database* db) {
// explicitly having the ref count live longer than the object.
class RefCounter {
public:
- RefCounter(size_t* counter) : counter_(counter) { (*counter_)++; }
+ explicit RefCounter(size_t* counter) : counter_(counter) { (*counter_)++; }
RefCounter(const RefCounter& other) : counter_(other.counter_) {
(*counter_)++;
}
@@ -61,24 +59,24 @@ class RefCounter {
};
// Empty callback for implementation of ErrorCallbackSetHelper().
-void IgnoreErrorCallback(int error, sql::Statement* stmt) {}
+void IgnoreErrorCallback(int error, Statement* stmt) {}
-void ErrorCallbackSetHelper(sql::Database* db,
+void ErrorCallbackSetHelper(Database* db,
size_t* counter,
const RefCounter& r,
int error,
- sql::Statement* stmt) {
+ Statement* stmt) {
// The ref count should not go to zero when changing the callback.
EXPECT_GT(*counter, 0u);
db->set_error_callback(base::BindRepeating(&IgnoreErrorCallback));
EXPECT_GT(*counter, 0u);
}
-void ErrorCallbackResetHelper(sql::Database* db,
+void ErrorCallbackResetHelper(Database* db,
size_t* counter,
const RefCounter& r,
int error,
- sql::Statement* stmt) {
+ Statement* stmt) {
// The ref count should not go to zero when clearing the callback.
EXPECT_GT(*counter, 0u);
db->reset_error_callback();
@@ -86,10 +84,10 @@ void ErrorCallbackResetHelper(sql::Database* db,
}
// Handle errors by blowing away the database.
-void RazeErrorCallback(sql::Database* db,
+void RazeErrorCallback(Database* db,
int expected_error,
int error,
- sql::Statement* stmt) {
+ Statement* stmt) {
// Nothing here needs extended errors at this time.
EXPECT_EQ(expected_error, expected_error & 0xff);
EXPECT_EQ(expected_error, error & 0xff);
@@ -106,23 +104,36 @@ class ScopedUmaskSetter {
}
~ScopedUmaskSetter() { umask(old_umask_); }
+ ScopedUmaskSetter(const ScopedUmaskSetter&) = delete;
+ ScopedUmaskSetter& operator=(const ScopedUmaskSetter&) = delete;
+
private:
mode_t old_umask_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedUmaskSetter);
};
#endif // defined(OS_POSIX)
} // namespace
// We use the parameter to run all tests with WAL mode on and off.
-class SQLDatabaseTest : public SQLTestBase,
+class SQLDatabaseTest : public testing::Test,
public testing::WithParamInterface<bool> {
public:
- SQLDatabaseTest() : SQLTestBase(GetDBOptions()) {}
- explicit SQLDatabaseTest(DatabaseOptions options) : SQLTestBase(options) {}
+ enum class OverwriteType {
+ kTruncate,
+ kOverwrite,
+ };
+
+ ~SQLDatabaseTest() override = default;
+
+ void SetUp() override {
+ db_ = std::make_unique<Database>(GetDBOptions());
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ db_path_ = temp_dir_.GetPath().AppendASCII("database_test.sqlite");
+ ASSERT_TRUE(db_->Open(db_path_));
+ }
- sql::DatabaseOptions GetDBOptions() {
- sql::DatabaseOptions options;
+ DatabaseOptions GetDBOptions() {
+ DatabaseOptions options;
options.wal_mode = IsWALEnabled();
// TODO(crbug.com/1120969): Remove after switching to exclusive mode on by
// default.
@@ -135,186 +146,211 @@ class SQLDatabaseTest : public SQLTestBase,
#endif // defined(OS_FUCHSIA)
return options;
}
+
bool IsWALEnabled() { return GetParam(); }
+
+ bool TruncateDatabase() {
+ base::File file(db_path_,
+ base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+ return file.SetLength(0);
+ }
+
+ bool OverwriteDatabaseHeader(OverwriteType type) {
+ base::File file(db_path_,
+ base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+ if (type == OverwriteType::kTruncate) {
+ if (!file.SetLength(0))
+ return false;
+ }
+
+ static constexpr char kText[] = "Now is the winter of our discontent.";
+ constexpr int kTextBytes = sizeof(kText) - 1;
+ return file.Write(0, kText, kTextBytes) == kTextBytes;
+ }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ base::FilePath db_path_;
+ std::unique_ptr<Database> db_;
};
TEST_P(SQLDatabaseTest, Execute) {
// Valid statement should return true.
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
+ EXPECT_EQ(SQLITE_OK, db_->GetErrorCode());
// Invalid statement should fail.
ASSERT_EQ(SQLITE_ERROR,
- db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
- EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
+ db_->ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
+ EXPECT_EQ(SQLITE_ERROR, db_->GetErrorCode());
}
TEST_P(SQLDatabaseTest, ExecuteWithErrorCode) {
ASSERT_EQ(SQLITE_OK,
- db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
- ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
- ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(
+ db_->ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
+ ASSERT_EQ(SQLITE_ERROR, db_->ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
+ ASSERT_EQ(SQLITE_ERROR, db_->ExecuteAndReturnErrorCode(
"INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
}
TEST_P(SQLDatabaseTest, CachedStatement) {
- sql::StatementID id1 = SQL_FROM_HERE;
- sql::StatementID id2 = SQL_FROM_HERE;
+ StatementID id1 = SQL_FROM_HERE;
+ StatementID id2 = SQL_FROM_HERE;
static const char kId1Sql[] = "SELECT a FROM foo";
static const char kId2Sql[] = "SELECT b FROM foo";
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
sqlite3_stmt* raw_id1_statement;
sqlite3_stmt* raw_id2_statement;
{
- scoped_refptr<sql::Database::StatementRef> ref_from_id1 =
- db().GetCachedStatement(id1, kId1Sql);
+ scoped_refptr<Database::StatementRef> ref_from_id1 =
+ db_->GetCachedStatement(id1, kId1Sql);
raw_id1_statement = ref_from_id1->stmt();
- sql::Statement from_id1(std::move(ref_from_id1));
+ Statement from_id1(std::move(ref_from_id1));
ASSERT_TRUE(from_id1.is_valid());
ASSERT_TRUE(from_id1.Step());
EXPECT_EQ(12, from_id1.ColumnInt(0));
- scoped_refptr<sql::Database::StatementRef> ref_from_id2 =
- db().GetCachedStatement(id2, kId2Sql);
+ scoped_refptr<Database::StatementRef> ref_from_id2 =
+ db_->GetCachedStatement(id2, kId2Sql);
raw_id2_statement = ref_from_id2->stmt();
EXPECT_NE(raw_id1_statement, raw_id2_statement);
- sql::Statement from_id2(std::move(ref_from_id2));
+ Statement from_id2(std::move(ref_from_id2));
ASSERT_TRUE(from_id2.is_valid());
ASSERT_TRUE(from_id2.Step());
EXPECT_EQ(13, from_id2.ColumnInt(0));
}
{
- scoped_refptr<sql::Database::StatementRef> ref_from_id1 =
- db().GetCachedStatement(id1, kId1Sql);
+ scoped_refptr<Database::StatementRef> ref_from_id1 =
+ db_->GetCachedStatement(id1, kId1Sql);
EXPECT_EQ(raw_id1_statement, ref_from_id1->stmt())
<< "statement was not cached";
- sql::Statement from_id1(std::move(ref_from_id1));
+ Statement from_id1(std::move(ref_from_id1));
ASSERT_TRUE(from_id1.is_valid());
ASSERT_TRUE(from_id1.Step()) << "cached statement was not reset";
EXPECT_EQ(12, from_id1.ColumnInt(0));
- scoped_refptr<sql::Database::StatementRef> ref_from_id2 =
- db().GetCachedStatement(id2, kId2Sql);
+ scoped_refptr<Database::StatementRef> ref_from_id2 =
+ db_->GetCachedStatement(id2, kId2Sql);
EXPECT_EQ(raw_id2_statement, ref_from_id2->stmt())
<< "statement was not cached";
- sql::Statement from_id2(std::move(ref_from_id2));
+ Statement from_id2(std::move(ref_from_id2));
ASSERT_TRUE(from_id2.is_valid());
ASSERT_TRUE(from_id2.Step()) << "cached statement was not reset";
EXPECT_EQ(13, from_id2.ColumnInt(0));
}
- EXPECT_DCHECK_DEATH(db().GetCachedStatement(id1, kId2Sql))
+ EXPECT_DCHECK_DEATH(db_->GetCachedStatement(id1, kId2Sql))
<< "Using a different SQL with the same statement ID should DCHECK";
- EXPECT_DCHECK_DEATH(db().GetCachedStatement(id2, kId1Sql))
+ EXPECT_DCHECK_DEATH(db_->GetCachedStatement(id2, kId1Sql))
<< "Using a different SQL with the same statement ID should DCHECK";
}
TEST_P(SQLDatabaseTest, IsSQLValidTest) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
- ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_->IsSQLValid("SELECT a FROM foo"));
+ ASSERT_FALSE(db_->IsSQLValid("SELECT no_exist FROM foo"));
}
TEST_P(SQLDatabaseTest, DoesTableExist) {
- EXPECT_FALSE(db().DoesTableExist("foo"));
- EXPECT_FALSE(db().DoesTableExist("foo_index"));
+ EXPECT_FALSE(db_->DoesTableExist("foo"));
+ EXPECT_FALSE(db_->DoesTableExist("foo_index"));
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- ASSERT_TRUE(db().Execute("CREATE INDEX foo_index ON foo (a)"));
- EXPECT_TRUE(db().DoesTableExist("foo"));
- EXPECT_FALSE(db().DoesTableExist("foo_index"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_->Execute("CREATE INDEX foo_index ON foo (a)"));
+ EXPECT_TRUE(db_->DoesTableExist("foo"));
+ EXPECT_FALSE(db_->DoesTableExist("foo_index"));
// DoesTableExist() is case-sensitive.
- EXPECT_FALSE(db().DoesTableExist("Foo"));
- EXPECT_FALSE(db().DoesTableExist("FOO"));
+ EXPECT_FALSE(db_->DoesTableExist("Foo"));
+ EXPECT_FALSE(db_->DoesTableExist("FOO"));
}
TEST_P(SQLDatabaseTest, DoesIndexExist) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- EXPECT_FALSE(db().DoesIndexExist("foo"));
- EXPECT_FALSE(db().DoesIndexExist("foo_ubdex"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
+ EXPECT_FALSE(db_->DoesIndexExist("foo"));
+ EXPECT_FALSE(db_->DoesIndexExist("foo_ubdex"));
- ASSERT_TRUE(db().Execute("CREATE INDEX foo_index ON foo (a)"));
- EXPECT_TRUE(db().DoesIndexExist("foo_index"));
- EXPECT_FALSE(db().DoesIndexExist("foo"));
+ ASSERT_TRUE(db_->Execute("CREATE INDEX foo_index ON foo (a)"));
+ EXPECT_TRUE(db_->DoesIndexExist("foo_index"));
+ EXPECT_FALSE(db_->DoesIndexExist("foo"));
// DoesIndexExist() is case-sensitive.
- EXPECT_FALSE(db().DoesIndexExist("Foo_index"));
- EXPECT_FALSE(db().DoesIndexExist("Foo_Index"));
- EXPECT_FALSE(db().DoesIndexExist("FOO_INDEX"));
+ EXPECT_FALSE(db_->DoesIndexExist("Foo_index"));
+ EXPECT_FALSE(db_->DoesIndexExist("Foo_Index"));
+ EXPECT_FALSE(db_->DoesIndexExist("FOO_INDEX"));
}
TEST_P(SQLDatabaseTest, DoesViewExist) {
- EXPECT_FALSE(db().DoesViewExist("voo"));
- ASSERT_TRUE(db().Execute("CREATE VIEW voo (a) AS SELECT 1"));
- EXPECT_FALSE(db().DoesIndexExist("voo"));
- EXPECT_FALSE(db().DoesTableExist("voo"));
- EXPECT_TRUE(db().DoesViewExist("voo"));
+ EXPECT_FALSE(db_->DoesViewExist("voo"));
+ ASSERT_TRUE(db_->Execute("CREATE VIEW voo (a) AS SELECT 1"));
+ EXPECT_FALSE(db_->DoesIndexExist("voo"));
+ EXPECT_FALSE(db_->DoesTableExist("voo"));
+ EXPECT_TRUE(db_->DoesViewExist("voo"));
// DoesTableExist() is case-sensitive.
- EXPECT_FALSE(db().DoesViewExist("Voo"));
- EXPECT_FALSE(db().DoesViewExist("VOO"));
+ EXPECT_FALSE(db_->DoesViewExist("Voo"));
+ EXPECT_FALSE(db_->DoesViewExist("VOO"));
}
TEST_P(SQLDatabaseTest, DoesColumnExist) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
- EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
- EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
+ EXPECT_FALSE(db_->DoesColumnExist("foo", "bar"));
+ EXPECT_TRUE(db_->DoesColumnExist("foo", "a"));
- ASSERT_FALSE(db().DoesTableExist("bar"));
- EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
+ ASSERT_FALSE(db_->DoesTableExist("bar"));
+ EXPECT_FALSE(db_->DoesColumnExist("bar", "b"));
// SQLite resolves table/column names without case sensitivity.
- EXPECT_TRUE(db().DoesColumnExist("FOO", "A"));
- EXPECT_TRUE(db().DoesColumnExist("FOO", "a"));
- EXPECT_TRUE(db().DoesColumnExist("foo", "A"));
+ EXPECT_TRUE(db_->DoesColumnExist("FOO", "A"));
+ EXPECT_TRUE(db_->DoesColumnExist("FOO", "a"));
+ EXPECT_TRUE(db_->DoesColumnExist("foo", "A"));
}
TEST_P(SQLDatabaseTest, GetLastInsertRowId) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo (value) VALUES (12)"));
// Last insert row ID should be valid.
- int64_t row = db().GetLastInsertRowId();
+ int64_t row = db_->GetLastInsertRowId();
EXPECT_LT(0, row);
// It should be the primary key of the row we just inserted.
- sql::Statement s(db().GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
+ Statement s(db_->GetUniqueStatement("SELECT value FROM foo WHERE id=?"));
s.BindInt64(0, row);
ASSERT_TRUE(s.Step());
EXPECT_EQ(12, s.ColumnInt(0));
}
TEST_P(SQLDatabaseTest, Rollback) {
- ASSERT_TRUE(db().BeginTransaction());
- ASSERT_TRUE(db().BeginTransaction());
- EXPECT_EQ(2, db().transaction_nesting());
- db().RollbackTransaction();
- EXPECT_FALSE(db().CommitTransaction());
- EXPECT_TRUE(db().BeginTransaction());
+ ASSERT_TRUE(db_->BeginTransaction());
+ ASSERT_TRUE(db_->BeginTransaction());
+ EXPECT_EQ(2, db_->transaction_nesting());
+ db_->RollbackTransaction();
+ EXPECT_FALSE(db_->CommitTransaction());
+ EXPECT_TRUE(db_->BeginTransaction());
}
// Test the scoped error expecter by attempting to insert a duplicate
// value into an index.
TEST_P(SQLDatabaseTest, ScopedErrorExpecter) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CONSTRAINT);
- ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ ASSERT_FALSE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
ASSERT_TRUE(expecter.SawExpectedErrors());
}
}
@@ -323,36 +359,36 @@ TEST_P(SQLDatabaseTest, ScopedErrorExpecter) {
// with ScopedErrorExpecter.
TEST_P(SQLDatabaseTest, ScopedIgnoreUntracked) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_FALSE(db().DoesTableExist("bar"));
- ASSERT_TRUE(db().DoesTableExist("foo"));
- ASSERT_TRUE(db().DoesColumnExist("foo", "id"));
- db().Close();
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_FALSE(db_->DoesTableExist("bar"));
+ ASSERT_TRUE(db_->DoesTableExist("foo"));
+ ASSERT_TRUE(db_->DoesColumnExist("foo", "id"));
+ db_->Close();
// Corrupt the database so that nothing works, including PRAGMAs.
- ASSERT_TRUE(CorruptSizeInHeaderOfDB());
+ ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CORRUPT);
- ASSERT_TRUE(db().Open(db_path()));
- ASSERT_FALSE(db().DoesTableExist("bar"));
- ASSERT_FALSE(db().DoesTableExist("foo"));
- ASSERT_FALSE(db().DoesColumnExist("foo", "id"));
+ ASSERT_TRUE(db_->Open(db_path_));
+ ASSERT_FALSE(db_->DoesTableExist("bar"));
+ ASSERT_FALSE(db_->DoesTableExist("foo"));
+ ASSERT_FALSE(db_->DoesColumnExist("foo", "id"));
ASSERT_TRUE(expecter.SawExpectedErrors());
}
}
TEST_P(SQLDatabaseTest, ErrorCallback) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER UNIQUE)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
int error = SQLITE_OK;
{
- sql::ScopedErrorCallback sec(
- &db(), base::BindRepeating(&sql::CaptureErrorCallback, &error));
- EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ ScopedErrorCallback sec(db_.get(),
+ base::BindRepeating(&CaptureErrorCallback, &error));
+ EXPECT_FALSE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
// Later versions of SQLite throw SQLITE_CONSTRAINT_UNIQUE. The specific
// sub-error isn't really important.
@@ -364,7 +400,7 @@ TEST_P(SQLDatabaseTest, ErrorCallback) {
error = SQLITE_OK;
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CONSTRAINT);
- ASSERT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ ASSERT_FALSE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
ASSERT_TRUE(expecter.SawExpectedErrors());
EXPECT_EQ(SQLITE_OK, error);
}
@@ -380,34 +416,34 @@ TEST_P(SQLDatabaseTest, ErrorCallback) {
// live.
{
size_t count = 0;
- sql::ScopedErrorCallback sec(
- &db(), base::BindRepeating(&ErrorCallbackSetHelper, &db(), &count,
- RefCounter(&count)));
+ ScopedErrorCallback sec(
+ db_.get(), base::BindRepeating(&ErrorCallbackSetHelper, db_.get(),
+ &count, RefCounter(&count)));
- EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ EXPECT_FALSE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
}
// Same test, but reset_error_callback() case.
{
size_t count = 0;
- sql::ScopedErrorCallback sec(
- &db(), base::BindRepeating(&ErrorCallbackResetHelper, &db(), &count,
- RefCounter(&count)));
+ ScopedErrorCallback sec(
+ db_.get(), base::BindRepeating(&ErrorCallbackResetHelper, db_.get(),
+ &count, RefCounter(&count)));
- EXPECT_FALSE(db().Execute("INSERT INTO foo (id) VALUES (12)"));
+ EXPECT_FALSE(db_->Execute("INSERT INTO foo (id) VALUES (12)"));
}
}
-// Test that sql::Database::Raze() results in a database without the
+// Test that Database::Raze() results in a database without the
// tables from the original database.
TEST_P(SQLDatabaseTest, Raze) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo (value) VALUES (12)"));
int pragma_auto_vacuum = 0;
{
- sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
+ Statement s(db_->GetUniqueStatement("PRAGMA auto_vacuum"));
ASSERT_TRUE(s.Step());
pragma_auto_vacuum = s.ColumnInt(0);
ASSERT_TRUE(pragma_auto_vacuum == 0 || pragma_auto_vacuum == 1);
@@ -417,13 +453,13 @@ TEST_P(SQLDatabaseTest, Raze) {
const int kExpectedPageCount = 2 + pragma_auto_vacuum;
{
- sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
+ Statement s(db_->GetUniqueStatement("PRAGMA page_count"));
ASSERT_TRUE(s.Step());
EXPECT_EQ(kExpectedPageCount, s.ColumnInt(0));
}
{
- sql::Statement s(db().GetUniqueStatement("SELECT * FROM sqlite_master"));
+ Statement s(db_->GetUniqueStatement("SELECT * FROM sqlite_master"));
ASSERT_TRUE(s.Step());
EXPECT_EQ("table", s.ColumnString(0));
EXPECT_EQ("foo", s.ColumnString(1));
@@ -433,18 +469,18 @@ TEST_P(SQLDatabaseTest, Raze) {
EXPECT_EQ(kCreateSql, s.ColumnString(4));
}
- ASSERT_TRUE(db().Raze());
+ ASSERT_TRUE(db_->Raze());
{
- sql::Statement s(db().GetUniqueStatement("PRAGMA page_count"));
+ Statement s(db_->GetUniqueStatement("PRAGMA page_count"));
ASSERT_TRUE(s.Step());
EXPECT_EQ(1, s.ColumnInt(0));
}
- ASSERT_EQ(0, SqliteMasterCount(&db()));
+ ASSERT_EQ(0, SqliteMasterCount(db_.get()));
{
- sql::Statement s(db().GetUniqueStatement("PRAGMA auto_vacuum"));
+ Statement s(db_->GetUniqueStatement("PRAGMA auto_vacuum"));
ASSERT_TRUE(s.Step());
// The new database has the same auto_vacuum as a fresh database.
EXPECT_EQ(pragma_auto_vacuum, s.ColumnInt(0));
@@ -466,8 +502,8 @@ void TestPageSize(const base::FilePath& db_prefix,
const base::FilePath db_path = db_prefix.InsertBeforeExtensionASCII(
base::NumberToString(initial_page_size));
- sql::Database::Delete(db_path);
- sql::Database db({.page_size = initial_page_size});
+ Database::Delete(db_path);
+ Database db({.page_size = initial_page_size});
ASSERT_TRUE(db.Open(db_path));
ASSERT_TRUE(db.Execute(kCreateSql));
ASSERT_TRUE(db.Execute(kInsertSql1));
@@ -477,7 +513,7 @@ void TestPageSize(const base::FilePath& db_prefix,
db.Close();
// Re-open the database while setting a new |options.page_size| in the object.
- sql::Database razed_db({.page_size = final_page_size});
+ Database razed_db({.page_size = final_page_size});
ASSERT_TRUE(razed_db.Open(db_path));
// Raze will use the page size set in the connection object, which may not
// match the file's page size.
@@ -495,29 +531,29 @@ void TestPageSize(const base::FilePath& db_prefix,
EXPECT_EQ("1", ExecuteWithResult(&razed_db, "PRAGMA page_count"));
}
-// Verify that sql::Recovery maintains the page size, and the virtual table
+// Verify that Recovery maintains the page size, and the virtual table
// works with page sizes other than SQLite's default. Also verify the case
// where the default page size has changed.
TEST_P(SQLDatabaseTest, RazePageSize) {
const std::string default_page_size =
- ExecuteWithResult(&db(), "PRAGMA page_size");
+ ExecuteWithResult(db_.get(), "PRAGMA page_size");
// Sync uses 32k pages.
EXPECT_NO_FATAL_FAILURE(
- TestPageSize(db_path(), 32768, "32768", 32768, "32768"));
+ TestPageSize(db_path_, 32768, "32768", 32768, "32768"));
// Many clients use 4k pages. This is the SQLite default after 3.12.0.
- EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 4096, "4096", 4096, "4096"));
+ EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 4096, "4096", 4096, "4096"));
// 1k is the default page size before 3.12.0.
- EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 1024, "1024", 1024, "1024"));
+ EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 1024, "1024", 1024, "1024"));
- EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 2048, "2048", 4096, "4096"));
+ EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 2048, "2048", 4096, "4096"));
// Databases with no page size specified should result in the default
// page size. 2k has never been the default page size.
ASSERT_NE("2048", default_page_size);
- EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 2048, "2048",
+ EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 2048, "2048",
DatabaseOptions::kDefaultPageSize,
default_page_size));
}
@@ -525,15 +561,15 @@ TEST_P(SQLDatabaseTest, RazePageSize) {
// Test that Raze() results are seen in other connections.
TEST_P(SQLDatabaseTest, RazeMultiple) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
- sql::Database other_db(GetDBOptions());
- ASSERT_TRUE(other_db.Open(db_path()));
+ Database other_db(GetDBOptions());
+ ASSERT_TRUE(other_db.Open(db_path_));
// Check that the second connection sees the table.
ASSERT_EQ(1, SqliteMasterCount(&other_db));
- ASSERT_TRUE(db().Raze());
+ ASSERT_TRUE(db_->Raze());
// The second connection sees the updated database.
ASSERT_EQ(0, SqliteMasterCount(&other_db));
@@ -541,26 +577,26 @@ TEST_P(SQLDatabaseTest, RazeMultiple) {
TEST_P(SQLDatabaseTest, RazeLocked) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
// Open a transaction and write some data in a second connection.
// This will acquire a PENDING or EXCLUSIVE transaction, which will
// cause the raze to fail.
- sql::Database other_db(GetDBOptions());
- ASSERT_TRUE(other_db.Open(db_path()));
+ Database other_db(GetDBOptions());
+ ASSERT_TRUE(other_db.Open(db_path_));
ASSERT_TRUE(other_db.BeginTransaction());
const char* kInsertSql = "INSERT INTO foo VALUES (1, 'data')";
ASSERT_TRUE(other_db.Execute(kInsertSql));
- ASSERT_FALSE(db().Raze());
+ ASSERT_FALSE(db_->Raze());
// Works after COMMIT.
ASSERT_TRUE(other_db.CommitTransaction());
- ASSERT_TRUE(db().Raze());
+ ASSERT_TRUE(db_->Raze());
// Re-create the database.
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute(kInsertSql));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute(kInsertSql));
// An unfinished read transaction in the other connection also
// blocks raze.
@@ -568,13 +604,13 @@ TEST_P(SQLDatabaseTest, RazeLocked) {
// write operations when using a WAL.
if (!IsWALEnabled()) {
const char* kQuery = "SELECT COUNT(*) FROM foo";
- sql::Statement s(other_db.GetUniqueStatement(kQuery));
+ Statement s(other_db.GetUniqueStatement(kQuery));
ASSERT_TRUE(s.Step());
- ASSERT_FALSE(db().Raze());
+ ASSERT_FALSE(db_->Raze());
// Completing the statement unlocks the database.
ASSERT_FALSE(s.Step());
- ASSERT_TRUE(db().Raze());
+ ASSERT_TRUE(db_->Raze());
}
}
@@ -582,26 +618,26 @@ TEST_P(SQLDatabaseTest, RazeLocked) {
// this as an empty database.
TEST_P(SQLDatabaseTest, RazeEmptyDB) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- db().Close();
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ db_->Close();
- TruncateDatabase();
+ ASSERT_TRUE(TruncateDatabase());
- ASSERT_TRUE(db().Open(db_path()));
- ASSERT_TRUE(db().Raze());
- EXPECT_EQ(0, SqliteMasterCount(&db()));
+ ASSERT_TRUE(db_->Open(db_path_));
+ ASSERT_TRUE(db_->Raze());
+ EXPECT_EQ(0, SqliteMasterCount(db_.get()));
}
// Verify that Raze() can handle a file of junk.
// Need exclusive mode off here as there are some subtleties (by design) around
// how the cache is used with it on which causes the test to fail.
TEST_P(SQLDatabaseTest, RazeNOTADB) {
- db().Close();
- sql::Database::Delete(db_path());
- ASSERT_FALSE(GetPathExists(db_path()));
+ db_->Close();
+ Database::Delete(db_path_);
+ ASSERT_FALSE(base::PathExists(db_path_));
- WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE_AND_TRUNCATE);
- ASSERT_TRUE(GetPathExists(db_path()));
+ ASSERT_TRUE(OverwriteDatabaseHeader(OverwriteType::kTruncate));
+ ASSERT_TRUE(base::PathExists(db_path_));
// SQLite will successfully open the handle, but fail when running PRAGMA
// statements that access the database.
@@ -609,25 +645,25 @@ TEST_P(SQLDatabaseTest, RazeNOTADB) {
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_NOTADB);
- EXPECT_TRUE(db().Open(db_path()));
+ EXPECT_TRUE(db_->Open(db_path_));
ASSERT_TRUE(expecter.SawExpectedErrors());
}
- EXPECT_TRUE(db().Raze());
- db().Close();
+ EXPECT_TRUE(db_->Raze());
+ db_->Close();
// Now empty, the open should open an empty database.
- EXPECT_TRUE(db().Open(db_path()));
- EXPECT_EQ(0, SqliteMasterCount(&db()));
+ EXPECT_TRUE(db_->Open(db_path_));
+ EXPECT_EQ(0, SqliteMasterCount(db_.get()));
}
// Verify that Raze() can handle a database overwritten with garbage.
TEST_P(SQLDatabaseTest, RazeNOTADB2) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_EQ(1, SqliteMasterCount(&db()));
- db().Close();
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_EQ(1, SqliteMasterCount(db_.get()));
+ db_->Close();
- WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE);
+ ASSERT_TRUE(OverwriteDatabaseHeader(OverwriteType::kOverwrite));
// SQLite will successfully open the handle, but will fail with
// SQLITE_NOTADB on pragma statemenets which attempt to read the
@@ -635,15 +671,15 @@ TEST_P(SQLDatabaseTest, RazeNOTADB2) {
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_NOTADB);
- EXPECT_TRUE(db().Open(db_path()));
+ EXPECT_TRUE(db_->Open(db_path_));
ASSERT_TRUE(expecter.SawExpectedErrors());
}
- EXPECT_TRUE(db().Raze());
- db().Close();
+ EXPECT_TRUE(db_->Raze());
+ db_->Close();
// Now empty, the open should succeed with an empty database.
- EXPECT_TRUE(db().Open(db_path()));
- EXPECT_EQ(0, SqliteMasterCount(&db()));
+ EXPECT_TRUE(db_->Open(db_path_));
+ EXPECT_EQ(0, SqliteMasterCount(db_.get()));
}
// Test that a callback from Open() can raze the database. This is
@@ -652,34 +688,34 @@ TEST_P(SQLDatabaseTest, RazeNOTADB2) {
// callback does this during Open(), the open is retried and succeeds.
TEST_P(SQLDatabaseTest, RazeCallbackReopen) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_EQ(1, SqliteMasterCount(&db()));
- db().Close();
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_EQ(1, SqliteMasterCount(db_.get()));
+ db_->Close();
// Corrupt the database so that nothing works, including PRAGMAs.
- ASSERT_TRUE(CorruptSizeInHeaderOfDB());
+ ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
// Open() will succeed, even though the PRAGMA calls within will
// fail with SQLITE_CORRUPT, as will this PRAGMA.
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CORRUPT);
- ASSERT_TRUE(db().Open(db_path()));
- ASSERT_FALSE(db().Execute("PRAGMA auto_vacuum"));
- db().Close();
+ ASSERT_TRUE(db_->Open(db_path_));
+ ASSERT_FALSE(db_->Execute("PRAGMA auto_vacuum"));
+ db_->Close();
ASSERT_TRUE(expecter.SawExpectedErrors());
}
- db().set_error_callback(
- base::BindRepeating(&RazeErrorCallback, &db(), SQLITE_CORRUPT));
+ db_->set_error_callback(
+ base::BindRepeating(&RazeErrorCallback, db_.get(), SQLITE_CORRUPT));
// When the PRAGMA calls in Open() raise SQLITE_CORRUPT, the error
// callback will call RazeAndClose(). Open() will then fail and be
// retried. The second Open() on the empty database will succeed
// cleanly.
- ASSERT_TRUE(db().Open(db_path()));
- ASSERT_TRUE(db().Execute("PRAGMA auto_vacuum"));
- EXPECT_EQ(0, SqliteMasterCount(&db()));
+ ASSERT_TRUE(db_->Open(db_path_));
+ ASSERT_TRUE(db_->Execute("PRAGMA auto_vacuum"));
+ EXPECT_EQ(0, SqliteMasterCount(db_.get()));
}
// Basic test of RazeAndClose() operation.
@@ -689,24 +725,24 @@ TEST_P(SQLDatabaseTest, RazeAndClose) {
// Test that RazeAndClose() closes the database, and that the
// database is empty when re-opened.
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute(kPopulateSql));
- ASSERT_TRUE(db().RazeAndClose());
- ASSERT_FALSE(db().is_open());
- db().Close();
- ASSERT_TRUE(db().Open(db_path()));
- ASSERT_EQ(0, SqliteMasterCount(&db()));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute(kPopulateSql));
+ ASSERT_TRUE(db_->RazeAndClose());
+ ASSERT_FALSE(db_->is_open());
+ db_->Close();
+ ASSERT_TRUE(db_->Open(db_path_));
+ ASSERT_EQ(0, SqliteMasterCount(db_.get()));
// Test that RazeAndClose() can break transactions.
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute(kPopulateSql));
- ASSERT_TRUE(db().BeginTransaction());
- ASSERT_TRUE(db().RazeAndClose());
- ASSERT_FALSE(db().is_open());
- ASSERT_FALSE(db().CommitTransaction());
- db().Close();
- ASSERT_TRUE(db().Open(db_path()));
- ASSERT_EQ(0, SqliteMasterCount(&db()));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute(kPopulateSql));
+ ASSERT_TRUE(db_->BeginTransaction());
+ ASSERT_TRUE(db_->RazeAndClose());
+ ASSERT_FALSE(db_->is_open());
+ ASSERT_FALSE(db_->CommitTransaction());
+ db_->Close();
+ ASSERT_TRUE(db_->Open(db_path_));
+ ASSERT_EQ(0, SqliteMasterCount(db_.get()));
}
// Test that various operations fail without crashing after
@@ -716,53 +752,53 @@ TEST_P(SQLDatabaseTest, RazeAndCloseDiagnostics) {
const char* kPopulateSql = "INSERT INTO foo (value) VALUES (12)";
const char* kSimpleSql = "SELECT 1";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute(kPopulateSql));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute(kPopulateSql));
// Test baseline expectations.
- db().Preload();
- ASSERT_TRUE(db().DoesTableExist("foo"));
- ASSERT_TRUE(db().IsSQLValid(kSimpleSql));
- ASSERT_EQ(SQLITE_OK, db().ExecuteAndReturnErrorCode(kSimpleSql));
- ASSERT_TRUE(db().Execute(kSimpleSql));
- ASSERT_TRUE(db().is_open());
+ db_->Preload();
+ ASSERT_TRUE(db_->DoesTableExist("foo"));
+ ASSERT_TRUE(db_->IsSQLValid(kSimpleSql));
+ ASSERT_EQ(SQLITE_OK, db_->ExecuteAndReturnErrorCode(kSimpleSql));
+ ASSERT_TRUE(db_->Execute(kSimpleSql));
+ ASSERT_TRUE(db_->is_open());
{
- sql::Statement s(db().GetUniqueStatement(kSimpleSql));
+ Statement s(db_->GetUniqueStatement(kSimpleSql));
ASSERT_TRUE(s.Step());
}
{
- sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
+ Statement s(db_->GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
ASSERT_TRUE(s.Step());
}
- ASSERT_TRUE(db().BeginTransaction());
- ASSERT_TRUE(db().CommitTransaction());
- ASSERT_TRUE(db().BeginTransaction());
- db().RollbackTransaction();
+ ASSERT_TRUE(db_->BeginTransaction());
+ ASSERT_TRUE(db_->CommitTransaction());
+ ASSERT_TRUE(db_->BeginTransaction());
+ db_->RollbackTransaction();
- ASSERT_TRUE(db().RazeAndClose());
+ ASSERT_TRUE(db_->RazeAndClose());
// At this point, they should all fail, but not crash.
- db().Preload();
- ASSERT_FALSE(db().DoesTableExist("foo"));
- ASSERT_FALSE(db().IsSQLValid(kSimpleSql));
- ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(kSimpleSql));
- ASSERT_FALSE(db().Execute(kSimpleSql));
- ASSERT_FALSE(db().is_open());
+ db_->Preload();
+ ASSERT_FALSE(db_->DoesTableExist("foo"));
+ ASSERT_FALSE(db_->IsSQLValid(kSimpleSql));
+ ASSERT_EQ(SQLITE_ERROR, db_->ExecuteAndReturnErrorCode(kSimpleSql));
+ ASSERT_FALSE(db_->Execute(kSimpleSql));
+ ASSERT_FALSE(db_->is_open());
{
- sql::Statement s(db().GetUniqueStatement(kSimpleSql));
+ Statement s(db_->GetUniqueStatement(kSimpleSql));
ASSERT_FALSE(s.Step());
}
{
- sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
+ Statement s(db_->GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
ASSERT_FALSE(s.Step());
}
- ASSERT_FALSE(db().BeginTransaction());
- ASSERT_FALSE(db().CommitTransaction());
- ASSERT_FALSE(db().BeginTransaction());
- db().RollbackTransaction();
+ ASSERT_FALSE(db_->BeginTransaction());
+ ASSERT_FALSE(db_->CommitTransaction());
+ ASSERT_FALSE(db_->BeginTransaction());
+ db_->RollbackTransaction();
// Close normally to reset the poisoned flag.
- db().Close();
+ db_->Close();
// DEATH tests not supported on Android, iOS, or Fuchsia.
#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
@@ -770,7 +806,7 @@ TEST_P(SQLDatabaseTest, RazeAndCloseDiagnostics) {
// usage by becoming fatal in debug mode. Since DEATH tests are
// expensive, just test one of them.
if (DLOG_IS_ON(FATAL)) {
- ASSERT_DEATH({ db().IsSQLValid(kSimpleSql); },
+ ASSERT_DEATH({ db_->IsSQLValid(kSimpleSql); },
"Illegal use of Database without a db");
}
#endif // !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
@@ -789,75 +825,75 @@ TEST_P(SQLDatabaseTest, RazeTruncate) {
// The empty database has 0 or 1 pages. Raze() should leave it with exactly 1
// page. Not checking directly because auto_vacuum on Android adds a freelist
// page.
- ASSERT_TRUE(db().Raze());
+ ASSERT_TRUE(db_->Raze());
int64_t expected_size;
- ASSERT_TRUE(base::GetFileSize(db_path(), &expected_size));
+ ASSERT_TRUE(base::GetFileSize(db_path_, &expected_size));
ASSERT_GT(expected_size, 0);
// Cause the database to take a few pages.
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
for (size_t i = 0; i < 24; ++i) {
ASSERT_TRUE(
- db().Execute("INSERT INTO foo (value) VALUES (randomblob(1024))"));
+ db_->Execute("INSERT INTO foo (value) VALUES (randomblob(1024))"));
}
// In WAL mode, writes don't reach the database file until a checkpoint
// happens.
- ASSERT_TRUE(db().CheckpointDatabase());
+ ASSERT_TRUE(db_->CheckpointDatabase());
int64_t db_size;
- ASSERT_TRUE(base::GetFileSize(db_path(), &db_size));
+ ASSERT_TRUE(base::GetFileSize(db_path_, &db_size));
ASSERT_GT(db_size, expected_size);
// Make a query covering most of the database file to make sure that the
// blocks are actually mapped into memory. Empirically, the truncate problem
// doesn't seem to happen if no blocks are mapped.
EXPECT_EQ("24576",
- ExecuteWithResult(&db(), "SELECT SUM(LENGTH(value)) FROM foo"));
+ ExecuteWithResult(db_.get(), "SELECT SUM(LENGTH(value)) FROM foo"));
- ASSERT_TRUE(db().Raze());
- ASSERT_TRUE(base::GetFileSize(db_path(), &db_size));
+ ASSERT_TRUE(db_->Raze());
+ ASSERT_TRUE(base::GetFileSize(db_path_, &db_size));
ASSERT_EQ(expected_size, db_size);
}
#if defined(OS_ANDROID)
TEST_P(SQLDatabaseTest, SetTempDirForSQL) {
- sql::MetaTable meta_table;
+ MetaTable meta_table;
// Below call needs a temporary directory in sqlite3
// On Android, it can pass only when the temporary directory is set.
// Otherwise, sqlite3 doesn't find the correct directory to store
// temporary files and will report the error 'unable to open
// database file'.
- ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
+ ASSERT_TRUE(meta_table.Init(db_.get(), 4, 4));
}
#endif // defined(OS_ANDROID)
TEST_P(SQLDatabaseTest, Delete) {
- EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
- db().Close();
+ EXPECT_TRUE(db_->Execute("CREATE TABLE x (x)"));
+ db_->Close();
- base::FilePath journal_path = sql::Database::JournalPath(db_path());
- base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
+ base::FilePath journal_path = Database::JournalPath(db_path_);
+ base::FilePath wal_path = Database::WriteAheadLogPath(db_path_);
// Should have both a main database file and a journal file if
// journal_mode is TRUNCATE. There is no WAL file as it is deleted on Close.
- ASSERT_TRUE(GetPathExists(db_path()));
+ ASSERT_TRUE(base::PathExists(db_path_));
if (!IsWALEnabled()) { // TRUNCATE mode
- ASSERT_TRUE(GetPathExists(journal_path));
+ ASSERT_TRUE(base::PathExists(journal_path));
}
- sql::Database::Delete(db_path());
- EXPECT_FALSE(GetPathExists(db_path()));
- EXPECT_FALSE(GetPathExists(journal_path));
- EXPECT_FALSE(GetPathExists(wal_path));
+ Database::Delete(db_path_);
+ EXPECT_FALSE(base::PathExists(db_path_));
+ EXPECT_FALSE(base::PathExists(journal_path));
+ EXPECT_FALSE(base::PathExists(wal_path));
}
#if defined(OS_POSIX) // This test operates on POSIX file permissions.
TEST_P(SQLDatabaseTest, PosixFilePermissions) {
- db().Close();
- sql::Database::Delete(db_path());
- ASSERT_FALSE(GetPathExists(db_path()));
+ db_->Close();
+ Database::Delete(db_path_);
+ ASSERT_FALSE(base::PathExists(db_path_));
// If the bots all had a restrictive umask setting such that databases are
// always created with only the owner able to read them, then the code could
@@ -865,37 +901,37 @@ TEST_P(SQLDatabaseTest, PosixFilePermissions) {
// umask.
ScopedUmaskSetter permissive_umask(S_IWGRP | S_IWOTH);
- ASSERT_TRUE(db().Open(db_path()));
+ ASSERT_TRUE(db_->Open(db_path_));
// Cause the journal file to be created. If the default journal_mode is
// changed back to DELETE, this test will need to be updated.
- EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
+ EXPECT_TRUE(db_->Execute("CREATE TABLE x (x)"));
int mode;
- ASSERT_TRUE(GetPathExists(db_path()));
- EXPECT_TRUE(base::GetPosixFilePermissions(db_path(), &mode));
+ ASSERT_TRUE(base::PathExists(db_path_));
+ EXPECT_TRUE(base::GetPosixFilePermissions(db_path_, &mode));
ASSERT_EQ(mode, 0600);
if (IsWALEnabled()) { // WAL mode
// The WAL file is created lazily on first change.
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
- base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
- ASSERT_TRUE(GetPathExists(wal_path));
+ base::FilePath wal_path = Database::WriteAheadLogPath(db_path_);
+ ASSERT_TRUE(base::PathExists(wal_path));
EXPECT_TRUE(base::GetPosixFilePermissions(wal_path, &mode));
ASSERT_EQ(mode, 0600);
// The shm file doesn't exist in exclusive locking mode.
- if (ExecuteWithResult(&db(), "PRAGMA locking_mode") == "normal") {
- base::FilePath shm_path = sql::Database::SharedMemoryFilePath(db_path());
- ASSERT_TRUE(GetPathExists(shm_path));
+ if (ExecuteWithResult(db_.get(), "PRAGMA locking_mode") == "normal") {
+ base::FilePath shm_path = Database::SharedMemoryFilePath(db_path_);
+ ASSERT_TRUE(base::PathExists(shm_path));
EXPECT_TRUE(base::GetPosixFilePermissions(shm_path, &mode));
ASSERT_EQ(mode, 0600);
}
} else { // Truncate mode
- base::FilePath journal_path = sql::Database::JournalPath(db_path());
+ base::FilePath journal_path = Database::JournalPath(db_path_);
DLOG(ERROR) << "journal_path: " << journal_path;
- ASSERT_TRUE(GetPathExists(journal_path));
+ ASSERT_TRUE(base::PathExists(journal_path));
EXPECT_TRUE(base::GetPosixFilePermissions(journal_path, &mode));
ASSERT_EQ(mode, 0600);
}
@@ -904,31 +940,31 @@ TEST_P(SQLDatabaseTest, PosixFilePermissions) {
// Test that errors start happening once Poison() is called.
TEST_P(SQLDatabaseTest, Poison) {
- EXPECT_TRUE(db().Execute("CREATE TABLE x (x)"));
+ EXPECT_TRUE(db_->Execute("CREATE TABLE x (x)"));
// Before the Poison() call, things generally work.
- EXPECT_TRUE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
- EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
+ EXPECT_TRUE(db_->IsSQLValid("INSERT INTO x VALUES ('x')"));
+ EXPECT_TRUE(db_->Execute("INSERT INTO x VALUES ('x')"));
{
- sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
+ Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM x"));
ASSERT_TRUE(s.is_valid());
ASSERT_TRUE(s.Step());
}
// Get a statement which is valid before and will exist across Poison().
- sql::Statement valid_statement(
- db().GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
+ Statement valid_statement(
+ db_->GetUniqueStatement("SELECT COUNT(*) FROM sqlite_master"));
ASSERT_TRUE(valid_statement.is_valid());
ASSERT_TRUE(valid_statement.Step());
valid_statement.Reset(true);
- db().Poison();
+ db_->Poison();
// After the Poison() call, things fail.
- EXPECT_FALSE(db().IsSQLValid("INSERT INTO x VALUES ('x')"));
- EXPECT_FALSE(db().Execute("INSERT INTO x VALUES ('x')"));
+ EXPECT_FALSE(db_->IsSQLValid("INSERT INTO x VALUES ('x')"));
+ EXPECT_FALSE(db_->Execute("INSERT INTO x VALUES ('x')"));
{
- sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM x"));
+ Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM x"));
ASSERT_FALSE(s.is_valid());
ASSERT_FALSE(s.Step());
}
@@ -939,77 +975,77 @@ TEST_P(SQLDatabaseTest, Poison) {
// Test that poisoning the database during a transaction works (with errors).
// RazeErrorCallback() poisons the database, the extra COMMIT causes
- // CommitTransaction() to throw an error while commiting.
- db().set_error_callback(
- base::BindRepeating(&RazeErrorCallback, &db(), SQLITE_ERROR));
- db().Close();
- ASSERT_TRUE(db().Open(db_path()));
- EXPECT_TRUE(db().BeginTransaction());
- EXPECT_TRUE(db().Execute("INSERT INTO x VALUES ('x')"));
- EXPECT_TRUE(db().Execute("COMMIT"));
- EXPECT_FALSE(db().CommitTransaction());
+ // CommitTransaction() to throw an error while committing.
+ db_->set_error_callback(
+ base::BindRepeating(&RazeErrorCallback, db_.get(), SQLITE_ERROR));
+ db_->Close();
+ ASSERT_TRUE(db_->Open(db_path_));
+ EXPECT_TRUE(db_->BeginTransaction());
+ EXPECT_TRUE(db_->Execute("INSERT INTO x VALUES ('x')"));
+ EXPECT_TRUE(db_->Execute("COMMIT"));
+ EXPECT_FALSE(db_->CommitTransaction());
}
TEST_P(SQLDatabaseTest, AttachDatabase) {
- EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+ EXPECT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
// Create a database to attach to.
base::FilePath attach_path =
- db_path().DirName().AppendASCII("SQLDatabaseAttach.db");
+ db_path_.DirName().AppendASCII("SQLDatabaseAttach.db");
static const char kAttachmentPoint[] = "other";
{
- sql::Database other_db;
+ Database other_db;
ASSERT_TRUE(other_db.Open(attach_path));
EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
}
// Cannot see the attached database, yet.
- EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
+ EXPECT_FALSE(db_->IsSQLValid("SELECT count(*) from other.bar"));
- EXPECT_TRUE(
- DatabaseTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
- EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
+ EXPECT_TRUE(DatabaseTestPeer::AttachDatabase(db_.get(), attach_path,
+ kAttachmentPoint));
+ EXPECT_TRUE(db_->IsSQLValid("SELECT count(*) from other.bar"));
// Queries can touch both databases after the ATTACH.
- EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
+ EXPECT_TRUE(db_->Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
{
- sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
+ Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM foo"));
ASSERT_TRUE(s.Step());
EXPECT_EQ(1, s.ColumnInt(0));
}
- EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
- EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
+ EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(db_.get(), kAttachmentPoint));
+ EXPECT_FALSE(db_->IsSQLValid("SELECT count(*) from other.bar"));
}
TEST_P(SQLDatabaseTest, AttachDatabaseWithOpenTransaction) {
- EXPECT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+ EXPECT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
// Create a database to attach to.
base::FilePath attach_path =
- db_path().DirName().AppendASCII("SQLDatabaseAttach.db");
+ db_path_.DirName().AppendASCII("SQLDatabaseAttach.db");
static const char kAttachmentPoint[] = "other";
{
- sql::Database other_db;
+ Database other_db;
ASSERT_TRUE(other_db.Open(attach_path));
EXPECT_TRUE(other_db.Execute("CREATE TABLE bar (a, b)"));
EXPECT_TRUE(other_db.Execute("INSERT INTO bar VALUES ('hello', 'world')"));
}
// Cannot see the attached database, yet.
- EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
+ EXPECT_FALSE(db_->IsSQLValid("SELECT count(*) from other.bar"));
// Attach succeeds in a transaction.
- EXPECT_TRUE(db().BeginTransaction());
- EXPECT_TRUE(
- DatabaseTestPeer::AttachDatabase(&db(), attach_path, kAttachmentPoint));
- EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
+ EXPECT_TRUE(db_->BeginTransaction());
+ EXPECT_TRUE(DatabaseTestPeer::AttachDatabase(db_.get(), attach_path,
+ kAttachmentPoint));
+ EXPECT_TRUE(db_->IsSQLValid("SELECT count(*) from other.bar"));
// Queries can touch both databases after the ATTACH.
- EXPECT_TRUE(db().Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
+ EXPECT_TRUE(db_->Execute("INSERT INTO foo SELECT a, b FROM other.bar"));
{
- sql::Statement s(db().GetUniqueStatement("SELECT COUNT(*) FROM foo"));
+ Statement s(db_->GetUniqueStatement("SELECT COUNT(*) FROM foo"));
ASSERT_TRUE(s.Step());
EXPECT_EQ(1, s.ColumnInt(0));
}
@@ -1018,30 +1054,30 @@ TEST_P(SQLDatabaseTest, AttachDatabaseWithOpenTransaction) {
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_ERROR);
- EXPECT_FALSE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
- EXPECT_TRUE(db().IsSQLValid("SELECT count(*) from other.bar"));
+ EXPECT_FALSE(DatabaseTestPeer::DetachDatabase(db_.get(), kAttachmentPoint));
+ EXPECT_TRUE(db_->IsSQLValid("SELECT count(*) from other.bar"));
ASSERT_TRUE(expecter.SawExpectedErrors());
}
// Detach succeeds when the transaction is closed.
- db().RollbackTransaction();
- EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(&db(), kAttachmentPoint));
- EXPECT_FALSE(db().IsSQLValid("SELECT count(*) from other.bar"));
+ db_->RollbackTransaction();
+ EXPECT_TRUE(DatabaseTestPeer::DetachDatabase(db_.get(), kAttachmentPoint));
+ EXPECT_FALSE(db_->IsSQLValid("SELECT count(*) from other.bar"));
}
TEST_P(SQLDatabaseTest, Basic_QuickIntegrityCheck) {
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- EXPECT_TRUE(db().QuickIntegrityCheck());
- db().Close();
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ EXPECT_TRUE(db_->QuickIntegrityCheck());
+ db_->Close();
- ASSERT_TRUE(CorruptSizeInHeaderOfDB());
+ ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CORRUPT);
- ASSERT_TRUE(db().Open(db_path()));
- EXPECT_FALSE(db().QuickIntegrityCheck());
+ ASSERT_TRUE(db_->Open(db_path_));
+ EXPECT_FALSE(db_->QuickIntegrityCheck());
ASSERT_TRUE(expecter.SawExpectedErrors());
}
}
@@ -1051,19 +1087,19 @@ TEST_P(SQLDatabaseTest, Basic_FullIntegrityCheck) {
std::vector<std::string> messages;
const char* kCreateSql = "CREATE TABLE foo (id INTEGER PRIMARY KEY, value)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- EXPECT_TRUE(db().FullIntegrityCheck(&messages));
+ ASSERT_TRUE(db_->Execute(kCreateSql));
+ EXPECT_TRUE(db_->FullIntegrityCheck(&messages));
EXPECT_EQ(1u, messages.size());
EXPECT_EQ(kOk, messages[0]);
- db().Close();
+ db_->Close();
- ASSERT_TRUE(CorruptSizeInHeaderOfDB());
+ ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CORRUPT);
- ASSERT_TRUE(db().Open(db_path()));
- EXPECT_TRUE(db().FullIntegrityCheck(&messages));
+ ASSERT_TRUE(db_->Open(db_path_));
+ EXPECT_TRUE(db_->FullIntegrityCheck(&messages));
EXPECT_LT(1u, messages.size());
EXPECT_NE(kOk, messages[0]);
ASSERT_TRUE(expecter.SawExpectedErrors());
@@ -1077,38 +1113,38 @@ TEST_P(SQLDatabaseTest, OnMemoryDump) {
base::trace_event::MemoryDumpArgs args = {
base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
base::trace_event::ProcessMemoryDump pmd(args);
- ASSERT_TRUE(db().memory_dump_provider_->OnMemoryDump(args, &pmd));
+ ASSERT_TRUE(db_->memory_dump_provider_->OnMemoryDump(args, &pmd));
EXPECT_GE(pmd.allocator_dumps().size(), 1u);
}
// Test that the functions to collect diagnostic data run to completion, without
// worrying too much about what they generate (since that will change).
TEST_P(SQLDatabaseTest, CollectDiagnosticInfo) {
- const std::string corruption_info = db().CollectCorruptionInfo();
+ const std::string corruption_info = db_->CollectCorruptionInfo();
EXPECT_NE(std::string::npos, corruption_info.find("SQLITE_CORRUPT"));
EXPECT_NE(std::string::npos, corruption_info.find("integrity_check"));
// A statement to see in the results.
const char* kSimpleSql = "SELECT 'mountain'";
- Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
+ Statement s(db_->GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
// Error includes the statement.
- const std::string readonly_info = db().CollectErrorInfo(SQLITE_READONLY, &s);
+ const std::string readonly_info = db_->CollectErrorInfo(SQLITE_READONLY, &s);
EXPECT_NE(std::string::npos, readonly_info.find(kSimpleSql));
// Some other error doesn't include the statment.
// TODO(shess): This is weak.
- const std::string full_info = db().CollectErrorInfo(SQLITE_FULL, nullptr);
+ const std::string full_info = db_->CollectErrorInfo(SQLITE_FULL, nullptr);
EXPECT_EQ(std::string::npos, full_info.find(kSimpleSql));
// A table to see in the SQLITE_ERROR results.
- EXPECT_TRUE(db().Execute("CREATE TABLE volcano (x)"));
+ EXPECT_TRUE(db_->Execute("CREATE TABLE volcano (x)"));
// Version info to see in the SQLITE_ERROR results.
- sql::MetaTable meta_table;
- ASSERT_TRUE(meta_table.Init(&db(), 4, 4));
+ MetaTable meta_table;
+ ASSERT_TRUE(meta_table.Init(db_.get(), 4, 4));
- const std::string error_info = db().CollectErrorInfo(SQLITE_ERROR, &s);
+ const std::string error_info = db_->CollectErrorInfo(SQLITE_ERROR, &s);
EXPECT_NE(std::string::npos, error_info.find(kSimpleSql));
EXPECT_NE(std::string::npos, error_info.find("volcano"));
EXPECT_NE(std::string::npos, error_info.find("version: 4"));
@@ -1118,7 +1154,7 @@ TEST_P(SQLDatabaseTest, CollectDiagnosticInfo) {
// enabled by SQLite.
TEST_P(SQLDatabaseTest, MmapInitiallyEnabled) {
{
- sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size"));
+ Statement s(db_->GetUniqueStatement("PRAGMA mmap_size"));
ASSERT_TRUE(s.Step())
<< "All supported SQLite versions should have mmap support";
@@ -1127,7 +1163,7 @@ TEST_P(SQLDatabaseTest, MmapInitiallyEnabled) {
// returned. If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
// instance MojoVFS), -1 is returned.
if (s.ColumnInt(0) <= 0) {
- ASSERT_TRUE(db().Execute("PRAGMA mmap_size = 1048576"));
+ ASSERT_TRUE(db_->Execute("PRAGMA mmap_size = 1048576"));
s.Reset(true);
ASSERT_TRUE(s.Step());
EXPECT_LE(s.ColumnInt(0), 0);
@@ -1135,24 +1171,24 @@ TEST_P(SQLDatabaseTest, MmapInitiallyEnabled) {
}
// Test that explicit disable prevents mmap'ed I/O.
- db().Close();
- sql::Database::Delete(db_path());
- db().set_mmap_disabled();
- ASSERT_TRUE(db().Open(db_path()));
- EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size"));
+ db_->Close();
+ Database::Delete(db_path_);
+ db_->set_mmap_disabled();
+ ASSERT_TRUE(db_->Open(db_path_));
+ EXPECT_EQ("0", ExecuteWithResult(db_.get(), "PRAGMA mmap_size"));
}
// Test whether a fresh database gets mmap enabled when using alternate status
// storage.
TEST_P(SQLDatabaseTest, MmapInitiallyEnabledAltStatus) {
// Re-open fresh database with alt-status flag set.
- db().Close();
- sql::Database::Delete(db_path());
- db().set_mmap_alt_status();
- ASSERT_TRUE(db().Open(db_path()));
+ db_->Close();
+ Database::Delete(db_path_);
+ db_->set_mmap_alt_status();
+ ASSERT_TRUE(db_->Open(db_path_));
{
- sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size"));
+ Statement s(db_->GetUniqueStatement("PRAGMA mmap_size"));
ASSERT_TRUE(s.Step())
<< "All supported SQLite versions should have mmap support";
@@ -1161,7 +1197,7 @@ TEST_P(SQLDatabaseTest, MmapInitiallyEnabledAltStatus) {
// returned. If the VFS does not understand SQLITE_FCNTL_MMAP_SIZE (for
// instance MojoVFS), -1 is returned.
if (s.ColumnInt(0) <= 0) {
- ASSERT_TRUE(db().Execute("PRAGMA mmap_size = 1048576"));
+ ASSERT_TRUE(db_->Execute("PRAGMA mmap_size = 1048576"));
s.Reset(true);
ASSERT_TRUE(s.Step());
EXPECT_LE(s.ColumnInt(0), 0);
@@ -1169,11 +1205,11 @@ TEST_P(SQLDatabaseTest, MmapInitiallyEnabledAltStatus) {
}
// Test that explicit disable overrides set_mmap_alt_status().
- db().Close();
- sql::Database::Delete(db_path());
- db().set_mmap_disabled();
- ASSERT_TRUE(db().Open(db_path()));
- EXPECT_EQ("0", ExecuteWithResult(&db(), "PRAGMA mmap_size"));
+ db_->Close();
+ Database::Delete(db_path_);
+ db_->set_mmap_disabled();
+ ASSERT_TRUE(db_->Open(db_path_));
+ EXPECT_EQ("0", ExecuteWithResult(db_.get(), "PRAGMA mmap_size"));
}
TEST_P(SQLDatabaseTest, GetAppropriateMmapSize) {
@@ -1182,40 +1218,40 @@ TEST_P(SQLDatabaseTest, GetAppropriateMmapSize) {
// If there is no meta table (as for a fresh database), assume that everything
// should be mapped, and the status of the meta table is not affected.
- ASSERT_TRUE(!db().DoesTableExist("meta"));
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
- ASSERT_TRUE(!db().DoesTableExist("meta"));
+ ASSERT_TRUE(!db_->DoesTableExist("meta"));
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_TRUE(!db_->DoesTableExist("meta"));
// When the meta table is first created, it sets up to map everything.
- MetaTable().Init(&db(), 1, 1);
- ASSERT_TRUE(db().DoesTableExist("meta"));
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
- ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
+ MetaTable().Init(db_.get(), 1, 1);
+ ASSERT_TRUE(db_->DoesTableExist("meta"));
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
// Preload with partial progress of one page. Should map everything.
- ASSERT_TRUE(db().Execute("REPLACE INTO meta VALUES ('mmap_status', 1)"));
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
- ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
+ ASSERT_TRUE(db_->Execute("REPLACE INTO meta VALUES ('mmap_status', 1)"));
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
// Failure status maps nothing.
- ASSERT_TRUE(db().Execute("REPLACE INTO meta VALUES ('mmap_status', -2)"));
- ASSERT_EQ(0UL, db().GetAppropriateMmapSize());
+ ASSERT_TRUE(db_->Execute("REPLACE INTO meta VALUES ('mmap_status', -2)"));
+ ASSERT_EQ(0UL, db_->GetAppropriateMmapSize());
// Re-initializing the meta table does not re-create the key if the table
// already exists.
- ASSERT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'mmap_status'"));
- MetaTable().Init(&db(), 1, 1);
+ ASSERT_TRUE(db_->Execute("DELETE FROM meta WHERE key = 'mmap_status'"));
+ MetaTable().Init(db_.get(), 1, 1);
ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
- ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
+ ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
ASSERT_EQ(0, mmap_status);
// With no key, map everything and create the key.
// TODO(shess): This really should be "maps everything after validating it",
// but that is more complicated to structure.
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
- ASSERT_TRUE(MetaTable::GetMmapStatus(&db(), &mmap_status));
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status));
ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status);
}
@@ -1223,133 +1259,151 @@ TEST_P(SQLDatabaseTest, GetAppropriateMmapSizeAltStatus) {
const size_t kMmapAlot = 25 * 1024 * 1024;
// At this point, Database still expects a future [meta] table.
- ASSERT_FALSE(db().DoesTableExist("meta"));
- ASSERT_FALSE(db().DoesViewExist("MmapStatus"));
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
- ASSERT_FALSE(db().DoesTableExist("meta"));
- ASSERT_FALSE(db().DoesViewExist("MmapStatus"));
+ ASSERT_FALSE(db_->DoesTableExist("meta"));
+ ASSERT_FALSE(db_->DoesViewExist("MmapStatus"));
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_FALSE(db_->DoesTableExist("meta"));
+ ASSERT_FALSE(db_->DoesViewExist("MmapStatus"));
// Using alt status, everything should be mapped, with state in the view.
- db().set_mmap_alt_status();
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
- ASSERT_FALSE(db().DoesTableExist("meta"));
- ASSERT_TRUE(db().DoesViewExist("MmapStatus"));
+ db_->set_mmap_alt_status();
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_FALSE(db_->DoesTableExist("meta"));
+ ASSERT_TRUE(db_->DoesViewExist("MmapStatus"));
EXPECT_EQ(base::NumberToString(MetaTable::kMmapSuccess),
- ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
+ ExecuteWithResult(db_.get(), "SELECT * FROM MmapStatus"));
// Also maps everything when kMmapSuccess is already in the view.
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
// Preload with partial progress of one page. Should map everything.
- ASSERT_TRUE(db().Execute("DROP VIEW MmapStatus"));
- ASSERT_TRUE(db().Execute("CREATE VIEW MmapStatus (value) AS SELECT 1"));
- ASSERT_GT(db().GetAppropriateMmapSize(), kMmapAlot);
+ ASSERT_TRUE(db_->Execute("DROP VIEW MmapStatus"));
+ ASSERT_TRUE(db_->Execute("CREATE VIEW MmapStatus (value) AS SELECT 1"));
+ ASSERT_GT(db_->GetAppropriateMmapSize(), kMmapAlot);
EXPECT_EQ(base::NumberToString(MetaTable::kMmapSuccess),
- ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
+ ExecuteWithResult(db_.get(), "SELECT * FROM MmapStatus"));
// Failure status leads to nothing being mapped.
- ASSERT_TRUE(db().Execute("DROP VIEW MmapStatus"));
- ASSERT_TRUE(db().Execute("CREATE VIEW MmapStatus (value) AS SELECT -2"));
- ASSERT_EQ(0UL, db().GetAppropriateMmapSize());
+ ASSERT_TRUE(db_->Execute("DROP VIEW MmapStatus"));
+ ASSERT_TRUE(db_->Execute("CREATE VIEW MmapStatus (value) AS SELECT -2"));
+ ASSERT_EQ(0UL, db_->GetAppropriateMmapSize());
EXPECT_EQ(base::NumberToString(MetaTable::kMmapFailure),
- ExecuteWithResult(&db(), "SELECT * FROM MmapStatus"));
+ ExecuteWithResult(db_.get(), "SELECT * FROM MmapStatus"));
}
TEST_P(SQLDatabaseTest, GetMemoryUsage) {
// Databases with mmap enabled may not follow the assumptions below.
- db().Close();
- db().set_mmap_disabled();
- ASSERT_TRUE(db().Open(db_path()));
+ db_->Close();
+ db_->set_mmap_disabled();
+ ASSERT_TRUE(db_->Open(db_path_));
- int initial_memory = db().GetMemoryUsage();
+ int initial_memory = db_->GetMemoryUsage();
EXPECT_GT(initial_memory, 0)
<< "SQLite should always use some memory for a database";
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
- int post_query_memory = db().GetMemoryUsage();
+ int post_query_memory = db_->GetMemoryUsage();
EXPECT_GT(post_query_memory, initial_memory)
<< "Page cache usage should go up after executing queries";
- db().TrimMemory();
- int post_trim_memory = db().GetMemoryUsage();
+ db_->TrimMemory();
+ int post_trim_memory = db_->GetMemoryUsage();
EXPECT_GT(post_query_memory, post_trim_memory)
<< "Page cache usage should go down after calling TrimMemory()";
}
-class SQLDatabaseTestExclusiveMode : public SQLDatabaseTest {
+class SQLDatabaseTestExclusiveMode : public testing::Test,
+ public testing::WithParamInterface<bool> {
public:
- SQLDatabaseTestExclusiveMode() : SQLDatabaseTest(GetDBOptions()) {}
+ ~SQLDatabaseTestExclusiveMode() override = default;
+
+ void SetUp() override {
+ db_ = std::make_unique<Database>(GetDBOptions());
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ db_path_ = temp_dir_.GetPath().AppendASCII("recovery_test.sqlite");
+ ASSERT_TRUE(db_->Open(db_path_));
+ }
DatabaseOptions GetDBOptions() {
- DatabaseOptions options = SQLDatabaseTest::GetDBOptions();
+ DatabaseOptions options;
+ options.wal_mode = IsWALEnabled();
options.exclusive_locking = true;
return options;
}
+
+ bool IsWALEnabled() { return GetParam(); }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ base::FilePath db_path_;
+ std::unique_ptr<Database> db_;
};
TEST_P(SQLDatabaseTestExclusiveMode, LockingModeExclusive) {
- EXPECT_EQ(ExecuteWithResult(&db(), "PRAGMA locking_mode"), "exclusive");
+ EXPECT_EQ(ExecuteWithResult(db_.get(), "PRAGMA locking_mode"), "exclusive");
}
TEST_P(SQLDatabaseTest, LockingModeNormal) {
- EXPECT_EQ(ExecuteWithResult(&db(), "PRAGMA locking_mode"), "normal");
+ EXPECT_EQ(ExecuteWithResult(db_.get(), "PRAGMA locking_mode"), "normal");
}
TEST_P(SQLDatabaseTest, OpenedInCorrectMode) {
std::string expected_mode = IsWALEnabled() ? "wal" : "truncate";
- EXPECT_EQ(ExecuteWithResult(&db(), "PRAGMA journal_mode"), expected_mode);
+ EXPECT_EQ(ExecuteWithResult(db_.get(), "PRAGMA journal_mode"), expected_mode);
}
TEST_P(SQLDatabaseTest, CheckpointDatabase) {
if (!IsWALEnabled())
return;
- base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
+ base::FilePath wal_path = Database::WriteAheadLogPath(db_path_);
int64_t wal_size = 0;
// WAL file initially empty.
- EXPECT_TRUE(GetPathExists(wal_path));
+ EXPECT_TRUE(base::PathExists(wal_path));
base::GetFileSize(wal_path, &wal_size);
EXPECT_EQ(wal_size, 0);
ASSERT_TRUE(
- db().Execute("CREATE TABLE foo (id INTEGER UNIQUE, value INTEGER)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo VALUES (1, 1)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo VALUES (2, 2)"));
+ db_->Execute("CREATE TABLE foo (id INTEGER UNIQUE, value INTEGER)"));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo VALUES (1, 1)"));
+ ASSERT_TRUE(db_->Execute("INSERT INTO foo VALUES (2, 2)"));
// Writes reach WAL file but not db file.
base::GetFileSize(wal_path, &wal_size);
EXPECT_GT(wal_size, 0);
int64_t db_size = 0;
- base::GetFileSize(db_path(), &db_size);
- EXPECT_EQ(db_size, db().page_size());
+ base::GetFileSize(db_path_, &db_size);
+ EXPECT_EQ(db_size, db_->page_size());
// Checkpoint database to immediately propagate writes to DB file.
- EXPECT_TRUE(db().CheckpointDatabase());
-
- base::GetFileSize(db_path(), &db_size);
- EXPECT_GT(db_size, db().page_size());
- EXPECT_EQ(ExecuteWithResult(&db(), "SELECT value FROM foo where id=1"), "1");
- EXPECT_EQ(ExecuteWithResult(&db(), "SELECT value FROM foo where id=2"), "2");
+ EXPECT_TRUE(db_->CheckpointDatabase());
+
+ base::GetFileSize(db_path_, &db_size);
+ EXPECT_GT(db_size, db_->page_size());
+ EXPECT_EQ(ExecuteWithResult(db_.get(), "SELECT value FROM foo where id=1"),
+ "1");
+ EXPECT_EQ(ExecuteWithResult(db_.get(), "SELECT value FROM foo where id=2"),
+ "2");
}
TEST_P(SQLDatabaseTest, CorruptSizeInHeaderTest) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (x)"));
- ASSERT_TRUE(db().Execute("CREATE TABLE bar (x)"));
- db().Close();
+ ASSERT_TRUE(db_->Execute("CREATE TABLE foo (x)"));
+ ASSERT_TRUE(db_->Execute("CREATE TABLE bar (x)"));
+ db_->Close();
- ASSERT_TRUE(CorruptSizeInHeaderOfDB());
+ ASSERT_TRUE(sql::test::CorruptSizeInHeader(db_path_));
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CORRUPT);
- ASSERT_TRUE(db().Open(db_path()));
- EXPECT_FALSE(db().Execute("INSERT INTO foo values (1)"));
- EXPECT_FALSE(db().DoesTableExist("foo"));
- EXPECT_FALSE(db().DoesTableExist("bar"));
- EXPECT_FALSE(db().Execute("SELECT * FROM foo"));
+ ASSERT_TRUE(db_->Open(db_path_));
+ EXPECT_FALSE(db_->Execute("INSERT INTO foo values (1)"));
+ EXPECT_FALSE(db_->DoesTableExist("foo"));
+ EXPECT_FALSE(db_->DoesTableExist("bar"));
+ EXPECT_FALSE(db_->Execute("SELECT * FROM foo"));
EXPECT_TRUE(expecter.SawExpectedErrors());
}
}
@@ -1361,8 +1415,8 @@ TEST_P(SQLDatabaseTest, CompileError) {
// DEATH tests not supported on Android, iOS, or Fuchsia.
#if !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
if (DLOG_IS_ON(FATAL)) {
- db().set_error_callback(base::BindRepeating(&IgnoreErrorCallback));
- ASSERT_DEATH({ db().GetUniqueStatement("SELECT x"); },
+ db_->set_error_callback(base::BindRepeating(&IgnoreErrorCallback));
+ ASSERT_DEATH({ db_->GetUniqueStatement("SELECT x"); },
"SQL compile error no such column: x");
}
#endif // !defined(OS_ANDROID) && !defined(OS_IOS) && !defined(OS_FUCHSIA)
diff --git a/chromium/sql/initialization.cc b/chromium/sql/initialization.cc
index 4fa0bc07342..58a1ed7a3da 100644
--- a/chromium/sql/initialization.cc
+++ b/chromium/sql/initialization.cc
@@ -9,6 +9,7 @@
#include "base/no_destructor.h"
#include "base/numerics/safe_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "third_party/sqlite/sqlite3.h"
@@ -52,6 +53,7 @@ void EnsureSqliteInitialized() {
static bool first_call = true;
if (first_call) {
+ TRACE_EVENT0("sql", "EnsureSqliteInitialized");
sqlite3_initialize();
#if !defined(OS_IOS)
diff --git a/chromium/sql/meta_table_unittest.cc b/chromium/sql/meta_table_unittest.cc
index 928c0ed02da..e91380b2279 100644
--- a/chromium/sql/meta_table_unittest.cc
+++ b/chromium/sql/meta_table_unittest.cc
@@ -10,22 +10,36 @@
#include "base/files/scoped_temp_dir.h"
#include "sql/database.h"
#include "sql/statement.h"
-#include "sql/test/sql_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace sql {
+
namespace {
-using SQLMetaTableTest = sql::SQLTestBase;
+class SQLMetaTableTest : public testing::Test {
+ public:
+ ~SQLMetaTableTest() override = default;
+
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ db_.Open(temp_dir_.GetPath().AppendASCII("meta_table_test.sqlite")));
+ }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ Database db_;
+};
TEST_F(SQLMetaTableTest, DoesTableExist) {
- EXPECT_FALSE(sql::MetaTable::DoesTableExist(&db()));
+ EXPECT_FALSE(MetaTable::DoesTableExist(&db_));
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
}
- EXPECT_TRUE(sql::MetaTable::DoesTableExist(&db()));
+ EXPECT_TRUE(MetaTable::DoesTableExist(&db_));
}
TEST_F(SQLMetaTableTest, RazeIfDeprecated) {
@@ -34,45 +48,45 @@ TEST_F(SQLMetaTableTest, RazeIfDeprecated) {
// Setup a current database.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), kVersion, kVersion));
- EXPECT_TRUE(db().Execute("CREATE TABLE t(c)"));
- EXPECT_TRUE(db().DoesTableExist("t"));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, kVersion, kVersion));
+ EXPECT_TRUE(db_.Execute("CREATE TABLE t(c)"));
+ EXPECT_TRUE(db_.DoesTableExist("t"));
}
// Table should should still exist if the database version is new enough.
- sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
- EXPECT_TRUE(db().DoesTableExist("t"));
+ MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion);
+ EXPECT_TRUE(db_.DoesTableExist("t"));
// TODO(shess): It may make sense to Raze() if meta isn't present or
// version isn't present. See meta_table.h TODO on RazeIfDeprecated().
// Table should still exist if the version is not available.
- EXPECT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'version'"));
+ EXPECT_TRUE(db_.Execute("DELETE FROM meta WHERE key = 'version'"));
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), kVersion, kVersion));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, kVersion, kVersion));
EXPECT_EQ(0, meta_table.GetVersionNumber());
}
- sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
- EXPECT_TRUE(db().DoesTableExist("t"));
+ MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion);
+ EXPECT_TRUE(db_.DoesTableExist("t"));
// Table should still exist if meta table is missing.
- EXPECT_TRUE(db().Execute("DROP TABLE meta"));
- sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
- EXPECT_TRUE(db().DoesTableExist("t"));
+ EXPECT_TRUE(db_.Execute("DROP TABLE meta"));
+ MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion);
+ EXPECT_TRUE(db_.DoesTableExist("t"));
// Setup meta with deprecated version.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), kDeprecatedVersion, kDeprecatedVersion));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, kDeprecatedVersion, kDeprecatedVersion));
}
// Deprecation check should remove the table.
- EXPECT_TRUE(db().DoesTableExist("t"));
- sql::MetaTable::RazeIfDeprecated(&db(), kDeprecatedVersion);
- EXPECT_FALSE(sql::MetaTable::DoesTableExist(&db()));
- EXPECT_FALSE(db().DoesTableExist("t"));
+ EXPECT_TRUE(db_.DoesTableExist("t"));
+ MetaTable::RazeIfDeprecated(&db_, kDeprecatedVersion);
+ EXPECT_FALSE(MetaTable::DoesTableExist(&db_));
+ EXPECT_FALSE(db_.DoesTableExist("t"));
}
TEST_F(SQLMetaTableTest, VersionNumber) {
@@ -87,16 +101,16 @@ TEST_F(SQLMetaTableTest, VersionNumber) {
// First Init() sets the version info as expected.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), kVersionFirst, kCompatVersionFirst));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, kVersionFirst, kCompatVersionFirst));
EXPECT_EQ(kVersionFirst, meta_table.GetVersionNumber());
EXPECT_EQ(kCompatVersionFirst, meta_table.GetCompatibleVersionNumber());
}
// Second Init() does not change the version info.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), kVersionSecond, kCompatVersionSecond));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, kVersionSecond, kCompatVersionSecond));
EXPECT_EQ(kVersionFirst, meta_table.GetVersionNumber());
EXPECT_EQ(kCompatVersionFirst, meta_table.GetCompatibleVersionNumber());
@@ -106,8 +120,8 @@ TEST_F(SQLMetaTableTest, VersionNumber) {
// Version info from Set*() calls is seen.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), kVersionThird, kCompatVersionThird));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, kVersionThird, kCompatVersionThird));
EXPECT_EQ(kVersionSecond, meta_table.GetVersionNumber());
EXPECT_EQ(kCompatVersionSecond, meta_table.GetCompatibleVersionNumber());
}
@@ -120,8 +134,8 @@ TEST_F(SQLMetaTableTest, StringValue) {
// Initially, the value isn't there until set.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
std::string value;
EXPECT_FALSE(meta_table.GetValue(kKey, &value));
@@ -133,8 +147,8 @@ TEST_F(SQLMetaTableTest, StringValue) {
// Value is persistent across different instances.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
std::string value;
EXPECT_TRUE(meta_table.GetValue(kKey, &value));
@@ -145,8 +159,8 @@ TEST_F(SQLMetaTableTest, StringValue) {
// Existing value was successfully changed.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
std::string value;
EXPECT_TRUE(meta_table.GetValue(kKey, &value));
@@ -161,8 +175,8 @@ TEST_F(SQLMetaTableTest, IntValue) {
// Initially, the value isn't there until set.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
int value;
EXPECT_FALSE(meta_table.GetValue(kKey, &value));
@@ -174,8 +188,8 @@ TEST_F(SQLMetaTableTest, IntValue) {
// Value is persistent across different instances.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
int value;
EXPECT_TRUE(meta_table.GetValue(kKey, &value));
@@ -186,8 +200,8 @@ TEST_F(SQLMetaTableTest, IntValue) {
// Existing value was successfully changed.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
int value;
EXPECT_TRUE(meta_table.GetValue(kKey, &value));
@@ -202,8 +216,8 @@ TEST_F(SQLMetaTableTest, Int64Value) {
// Initially, the value isn't there until set.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
int64_t value;
EXPECT_FALSE(meta_table.GetValue(kKey, &value));
@@ -215,8 +229,8 @@ TEST_F(SQLMetaTableTest, Int64Value) {
// Value is persistent across different instances.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
int64_t value;
EXPECT_TRUE(meta_table.GetValue(kKey, &value));
@@ -227,8 +241,8 @@ TEST_F(SQLMetaTableTest, Int64Value) {
// Existing value was successfully changed.
{
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
int64_t value;
EXPECT_TRUE(meta_table.GetValue(kKey, &value));
@@ -240,8 +254,8 @@ TEST_F(SQLMetaTableTest, DeleteKey) {
static const char kKey[] = "String Key";
const std::string kValue("String Value");
- sql::MetaTable meta_table;
- EXPECT_TRUE(meta_table.Init(&db(), 1, 1));
+ MetaTable meta_table;
+ EXPECT_TRUE(meta_table.Init(&db_, 1, 1));
// Value isn't present.
std::string value;
@@ -258,3 +272,5 @@ TEST_F(SQLMetaTableTest, DeleteKey) {
}
} // namespace
+
+} // namespace sql
diff --git a/chromium/sql/recover_module/module_unittest.cc b/chromium/sql/recover_module/module_unittest.cc
index ba620b7fda6..2e0db47cf26 100644
--- a/chromium/sql/recover_module/module_unittest.cc
+++ b/chromium/sql/recover_module/module_unittest.cc
@@ -7,12 +7,12 @@
#include <tuple>
#include <vector>
+#include "base/files/scoped_temp_dir.h"
#include "base/strings/stringprintf.h"
#include "sql/database.h"
#include "sql/statement.h"
#include "sql/test/database_test_peer.h"
#include "sql/test/scoped_error_expecter.h"
-#include "sql/test/sql_test_base.h"
#include "sql/test/test_helpers.h"
#include "sql/transaction.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,123 +21,131 @@
namespace sql {
namespace recover {
-class RecoverModuleTest : public sql::SQLTestBase {
+class RecoverModuleTest : public testing::Test {
public:
+ ~RecoverModuleTest() override = default;
+
void SetUp() override {
- SQLTestBase::SetUp();
- ASSERT_TRUE(DatabaseTestPeer::EnableRecoveryExtension(&db()));
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ db_.Open(temp_dir_.GetPath().AppendASCII("recovery_test.sqlite")));
+ ASSERT_TRUE(DatabaseTestPeer::EnableRecoveryExtension(&db_));
}
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ sql::Database db_;
};
TEST_F(RecoverModuleTest, CreateVtable) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
EXPECT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing, t TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing, t TEXT)"));
}
TEST_F(RecoverModuleTest, CreateVtableWithDatabaseSpecifier) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
EXPECT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(main.backing, t TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(main.backing, t TEXT)"));
}
TEST_F(RecoverModuleTest, CreateVtableOnSqliteMaster) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
EXPECT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing USING recover("
- "sqlite_master, type TEXT, name TEXT, tbl_name TEXT, "
- "rootpage INTEGER, sql TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing USING recover("
+ "sqlite_master, type TEXT, name TEXT, tbl_name TEXT, "
+ "rootpage INTEGER, sql TEXT)"));
}
TEST_F(RecoverModuleTest, CreateVtableFailsOnNonTempTable) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
- EXPECT_FALSE(db().Execute(
+ EXPECT_FALSE(db_.Execute(
"CREATE VIRTUAL TABLE recover_backing USING recover(backing, t TEXT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, CreateVtableFailsOnMissingTable) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_CORRUPT);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_missing "
- "USING recover(missing, t TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_missing "
+ "USING recover(missing, t TEXT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, DISABLED_CreateVtableFailsOnMissingDatabase) {
// TODO(pwnall): Enable test after removing incorrect DLOG(FATAL) from
// sql::Statement::Execute().
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_ERROR);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(db.backing, t TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(db.backing, t TEXT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, CreateVtableFailsOnTableWithInvalidQualifier) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_CORRUPT);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing invalid, t TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing invalid, t TEXT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, DISABLED_CreateVtableFailsOnMissingTableName) {
// TODO(pwnall): Enable test after removing incorrect DLOG(FATAL) from
// sql::Statement::Execute().
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_ERROR);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(main., t TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(main., t TEXT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, CreateVtableFailsOnMissingSchemaSpec) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, CreateVtableFailsOnMissingDbName) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(.backing)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(.backing)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, ColumnTypeMappingAny) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
EXPECT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing, t ANY)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing, t ANY)"));
sql::test::ColumnInfo column_info =
- sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "t");
+ sql::test::ColumnInfo::Create(&db_, "temp", "recover_backing", "t");
EXPECT_EQ("(nullptr)", column_info.data_type);
EXPECT_EQ("BINARY", column_info.collation_sequence);
EXPECT_FALSE(column_info.has_non_null_constraint);
@@ -145,13 +153,13 @@ TEST_F(RecoverModuleTest, ColumnTypeMappingAny) {
EXPECT_FALSE(column_info.is_auto_incremented);
}
TEST_F(RecoverModuleTest, ColumnTypeMappingAnyNotNull) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
EXPECT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing, t ANY NOT NULL)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing, t ANY NOT NULL)"));
sql::test::ColumnInfo column_info =
- sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "t");
+ sql::test::ColumnInfo::Create(&db_, "temp", "recover_backing", "t");
EXPECT_EQ("(nullptr)", column_info.data_type);
EXPECT_EQ("BINARY", column_info.collation_sequence);
EXPECT_TRUE(column_info.has_non_null_constraint);
@@ -159,58 +167,58 @@ TEST_F(RecoverModuleTest, ColumnTypeMappingAnyNotNull) {
EXPECT_FALSE(column_info.is_auto_incremented);
}
TEST_F(RecoverModuleTest, ColumnTypeMappingAnyStrict) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing, t ANY STRICT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing, t ANY STRICT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, ColumnTypeExtraKeyword) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing, t INTEGER SOMETHING)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing, t INTEGER SOMETHING)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, ColumnTypeNotNullExtraKeyword) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing, t INTEGER NOT NULL SOMETHING)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing, t INTEGER NOT NULL SOMETHING)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, ColumnTypeDoubleTypes) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing "
- "USING recover(backing, t INTEGER FLOAT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing "
+ "USING recover(backing, t INTEGER FLOAT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
TEST_F(RecoverModuleTest, ColumnTypeNotNullDoubleTypes) {
- ASSERT_TRUE(db().Execute("CREATE TABLE backing(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE backing(t TEXT)"));
{
sql::test::ScopedErrorExpecter error_expecter;
error_expecter.ExpectError(SQLITE_MISUSE);
EXPECT_FALSE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_backing USING recover("
- "backing, t INTEGER NOT NULL TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_backing USING recover("
+ "backing, t INTEGER NOT NULL TEXT)"));
EXPECT_TRUE(error_expecter.SawExpectedErrors());
}
}
@@ -220,30 +228,39 @@ class RecoverModuleColumnTypeMappingTest
public ::testing::WithParamInterface<
std::tuple<const char*, const char*, bool>> {
public:
+ ~RecoverModuleColumnTypeMappingTest() override = default;
+
void SetUp() override {
- RecoverModuleTest::SetUp();
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ db_.Open(temp_dir_.GetPath().AppendASCII("recovery_test.sqlite")));
+ ASSERT_TRUE(DatabaseTestPeer::EnableRecoveryExtension(&db_));
+
std::string sql =
base::StringPrintf("CREATE TABLE backing(data %s)", SchemaType());
- ASSERT_TRUE(db().Execute(sql.c_str()));
+ ASSERT_TRUE(db_.Execute(sql.c_str()));
}
- protected:
void CreateRecoveryTable(const char* suffix) {
std::string sql = base::StringPrintf(
"CREATE VIRTUAL TABLE temp.recover_backing "
"USING recover(backing, data %s%s)",
SchemaType(), suffix);
- ASSERT_TRUE(db().Execute(sql.c_str()));
+ ASSERT_TRUE(db_.Execute(sql.c_str()));
}
const char* SchemaType() const { return std::get<0>(GetParam()); }
const char* ExpectedType() const { return std::get<1>(GetParam()); }
bool IsAlwaysNonNull() const { return std::get<2>(GetParam()); }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ sql::Database db_;
};
TEST_P(RecoverModuleColumnTypeMappingTest, Unqualified) {
CreateRecoveryTable("");
sql::test::ColumnInfo column_info =
- sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data");
+ sql::test::ColumnInfo::Create(&db_, "temp", "recover_backing", "data");
EXPECT_EQ(ExpectedType(), column_info.data_type);
EXPECT_EQ("BINARY", column_info.collation_sequence);
EXPECT_EQ(IsAlwaysNonNull(), column_info.has_non_null_constraint);
@@ -253,7 +270,7 @@ TEST_P(RecoverModuleColumnTypeMappingTest, Unqualified) {
TEST_P(RecoverModuleColumnTypeMappingTest, NotNull) {
CreateRecoveryTable(" NOT NULL");
sql::test::ColumnInfo column_info =
- sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data");
+ sql::test::ColumnInfo::Create(&db_, "temp", "recover_backing", "data");
EXPECT_EQ(ExpectedType(), column_info.data_type);
EXPECT_EQ("BINARY", column_info.collation_sequence);
EXPECT_TRUE(column_info.has_non_null_constraint);
@@ -263,7 +280,7 @@ TEST_P(RecoverModuleColumnTypeMappingTest, NotNull) {
TEST_P(RecoverModuleColumnTypeMappingTest, Strict) {
CreateRecoveryTable(" STRICT");
sql::test::ColumnInfo column_info =
- sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data");
+ sql::test::ColumnInfo::Create(&db_, "temp", "recover_backing", "data");
EXPECT_EQ(ExpectedType(), column_info.data_type);
EXPECT_EQ("BINARY", column_info.collation_sequence);
EXPECT_EQ(IsAlwaysNonNull(), column_info.has_non_null_constraint);
@@ -273,7 +290,7 @@ TEST_P(RecoverModuleColumnTypeMappingTest, Strict) {
TEST_P(RecoverModuleColumnTypeMappingTest, StrictNotNull) {
CreateRecoveryTable(" STRICT NOT NULL");
sql::test::ColumnInfo column_info =
- sql::test::ColumnInfo::Create(&db(), "temp", "recover_backing", "data");
+ sql::test::ColumnInfo::Create(&db_, "temp", "recover_backing", "data");
EXPECT_EQ(ExpectedType(), column_info.data_type);
EXPECT_EQ("BINARY", column_info.collation_sequence);
EXPECT_TRUE(column_info.has_non_null_constraint);
@@ -305,12 +322,12 @@ void GenerateAlteredTable(sql::Database* db) {
} // namespace
TEST_F(RecoverModuleTest, ReadFromAlteredTableNullDefaults) {
- GenerateAlteredTable(&db());
+ GenerateAlteredTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_altered "
- "USING recover(altered, t TEXT, i INTEGER)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_altered "
+ "USING recover(altered, t TEXT, i INTEGER)"));
- sql::Statement statement(db().GetUniqueStatement(
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT t, i FROM recover_altered ORDER BY rowid"));
ASSERT_TRUE(statement.Step());
EXPECT_EQ("a", statement.ColumnString(0));
@@ -329,12 +346,12 @@ TEST_F(RecoverModuleTest, ReadFromAlteredTableNullDefaults) {
}
TEST_F(RecoverModuleTest, ReadFromAlteredTableSkipsNulls) {
- GenerateAlteredTable(&db());
+ GenerateAlteredTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_altered "
- "USING recover(altered, t TEXT, i INTEGER NOT NULL)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_altered "
+ "USING recover(altered, t TEXT, i INTEGER NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT t, i FROM recover_altered ORDER BY rowid"));
ASSERT_TRUE(statement.Step());
EXPECT_EQ("d", statement.ColumnString(0));
@@ -366,13 +383,13 @@ void GenerateSizedTable(sql::Database* db,
} // namespace
TEST_F(RecoverModuleTest, LeafNodes) {
- GenerateSizedTable(&db(), 10, "Leaf-node-generating line ");
+ GenerateSizedTable(&db_, 10, "Leaf-node-generating line ");
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_sized "
- "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_sized "
+ "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
sql::Statement statement(
- db().GetUniqueStatement("SELECT t, i FROM recover_sized ORDER BY rowid"));
+ db_.GetUniqueStatement("SELECT t, i FROM recover_sized ORDER BY rowid"));
for (int i = 0; i < 10; ++i) {
ASSERT_TRUE(statement.Step());
EXPECT_EQ(base::StringPrintf("Leaf-node-generating line %d", i),
@@ -383,22 +400,22 @@ TEST_F(RecoverModuleTest, LeafNodes) {
}
TEST_F(RecoverModuleTest, EmptyTable) {
- GenerateSizedTable(&db(), 0, "");
+ GenerateSizedTable(&db_, 0, "");
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_sized "
- "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_sized "
+ "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, t, i FROM recover_sized ORDER BY rowid"));
EXPECT_FALSE(statement.Step());
}
TEST_F(RecoverModuleTest, SingleLevelInteriorNodes) {
- GenerateSizedTable(&db(), 100, "Interior-node-generating line ");
+ GenerateSizedTable(&db_, 100, "Interior-node-generating line ");
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_sized "
- "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_sized "
+ "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, t, i FROM recover_sized ORDER BY rowid"));
for (int i = 0; i < 100; ++i) {
ASSERT_TRUE(statement.Step());
@@ -411,12 +428,12 @@ TEST_F(RecoverModuleTest, SingleLevelInteriorNodes) {
}
TEST_F(RecoverModuleTest, MultiLevelInteriorNodes) {
- GenerateSizedTable(&db(), 5000, "Interior-node-generating line ");
+ GenerateSizedTable(&db_, 5000, "Interior-node-generating line ");
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_sized "
- "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_sized "
+ "USING recover(sized, t TEXT, i INTEGER NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, t, i FROM recover_sized ORDER BY rowid"));
for (int i = 0; i < 5000; ++i) {
ASSERT_TRUE(statement.Step());
@@ -444,11 +461,11 @@ void GenerateTypesTable(sql::Database* db) {
} // namespace
TEST_F(RecoverModuleTest, Any) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value ANY)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value ANY)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -482,11 +499,11 @@ TEST_F(RecoverModuleTest, Any) {
}
TEST_F(RecoverModuleTest, Integers) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value INTEGER)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value INTEGER)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -503,11 +520,11 @@ TEST_F(RecoverModuleTest, Integers) {
}
TEST_F(RecoverModuleTest, NonNullIntegers) {
- GenerateTypesTable(&db());
- ASSERT_TRUE(db().Execute(
+ GenerateTypesTable(&db_);
+ ASSERT_TRUE(db_.Execute(
"CREATE VIRTUAL TABLE temp.recover_types "
"USING recover(types, rowtype TEXT, value INTEGER NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -520,11 +537,11 @@ TEST_F(RecoverModuleTest, NonNullIntegers) {
}
TEST_F(RecoverModuleTest, Floats) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value FLOAT)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value FLOAT)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -546,11 +563,11 @@ TEST_F(RecoverModuleTest, Floats) {
}
TEST_F(RecoverModuleTest, NonNullFloats) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value FLOAT NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value FLOAT NOT NULL)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -568,11 +585,11 @@ TEST_F(RecoverModuleTest, NonNullFloats) {
}
TEST_F(RecoverModuleTest, FloatsStrict) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value FLOAT STRICT)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value FLOAT STRICT)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -589,11 +606,11 @@ TEST_F(RecoverModuleTest, FloatsStrict) {
}
TEST_F(RecoverModuleTest, NonNullFloatsStrict) {
- GenerateTypesTable(&db());
- ASSERT_TRUE(db().Execute(
+ GenerateTypesTable(&db_);
+ ASSERT_TRUE(db_.Execute(
"CREATE VIRTUAL TABLE temp.recover_types "
"USING recover(types, rowtype TEXT, value FLOAT STRICT NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -606,11 +623,11 @@ TEST_F(RecoverModuleTest, NonNullFloatsStrict) {
}
TEST_F(RecoverModuleTest, Texts) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value TEXT)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value TEXT)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -634,11 +651,11 @@ TEST_F(RecoverModuleTest, Texts) {
}
TEST_F(RecoverModuleTest, NonNullTexts) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value TEXT NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value TEXT NOT NULL)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -658,11 +675,11 @@ TEST_F(RecoverModuleTest, NonNullTexts) {
}
TEST_F(RecoverModuleTest, TextsStrict) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value TEXT STRICT)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value TEXT STRICT)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -679,11 +696,11 @@ TEST_F(RecoverModuleTest, TextsStrict) {
}
TEST_F(RecoverModuleTest, NonNullTextsStrict) {
- GenerateTypesTable(&db());
- ASSERT_TRUE(db().Execute(
+ GenerateTypesTable(&db_);
+ ASSERT_TRUE(db_.Execute(
"CREATE VIRTUAL TABLE temp.recover_types "
"USING recover(types, rowtype TEXT, value TEXT STRICT NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -696,11 +713,11 @@ TEST_F(RecoverModuleTest, NonNullTextsStrict) {
}
TEST_F(RecoverModuleTest, Blobs) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value BLOB)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value BLOB)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -719,11 +736,11 @@ TEST_F(RecoverModuleTest, Blobs) {
}
TEST_F(RecoverModuleTest, NonNullBlobs) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value BLOB NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value BLOB NOT NULL)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -738,11 +755,11 @@ TEST_F(RecoverModuleTest, NonNullBlobs) {
}
TEST_F(RecoverModuleTest, AnyNonNull) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_types "
- "USING recover(types, rowtype TEXT, value ANY NOT NULL)"));
- sql::Statement statement(db().GetUniqueStatement(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_types "
+ "USING recover(types, rowtype TEXT, value ANY NOT NULL)"));
+ sql::Statement statement(db_.GetUniqueStatement(
"SELECT rowid, rowtype, value FROM recover_types"));
ASSERT_TRUE(statement.Step());
@@ -772,20 +789,20 @@ TEST_F(RecoverModuleTest, AnyNonNull) {
}
TEST_F(RecoverModuleTest, RowidAlias) {
- GenerateTypesTable(&db());
+ GenerateTypesTable(&db_);
// The id column is an alias for rowid, and its values get serialized as NULL.
- ASSERT_TRUE(db().Execute(
+ ASSERT_TRUE(db_.Execute(
"CREATE TABLE types2(id INTEGER PRIMARY KEY, rowtype TEXT, value)"));
ASSERT_TRUE(
- db().Execute("INSERT INTO types2(id, rowtype, value) "
- "SELECT rowid, rowtype, value FROM types WHERE true"));
- ASSERT_TRUE(db().Execute(
+ db_.Execute("INSERT INTO types2(id, rowtype, value) "
+ "SELECT rowid, rowtype, value FROM types WHERE true"));
+ ASSERT_TRUE(db_.Execute(
"CREATE VIRTUAL TABLE temp.recover_types2 "
"USING recover(types2, id ROWID NOT NULL, rowtype TEXT, value ANY)"));
sql::Statement statement(
- db().GetUniqueStatement("SELECT id, rowid, rowtype, value FROM types2"));
+ db_.GetUniqueStatement("SELECT id, rowid, rowtype, value FROM types2"));
ASSERT_TRUE(statement.Step());
EXPECT_EQ(1, statement.ColumnInt(0));
@@ -819,7 +836,7 @@ TEST_F(RecoverModuleTest, RowidAlias) {
}
TEST_F(RecoverModuleTest, IntegerEncodings) {
- ASSERT_TRUE(db().Execute("CREATE TABLE integers(value)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE integers(value)"));
const std::vector<int64_t> values = {
// Encoded directly in type info.
@@ -857,7 +874,7 @@ TEST_F(RecoverModuleTest, IntegerEncodings) {
-9223372036854775807,
};
sql::Statement insert(
- db().GetUniqueStatement("INSERT INTO integers VALUES(?)"));
+ db_.GetUniqueStatement("INSERT INTO integers VALUES(?)"));
for (int64_t value : values) {
insert.BindInt64(0, value);
ASSERT_TRUE(insert.Run());
@@ -865,10 +882,10 @@ TEST_F(RecoverModuleTest, IntegerEncodings) {
}
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_integers "
- "USING recover(integers, value INTEGER)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_integers "
+ "USING recover(integers, value INTEGER)"));
sql::Statement select(
- db().GetUniqueStatement("SELECT rowid, value FROM recover_integers"));
+ db_.GetUniqueStatement("SELECT rowid, value FROM recover_integers"));
for (size_t i = 0; i < values.size(); ++i) {
ASSERT_TRUE(select.Step()) << "Was attemping to read " << values[i];
EXPECT_EQ(static_cast<int>(i + 1), select.ColumnInt(0));
@@ -967,38 +984,38 @@ TEST_F(RecoverModuleTest, VarintEncodings) {
-0x8000000000000000,
};
- ASSERT_TRUE(db().Execute("CREATE TABLE varints(value INTEGER PRIMARY KEY)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE varints(value INTEGER PRIMARY KEY)"));
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_varints "
- "USING recover(varints, value ROWID)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_varints "
+ "USING recover(varints, value ROWID)"));
for (int64_t value : values) {
sql::Statement insert(
- db().GetUniqueStatement("INSERT INTO varints VALUES(?)"));
+ db_.GetUniqueStatement("INSERT INTO varints VALUES(?)"));
insert.BindInt64(0, value);
ASSERT_TRUE(insert.Run());
sql::Statement select(
- db().GetUniqueStatement("SELECT rowid, value FROM recover_varints"));
+ db_.GetUniqueStatement("SELECT rowid, value FROM recover_varints"));
ASSERT_TRUE(select.Step()) << "Was attemping to read " << value;
EXPECT_EQ(value, select.ColumnInt64(0));
EXPECT_EQ(value, select.ColumnInt64(1));
EXPECT_FALSE(select.Step());
- ASSERT_TRUE(db().Execute("DELETE FROM varints"));
+ ASSERT_TRUE(db_.Execute("DELETE FROM varints"));
}
}
TEST_F(RecoverModuleTest, TextEncodings) {
- ASSERT_TRUE(db().Execute("CREATE TABLE encodings(t TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE encodings(t TEXT)"));
const std::vector<std::string> values = {
- u8"Mjollnir", u8"Mjölnir", u8"Mjǫlnir",
- u8"Mjölner", u8"Mjølner", u8"ハンマー",
+ "", "a", u8"ö", u8"Mjollnir", u8"Mjölnir",
+ u8"Mjǫlnir", u8"Mjölner", u8"Mjølner", u8"ハンマー",
};
sql::Statement insert(
- db().GetUniqueStatement("INSERT INTO encodings VALUES(?)"));
+ db_.GetUniqueStatement("INSERT INTO encodings VALUES(?)"));
for (const std::string& value : values) {
insert.BindString(0, value);
ASSERT_TRUE(insert.Run());
@@ -1006,10 +1023,10 @@ TEST_F(RecoverModuleTest, TextEncodings) {
}
ASSERT_TRUE(
- db().Execute("CREATE VIRTUAL TABLE temp.recover_encodings "
- "USING recover(encodings, t TEXT)"));
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_encodings "
+ "USING recover(encodings, t TEXT)"));
sql::Statement select(
- db().GetUniqueStatement("SELECT rowid, t FROM recover_encodings"));
+ db_.GetUniqueStatement("SELECT rowid, t FROM recover_encodings"));
for (size_t i = 0; i < values.size(); ++i) {
ASSERT_TRUE(select.Step());
EXPECT_EQ(static_cast<int>(i + 1), select.ColumnInt(0));
@@ -1018,6 +1035,46 @@ TEST_F(RecoverModuleTest, TextEncodings) {
EXPECT_FALSE(select.Step());
}
+TEST_F(RecoverModuleTest, BlobEncodings) {
+ ASSERT_TRUE(db_.Execute("CREATE TABLE blob_encodings(t BLOB)"));
+
+ const std::vector<std::vector<uint8_t>> values = {
+ {}, {0x00}, {0x01},
+ {0x42}, {0xff}, {0x00, 0x00},
+ {0x00, 0x01}, {0x00, 0xff}, {0x42, 0x43, 0x44, 0x45, 0x46},
+ };
+
+ sql::Statement insert(
+ db_.GetUniqueStatement("INSERT INTO blob_encodings VALUES(?)"));
+ for (const std::vector<uint8_t>& value : values) {
+ // std::vector::data() returns nullptr for empty vectors. Unfortunately,
+ // sqlite3_bind_blob() always interprets null data as a NULL value. In this
+ // case, we really want to write an empty blob, so we need to pass non-null
+ // data.
+ const uint8_t* blob_data =
+ (value.size() > 0) ? value.data() : values[1].data();
+
+ insert.BindBlob(0, blob_data, value.size());
+ ASSERT_TRUE(insert.Run());
+ insert.Reset(/* clear_bound_vars= */ true);
+ }
+
+ ASSERT_TRUE(
+ db_.Execute("CREATE VIRTUAL TABLE temp.recover_blob_encodings "
+ "USING recover(blob_encodings, t BLOB)"));
+ sql::Statement select(
+ db_.GetUniqueStatement("SELECT rowid, t FROM recover_blob_encodings"));
+ for (size_t i = 0; i < values.size(); ++i) {
+ ASSERT_TRUE(select.Step());
+ EXPECT_EQ(static_cast<int>(i + 1), select.ColumnInt(0));
+
+ std::vector<uint8_t> column_value;
+ EXPECT_TRUE(select.ColumnBlobAsVector(1, &column_value));
+ EXPECT_EQ(values[i], column_value);
+ }
+ EXPECT_FALSE(select.Step());
+}
+
namespace {
std::string RandomString(int size) {
@@ -1073,60 +1130,60 @@ constexpr int kOverflowOverhead = 4;
} // namespace
TEST_F(RecoverModuleTest, ValueWithoutOverflow) {
- CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead);
- int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0;
- ASSERT_EQ(2 + auto_vacuum_pages, sql::test::GetPageCount(&db()))
+ CheckLargeValueRecovery(&db_, db_.page_size() - kRecordOverhead);
+ int auto_vacuum_pages = HasEnabledAutoVacuum(&db_) ? 1 : 0;
+ ASSERT_EQ(2 + auto_vacuum_pages, sql::test::GetPageCount(&db_))
<< "Database should have a root page and a leaf page";
}
TEST_F(RecoverModuleTest, ValueWithOneByteOverflow) {
- CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead + 1);
- int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0;
- ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db()))
+ CheckLargeValueRecovery(&db_, db_.page_size() - kRecordOverhead + 1);
+ int auto_vacuum_pages = HasEnabledAutoVacuum(&db_) ? 1 : 0;
+ ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db_))
<< "Database should have a root page, a leaf page, and 1 overflow page";
}
TEST_F(RecoverModuleTest, ValueWithOneOverflowPage) {
CheckLargeValueRecovery(
- &db(), db().page_size() - kRecordOverhead + db().page_size() / 2);
- int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0;
- ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db()))
+ &db_, db_.page_size() - kRecordOverhead + db_.page_size() / 2);
+ int auto_vacuum_pages = HasEnabledAutoVacuum(&db_) ? 1 : 0;
+ ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db_))
<< "Database should have a root page, a leaf page, and 1 overflow page";
}
TEST_F(RecoverModuleTest, ValueWithOneFullOverflowPage) {
- CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead +
- db().page_size() - kOverflowOverhead);
- int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0;
- ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db()))
+ CheckLargeValueRecovery(&db_, db_.page_size() - kRecordOverhead +
+ db_.page_size() - kOverflowOverhead);
+ int auto_vacuum_pages = HasEnabledAutoVacuum(&db_) ? 1 : 0;
+ ASSERT_EQ(3 + auto_vacuum_pages, sql::test::GetPageCount(&db_))
<< "Database should have a root page, a leaf page, and 1 overflow page";
}
TEST_F(RecoverModuleTest, ValueWithOneByteSecondOverflowPage) {
- CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead +
- db().page_size() - kOverflowOverhead + 1);
- int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0;
- ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db()))
+ CheckLargeValueRecovery(&db_, db_.page_size() - kRecordOverhead +
+ db_.page_size() - kOverflowOverhead + 1);
+ int auto_vacuum_pages = HasEnabledAutoVacuum(&db_) ? 1 : 0;
+ ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db_))
<< "Database should have a root page, a leaf page, and 2 overflow pages";
}
TEST_F(RecoverModuleTest, ValueWithTwoOverflowPages) {
- CheckLargeValueRecovery(&db(), db().page_size() - kRecordOverhead +
- db().page_size() - kOverflowOverhead +
- db().page_size() / 2);
- int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0;
- ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db()))
+ CheckLargeValueRecovery(&db_, db_.page_size() - kRecordOverhead +
+ db_.page_size() - kOverflowOverhead +
+ db_.page_size() / 2);
+ int auto_vacuum_pages = HasEnabledAutoVacuum(&db_) ? 1 : 0;
+ ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db_))
<< "Database should have a root page, a leaf page, and 2 overflow pages";
}
TEST_F(RecoverModuleTest, ValueWithTwoFullOverflowPages) {
// This value is large enough that the varint encoding of its type ID takes up
// 3 bytes, instead of 2.
- CheckLargeValueRecovery(&db(),
- db().page_size() - kRecordOverhead +
- (db().page_size() - kOverflowOverhead) * 2 - 1);
- int auto_vacuum_pages = HasEnabledAutoVacuum(&db()) ? 1 : 0;
- ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db()))
+ CheckLargeValueRecovery(&db_, db_.page_size() - kRecordOverhead +
+ (db_.page_size() - kOverflowOverhead) * 2 -
+ 1);
+ int auto_vacuum_pages = HasEnabledAutoVacuum(&db_) ? 1 : 0;
+ ASSERT_EQ(4 + auto_vacuum_pages, sql::test::GetPageCount(&db_))
<< "Database should have a root page, a leaf page, and 2 overflow pages";
}
diff --git a/chromium/sql/recover_module/parsing.cc b/chromium/sql/recover_module/parsing.cc
index 383ebe275b2..bbcf0b20b9c 100644
--- a/chromium/sql/recover_module/parsing.cc
+++ b/chromium/sql/recover_module/parsing.cc
@@ -10,10 +10,10 @@
#include "base/check.h"
#include "base/notreached.h"
-#include "base/optional.h"
#include "base/strings/strcat.h"
#include "base/strings/string_piece.h"
#include "sql/recover_module/record.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace sql {
namespace recover {
@@ -62,7 +62,7 @@ constexpr base::StringPiece kStrictSql("STRICT");
constexpr base::StringPiece kNonNullSql1("NOT");
constexpr base::StringPiece kNonNullSql2("NULL");
-base::Optional<ModuleColumnType> ParseColumnType(
+absl::optional<ModuleColumnType> ParseColumnType(
base::StringPiece column_type_sql) {
if (column_type_sql == kIntegerSql)
return ModuleColumnType::kInteger;
@@ -79,7 +79,7 @@ base::Optional<ModuleColumnType> ParseColumnType(
if (column_type_sql == kAnySql)
return ModuleColumnType::kAny;
- return base::nullopt;
+ return absl::nullopt;
}
// Returns a view into a SQL string representing the column type.
@@ -152,7 +152,7 @@ RecoveredColumnSpec ParseColumnSpec(const char* sqlite_arg) {
base::StringPiece column_type_sql;
std::tie(column_type_sql, sql) = SplitToken(sql);
- base::Optional<ModuleColumnType> column_type =
+ absl::optional<ModuleColumnType> column_type =
ParseColumnType(column_type_sql);
if (!column_type.has_value()) {
// Invalid column type.
@@ -192,7 +192,7 @@ RecoveredColumnSpec ParseColumnSpec(const char* sqlite_arg) {
result.is_non_null = true;
}
- result.name = column_name.as_string();
+ result.name = std::string(column_name);
return result;
}
@@ -212,7 +212,7 @@ TargetTableSpec ParseTableSpec(const char* sqlite_arg) {
base::StringPiece db_name = sql.substr(0, separator_pos);
base::StringPiece table_name = sql.substr(separator_pos + 1);
- return TargetTableSpec{db_name.as_string(), table_name.as_string()};
+ return TargetTableSpec{std::string(db_name), std::string(table_name)};
}
} // namespace recover
diff --git a/chromium/sql/recover_module/record.cc b/chromium/sql/recover_module/record.cc
index 6c2be3fe91d..f85def5944f 100644
--- a/chromium/sql/recover_module/record.cc
+++ b/chromium/sql/recover_module/record.cc
@@ -246,7 +246,7 @@ bool RecordReader::ReadValue(int column_index,
DCHECK(!header.has_inline_value);
uint8_t* const value_bytes = new uint8_t[size];
- if (!payload_reader_->ReadPayload(offset, size, value_bytes)) {
+ if (size > 0 && !payload_reader_->ReadPayload(offset, size, value_bytes)) {
delete[] value_bytes;
return false;
}
@@ -313,4 +313,4 @@ int64_t RecordReader::InitializeHeaderBuffer() {
}
} // namespace recover
-} // namespace sql \ No newline at end of file
+} // namespace sql
diff --git a/chromium/sql/recover_module/table.cc b/chromium/sql/recover_module/table.cc
index 65857e4368d..04f66ac77ee 100644
--- a/chromium/sql/recover_module/table.cc
+++ b/chromium/sql/recover_module/table.cc
@@ -20,12 +20,12 @@ namespace recover {
// Returns a null optional if the operation fails in any way. The failure is
// most likely due to an incorrect table spec (missing attachment or table).
// Corrupted SQLite metadata can cause failures here.
-base::Optional<int> GetTableRootPageId(sqlite3* sqlite_db,
+absl::optional<int> GetTableRootPageId(sqlite3* sqlite_db,
const TargetTableSpec& table) {
if (table.table_name == "sqlite_master") {
// The sqlite_master table is always rooted at the first page.
// SQLite page IDs use 1-based indexing.
- return base::Optional<int64_t>(1);
+ return absl::optional<int64_t>(1);
}
std::string select_sql =
@@ -36,7 +36,7 @@ base::Optional<int> GetTableRootPageId(sqlite3* sqlite_db,
SQLITE_PREPARE_NO_VTAB, &sqlite_statement,
nullptr) != SQLITE_OK) {
// The sqlite_master table is missing or its schema is corrupted.
- return base::nullopt;
+ return absl::nullopt;
}
if (sqlite3_bind_text(sqlite_statement, 1, table.table_name.c_str(),
@@ -44,13 +44,13 @@ base::Optional<int> GetTableRootPageId(sqlite3* sqlite_db,
SQLITE_STATIC) != SQLITE_OK) {
// Binding the table name failed. This shouldn't happen.
sqlite3_finalize(sqlite_statement);
- return base::nullopt;
+ return absl::nullopt;
}
if (sqlite3_step(sqlite_statement) != SQLITE_ROW) {
// The database attachment point or table does not exist.
sqlite3_finalize(sqlite_statement);
- return base::nullopt;
+ return absl::nullopt;
}
int64_t root_page = sqlite3_column_int64(sqlite_statement, 0);
@@ -58,13 +58,13 @@ base::Optional<int> GetTableRootPageId(sqlite3* sqlite_db,
if (!DatabasePageReader::IsValidPageId(root_page)) {
// Database corruption.
- return base::nullopt;
+ return absl::nullopt;
}
static_assert(
DatabasePageReader::kMaxPageId <= std::numeric_limits<int>::max(),
"Converting the page ID to int may overflow");
- return base::make_optional(static_cast<int>(root_page));
+ return absl::make_optional(static_cast<int>(root_page));
}
// Returns (SQLite status, a SQLite database's page size).
@@ -125,7 +125,7 @@ std::pair<int, std::unique_ptr<VirtualTable>> VirtualTable::Create(
std::vector<RecoveredColumnSpec> column_specs) {
DCHECK(backing_table_spec.IsValid());
- base::Optional<int64_t> backing_table_root_page_id =
+ absl::optional<int64_t> backing_table_root_page_id =
GetTableRootPageId(sqlite_db, backing_table_spec);
if (!backing_table_root_page_id.has_value()) {
// Either the backing table specification is incorrect, or the database
diff --git a/chromium/sql/recover_module/table.h b/chromium/sql/recover_module/table.h
index 409d12cf8c2..95d6f9ea79b 100644
--- a/chromium/sql/recover_module/table.h
+++ b/chromium/sql/recover_module/table.h
@@ -12,8 +12,8 @@
#include <vector>
#include "base/check_op.h"
-#include "base/optional.h"
#include "sql/recover_module/parsing.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/sqlite/sqlite3.h"
namespace sql {
diff --git a/chromium/sql/recovery_unittest.cc b/chromium/sql/recovery_unittest.cc
index afd386574f3..f40290757a0 100644
--- a/chromium/sql/recovery_unittest.cc
+++ b/chromium/sql/recovery_unittest.cc
@@ -22,11 +22,12 @@
#include "sql/statement.h"
#include "sql/test/paths.h"
#include "sql/test/scoped_error_expecter.h"
-#include "sql/test/sql_test_base.h"
#include "sql/test/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
+namespace sql {
+
namespace {
using sql::test::ExecuteWithResult;
@@ -36,81 +37,104 @@ using sql::test::ExecuteWithResults;
// schema. For tables or indices, this will contain the sql command
// to create the table or index. For certain automatic SQLite
// structures with no sql, the name is used.
-std::string GetSchema(sql::Database* db) {
+std::string GetSchema(Database* db) {
static const char kSql[] =
"SELECT COALESCE(sql, name) FROM sqlite_master ORDER BY 1";
return ExecuteWithResults(db, kSql, "|", "\n");
}
-using SQLRecoveryTest = sql::SQLTestBase;
+class SQLRecoveryTest : public testing::Test {
+ public:
+ ~SQLRecoveryTest() override = default;
+
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ db_path_ = temp_dir_.GetPath().AppendASCII("recovery_test.sqlite");
+ ASSERT_TRUE(db_.Open(db_path_));
+ }
+
+ bool Reopen() {
+ db_.Close();
+ return db_.Open(db_path_);
+ }
-// Baseline sql::Recovery test covering the different ways to dispose of the
-// scoped pointer received from sql::Recovery::Begin().
+ bool OverwriteDatabaseHeader() {
+ base::File file(db_path_,
+ base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+ static constexpr char kText[] = "Now is the winter of our discontent.";
+ constexpr int kTextBytes = sizeof(kText) - 1;
+ return file.Write(0, kText, kTextBytes) == kTextBytes;
+ }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ base::FilePath db_path_;
+ Database db_;
+};
+
+// Baseline Recovery test covering the different ways to dispose of the
+// scoped pointer received from Recovery::Begin().
TEST_F(SQLRecoveryTest, RecoverBasic) {
static const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
static const char kInsertSql[] = "INSERT INTO x VALUES ('This is a test')";
static const char kAltInsertSql[] =
"INSERT INTO x VALUES ('That was a test')";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute(kInsertSql));
- ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute(kInsertSql));
+ ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db_));
// If the Recovery handle goes out of scope without being
// Recovered(), the database is razed.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery.get());
}
- EXPECT_FALSE(db().is_open());
+ EXPECT_FALSE(db_.is_open());
ASSERT_TRUE(Reopen());
- EXPECT_TRUE(db().is_open());
- ASSERT_EQ("", GetSchema(&db()));
+ EXPECT_TRUE(db_.is_open());
+ ASSERT_EQ("", GetSchema(&db_));
// Recreate the database.
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute(kInsertSql));
- ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute(kInsertSql));
+ ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db_));
// Unrecoverable() also razes.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery.get());
- sql::Recovery::Unrecoverable(std::move(recovery));
+ Recovery::Unrecoverable(std::move(recovery));
- // TODO(shess): Test that calls to recover.db() start failing.
+ // TODO(shess): Test that calls to recover.db_ start failing.
}
- EXPECT_FALSE(db().is_open());
+ EXPECT_FALSE(db_.is_open());
ASSERT_TRUE(Reopen());
- EXPECT_TRUE(db().is_open());
- ASSERT_EQ("", GetSchema(&db()));
+ EXPECT_TRUE(db_.is_open());
+ ASSERT_EQ("", GetSchema(&db_));
// Attempting to recover a previously-recovered handle fails early.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery.get());
recovery.reset();
- recovery = sql::Recovery::Begin(&db(), db_path());
+ recovery = Recovery::Begin(&db_, db_path_);
ASSERT_FALSE(recovery.get());
}
ASSERT_TRUE(Reopen());
// Recreate the database.
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute(kInsertSql));
- ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute(kInsertSql));
+ ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db_));
// Unrecovered table to distinguish from recovered database.
- ASSERT_TRUE(db().Execute("CREATE TABLE y (c INTEGER)"));
- ASSERT_NE("CREATE TABLE x (t TEXT)", GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE y (c INTEGER)"));
+ ASSERT_NE("CREATE TABLE x (t TEXT)", GetSchema(&db_));
// Recovered() replaces the original with the "recovered" version.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery.get());
// Create the new version of the table.
@@ -120,50 +144,48 @@ TEST_F(SQLRecoveryTest, RecoverBasic) {
ASSERT_TRUE(recovery->db()->Execute(kAltInsertSql));
// Successfully recovered.
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
- EXPECT_FALSE(db().is_open());
+ EXPECT_FALSE(db_.is_open());
ASSERT_TRUE(Reopen());
- EXPECT_TRUE(db().is_open());
- ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
+ EXPECT_TRUE(db_.is_open());
+ ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db_));
const char* kXSql = "SELECT * FROM x ORDER BY 1";
- ASSERT_EQ("That was a test", ExecuteWithResult(&db(), kXSql));
+ ASSERT_EQ("That was a test", ExecuteWithResult(&db_, kXSql));
// Reset the database contents.
- ASSERT_TRUE(db().Execute("DELETE FROM x"));
- ASSERT_TRUE(db().Execute(kInsertSql));
+ ASSERT_TRUE(db_.Execute("DELETE FROM x"));
+ ASSERT_TRUE(db_.Execute(kInsertSql));
// Rollback() discards recovery progress and leaves the database as it was.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery.get());
ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
ASSERT_TRUE(recovery->db()->Execute(kAltInsertSql));
- sql::Recovery::Rollback(std::move(recovery));
+ Recovery::Rollback(std::move(recovery));
}
- EXPECT_FALSE(db().is_open());
+ EXPECT_FALSE(db_.is_open());
ASSERT_TRUE(Reopen());
- EXPECT_TRUE(db().is_open());
- ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
+ EXPECT_TRUE(db_.is_open());
+ ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db_));
- ASSERT_EQ("This is a test", ExecuteWithResult(&db(), kXSql));
+ ASSERT_EQ("This is a test", ExecuteWithResult(&db_, kXSql));
}
-// Test operation of the virtual table used by sql::Recovery.
+// Test operation of the virtual table used by Recovery.
TEST_F(SQLRecoveryTest, VirtualTable) {
static const char kCreateSql[] = "CREATE TABLE x (t TEXT)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('That was a test')"));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES ('This is a test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES ('That was a test')"));
// Successfully recover the database.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
// Tables to recover original DB, now at [corrupt].
static const char kRecoveryCreateSql[] =
@@ -182,32 +204,32 @@ TEST_F(SQLRecoveryTest, VirtualTable) {
ASSERT_TRUE(recovery->db()->Execute(kRecoveryCopySql));
// Successfully recovered.
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// Since the database was not corrupt, the entire schema and all
// data should be recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db()));
+ ASSERT_EQ("CREATE TABLE x (t TEXT)", GetSchema(&db_));
static const char* kXSql = "SELECT * FROM x ORDER BY 1";
ASSERT_EQ("That was a test\nThis is a test",
- ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ExecuteWithResults(&db_, kXSql, "|", "\n"));
}
-void RecoveryCallback(sql::Database* db,
+void RecoveryCallback(Database* db,
const base::FilePath& db_path,
const char* create_table,
const char* create_index,
int* record_error,
int error,
- sql::Statement* stmt) {
+ Statement* stmt) {
*record_error = error;
// Clear the error callback to prevent reentrancy.
db->reset_error_callback();
- std::unique_ptr<sql::Recovery> recovery = sql::Recovery::Begin(db, db_path);
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(db, db_path);
ASSERT_TRUE(recovery.get());
ASSERT_TRUE(recovery->db()->Execute(create_table));
@@ -216,7 +238,7 @@ void RecoveryCallback(sql::Database* db,
size_t rows = 0;
ASSERT_TRUE(recovery->AutoRecoverTable("x", &rows));
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// Build a database, corrupt it by making an index reference to
@@ -224,15 +246,15 @@ void RecoveryCallback(sql::Database* db,
TEST_F(SQLRecoveryTest, RecoverCorruptIndex) {
static const char kCreateTable[] = "CREATE TABLE x (id INTEGER, v INTEGER)";
static const char kCreateIndex[] = "CREATE UNIQUE INDEX x_id ON x (id)";
- ASSERT_TRUE(db().Execute(kCreateTable));
- ASSERT_TRUE(db().Execute(kCreateIndex));
+ ASSERT_TRUE(db_.Execute(kCreateTable));
+ ASSERT_TRUE(db_.Execute(kCreateIndex));
// Insert a bit of data.
{
- ASSERT_TRUE(db().BeginTransaction());
+ ASSERT_TRUE(db_.BeginTransaction());
static const char kInsertSql[] = "INSERT INTO x (id, v) VALUES (?, ?)";
- sql::Statement s(db().GetUniqueStatement(kInsertSql));
+ Statement s(db_.GetUniqueStatement(kInsertSql));
for (int i = 0; i < 10; ++i) {
s.Reset(true);
s.BindInt(0, i);
@@ -241,42 +263,42 @@ TEST_F(SQLRecoveryTest, RecoverCorruptIndex) {
EXPECT_TRUE(s.Succeeded());
}
- ASSERT_TRUE(db().CommitTransaction());
+ ASSERT_TRUE(db_.CommitTransaction());
}
- db().Close();
+ db_.Close();
// Delete a row from the table, while leaving the index entry which
// references it.
static const char kDeleteSql[] = "DELETE FROM x WHERE id = 0";
- ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path(), "x_id", kDeleteSql));
+ ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path_, "x_id", kDeleteSql));
ASSERT_TRUE(Reopen());
int error = SQLITE_OK;
- db().set_error_callback(base::BindRepeating(
- &RecoveryCallback, &db(), db_path(), kCreateTable, kCreateIndex, &error));
+ db_.set_error_callback(base::BindRepeating(
+ &RecoveryCallback, &db_, db_path_, kCreateTable, kCreateIndex, &error));
// This works before the callback is called.
static const char kTrivialSql[] = "SELECT COUNT(*) FROM sqlite_master";
- EXPECT_TRUE(db().IsSQLValid(kTrivialSql));
+ EXPECT_TRUE(db_.IsSQLValid(kTrivialSql));
// TODO(shess): Could this be delete? Anything which fails should work.
static const char kSelectSql[] = "SELECT v FROM x WHERE id = 0";
- ASSERT_FALSE(db().Execute(kSelectSql));
+ ASSERT_FALSE(db_.Execute(kSelectSql));
EXPECT_EQ(SQLITE_CORRUPT, error);
// Database handle has been poisoned.
- EXPECT_FALSE(db().IsSQLValid(kTrivialSql));
+ EXPECT_FALSE(db_.IsSQLValid(kTrivialSql));
ASSERT_TRUE(Reopen());
// The recovered table should reflect the deletion.
static const char kSelectAllSql[] = "SELECT v FROM x ORDER BY id";
EXPECT_EQ("1,2,3,4,5,6,7,8,9",
- ExecuteWithResults(&db(), kSelectAllSql, "|", ","));
+ ExecuteWithResults(&db_, kSelectAllSql, "|", ","));
// The failing statement should now succeed, with no results.
- EXPECT_EQ("", ExecuteWithResults(&db(), kSelectSql, "|", ","));
+ EXPECT_EQ("", ExecuteWithResults(&db_, kSelectSql, "|", ","));
}
// Build a database, corrupt it by making a table contain a row not
@@ -284,15 +306,15 @@ TEST_F(SQLRecoveryTest, RecoverCorruptIndex) {
TEST_F(SQLRecoveryTest, RecoverCorruptTable) {
static const char kCreateTable[] = "CREATE TABLE x (id INTEGER, v INTEGER)";
static const char kCreateIndex[] = "CREATE UNIQUE INDEX x_id ON x (id)";
- ASSERT_TRUE(db().Execute(kCreateTable));
- ASSERT_TRUE(db().Execute(kCreateIndex));
+ ASSERT_TRUE(db_.Execute(kCreateTable));
+ ASSERT_TRUE(db_.Execute(kCreateIndex));
// Insert a bit of data.
{
- ASSERT_TRUE(db().BeginTransaction());
+ ASSERT_TRUE(db_.BeginTransaction());
static const char kInsertSql[] = "INSERT INTO x (id, v) VALUES (?, ?)";
- sql::Statement s(db().GetUniqueStatement(kInsertSql));
+ Statement s(db_.GetUniqueStatement(kInsertSql));
for (int i = 0; i < 10; ++i) {
s.Reset(true);
s.BindInt(0, i);
@@ -301,62 +323,62 @@ TEST_F(SQLRecoveryTest, RecoverCorruptTable) {
EXPECT_TRUE(s.Succeeded());
}
- ASSERT_TRUE(db().CommitTransaction());
+ ASSERT_TRUE(db_.CommitTransaction());
}
- db().Close();
+ db_.Close();
// Delete a row from the index while leaving a table entry.
static const char kDeleteSql[] = "DELETE FROM x WHERE id = 0";
- ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path(), "x", kDeleteSql));
+ ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path_, "x", kDeleteSql));
ASSERT_TRUE(Reopen());
int error = SQLITE_OK;
- db().set_error_callback(base::BindRepeating(
- &RecoveryCallback, &db(), db_path(), kCreateTable, kCreateIndex, &error));
+ db_.set_error_callback(base::BindRepeating(
+ &RecoveryCallback, &db_, db_path_, kCreateTable, kCreateIndex, &error));
// Index shows one less than originally inserted.
static const char kCountSql[] = "SELECT COUNT (*) FROM x";
- EXPECT_EQ("9", ExecuteWithResult(&db(), kCountSql));
+ EXPECT_EQ("9", ExecuteWithResult(&db_, kCountSql));
// A full table scan shows all of the original data. Using column [v] to
// force use of the table rather than the index.
static const char kDistinctSql[] = "SELECT DISTINCT COUNT (v) FROM x";
- EXPECT_EQ("10", ExecuteWithResult(&db(), kDistinctSql));
+ EXPECT_EQ("10", ExecuteWithResult(&db_, kDistinctSql));
// Insert id 0 again. Since it is not in the index, the insert
// succeeds, but results in a duplicate value in the table.
static const char kInsertSql[] = "INSERT INTO x (id, v) VALUES (0, 100)";
- ASSERT_TRUE(db().Execute(kInsertSql));
+ ASSERT_TRUE(db_.Execute(kInsertSql));
// Duplication is visible.
- EXPECT_EQ("10", ExecuteWithResult(&db(), kCountSql));
- EXPECT_EQ("11", ExecuteWithResult(&db(), kDistinctSql));
+ EXPECT_EQ("10", ExecuteWithResult(&db_, kCountSql));
+ EXPECT_EQ("11", ExecuteWithResult(&db_, kDistinctSql));
// This works before the callback is called.
static const char kTrivialSql[] = "SELECT COUNT(*) FROM sqlite_master";
- EXPECT_TRUE(db().IsSQLValid(kTrivialSql));
+ EXPECT_TRUE(db_.IsSQLValid(kTrivialSql));
// TODO(shess): Figure out a statement which causes SQLite to notice the
// corruption. SELECT doesn't see errors because missing index values aren't
// visible. UPDATE or DELETE against v=0 don't see errors, even though the
// index item is missing. I suspect SQLite only deletes the key in these
// cases, but doesn't verify that one or more keys were deleted.
- ASSERT_FALSE(db().Execute("INSERT INTO x (id, v) VALUES (0, 101)"));
+ ASSERT_FALSE(db_.Execute("INSERT INTO x (id, v) VALUES (0, 101)"));
EXPECT_EQ(SQLITE_CONSTRAINT_UNIQUE, error);
// Database handle has been poisoned.
- EXPECT_FALSE(db().IsSQLValid(kTrivialSql));
+ EXPECT_FALSE(db_.IsSQLValid(kTrivialSql));
ASSERT_TRUE(Reopen());
// The recovered table has consistency between the index and the table.
- EXPECT_EQ("10", ExecuteWithResult(&db(), kCountSql));
- EXPECT_EQ("10", ExecuteWithResult(&db(), kDistinctSql));
+ EXPECT_EQ("10", ExecuteWithResult(&db_, kCountSql));
+ EXPECT_EQ("10", ExecuteWithResult(&db_, kDistinctSql));
// Only one of the values is retained.
static const char kSelectSql[] = "SELECT v FROM x WHERE id = 0";
- const std::string results = ExecuteWithResult(&db(), kSelectSql);
+ const std::string results = ExecuteWithResult(&db_, kSelectSql);
EXPECT_TRUE(results=="100" || results=="0") << "Actual results: " << results;
}
@@ -365,45 +387,42 @@ TEST_F(SQLRecoveryTest, Meta) {
const int kCompatibleVersion = 2;
{
- sql::MetaTable meta;
- EXPECT_TRUE(meta.Init(&db(), kVersion, kCompatibleVersion));
+ MetaTable meta;
+ EXPECT_TRUE(meta.Init(&db_, kVersion, kCompatibleVersion));
EXPECT_EQ(kVersion, meta.GetVersionNumber());
}
// Test expected case where everything works.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
EXPECT_TRUE(recovery->SetupMeta());
int version = 0;
EXPECT_TRUE(recovery->GetMetaVersionNumber(&version));
EXPECT_EQ(kVersion, version);
- sql::Recovery::Rollback(std::move(recovery));
+ Recovery::Rollback(std::move(recovery));
}
ASSERT_TRUE(Reopen()); // Handle was poisoned.
// Test version row missing.
- EXPECT_TRUE(db().Execute("DELETE FROM meta WHERE key = 'version'"));
+ EXPECT_TRUE(db_.Execute("DELETE FROM meta WHERE key = 'version'"));
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
EXPECT_TRUE(recovery->SetupMeta());
int version = 0;
EXPECT_FALSE(recovery->GetMetaVersionNumber(&version));
EXPECT_EQ(0, version);
- sql::Recovery::Rollback(std::move(recovery));
+ Recovery::Rollback(std::move(recovery));
}
ASSERT_TRUE(Reopen()); // Handle was poisoned.
// Test meta table missing.
- EXPECT_TRUE(db().Execute("DROP TABLE meta"));
+ EXPECT_TRUE(db_.Execute("DROP TABLE meta"));
{
sql::test::ScopedErrorExpecter expecter;
expecter.ExpectError(SQLITE_CORRUPT); // From virtual table.
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
EXPECT_FALSE(recovery->SetupMeta());
ASSERT_TRUE(expecter.SawExpectedErrors());
}
@@ -414,23 +433,22 @@ TEST_F(SQLRecoveryTest, AutoRecoverTable) {
// BIGINT and VARCHAR to test type affinity.
static const char kCreateSql[] =
"CREATE TABLE x (id BIGINT, t TEXT, v VARCHAR)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (11, 'This is', 'a test')"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (5, 'That was', 'a test')"));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (11, 'This is', 'a test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (5, 'That was', 'a test')"));
// Save aside a copy of the original schema and data.
- const std::string orig_schema(GetSchema(&db()));
+ const std::string orig_schema(GetSchema(&db_));
static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
- const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ const std::string orig_data(ExecuteWithResults(&db_, kXSql, "|", "\n"));
// Create a lame-duck table which will not be propagated by recovery to
// detect that the recovery code actually ran.
- ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
- ASSERT_NE(orig_schema, GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE y (c TEXT)"));
+ ASSERT_NE(orig_schema, GetSchema(&db_));
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
// Save a copy of the temp db's schema before recovering the table.
@@ -447,26 +465,25 @@ TEST_F(SQLRecoveryTest, AutoRecoverTable) {
EXPECT_EQ(temp_schema,
ExecuteWithResults(recovery->db(), kTempSchemaSql, "|", "\n"));
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// Since the database was not corrupt, the entire schema and all
// data should be recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ(orig_schema, GetSchema(&db()));
- ASSERT_EQ(orig_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ASSERT_EQ(orig_schema, GetSchema(&db_));
+ ASSERT_EQ(orig_data, ExecuteWithResults(&db_, kXSql, "|", "\n"));
// Recovery fails if the target table doesn't exist.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
// TODO(shess): Should this failure implicitly lead to Raze()?
size_t rows = 0;
EXPECT_FALSE(recovery->AutoRecoverTable("y", &rows));
- sql::Recovery::Unrecoverable(std::move(recovery));
+ Recovery::Unrecoverable(std::move(recovery));
}
}
@@ -474,30 +491,30 @@ TEST_F(SQLRecoveryTest, AutoRecoverTable) {
// virtual table reads directly from the database, so DEFAULT is not
// interpretted at that level.
TEST_F(SQLRecoveryTest, AutoRecoverTableWithDefault) {
- ASSERT_TRUE(db().Execute("CREATE TABLE x (id INTEGER)"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (5)"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (15)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE x (id INTEGER)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (5)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (15)"));
// ALTER effectively leaves the new columns NULL in the first two
// rows. The row with 17 will get the default injected at insert
// time, while the row with 42 will get the actual value provided.
// Embedded "'" to make sure default-handling continues to be quoted
// correctly.
- ASSERT_TRUE(db().Execute("ALTER TABLE x ADD COLUMN t TEXT DEFAULT 'a''a'"));
- ASSERT_TRUE(db().Execute("ALTER TABLE x ADD COLUMN b BLOB DEFAULT x'AA55'"));
- ASSERT_TRUE(db().Execute("ALTER TABLE x ADD COLUMN i INT DEFAULT 93"));
- ASSERT_TRUE(db().Execute("INSERT INTO x (id) VALUES (17)"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (42, 'b', x'1234', 12)"));
+ ASSERT_TRUE(db_.Execute("ALTER TABLE x ADD COLUMN t TEXT DEFAULT 'a''a'"));
+ ASSERT_TRUE(db_.Execute("ALTER TABLE x ADD COLUMN b BLOB DEFAULT x'AA55'"));
+ ASSERT_TRUE(db_.Execute("ALTER TABLE x ADD COLUMN i INT DEFAULT 93"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x (id) VALUES (17)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (42, 'b', x'1234', 12)"));
// Save aside a copy of the original schema and data.
- const std::string orig_schema(GetSchema(&db()));
+ const std::string orig_schema(GetSchema(&db_));
static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
- const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ const std::string orig_data(ExecuteWithResults(&db_, kXSql, "|", "\n"));
// Create a lame-duck table which will not be propagated by recovery to
// detect that the recovery code actually ran.
- ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
- ASSERT_NE(orig_schema, GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE y (c TEXT)"));
+ ASSERT_NE(orig_schema, GetSchema(&db_));
// Mechanically adjust the stored schema and data to allow detecting
// where the default value is coming from. The target table is just
@@ -516,8 +533,7 @@ TEST_F(SQLRecoveryTest, AutoRecoverTableWithDefault) {
}
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
// Different default to detect which table provides the default.
ASSERT_TRUE(recovery->db()->Execute(final_schema.c_str()));
@@ -525,14 +541,14 @@ TEST_F(SQLRecoveryTest, AutoRecoverTableWithDefault) {
EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
EXPECT_EQ(4u, rows);
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// Since the database was not corrupt, the entire schema and all
// data should be recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ(final_schema, GetSchema(&db()));
- ASSERT_EQ(final_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ASSERT_EQ(final_schema, GetSchema(&db_));
+ ASSERT_EQ(final_data, ExecuteWithResults(&db_, kXSql, "|", "\n"));
}
// Test that rows with NULL in a NOT NULL column are filtered
@@ -544,34 +560,33 @@ TEST_F(SQLRecoveryTest, AutoRecoverTableNullFilter) {
static const char kFinalSchema[] =
"CREATE TABLE x (id INTEGER, t TEXT NOT NULL)";
- ASSERT_TRUE(db().Execute(kOrigSchema));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (5, NULL)"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (15, 'this is a test')"));
+ ASSERT_TRUE(db_.Execute(kOrigSchema));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (5, NULL)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (15, 'this is a test')"));
// Create a lame-duck table which will not be propagated by recovery to
// detect that the recovery code actually ran.
- ASSERT_EQ(kOrigSchema, GetSchema(&db()));
- ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
- ASSERT_NE(kOrigSchema, GetSchema(&db()));
+ ASSERT_EQ(kOrigSchema, GetSchema(&db_));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE y (c TEXT)"));
+ ASSERT_NE(kOrigSchema, GetSchema(&db_));
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery->db()->Execute(kFinalSchema));
size_t rows = 0;
EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
EXPECT_EQ(1u, rows);
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// The schema should be the same, but only one row of data should
// have been recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ(kFinalSchema, GetSchema(&db()));
+ ASSERT_EQ(kFinalSchema, GetSchema(&db_));
static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
- ASSERT_EQ("15|this is a test", ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ASSERT_EQ("15|this is a test", ExecuteWithResults(&db_, kXSql, "|", "\n"));
}
// Test AutoRecoverTable with a ROWID alias.
@@ -580,37 +595,36 @@ TEST_F(SQLRecoveryTest, AutoRecoverTableWithRowid) {
// put it later.
static const char kCreateSql[] =
"CREATE TABLE x (t TEXT, id INTEGER PRIMARY KEY NOT NULL)";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test', NULL)"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('That was a test', NULL)"));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES ('This is a test', NULL)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES ('That was a test', NULL)"));
// Save aside a copy of the original schema and data.
- const std::string orig_schema(GetSchema(&db()));
+ const std::string orig_schema(GetSchema(&db_));
static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
- const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ const std::string orig_data(ExecuteWithResults(&db_, kXSql, "|", "\n"));
// Create a lame-duck table which will not be propagated by recovery to
// detect that the recovery code actually ran.
- ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
- ASSERT_NE(orig_schema, GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE y (c TEXT)"));
+ ASSERT_NE(orig_schema, GetSchema(&db_));
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
size_t rows = 0;
EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
EXPECT_EQ(2u, rows);
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// Since the database was not corrupt, the entire schema and all
// data should be recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ(orig_schema, GetSchema(&db()));
- ASSERT_EQ(orig_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ASSERT_EQ(orig_schema, GetSchema(&db_));
+ ASSERT_EQ(orig_data, ExecuteWithResults(&db_, kXSql, "|", "\n"));
}
// Test that a compound primary key doesn't fire the ROWID code.
@@ -622,41 +636,40 @@ TEST_F(SQLRecoveryTest, AutoRecoverTableWithCompoundKey) {
"t TEXT,"
"PRIMARY KEY (id, id2)"
")";
- ASSERT_TRUE(db().Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
// NOTE(shess): Do not accidentally use [id] 1, 2, 3, as those will
// be the ROWID values.
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (1, 'a', 'This is a test')"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (1, 'b', 'That was a test')"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (2, 'a', 'Another test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (1, 'a', 'This is a test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (1, 'b', 'That was a test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (2, 'a', 'Another test')"));
// Save aside a copy of the original schema and data.
- const std::string orig_schema(GetSchema(&db()));
+ const std::string orig_schema(GetSchema(&db_));
static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
- const std::string orig_data(ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ const std::string orig_data(ExecuteWithResults(&db_, kXSql, "|", "\n"));
// Create a lame-duck table which will not be propagated by recovery to
// detect that the recovery code actually ran.
- ASSERT_TRUE(db().Execute("CREATE TABLE y (c TEXT)"));
- ASSERT_NE(orig_schema, GetSchema(&db()));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE y (c TEXT)"));
+ ASSERT_NE(orig_schema, GetSchema(&db_));
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
size_t rows = 0;
EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
EXPECT_EQ(3u, rows);
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// Since the database was not corrupt, the entire schema and all
// data should be recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ(orig_schema, GetSchema(&db()));
- ASSERT_EQ(orig_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ASSERT_EQ(orig_schema, GetSchema(&db_));
+ ASSERT_EQ(orig_data, ExecuteWithResults(&db_, kXSql, "|", "\n"));
}
// Test recovering from a table with fewer columns than the target.
@@ -665,46 +678,45 @@ TEST_F(SQLRecoveryTest, AutoRecoverTableMissingColumns) {
"CREATE TABLE x (id INTEGER PRIMARY KEY, t0 TEXT)";
static const char kAlterSql[] =
"ALTER TABLE x ADD COLUMN t1 TEXT DEFAULT 't'";
- ASSERT_TRUE(db().Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (1, 'This is')"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES (2, 'That was')"));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (1, 'This is')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES (2, 'That was')"));
// Generate the expected info by faking a table to match what recovery will
// create.
- const std::string orig_schema(GetSchema(&db()));
+ const std::string orig_schema(GetSchema(&db_));
static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
std::string expected_schema;
std::string expected_data;
{
- ASSERT_TRUE(db().BeginTransaction());
- ASSERT_TRUE(db().Execute(kAlterSql));
+ ASSERT_TRUE(db_.BeginTransaction());
+ ASSERT_TRUE(db_.Execute(kAlterSql));
- expected_schema = GetSchema(&db());
- expected_data = ExecuteWithResults(&db(), kXSql, "|", "\n");
+ expected_schema = GetSchema(&db_);
+ expected_data = ExecuteWithResults(&db_, kXSql, "|", "\n");
- db().RollbackTransaction();
+ db_.RollbackTransaction();
}
// Following tests are pointless if the rollback didn't work.
- ASSERT_EQ(orig_schema, GetSchema(&db()));
+ ASSERT_EQ(orig_schema, GetSchema(&db_));
// Recover the previous version of the table into the altered version.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery->db()->Execute(kCreateSql));
ASSERT_TRUE(recovery->db()->Execute(kAlterSql));
size_t rows = 0;
EXPECT_TRUE(recovery->AutoRecoverTable("x", &rows));
EXPECT_EQ(2u, rows);
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
// Since the database was not corrupt, the entire schema and all
// data should be recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ(expected_schema, GetSchema(&db()));
- ASSERT_EQ(expected_data, ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ASSERT_EQ(expected_schema, GetSchema(&db_));
+ ASSERT_EQ(expected_data, ExecuteWithResults(&db_, kXSql, "|", "\n"));
}
// Recover a golden file where an interior page has been manually modified so
@@ -714,13 +726,12 @@ TEST_F(SQLRecoveryTest, Bug387868) {
base::FilePath golden_path;
ASSERT_TRUE(base::PathService::Get(sql::test::DIR_TEST_DATA, &golden_path));
golden_path = golden_path.AppendASCII("recovery_387868");
- db().Close();
- ASSERT_TRUE(base::CopyFile(golden_path, db_path()));
+ db_.Close();
+ ASSERT_TRUE(base::CopyFile(golden_path, db_path_));
ASSERT_TRUE(Reopen());
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery.get());
// Create the new version of the table.
@@ -733,96 +744,95 @@ TEST_F(SQLRecoveryTest, Bug387868) {
EXPECT_EQ(43u, rows);
// Successfully recovered.
- EXPECT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ EXPECT_TRUE(Recovery::Recovered(std::move(recovery)));
}
}
// Memory-mapped I/O interacts poorly with I/O errors. Make sure the recovery
// database doesn't accidentally enable it.
TEST_F(SQLRecoveryTest, NoMmap) {
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_TRUE(recovery.get());
// In the current implementation, the PRAGMA successfully runs with no result
// rows. Running with a single result of |0| is also acceptable.
- sql::Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size"));
+ Statement s(recovery->db()->GetUniqueStatement("PRAGMA mmap_size"));
EXPECT_TRUE(!s.Step() || !s.ColumnInt64(0));
}
TEST_F(SQLRecoveryTest, RecoverDatabase) {
// As a side effect, AUTOINCREMENT creates the sqlite_sequence table for
// RecoverDatabase() to handle.
- ASSERT_TRUE(db().Execute(
+ ASSERT_TRUE(db_.Execute(
"CREATE TABLE x (id INTEGER PRIMARY KEY AUTOINCREMENT, v TEXT)"));
- EXPECT_TRUE(db().Execute("INSERT INTO x (v) VALUES ('turtle')"));
- EXPECT_TRUE(db().Execute("INSERT INTO x (v) VALUES ('truck')"));
- EXPECT_TRUE(db().Execute("INSERT INTO x (v) VALUES ('trailer')"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO x (v) VALUES ('turtle')"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO x (v) VALUES ('truck')"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO x (v) VALUES ('trailer')"));
// This table needs index and a unique index to work.
- ASSERT_TRUE(db().Execute("CREATE TABLE y (name TEXT, v TEXT)"));
- ASSERT_TRUE(db().Execute("CREATE UNIQUE INDEX y_name ON y(name)"));
- ASSERT_TRUE(db().Execute("CREATE INDEX y_v ON y(v)"));
- EXPECT_TRUE(db().Execute("INSERT INTO y VALUES ('jim', 'telephone')"));
- EXPECT_TRUE(db().Execute("INSERT INTO y VALUES ('bob', 'truck')"));
- EXPECT_TRUE(db().Execute("INSERT INTO y VALUES ('dean', 'trailer')"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE y (name TEXT, v TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE UNIQUE INDEX y_name ON y(name)"));
+ ASSERT_TRUE(db_.Execute("CREATE INDEX y_v ON y(v)"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO y VALUES ('jim', 'telephone')"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO y VALUES ('bob', 'truck')"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO y VALUES ('dean', 'trailer')"));
// View which is the intersection of [x.v] and [y.v].
- ASSERT_TRUE(db().Execute(
- "CREATE VIEW v AS SELECT x.v FROM x, y WHERE x.v = y.v"));
+ ASSERT_TRUE(
+ db_.Execute("CREATE VIEW v AS SELECT x.v FROM x, y WHERE x.v = y.v"));
// When an element is deleted from [x], trigger a delete on [y]. Between the
// BEGIN and END, [old] stands for the deleted rows from [x].
- ASSERT_TRUE(db().Execute("CREATE TRIGGER t AFTER DELETE ON x "
- "BEGIN DELETE FROM y WHERE y.v = old.v; END"));
+ ASSERT_TRUE(
+ db_.Execute("CREATE TRIGGER t AFTER DELETE ON x "
+ "BEGIN DELETE FROM y WHERE y.v = old.v; END"));
// Save aside a copy of the original schema, verifying that it has the created
// items plus the sqlite_sequence table.
- const std::string orig_schema(GetSchema(&db()));
+ const std::string orig_schema(GetSchema(&db_));
ASSERT_EQ(6, std::count(orig_schema.begin(), orig_schema.end(), '\n'));
static const char kXSql[] = "SELECT * FROM x ORDER BY 1";
static const char kYSql[] = "SELECT * FROM y ORDER BY 1";
static const char kVSql[] = "SELECT * FROM v ORDER BY 1";
EXPECT_EQ("1|turtle\n2|truck\n3|trailer",
- ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ExecuteWithResults(&db_, kXSql, "|", "\n"));
EXPECT_EQ("bob|truck\ndean|trailer\njim|telephone",
- ExecuteWithResults(&db(), kYSql, "|", "\n"));
- EXPECT_EQ("trailer\ntruck", ExecuteWithResults(&db(), kVSql, "|", "\n"));
+ ExecuteWithResults(&db_, kYSql, "|", "\n"));
+ EXPECT_EQ("trailer\ntruck", ExecuteWithResults(&db_, kVSql, "|", "\n"));
// Database handle is valid before recovery, poisoned after.
static const char kTrivialSql[] = "SELECT COUNT(*) FROM sqlite_master";
- EXPECT_TRUE(db().IsSQLValid(kTrivialSql));
- sql::Recovery::RecoverDatabase(&db(), db_path());
- EXPECT_FALSE(db().IsSQLValid(kTrivialSql));
+ EXPECT_TRUE(db_.IsSQLValid(kTrivialSql));
+ Recovery::RecoverDatabase(&db_, db_path_);
+ EXPECT_FALSE(db_.IsSQLValid(kTrivialSql));
// Since the database was not corrupt, the entire schema and all
// data should be recovered.
ASSERT_TRUE(Reopen());
- ASSERT_EQ(orig_schema, GetSchema(&db()));
+ ASSERT_EQ(orig_schema, GetSchema(&db_));
EXPECT_EQ("1|turtle\n2|truck\n3|trailer",
- ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ExecuteWithResults(&db_, kXSql, "|", "\n"));
EXPECT_EQ("bob|truck\ndean|trailer\njim|telephone",
- ExecuteWithResults(&db(), kYSql, "|", "\n"));
- EXPECT_EQ("trailer\ntruck", ExecuteWithResults(&db(), kVSql, "|", "\n"));
+ ExecuteWithResults(&db_, kYSql, "|", "\n"));
+ EXPECT_EQ("trailer\ntruck", ExecuteWithResults(&db_, kVSql, "|", "\n"));
// Test that the trigger works.
- ASSERT_TRUE(db().Execute("DELETE FROM x WHERE v = 'truck'"));
- EXPECT_EQ("1|turtle\n3|trailer",
- ExecuteWithResults(&db(), kXSql, "|", "\n"));
+ ASSERT_TRUE(db_.Execute("DELETE FROM x WHERE v = 'truck'"));
+ EXPECT_EQ("1|turtle\n3|trailer", ExecuteWithResults(&db_, kXSql, "|", "\n"));
EXPECT_EQ("dean|trailer\njim|telephone",
- ExecuteWithResults(&db(), kYSql, "|", "\n"));
- EXPECT_EQ("trailer", ExecuteWithResults(&db(), kVSql, "|", "\n"));
+ ExecuteWithResults(&db_, kYSql, "|", "\n"));
+ EXPECT_EQ("trailer", ExecuteWithResults(&db_, kVSql, "|", "\n"));
}
// When RecoverDatabase() encounters SQLITE_NOTADB, the database is deleted.
TEST_F(SQLRecoveryTest, RecoverDatabaseDelete) {
// Create a valid database, then write junk over the header. This should lead
// to SQLITE_NOTADB, which will cause ATTACH to fail.
- ASSERT_TRUE(db().Execute("CREATE TABLE x (t TEXT)"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')"));
- db().Close();
- WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE);
+ ASSERT_TRUE(db_.Execute("CREATE TABLE x (t TEXT)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES ('This is a test')"));
+ db_.Close();
+ ASSERT_TRUE(OverwriteDatabaseHeader());
{
sql::test::ScopedErrorExpecter expecter;
@@ -832,74 +842,74 @@ TEST_F(SQLRecoveryTest, RecoverDatabaseDelete) {
ASSERT_TRUE(Reopen());
// This should "recover" the database by making it valid, but empty.
- sql::Recovery::RecoverDatabase(&db(), db_path());
+ Recovery::RecoverDatabase(&db_, db_path_);
ASSERT_TRUE(expecter.SawExpectedErrors());
}
// Recovery poisoned the handle, must re-open.
- db().Close();
+ db_.Close();
ASSERT_TRUE(Reopen());
- EXPECT_EQ("", GetSchema(&db()));
+ EXPECT_EQ("", GetSchema(&db_));
}
// Allow callers to validate the database between recovery and commit.
TEST_F(SQLRecoveryTest, BeginRecoverDatabase) {
// Create a table with a broken index.
- ASSERT_TRUE(db().Execute("CREATE TABLE t (id INTEGER PRIMARY KEY, c TEXT)"));
- ASSERT_TRUE(db().Execute("CREATE UNIQUE INDEX t_id ON t (id)"));
- ASSERT_TRUE(db().Execute("INSERT INTO t VALUES (1, 'hello world')"));
- ASSERT_TRUE(db().Execute("INSERT INTO t VALUES (2, 'testing')"));
- ASSERT_TRUE(db().Execute("INSERT INTO t VALUES (3, 'nope')"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE t (id INTEGER PRIMARY KEY, c TEXT)"));
+ ASSERT_TRUE(db_.Execute("CREATE UNIQUE INDEX t_id ON t (id)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO t VALUES (1, 'hello world')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO t VALUES (2, 'testing')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO t VALUES (3, 'nope')"));
// Inject corruption into the index.
- db().Close();
+ db_.Close();
static const char kDeleteSql[] = "DELETE FROM t WHERE id = 3";
- ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path(), "t_id", kDeleteSql));
+ ASSERT_TRUE(sql::test::CorruptTableOrIndex(db_path_, "t_id", kDeleteSql));
ASSERT_TRUE(Reopen());
// id as read from index.
static const char kSelectIndexIdSql[] = "SELECT id FROM t INDEXED BY t_id";
- EXPECT_EQ("1,2,3", ExecuteWithResults(&db(), kSelectIndexIdSql, "|", ","));
+ EXPECT_EQ("1,2,3", ExecuteWithResults(&db_, kSelectIndexIdSql, "|", ","));
// id as read from table.
static const char kSelectTableIdSql[] = "SELECT id FROM t NOT INDEXED";
- EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectTableIdSql, "|", ","));
+ EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectTableIdSql, "|", ","));
// Run recovery code, then rollback. Database remains the same.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::BeginRecoverDatabase(&db(), db_path());
+ std::unique_ptr<Recovery> recovery =
+ Recovery::BeginRecoverDatabase(&db_, db_path_);
ASSERT_TRUE(recovery);
- sql::Recovery::Rollback(std::move(recovery));
+ Recovery::Rollback(std::move(recovery));
}
- db().Close();
+ db_.Close();
ASSERT_TRUE(Reopen());
- EXPECT_EQ("1,2,3", ExecuteWithResults(&db(), kSelectIndexIdSql, "|", ","));
- EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectTableIdSql, "|", ","));
+ EXPECT_EQ("1,2,3", ExecuteWithResults(&db_, kSelectIndexIdSql, "|", ","));
+ EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectTableIdSql, "|", ","));
// Run recovery code, then commit. The failing row is dropped.
{
- std::unique_ptr<sql::Recovery> recovery =
- sql::Recovery::BeginRecoverDatabase(&db(), db_path());
+ std::unique_ptr<Recovery> recovery =
+ Recovery::BeginRecoverDatabase(&db_, db_path_);
ASSERT_TRUE(recovery);
- ASSERT_TRUE(sql::Recovery::Recovered(std::move(recovery)));
+ ASSERT_TRUE(Recovery::Recovered(std::move(recovery)));
}
- db().Close();
+ db_.Close();
ASSERT_TRUE(Reopen());
- EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectIndexIdSql, "|", ","));
- EXPECT_EQ("1,2", ExecuteWithResults(&db(), kSelectTableIdSql, "|", ","));
+ EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectIndexIdSql, "|", ","));
+ EXPECT_EQ("1,2", ExecuteWithResults(&db_, kSelectTableIdSql, "|", ","));
}
// Test histograms recorded when the invalid database cannot be attached.
TEST_F(SQLRecoveryTest, AttachFailure) {
// Create a valid database, then write junk over the header. This should lead
// to SQLITE_NOTADB, which will cause ATTACH to fail.
- ASSERT_TRUE(db().Execute("CREATE TABLE x (t TEXT)"));
- ASSERT_TRUE(db().Execute("INSERT INTO x VALUES ('This is a test')"));
- db().Close();
- WriteJunkToDatabase(SQLTestBase::TYPE_OVERWRITE);
+ ASSERT_TRUE(db_.Execute("CREATE TABLE x (t TEXT)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO x VALUES ('This is a test')"));
+ db_.Close();
+ ASSERT_TRUE(OverwriteDatabaseHeader());
static const char kEventHistogramName[] = "Sqlite.RecoveryEvents";
const int kEventEnum = 5; // RECOVERY_FAILED_ATTACH
@@ -914,8 +924,7 @@ TEST_F(SQLRecoveryTest, AttachFailure) {
ASSERT_TRUE(Reopen());
// Begin() should fail.
- std::unique_ptr<sql::Recovery>
- recovery = sql::Recovery::Begin(&db(), db_path());
+ std::unique_ptr<Recovery> recovery = Recovery::Begin(&db_, db_path_);
ASSERT_FALSE(recovery.get());
ASSERT_TRUE(expecter.SawExpectedErrors());
@@ -942,8 +951,8 @@ void TestPageSize(const base::FilePath& db_prefix,
const base::FilePath db_path = db_prefix.InsertBeforeExtensionASCII(
base::NumberToString(initial_page_size));
- sql::Database::Delete(db_path);
- sql::Database db({.page_size = initial_page_size});
+ Database::Delete(db_path);
+ Database db({.page_size = initial_page_size});
ASSERT_TRUE(db.Open(db_path));
ASSERT_TRUE(db.Execute(kCreateSql));
ASSERT_TRUE(db.Execute(kInsertSql1));
@@ -953,18 +962,17 @@ void TestPageSize(const base::FilePath& db_prefix,
db.Close();
// Re-open the database while setting a new |options.page_size| in the object.
- sql::Database recover_db({.page_size = final_page_size});
+ Database recover_db({.page_size = final_page_size});
ASSERT_TRUE(recover_db.Open(db_path));
// Recovery will use the page size set in the database object, which may not
// match the file's page size.
- sql::Recovery::RecoverDatabase(&recover_db, db_path);
+ Recovery::RecoverDatabase(&recover_db, db_path);
// Recovery poisoned the handle, must re-open.
recover_db.Close();
// Make sure the page size is read from the file.
- sql::Database recovered_db(
- {.page_size = sql::DatabaseOptions::kDefaultPageSize});
+ Database recovered_db({.page_size = DatabaseOptions::kDefaultPageSize});
ASSERT_TRUE(recovered_db.Open(db_path));
ASSERT_EQ(expected_final_page_size,
ExecuteWithResult(&recovered_db, "PRAGMA page_size"));
@@ -972,34 +980,36 @@ void TestPageSize(const base::FilePath& db_prefix,
ExecuteWithResults(&recovered_db, kSelectSql, "|", "\n"));
}
-// Verify that sql::Recovery maintains the page size, and the virtual table
+// Verify that Recovery maintains the page size, and the virtual table
// works with page sizes other than SQLite's default. Also verify the case
// where the default page size has changed.
TEST_F(SQLRecoveryTest, PageSize) {
const std::string default_page_size =
- ExecuteWithResult(&db(), "PRAGMA page_size");
+ ExecuteWithResult(&db_, "PRAGMA page_size");
// Check the default page size first.
EXPECT_NO_FATAL_FAILURE(TestPageSize(
- db_path(), sql::DatabaseOptions::kDefaultPageSize, default_page_size,
- sql::DatabaseOptions::kDefaultPageSize, default_page_size));
+ db_path_, DatabaseOptions::kDefaultPageSize, default_page_size,
+ DatabaseOptions::kDefaultPageSize, default_page_size));
// Sync uses 32k pages.
EXPECT_NO_FATAL_FAILURE(
- TestPageSize(db_path(), 32768, "32768", 32768, "32768"));
+ TestPageSize(db_path_, 32768, "32768", 32768, "32768"));
// Many clients use 4k pages. This is the SQLite default after 3.12.0.
- EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 4096, "4096", 4096, "4096"));
+ EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 4096, "4096", 4096, "4096"));
// 1k is the default page size before 3.12.0.
- EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 1024, "1024", 1024, "1024"));
+ EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 1024, "1024", 1024, "1024"));
// Databases with no page size specified should recover with the new default
// page size. 2k has never been the default page size.
ASSERT_NE("2048", default_page_size);
- EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path(), 2048, "2048",
- sql::DatabaseOptions::kDefaultPageSize,
+ EXPECT_NO_FATAL_FAILURE(TestPageSize(db_path_, 2048, "2048",
+ DatabaseOptions::kDefaultPageSize,
default_page_size));
}
} // namespace
+
+} // namespace sql
diff --git a/chromium/sql/sandboxed_vfs.cc b/chromium/sql/sandboxed_vfs.cc
index 906a11c68a2..145efad294b 100644
--- a/chromium/sql/sandboxed_vfs.cc
+++ b/chromium/sql/sandboxed_vfs.cc
@@ -165,7 +165,7 @@ int SandboxedVfs::Delete(const char* full_path, int sync_dir) {
int SandboxedVfs::Access(const char* full_path, int flags, int& result) {
DCHECK(full_path);
- base::Optional<PathAccessInfo> access =
+ absl::optional<PathAccessInfo> access =
delegate_->GetPathAccess(base::FilePath::FromUTF8Unsafe(full_path));
if (!access) {
result = 0;
diff --git a/chromium/sql/sandboxed_vfs.h b/chromium/sql/sandboxed_vfs.h
index a7eed6288de..fd787b12225 100644
--- a/chromium/sql/sandboxed_vfs.h
+++ b/chromium/sql/sandboxed_vfs.h
@@ -12,7 +12,7 @@
#include "base/component_export.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
-#include "base/optional.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "third_party/sqlite/sqlite3.h"
namespace sql {
@@ -57,7 +57,7 @@ class COMPONENT_EXPORT(SQL) SandboxedVfs {
// Queries path access information for `file_path`. Returns null if the
// given path does not exist.
- virtual base::Optional<PathAccessInfo> GetPathAccess(
+ virtual absl::optional<PathAccessInfo> GetPathAccess(
const base::FilePath& file_path) = 0;
// Resizes a file.
diff --git a/chromium/sql/sql_memory_dump_provider.h b/chromium/sql/sql_memory_dump_provider.h
index 57e88c67f16..190b802adf8 100644
--- a/chromium/sql/sql_memory_dump_provider.h
+++ b/chromium/sql/sql_memory_dump_provider.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef SQL_SQL_MEMORY_DUMP_PROVIDER_H
-#define SQL_SQL_MEMORY_DUMP_PROVIDER_H
+#ifndef SQL_SQL_MEMORY_DUMP_PROVIDER_H_
+#define SQL_SQL_MEMORY_DUMP_PROVIDER_H_
#include "base/component_export.h"
#include "base/macros.h"
@@ -34,4 +34,4 @@ class COMPONENT_EXPORT(SQL) SqlMemoryDumpProvider
} // namespace sql
-#endif // SQL_SQL_MEMORY_DUMP_PROVIDER_H
+#endif // SQL_SQL_MEMORY_DUMP_PROVIDER_H_
diff --git a/chromium/sql/sql_memory_dump_provider_unittest.cc b/chromium/sql/sql_memory_dump_provider_unittest.cc
index c361253b0d1..6929639c7e9 100644
--- a/chromium/sql/sql_memory_dump_provider_unittest.cc
+++ b/chromium/sql/sql_memory_dump_provider_unittest.cc
@@ -4,19 +4,41 @@
#include "sql/sql_memory_dump_provider.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/trace_event/memory_dump_request_args.h"
#include "base/trace_event/process_memory_dump.h"
-#include "sql/test/sql_test_base.h"
+#include "sql/database.h"
#include "testing/gtest/include/gtest/gtest.h"
+namespace sql {
+
namespace {
-using SQLMemoryDumpProviderTest = sql::SQLTestBase;
-}
+
+class SQLMemoryDumpProviderTest : public testing::Test {
+ public:
+ ~SQLMemoryDumpProviderTest() override = default;
+
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(db_.Open(
+ temp_dir_.GetPath().AppendASCII("memory_dump_provider_test.sqlite")));
+
+ ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a, b)"));
+ }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ Database db_;
+};
TEST_F(SQLMemoryDumpProviderTest, OnMemoryDump) {
base::trace_event::MemoryDumpArgs args = {
base::trace_event::MemoryDumpLevelOfDetail::DETAILED};
base::trace_event::ProcessMemoryDump pmd(args);
- ASSERT_TRUE(
- sql::SqlMemoryDumpProvider::GetInstance()->OnMemoryDump(args, &pmd));
+ ASSERT_TRUE(SqlMemoryDumpProvider::GetInstance()->OnMemoryDump(args, &pmd));
ASSERT_TRUE(pmd.GetAllocatorDump("sqlite"));
}
+
+} // namespace
+
+} // namespace sql
diff --git a/chromium/sql/sqlite_features_unittest.cc b/chromium/sql/sqlite_features_unittest.cc
index 877ec675c9a..a84a51bb57d 100644
--- a/chromium/sql/sqlite_features_unittest.cc
+++ b/chromium/sql/sqlite_features_unittest.cc
@@ -8,13 +8,13 @@
#include <string>
#include "base/bind.h"
+#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/memory_mapped_file.h"
#include "base/files/scoped_temp_dir.h"
#include "build/build_config.h"
#include "sql/database.h"
#include "sql/statement.h"
-#include "sql/test/sql_test_base.h"
#include "sql/test/test_helpers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
@@ -40,16 +40,18 @@ void CaptureErrorCallback(int* error_pointer, std::string* sql_text,
} // namespace
-class SQLiteFeaturesTest : public sql::SQLTestBase {
+class SQLiteFeaturesTest : public testing::Test {
public:
- SQLiteFeaturesTest() : error_(SQLITE_OK) {}
+ ~SQLiteFeaturesTest() override = default;
void SetUp() override {
- SQLTestBase::SetUp();
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ db_path_ = temp_dir_.GetPath().AppendASCII("sqlite_features_test.sqlite");
+ ASSERT_TRUE(db_.Open(db_path_));
// The error delegate will set |error_| and |sql_text_| when any sqlite
// statement operation returns an error code.
- db().set_error_callback(
+ db_.set_error_callback(
base::BindRepeating(&CaptureErrorCallback, &error_, &sql_text_));
}
@@ -57,15 +59,20 @@ class SQLiteFeaturesTest : public sql::SQLTestBase {
// If any error happened the original sql statement can be found in
// |sql_text_|.
EXPECT_EQ(SQLITE_OK, error_) << sql_text_;
+ }
- SQLTestBase::TearDown();
+ bool Reopen() {
+ db_.Close();
+ return db_.Open(db_path_);
}
- int error() { return error_; }
+ protected:
+ base::ScopedTempDir temp_dir_;
+ base::FilePath db_path_;
+ Database db_;
- private:
// The error code of the most recent error.
- int error_;
+ int error_ = SQLITE_OK;
// Original statement which has caused the error.
std::string sql_text_;
};
@@ -73,21 +80,20 @@ class SQLiteFeaturesTest : public sql::SQLTestBase {
// Do not include fts1 support, it is not useful, and nobody is
// looking at it.
TEST_F(SQLiteFeaturesTest, NoFTS1) {
- ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(
- "CREATE VIRTUAL TABLE foo USING fts1(x)"));
+ ASSERT_EQ(SQLITE_ERROR, db_.ExecuteAndReturnErrorCode(
+ "CREATE VIRTUAL TABLE foo USING fts1(x)"));
}
// Do not include fts2 support, it is not useful, and nobody is
// looking at it.
TEST_F(SQLiteFeaturesTest, NoFTS2) {
- ASSERT_EQ(SQLITE_ERROR, db().ExecuteAndReturnErrorCode(
- "CREATE VIRTUAL TABLE foo USING fts2(x)"));
+ ASSERT_EQ(SQLITE_ERROR, db_.ExecuteAndReturnErrorCode(
+ "CREATE VIRTUAL TABLE foo USING fts2(x)"));
}
-// fts3 used to be used for history files, and may also be used by WebDatabase
-// clients.
+// fts3 is exposed in WebSQL.
TEST_F(SQLiteFeaturesTest, FTS3) {
- ASSERT_TRUE(db().Execute("CREATE VIRTUAL TABLE foo USING fts3(x)"));
+ ASSERT_TRUE(db_.Execute("CREATE VIRTUAL TABLE foo USING fts3(x)"));
}
// Originally history used fts2, which Chromium patched to treat "foo*" as a
@@ -96,12 +102,12 @@ TEST_F(SQLiteFeaturesTest, FTS3) {
TEST_F(SQLiteFeaturesTest, FTS3_Prefix) {
static const char kCreateSql[] =
"CREATE VIRTUAL TABLE foo USING fts3(x, tokenize icu)";
- ASSERT_TRUE(db().Execute(kCreateSql));
+ ASSERT_TRUE(db_.Execute(kCreateSql));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (x) VALUES ('test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO foo (x) VALUES ('test')"));
EXPECT_EQ("test",
- ExecuteWithResult(&db(), "SELECT x FROM foo WHERE x MATCH 'te*'"));
+ ExecuteWithResult(&db_, "SELECT x FROM foo WHERE x MATCH 'te*'"));
}
// Verify that Chromium's SQLite is compiled with HAVE_USLEEP defined. With
@@ -121,9 +127,9 @@ TEST_F(SQLiteFeaturesTest, UsesUsleep) {
// Ensure that our SQLite version has working foreign key support with cascade
// delete support.
TEST_F(SQLiteFeaturesTest, ForeignKeySupport) {
- ASSERT_TRUE(db().Execute("PRAGMA foreign_keys=1"));
- ASSERT_TRUE(db().Execute("CREATE TABLE parents (id INTEGER PRIMARY KEY)"));
- ASSERT_TRUE(db().Execute(
+ ASSERT_TRUE(db_.Execute("PRAGMA foreign_keys=1"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE parents (id INTEGER PRIMARY KEY)"));
+ ASSERT_TRUE(db_.Execute(
"CREATE TABLE children ("
" id INTEGER PRIMARY KEY,"
" pid INTEGER NOT NULL REFERENCES parents(id) ON DELETE CASCADE)"));
@@ -131,40 +137,40 @@ TEST_F(SQLiteFeaturesTest, ForeignKeySupport) {
static const char kSelectChildrenSql[] = "SELECT * FROM children ORDER BY id";
// Inserting without a matching parent should fail with constraint violation.
- EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParentsSql));
+ EXPECT_EQ("", ExecuteWithResult(&db_, kSelectParentsSql));
const int insert_error =
- db().ExecuteAndReturnErrorCode("INSERT INTO children VALUES (10, 1)");
+ db_.ExecuteAndReturnErrorCode("INSERT INTO children VALUES (10, 1)");
EXPECT_EQ(SQLITE_CONSTRAINT | SQLITE_CONSTRAINT_FOREIGNKEY, insert_error);
- EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildrenSql));
+ EXPECT_EQ("", ExecuteWithResult(&db_, kSelectChildrenSql));
// Inserting with a matching parent should work.
- ASSERT_TRUE(db().Execute("INSERT INTO parents VALUES (1)"));
- EXPECT_EQ("1", ExecuteWithResults(&db(), kSelectParentsSql, "|", "\n"));
- EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (11, 1)"));
- EXPECT_TRUE(db().Execute("INSERT INTO children VALUES (12, 1)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO parents VALUES (1)"));
+ EXPECT_EQ("1", ExecuteWithResults(&db_, kSelectParentsSql, "|", "\n"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO children VALUES (11, 1)"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO children VALUES (12, 1)"));
EXPECT_EQ("11|1\n12|1",
- ExecuteWithResults(&db(), kSelectChildrenSql, "|", "\n"));
+ ExecuteWithResults(&db_, kSelectChildrenSql, "|", "\n"));
// Deleting the parent should cascade, deleting the children as well.
- ASSERT_TRUE(db().Execute("DELETE FROM parents"));
- EXPECT_EQ("", ExecuteWithResult(&db(), kSelectParentsSql));
- EXPECT_EQ("", ExecuteWithResult(&db(), kSelectChildrenSql));
+ ASSERT_TRUE(db_.Execute("DELETE FROM parents"));
+ EXPECT_EQ("", ExecuteWithResult(&db_, kSelectParentsSql));
+ EXPECT_EQ("", ExecuteWithResult(&db_, kSelectChildrenSql));
}
// Ensure that our SQLite version supports booleans.
TEST_F(SQLiteFeaturesTest, BooleanSupport) {
ASSERT_TRUE(
- db().Execute("CREATE TABLE flags ("
- " id INTEGER PRIMARY KEY,"
- " true_flag BOOL NOT NULL DEFAULT TRUE,"
- " false_flag BOOL NOT NULL DEFAULT FALSE)"));
- ASSERT_TRUE(db().Execute(
+ db_.Execute("CREATE TABLE flags ("
+ " id INTEGER PRIMARY KEY,"
+ " true_flag BOOL NOT NULL DEFAULT TRUE,"
+ " false_flag BOOL NOT NULL DEFAULT FALSE)"));
+ ASSERT_TRUE(db_.Execute(
"ALTER TABLE flags ADD COLUMN true_flag2 BOOL NOT NULL DEFAULT TRUE"));
- ASSERT_TRUE(db().Execute(
+ ASSERT_TRUE(db_.Execute(
"ALTER TABLE flags ADD COLUMN false_flag2 BOOL NOT NULL DEFAULT FALSE"));
- ASSERT_TRUE(db().Execute("INSERT INTO flags (id) VALUES (1)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO flags (id) VALUES (1)"));
- sql::Statement s(db().GetUniqueStatement(
+ sql::Statement s(db_.GetUniqueStatement(
"SELECT true_flag, false_flag, true_flag2, false_flag2"
" FROM flags WHERE id=1;"));
ASSERT_TRUE(s.Step());
@@ -177,13 +183,11 @@ TEST_F(SQLiteFeaturesTest, BooleanSupport) {
}
TEST_F(SQLiteFeaturesTest, IcuEnabled) {
- sql::Statement lower_en(
- db().GetUniqueStatement("SELECT lower('I', 'en_us')"));
+ sql::Statement lower_en(db_.GetUniqueStatement("SELECT lower('I', 'en_us')"));
ASSERT_TRUE(lower_en.Step());
EXPECT_EQ("i", lower_en.ColumnString(0));
- sql::Statement lower_tr(
- db().GetUniqueStatement("SELECT lower('I', 'tr_tr')"));
+ sql::Statement lower_tr(db_.GetUniqueStatement("SELECT lower('I', 'tr_tr')"));
ASSERT_TRUE(lower_tr.Step());
EXPECT_EQ("\u0131", lower_tr.ColumnString(0));
}
@@ -196,14 +200,14 @@ TEST_F(SQLiteFeaturesTest, IcuEnabled) {
// be disabled on this platform using SQLITE_MAX_MMAP_SIZE=0.
TEST_F(SQLiteFeaturesTest, Mmap) {
// Try to turn on mmap'ed I/O.
- ignore_result(db().Execute("PRAGMA mmap_size = 1048576"));
+ ignore_result(db_.Execute("PRAGMA mmap_size = 1048576"));
{
- sql::Statement s(db().GetUniqueStatement("PRAGMA mmap_size"));
+ sql::Statement s(db_.GetUniqueStatement("PRAGMA mmap_size"));
ASSERT_TRUE(s.Step());
ASSERT_GT(s.ColumnInt64(0), 0);
}
- db().Close();
+ db_.Close();
const uint32_t kFlags =
base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE;
@@ -211,7 +215,7 @@ TEST_F(SQLiteFeaturesTest, Mmap) {
// Create a file with a block of '0', a block of '1', and a block of '2'.
{
- base::File f(db_path(), kFlags);
+ base::File f(db_path_, kFlags);
ASSERT_TRUE(f.IsValid());
memset(buf, '0', sizeof(buf));
ASSERT_EQ(f.Write(0*sizeof(buf), buf, sizeof(buf)), (int)sizeof(buf));
@@ -226,7 +230,7 @@ TEST_F(SQLiteFeaturesTest, Mmap) {
// mmap the file and verify that everything looks right.
{
base::MemoryMappedFile m;
- ASSERT_TRUE(m.Initialize(db_path()));
+ ASSERT_TRUE(m.Initialize(db_path_));
memset(buf, '0', sizeof(buf));
ASSERT_EQ(0, memcmp(buf, m.data() + 0*sizeof(buf), sizeof(buf)));
@@ -240,7 +244,7 @@ TEST_F(SQLiteFeaturesTest, Mmap) {
// Scribble some '3' into the first page of the file, and verify that it
// looks the same in the memory mapping.
{
- base::File f(db_path(), kFlags);
+ base::File f(db_path_, kFlags);
ASSERT_TRUE(f.IsValid());
memset(buf, '3', sizeof(buf));
ASSERT_EQ(f.Write(0*sizeof(buf), buf, sizeof(buf)), (int)sizeof(buf));
@@ -251,7 +255,7 @@ TEST_F(SQLiteFeaturesTest, Mmap) {
const size_t kOffset = 1*sizeof(buf) + 123;
ASSERT_NE('4', m.data()[kOffset]);
{
- base::File f(db_path(), kFlags);
+ base::File f(db_path_, kFlags);
ASSERT_TRUE(f.IsValid());
buf[0] = '4';
ASSERT_EQ(f.Write(kOffset, buf, 1), 1);
@@ -264,14 +268,14 @@ TEST_F(SQLiteFeaturesTest, Mmap) {
// compiled regular expression is effectively cached with the prepared
// statement, causing errors if the regular expression is rebound.
TEST_F(SQLiteFeaturesTest, CachedRegexp) {
- ASSERT_TRUE(db().Execute("CREATE TABLE r (id INTEGER UNIQUE, x TEXT)"));
- ASSERT_TRUE(db().Execute("INSERT INTO r VALUES (1, 'this is a test')"));
- ASSERT_TRUE(db().Execute("INSERT INTO r VALUES (2, 'that was a test')"));
- ASSERT_TRUE(db().Execute("INSERT INTO r VALUES (3, 'this is a stickup')"));
- ASSERT_TRUE(db().Execute("INSERT INTO r VALUES (4, 'that sucks')"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE r (id INTEGER UNIQUE, x TEXT)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO r VALUES (1, 'this is a test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO r VALUES (2, 'that was a test')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO r VALUES (3, 'this is a stickup')"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO r VALUES (4, 'that sucks')"));
static const char kSimpleSql[] = "SELECT SUM(id) FROM r WHERE x REGEXP ?";
- sql::Statement s(db().GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
+ sql::Statement s(db_.GetCachedStatement(SQL_FROM_HERE, kSimpleSql));
s.BindString(0, "this.*");
ASSERT_TRUE(s.Step());
@@ -297,26 +301,26 @@ TEST_F(SQLiteFeaturesTest, CachedRegexp) {
// If a database file is marked to be excluded from Time Machine, verify that
// journal files are also excluded.
TEST_F(SQLiteFeaturesTest, TimeMachine) {
- ASSERT_TRUE(db().Execute("CREATE TABLE t (id INTEGER PRIMARY KEY)"));
- db().Close();
+ ASSERT_TRUE(db_.Execute("CREATE TABLE t (id INTEGER PRIMARY KEY)"));
+ db_.Close();
- base::FilePath journal_path = sql::Database::JournalPath(db_path());
- ASSERT_TRUE(GetPathExists(db_path()));
- ASSERT_TRUE(GetPathExists(journal_path));
+ base::FilePath journal_path = sql::Database::JournalPath(db_path_);
+ ASSERT_TRUE(base::PathExists(db_path_));
+ ASSERT_TRUE(base::PathExists(journal_path));
// Not excluded to start.
- EXPECT_FALSE(base::mac::GetFileBackupExclusion(db_path()));
+ EXPECT_FALSE(base::mac::GetFileBackupExclusion(db_path_));
EXPECT_FALSE(base::mac::GetFileBackupExclusion(journal_path));
// Exclude the main database file.
- EXPECT_TRUE(base::mac::SetFileBackupExclusion(db_path()));
+ EXPECT_TRUE(base::mac::SetFileBackupExclusion(db_path_));
- EXPECT_TRUE(base::mac::GetFileBackupExclusion(db_path()));
+ EXPECT_TRUE(base::mac::GetFileBackupExclusion(db_path_));
EXPECT_FALSE(base::mac::GetFileBackupExclusion(journal_path));
- EXPECT_TRUE(db().Open(db_path()));
- ASSERT_TRUE(db().Execute("INSERT INTO t VALUES (1)"));
- EXPECT_TRUE(base::mac::GetFileBackupExclusion(db_path()));
+ EXPECT_TRUE(db_.Open(db_path_));
+ ASSERT_TRUE(db_.Execute("INSERT INTO t VALUES (1)"));
+ EXPECT_TRUE(base::mac::GetFileBackupExclusion(db_path_));
EXPECT_TRUE(base::mac::GetFileBackupExclusion(journal_path));
// TODO(shess): In WAL mode this will touch -wal and -shm files. -shm files
@@ -329,30 +333,30 @@ TEST_F(SQLiteFeaturesTest, TimeMachine) {
// additional work into Chromium shutdown. Verify that SQLite supports a config
// option to not checkpoint on close.
TEST_F(SQLiteFeaturesTest, WALNoClose) {
- base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path());
+ base::FilePath wal_path = sql::Database::WriteAheadLogPath(db_path_);
// Turn on WAL mode, then verify that the mode changed (WAL is supported).
- ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL"));
- ASSERT_EQ("wal", ExecuteWithResult(&db(), "PRAGMA journal_mode"));
+ ASSERT_TRUE(db_.Execute("PRAGMA journal_mode = WAL"));
+ ASSERT_EQ("wal", ExecuteWithResult(&db_, "PRAGMA journal_mode"));
// The WAL file is created lazily on first change.
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a, b)"));
// By default, the WAL is checkpointed then deleted on close.
- ASSERT_TRUE(GetPathExists(wal_path));
- db().Close();
- ASSERT_FALSE(GetPathExists(wal_path));
+ ASSERT_TRUE(base::PathExists(wal_path));
+ db_.Close();
+ ASSERT_FALSE(base::PathExists(wal_path));
// Reopen and configure the database to not checkpoint WAL on close.
ASSERT_TRUE(Reopen());
- ASSERT_TRUE(db().Execute("PRAGMA journal_mode = WAL"));
- ASSERT_TRUE(db().Execute("ALTER TABLE foo ADD COLUMN c"));
- ASSERT_EQ(SQLITE_OK,
- sqlite3_db_config(db().db_, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1,
- nullptr));
- ASSERT_TRUE(GetPathExists(wal_path));
- db().Close();
- ASSERT_TRUE(GetPathExists(wal_path));
+ ASSERT_TRUE(db_.Execute("PRAGMA journal_mode = WAL"));
+ ASSERT_TRUE(db_.Execute("ALTER TABLE foo ADD COLUMN c"));
+ ASSERT_EQ(
+ SQLITE_OK,
+ sqlite3_db_config(db_.db_, SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, 1, nullptr));
+ ASSERT_TRUE(base::PathExists(wal_path));
+ db_.Close();
+ ASSERT_TRUE(base::PathExists(wal_path));
}
#endif
diff --git a/chromium/sql/statement.cc b/chromium/sql/statement.cc
index 87c2b120796..fe8ae340aaf 100644
--- a/chromium/sql/statement.cc
+++ b/chromium/sql/statement.cc
@@ -79,7 +79,7 @@ int Statement::StepInternal() {
if (!CheckValid())
return SQLITE_ERROR;
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
stepped_ = true;
@@ -109,7 +109,7 @@ void Statement::Reset(bool clear_bound_vars) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#endif // OS_ANDROID
- base::Optional<base::ScopedBlockingCall> scoped_blocking_call;
+ absl::optional<base::ScopedBlockingCall> scoped_blocking_call;
ref_->InitScopedBlockingCall(FROM_HERE, &scoped_blocking_call);
if (is_valid()) {
if (clear_bound_vars)
diff --git a/chromium/sql/statement_unittest.cc b/chromium/sql/statement_unittest.cc
index 2033ee367e9..af85326ea2d 100644
--- a/chromium/sql/statement_unittest.cc
+++ b/chromium/sql/statement_unittest.cc
@@ -11,29 +11,40 @@
#include "sql/statement.h"
#include "sql/test/error_callback_support.h"
#include "sql/test/scoped_error_expecter.h"
-#include "sql/test/sql_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
+namespace sql {
namespace {
-using SQLStatementTest = sql::SQLTestBase;
+class SQLStatementTest : public testing::Test {
+ public:
+ ~SQLStatementTest() override = default;
-} // namespace
+ void SetUp() override {
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ db_.Open(temp_dir_.GetPath().AppendASCII("statement_test.sqlite")));
+ }
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ Database db_;
+};
TEST_F(SQLStatementTest, Assign) {
- sql::Statement s;
+ Statement s;
EXPECT_FALSE(s.is_valid());
- s.Assign(db().GetUniqueStatement("CREATE TABLE foo (a, b)"));
+ s.Assign(db_.GetUniqueStatement("CREATE TABLE foo (a, b)"));
EXPECT_TRUE(s.is_valid());
}
TEST_F(SQLStatementTest, Run) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
- sql::Statement s(db().GetUniqueStatement("SELECT b FROM foo WHERE a=?"));
+ Statement s(db_.GetUniqueStatement("SELECT b FROM foo WHERE a=?"));
EXPECT_FALSE(s.Succeeded());
// Stepping it won't work since we haven't bound the value.
@@ -44,7 +55,7 @@ TEST_F(SQLStatementTest, Run) {
s.Reset(true);
s.BindInt(0, 3);
EXPECT_FALSE(s.Run());
- EXPECT_EQ(SQLITE_ROW, db().GetErrorCode());
+ EXPECT_EQ(SQLITE_ROW, db_.GetErrorCode());
EXPECT_TRUE(s.Succeeded());
// Resetting it should put it back to the previous state (not runnable).
@@ -62,16 +73,16 @@ TEST_F(SQLStatementTest, Run) {
// Error callback called for error running a statement.
TEST_F(SQLStatementTest, ErrorCallback) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
int error = SQLITE_OK;
- sql::ScopedErrorCallback sec(
- &db(), base::BindRepeating(&sql::CaptureErrorCallback, &error));
+ ScopedErrorCallback sec(&db_,
+ base::BindRepeating(&CaptureErrorCallback, &error));
// Insert in the foo table the primary key. It is an error to insert
// something other than an number. This error causes the error callback
// handler to be called with SQLITE_MISMATCH as error code.
- sql::Statement s(db().GetUniqueStatement("INSERT INTO foo (a) VALUES (?)"));
+ Statement s(db_.GetUniqueStatement("INSERT INTO foo (a) VALUES (?)"));
EXPECT_TRUE(s.is_valid());
s.BindCString(0, "bad bad");
EXPECT_FALSE(s.Run());
@@ -80,9 +91,9 @@ TEST_F(SQLStatementTest, ErrorCallback) {
// Error expecter works for error running a statement.
TEST_F(SQLStatementTest, ScopedIgnoreError) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
- sql::Statement s(db().GetUniqueStatement("INSERT INTO foo (a) VALUES (?)"));
+ Statement s(db_.GetUniqueStatement("INSERT INTO foo (a) VALUES (?)"));
EXPECT_TRUE(s.is_valid());
{
@@ -95,12 +106,11 @@ TEST_F(SQLStatementTest, ScopedIgnoreError) {
}
TEST_F(SQLStatementTest, Reset) {
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
- ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (4, 13)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
+ ASSERT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (4, 13)"));
- sql::Statement s(db().GetUniqueStatement(
- "SELECT b FROM foo WHERE a = ? "));
+ Statement s(db_.GetUniqueStatement("SELECT b FROM foo WHERE a = ? "));
s.BindInt(0, 3);
ASSERT_TRUE(s.Step());
EXPECT_EQ(12, s.ColumnInt(0));
@@ -115,3 +125,6 @@ TEST_F(SQLStatementTest, Reset) {
s.Reset(true);
ASSERT_FALSE(s.Step());
}
+
+} // namespace
+} // namespace sql
diff --git a/chromium/sql/transaction_unittest.cc b/chromium/sql/transaction_unittest.cc
index bcc05f5815b..48f75da20b2 100644
--- a/chromium/sql/transaction_unittest.cc
+++ b/chromium/sql/transaction_unittest.cc
@@ -3,38 +3,50 @@
// found in the LICENSE file.
#include "sql/transaction.h"
+
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "sql/database.h"
#include "sql/statement.h"
-#include "sql/test/sql_test_base.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
-class SQLTransactionTest : public sql::SQLTestBase {
+namespace sql {
+
+namespace {
+
+class SQLTransactionTest : public testing::Test {
public:
+ ~SQLTransactionTest() override = default;
+
void SetUp() override {
- SQLTestBase::SetUp();
+ ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+ ASSERT_TRUE(
+ db_.Open(temp_dir_.GetPath().AppendASCII("transaction_test.sqlite")));
- ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
+ ASSERT_TRUE(db_.Execute("CREATE TABLE foo (a, b)"));
}
// Returns the number of rows in table "foo".
int CountFoo() {
- sql::Statement count(db().GetUniqueStatement("SELECT count(*) FROM foo"));
+ Statement count(db_.GetUniqueStatement("SELECT count(*) FROM foo"));
count.Step();
return count.ColumnInt(0);
}
+
+ protected:
+ base::ScopedTempDir temp_dir_;
+ Database db_;
};
TEST_F(SQLTransactionTest, Commit) {
{
- sql::Transaction t(&db());
+ Transaction t(&db_);
EXPECT_FALSE(t.is_open());
EXPECT_TRUE(t.Begin());
EXPECT_TRUE(t.is_open());
- EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
t.Commit();
EXPECT_FALSE(t.is_open());
@@ -47,23 +59,23 @@ TEST_F(SQLTransactionTest, Rollback) {
// Test some basic initialization, and that rollback runs when you exit the
// scope.
{
- sql::Transaction t(&db());
+ Transaction t(&db_);
EXPECT_FALSE(t.is_open());
EXPECT_TRUE(t.Begin());
EXPECT_TRUE(t.is_open());
- EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
}
// Nothing should have been committed since it was implicitly rolled back.
EXPECT_EQ(0, CountFoo());
// Test explicit rollback.
- sql::Transaction t2(&db());
+ Transaction t2(&db_);
EXPECT_FALSE(t2.is_open());
EXPECT_TRUE(t2.Begin());
- EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ EXPECT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
t2.Rollback();
EXPECT_FALSE(t2.is_open());
@@ -73,23 +85,23 @@ TEST_F(SQLTransactionTest, Rollback) {
// Rolling back any part of a transaction should roll back all of them.
TEST_F(SQLTransactionTest, NestedRollback) {
- EXPECT_EQ(0, db().transaction_nesting());
+ EXPECT_EQ(0, db_.transaction_nesting());
// Outermost transaction.
{
- sql::Transaction outer(&db());
+ Transaction outer(&db_);
EXPECT_TRUE(outer.Begin());
- EXPECT_EQ(1, db().transaction_nesting());
+ EXPECT_EQ(1, db_.transaction_nesting());
// The first inner one gets committed.
{
- sql::Transaction inner1(&db());
+ Transaction inner1(&db_);
EXPECT_TRUE(inner1.Begin());
- EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
- EXPECT_EQ(2, db().transaction_nesting());
+ EXPECT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ EXPECT_EQ(2, db_.transaction_nesting());
inner1.Commit();
- EXPECT_EQ(1, db().transaction_nesting());
+ EXPECT_EQ(1, db_.transaction_nesting());
}
// One row should have gotten inserted.
@@ -97,24 +109,28 @@ TEST_F(SQLTransactionTest, NestedRollback) {
// The second inner one gets rolled back.
{
- sql::Transaction inner2(&db());
+ Transaction inner2(&db_);
EXPECT_TRUE(inner2.Begin());
- EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
- EXPECT_EQ(2, db().transaction_nesting());
+ EXPECT_TRUE(db_.Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
+ EXPECT_EQ(2, db_.transaction_nesting());
inner2.Rollback();
- EXPECT_EQ(1, db().transaction_nesting());
+ EXPECT_EQ(1, db_.transaction_nesting());
}
// A third inner one will fail in Begin since one has already been rolled
// back.
- EXPECT_EQ(1, db().transaction_nesting());
+ EXPECT_EQ(1, db_.transaction_nesting());
{
- sql::Transaction inner3(&db());
+ Transaction inner3(&db_);
EXPECT_FALSE(inner3.Begin());
- EXPECT_EQ(1, db().transaction_nesting());
+ EXPECT_EQ(1, db_.transaction_nesting());
}
}
- EXPECT_EQ(0, db().transaction_nesting());
+ EXPECT_EQ(0, db_.transaction_nesting());
EXPECT_EQ(0, CountFoo());
}
+
+} // namespace
+
+} // namespace sql