Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00034 #include <string.h>
00035 #include <mysql/mysql.h>
00036 #include "../../lib/srdb1/db_res.h"
00037 #include "../../mem/mem.h"
00038 #include "../../dprint.h"
00039 #include "km_row.h"
00040 #include "km_my_con.h"
00041 #include "km_res.h"
00042
00043
00053 int db_mysql_get_columns(const db1_con_t* _h, db1_res_t* _r)
00054 {
00055 int col;
00056 MYSQL_FIELD* fields;
00057
00058 if ((!_h) || (!_r)) {
00059 LM_ERR("invalid parameter\n");
00060 return -1;
00061 }
00062
00063 RES_COL_N(_r) = mysql_field_count(CON_CONNECTION(_h));
00064 if (!RES_COL_N(_r)) {
00065 LM_ERR("no columns returned from the query\n");
00066 return -2;
00067 } else {
00068 LM_DBG("%d columns returned from the query\n", RES_COL_N(_r));
00069 }
00070
00071 if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) {
00072 LM_ERR("could not allocate columns\n");
00073 return -3;
00074 }
00075
00076 fields = mysql_fetch_fields(CON_RESULT(_h));
00077 for(col = 0; col < RES_COL_N(_r); col++) {
00078 RES_NAMES(_r)[col] = (str*)pkg_malloc(sizeof(str));
00079 if (! RES_NAMES(_r)[col]) {
00080 LM_ERR("no private memory left\n");
00081 db_free_columns(_r);
00082 return -4;
00083 }
00084 LM_DBG("allocate %lu bytes for RES_NAMES[%d] at %p\n",
00085 (unsigned long)sizeof(str), col, RES_NAMES(_r)[col]);
00086
00087
00088 RES_NAMES(_r)[col]->s = fields[col].name;
00089 RES_NAMES(_r)[col]->len = strlen(fields[col].name);
00090
00091 LM_DBG("RES_NAMES(%p)[%d]=[%.*s]\n", RES_NAMES(_r)[col], col,
00092 RES_NAMES(_r)[col]->len, RES_NAMES(_r)[col]->s);
00093
00094 switch(fields[col].type) {
00095 case MYSQL_TYPE_TINY:
00096 case MYSQL_TYPE_SHORT:
00097 case MYSQL_TYPE_LONG:
00098 case MYSQL_TYPE_INT24:
00099 case MYSQL_TYPE_TIMESTAMP:
00100 LM_DBG("use DB1_INT result type\n");
00101 RES_TYPES(_r)[col] = DB1_INT;
00102 break;
00103
00104 case MYSQL_TYPE_LONGLONG:
00105 LM_DBG("use DB1_BIGINT result type\n");
00106 RES_TYPES(_r)[col] = DB1_BIGINT;
00107 break;
00108
00109 case MYSQL_TYPE_FLOAT:
00110 case MYSQL_TYPE_DOUBLE:
00111 LM_DBG("use DB1_DOUBLE result type\n");
00112 RES_TYPES(_r)[col] = DB1_DOUBLE;
00113 break;
00114
00115 case MYSQL_TYPE_DATETIME:
00116 LM_DBG("use DB1_DATETIME result type\n");
00117 RES_TYPES(_r)[col] = DB1_DATETIME;
00118 break;
00119
00120 case MYSQL_TYPE_BLOB:
00121 LM_DBG("use DB1_BLOB result type\n");
00122 RES_TYPES(_r)[col] = DB1_BLOB;
00123 break;
00124
00125 case FIELD_TYPE_SET:
00126 LM_DBG("use DB1_BITMAP result type\n");
00127 RES_TYPES(_r)[col] = DB1_BITMAP;
00128 break;
00129
00130 case MYSQL_TYPE_DECIMAL:
00131 #if MYSQL_VERSION_ID > 49999
00132 case MYSQL_TYPE_NEWDECIMAL:
00133 #endif
00134 case MYSQL_TYPE_STRING:
00135 case MYSQL_TYPE_VAR_STRING:
00136 LM_DBG("use DB1_STRING result type\n");
00137 RES_TYPES(_r)[col] = DB1_STRING;
00138 break;
00139
00140 default:
00141 LM_WARN("unhandled data type column (%.*s) type id (%d), "
00142 "use DB1_STRING as default\n", RES_NAMES(_r)[col]->len,
00143 RES_NAMES(_r)[col]->s, fields[col].type);
00144 RES_TYPES(_r)[col] = DB1_STRING;
00145 break;
00146 }
00147 }
00148 return 0;
00149 }
00150
00151
00158 static inline int db_mysql_convert_rows(const db1_con_t* _h, db1_res_t* _r)
00159 {
00160 int row;
00161
00162 if ((!_h) || (!_r)) {
00163 LM_ERR("invalid parameter\n");
00164 return -1;
00165 }
00166
00167 RES_ROW_N(_r) = mysql_num_rows(CON_RESULT(_h));
00168 if (!RES_ROW_N(_r)) {
00169 LM_DBG("no rows returned from the query\n");
00170 RES_ROWS(_r) = 0;
00171 return 0;
00172 }
00173
00174 if (db_allocate_rows(_r) < 0) {
00175 LM_ERR("could not allocate rows");
00176 return -2;
00177 }
00178
00179 for(row = 0; row < RES_ROW_N(_r); row++) {
00180 CON_ROW(_h) = mysql_fetch_row(CON_RESULT(_h));
00181 if (!CON_ROW(_h)) {
00182 LM_ERR("driver error: %s\n", mysql_error(CON_CONNECTION(_h)));
00183 RES_ROW_N(_r) = row;
00184 db_free_rows(_r);
00185 return -3;
00186 }
00187 if (db_mysql_convert_row(_h, _r, &(RES_ROWS(_r)[row])) < 0) {
00188 LM_ERR("error while converting row #%d\n", row);
00189 RES_ROW_N(_r) = row;
00190 db_free_rows(_r);
00191 return -4;
00192 }
00193 }
00194 return 0;
00195 }
00196
00197
00204 int db_mysql_convert_result(const db1_con_t* _h, db1_res_t* _r)
00205 {
00206 if ((!_h) || (!_r)) {
00207 LM_ERR("invalid parameter\n");
00208 return -1;
00209 }
00210
00211 if (db_mysql_get_columns(_h, _r) < 0) {
00212 LM_ERR("error while getting column names\n");
00213 return -2;
00214 }
00215
00216 if (db_mysql_convert_rows(_h, _r) < 0) {
00217 LM_ERR("error while converting rows\n");
00218 db_free_columns(_r);
00219 return -3;
00220 }
00221 return 0;
00222 }
00223