implemented mysql::store_result(), mysql::free_result(), mysql::fetch_row() roughly
This commit is contained in:
		@ -920,7 +920,7 @@ static int fnc_getnwifcfg (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
				{
 | 
			
		||||
					int x;
 | 
			
		||||
					qse_awk_rtx_refupval (rtx, tmp);
 | 
			
		||||
					x = qse_awk_rtx_setrefval (rtx, (qse_awk_val_ref_t*)qse_awk_rtx_getarg (rtx, 2), tmp);
 | 
			
		||||
					x = qse_awk_rtx_setrefval (rtx, (qse_awk_val_ref_t*)qse_awk_rtx_getarg(rtx, 2), tmp);
 | 
			
		||||
					qse_awk_rtx_refdownval (rtx, tmp);
 | 
			
		||||
					if (x <= -1) return -1;
 | 
			
		||||
					ret = 0;
 | 
			
		||||
 | 
			
		||||
@ -38,30 +38,6 @@
 | 
			
		||||
#define __FREE_IMAP_NODE __free_sql_node
 | 
			
		||||
#include "../lib/awk/imap-imp.h"
 | 
			
		||||
 | 
			
		||||
static sql_node_t* new_sql_node (qse_awk_rtx_t* rtx, sql_list_t* list)
 | 
			
		||||
{
 | 
			
		||||
	sql_node_t* node;
 | 
			
		||||
 | 
			
		||||
	node = __new_sql_node(rtx, list);
 | 
			
		||||
	if (!node) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	node->mysql = mysql_init(QSE_NULL);
 | 
			
		||||
	if (!node->mysql)
 | 
			
		||||
	{
 | 
			
		||||
		qse_awk_rtx_seterrfmt (rtx, QSE_AWK_ENOMEM, QSE_NULL, QSE_T("unable to allocate a mysql object"));
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void free_sql_node (qse_awk_rtx_t* rtx, sql_list_t* list, sql_node_t* node)
 | 
			
		||||
{
 | 
			
		||||
	mysql_close (node->mysql);
 | 
			
		||||
	node->mysql = QSE_NULL;
 | 
			
		||||
	__free_sql_node (rtx, list, node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#undef __IMAP_NODE_T_DATA
 | 
			
		||||
#undef __IMAP_LIST_T_DATA
 | 
			
		||||
#undef __IMAP_LIST_T
 | 
			
		||||
@ -69,7 +45,7 @@ static void free_sql_node (qse_awk_rtx_t* rtx, sql_list_t* list, sql_node_t* nod
 | 
			
		||||
#undef __MAKE_IMAP_NODE
 | 
			
		||||
#undef __FREE_IMAP_NODE
 | 
			
		||||
 | 
			
		||||
#define __IMAP_NODE_T_DATA  MYSQL_RES* res;
 | 
			
		||||
#define __IMAP_NODE_T_DATA  MYSQL_RES* res; unsigned int num_fields;
 | 
			
		||||
#define __IMAP_LIST_T_DATA  int errnum;
 | 
			
		||||
#define __IMAP_LIST_T res_list_t
 | 
			
		||||
#define __IMAP_NODE_T res_node_t
 | 
			
		||||
@ -77,34 +53,105 @@ static void free_sql_node (qse_awk_rtx_t* rtx, sql_list_t* list, sql_node_t* nod
 | 
			
		||||
#define __FREE_IMAP_NODE __free_res_node
 | 
			
		||||
#include "../lib/awk/imap-imp.h"
 | 
			
		||||
 | 
			
		||||
struct rtx_data_t
 | 
			
		||||
{
 | 
			
		||||
	sql_list_t sql_list;
 | 
			
		||||
	res_list_t res_list;
 | 
			
		||||
};
 | 
			
		||||
typedef struct rtx_data_t rtx_data_t;
 | 
			
		||||
 | 
			
		||||
static sql_node_t* new_sql_node (qse_awk_rtx_t* rtx, sql_list_t* sql_list)
 | 
			
		||||
{
 | 
			
		||||
	sql_node_t* sql_node;
 | 
			
		||||
 | 
			
		||||
	sql_node = __new_sql_node(rtx, sql_list);
 | 
			
		||||
	if (!sql_node) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	sql_node->mysql = mysql_init(QSE_NULL);
 | 
			
		||||
	if (!sql_node->mysql)
 | 
			
		||||
	{
 | 
			
		||||
		qse_awk_rtx_seterrfmt (rtx, QSE_AWK_ENOMEM, QSE_NULL, QSE_T("unable to allocate a mysql object"));
 | 
			
		||||
		return QSE_NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return sql_node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void free_sql_node (qse_awk_rtx_t* rtx, sql_list_t* sql_list, sql_node_t* sql_node)
 | 
			
		||||
{
 | 
			
		||||
	mysql_close (sql_node->mysql);
 | 
			
		||||
	sql_node->mysql = QSE_NULL;
 | 
			
		||||
	__free_sql_node (rtx, sql_list, sql_node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
static res_node_t* new_res_node (qse_awk_rtx_t* rtx, res_list_t* res_list, MYSQL_RES* res)
 | 
			
		||||
{
 | 
			
		||||
	res_node_t* res_node;
 | 
			
		||||
 | 
			
		||||
	res_node = __new_res_node(rtx, res_list);
 | 
			
		||||
	if (!res_node) return QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	res_node->res = res;
 | 
			
		||||
	res_node->num_fields = mysql_num_fields(res);
 | 
			
		||||
 | 
			
		||||
	return res_node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void free_res_node (qse_awk_rtx_t* rtx, res_list_t* res_list, res_node_t* res_node)
 | 
			
		||||
{
 | 
			
		||||
	mysql_free_result (res_node->res);
 | 
			
		||||
	res_node->res = QSE_NULL;
 | 
			
		||||
	__free_res_node (rtx, res_list, res_node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
static QSE_INLINE sql_list_t* rtx_to_list (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
static QSE_INLINE sql_list_t* rtx_to_sql_list (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	qse_rbt_pair_t* pair;
 | 
			
		||||
	rtx_data_t* data;
 | 
			
		||||
	pair = qse_rbt_search((qse_rbt_t*)fi->mod->ctx, &rtx, QSE_SIZEOF(rtx));
 | 
			
		||||
	QSE_ASSERT (pair != QSE_NULL);
 | 
			
		||||
	return (sql_list_t*)QSE_RBT_VPTR(pair);
 | 
			
		||||
	data = (rtx_data_t*)QSE_RBT_VPTR(pair);
 | 
			
		||||
	return &data->sql_list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static QSE_INLINE sql_node_t* get_list_node (sql_list_t* list, qse_awk_int_t id)
 | 
			
		||||
static QSE_INLINE sql_node_t* get_sql_list_node (sql_list_t* sql_list, qse_awk_int_t id)
 | 
			
		||||
{
 | 
			
		||||
	if (id < 0 || id >= list->map.high || !list->map.tab[id]) return QSE_NULL;
 | 
			
		||||
	return list->map.tab[id];
 | 
			
		||||
	if (id < 0 || id >= sql_list->map.high || !sql_list->map.tab[id]) return QSE_NULL;
 | 
			
		||||
	return sql_list->map.tab[id];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static QSE_INLINE res_list_t* rtx_to_res_list (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	qse_rbt_pair_t* pair;
 | 
			
		||||
	rtx_data_t* data;
 | 
			
		||||
	pair = qse_rbt_search((qse_rbt_t*)fi->mod->ctx, &rtx, QSE_SIZEOF(rtx));
 | 
			
		||||
	QSE_ASSERT (pair != QSE_NULL);
 | 
			
		||||
	data = (rtx_data_t*)QSE_RBT_VPTR(pair);
 | 
			
		||||
	return &data->res_list;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static QSE_INLINE res_node_t* get_res_list_node (res_list_t* res_list, qse_awk_int_t id)
 | 
			
		||||
{
 | 
			
		||||
	if (id < 0 || id >= res_list->map.high || !res_list->map.tab[id]) return QSE_NULL;
 | 
			
		||||
	return res_list->map.tab[id];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* ------------------------------------------------------------------------ */
 | 
			
		||||
 | 
			
		||||
static int fnc_open (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	sql_list_t* list;
 | 
			
		||||
	sql_node_t* node = QSE_NULL;
 | 
			
		||||
	sql_list_t* sql_list;
 | 
			
		||||
	sql_node_t* sql_node = QSE_NULL;
 | 
			
		||||
	qse_awk_int_t ret;
 | 
			
		||||
	qse_awk_val_t* retv;
 | 
			
		||||
 | 
			
		||||
	list = rtx_to_list(rtx, fi);
 | 
			
		||||
	sql_list = rtx_to_sql_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
	node = new_sql_node(rtx, list);
 | 
			
		||||
	if (node) ret = node->id;
 | 
			
		||||
	sql_node = new_sql_node(rtx, sql_list);
 | 
			
		||||
	if (sql_node) ret = sql_node->id;
 | 
			
		||||
	else ret = -1;
 | 
			
		||||
 | 
			
		||||
	/* ret may not be a statically managed number. 
 | 
			
		||||
@ -112,7 +159,7 @@ static int fnc_open (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
	retv = qse_awk_rtx_makeintval(rtx, ret);
 | 
			
		||||
	if (retv == QSE_NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (node) free_sql_node (rtx, list, node);
 | 
			
		||||
		if (sql_node) free_sql_node (rtx, sql_list, sql_node);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -122,28 +169,28 @@ static int fnc_open (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
 | 
			
		||||
static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	sql_list_t* list;
 | 
			
		||||
	sql_node_t* node;
 | 
			
		||||
	sql_list_t* sql_list;
 | 
			
		||||
	sql_node_t* sql_node;
 | 
			
		||||
	qse_awk_int_t id;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	list = rtx_to_list(rtx, fi);
 | 
			
		||||
	sql_list = rtx_to_sql_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
	ret = qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &id);
 | 
			
		||||
	if (ret <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
		sql_list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
		ret = -1;
 | 
			
		||||
	}
 | 
			
		||||
	else if (!(node = get_list_node(list, id)))
 | 
			
		||||
	else if (!(sql_node = get_sql_list_node(sql_list, id)))
 | 
			
		||||
	{
 | 
			
		||||
/* TODO: enhance error */
 | 
			
		||||
		list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
		sql_list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
		ret = -1;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		free_sql_node (rtx, list, node);
 | 
			
		||||
		free_sql_node (rtx, sql_list, sql_node);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval(rtx, ret));
 | 
			
		||||
@ -152,8 +199,8 @@ static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
 | 
			
		||||
static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	sql_list_t* list;
 | 
			
		||||
	sql_node_t* node;
 | 
			
		||||
	sql_list_t* sql_list;
 | 
			
		||||
	sql_node_t* sql_node;
 | 
			
		||||
	qse_awk_int_t id;
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
 | 
			
		||||
@ -162,16 +209,16 @@ static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
	qse_mchar_t* user = QSE_NULL;
 | 
			
		||||
	qse_mchar_t* pass = QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	list = rtx_to_list(rtx, fi);
 | 
			
		||||
	sql_list = rtx_to_sql_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
	if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &id) <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
		sql_list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
	}
 | 
			
		||||
	else if (!(node = get_list_node(list, id)))
 | 
			
		||||
	else if (!(sql_node = get_sql_list_node(sql_list, id)))
 | 
			
		||||
	{
 | 
			
		||||
/* TODO: enhance error */
 | 
			
		||||
		list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
		sql_list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
@ -180,16 +227,16 @@ static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
		a3 = qse_awk_rtx_getarg(rtx, 3);
 | 
			
		||||
 | 
			
		||||
		host = qse_awk_rtx_getvalmbs(rtx, a1, QSE_NULL);
 | 
			
		||||
		if (!host) goto done; /* TODO: set list->errnum ... */
 | 
			
		||||
		if (!host) goto done; /* TODO: set sql_list->errnum ... */
 | 
			
		||||
		user = qse_awk_rtx_getvalmbs(rtx, a2, QSE_NULL);
 | 
			
		||||
		if (!user) goto done;
 | 
			
		||||
		pass = qse_awk_rtx_getvalmbs(rtx, a3, QSE_NULL);
 | 
			
		||||
		if (!pass) goto done;
 | 
			
		||||
 | 
			
		||||
		if (!mysql_real_connect(node->mysql, host, user, pass, QSE_NULL, 0, QSE_NULL, 0))
 | 
			
		||||
		if (!mysql_real_connect(sql_node->mysql, host, user, pass, QSE_NULL, 0, QSE_NULL, 0))
 | 
			
		||||
		{
 | 
			
		||||
/* TODO: capture error message... */
 | 
			
		||||
			list->errnum = QSE_AWK_ESYSERR;
 | 
			
		||||
			sql_list->errnum = QSE_AWK_ESYSERR;
 | 
			
		||||
			goto done;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -197,44 +244,46 @@ static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
	if (pass) qse_awk_rtx_freevalmbs (rtx, a3, pass);
 | 
			
		||||
	if (user) qse_awk_rtx_freevalmbs (rtx, a2, user);
 | 
			
		||||
	if (host) qse_awk_rtx_freevalmbs (rtx, a1, host);
 | 
			
		||||
	qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval(rtx, ret));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int fnc_query (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	sql_list_t* list;
 | 
			
		||||
	sql_node_t* node;
 | 
			
		||||
	sql_list_t* sql_list;
 | 
			
		||||
	sql_node_t* sql_node;
 | 
			
		||||
	qse_awk_int_t id;
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
 | 
			
		||||
	qse_awk_val_t* a1;
 | 
			
		||||
	qse_mchar_t* qstr = QSE_NULL;
 | 
			
		||||
 | 
			
		||||
	list = rtx_to_list(rtx, fi);
 | 
			
		||||
	sql_list = rtx_to_sql_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
	if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &id) <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
		sql_list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
	}
 | 
			
		||||
	else if (!(node = get_list_node(list, id)))
 | 
			
		||||
	else if (!(sql_node = get_sql_list_node(sql_list, id)))
 | 
			
		||||
	{
 | 
			
		||||
/* TODO: enhance error */
 | 
			
		||||
		list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
		sql_list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		qse_size_t qlen;
 | 
			
		||||
		a1 = qse_awk_rtx_getarg(rtx, 1);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		qstr = qse_awk_rtx_getvalmbs(rtx, a1, &qlen);
 | 
			
		||||
		if (!qstr) goto done; /* TODO: set list->errnum ... */
 | 
			
		||||
		if (!qstr) goto done; /* TODO: set sql_list->errnum ... */
 | 
			
		||||
 | 
			
		||||
		if (mysql_real_query(node->mysql, qstr, qlen) != 0)
 | 
			
		||||
		if (mysql_real_query(sql_node->mysql, qstr, qlen) != 0)
 | 
			
		||||
		{
 | 
			
		||||
/* TODO: capture error message... */
 | 
			
		||||
			list->errnum = QSE_AWK_ESYSERR;
 | 
			
		||||
			sql_list->errnum = QSE_AWK_ESYSERR;
 | 
			
		||||
			goto done;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
@ -242,42 +291,53 @@ static int fnc_query (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
	if (qstr) qse_awk_rtx_freevalmbs (rtx, a1, qstr);
 | 
			
		||||
	qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval(rtx, ret));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int fnc_store_result (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	sql_list_t* list;
 | 
			
		||||
	sql_node_t* node;
 | 
			
		||||
	sql_list_t* sql_list;
 | 
			
		||||
	sql_node_t* sql_node;
 | 
			
		||||
	qse_awk_int_t id;
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
 | 
			
		||||
	list = rtx_to_list(rtx, fi);
 | 
			
		||||
	sql_list = rtx_to_sql_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
	if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &id) <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
		sql_list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
	}
 | 
			
		||||
	else if (!(node = get_list_node(list, id)))
 | 
			
		||||
	else if (!(sql_node = get_sql_list_node(sql_list, id)))
 | 
			
		||||
	{
 | 
			
		||||
/* TODO: enhance error */
 | 
			
		||||
		list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
		sql_list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		res_list_t* res_list;
 | 
			
		||||
		res_node_t* res_node;
 | 
			
		||||
		MYSQL_RES* res;
 | 
			
		||||
 | 
			
		||||
		res = mysql_store_result(node->mysql);
 | 
			
		||||
		res_list = rtx_to_res_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
		res = mysql_store_result(sql_node->mysql);
 | 
			
		||||
		if (!res)
 | 
			
		||||
		{
 | 
			
		||||
/* TODO: capture error message... */
 | 
			
		||||
			list->errnum = QSE_AWK_ESYSERR;
 | 
			
		||||
			sql_list->errnum = QSE_AWK_ESYSERR;
 | 
			
		||||
			goto done;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
/* register this pointer to ASSSSS */
 | 
			
		||||
		ret = 0;
 | 
			
		||||
		res_node = new_res_node(rtx, res_list, res);
 | 
			
		||||
		if (!res_node)	
 | 
			
		||||
		{
 | 
			
		||||
			mysql_free_result (res);
 | 
			
		||||
			goto done;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ret = res_node->id;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
@ -287,6 +347,120 @@ done:
 | 
			
		||||
 | 
			
		||||
static int fnc_free_result (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	res_list_t* res_list;
 | 
			
		||||
	res_node_t* res_node;
 | 
			
		||||
	qse_awk_int_t id;
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
 | 
			
		||||
	res_list = rtx_to_res_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
	if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &id) <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		res_list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
	}
 | 
			
		||||
	else if (!(res_node = get_res_list_node(res_list, id)))
 | 
			
		||||
	{
 | 
			
		||||
/* TODO: enhance error */
 | 
			
		||||
		res_list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		free_res_node (rtx, res_list, res_node);
 | 
			
		||||
		ret = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval(rtx, ret));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int fnc_fetch_row (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi)
 | 
			
		||||
{
 | 
			
		||||
	res_list_t* res_list;
 | 
			
		||||
	res_node_t* res_node;
 | 
			
		||||
	qse_awk_int_t id;
 | 
			
		||||
	int ret = -1;
 | 
			
		||||
 | 
			
		||||
	res_list = rtx_to_res_list(rtx, fi);
 | 
			
		||||
 | 
			
		||||
	if (qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 0), &id) <= -1)
 | 
			
		||||
	{
 | 
			
		||||
		res_list->errnum = qse_awk_rtx_geterrnum(rtx);
 | 
			
		||||
	}
 | 
			
		||||
	else if (!(res_node = get_res_list_node(res_list, id)))
 | 
			
		||||
	{
 | 
			
		||||
/* TODO: enhance error */
 | 
			
		||||
		res_list->errnum = QSE_AWK_EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		MYSQL_ROW row;
 | 
			
		||||
		unsigned int i;
 | 
			
		||||
		qse_awk_val_t* row_map, * row_val;
 | 
			
		||||
		int x;
 | 
			
		||||
 | 
			
		||||
		row = mysql_fetch_row(res_node->res);
 | 
			
		||||
		if (!row)
 | 
			
		||||
		{
 | 
			
		||||
			ret = 0;
 | 
			
		||||
			goto done;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		row_map = qse_awk_rtx_makemapval(rtx);
 | 
			
		||||
		if (!row_map) 
 | 
			
		||||
		{
 | 
			
		||||
			/* TODO set erro rmessage */
 | 
			
		||||
			goto done;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		qse_awk_rtx_refupval (rtx, row_map);
 | 
			
		||||
		x = qse_awk_rtx_setrefval(rtx, (qse_awk_val_ref_t*)qse_awk_rtx_getarg(rtx, 1), row_map);
 | 
			
		||||
		qse_awk_rtx_refdownval (rtx, row_map);
 | 
			
		||||
		if (x <= -1)
 | 
			
		||||
		{
 | 
			
		||||
			/* TODO set erro rmessage */
 | 
			
		||||
			goto done;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (i = 0; i < res_node->num_fields; )
 | 
			
		||||
		{
 | 
			
		||||
			qse_char_t key_buf[QSE_SIZEOF(qse_awk_int_t) * 8 + 2];
 | 
			
		||||
			qse_size_t key_len;
 | 
			
		||||
 | 
			
		||||
			if (row[i])
 | 
			
		||||
			{
 | 
			
		||||
/* TODO: consider using make multi byte string - qse_awk_rtx_makembsstr */
 | 
			
		||||
				row_val = qse_awk_rtx_makestrvalwithmbs(rtx, row[i]);
 | 
			
		||||
				if (!row_val)
 | 
			
		||||
				{
 | 
			
		||||
					/* TODO set erro rmessage */
 | 
			
		||||
					goto done;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				row_val = qse_awk_rtx_makenilval(rtx);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			++i;
 | 
			
		||||
 | 
			
		||||
			/* put it into the map */
 | 
			
		||||
			key_len = qse_awk_inttostr(qse_awk_rtx_getawk(rtx), i, 10, QSE_NULL, key_buf, QSE_COUNTOF(key_buf));
 | 
			
		||||
			QSE_ASSERT (key_len != (qse_size_t)-1);
 | 
			
		||||
 | 
			
		||||
			if (qse_awk_rtx_setmapvalfld(rtx, row_map, key_buf, key_len, row_val) == QSE_NULL)
 | 
			
		||||
			{
 | 
			
		||||
				qse_awk_rtx_refupval (rtx, row_val);
 | 
			
		||||
				qse_awk_rtx_refdownval (rtx, row_val);
 | 
			
		||||
			/* TODO: set error message */
 | 
			
		||||
				goto done;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ret = 1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
done:
 | 
			
		||||
	qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval(rtx, ret));
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -304,6 +478,7 @@ static fnctab_t fnctab[] =
 | 
			
		||||
	/* keep this table sorted for binary search in query(). */
 | 
			
		||||
	{ QSE_T("close"),        { { 1, 1, QSE_NULL },     fnc_close,          0 } },
 | 
			
		||||
	{ QSE_T("connect"),      { { 4, 8, QSE_NULL },     fnc_connect,        0 } },
 | 
			
		||||
	{ QSE_T("fetch_row"),    { { 2, 2, QSE_T("vr") },  fnc_fetch_row,      0 } },
 | 
			
		||||
	{ QSE_T("free_result"),  { { 1, 1, QSE_NULL },     fnc_free_result,    0 } },
 | 
			
		||||
	{ QSE_T("open"),         { { 0, 0, QSE_NULL },     fnc_open,           0 } },
 | 
			
		||||
	{ QSE_T("query"),        { { 2, 2, QSE_NULL },     fnc_query,          0 } },
 | 
			
		||||
@ -361,12 +536,12 @@ static int query (qse_awk_mod_t* mod, qse_awk_t* awk, const qse_char_t* name, qs
 | 
			
		||||
static int init (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
 | 
			
		||||
{
 | 
			
		||||
	qse_rbt_t* rbt;
 | 
			
		||||
	sql_list_t list;
 | 
			
		||||
	rtx_data_t data;
 | 
			
		||||
 | 
			
		||||
	rbt = (qse_rbt_t*)mod->ctx;
 | 
			
		||||
 | 
			
		||||
	QSE_MEMSET (&list, 0, QSE_SIZEOF(list));
 | 
			
		||||
	if (qse_rbt_insert (rbt, &rtx, QSE_SIZEOF(rtx), &list, QSE_SIZEOF(list)) == QSE_NULL) 
 | 
			
		||||
	QSE_MEMSET (&data, 0, QSE_SIZEOF(data));
 | 
			
		||||
	if (qse_rbt_insert (rbt, &rtx, QSE_SIZEOF(rtx), &data, QSE_SIZEOF(data)) == QSE_NULL) 
 | 
			
		||||
	{
 | 
			
		||||
		qse_awk_rtx_seterrnum (rtx, QSE_AWK_ENOMEM, QSE_NULL);
 | 
			
		||||
		return -1;
 | 
			
		||||
@ -386,16 +561,26 @@ static void fini (qse_awk_mod_t* mod, qse_awk_rtx_t* rtx)
 | 
			
		||||
	pair = qse_rbt_search(rbt, &rtx, QSE_SIZEOF(rtx));
 | 
			
		||||
	if (pair)
 | 
			
		||||
	{
 | 
			
		||||
		sql_list_t* list;
 | 
			
		||||
		sql_node_t* node, * next;
 | 
			
		||||
		rtx_data_t* data;
 | 
			
		||||
		sql_node_t* sql_node, * sql_next;
 | 
			
		||||
		res_node_t* res_node, * res_next;
 | 
			
		||||
 | 
			
		||||
		list = QSE_RBT_VPTR(pair);
 | 
			
		||||
		node = list->head;
 | 
			
		||||
		while (node)
 | 
			
		||||
		data = (rtx_data_t*)QSE_RBT_VPTR(pair);
 | 
			
		||||
 | 
			
		||||
		res_node = data->res_list.head;
 | 
			
		||||
		while (sql_node)
 | 
			
		||||
		{
 | 
			
		||||
			next = node->next;
 | 
			
		||||
			free_sql_node (rtx, list, node);
 | 
			
		||||
			node = next;
 | 
			
		||||
			res_next = res_node->next;
 | 
			
		||||
			free_res_node (rtx, &data->res_list, res_node);
 | 
			
		||||
			res_node = res_next;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sql_node = data->sql_list.head;
 | 
			
		||||
		while (sql_node)
 | 
			
		||||
		{
 | 
			
		||||
			sql_next = sql_node->next;
 | 
			
		||||
			free_sql_node (rtx, &data->sql_list, sql_node);
 | 
			
		||||
			sql_node = sql_next;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		qse_rbt_delete (rbt, &rtx, QSE_SIZEOF(rtx));
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user