Kannel: Open Source WAP and SMS gateway  svn-r5335
sqlbox_mssql.c
Go to the documentation of this file.
1 #include "gwlib/gwlib.h"
2 #ifdef HAVE_MSSQL
3 #include "gwlib/dbpool.h"
4 #include <ctpublic.h>
5 #include "sqlbox_mssql.h"
6 
7 #define sql_update dbpool_conn_update
8 #define sql_select dbpool_conn_select
9 
10 static Octstr *sqlbox_logtable;
11 static Octstr *sqlbox_insert_table;
12 
13 /*
14  * Our connection pool to mssql.
15  */
16 
17 static DBPool *pool = NULL;
18 
19 void sqlbox_configure_mssql(Cfg* cfg)
20 {
21  DBPoolConn *pc;
22  CfgGroup *grp;
23  Octstr *sql;
24 
25  if (!(grp = cfg_get_single_group(cfg, octstr_imm("sqlbox"))))
26  panic(0, "SQLBOX: MSSql: group 'sqlbox' is not specified!");
27 
28  sqlbox_logtable = cfg_get(grp, octstr_imm("sql-log-table"));
29  if (sqlbox_logtable == NULL) {
30  panic(0, "Parameter 'sql-log-table' not configured.");
31  }
32  sqlbox_insert_table = cfg_get(grp, octstr_imm("sql-insert-table"));
33  if (sqlbox_insert_table == NULL) {
34  panic(0, "Parameter 'sql-insert-table' not configured.");
35  }
36 
37  pc = dbpool_conn_consume(pool);
38  if (pc == NULL) {
39  error(0, "MSSql: DBPool Error!");
40  return;
41  }
42 
43  /* create send_sms && sent_sms tables if they do not exist */
44  sql = octstr_format(SQLBOX_MSSQL_CREATE_LOG_TABLE, sqlbox_logtable, sqlbox_logtable);
45 #if defined(SQLBOX_TRACE)
46  debug("SQLBOX", 0, "sql: %s", octstr_get_cstr(sql));
47 #endif
48  sql_update(pc, sql, NULL);
49  octstr_destroy(sql);
50 
51  sql = octstr_format(SQLBOX_MSSQL_CREATE_INSERT_TABLE, sqlbox_insert_table, sqlbox_insert_table);
52 #if defined(SQLBOX_TRACE)
53  debug("SQLBOX", 0, "sql: %s", octstr_get_cstr(sql));
54 #endif
55  sql_update(pc, sql, NULL);
56  octstr_destroy(sql);
57 
59 
60 }
61 
62 Octstr *get_column(Octstr *str)
63 {
65  if (ret != NULL)
67  return ret;
68 }
69 
70 static Octstr *get_numeric_value_or_return_null(long int num)
71 {
72  if (num == -1) {
73  return octstr_create("NULL");
74  }
75  return octstr_format("%ld", num);
76 }
77 
78 static Octstr *get_string_value_or_return_null(Octstr *str)
79 {
80  if (str == NULL) {
81  return octstr_create("NULL");
82  } else if (octstr_compare(str, octstr_imm("")) == 0) {
83  return octstr_create("NULL");
84  }
85  octstr_replace(str, octstr_imm("\\"), octstr_imm("\\\\"));
86  octstr_replace(str, octstr_imm("\'"), octstr_imm("\\\'"));
87  return octstr_format("\'%S\'", str);
88 }
89 
90 #define st_num(x) (stuffer[stuffcount++] = get_numeric_value_or_return_null(x))
91 #define st_str(x) (stuffer[stuffcount++] = get_string_value_or_return_null(x))
92 #define octstr_null_create(x) ((x != NULL) ? octstr_create(x) : octstr_create(""))
93 #define atol_null(x) ((x != NULL) ? atol(x) : -1)
94 #define get_mssql_octstr_col(x) (get_column(gwlist_get(row,x)))
95 #define get_mssql_long_col(x) (atol(octstr_get_cstr(gwlist_get(row,x))))
96 
97 Msg *mssql_fetch_msg()
98 {
99  Msg *msg = NULL;
100  Octstr *sql, *delet, *id;
101  List *res, *row;
102  DBPoolConn *pc;
103 
104  pc = dbpool_conn_consume(pool);
105  if (pc == NULL) {
106  error(0, "MSSql: DBPool error!");
107  return NULL;
108  }
109 
110  sql = octstr_format(SQLBOX_MSSQL_SELECT_QUERY, sqlbox_insert_table);
111 #if defined(SQLBOX_TRACE)
112  debug("SQLBOX", 0, "sql: %s", octstr_get_cstr(sql));
113 #endif
114  if (sql_select(pc, sql, NULL, &res) != 0) {
115  debug("sqlbox", 0, "SQL statement failed: %s", octstr_get_cstr(sql));
116  } else {
117  if (gwlist_len(res) > 0) {
118  row = gwlist_extract_first(res);
119  id = get_mssql_octstr_col(0);
120  /* save fields in this row as msg struct */
121  msg = msg_create(sms);
122  /* we abuse the foreign_id field in the message struct for our sql_id value */
123  msg->sms.foreign_id = get_mssql_octstr_col(0);
124  msg->sms.sender = get_mssql_octstr_col(2);
125  msg->sms.receiver = get_mssql_octstr_col(3);
126  msg->sms.udhdata = get_mssql_octstr_col(4);
127  msg->sms.msgdata = get_mssql_octstr_col(5);
128  msg->sms.time = get_mssql_long_col(6);
129  msg->sms.smsc_id = get_mssql_octstr_col(7);
130  msg->sms.service = get_mssql_octstr_col(8);
131  msg->sms.account = get_mssql_octstr_col(9);
132  /* msg->sms.id = get_mssql_long_col(10); */
133  msg->sms.sms_type = get_mssql_long_col(11);
134  msg->sms.mclass = get_mssql_long_col(12);
135  msg->sms.mwi = get_mssql_long_col(13);
136  msg->sms.coding = get_mssql_long_col(14);
137  msg->sms.compress = get_mssql_long_col(15);
138  msg->sms.validity = get_mssql_long_col(16);
139  msg->sms.deferred = get_mssql_long_col(17);
140  msg->sms.dlr_mask = get_mssql_long_col(18);
141  msg->sms.dlr_url = get_mssql_octstr_col(19);
142  msg->sms.pid = get_mssql_long_col(20);
143  msg->sms.alt_dcs = get_mssql_long_col(21);
144  msg->sms.rpi = get_mssql_long_col(22);
145  msg->sms.charset = get_mssql_octstr_col(23);
146  msg->sms.binfo = get_mssql_octstr_col(25);
147  msg->sms.meta_data = get_mssql_octstr_col(26);
148  if (gwlist_get(row,24) == NULL) {
149  msg->sms.boxc_id = octstr_duplicate(sqlbox_id);
150  }
151  else {
152  msg->sms.boxc_id = get_mssql_octstr_col(24);
153  }
154  /* delete current row */
155  delet = octstr_format(SQLBOX_MSSQL_DELETE_QUERY, sqlbox_insert_table, id);
156 #if defined(SQLBOX_TRACE)
157  debug("SQLBOX", 0, "sql: %s", octstr_get_cstr(delet));
158 #endif
159  sql_update(pc, delet, NULL);
160  octstr_destroy(id);
161  octstr_destroy(delet);
163  }
164  gwlist_destroy(res, NULL);
165  }
167  octstr_destroy(sql);
168  return msg;
169 }
170 
171 void mssql_save_msg(Msg *msg, Octstr *momt /*, Octstr smsbox_id */)
172 {
173  Octstr *sql;
174  Octstr *stuffer[30];
175  int stuffcount = 0;
176  DBPoolConn *pc;
177  pc = dbpool_conn_consume(pool);
178  if (pc == NULL) {
179  error(0, "MSSql: DBPool Error!");
180  return;
181  }
182 
183  sql = octstr_format(SQLBOX_MSSQL_INSERT_QUERY, sqlbox_logtable, st_str(momt), st_str(msg->sms.sender),
184  st_str(msg->sms.receiver), st_str(msg->sms.udhdata), st_str(msg->sms.msgdata), st_num(msg->sms.time),
185  st_str(msg->sms.smsc_id), st_str(msg->sms.service), st_str(msg->sms.account), st_num(msg->sms.sms_type),
186  st_num(msg->sms.mclass), st_num(msg->sms.mwi), st_num(msg->sms.coding), st_num(msg->sms.compress),
187  st_num(msg->sms.validity), st_num(msg->sms.deferred), st_num(msg->sms.dlr_mask), st_str(msg->sms.dlr_url),
188  st_num(msg->sms.pid), st_num(msg->sms.alt_dcs), st_num(msg->sms.rpi), st_str(msg->sms.charset),
189  st_str(msg->sms.boxc_id), st_str(msg->sms.binfo), st_str(msg->sms.meta_data), st_str(msg->sms.foreign_id));
190 #if defined(SQLBOX_TRACE)
191  debug("SQLBOX", 0, "sql: %s", octstr_get_cstr(sql));
192 #endif
193  sql_update(pc, sql, NULL);
194  while (stuffcount > 0) {
195  octstr_destroy(stuffer[--stuffcount]);
196  }
198  octstr_destroy(sql);
199 }
200 
201 void mssql_leave()
202 {
203  dbpool_destroy(pool);
204 }
205 
206 struct server_type *sqlbox_init_mssql(Cfg* cfg)
207 {
208  CfgGroup *grp;
209  List *grplist;
210  Octstr *mssql_user, *mssql_pass, *mssql_server, *mssql_database, *mssql_id;
211  Octstr *p = NULL;
212  long pool_size;
213  DBConf *db_conf = NULL;
214  struct server_type *res = NULL;
215 
216  /*
217  * check for all mandatory directives that specify the field names
218  * of the used MSSql table
219  */
220  if (!(grp = cfg_get_single_group(cfg, octstr_imm("sqlbox"))))
221  panic(0, "SQLBOX: MSSql: group 'sqlbox' is not specified!");
222 
223  if (!(mssql_id = cfg_get(grp, octstr_imm("id"))))
224  panic(0, "SQLBOX: MSSql: directive 'id' is not specified!");
225 
226  /*
227  * now grap the required information from the 'mssql-connection' group
228  * with the mssql-id we just obtained
229  *
230  * we have to loop through all available MSSql connection definitions
231  * and search for the one we are looking for
232  */
233 
234  grplist = cfg_get_multi_group(cfg, octstr_imm("mssql-connection"));
235  while (grplist && (grp = (CfgGroup *)gwlist_extract_first(grplist)) != NULL) {
236  p = cfg_get(grp, octstr_imm("id"));
237  if (p != NULL && octstr_compare(p, mssql_id) == 0) {
238  goto found;
239  }
240  if (p != NULL) octstr_destroy(p);
241  }
242  panic(0, "SQLBOX: MSSql: connection settings for id '%s' are not specified!",
243  octstr_get_cstr(mssql_id));
244 
245 found:
246  octstr_destroy(p);
247  gwlist_destroy(grplist, NULL);
248 
249  if (cfg_get_integer(&pool_size, grp, octstr_imm("max-connections")) == -1 || pool_size == 0)
250  pool_size = 1;
251 
252  if (!(mssql_user = cfg_get(grp, octstr_imm("username"))))
253  panic(0, "SQLBOX: MSSql: directive 'username' is not specified!");
254  if (!(mssql_pass = cfg_get(grp, octstr_imm("password"))))
255  panic(0, "SQLBOX: MSSql: directive 'password' is not specified!");
256  if (!(mssql_server = cfg_get(grp, octstr_imm("server"))))
257  panic(0, "SQLBOX: MSSql: directive 'server' is not specified!");
258  if (!(mssql_database = cfg_get(grp, octstr_imm("database"))))
259  panic(0, "SQLBOX: MSSql: directive 'database' is not specified!");
260 
261  /*
262  * ok, ready to connect to MSSql
263  */
264  db_conf = gw_malloc(sizeof(DBConf));
265  gw_assert(db_conf != NULL);
266 
267  db_conf->mssql = gw_malloc(sizeof(MSSQLConf));
268  gw_assert(db_conf->mssql != NULL);
269 
270  db_conf->mssql->username = mssql_user;
271  db_conf->mssql->password = mssql_pass;
272  db_conf->mssql->server = mssql_server;
273  db_conf->mssql->database = mssql_database;
274 
275  pool = dbpool_create(DBPOOL_MSSQL, db_conf, pool_size);
276  gw_assert(pool != NULL);
277 
278  /*
279  * XXX should a failing connect throw panic?!
280  */
281  if (dbpool_conn_count(pool) == 0)
282  panic(0,"SQLBOX: MSSql: database pool has no connections!");
283 
284  octstr_destroy(mssql_id);
285 
286  res = gw_malloc(sizeof(struct server_type));
287  gw_assert(res != NULL);
288 
289  res->type = octstr_create("MSSql");
290  res->sql_enter = sqlbox_configure_mssql;
291  res->sql_leave = mssql_leave;
292  res->sql_fetch_msg = mssql_fetch_msg;
293  res->sql_save_msg = mssql_save_msg;
294  res->sql_fetch_msg_list = NULL;
295  res->sql_save_list = NULL;
296  return res;
297 }
298 #endif
void error(int err, const char *fmt,...)
Definition: log.c:648
MSSQLConf * mssql
Definition: dbpool.h:165
int(* sql_fetch_msg_list)(List *, long)
Definition: sqlbox_sql.h:19
void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl)
Definition: octstr.c:2649
long dbpool_conn_count(DBPool *p)
DBPool * dbpool_create(enum db_type db_type, DBConf *conf, unsigned int connections)
gw_assert(wtls_machine->packet_to_send !=NULL)
Octstr * server
Definition: dbpool.h:113
long gwlist_len(List *list)
Definition: list.c:166
void * gwlist_get(List *list, long pos)
Definition: list.c:292
Octstr * database
Definition: dbpool.h:114
#define cfg_get(grp, varname)
Definition: cfg.h:86
#define msg_create(type)
Definition: msg.h:136
void(* sql_save_list)(List *, Octstr *, int)
Definition: sqlbox_sql.h:20
static Cfg * cfg
Definition: opensmppbox.c:95
void octstr_strip_blanks(Octstr *text)
Definition: octstr.c:1346
void(* sql_leave)()
Definition: sqlbox_sql.h:16
#define octstr_get_cstr(ostr)
Definition: octstr.h:233
static struct pid_list * found
void(* sql_enter)(Cfg *)
Definition: sqlbox_sql.h:15
void dbpool_conn_produce(DBPoolConn *conn)
Octstr * octstr_imm(const char *cstr)
Definition: octstr.c:283
Definition: msg.h:79
Definition: cfg.c:164
Octstr * password
Definition: dbpool.h:112
void * gwlist_extract_first(List *list)
Definition: list.c:305
Msg *(* sql_fetch_msg)()
Definition: sqlbox_sql.h:17
#define octstr_duplicate(ostr)
Definition: octstr.h:187
List * cfg_get_multi_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:645
Octstr * octstr_format(const char *fmt,...)
Definition: octstr.c:2464
void octstr_destroy(Octstr *ostr)
Definition: octstr.c:324
#define octstr_create(cstr)
Definition: octstr.h:125
void octstr_destroy_item(void *os)
Definition: octstr.c:336
Octstr * username
Definition: dbpool.h:111
Definition: dbpool.h:164
void dbpool_destroy(DBPool *p)
Definition: octstr.c:118
void debug(const char *place, int err, const char *fmt,...)
Definition: log.c:726
int cfg_get_integer(long *n, CfgGroup *grp, Octstr *varname)
Definition: cfg.c:742
#define panic
Definition: log.h:87
Definition: cfg.c:73
DBPoolConn * dbpool_conn_consume(DBPool *p)
Octstr * type
Definition: sqlbox_sql.h:14
CfgGroup * cfg_get_single_group(Cfg *cfg, Octstr *name)
Definition: cfg.c:639
Octstr * sqlbox_id
Definition: sqlbox.c:95
Definition: list.c:102
static XMLRPCDocument * msg
Definition: test_xmlrpc.c:86
void(* sql_save_msg)(Msg *, Octstr *)
Definition: sqlbox_sql.h:18
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
Definition: octstr.c:871
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)
Definition: list.c:145
See file LICENSE for details about the license agreement for using, modifying, copying or deriving work from this software.