blob: baa72d02d802a62888ca57ab81cae8b2e71a41e6 [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
Victor Costane06e6842022-03-09 20:36:0576// Test-friendly wrapper around sql::Database::IntegrityCheck().
77[[nodiscard]] std::string IntegrityCheck(sql::Database& db);
[email protected]a8848a72013-11-18 04:18:4778
shess1f955b182016-10-25 22:59:0979// ExecuteWithResult() executes |sql| and returns the first column of the first
80// row as a string. The empty string is returned for no rows. This makes it
81// easier to test simple query results using EXPECT_EQ(). For instance:
82// EXPECT_EQ("1024", ExecuteWithResult(db, "PRAGMA page_size"));
83//
84// ExecuteWithResults() stringifies a larger result set by putting |column_sep|
85// between columns and |row_sep| between rows. For instance:
86// EXPECT_EQ("1,3,5", ExecuteWithResults(
87// db, "SELECT id FROM t ORDER BY id", "|", ","));
88// Note that EXPECT_EQ() can nicely diff when using \n as |row_sep|.
89//
90// To test NULL, use the COALESCE() function:
91// EXPECT_EQ("<NULL>", ExecuteWithResult(
92// db, "SELECT c || '<NULL>' FROM t WHERE id = 1"));
93// To test blobs use the HEX() function.
Victor Costancfbfa602018-08-01 23:24:4694std::string ExecuteWithResult(sql::Database* db, const char* sql);
95std::string ExecuteWithResults(sql::Database* db,
shess1f955b182016-10-25 22:59:0996 const char* sql,
97 const char* column_sep,
98 const char* row_sep);
99
Victor Costan455989b2019-05-13 21:43:15100// Returns the database size, in pages. Crashes on SQLite errors.
101int GetPageCount(sql::Database* db);
102
103// Column information returned by GetColumnInfo.
104//
105// C++ wrapper around the out-params of sqlite3_table_column_metadata().
106struct ColumnInfo {
107 // Retrieves schema information for a column in a table.
108 //
109 // Crashes on SQLite errors.
110 //
111 // |db_name| should be "main" for the connection's main (opened) database, and
112 // "temp" for the connection's temporary (in-memory) database.
113 //
114 // This is a static method rather than a function so it can be listed in the
115 // InternalApiToken access control list.
Daniel Cheng1ac0cad2022-01-14 00:19:53116 [[nodiscard]] static ColumnInfo Create(sql::Database* db,
117 const std::string& db_name,
118 const std::string& table_name,
119 const std::string& column_name);
Victor Costan455989b2019-05-13 21:43:15120
121 // The native data type. Example: "INTEGER".
122 std::string data_type;
123 // Default collation sequence for sorting. Example: "BINARY".
124 std::string collation_sequence;
125 // True if the column has a "NOT NULL" constraint.
126 bool has_non_null_constraint;
127 // True if the column is included in the table's PRIMARY KEY.
128 bool is_in_primary_key;
129 // True if the column is AUTOINCREMENT.
130 bool is_auto_incremented;
131};
132
Victor Costan63b2c4c42022-02-26 03:43:44133} // namespace sql::test
[email protected]43ffdd82013-09-10 23:44:50134
135#endif // SQL_TEST_TEST_HELPERS_H_