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_PGSQL
00074 #include <libpq-fe.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 inline int pgsql_update(const Octstr *sql)
00088 {
00089 DBPoolConn *pc;
00090 int ret = 0;
00091
00092 #if defined(DLR_TRACE)
00093 debug("dlr.pgsql", 0, "sql: %s", octstr_get_cstr(sql));
00094 #endif
00095
00096 pc = dbpool_conn_consume(pool);
00097 if (pc == NULL) {
00098 error(0, "PGSQL: Database pool got no connection! DB update failed!");
00099 return -1;
00100 }
00101
00102 if ((ret = dbpool_conn_update(pc, sql, NULL)) == -1)
00103 error(0, "PGSQL: DB update failed!");
00104
00105 dbpool_conn_produce(pc);
00106 return ret;
00107 }
00108
00109
00110 static inline List *pgsql_select(const Octstr *sql)
00111 {
00112 DBPoolConn *pc;
00113 List *ret = NULL;
00114
00115 #if defined(DLR_TRACE)
00116 debug("dlr.pgsql", 0, "sql: %s", octstr_get_cstr(sql));
00117 #endif
00118
00119 pc = dbpool_conn_consume(pool);
00120 if (pc == NULL) {
00121 error(0, "PGSQL: Database pool got no connection! DB operation failed!");
00122 return NULL;
00123 }
00124
00125 if (dbpool_conn_select(pc, sql, NULL, &ret) == -1)
00126 error(0, "PGSQL: Select failed!");
00127
00128 dbpool_conn_produce(pc);
00129 return ret;
00130 }
00131
00132
00133 static void dlr_pgsql_shutdown()
00134 {
00135 dbpool_destroy(pool);
00136 dlr_db_fields_destroy(fields);
00137 }
00138
00139
00140 static void dlr_pgsql_add(struct dlr_entry *entry)
00141 {
00142 Octstr *sql;
00143
00144 sql = octstr_format("INSERT INTO %s (%s, %s, %s, %s, %s, %s, %s, %s, %s) VALUES "
00145 "('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%s', '%d');",
00146 octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
00147 octstr_get_cstr(fields->field_ts),
00148 octstr_get_cstr(fields->field_src), octstr_get_cstr(fields->field_dst),
00149 octstr_get_cstr(fields->field_serv), octstr_get_cstr(fields->field_url),
00150 octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_boxc),
00151 octstr_get_cstr(fields->field_status),
00152 octstr_get_cstr(entry->smsc), octstr_get_cstr(entry->timestamp), octstr_get_cstr(entry->source),
00153 octstr_get_cstr(entry->destination), octstr_get_cstr(entry->service), octstr_get_cstr(entry->url),
00154 entry->mask, octstr_get_cstr(entry->boxc_id), 0);
00155
00156
00157 pgsql_update(sql);
00158
00159 octstr_destroy(sql);
00160 dlr_entry_destroy(entry);
00161 }
00162
00163
00164 static struct dlr_entry *dlr_pgsql_get(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
00165 {
00166 struct dlr_entry *res = NULL;
00167 Octstr *sql;
00168 List *result, *row;
00169
00170 sql = octstr_format("SELECT %s, %s, %s, %s, %s, %s FROM %s WHERE %s='%s' AND %s='%s' LIMIT 1;",
00171 octstr_get_cstr(fields->field_mask), octstr_get_cstr(fields->field_serv),
00172 octstr_get_cstr(fields->field_url), octstr_get_cstr(fields->field_src),
00173 octstr_get_cstr(fields->field_dst), octstr_get_cstr(fields->field_boxc),
00174 octstr_get_cstr(fields->table), octstr_get_cstr(fields->field_smsc),
00175 octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
00176
00177
00178 result = pgsql_select(sql);
00179 octstr_destroy(sql);
00180
00181 if (result == NULL || gwlist_len(result) < 1) {
00182 debug("dlr.pgsql", 0, "no rows found");
00183 while((row = gwlist_extract_first(result)))
00184 gwlist_destroy(row, octstr_destroy_item);
00185 gwlist_destroy(result, NULL);
00186 return NULL;
00187 }
00188
00189 row = gwlist_get(result, 0);
00190
00191 debug("dlr.pgsql", 0, "Found entry, col1=%s, col2=%s, col3=%s, col4=%s, col5=%s col6=%s",
00192 octstr_get_cstr(gwlist_get(row, 0)),
00193 octstr_get_cstr(gwlist_get(row, 1)),
00194 octstr_get_cstr(gwlist_get(row, 2)),
00195 octstr_get_cstr(gwlist_get(row, 3)),
00196 octstr_get_cstr(gwlist_get(row, 4)),
00197 octstr_get_cstr(gwlist_get(row, 5))
00198 );
00199
00200 res = dlr_entry_create();
00201 gw_assert(res != NULL);
00202 res->mask = atoi(octstr_get_cstr(gwlist_get(row, 0)));
00203 res->service = octstr_duplicate(gwlist_get(row, 1));
00204 res->url = octstr_duplicate(gwlist_get(row, 2));
00205 res->source = octstr_duplicate(gwlist_get(row, 3));
00206 res->destination = octstr_duplicate(gwlist_get(row, 4));
00207 res->boxc_id = octstr_duplicate(gwlist_get(row, 5));
00208 res->smsc = octstr_duplicate(smsc);
00209
00210 while((row = gwlist_extract_first(result)))
00211 gwlist_destroy(row, octstr_destroy_item);
00212 gwlist_destroy(result, NULL);
00213
00214 return res;
00215 }
00216
00217
00218 static void dlr_pgsql_remove(const Octstr *smsc, const Octstr *ts, const Octstr *dst)
00219 {
00220 Octstr *sql;
00221
00222 debug("dlr.pgsql", 0, "removing DLR from database");
00223 sql = octstr_format("DELETE FROM %s WHERE oid = (SELECT oid FROM %s WHERE %s='%s' AND %s='%s' LIMIT 1);",
00224 octstr_get_cstr(fields->table), octstr_get_cstr(fields->table),
00225 octstr_get_cstr(fields->field_smsc),
00226 octstr_get_cstr(smsc), octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
00227
00228
00229 pgsql_update(sql);
00230 octstr_destroy(sql);
00231 }
00232
00233
00234 static void dlr_pgsql_update(const Octstr *smsc, const Octstr *ts, const Octstr *dst, int status)
00235 {
00236 Octstr *sql;
00237
00238 debug("dlr.pgsql", 0, "updating DLR status in database");
00239 sql = octstr_format("UPDATE %s SET %s=%d WHERE oid = (SELECT oid FROM %s WHERE %s='%s' AND %s='%s' LIMIT 1);",
00240 octstr_get_cstr(fields->table),
00241 octstr_get_cstr(fields->field_status), status,
00242 octstr_get_cstr(fields->table),
00243 octstr_get_cstr(fields->field_smsc), octstr_get_cstr(smsc),
00244 octstr_get_cstr(fields->field_ts), octstr_get_cstr(ts));
00245 pgsql_update(sql);
00246 octstr_destroy(sql);
00247 }
00248
00249
00250 static long dlr_pgsql_messages(void)
00251 {
00252 Octstr *sql;
00253 long ret;
00254 List *res;
00255
00256 sql = octstr_format("SELECT count(*) FROM %s;", octstr_get_cstr(fields->table));
00257
00258 res = pgsql_select(sql);
00259 octstr_destroy(sql);
00260
00261 if (res == NULL || gwlist_len(res) < 1) {
00262 error(0, "PGSQL: Could not get count of DLR table");
00263 ret = -1;
00264 } else {
00265 ret = atol(octstr_get_cstr(gwlist_get(gwlist_get(res, 0), 0)));
00266 }
00267
00268 gwlist_destroy(gwlist_extract_first(res), octstr_destroy_item);
00269 gwlist_destroy(res, NULL);
00270
00271 return ret;
00272 }
00273
00274
00275 static void dlr_pgsql_flush(void)
00276 {
00277 Octstr *sql;
00278
00279 sql = octstr_format("DELETE FROM %s;", octstr_get_cstr(fields->table));
00280
00281 pgsql_update(sql);
00282 octstr_destroy(sql);
00283 }
00284
00285
00286 static struct dlr_storage handles = {
00287 .type = "pgsql",
00288 .dlr_add = dlr_pgsql_add,
00289 .dlr_get = dlr_pgsql_get,
00290 .dlr_update = dlr_pgsql_update,
00291 .dlr_remove = dlr_pgsql_remove,
00292 .dlr_shutdown = dlr_pgsql_shutdown,
00293 .dlr_messages = dlr_pgsql_messages,
00294 .dlr_flush = dlr_pgsql_flush
00295 };
00296
00297
00298 struct dlr_storage *dlr_init_pgsql(Cfg *cfg)
00299 {
00300 CfgGroup *grp;
00301 List *grplist;
00302 Octstr *pgsql_host, *pgsql_user, *pgsql_pass, *pgsql_db, *pgsql_id;
00303 long pgsql_port = 0;
00304 Octstr *p = NULL;
00305 long pool_size;
00306 DBConf *db_conf = NULL;
00307
00308
00309
00310
00311
00312 if (!(grp = cfg_get_single_group(cfg, octstr_imm("dlr-db"))))
00313 panic(0, "DLR: PgSQL: group 'dlr-db' is not specified!");
00314
00315 if (!(pgsql_id = cfg_get(grp, octstr_imm("id"))))
00316 panic(0, "DLR: PgSQL: directive 'id' is not specified!");
00317
00318 fields = dlr_db_fields_create(grp);
00319 gw_assert(fields != NULL);
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 grplist = cfg_get_multi_group(cfg, octstr_imm("pgsql-connection"));
00330 while (grplist && (grp = gwlist_extract_first(grplist)) != NULL) {
00331 p = cfg_get(grp, octstr_imm("id"));
00332 if (p != NULL && octstr_compare(p, pgsql_id) == 0) {
00333 goto found;
00334 }
00335 if (p != NULL)
00336 octstr_destroy(p);
00337 }
00338 panic(0, "DLR: PgSQL: connection settings for id '%s' are not specified!",
00339 octstr_get_cstr(pgsql_id));
00340
00341 found:
00342 octstr_destroy(p);
00343 gwlist_destroy(grplist, NULL);
00344
00345 if (cfg_get_integer(&pool_size, grp, octstr_imm("max-connections")) == -1 || pool_size == 0)
00346 pool_size = 1;
00347
00348 if (!(pgsql_host = cfg_get(grp, octstr_imm("host"))))
00349 panic(0, "DLR: PgSQL: directive 'host' is not specified!");
00350 if (!(pgsql_user = cfg_get(grp, octstr_imm("username"))))
00351 panic(0, "DLR: PgSQL: directive 'username' is not specified!");
00352 if (!(pgsql_pass = cfg_get(grp, octstr_imm("password"))))
00353 panic(0, "DLR: PgSQL: directive 'password' is not specified!");
00354 if (!(pgsql_db = cfg_get(grp, octstr_imm("database"))))
00355 panic(0, "DLR: PgSQL: directive 'database' is not specified!");
00356 cfg_get_integer(&pgsql_port, grp, octstr_imm("port"));
00357
00358
00359
00360
00361 db_conf = gw_malloc(sizeof(DBConf));
00362 gw_assert(db_conf != NULL);
00363
00364 db_conf->pgsql = gw_malloc(sizeof(PgSQLConf));
00365 gw_assert(db_conf->pgsql != NULL);
00366
00367 db_conf->pgsql->host = pgsql_host;
00368 db_conf->pgsql->port = pgsql_port;
00369 db_conf->pgsql->username = pgsql_user;
00370 db_conf->pgsql->password = pgsql_pass;
00371 db_conf->pgsql->database = pgsql_db;
00372
00373 pool = dbpool_create(DBPOOL_PGSQL, db_conf, pool_size);
00374 gw_assert(pool != NULL);
00375
00376
00377
00378
00379 if (dbpool_conn_count(pool) == 0)
00380 panic(0,"DLR: PgSQL: database pool has no connections!");
00381
00382 octstr_destroy(pgsql_id);
00383
00384 return &handles;
00385 }
00386 #else
00387
00388
00389
00390
00391 struct dlr_storage *dlr_init_pgsql(Cfg* cfg)
00392 {
00393 return NULL;
00394 }
00395 #endif
00396
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.