2 * sql_firebird.c Part of Firebird rlm_sql driver
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Copyright 2006 The FreeRADIUS server project
19 * Copyright 2006 Vitaly Bodzhgua <vitaly@eastera.net>
22 #include <freeradius-devel/ident.h>
25 #include "sql_fbapi.h"
28 /* Forward declarations */
29 static const char *sql_error(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
30 static int sql_free_result(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
31 static int sql_affected_rows(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
32 static int sql_num_fields(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
33 static int sql_finish_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config);
35 /** Establish connection to the db
38 static int sql_init_socket(rlm_sql_handle_t *handle, rlm_sql_config_t *config) {
39 rlm_sql_firebird_sock *firebird_sock;
44 handle->conn = rad_malloc(sizeof(rlm_sql_firebird_sock));
50 firebird_sock = handle->conn;
52 res = fb_init_socket(firebird_sock);
57 if (fb_connect(firebird_sock,config)) {
58 radlog(L_ERR, "rlm_sql_firebird: Connection failed %s\n",
59 firebird_sock->lasterror);
67 /** Free socket and private connection data
70 static int sql_destroy_socket(rlm_sql_handle_t *handle,
71 UNUSED rlm_sql_config_t *config)
81 /** Issue a non-SELECT query (ie: update/delete/insert) to the database.
84 static int sql_query(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config,
86 rlm_sql_firebird_sock *firebird_sock = handle->conn;
91 pthread_mutex_lock(&firebird_sock->mut);
96 * Try again query when deadlock, beacuse in any case it
99 if (fb_sql_query(firebird_sock,querystr)) {
100 /* but may be lost for short sessions */
101 if ((firebird_sock->sql_code == DEADLOCK_SQL_CODE) &&
103 radlog(L_DBG,"sock_id deadlock. Retry query %s",
107 * @todo For non READ_COMMITED transactions put
115 radlog(L_ERR, "sock_id rlm_sql_firebird,sql_query error: "
116 "sql_code=%li, error='%s', query=%s",
117 (long int) firebird_sock->sql_code,
118 firebird_sock->lasterror,
121 if (firebird_sock->sql_code == DOWN_SQL_CODE) {
125 /* Free problem query */
126 if (fb_rollback(firebird_sock)) {
127 //assume the network is down if rollback had failed
128 radlog(L_ERR,"Fail to rollback transaction after "
129 "previous error. Error: %s",
130 firebird_sock->lasterror);
134 // firebird_sock->in_use=0;
138 if (firebird_sock->statement_type != isc_info_sql_stmt_select) {
139 if (fb_commit(firebird_sock)) {
147 /** Issue a select query to the database.
150 static int sql_select_query(rlm_sql_handle_t *handle, rlm_sql_config_t *config,
152 return sql_query(handle, config, querystr);
155 /** Returns a result set for the query.
158 static int sql_store_result(UNUSED rlm_sql_handle_t *handle,
159 UNUSED rlm_sql_config_t *config) {
163 /** Returns number of columns from query.
166 static int sql_num_fields(rlm_sql_handle_t *handle,
167 UNUSED rlm_sql_config_t *config) {
168 return ((rlm_sql_firebird_sock *) handle->conn)->sqlda_out->sqld;
171 /** Returns number of rows in query.
174 static int sql_num_rows(rlm_sql_handle_t *handle, rlm_sql_config_t *config) {
175 return sql_affected_rows(handle, config);
178 /** Returns an individual row.
181 static int sql_fetch_row(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
183 rlm_sql_firebird_sock *firebird_sock = handle->conn;
188 if (firebird_sock->statement_type != isc_info_sql_stmt_exec_procedure) {
189 res = fb_fetch(firebird_sock);
195 radlog(L_ERR, "rlm_sql_firebird. Fetch problem:'%s'",
196 firebird_sock->lasterror);
201 firebird_sock->statement_type=0;
204 fb_store_row(firebird_sock);
206 handle->row = firebird_sock->row;
211 /** End the select query, such as freeing memory or result.
214 static int sql_finish_select_query(rlm_sql_handle_t *handle,
215 UNUSED rlm_sql_config_t *config) {
217 rlm_sql_firebird_sock *sock = (rlm_sql_firebird_sock *) handle->conn;
220 fb_close_cursor(sock);
228 static int sql_finish_query(rlm_sql_handle_t *handle,
229 rlm_sql_config_t *config) {
230 sql_free_result(handle, config);
235 /** Frees memory allocated for a result set.
238 static int sql_free_result(UNUSED rlm_sql_handle_t *handle,
239 UNUSED rlm_sql_config_t *config) {
243 /** Closes an open database connection and cleans up any open handles.
246 static int sql_close(rlm_sql_handle_t *handle, UNUSED rlm_sql_config_t *config)
248 fb_destroy_socket((rlm_sql_firebird_sock *) handle->conn);
252 /** Returns error associated with connection.
255 static const char *sql_error(rlm_sql_handle_t *handle,
256 UNUSED rlm_sql_config_t *config) {
257 rlm_sql_firebird_sock *firebird_sock = handle->conn;
259 return firebird_sock->lasterror;
262 /** Return the number of rows affected by the query (update, or insert)
265 static int sql_affected_rows(rlm_sql_handle_t *handle, rlm_sql_config_t *config) {
266 int affected_rows=fb_affected_rows(handle->conn);
268 if (affected_rows < 0) {
269 radlog(L_ERR, "sql_affected_rows, rlm_sql_firebird. error:%s\n",
270 sql_error(handle,config));
273 return affected_rows;
276 /* Exported to rlm_sql */
277 rlm_sql_module_t rlm_sql_firebird = {
291 sql_finish_select_query,