blob: ba98f42e08b97c9caec392e169f004691b1f4ff7 [file] [log] [blame]
[email protected]43ffdd82013-09-10 23:44:501// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef SQL_TEST_TEST_HELPERS_H_
6#define SQL_TEST_TEST_HELPERS_H_
7
avi0b519202015-12-21 07:25:198#include <stddef.h>
9#include <stdint.h>
10
[email protected]a8848a72013-11-18 04:18:4711#include <string>
12
Victor Costan63b2c4c42022-02-26 03:43:4413#include "base/strings/string_piece_forward.h"
[email protected]43ffdd82013-09-10 23:44:5014
15// Collection of test-only convenience functions.
16
17namespace base {
18class FilePath;
19}
20
21namespace sql {
Victor Costancfbfa602018-08-01 23:24:4622class Database;
[email protected]43ffdd82013-09-10 23:44:5023}
24
Victor Costan63b2c4c42022-02-26 03:43:4425namespace sql::test {
[email protected]43ffdd82013-09-10 23:44:5026
[email protected]a8848a72013-11-18 04:18:4727// SQLite stores the database size in the header, and if the actual
28// OS-derived size is smaller, the database is considered corrupt.
29// [This case is actually a common form of corruption in the wild.]
30// This helper sets the in-header size to one page larger than the
31// actual file size. The resulting file will return SQLITE_CORRUPT
32// for most operations unless PRAGMA writable_schema is turned ON.
33//
shess4640cc22016-10-19 22:47:1334// This function operates on the raw database file, outstanding database
35// connections may not see the change because of the database cache. See
36// CorruptSizeInHeaderWithLock().
37//
[email protected]a8848a72013-11-18 04:18:4738// Returns false if any error occurs accessing the file.
Daniel Cheng1ac0cad2022-01-14 00:19:5339[[nodiscard]] bool CorruptSizeInHeader(const base::FilePath& db_path);
[email protected]a8848a72013-11-18 04:18:4740
shess4640cc22016-10-19 22:47:1341// Call CorruptSizeInHeader() while holding a SQLite-compatible lock
42// on the database. This can be used to corrupt a database which is
43// already open elsewhere. Blocks until a write lock can be acquired.
Daniel Cheng1ac0cad2022-01-14 00:19:5344[[nodiscard]] bool CorruptSizeInHeaderWithLock(const base::FilePath& db_path);
shess4640cc22016-10-19 22:47:1345
Victor Costan63b2c4c42022-02-26 03:43:4446// Simulates total index corruption by zeroing the root page of an index B-tree.
[email protected]ae4f1622013-12-08 06:49:1247//
Victor Costan63b2c4c42022-02-26 03:43:4448// The corrupted database will still open successfully. SELECTs on the table
49// associated with the index will work, as long as they don't access the index.
50// However, any query that accesses the index will fail with SQLITE_CORRUPT.
51// DROPping the table or the index will fail.
52[[nodiscard]] bool CorruptIndexRootPage(const base::FilePath& db_path,
53 base::StringPiece index_name);
[email protected]ae4f1622013-12-08 06:49:1254
John Delaney86dbec62021-08-24 15:05:2155// Return the number of tables in sqlite_schema.
Daniel Cheng1ac0cad2022-01-14 00:19:5356[[nodiscard]] size_t CountSQLTables(sql::Database* db);
[email protected]43ffdd82013-09-10 23:44:5057
John Delaney86dbec62021-08-24 15:05:2158// Return the number of indices in sqlite_schema.
Daniel Cheng1ac0cad2022-01-14 00:19:5359[[nodiscard]] size_t CountSQLIndices(sql::Database* db);
[email protected]43ffdd82013-09-10 23:44:5060
61// Returns the number of columns in the named table. 0 indicates an
62// error (probably no such table).
Daniel Cheng1ac0cad2022-01-14 00:19:5363[[nodiscard]] size_t CountTableColumns(sql::Database* db, const char* table);
[email protected]43ffdd82013-09-10 23:44:5064
[email protected]fe4e3de2013-10-08 02:19:1765// Sets |*count| to the number of rows in |table|. Returns false in
66// case of error, such as the table not existing.
Victor Costancfbfa602018-08-01 23:24:4667bool CountTableRows(sql::Database* db, const char* table, size_t* count);
[email protected]fe4e3de2013-10-08 02:19:1768
[email protected]43ffdd82013-09-10 23:44:5069// Creates a SQLite database at |db_path| from the sqlite .dump output
70// at |sql_path|. Returns false if |db_path| already exists, or if
71// sql_path does not exist or cannot be read, or if there is an error
72// executing the statements.
Daniel Cheng1ac0cad2022-01-14 00:19:5373[[nodiscard]] bool CreateDatabaseFromSQL(const base::FilePath& db_path,
74 const base::FilePath& sql_path);
[email protected]43ffdd82013-09-10 23:44:5075
[email protected]a8848a72013-11-18 04:18:4776// Return the results of running "PRAGMA integrity_check" on |db|.
Victor Costancfbfa602018-08-01 23:24:4677// TODO(shess): sql::Database::IntegrityCheck() is basically the
[email protected]a8848a72013-11-18 04:18:4778// same, but not as convenient for testing. Maybe combine.
Daniel Cheng1ac0cad2022-01-14 00:19:5379[[nodiscard]] std::string IntegrityCheck(sql::Database* db);
[email protected]a8848a72013-11-18 04:18:4780
shess1f955b182016-10-25 22:59:0981// ExecuteWithResult() executes |sql| and returns the first column of the first
82// row as a string. The empty string is returned for no rows. This makes it
83// easier to test simple query results using EXPECT_EQ(). For instance:
84// EXPECT_EQ("1024", ExecuteWithResult(db, "PRAGMA page_size"));
85//
86// ExecuteWithResults() stringifies a larger result set by putting |column_sep|
87// between columns and |row_sep| between rows. For instance:
88// EXPECT_EQ("1,3,5", ExecuteWithResults(
89// db, "SELECT id FROM t ORDER BY id", "|", ","));
90// Note that EXPECT_EQ() can nicely diff when using \n as |row_sep|.
91//
92// To test NULL, use the COALESCE() function:
93// EXPECT_EQ("<NULL>", ExecuteWithResult(
94// db, "SELECT c || '<NULL>' FROM t WHERE id = 1"));
95// To test blobs use the HEX() function.
Victor Costancfbfa602018-08-01 23:24:4696std::string ExecuteWithResult(sql::Database* db, const char* sql);
97std::string ExecuteWithResults(sql::Database* db,
shess1f955b182016-10-25 22:59:0998 const char* sql,
99 const char* column_sep,
100 const char* row_sep);
101
Victor Costan455989b2019-05-13 21:43:15102// Returns the database size, in pages. Crashes on SQLite errors.
103int GetPageCount(sql::Database* db);
104
105// Column information returned by GetColumnInfo.
106//
107// C++ wrapper around the out-params of sqlite3_table_column_metadata().
108struct ColumnInfo {
109 // Retrieves schema information for a column in a table.
110 //
111 // Crashes on SQLite errors.
112 //
113 // |db_name| should be "main" for the connection's main (opened) database, and
114 // "temp" for the connection's temporary (in-memory) database.
115 //
116 // This is a static method rather than a function so it can be listed in the
117 // InternalApiToken access control list.
Daniel Cheng1ac0cad2022-01-14 00:19:53118 [[nodiscard]] static ColumnInfo Create(sql::Database* db,
119 const std::string& db_name,
120 const std::string& table_name,
121 const std::string& column_name);
Victor Costan455989b2019-05-13 21:43:15122
123 // The native data type. Example: "INTEGER".
124 std::string data_type;
125 // Default collation sequence for sorting. Example: "BINARY".
126 std::string collation_sequence;
127 // True if the column has a "NOT NULL" constraint.
128 bool has_non_null_constraint;
129 // True if the column is included in the table's PRIMARY KEY.
130 bool is_in_primary_key;
131 // True if the column is AUTOINCREMENT.
132 bool is_auto_incremented;
133};
134
Victor Costan63b2c4c42022-02-26 03:43:44135} // namespace sql::test
[email protected]43ffdd82013-09-10 23:44:50136
137#endif // SQL_TEST_TEST_HELPERS_H_