blob: 39059e4def1279ee729587d7a545b5415f28f86c [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
[email protected]43ffdd82013-09-10 23:44:5013#include "base/compiler_specific.h"
[email protected]ae4f1622013-12-08 06:49:1214#include "base/files/file_path.h"
[email protected]43ffdd82013-09-10 23:44:5015
16// Collection of test-only convenience functions.
17
18namespace base {
19class FilePath;
20}
21
22namespace sql {
Victor Costancfbfa602018-08-01 23:24:4623class Database;
[email protected]43ffdd82013-09-10 23:44:5024}
25
26namespace sql {
27namespace test {
28
[email protected]a8848a72013-11-18 04:18:4729// SQLite stores the database size in the header, and if the actual
30// OS-derived size is smaller, the database is considered corrupt.
31// [This case is actually a common form of corruption in the wild.]
32// This helper sets the in-header size to one page larger than the
33// actual file size. The resulting file will return SQLITE_CORRUPT
34// for most operations unless PRAGMA writable_schema is turned ON.
35//
shess4640cc22016-10-19 22:47:1336// This function operates on the raw database file, outstanding database
37// connections may not see the change because of the database cache. See
38// CorruptSizeInHeaderWithLock().
39//
[email protected]a8848a72013-11-18 04:18:4740// Returns false if any error occurs accessing the file.
41bool CorruptSizeInHeader(const base::FilePath& db_path) WARN_UNUSED_RESULT;
42
erg102ceb412015-06-20 01:38:1343// Common implementation of CorruptSizeInHeader() which operates on loaded
44// memory. Shared between CorruptSizeInHeader() and the the mojo proxy testing
45// code.
46void CorruptSizeInHeaderMemory(unsigned char* header, int64_t db_size);
47
shess4640cc22016-10-19 22:47:1348// Call CorruptSizeInHeader() while holding a SQLite-compatible lock
49// on the database. This can be used to corrupt a database which is
50// already open elsewhere. Blocks until a write lock can be acquired.
51bool CorruptSizeInHeaderWithLock(
52 const base::FilePath& db_path) WARN_UNUSED_RESULT;
53
[email protected]ae4f1622013-12-08 06:49:1254// Frequently corruption is a result of failure to atomically update
55// pages in different structures. For instance, if an index update
56// takes effect but the corresponding table update does not. This
57// helper restores the prior version of a b-tree root after running an
58// update which changed that b-tree. The named b-tree must exist and
59// must be a leaf node (either index or table). Returns true if the
60// on-disk file is successfully modified, and the restored page
61// differs from the updated page.
62//
63// The resulting database should be possible to open, and many
64// statements should work. SQLITE_CORRUPT will be thrown if a query
65// through the index finds the row missing in the table.
66//
67// TODO(shess): It would be very helpful to allow a parameter to the
68// sql statement. Perhaps a version with a string parameter would be
69// sufficient, given affinity rules?
70bool CorruptTableOrIndex(const base::FilePath& db_path,
71 const char* tree_name,
72 const char* update_sql) WARN_UNUSED_RESULT;
73
[email protected]43ffdd82013-09-10 23:44:5074// Return the number of tables in sqlite_master.
Victor Costancfbfa602018-08-01 23:24:4675size_t CountSQLTables(sql::Database* db) WARN_UNUSED_RESULT;
[email protected]43ffdd82013-09-10 23:44:5076
77// Return the number of indices in sqlite_master.
Victor Costancfbfa602018-08-01 23:24:4678size_t CountSQLIndices(sql::Database* db) WARN_UNUSED_RESULT;
[email protected]43ffdd82013-09-10 23:44:5079
80// Returns the number of columns in the named table. 0 indicates an
81// error (probably no such table).
Victor Costancfbfa602018-08-01 23:24:4682size_t CountTableColumns(sql::Database* db,
83 const char* table) WARN_UNUSED_RESULT;
[email protected]43ffdd82013-09-10 23:44:5084
[email protected]fe4e3de2013-10-08 02:19:1785// Sets |*count| to the number of rows in |table|. Returns false in
86// case of error, such as the table not existing.
Victor Costancfbfa602018-08-01 23:24:4687bool CountTableRows(sql::Database* db, const char* table, size_t* count);
[email protected]fe4e3de2013-10-08 02:19:1788
[email protected]43ffdd82013-09-10 23:44:5089// Creates a SQLite database at |db_path| from the sqlite .dump output
90// at |sql_path|. Returns false if |db_path| already exists, or if
91// sql_path does not exist or cannot be read, or if there is an error
92// executing the statements.
93bool CreateDatabaseFromSQL(const base::FilePath& db_path,
94 const base::FilePath& sql_path) WARN_UNUSED_RESULT;
95
[email protected]a8848a72013-11-18 04:18:4796// Return the results of running "PRAGMA integrity_check" on |db|.
Victor Costancfbfa602018-08-01 23:24:4697// TODO(shess): sql::Database::IntegrityCheck() is basically the
[email protected]a8848a72013-11-18 04:18:4798// same, but not as convenient for testing. Maybe combine.
Victor Costancfbfa602018-08-01 23:24:4699std::string IntegrityCheck(sql::Database* db) WARN_UNUSED_RESULT;
[email protected]a8848a72013-11-18 04:18:47100
shess1f955b182016-10-25 22:59:09101// ExecuteWithResult() executes |sql| and returns the first column of the first
102// row as a string. The empty string is returned for no rows. This makes it
103// easier to test simple query results using EXPECT_EQ(). For instance:
104// EXPECT_EQ("1024", ExecuteWithResult(db, "PRAGMA page_size"));
105//
106// ExecuteWithResults() stringifies a larger result set by putting |column_sep|
107// between columns and |row_sep| between rows. For instance:
108// EXPECT_EQ("1,3,5", ExecuteWithResults(
109// db, "SELECT id FROM t ORDER BY id", "|", ","));
110// Note that EXPECT_EQ() can nicely diff when using \n as |row_sep|.
111//
112// To test NULL, use the COALESCE() function:
113// EXPECT_EQ("<NULL>", ExecuteWithResult(
114// db, "SELECT c || '<NULL>' FROM t WHERE id = 1"));
115// To test blobs use the HEX() function.
Victor Costancfbfa602018-08-01 23:24:46116std::string ExecuteWithResult(sql::Database* db, const char* sql);
117std::string ExecuteWithResults(sql::Database* db,
shess1f955b182016-10-25 22:59:09118 const char* sql,
119 const char* column_sep,
120 const char* row_sep);
121
Victor Costan455989b2019-05-13 21:43:15122// Returns the database size, in pages. Crashes on SQLite errors.
123int GetPageCount(sql::Database* db);
124
125// Column information returned by GetColumnInfo.
126//
127// C++ wrapper around the out-params of sqlite3_table_column_metadata().
128struct ColumnInfo {
129 // Retrieves schema information for a column in a table.
130 //
131 // Crashes on SQLite errors.
132 //
133 // |db_name| should be "main" for the connection's main (opened) database, and
134 // "temp" for the connection's temporary (in-memory) database.
135 //
136 // This is a static method rather than a function so it can be listed in the
137 // InternalApiToken access control list.
138 static ColumnInfo Create(sql::Database* db,
139 const std::string& db_name,
140 const std::string& table_name,
141 const std::string& column_name) WARN_UNUSED_RESULT;
142
143 // The native data type. Example: "INTEGER".
144 std::string data_type;
145 // Default collation sequence for sorting. Example: "BINARY".
146 std::string collation_sequence;
147 // True if the column has a "NOT NULL" constraint.
148 bool has_non_null_constraint;
149 // True if the column is included in the table's PRIMARY KEY.
150 bool is_in_primary_key;
151 // True if the column is AUTOINCREMENT.
152 bool is_auto_incremented;
153};
154
[email protected]43ffdd82013-09-10 23:44:50155} // namespace test
156} // namespace sql
157
158#endif // SQL_TEST_TEST_HELPERS_H_