This fixes a bug in PHP/HH's crypt_blowfish implementation that can cause a short...
[hiphop-php.git] / hphp / util / sqlite-wrapper.h
bloba14d9a5da8c65926bbb8e530f27ee48465e66d6e
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #pragma once
19 #include <string>
21 #include "hphp/util/sqlite-wrapper-helpers.h"
23 struct sqlite3;
25 namespace HPHP {
27 /**
28 * RAII wrapper around a sqlite3 database connection.
30 * Use with:
32 * SQLite& db = SQLite::get(":memory:");
34 * SQLiteTxn txn = db.begin();
35 * txn.exec("CREATE TABLE foo (bar)");
37 * SQLiteStmt insertStmt = db.prepare("INSERT INTO foo VALUES (@v)");
38 * for (auto i = 0; i < 10; i++) {
39 * SQLiteQuery query = db.query(insertStmt);
41 * query.bindInt("@v", i);
42 * query.step();
43 * }
45 * SQLiteStmt selectStmt = db.prepare("SELECT bar FROM foo;");
46 * SQLiteQuery query = txn.query(selectStmt);
47 * for (; !query.done(); query.step()) {
48 * std::cout << query.getInt(0) << std::endl;
49 * }
52 struct SQLite {
53 SQLite(SQLite&&) noexcept;
54 SQLite& operator=(SQLite&&) noexcept;
55 ~SQLite();
57 /**
58 * Run `ANALYZE` to improve query planning.
60 * We recommend you run this method after creating the DB and
61 * loading it with data.
63 * https://sqlite.org/lang_analyze.html
65 void analyze();
67 enum class OpenMode {
68 ReadOnly = 1,
69 ReadWrite = 2,
70 ReadWriteCreate = 3,
73 static std::string_view openModeName(SQLite::OpenMode mode) noexcept;
75 /**
76 * Return a new SQLite connection, creating the DB file if necessary.
78 * path is the location of the DB in your filesystem, or ":memory:"
79 * if you want to store data in memory instead.
81 static SQLite connect(const std::string& path,
82 OpenMode mode = OpenMode::ReadWriteCreate);
83 static SQLite connect(const char* path,
84 OpenMode mode = OpenMode::ReadWriteCreate);
86 /**
87 * Compile the given SQL query into a statement object which can run and rerun
88 * the query.
90 SQLiteStmt prepare(const std::string_view sql); // throws(SQLiteExc)
92 /**
93 * Begin a SQLite transaction to run queries within.
95 SQLiteTxn begin();
97 /**
98 * Sleep for a time up to the given maximum when the DB is locked.
100 * Setting a number equal to 0 or less than zero will disable the
101 * busy timeout.
103 void setBusyTimeout(int ms) noexcept;
105 enum class JournalMode {
106 // Default behavior. During each transaction, create a rollback journal
107 // with the extension `.sql3-journal` file during each transaction, and
108 // delete it when the transaction is committed or rolled back.
109 DELETE,
111 // Truncate the rollback journal to 0 bytes instead of deleting it from
112 // the filesystem.
113 TRUNCATE,
115 // Instead of deleting or truncating the rollback journal, overwrite the
116 // header with null bytes.
117 PERSIST,
119 // Instead of creating the rollback journal on-disk, store the journal
120 // in-memory. This may cause your database to become corrupt if your
121 // application crashes in the middle of a write transaction.
122 MEMORY,
124 // Instead of creating a rollback journal, create a write-ahead log file
125 // with the extension `.sql3-wal`.
126 WAL,
128 // Don't use a rollback journal at all. The behavior of the ROLLBACK
129 // command will be undefined if you enable this, and application crashes
130 // in the middle of a transaction can easily cause the db to become
131 // corrupt.
136 * Set SQLite's journaling mode.
138 * Journaling is the mechanism that SQLite uses to rollback transactions,
139 * recover from crashes and exceptions, and prevent other processes/threads
140 * from seeing data that hasn't officially been committed yet.
142 void setJournalMode(JournalMode mode);
144 enum class SynchronousLevel {
145 // Trust the filesystem to fsync for you. This may result in database
146 // corruption if power loss occurs.
147 OFF = 0,
149 // Sync often enough to guarantee consistency in WAL mode.
150 NORMAL = 1,
152 // Sync on every write.
153 FULL = 2,
155 // On every write, sync the SQLite DB, its journal or WAL, and the
156 // directory containing the files.
157 EXTRA = 3,
161 * Tell SQLite when to fsync the DB.
163 * https://www.sqlite.org/pragma.html#pragma_synchronous
165 void setSynchronousLevel(SynchronousLevel lvl);
168 * True iff this wrapper points to a valid SQLite connection.
170 * This will be false if we've moved a connection out of this object.
172 operator bool() const noexcept {
173 return m_dbc != nullptr;
176 bool operator!() const noexcept {
177 return m_dbc == nullptr;
181 * True iff the database is read-only.
183 * dbName: The name you've given to a database you ATTACHed to your
184 * connection, or "main" by default.
186 bool isReadOnly() const;
187 bool isReadOnly(const std::string& dbName) const;
188 bool isReadOnly(const char* dbName) const;
191 * Return the most recent error message from SQLite.
193 std::string errMsg() const noexcept;
195 private:
196 friend struct SQLiteStmt;
197 friend struct SQLiteTxn;
199 explicit SQLite(sqlite3* dbc);
201 SQLite() = delete;
202 SQLite(const SQLite&) = delete;
203 SQLite& operator=(const SQLite&) = delete;
205 void txPush(); // throws(SQLiteExc)
206 void txPop(); // throws(SQLiteExc)
207 void rollback() noexcept;
208 void commit(); // throws(SQLiteExc)
210 sqlite3* m_dbc = nullptr;
211 unsigned m_txDepth = 0; // Transaction nesting depth.
212 bool m_rollback = false; // If true, rollback rather than commit.
214 SQLiteStmt m_beginStmt;
215 SQLiteStmt m_rollbackStmt;
216 SQLiteStmt m_commitStmt;
219 } // namespace HPHP