Get mysqli_stmt_send_long_data to work
[hiphop-php.git] / hphp / runtime / ext / mysql / mysql_common.h
blob7ad088da2850bb3705d3f9539d05445bdf568ba7
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-2013 Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1997-2010 The PHP Group |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #ifndef incl_HPHP_MYSQL_COMMON_H_
19 #define incl_HPHP_MYSQL_COMMON_H_
21 #include "folly/Optional.h"
23 #include "hphp/runtime/base/base-includes.h"
24 #include "mysql.h"
25 #include "hphp/runtime/base/smart-containers.h"
27 #ifdef PHP_MYSQL_UNIX_SOCK_ADDR
28 #ifdef MYSQL_UNIX_ADDR
29 #undef MYSQL_UNIX_ADDR
30 #endif
31 #define MYSQL_UNIX_ADDR PHP_MYSQL_UNIX_SOCK_ADDR
32 #endif
34 namespace HPHP {
36 class MySQL : public SweepableResourceData {
37 public:
38 /**
39 * Operations on a resource object.
41 static MYSQL *GetConn(CVarRef link_identifier, MySQL **rconn = NULL);
42 static MySQL *Get(CVarRef link_identifier);
43 static bool CloseConn(CVarRef link_identifier);
45 /**
46 * Default settings.
48 static String GetDefaultServer() { return String();}
49 static int GetDefaultPort();
50 static String GetDefaultSocket();
51 static String GetDefaultUsername() { return String();}
52 static String GetDefaultPassword() { return String();}
53 static String GetDefaultDatabase() { return String();}
55 /**
56 * A connection may be persistent across multiple HTTP requests.
58 static MySQL *GetPersistent(const String& host, int port, const String& socket,
59 const String& username, const String& password,
60 int client_flags) {
61 return GetCachedImpl("mysql::persistent_conns", host, port, socket,
62 username, password, client_flags);
65 static void SetPersistent(const String& host, int port, const String& socket,
66 const String& username, const String& password,
67 int client_flags, MySQL *conn) {
68 SetCachedImpl("mysql::persistent_conns", host, port, socket,
69 username, password, client_flags, conn);
72 /**
73 * If connection object is not provided, a default connection will be used.
75 static MySQL *GetDefaultConn();
76 static void SetDefaultConn(MySQL *conn);
78 static int GetDefaultReadTimeout();
79 static void SetDefaultReadTimeout(int timeout_ms);
81 private:
82 static int s_default_port;
84 static String GetHash(const String& host, int port, const String& socket,
85 const String& username, const String& password, int client_flags);
87 static MySQL *GetCachedImpl(const char *name, const String& host, int port,
88 const String& socket, const String& username,
89 const String& password, int client_flags);
91 static void SetCachedImpl(const char *name, const String& host, int port,
92 const String& socket, const String& username, const String& password,
93 int client_flags, MySQL *conn);
95 public:
96 MySQL(const char *host, int port, const char *username,
97 const char *password, const char *database,
98 MYSQL* raw_connection = nullptr);
99 ~MySQL();
100 void sweep() FOLLY_OVERRIDE;
101 void setLastError(const char *func);
102 void close();
104 CLASSNAME_IS("mysql link")
105 // overriding ResourceData
106 virtual const String& o_getClassNameHook() const { return classnameof(); }
107 virtual bool isInvalid() const { return m_conn == nullptr; }
109 bool connect(const String& host, int port, const String& socket, const String& username,
110 const String& password, const String& database, int client_flags,
111 int connect_timeout);
112 #ifdef FACEBOOK
113 bool async_connect(const String& host, int port, const String& socket, const String& username,
114 const String& password, const String& database);
115 #endif
116 bool reconnect(const String& host, int port, const String& socket, const String& username,
117 const String& password, const String& database, int client_flags,
118 int connect_timeout);
120 MYSQL *get() { return m_conn;}
121 MYSQL *eject_mysql() {
122 auto ret = m_conn;
123 m_conn = nullptr;
124 return ret;
127 private:
128 MYSQL *m_conn;
130 public:
131 std::string m_host;
132 int m_port;
133 std::string m_username;
134 std::string m_password;
135 std::string m_database;
136 std::string m_socket;
137 bool m_last_error_set;
138 int m_last_errno;
139 std::string m_last_error;
140 int m_xaction_count;
141 bool m_multi_query;
142 String m_async_query;
145 ///////////////////////////////////////////////////////////////////////////////
147 class MySQLRequestData : public RequestEventHandler {
148 public:
149 virtual void requestInit();
151 virtual void requestShutdown() {
152 defaultConn.reset();
153 totalRowCount = 0;
156 Resource defaultConn;
157 int readTimeout;
158 int totalRowCount; // from all queries in current request
160 static MySQLRequestData s_mysql_data;
163 ///////////////////////////////////////////////////////////////////////////////
165 class MySQLFieldInfo {
166 public:
167 MySQLFieldInfo()
168 : max_length(0), length(0), type(0), flags(0)
171 String name;
172 String table;
173 String def;
174 int64_t max_length;
175 int64_t length;
176 int type;
177 unsigned int flags;
180 ///////////////////////////////////////////////////////////////////////////////
182 class MySQLResult : public SweepableResourceData {
183 public:
184 DECLARE_RESOURCE_ALLOCATION(MySQLResult);
186 explicit MySQLResult(MYSQL_RES *res, bool localized = false);
187 virtual ~MySQLResult();
189 CLASSNAME_IS("mysql result")
190 // overriding ResourceData
191 virtual const String& o_getClassNameHook() const { return classnameof(); }
193 void close() {
194 if (m_res) {
195 mysql_free_result(m_res);
196 m_res = NULL;
200 MYSQL_RES *get() {
201 return m_res;
204 bool isLocalized() {
205 return m_localized;
208 void addRow();
210 void addField(Variant&& value);
212 void setFieldCount(int64_t fields);
213 void setFieldInfo(int64_t f, MYSQL_FIELD *field);
214 MySQLFieldInfo *getFieldInfo(int64_t field);
217 * Gets the field content. Only for localized result.
219 Variant getField(int64_t field) const;
221 int64_t getFieldCount() const;
223 int64_t getRowCount() const;
225 bool seekRow(int64_t row);
227 bool fetchRow();
229 bool isRowReady() const {
230 return m_row_ready;
233 bool seekField(int64_t field);
235 MySQLFieldInfo *fetchFieldInfo();
237 void setAsyncConnection(MySQL* conn) {
238 m_conn = conn;
239 m_conn->incRefCount();
242 protected:
243 MYSQL_RES *m_res;
244 MYSQL_ROW m_current_async_row;
245 bool m_localized; // whether all the rows have been localized
246 MySQLFieldInfo *m_fields;
247 folly::Optional<smart::list<smart::vector<Variant>>> m_rows;
248 smart::list<smart::vector<Variant>>::const_iterator m_current_row;
249 int64_t m_current_field;
250 bool m_row_ready; // set to false after seekRow, true after fetchRow
251 int64_t m_field_count;
252 int64_t m_row_count;
253 MySQL* m_conn; // only set for async for refcounting underlying buffers
256 ///////////////////////////////////////////////////////////////////////////////
258 class MySQLStmtVariables {
259 public:
260 explicit MySQLStmtVariables(std::vector<Variant*> arr);
261 ~MySQLStmtVariables();
263 bool init_params(MYSQL_STMT *stmt, const String& types);
264 bool bind_result(MYSQL_STMT *stmt);
265 bool bind_params(MYSQL_STMT *stmt);
266 void update_result();
268 private:
269 std::vector<Variant*> m_arr;
270 std::vector<Variant> m_value_arr;
271 MYSQL_BIND *m_vars;
272 my_bool *m_null;
273 unsigned long *m_length;
276 ///////////////////////////////////////////////////////////////////////////////
278 class MySQLStmt : public SweepableResourceData {
279 public:
280 DECLARE_RESOURCE_ALLOCATION(MySQLStmt);
282 explicit MySQLStmt(MYSQL *mysql);
283 virtual ~MySQLStmt();
285 CLASSNAME_IS("mysql stmt")
287 // overriding ResourceData
288 virtual const String& o_getClassNameHook() const { return classnameof(); }
290 Variant close();
292 MYSQL_STMT *get() { return m_stmt; }
294 Variant affected_rows();
295 Variant attr_get(int64_t attr);
296 Variant attr_set(int64_t attr, int64_t value);
297 Variant bind_param(const String& types, std::vector<Variant*> vars);
298 Variant bind_result(std::vector<Variant*> vars);
299 Variant get_errno();
300 Variant get_error();
301 Variant execute();
302 Variant fetch();
303 Variant field_count();
304 Variant free_result();
305 Variant insert_id();
306 Variant num_rows();
307 Variant param_count();
308 Variant prepare(const String& query);
309 Variant reset();
310 Variant result_metadata();
311 Variant send_long_data(int64_t param_idx, const String& data);
312 Variant store_result();
314 protected:
315 MYSQL_STMT *m_stmt;
316 bool m_prepared;
317 MySQLStmtVariables *m_param_vars;
318 MySQLStmtVariables *m_result_vars;
321 ///////////////////////////////////////////////////////////////////////////////
322 // helper
324 MySQLResult *php_mysql_extract_result(CVarRef result);
327 enum MySQLFieldEntryType { NAME, TABLE, LEN, TYPE, FLAGS };
328 #define PHP_MYSQL_FIELD_NAME 1
329 #define PHP_MYSQL_FIELD_TABLE 2
330 #define PHP_MYSQL_FIELD_LEN 3
331 #define PHP_MYSQL_FIELD_TYPE 4
332 #define PHP_MYSQL_FIELD_FLAGS 5
334 Variant php_mysql_field_info(CVarRef result, int field, int entry_type);
335 Variant php_mysql_do_connect(String server, String username,
336 String password, String database,
337 int client_flags, bool persistent,
338 bool async,
339 int connect_timeout_ms,
340 int query_timeout_ms);
342 enum MySQLQueryReturn { FAIL = 0, OK = 1, OK_FETCH_RESULT = 2 };
343 MySQLQueryReturn php_mysql_do_query(const String& query, CVarRef link_id,
344 bool async_mode);
345 Variant php_mysql_get_result(CVarRef link_id, bool use_store);
346 Variant php_mysql_do_query_and_get_result(const String& query, CVarRef link_id,
347 bool use_store, bool async_mode);
349 #define PHP_MYSQL_ASSOC 1 << 0
350 #define PHP_MYSQL_NUM 1 << 1
351 #define PHP_MYSQL_BOTH (PHP_MYSQL_ASSOC|PHP_MYSQL_NUM)
353 Variant php_mysql_fetch_hash(CVarRef result, int result_type);
355 Variant mysql_makevalue(const String& data, MYSQL_FIELD *mysql_field);
356 Variant mysql_makevalue(const String& data, enum_field_types field_type);
357 const char *php_mysql_get_field_name(int field_type);
359 ///////////////////////////////////////////////////////////////////////////////
361 extern const int64_t k_ASYNC_OP_INVALID;
362 extern const int64_t k_ASYNC_OP_UNSET;
363 extern const int64_t k_ASYNC_OP_CONNECT;
364 extern const int64_t k_ASYNC_OP_QUERY;
365 extern const int64_t k_ASYNC_OP_FETCH_ROW;
369 #endif // incl_HPHP_MYSQL_COMMON_H_