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
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 #include "gwlib/gwlib.h"
00069 #include "gwlib/dbpool.h"
00070 #include "dlr_p.h"
00071
00072
00073 #ifdef HAVE_MYSQL
00074 #include <mysql/mysql.h>
00075
00076
00077
00078
00079 static DBPool *pool = NULL;
00080
00081
00082
00083
00084 static struct dlr_db_fields *fields = NULL;
00085
00086
00087 static void mysql_update(const Octstr *sql)
00088 {
00089 int state;
00090 DBPoolConn *pc;
00091
00092 #if defined(DLR_TRACE)
00093 debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
00094 #endif
00095
00096 pc = dbpool_conn_consume(pool);
00097 if (pc == NULL) {
00098 error(0, "MYSQL: Database pool got no connection! DB update failed!");
00099 return;
00100 }
00101
00102 state = mysql_query(pc->conn, octstr_get_cstr(sql));
00103 if (state != 0)
00104 error(0, "MYSQL: %s", mysql_error(pc->conn));
00105
00106 dbpool_conn_produce(pc);
00107 }
00108
00109 static MYSQL_RES* mysql_select(const Octstr *sql)
00110 {
00111 int state;
00112 MYSQL_RES *result = NULL;
00113 DBPoolConn *pc;
00114
00115 #if defined(DLR_TRACE)
00116 debug("dlr.mysql", 0, "sql: %s", octstr_get_cstr(sql));
00117 #endif
00118
00119 pc = dbpool_conn_consume(pool);
00120 if (pc == NULL) {
00121 error(0, "MYSQL: Database pool got no connection! DB update failed!");
00122 return NULL;
00123 }
00124
00125 state = mysql_query(pc->conn, octstr_get_cstr(sql));
00126 if (state != 0) {
00127 error(0, "MYSQL: %s", mysql_error(pc->conn));
00128 } else {
00129 result = mysql_store_result(pc->conn);
00130 }
00131
00132 dbpool_conn_produce(pc);
00133
00134 return result;
00135 }
00136
00137 static void dlr_mysql_shutdown()
00138 {
00139 dbpool_destroy(pool);
00140 dlr_db_fields_destroy(fields);
00141 }
00142
00143 static void dlr_mysql_add(struct dlr_entry *entry)
00144 {
00145 Octstr *sql;
00146
00147 sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES "
00148 "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d');",
00149 octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
00150 octstr_get_cstr(fields->field_ts),
00151 octstr_get_cstr(fields->field_src), octstr_get_cstr(fields->field_dst),
00152 octstr_get_cstr(fields->field_serv), octstr_get_cstr(fields->field_url),
00153 octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_boxc),
00154 octstr_get_cstr(fields->field_status),
00155 octstr_get_cstr(entry->smsc), octstr_get_cstr(entry->timestamp), octstr_get_cstr(entry->source),
00156 octstr_get_cstr(entry->destination), octstr_get_cstr(entry->service), octstr_get_cstr(entry->url),
00157 entry->mask, octstr_get_cstr(entry->boxc_id), 0);
00158
00159
00160 mysql_update(sql);
00161
00162 octstr_destroy(sql);
00163 dlr_entry_destroy(entry);
00164 }
00165
00166 static struct dlr_entry* dlr_mysql_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
00167 {
00168 struct dlr_entry *res = NULL;
00169 Octstr *sql;
00170 MYSQL_RES *result;
00171 MYSQL_ROW row;
00172
00173 sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s';",
00174 octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_serv),
00175 octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_src),
00176 octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_boxc),
00177 octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
00178 octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
00179
00180
00181 result = mysql_select(sql);
00182 octstr_destroy(sql);
00183
00184 if (result == NULL) {
00185 return NULL;
00186 }
00187 if (mysql_num_rows(result) < 1) {
00188 debug("dlr.mysql", 0, "no rows found");
00189 mysql_free_result(result);
00190 return NULL;
00191 }
00192 row = mysql_fetch_row(result);
00193 if (!row) {
00194 debug("dlr.mysql", 0, "rows found but could not load them");
00195 mysql_free_result(result);
00196 return NULL;
00197 }
00198
00199 debug("dlr.mysql", 0, "Found entry, row[0]=%s, row[1]=%s, row[2]=%s, row[3]=%s, row[4]=%s row[5]=%s",
00200 row[0], row[1], row[2], (row[3] ? row[3] : "NULL"), (row[4] ? row[4] : "NULL"), (row[5] ? row[5] : "NULL"));
00201
00202 res = dlr_entry_create();
00203 gw_assert(res != NULL);
00204 res->mask = atoi(row[0]);
00205 res->service = octstr_create(row[1]);
00206 res->url = octstr_create(row[2]);
00207 res->source = row[3] ? octstr_create(row[3]) : octstr_create("");
00208 res->destination = row[4] ? octstr_create(row[4]) : octstr_create("");
00209 res->boxc_id = row[5] ? octstr_create(row[5]) : octstr_create("");
00210 res->smsc = octstr_duplicate(smsc);
00211
00212 mysql_free_result(result);
00213
00214 return res;
00215 }
00216
00217 static void dlr_mysql_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
00218 {
00219 Octstr *sql;
00220
00221 debug("dlr.mysql", 0, "removing DLR from database");
00222 sql = octstr_format("DELETE FROM %s WHERE %s='%s' AND %s='%s' LIMIT 1;",
00223 octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
00224 octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
00225
00226
00227 mysql_update(sql);
00228
00229 octstr_destroy(sql);
00230 }
00231
00232 static void dlr_mysql_update(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
00233 {
00234 Octstr *sql;
00235
00236 debug("dlr.mysql", 0, "updating DLR status in database");
00237 sql = octstr_format("UPDATE %s SET %s=%d WHERE %s='%s' AND %s='%s' LIMIT 1;",
00238 octstr_get_cstr(fields->table),
00239 octstr_get_cstr(fields->field_status), status,
00240 octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
00241 octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
00242
00243 mysql_update(sql);
00244
00245 octstr_destroy(sql);
00246 }
00247
00248
00249 static long dlr_mysql_messages(void)
00250 {
00251 Octstr *sql;
00252 long res;
00253 MYSQL_RES *result;
00254 MYSQL_ROW row;
00255
00256 sql = octstr_format("SELECT count(*) FROM %s;", octstr_get_cstr(fields->table));
00257
00258 result = mysql_select(sql);
00259 octstr_destroy(sql);
00260
00261 if (result == NULL) {
00262 return -1;
00263 }
00264 if (mysql_num_rows(result) < 1) {
00265 debug("dlr.mysql", 0, "Could not get count of DLR table");
00266 mysql_free_result(result);
00267 return 0;
00268 }
00269 row = mysql_fetch_row(result);
00270 if (row == NULL) {
00271 debug("dlr.mysql", 0, "rows found but could not load them");
00272 mysql_free_result(result);
00273 return 0;
00274 }
00275 res = atol(row[0]);
00276 mysql_free_result(result);
00277
00278 return res;
00279 }
00280
00281 static void dlr_mysql_flush(void)
00282 {
00283 Octstr *sql;
00284
00285 sql = octstr_format("DELETE FROM %s;", octstr_get_cstr(fields->table));
00286
00287 mysql_update(sql);
00288 octstr_destroy(sql);
00289 }
00290
00291 static struct dlr_storage handles = {
00292 .type = "mysql",
00293 .dlr_add = dlr_mysql_add,
00294 .dlr_get = dlr_mysql_get,
00295 .dlr_update = dlr_mysql_update,
00296 .dlr_remove = dlr_mysql_remove,
00297 .dlr_shutdown = dlr_mysql_shutdown,
00298 .dlr_messages = dlr_mysql_messages,
00299 .dlr_flush = dlr_mysql_flush
00300 };
00301
00302 struct dlr_storage *dlr_init_mysql(Cfg *cfg)
00303 {
00304 CfgGroup *grp;
00305 List *grplist;
00306 Octstr *mysql_host, *mysql_user, *mysql_pass, *mysql_db, *mysql_id;
00307 long mysql_port = 0;
00308 Octstr *p = NULL;
00309 long pool_size;
00310 DBConf *db_conf = NULL;
00311
00312
00313
00314
00315
00316 if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db"))))
00317 panic(0, "DLR: MySQL: group 'dlr-db' is not specified!");
00318
00319 if (!(mysql_id = cfg_get(grp, octstr_imm("id"))))
00320 panic(0, "DLR: MySQL: directive 'id' is not specified!");
00321
00322 fields = dlr_db_fields_create(grp);
00323 gw_assert(fields != NULL);
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 grplist = cfg_get_multi_group(cfg, octstr_imm("mysql-connection"));
00334 while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
00335 p = cfg_get(grp, octstr_imm("id"));
00336 if (p != NULL && octstr_compare(p, mysql_id) == 0) {
00337 goto found;
00338 }
00339 if (p != NULL) octstr_destroy(p);
00340 }
00341 panic(0, "DLR: MySQL: connection settings for id '%s' are not specified!",
00342 octstr_get_cstr(mysql_id));
00343
00344 found:
00345 octstr_destroy(p);
00346 gwlist_destroy(grplist, NULL);
00347
00348 if (cfg_get_integer(&pool_size, grp, octstr_imm("max-connections")) == -1 || pool_size == 0)
00349 pool_size = 1;
00350
00351 if (!(mysql_host = cfg_get(grp, octstr_imm("host"))))
00352 panic(0, "DLR: MySQL: directive 'host' is not specified!");
00353 if (!(mysql_user = cfg_get(grp, octstr_imm("username"))))
00354 panic(0, "DLR: MySQL: directive 'username' is not specified!");
00355 if (!(mysql_pass = cfg_get(grp, octstr_imm("password"))))
00356 panic(0, "DLR: MySQL: directive 'password' is not specified!");
00357 if (!(mysql_db = cfg_get(grp, octstr_imm("database"))))
00358 panic(0, "DLR: MySQL: directive 'database' is not specified!");
00359 cfg_get_integer(&mysql_port, grp, octstr_imm("port"));
00360
00361
00362
00363
00364 db_conf = gw_malloc(sizeof(DBConf));
00365 gw_assert(db_conf != NULL);
00366
00367 db_conf->mysql = gw_malloc(sizeof(MySQLConf));
00368 gw_assert(db_conf->mysql != NULL);
00369
00370 db_conf->mysql->host = mysql_host;
00371 db_conf->mysql->port = mysql_port;
00372 db_conf->mysql->username = mysql_user;
00373 db_conf->mysql->password = mysql_pass;
00374 db_conf->mysql->database = mysql_db;
00375
00376 pool = dbpool_create(DBPOOL_MYSQL, db_conf, pool_size);
00377 gw_assert(pool != NULL);
00378
00379
00380
00381
00382 if (dbpool_conn_count(pool) == 0)
00383 panic(0,"DLR: MySQL: database pool has no connections!");
00384
00385 octstr_destroy(mysql_id);
00386
00387 return &handles;
00388 }
00389 #else
00390
00391
00392
00393
00394 struct dlr_storage *dlr_init_mysql(Cfg* cfg)
00395 {
00396 return NULL;
00397 }
00398 #endif
00399
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.