1 #ifndef SQL_API_PRIVATE_H
2 #define SQL_API_PRIVATE_H
3 
4 #include "sql-api.h"
5 #include "module-context.h"
6 
7 enum sql_db_state {
8 	/* not connected to database */
9 	SQL_DB_STATE_DISCONNECTED,
10 	/* waiting for connection attempt to succeed or fail */
11 	SQL_DB_STATE_CONNECTING,
12 	/* connected, allowing more queries */
13 	SQL_DB_STATE_IDLE,
14 	/* connected, no more queries allowed */
15 	SQL_DB_STATE_BUSY
16 };
17 
18 /* Minimum delay between reconnecting to same server */
19 #define SQL_CONNECT_MIN_DELAY 1
20 /* Maximum time to avoiding reconnecting to same server */
21 #define SQL_CONNECT_MAX_DELAY (60*30)
22 /* If no servers are connected but a query is requested, try reconnecting to
23    next server which has been disconnected longer than this (with a single
24    server setup this is really the "max delay" and the SQL_CONNECT_MAX_DELAY
25    is never used). */
26 #define SQL_CONNECT_RESET_DELAY 15
27 /* Abort connect() if it can't connect within this time. */
28 #define SQL_CONNECT_TIMEOUT_SECS 5
29 /* Abort queries after this many seconds */
30 #define SQL_QUERY_TIMEOUT_SECS 60
31 /* Default max. number of connections to create per host */
32 #define SQL_DEFAULT_CONNECTION_LIMIT 5
33 
34 #define SQL_DB_IS_READY(db) \
35 	((db)->state == SQL_DB_STATE_IDLE)
36 #define SQL_ERRSTR_NOT_CONNECTED "Not connected to database"
37 
38 /* What is considered slow query */
39 #define SQL_SLOW_QUERY_MSEC 1000
40 
41 #define SQL_QUERY_FINISHED "sql_query_finished"
42 #define SQL_CONNECTION_FINISHED "sql_connection_finished"
43 #define SQL_TRANSACTION_FINISHED "sql_transaction_finished"
44 
45 #define SQL_QUERY_FINISHED_FMT "Finished query '%s' in %u msecs"
46 
47 struct sql_db_module_register {
48 	unsigned int id;
49 };
50 
51 union sql_db_module_context {
52 	struct sql_db_module_register *reg;
53 };
54 
55 extern struct sql_db_module_register sql_db_module_register;
56 
57 extern struct event_category event_category_sql;
58 
59 struct sql_transaction_query {
60 	struct sql_transaction_query *next;
61 	struct sql_transaction_context *trans;
62 
63 	const char *query;
64 	unsigned int *affected_rows;
65 };
66 
67 struct sql_db_vfuncs {
68 	struct sql_db *(*init)(const char *connect_string);
69 	int (*init_full)(const struct sql_settings *set, struct sql_db **db_r,
70 			 const char **error);
71 	void (*deinit)(struct sql_db *db);
72 	void (*unref)(struct sql_db *db);
73 	void (*wait) (struct sql_db *db);
74 
75 	enum sql_db_flags (*get_flags)(struct sql_db *db);
76 
77 	int (*connect)(struct sql_db *db);
78 	void (*disconnect)(struct sql_db *db);
79 	const char *(*escape_string)(struct sql_db *db, const char *string);
80 
81 	void (*exec)(struct sql_db *db, const char *query);
82 	void (*query)(struct sql_db *db, const char *query,
83 		      sql_query_callback_t *callback, void *context);
84 	struct sql_result *(*query_s)(struct sql_db *db, const char *query);
85 
86 	struct sql_transaction_context *(*transaction_begin)(struct sql_db *db);
87 	void (*transaction_commit)(struct sql_transaction_context *ctx,
88 				   sql_commit_callback_t *callback,
89 				   void *context);
90 	int (*transaction_commit_s)(struct sql_transaction_context *ctx,
91 				    const char **error_r);
92 	void (*transaction_rollback)(struct sql_transaction_context *ctx);
93 
94 	void (*update)(struct sql_transaction_context *ctx, const char *query,
95 		       unsigned int *affected_rows);
96 	const char *(*escape_blob)(struct sql_db *db,
97 				   const unsigned char *data, size_t size);
98 
99 	struct sql_prepared_statement *
100 		(*prepared_statement_init)(struct sql_db *db,
101 					   const char *query_template);
102 	void (*prepared_statement_deinit)(struct sql_prepared_statement *prep_stmt);
103 
104 
105 	struct sql_statement *
106 		(*statement_init)(struct sql_db *db, const char *query_template);
107 	struct sql_statement *
108 		(*statement_init_prepared)(struct sql_prepared_statement *prep_stmt);
109 	void (*statement_abort)(struct sql_statement *stmt);
110 	void (*statement_set_timestamp)(struct sql_statement *stmt,
111 					const struct timespec *ts);
112 	void (*statement_bind_str)(struct sql_statement *stmt,
113 				   unsigned int column_idx, const char *value);
114 	void (*statement_bind_binary)(struct sql_statement *stmt,
115 				      unsigned int column_idx, const void *value,
116 				      size_t value_size);
117 	void (*statement_bind_int64)(struct sql_statement *stmt,
118 				     unsigned int column_idx, int64_t value);
119 	void (*statement_query)(struct sql_statement *stmt,
120 				sql_query_callback_t *callback, void *context);
121 	struct sql_result *(*statement_query_s)(struct sql_statement *stmt);
122 	void (*update_stmt)(struct sql_transaction_context *ctx,
123 			    struct sql_statement *stmt,
124 			    unsigned int *affected_rows);
125 };
126 
127 struct sql_db {
128 	const char *name;
129 	enum sql_db_flags flags;
130 	int refcount;
131 
132 	struct sql_db_vfuncs v;
133 	ARRAY(union sql_db_module_context *) module_contexts;
134 
135 	void (*state_change_callback)(struct sql_db *db,
136 				      enum sql_db_state prev_state,
137 				      void *context);
138 	void *state_change_context;
139 
140 	struct event *event;
141 	HASH_TABLE(char *, struct sql_prepared_statement *) prepared_stmt_hash;
142 
143 	enum sql_db_state state;
144 	/* last time we started connecting to this server
145 	   (which may or may not have succeeded) */
146 	time_t last_connect_try;
147 	unsigned int connect_delay;
148 	unsigned int connect_failure_count;
149 	struct timeout *to_reconnect;
150 
151 	uint64_t succeeded_queries;
152 	uint64_t failed_queries;
153 	/* includes both succeeded and failed */
154 	uint64_t slow_queries;
155 
156 	bool no_reconnect:1;
157 };
158 
159 struct sql_result_vfuncs {
160 	void (*free)(struct sql_result *result);
161 	int (*next_row)(struct sql_result *result);
162 
163 	unsigned int (*get_fields_count)(struct sql_result *result);
164 	const char *(*get_field_name)(struct sql_result *result,
165 				      unsigned int idx);
166 	int (*find_field)(struct sql_result *result, const char *field_name);
167 
168 	const char *(*get_field_value)(struct sql_result *result,
169 				       unsigned int idx);
170 	const unsigned char *
171 		(*get_field_value_binary)(struct sql_result *result,
172 					  unsigned int idx,
173 					  size_t *size_r);
174 	const char *(*find_field_value)(struct sql_result *result,
175 					const char *field_name);
176 	const char *const *(*get_values)(struct sql_result *result);
177 
178 	const char *(*get_error)(struct sql_result *result);
179 	void (*more)(struct sql_result **result, bool async,
180 		     sql_query_callback_t *callback, void *context);
181 };
182 
183 struct sql_prepared_statement {
184 	struct sql_db *db;
185 	int refcount;
186 	char *query_template;
187 };
188 
189 struct sql_statement {
190 	struct sql_db *db;
191 
192 	pool_t pool;
193 	const char *query_template;
194 	ARRAY_TYPE(const_string) args;
195 };
196 
197 struct sql_field_map {
198 	enum sql_field_type type;
199 	size_t offset;
200 };
201 
202 struct sql_result {
203 	struct sql_result_vfuncs v;
204 	int refcount;
205 
206 	struct sql_db *db;
207 	const struct sql_field_def *fields;
208 
209 	unsigned int map_size;
210 	struct sql_field_map *map;
211 	void *fetch_dest;
212 	struct event *event;
213 	size_t fetch_dest_size;
214 	enum sql_result_error_type error_type;
215 
216 	bool failed:1;
217 	bool failed_try_retry:1;
218 	bool callback:1;
219 };
220 
221 struct sql_transaction_context {
222 	struct sql_db *db;
223 	struct event *event;
224 
225 	/* commit() must use this query list if head is non-NULL. */
226 	struct sql_transaction_query *head, *tail;
227 };
228 
229 ARRAY_DEFINE_TYPE(sql_drivers, const struct sql_db *);
230 
231 extern ARRAY_TYPE(sql_drivers) sql_drivers;
232 extern struct sql_result sql_not_connected_result;
233 
234 void sql_init_common(struct sql_db *db);
235 struct sql_db *
236 driver_sqlpool_init(const char *connect_string, const struct sql_db *driver);
237 int driver_sqlpool_init_full(const struct sql_settings *set, const struct sql_db *driver,
238 			     struct sql_db **db_r, const char **error_r);
239 
240 void sql_db_set_state(struct sql_db *db, enum sql_db_state state);
241 
242 void sql_transaction_add_query(struct sql_transaction_context *ctx, pool_t pool,
243 			       const char *query, unsigned int *affected_rows);
244 const char *sql_statement_get_query(struct sql_statement *stmt);
245 
246 void sql_connection_log_finished(struct sql_db *db);
247 struct event_passthrough *
248 sql_query_finished_event(struct sql_db *db, struct event *event, const char *query,
249 			 bool success, int *duration_r);
250 struct event_passthrough *sql_transaction_finished_event(struct sql_transaction_context *ctx);
251 #endif
252