src/modules/db_text/dbt_api.c
31ccf6a2
 /*
  * DBText library
  *
  * Copyright (C) 2001-2003 FhG Fokus
  *
27642a08
  * This file is part of Kamailio, a free SIP server.
31ccf6a2
  *
27642a08
  * Kamailio is free software; you can redistribute it and/or modify
31ccf6a2
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version
  *
27642a08
  * Kamailio is distributed in the hope that it will be useful,
31ccf6a2
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  *
5b37c3de
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
9e1ff448
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
31ccf6a2
  *
5b37c3de
  *
31ccf6a2
  */
 
 #include <string.h>
 
890fe7c0
 #include "../../lib/srdb1/db.h"
cf83221d
 #include "../../core/mem/mem.h"
31ccf6a2
 
 #include "dbt_res.h"
 #include "dbt_api.h"
 
890fe7c0
 int dbt_use_table(db1_con_t* _h, const str* _t)
31ccf6a2
 {
1ea49e9a
 	return db_use_table(_h, _t);
31ccf6a2
 }
 
 
 /*
  * Get and convert columns from a result
  */
3c3296da
 static int dbt_get_columns(db1_res_t* _r, dbt_table_p _dres)
31ccf6a2
 {
139283e4
 	int col;
5b37c3de
 
dae74e97
 	if (!_r || !_dres) {
789504a6
 		LM_ERR("invalid parameter\n");
31ccf6a2
 		return -1;
 	}
5b37c3de
 
dae74e97
 	RES_COL_N(_r) = _dres->nrcols;
139283e4
 	if (!RES_COL_N(_r)) {
789504a6
 		LM_ERR("no columns\n");
31ccf6a2
 		return -2;
 	}
139283e4
 	if (db_allocate_columns(_r, RES_COL_N(_r)) != 0) {
5937c668
 		LM_ERR("could not allocate columns\n");
31ccf6a2
 		return -3;
 	}
 
139283e4
 	for(col = 0; col < RES_COL_N(_r); col++) {
5b37c3de
 		/*
139283e4
 		 * Its would be not necessary to allocate here new memory, because of
 		 * the internal structure of the db_text module. But we do this anyway
 		 * to stay confirm to the other database modules.
 		 */
 		RES_NAMES(_r)[col] = (str*)pkg_malloc(sizeof(str));
 		if (! RES_NAMES(_r)[col]) {
 			LM_ERR("no private memory left\n");
 			db_free_columns(_r);
 			return -4;
 		}
5937c668
 		LM_DBG("allocate %d bytes for RES_NAMES[%d] at %p\n",
62ae4afe
 				(int)sizeof(str), col,
139283e4
 				RES_NAMES(_r)[col]);
3c3296da
 		RES_NAMES(_r)[col]->s = _dres->colv[col]->name.s;
 		RES_NAMES(_r)[col]->len = _dres->colv[col]->name.len;
31ccf6a2
 
3c3296da
 		switch(_dres->colv[col]->type)
31ccf6a2
 		{
890fe7c0
 			case DB1_STR:
 			case DB1_STRING:
 			case DB1_BLOB:
 			case DB1_INT:
 			case DB1_DATETIME:
 			case DB1_DOUBLE:
3c3296da
 				RES_TYPES(_r)[col] = _dres->colv[col]->type;
31ccf6a2
 			break;
 			default:
139283e4
 				LM_WARN("unhandled data type column (%.*s) type id (%d), "
 						"use STR as default\n", RES_NAMES(_r)[col]->len,
3c3296da
 						RES_NAMES(_r)[col]->s, _dres->colv[col]->type);
890fe7c0
 				RES_TYPES(_r)[col] = DB1_STR;
31ccf6a2
 			break;
139283e4
 		}
31ccf6a2
 	}
 	return 0;
 }
 
 /*
  * Convert a row from result into db API representation
  */
dae74e97
 static int dbt_convert_row(db1_res_t* _res, db_row_t* _r, dbt_row_p _r1)
31ccf6a2
 {
c7ef130e
 	int i;
dae74e97
 	if (!_r || !_res || !_r1) {
789504a6
 		LM_ERR("invalid parameter value\n");
31ccf6a2
 		return -1;
 	}
 
c7ef130e
 	if (db_allocate_row(_res, _r) != 0) {
5937c668
 		LM_ERR("could not allocate row\n");
c7ef130e
 		return -2;
31ccf6a2
 	}
 
139283e4
 	for(i = 0; i < RES_COL_N(_res); i++) {
dae74e97
 		(ROW_VALUES(_r)[i]).nul = _r1->fields[i].nul;
31ccf6a2
 		switch(RES_TYPES(_res)[i])
 		{
890fe7c0
 			case DB1_INT:
5b37c3de
 				VAL_INT(&(ROW_VALUES(_r)[i])) =
dae74e97
 						_r1->fields[i].val.int_val;
890fe7c0
 				VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_INT;
31ccf6a2
 			break;
 
890fe7c0
 			case DB1_BIGINT:
5937c668
 				LM_ERR("BIGINT not supported\n");
48ccd327
 				return -1;
 
890fe7c0
 			case DB1_DOUBLE:
5b37c3de
 				VAL_DOUBLE(&(ROW_VALUES(_r)[i])) =
dae74e97
 						_r1->fields[i].val.double_val;
890fe7c0
 				VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_DOUBLE;
31ccf6a2
 			break;
 
890fe7c0
 			case DB1_STRING:
5b37c3de
 				VAL_STR(&(ROW_VALUES(_r)[i])).s =
dae74e97
 						_r1->fields[i].val.str_val.s;
31ccf6a2
 				VAL_STR(&(ROW_VALUES(_r)[i])).len =
dae74e97
 						_r1->fields[i].val.str_val.len;
890fe7c0
 				VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_STRING;
0adaec47
 				VAL_FREE(&(ROW_VALUES(_r)[i])) = 0;
31ccf6a2
 			break;
 
890fe7c0
 			case DB1_STR:
5b37c3de
 				VAL_STR(&(ROW_VALUES(_r)[i])).s =
dae74e97
 						_r1->fields[i].val.str_val.s;
31ccf6a2
 				VAL_STR(&(ROW_VALUES(_r)[i])).len =
dae74e97
 						_r1->fields[i].val.str_val.len;
890fe7c0
 				VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_STR;
0adaec47
 				VAL_FREE(&(ROW_VALUES(_r)[i])) = 0;
31ccf6a2
 			break;
 
890fe7c0
 			case DB1_DATETIME:
5b37c3de
 				VAL_INT(&(ROW_VALUES(_r)[i])) =
dae74e97
 						_r1->fields[i].val.int_val;
890fe7c0
 				VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_DATETIME;
31ccf6a2
 			break;
 
890fe7c0
 			case DB1_BLOB:
31ccf6a2
 				VAL_STR(&(ROW_VALUES(_r)[i])).s =
dae74e97
 						_r1->fields[i].val.str_val.s;
31ccf6a2
 				VAL_STR(&(ROW_VALUES(_r)[i])).len =
dae74e97
 						_r1->fields[i].val.str_val.len;
890fe7c0
 				VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_BLOB;
0adaec47
 				VAL_FREE(&(ROW_VALUES(_r)[i])) = 0;
31ccf6a2
 			break;
 
890fe7c0
 			case DB1_BITMAP:
31ccf6a2
 				VAL_INT(&(ROW_VALUES(_r)[i])) =
dae74e97
 						_r1->fields[i].val.bitmap_val;
890fe7c0
 				VAL_TYPE(&(ROW_VALUES(_r)[i])) = DB1_INT;
31ccf6a2
 			break;
f4c7ac4c
 
 			default:
3c3296da
 				LM_ERR("val type [%d] for column %i not supported\n", RES_TYPES(_res)[i], i);
f4c7ac4c
 				return -1;
31ccf6a2
 		}
 	}
 	return 0;
 }
25d031f6
 
 
 /*
  * Convert rows from internal to db API representation
  */
3c3296da
 static int dbt_convert_rows(db1_res_t* _r, dbt_table_p _dres, int offset, int nrows)
25d031f6
 {
3c3296da
 	int row = 0, c = 0;
25d031f6
 	dbt_row_p _rp = NULL;
dae74e97
 	if (!_r || !_dres) {
25d031f6
 		LM_ERR("invalid parameter\n");
 		return -1;
 	}
3c3296da
 
 	if (nrows == 0) {
25d031f6
 		return 0;
 	}
3c3296da
 
c7ef130e
 	if (db_allocate_rows(_r) < 0) {
5937c668
 		LM_ERR("could not allocate rows\n");
25d031f6
 		return -2;
 	}
3c3296da
 
dae74e97
 	_rp = _dres->rows;
3c3296da
 	while(_rp && c < offset) {
 		c++;
 		_rp = _rp->next;
 	}
 
 	while(_rp && row < nrows) {
dae74e97
 		if (dbt_convert_row(_r, &(RES_ROWS(_r)[row]), _rp) < 0) {
 			LM_ERR("failed to convert row #%d\n", row);
 			RES_ROW_N(_r) = row;
25d031f6
 			db_free_rows(_r);
 			return -4;
 		}
dae74e97
 		row++;
25d031f6
 		_rp = _rp->next;
 	}
3c3296da
 	RES_ROW_N(_r) = row;
 	RES_LAST_ROW(_r) = c + row;
25d031f6
 	return 0;
 }
 
3c3296da
 static int dbt_convert_all_rows(db1_res_t* _r, dbt_table_p _dres)
 {
 	if (!_r || !_dres) {
 		LM_ERR("invalid parameter\n");
 		return -1;
 	}
 	RES_ROW_N(_r) = _dres->nrrows;
 	return dbt_convert_rows(_r, _dres, 0, _dres->nrrows);
 }
 
 
25d031f6
 
 /*
  * Fill the structure with data from database
  */
3c3296da
 //static int dbt_convert_result(db1_res_t* _r, dbt_table_p _dres)
 //{
 //	if (!_r || !_dres) {
 //		LM_ERR("invalid parameter\n");
 //		return -1;
 //	}
 //	if (dbt_get_columns(_r, _dres) < 0) {
 //		LM_ERR("failed to get column names\n");
 //		return -2;
 //	}
 //
 //	if (dbt_convert_all_rows(_r, _dres) < 0) {
 //		LM_ERR("failed to convert rows\n");
 //		db_free_columns(_r);
 //		return -3;
 //	}
 //	return 0;
 //}
 
 /*
  * Retrieve result set
  */
 int dbt_get_result(db1_res_t** _r, dbt_table_p _dres)
25d031f6
 {
3c3296da
 	int res = dbt_init_result(_r, _dres);
 	if ( res != 0) {
 		return res;
25d031f6
 	}
3c3296da
 
 	if (dbt_convert_all_rows(*_r, _dres) < 0) {
 		LM_ERR("failed to convert rows\n");
 		db_free_columns(*_r);
 		return -3;
25d031f6
 	}
 
3c3296da
 	return 0;
 }
 
 int dbt_get_next_result(db1_res_t** _r, int offset, int rows)
 {
 	dbt_table_p _dres = (dbt_table_p)(*_r)->ptr;
 	if (dbt_convert_rows(*_r, _dres, offset, rows) < 0) {
25d031f6
 		LM_ERR("failed to convert rows\n");
3c3296da
 		db_free_columns(*_r);
25d031f6
 		return -3;
 	}
 	return 0;
 }
 
3c3296da
 int dbt_init_result(db1_res_t** _r, dbt_table_p _dres)
25d031f6
 {
dae74e97
 	if ( !_r) {
25d031f6
 		LM_ERR("invalid parameter value\n");
 		return -1;
 	}
 
dae74e97
 	if (!_dres)
25d031f6
 	{
 		LM_ERR("failed to get result\n");
 		*_r = 0;
 		return -3;
 	}
 
 	*_r = db_new_result();
5b37c3de
 	if (*_r == 0)
25d031f6
 	{
 		LM_ERR("no private memory left\n");
 		return -2;
 	}
 
3c3296da
 	if (dbt_get_columns(*_r, _dres) < 0) {
 		LM_ERR("failed to get column names\n");
 		return -2;
25d031f6
 	}
5b37c3de
 
3c3296da
 	RES_NUM_ROWS(*_r) = _dres->nrrows;
dae74e97
 	(*_r)->ptr = _dres;
25d031f6
 	return 0;
 }