68 static int mssql_select(
void *theconn,
const Octstr *sql,
List *binds,
List **res);
69 static int mssql_update(
void *theconn,
const Octstr *sql,
List *binds);
75 #define mssql_undef_colfmt(cols) \ 76 for (j = 0; j < cols; j++) { gw_free(data[j].format); } 78 #define mssql_undef_coldata(cols) \ 79 mssql_undef_colfmt(cols); \ 80 for (j = 0; j < cols; j++) { gw_free(data[j].data); } \ 89 static void mssql_checkerr(
int err)
97 error(0,
"Command Failed");
100 error(0,
"Unknown Command Error");
104 static void* mssql_open_conn(
const DBConf *db_conf)
110 struct mssql_conn *conn = gw_malloc(
sizeof(
struct mssql_conn));
113 memset(conn, 0,
sizeof(
struct mssql_conn));
115 cs_ctx_alloc(CS_VERSION_100, &conn->context);
117 ct_init(conn->context, CS_VERSION_100);
119 ct_con_alloc(conn->context, &conn->connection);
126 ct_cmd_alloc(conn->connection, &conn->command);
129 ret = mssql_update(conn, sql, NULL);
132 error(0,
"MSSQL: DB selection failed!");
136 void mssql_close_conn(
void *theconn)
138 struct mssql_conn *conn = (
struct mssql_conn*) theconn;
142 ct_cmd_drop(conn->command);
143 ct_close(conn->connection, CS_UNUSED);
144 ct_con_drop(conn->connection);
145 ct_exit(conn->context, CS_UNUSED);
146 cs_ctx_drop(conn->context);
149 static int mssql_check_conn(
void *theconn)
154 struct mssql_conn *conn = (
struct mssql_conn*) theconn;
156 if (ct_con_props(conn->connection, CS_GET, CS_CON_STATUS,
157 &
status, CS_UNUSED, outlen) != CS_SUCCEED)
160 return (
status & CS_CONSTAT_CONNECTED) ? 0:1;
163 static void mssql_conf_destroy(
DBConf *theconf)
182 static int mssql_select(
void *theconn,
const Octstr *sql,
List *binds,
List **res)
186 CS_RETCODE ret, res_type;
187 int num_rows, count, i, j;
189 struct mssql_conn *conn = (
struct mssql_conn*) theconn;
190 int binds_len = (binds ?
gwlist_len(binds) : 0);
196 ct_command(conn->command, CS_LANG_CMD,
199 if ((ret = ct_send(conn->command)) != CS_SUCCEED) {
200 error(0,
"Error sending query");
205 while((ret = ct_results(conn->command, &res_type)) == CS_SUCCEED) {
208 if (ct_res_info(conn->command, CS_NUMDATA,
209 (CS_INT *)&columns, CS_UNUSED, NULL) != CS_SUCCEED) {
210 error(0,
"Error fetching attributes");
213 data = gw_malloc(
sizeof(
struct data_s)*columns);
214 memset(data, 0,
sizeof(
struct data_s)*columns);
216 for (i = 0; i < columns; i++) {
217 data[i].format = gw_malloc(
sizeof(CS_DATAFMT));
218 memset(data[i].
format, 0,
sizeof(CS_DATAFMT));
219 if (ct_describe(conn->command, i+1, data[i].format) != CS_SUCCEED) {
220 error(0,
"Error fetching column description");
221 mssql_undef_colfmt(i);
225 data[i].format->maxlength++;
226 data[i].data = gw_malloc(data[i].
format->maxlength);
227 data[i].format->datatype = CS_CHAR_TYPE;
228 data[i].format->format = CS_FMT_NULLTERM;
229 if (ct_bind(conn->command, i+1, data[i].format, data[i].data,
230 &data[i].size, &data[i].ind) != CS_SUCCEED) {
231 error(0,
"Error binding column");
232 mssql_undef_coldata(i);
236 while(((ret = ct_fetch(conn->command, CS_UNUSED, CS_UNUSED,
237 CS_UNUSED, &count)) == CS_SUCCEED) || (ret == CS_ROW_FAIL)) {
238 if( ret == CS_ROW_FAIL ) {
239 error(0,
"Error on row %d in this fetch batch.", count+1);
240 mssql_undef_coldata(columns);
245 for (i = 0; i < columns; i++) {
246 if (data[i].data == NULL || data[i].ind == -1) {
254 if( ret != CS_END_DATA ) {
255 error(0,
"ct_fetch failed");
256 mssql_undef_coldata(columns);
263 mssql_undef_coldata(columns);
267 case CS_STATUS_RESULT:
270 error(0,
"select failed!");
274 error(0,
"ct_result returned unexpected result type: %d", res_type);
283 static int mssql_update(
void *theconn,
const Octstr *sql,
List *binds)
285 CS_RETCODE
status, results_ret;
288 struct mssql_conn *conn = (
struct mssql_conn*) theconn;
291 if (conn->command == NULL)
295 if (
status != CS_SUCCEED) {
296 error(0,
"ct_command() failed\n");
299 status = ct_send(conn->command);
300 if (
status != CS_SUCCEED) {
301 error(0,
"ct_send() failed\n");
304 while ((results_ret = ct_results(conn->command, &
result_type)) == CS_SUCCEED) {
308 case CS_STATUS_RESULT:
315 mssql_checkerr(results_ret);
316 switch ((
int) results_ret) {
327 static struct db_ops mssql_ops = {
328 .
open = mssql_open_conn,
329 .close = mssql_close_conn,
330 .check = mssql_check_conn,
331 .conf_destroy = mssql_conf_destroy,
332 .select = mssql_select,
333 .update = mssql_update
void error(int err, const char *fmt,...)
gw_assert(wtls_machine->packet_to_send !=NULL)
void gwlist_append(List *list, void *item)
long gwlist_len(List *list)
static Octstr * connection
static void format(char *buf, const char *fmt)
#define octstr_get_cstr(ostr)
void * gwlist_extract_first(List *list)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
void gwlist_insert(List *list, long pos, void *item)
#define octstr_create_from_data(data, len)
void *(* open)(const DBConf *conf)
void gwlist_destroy(List *list, gwlist_item_destructor_t *destructor)