Codemod asserts to assertxs in the runtime
[hiphop-php.git] / hphp / runtime / vm / repo-helpers.h
blob79bfe3bea78eb359e472cfbccfebe5a1c7b3bc85
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 #ifndef incl_HPHP_VM_REPO_HELPERS_H_
18 #define incl_HPHP_VM_REPO_HELPERS_H_
20 #include "hphp/runtime/base/attr.h"
21 #include "hphp/runtime/base/types.h"
23 #include "hphp/util/md5.h"
24 #include "hphp/util/portability.h"
26 #include <sqlite3.h>
28 #include <folly/portability/Stdio.h>
30 namespace HPHP {
32 // Forward declaration.
33 struct BlobDecoder;
34 struct BlobEncoder;
35 struct StringData;
36 struct TypedValue;
37 struct Repo;
39 enum RepoId {
40 RepoIdInvalid = -1,
41 RepoIdCentral = 0,
42 RepoIdLocal = 1,
44 RepoIdCount = 2 // Number of database IDs.
47 struct RepoExc : std::exception {
48 RepoExc(ATTRIBUTE_PRINTF_STRING const char* fmt, ...)
49 ATTRIBUTE_PRINTF(2, 3) {
50 va_list(ap);
51 va_start(ap, fmt);
52 char* msg;
53 if (vasprintf(&msg, fmt, ap) == -1) {
54 m_msg = "";
55 } else {
56 m_msg = msg;
57 free(msg);
59 va_end(ap);
61 const std::string& msg() const { return m_msg; }
62 const char* what() const noexcept override { return m_msg.c_str(); }
64 private:
65 std::string m_msg;
68 struct RepoStmt {
69 explicit RepoStmt(Repo& repo);
70 ~RepoStmt();
71 private:
72 void finalize();
73 public:
74 bool prepared() const { return (m_stmt != nullptr); }
75 void prepare(const std::string& sql); // throws(RepoExc)
76 void reset();
77 Repo& repo() const { return m_repo; }
78 sqlite3_stmt*& get() { return m_stmt; }
79 const std::string& sql() const { return m_sql; }
81 protected:
82 Repo& m_repo;
83 std::string m_sql;
84 sqlite3_stmt* m_stmt;
87 // Under most circumstances RepoTxnQuery should be used instead of RepoQuery;
88 // queries outside of transactions are fraught with peril.
89 struct RepoQuery {
90 explicit RepoQuery(RepoStmt& stmt)
91 : m_stmt(stmt), m_row(false), m_done(false) {
92 assertx(m_stmt.prepared());
94 ~RepoQuery() { m_stmt.reset(); }
96 void bindBlob(const char* paramName, const void* blob, size_t size,
97 bool isStatic=false);
98 void bindBlob(const char* paramName, const BlobEncoder& blob,
99 bool isStatic=false);
100 void bindMd5(const char* paramName, const MD5& md5);
101 void bindTypedValue(const char* paramName, const TypedValue& tv);
102 void bindText(const char* paramName, const char* text, size_t size,
103 bool isStatic=false);
104 void bindStaticString(const char* paramName, const StringData* sd);
105 void bindStdString(const char* paramName, const std::string& s);
106 void bindStringPiece(const char* paramName, const folly::StringPiece s);
107 void bindDouble(const char* paramName, double val);
108 void bindInt(const char* paramName, int val);
109 void bindId(const char* paramName, Id id);
110 void bindOffset(const char* paramName, Offset offset);
111 void bindAttr(const char* paramName, Attr attrs);
112 void bindBool(const char* paramName, bool b);
113 void bindInt64(const char* paramName, int64_t val);
114 void bindNull(const char* paramName);
116 void step(); // throws(RepoExc)
117 bool row() const { return m_row; }
118 bool done() const { return m_done; }
119 void reset();
120 void exec(); // throws(RepoExc)
122 // rowid() returns the row id associated with the most recent successful
123 // insert. Thus the rowid is irrelevant for non-insert queries.
124 int64_t getInsertedRowid();
125 bool isBlob(int iCol);
126 bool isText(int iCol);
127 bool isDouble(int iCol);
128 bool isInt(int iCol);
129 bool isNull(int iCol);
131 // Get the column value as the named type. If the value cannot be converted
132 // into the named type then an error is thrown.
133 void getBlob(int iCol, const void*& blob, size_t& size); // throws(RepoExc)
134 BlobDecoder getBlob(int iCol); // throws(RepoExc)
135 void getMd5(int iCol, MD5& md5); // throws(RepoExc)
136 void getTypedValue(int iCol, TypedValue& tv); // throws(RepoExc)
137 void getText(int iCol, const char*& text); // throws(RepoExc)
138 void getText(int iCol, const char*& text, size_t& size); // throws(RepoExc)
139 void getStaticString(int iCol, StringData*& s); // throws(RepoExc)
140 void getStdString(int iCol, std::string& s); // throws(RepoExc)
141 void getDouble(int iCol, double& val); // throws(RepoExc)
142 void getInt(int iCol, int& val); // throws(RepoExc)
143 void getId(int iCol, Id& id); // throws(RepoExc)
144 void getOffset(int iCol, Offset& offset); // throws(RepoExc)
145 void getAttr(int iCol, Attr& attrs); // throws(RepoExc)
146 void getBool(int iCol, bool& b); // throws(RepoExc)
147 void getInt64(int iCol, int64_t& val); // throws(RepoExc)
149 protected:
150 RepoStmt& m_stmt;
151 bool m_row;
152 bool m_done;
156 * Transaction guard object.
158 * Semantics: the guard object will rollback the transaction unless
159 * you tell it not to. Call .commit() when you want things to stay.
161 struct RepoTxn {
162 explicit RepoTxn(Repo& repo); // throws(RepoExc)
163 ~RepoTxn();
165 RepoTxn(const RepoTxn&) = delete;
166 RepoTxn& operator=(const RepoTxn&) = delete;
169 * All these routines may throw if there is an error accessing the
170 * repo. The RepoTxn object will rollback the entire transaction in
171 * any of these cases (which technically means they only provide the
172 * basic exception safety guarantee, even though the whole point is
173 * to behave transactionally. ;)
175 void prepare(RepoStmt& stmt, const std::string& sql); // throws(RepoExc)
176 void exec(const std::string& sQuery); // throws(RepoExc)
177 void commit(); // throws(RepoExc)
179 bool error() const { return m_error; }
181 private:
182 friend struct RepoTxnQuery;
183 void step(RepoQuery& query); // throws(RepoExc)
184 void exec(RepoQuery& query); // throws(RepoExc)
185 void rollback(); // nothrow
187 Repo& m_repo;
188 bool m_pending;
189 bool m_error;
191 template<class F> void rollback_guard(const char* func, F f);
194 struct RepoTxnQuery : RepoQuery {
195 RepoTxnQuery(RepoTxn& txn, RepoStmt& stmt)
196 : RepoQuery(stmt), m_txn(txn) {
199 void step(); // throws(RepoExc)
200 void exec(); // throws(RepoExc)
202 private:
203 RepoTxn& m_txn;
206 struct RepoProxy {
207 explicit RepoProxy(Repo& repo) : m_repo(repo) {}
208 ~RepoProxy() {}
210 protected:
211 struct Stmt : RepoStmt {
212 Stmt(Repo& repo, int repoId) : RepoStmt(repo), m_repoId(repoId) {}
213 protected:
214 int m_repoId;
217 Repo& m_repo;
222 #endif