1 // 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 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <string> 12 13 #include "base/compiler_specific.h" 14 #include "base/files/file_path.h" 15 16 // Collection of test-only convenience functions. 17 18 namespace base { 19 class FilePath; 20 } 21 22 namespace sql { 23 class Database; 24 } 25 26 namespace sql { 27 namespace test { 28 29 // 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 // 36 // 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 // 40 // Returns false if any error occurs accessing the file. 41 bool CorruptSizeInHeader(const base::FilePath& db_path) WARN_UNUSED_RESULT; 42 43 // Common implementation of CorruptSizeInHeader() which operates on loaded 44 // memory. Shared between CorruptSizeInHeader() and the the mojo proxy testing 45 // code. 46 void CorruptSizeInHeaderMemory(unsigned char* header, int64_t db_size); 47 48 // 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. 51 bool CorruptSizeInHeaderWithLock( 52 const base::FilePath& db_path) WARN_UNUSED_RESULT; 53 54 // 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? 70 bool CorruptTableOrIndex(const base::FilePath& db_path, 71 const char* tree_name, 72 const char* update_sql) WARN_UNUSED_RESULT; 73 74 // Return the number of tables in sqlite_master. 75 size_t CountSQLTables(sql::Database* db) WARN_UNUSED_RESULT; 76 77 // Return the number of indices in sqlite_master. 78 size_t CountSQLIndices(sql::Database* db) WARN_UNUSED_RESULT; 79 80 // Returns the number of columns in the named table. 0 indicates an 81 // error (probably no such table). 82 size_t CountTableColumns(sql::Database* db, 83 const char* table) WARN_UNUSED_RESULT; 84 85 // Sets |*count| to the number of rows in |table|. Returns false in 86 // case of error, such as the table not existing. 87 bool CountTableRows(sql::Database* db, const char* table, size_t* count); 88 89 // 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. 93 bool CreateDatabaseFromSQL(const base::FilePath& db_path, 94 const base::FilePath& sql_path) WARN_UNUSED_RESULT; 95 96 // Return the results of running "PRAGMA integrity_check" on |db|. 97 // TODO(shess): sql::Database::IntegrityCheck() is basically the 98 // same, but not as convenient for testing. Maybe combine. 99 std::string IntegrityCheck(sql::Database* db) WARN_UNUSED_RESULT; 100 101 // 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. 116 std::string ExecuteWithResult(sql::Database* db, const char* sql); 117 std::string ExecuteWithResults(sql::Database* db, 118 const char* sql, 119 const char* column_sep, 120 const char* row_sep); 121 122 // Returns the database size, in pages. Crashes on SQLite errors. 123 int GetPageCount(sql::Database* db); 124 125 // Column information returned by GetColumnInfo. 126 // 127 // C++ wrapper around the out-params of sqlite3_table_column_metadata(). 128 struct 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 155 } // namespace test 156 } // namespace sql 157 158 #endif // SQL_TEST_TEST_HELPERS_H_ 159