1 #ifndef SQL_API_H 2 #define SQL_API_H 3 4 struct timespec; 5 6 /* This SQL API is designed to work asynchronously. The underlying drivers 7 however may not. */ 8 9 enum sql_db_flags { 10 /* Set if queries are not executed asynchronously */ 11 SQL_DB_FLAG_BLOCKING = 0x01, 12 /* Set if database wants to use connection pooling */ 13 SQL_DB_FLAG_POOLED = 0x02, 14 /* Prepared statements are supported by the database. If they aren't, 15 the functions can still be used, but they're just internally 16 convered into regular statements. */ 17 SQL_DB_FLAG_PREP_STATEMENTS = 0x04, 18 /* Database supports INSERT .. ON DUPLICATE KEY syntax. */ 19 SQL_DB_FLAG_ON_DUPLICATE_KEY = 0x08, 20 /* Database supports INSERT .. ON CONFLICT DO UPDATE syntax. */ 21 SQL_DB_FLAG_ON_CONFLICT_DO = 0x10, 22 }; 23 24 enum sql_field_type { 25 SQL_TYPE_STR, 26 SQL_TYPE_UINT, 27 SQL_TYPE_ULLONG, 28 SQL_TYPE_BOOL 29 }; 30 31 struct sql_field_def { 32 enum sql_field_type type; 33 const char *name; 34 size_t offset; 35 }; 36 37 enum sql_result_error_type { 38 SQL_RESULT_ERROR_TYPE_UNKNOWN = 0, 39 /* It's unknown whether write succeeded or not. This could be due to 40 a timeout or a disconnection from server. */ 41 SQL_RESULT_ERROR_TYPE_WRITE_UNCERTAIN 42 }; 43 44 enum sql_result_next { 45 /* Row was returned */ 46 SQL_RESULT_NEXT_OK = 1, 47 /* There are no more rows */ 48 SQL_RESULT_NEXT_LAST = 0, 49 /* Error occurred - see sql_result_get_error*() */ 50 SQL_RESULT_NEXT_ERROR = -1, 51 /* There are more results - call sql_result_more() */ 52 SQL_RESULT_NEXT_MORE = -99 53 }; 54 55 #define SQL_DEF_STRUCT(name, struct_name, type, c_type) \ 56 { (type) + COMPILE_ERROR_IF_TYPES_NOT_COMPATIBLE( \ 57 ((struct struct_name *)0)->name, c_type), \ 58 #name, offsetof(struct struct_name, name) } 59 60 #define SQL_DEF_STRUCT_STR(name, struct_name) \ 61 SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_STR, const char *) 62 #define SQL_DEF_STRUCT_UINT(name, struct_name) \ 63 SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_UINT, unsigned int) 64 #define SQL_DEF_STRUCT_ULLONG(name, struct_name) \ 65 SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_ULLONG, unsigned long long) 66 #define SQL_DEF_STRUCT_BOOL(name, struct_name) \ 67 SQL_DEF_STRUCT(name, struct_name, SQL_TYPE_BOOL, bool) 68 69 struct sql_db; 70 struct sql_result; 71 72 struct sql_commit_result { 73 const char *error; 74 enum sql_result_error_type error_type; 75 }; 76 77 struct sql_settings { 78 const char *driver; 79 const char *connect_string; 80 struct event *event_parent; 81 }; 82 83 typedef void sql_query_callback_t(struct sql_result *result, void *context); 84 typedef void sql_commit_callback_t(const struct sql_commit_result *result, void *context); 85 86 void sql_drivers_init(void); 87 void sql_drivers_deinit(void); 88 89 /* register all built-in SQL drivers */ 90 void sql_drivers_register_all(void); 91 92 void sql_driver_register(const struct sql_db *driver); 93 void sql_driver_unregister(const struct sql_db *driver); 94 95 /* Initialize database connections. db_driver is the database driver name, 96 eg. "mysql" or "pgsql". connect_string is driver-specific. */ 97 struct sql_db *sql_init(const char *db_driver, const char *connect_string); 98 int sql_init_full(const struct sql_settings *set, struct sql_db **db_r, 99 const char **error_r); 100 101 void sql_ref(struct sql_db *db); 102 void sql_unref(struct sql_db **db); 103 104 /* Returns SQL database state flags. */ 105 enum sql_db_flags sql_get_flags(struct sql_db *db); 106 107 /* Explicitly connect to the database. It's not required to call this function 108 though. Returns -1 if we're not connected, 0 if we started connecting or 109 1 if we are fully connected now. */ 110 int sql_connect(struct sql_db *db); 111 /* Explicitly disconnect from database and abort pending auth requests. */ 112 void sql_disconnect(struct sql_db *db); 113 114 /* Escape the given string if needed and return it. */ 115 const char *sql_escape_string(struct sql_db *db, const char *string); 116 /* Escape the given data as a string. */ 117 const char *sql_escape_blob(struct sql_db *db, 118 const unsigned char *data, size_t size); 119 120 /* Execute SQL query without waiting for results. */ 121 void sql_exec(struct sql_db *db, const char *query); 122 /* Execute SQL query and return result in callback. If fields list is given, 123 the returned fields are validated to be of correct type, and you can use 124 sql_result_next_row_get() */ 125 void sql_query(struct sql_db *db, const char *query, 126 sql_query_callback_t *callback, void *context); 127 #define sql_query(db, query, callback, context) \ 128 sql_query(db, query - \ 129 CALLBACK_TYPECHECK(callback, void (*)( \ 130 struct sql_result *, typeof(context))), \ 131 (sql_query_callback_t *)callback, context) 132 /* Execute blocking SQL query and return result. */ 133 struct sql_result *sql_query_s(struct sql_db *db, const char *query); 134 135 struct sql_prepared_statement * 136 sql_prepared_statement_init(struct sql_db *db, const char *query_template); 137 void sql_prepared_statement_unref(struct sql_prepared_statement **prep_stmt); 138 139 struct sql_statement * 140 sql_statement_init(struct sql_db *db, const char *query_template); 141 struct sql_statement * 142 sql_statement_init_prepared(struct sql_prepared_statement *prep_stmt); 143 void sql_statement_abort(struct sql_statement **stmt); 144 void sql_statement_set_timestamp(struct sql_statement *stmt, 145 const struct timespec *ts); 146 void sql_statement_bind_str(struct sql_statement *stmt, 147 unsigned int column_idx, const char *value); 148 void sql_statement_bind_binary(struct sql_statement *stmt, 149 unsigned int column_idx, const void *value, 150 size_t value_size); 151 void sql_statement_bind_int64(struct sql_statement *stmt, 152 unsigned int column_idx, int64_t value); 153 void sql_statement_query(struct sql_statement **stmt, 154 sql_query_callback_t *callback, void *context); 155 #define sql_statement_query(stmt, callback, context) \ 156 sql_statement_query(stmt, \ 157 (sql_query_callback_t *)callback, TRUE ? context : \ 158 CALLBACK_TYPECHECK(callback, void (*)( \ 159 struct sql_result *, typeof(context)))) 160 struct sql_result *sql_statement_query_s(struct sql_statement **stmt); 161 162 void sql_result_setup_fetch(struct sql_result *result, 163 const struct sql_field_def *fields, 164 void *dest, size_t dest_size); 165 166 /* Go to next row. See enum sql_result_next. */ 167 int sql_result_next_row(struct sql_result *result); 168 169 /* If sql_result_next_row() returned SQL_RESULT_NEXT_MORE, this can be called 170 to continue returning more results. The result is freed with this call, so 171 it must not be accesed anymore until the callback is finished. */ 172 void sql_result_more(struct sql_result **result, 173 sql_query_callback_t *callback, void *context); 174 #define sql_result_more(result, callback, context) \ 175 sql_result_more(result - \ 176 CALLBACK_TYPECHECK(callback, void (*)( \ 177 struct sql_result *, typeof(context))), \ 178 (sql_query_callback_t *)callback, context) 179 /* Synchronous version of sql_result_more(). The result will be replaced with 180 the new result. */ 181 void sql_result_more_s(struct sql_result **result); 182 183 void sql_result_ref(struct sql_result *result); 184 /* Needs to be called only with sql_query_s() or when result has been 185 explicitly referenced. */ 186 void sql_result_unref(struct sql_result *result); 187 188 /* Return number of fields in result. */ 189 unsigned int sql_result_get_fields_count(struct sql_result *result); 190 /* Return name of the given field index. */ 191 const char *sql_result_get_field_name(struct sql_result *result, 192 unsigned int idx); 193 /* Return field index for given name, or -1 if not found. */ 194 int sql_result_find_field(struct sql_result *result, const char *field_name); 195 196 /* Returns value of given field as string. Note that it can be NULL. */ 197 const char *sql_result_get_field_value(struct sql_result *result, 198 unsigned int idx); 199 /* Returns a binary value. Note that a NULL is returned as NULL with size=0, 200 while empty string returns non-NULL with size=0. */ 201 const unsigned char * 202 sql_result_get_field_value_binary(struct sql_result *result, 203 unsigned int idx, size_t *size_r); 204 /* Find the field and return its value. NULL return value can mean that either 205 the field didn't exist or that its value is NULL. */ 206 const char *sql_result_find_field_value(struct sql_result *result, 207 const char *field_name); 208 /* Return all values of current row. Note that this array is not 209 NULL-terminated - you must use sql_result_get_fields_count() to find out 210 the array's length. It's also possible that some of the values inside the 211 array are NULL. */ 212 const char *const *sql_result_get_values(struct sql_result *result); 213 214 /* Return last error message in result. */ 215 const char *sql_result_get_error(struct sql_result *result); 216 enum sql_result_error_type sql_result_get_error_type(struct sql_result *result); 217 218 /* Begin a new transaction. Currently you're limited to only one open 219 transaction at a time. */ 220 struct sql_transaction_context *sql_transaction_begin(struct sql_db *db); 221 /* Commit transaction. */ 222 void sql_transaction_commit(struct sql_transaction_context **ctx, 223 sql_commit_callback_t *callback, void *context); 224 #define sql_transaction_commit(ctx, callback, context) \ 225 sql_transaction_commit(ctx - \ 226 CALLBACK_TYPECHECK(callback, void (*)( \ 227 const struct sql_commit_result *, typeof(context))), \ 228 (sql_commit_callback_t *)callback, context) 229 /* Synchronous commit. Returns 0 if ok, -1 if error. */ 230 int sql_transaction_commit_s(struct sql_transaction_context **ctx, 231 const char **error_r); 232 void sql_transaction_rollback(struct sql_transaction_context **ctx); 233 234 /* Execute query in given transaction. */ 235 void sql_update(struct sql_transaction_context *ctx, const char *query); 236 void sql_update_stmt(struct sql_transaction_context *ctx, 237 struct sql_statement **stmt); 238 /* Save the number of rows updated by this query. The value is set before 239 commit callback is called. */ 240 void sql_update_get_rows(struct sql_transaction_context *ctx, const char *query, 241 unsigned int *affected_rows); 242 void sql_update_stmt_get_rows(struct sql_transaction_context *ctx, 243 struct sql_statement **stmt, 244 unsigned int *affected_rows); 245 246 /* Wait for SQL query results. */ 247 void sql_wait(struct sql_db *db); 248 249 #endif 250