diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index 9094b63a..dc8af106 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -6940,9 +6940,7 @@ static struct }; #endif -static qse_awk_mod_t* query_module ( - qse_awk_t* awk, const qse_cstr_t segs[], int nsegs, - qse_awk_mod_sym_t* sym) +static qse_awk_mod_t* query_module (qse_awk_t* awk, const qse_cstr_t segs[], int nsegs, qse_awk_mod_sym_t* sym) { qse_rbt_pair_t* pair; @@ -7108,7 +7106,7 @@ static qse_awk_mod_t* query_module ( } mdp = (qse_awk_mod_data_t*)QSE_RBT_VPTR(pair); - if (load (&mdp->mod, awk) <= -1) + if (load(&mdp->mod, awk) <= -1) { qse_rbt_delete (awk->modtab, segs[0].ptr, segs[0].len); awk->prm.modclose (awk, mdp->handle); @@ -7117,6 +7115,20 @@ static qse_awk_mod_t* query_module ( } done: - n = mdp->mod.query (&mdp->mod, awk, segs[1].ptr, sym); - return (n <= -1)? QSE_NULL: &mdp->mod; + qse_awk_seterrnum (awk, QSE_AWK_ENOERR, QSE_NULL); + n = mdp->mod.query(&mdp->mod, awk, segs[1].ptr, sym); + if (n <= -1) + { + if (qse_awk_geterrnum(awk) == QSE_AWK_ENOERR) + { + qse_awk_seterrfmt (awk, QSE_AWK_ENOENT, QSE_NULL, QSE_T("unable to find '%.*js' in module '%.*js'"), (int)segs[1].len, segs[1].ptr, (int)segs[0].len, segs[0].ptr); + } + else + { + qse_char_t* olderrmsg = qse_awk_backuperrmsg(awk); + qse_awk_seterrfmt (awk, QSE_AWK_ENOENT, QSE_NULL, QSE_T("unable to find '%.*js' in module '%.*js' - %js"), (int)segs[1].len, segs[1].ptr, (int)segs[0].len, segs[0].ptr, olderrmsg); + } + return QSE_NULL; + } + return &mdp->mod; } diff --git a/qse/lib/awk/run.c b/qse/lib/awk/run.c index cb2657f6..362882a3 100644 --- a/qse/lib/awk/run.c +++ b/qse/lib/awk/run.c @@ -1639,12 +1639,12 @@ qse_awk_val_t* qse_awk_rtx_callfun ( &crdata ); - if (v == QSE_NULL) + if (!v) { /* an error occurred. let's check if it is caused by exit(). * if so, the return value should have been captured into * crdata.val. */ - if (crdata.val != QSE_NULL) v = crdata.val; /* yet it is */ + if (crdata.val) v = crdata.val; /* yet it is */ } else { diff --git a/qse/lib/awkmod/mod-mysql.c b/qse/lib/awkmod/mod-mysql.c index e4100b81..72937a29 100644 --- a/qse/lib/awkmod/mod-mysql.c +++ b/qse/lib/awkmod/mod-mysql.c @@ -421,27 +421,49 @@ static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) sql_node_t* sql_node; int ret = -1, take_rtx_err = 0; - qse_awk_val_t* a1, * a2, * a3; + qse_awk_val_t* a1, * a2, * a3, * a4, * a6; qse_mchar_t* host = QSE_NULL; qse_mchar_t* user = QSE_NULL; qse_mchar_t* pass = QSE_NULL; + qse_mchar_t* db = QSE_NULL; + qse_awk_int_t port = 0; + qse_mchar_t* usck = QSE_NULL; sql_list = rtx_to_sql_list(rtx, fi); sql_node = get_sql_list_node_with_arg(rtx, sql_list, qse_awk_rtx_getarg(rtx, 0)); if (sql_node) { + qse_size_t nargs; + + nargs = qse_awk_rtx_getnargs(rtx); + a1 = qse_awk_rtx_getarg(rtx, 1); a2 = qse_awk_rtx_getarg(rtx, 2); a3 = qse_awk_rtx_getarg(rtx, 3); - host = qse_awk_rtx_getvalmbs(rtx, a1, QSE_NULL); - if (!host) { take_rtx_err = 1; goto done; } - user = qse_awk_rtx_getvalmbs(rtx, a2, QSE_NULL); - if (!user) { take_rtx_err = 1; goto done; } - pass = qse_awk_rtx_getvalmbs(rtx, a3, QSE_NULL); - if (!pass) { take_rtx_err = 1; goto done; } + if (!(host = qse_awk_rtx_getvalmbs(rtx, a1, QSE_NULL)) || + !(user = qse_awk_rtx_getvalmbs(rtx, a2, QSE_NULL)) || + !(pass = qse_awk_rtx_getvalmbs(rtx, a3, QSE_NULL))) + { + arg_fail: + take_rtx_err = 1; + goto done; + } - if (!mysql_real_connect(sql_node->mysql, host, user, pass, QSE_NULL, 0, QSE_NULL, 0)) + if (nargs >= 5) + { + a4 = qse_awk_rtx_getarg(rtx, 4); + if (!(db = qse_awk_rtx_getvalmbs(rtx, a4, QSE_NULL))) goto arg_fail; + if (nargs >= 6 && qse_awk_rtx_valtoint(rtx, qse_awk_rtx_getarg(rtx, 5), &port) <= -1) goto arg_fail; + + if (nargs >= 7) + { + a6 = qse_awk_rtx_getarg(rtx, 6); + if (!(usck = qse_awk_rtx_getvalmbs(rtx, a6, QSE_NULL))) goto arg_fail; + } + } + + if (!mysql_real_connect(sql_node->mysql, host, user, pass, db, port, usck, 0)) { set_error_on_sql_list (rtx, sql_list, QSE_T("%hs"), mysql_error(sql_node->mysql)); sql_node->connect_ever_attempted = 1; /* doesn't matter if mysql_real_connect() failed */ @@ -454,6 +476,8 @@ static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) done: if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); + if (usck) qse_awk_rtx_freevalmbs (rtx, a6, usck); + if (db) qse_awk_rtx_freevalmbs (rtx, a4, db); 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); @@ -502,6 +526,45 @@ oops: return -1; } +static int fnc_select_db (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + sql_list_t* sql_list; + sql_node_t* sql_node; + qse_awk_val_t* a1; + qse_mchar_t* db = QSE_NULL; + int ret = -1, take_rtx_err = 0; + + sql_list = rtx_to_sql_list(rtx, fi); + sql_node = get_sql_list_node_with_arg(rtx, sql_list, qse_awk_rtx_getarg(rtx, 0)); + if (sql_node) + { + a1 = qse_awk_rtx_getarg(rtx, 1); + + if (!(db = qse_awk_rtx_getvalmbs(rtx, a1, QSE_NULL))) { take_rtx_err = 1; goto oops; } + + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); + + if (mysql_select_db(sql_node->mysql, db) != 0) + { + set_error_on_sql_list (rtx, sql_list, QSE_T("%hs"), mysql_error(sql_node->mysql)); + goto done; + } + + ret = 0; + } + +done: + if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); + if (db) qse_awk_rtx_freevalmbs (rtx, a1, db); + qse_awk_rtx_setretval (rtx, qse_awk_rtx_makeintval(rtx, ret)); + return 0; + +oops: + if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); + return -1; +} + + static int fnc_autocommit (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { sql_list_t* sql_list; @@ -931,7 +994,7 @@ static fnctab_t fnctab[] = { QSE_T("autocommit"), { { 2, 2, QSE_NULL }, fnc_autocommit, 0 } }, { QSE_T("close"), { { 1, 1, QSE_NULL }, fnc_close, 0 } }, { QSE_T("commit"), { { 1, 1, QSE_NULL }, fnc_commit, 0 } }, - { QSE_T("connect"), { { 4, 8, QSE_NULL }, fnc_connect, 0 } }, + { QSE_T("connect"), { { 4, 7, QSE_NULL }, fnc_connect, 0 } }, { QSE_T("errmsg"), { { 0, 0, QSE_NULL }, fnc_errmsg, 0 } }, { QSE_T("escape_string"), { { 3, 3, QSE_T("vvr") }, fnc_escape_string, 0 } }, { QSE_T("fetch_row"), { { 2, 2, QSE_T("vr") }, fnc_fetch_row, 0 } }, @@ -941,6 +1004,7 @@ static fnctab_t fnctab[] = { QSE_T("ping"), { { 1, 1, QSE_NULL }, fnc_ping, 0 } }, { QSE_T("query"), { { 2, 2, QSE_NULL }, fnc_query, 0 } }, { QSE_T("rollback"), { { 1, 1, QSE_NULL }, fnc_rollback, 0 } }, + { QSE_T("select_db"), { { 2, 2, QSE_NULL }, fnc_select_db, 0 } }, { QSE_T("set_option"), { { 3, 3, QSE_NULL }, fnc_set_option, 0 } }, { QSE_T("store_result"), { { 1, 1, QSE_NULL }, fnc_store_result, 0 } } };