11#define Areweconected(retval) Apop_stopif(!mysql_db, return retval, 0, \
12 "No connection to a mySQL/mariadb database. apop_db_open() failure?");
14static char *opt_host_name = NULL;
15static unsigned int opt_port_num = 0;
16static char *opt_socket_name = NULL;
17static unsigned int opt_flags = 0;
19#define Apop_mstopif(cond, returnop, str) \
20 Apop_stopif(cond, returnop, 0, \
21 str "\n mySQL/mariadb error %u: %s\n", mysql_errno (mysql_db), mysql_error (mysql_db));
23static int apop_mysql_db_open(
char const *in){
24 Apop_stopif(!in,
return 2, 0,
"MySQL needs a non-NULL db name.");
25 mysql_db = mysql_init (NULL);
26 Apop_stopif(!mysql_db,
return 1, 0,
"mysql_init() failed (probably out of memory)");
27 Apop_mstopif (!mysql_real_connect (mysql_db, opt_host_name, apop_opts.db_user, apop_opts.db_pass,
28 in, opt_port_num, opt_socket_name, CLIENT_MULTI_STATEMENTS+opt_flags),
29 mysql_close (mysql_db);
return 1,
30 "mysql_real_connect() failed");
34static void apop_mysql_db_close(
int ignoreme){
35 if (mysql_db) mysql_close (mysql_db);
47static double apop_mysql_query(
char *query){
48 Apop_mstopif(mysql_query(mysql_db, query),
return 1,
"apop_mysql_query failed");
49 MYSQL_RES *result = mysql_store_result(mysql_db);
50 if (result) mysql_free_result(result);
54static double apop_mysql_table_exists(
char const *table,
int delme){
55 Areweconected(GSL_NAN);
56 MYSQL_RES *res_set = mysql_list_tables(mysql_db, table);
57 Apop_mstopif(!mysql_list_tables(mysql_db, table),
return GSL_NAN,
58 "show tables query failed.");
59 int is_found = mysql_num_rows(res_set);
60 mysql_free_result(res_set);
61 if (!is_found)
return 0;
63 if (delme ==
'd' || delme==
'D'){
65 Asprintf(&a_query,
"drop table %s", table);
66 Apop_mstopif(mysql_query (mysql_db, a_query), GSL_NAN,
67 "table exists, but table dropping failed");
72#define check_and_clean(do_if_failure) \
73 Apop_mstopif( mysql_errno (conn), \
74 if (out) do_if_failure; return NULL, \
75 "mysql_fetch_row() failed"); \
78static int get_name_row(
unsigned int *num_fields, MYSQL_FIELD *fields){
79 for(
size_t i = 0; i < *num_fields; i++)
80 if (apop_opts.db_name_column && !strcasecmp(fields[i].name, apop_opts.db_name_column)){
87static void * process_result_set_data (MYSQL *conn, MYSQL_RES *res_set) {
89 unsigned int num_fields = mysql_num_fields(res_set);
90 unsigned int num_rows = mysql_num_rows (res_set);
91 if (!num_fields || !num_rows)
return NULL;
93 MYSQL_FIELD *fields = mysql_fetch_fields(res_set);
94 int name_row = get_name_row(&num_fields, fields);
98 for(
size_t i = 0; i < num_fields+ (name_row>=0); i++)
99 if (i!=name_row)
apop_name_add(out->names, fields[i].name,
'c');
101 for (
int i=0; (row = mysql_fetch_row (res_set)); i++) {
103 for (
size_t j = 0; j < mysql_num_fields (res_set); j++){
112 double num = strtod(row[j], &end);
120static void * process_result_set_vector (MYSQL *conn, MYSQL_RES *res_set) {
122 unsigned int num_fields = mysql_num_fields(res_set);
123 unsigned int num_rows = mysql_num_rows (res_set);
124 if (num_fields == 0 || num_rows == 0)
return NULL;
125 gsl_vector *out = gsl_vector_alloc(num_rows);
126 for (
int j=0; (row = mysql_fetch_row (res_set)); j++){
127 double valor = (!row[0] || !strcmp(row[0],
"NULL"))
128 ? GSL_NAN : atof(row[0]);
129 gsl_vector_set(out, j, valor);
131 check_and_clean(gsl_vector_free(out))
134static void * process_result_set_chars (MYSQL *conn, MYSQL_RES *res_set) {
136 unsigned int total_cols = mysql_num_fields(res_set);
137 unsigned int total_rows = mysql_num_rows(res_set);
139 MYSQL_FIELD *fields = mysql_fetch_fields(res_set);
140 int name_row = get_name_row(&total_cols, fields);
143 for (
size_t i = 0; i < total_cols + (name_row>=0); i++)
144 if (i!=name_row)
apop_name_add(out->names, fields[i].name,
't');
146 for (
int i=0; (row = mysql_fetch_row (res_set)); i++){
148 for (
size_t jj=0; jj<total_cols; jj++){
154 apop_text_set(out, i, jj-passed_name,
"%s", (row[jj]==NULL)? apop_opts.nan_string : row[jj]);
160static void * apop_mysql_query_core(
char *query,
void *(*callback)(MYSQL*, MYSQL_RES*)){
163 Apop_mstopif(mysql_query (mysql_db, query),
return NULL,
"mysql_query() failed");
164 MYSQL_RES *res_set = mysql_store_result (mysql_db);
165 Apop_mstopif(!res_set,
166 if (callback == process_result_set_data || callback==process_result_set_data) apop_return_data_error(
'q')
168 "mysql_store_result() failed");
169 if (!res_set->row_count)
goto done;
170 output = callback(mysql_db, res_set);
173 mysql_free_result (res_set);
177static double apop_mysql_query_to_float(
char *query){
178 Areweconected(GSL_NAN);
179 Apop_mstopif(mysql_query (mysql_db, query) != 0,
return GSL_NAN,
180 "mysql_query() failed");
181 MYSQL_RES *res_set = mysql_store_result (mysql_db);
182 Apop_mstopif(!res_set,
return GSL_NAN,
"mysql_store_result() failed");
183 if (mysql_num_rows(res_set)==0)
return GSL_NAN;
184 MYSQL_ROW row = mysql_fetch_row (res_set);
185 Apop_mstopif(mysql_errno (mysql_db),
186 mysql_free_result (res_set);
return GSL_NAN,
187 "mysql_fetch_row() failed");
188 double out = atof(row[0]);
189 mysql_free_result (res_set);
193apop_data* apop_mysql_mixed_query(
char const *intypes,
char const *query){
196 Apop_mstopif(mysql_query (mysql_db, query),
return NULL,
"mysql_query() failed");
197 MYSQL_RES *res_set = mysql_store_result(mysql_db);
199 Apop_mstopif(!res_set,
return NULL,
"mysql_store_result() failed");
200 if (!res_set->row_count)
goto done;
202 unsigned int total_cols = mysql_num_fields(res_set);
203 unsigned int total_rows = mysql_num_rows(res_set);
204 if (!total_cols || !total_rows)
goto done;
207 count_types(&info, intypes);
211 info.intypes[2] ? total_rows : 0,
214 int requested = info.intypes[0]+info.intypes[1]+info.intypes[2]+info.intypes[3]+info.intypes[4];
215 int excess = requested - total_cols;
217 "you asked for %i columns in your list of types(%s), but your query produced %u columns. "
218 "The remainder will be placed in the text section. Output data set's ->error element set to 'd'." , requested, intypes, total_cols);
220 "you asked for %i columns in your list of types(%s), but your query produced %u columns. "
221 "Ignoring the last %i type(s) in your list. Output data set's ->error element set to 'd'." , requested, intypes, total_cols, -excess);
223 if (info.intypes[3]||excess>0)
apop_text_alloc(out, total_rows, info.intypes[3] + ((excess > 0) ? excess : 0));
224 if (info.intypes[4]) out->weights = gsl_vector_alloc(total_rows);
226 MYSQL_FIELD *fields = mysql_fetch_fields(res_set);
227 for (
size_t i=0; i<total_cols; i++){
228 char c = (i < requested) ? intypes[i] :
't';
229 if (c ==
't'|| c==
'T')
231 else if (c ==
'v'|| c==
'V')
233 else if (c ==
'm'|| c==
'M')
237 for (
int i=0; (row = mysql_fetch_row (res_set)); i++) {
238 int thism=0, thist=0;
239 for (
size_t j=0; j<total_cols; j++){
240 char c = (j < requested) ? intypes[j] :
't';
241 if (c ==
'n' || c ==
'N')
243 else if (c ==
't'|| c==
'T')
244 apop_text_set(out, i, thist++,
"%s", (row[j]==NULL)? apop_opts.nan_string : row[j]);
245 else if (c ==
'v'|| c==
'V'){
246 double valor = (!row[j] || !strcmp(row[j],
"NULL")) ? NAN : atof(row[j]);
247 gsl_vector_set(out->vector, i, valor);
248 }
else if (c ==
'w'|| c==
'W'){
249 double valor = (!row[j] || !strcmp(row[j],
"NULL")) ? NAN : atof(row[j]);
250 gsl_vector_set(out->weights, i, valor);
251 }
else if (c ==
'm'|| c==
'M')
252 gsl_matrix_set(out->matrix, i , thism++, row[j] ? atof(row[j]): GSL_NAN);
257 mysql_free_result (res_set);
#define apop_data_free(freeme)
Definition docs/include/apop.h:192
int apop_data_set(apop_data *data, size_t row, int col, const double val, const char *rowname, const char *colname, const char *page)
Definition apop_data.c:915
apop_data * apop_text_alloc(apop_data *in, const size_t row, const size_t col)
Definition apop_data.c:1063
#define Apop_stopif(test, onfail, level,...)
Definition docs/include/apop.h:1030
apop_data * apop_data_alloc(const size_t size1, const size_t size2, const int size3)
Definition apop_data.c:34
int apop_name_add(apop_name *n, char const *add_me, char type)
Definition apop_name.c:42
int apop_text_set(apop_data *in, const size_t row, const size_t col, const char *fmt,...)
Definition apop_data.c:1035
Definition docs/include/apop.h:72