diff --git a/qse/include/qse/awk/awk.h b/qse/include/qse/awk/awk.h index 794cc995..be5f8bb2 100644 --- a/qse/include/qse/awk/awk.h +++ b/qse/include/qse/awk/awk.h @@ -1667,6 +1667,11 @@ QSE_EXPORT const qse_char_t* qse_awk_geterrmsg ( const qse_awk_t* awk /**< awk */ ); +QSE_EXPORT const qse_char_t* qse_awk_backuperrmsg ( + qse_awk_t* awk /**< awk */ +); + + /** * The qse_awk_geterrinf() function copies error information into memory * pointed to by \a errinf from \a awk. @@ -2344,6 +2349,10 @@ QSE_EXPORT const qse_char_t* qse_awk_rtx_geterrmsg ( const qse_awk_rtx_t* rtx /**< runtime context */ ); +QSE_EXPORT const qse_char_t* qse_awk_rtx_backuperrmsg ( + qse_awk_rtx_t* rtx /**< runtime context */ +); + /** * The qse_awk_rtx_geterrinf() function copies error information into memory * pointed to by \a errinf from a runtime context \a rtx. diff --git a/qse/include/qse/cmn/Mmgr.hpp b/qse/include/qse/cmn/Mmgr.hpp index 4cab17b9..8daf8ae4 100644 --- a/qse/include/qse/cmn/Mmgr.hpp +++ b/qse/include/qse/cmn/Mmgr.hpp @@ -81,7 +81,7 @@ public: /// allocation. if it fails, it raise an exception if it's /// configured to do so. /// - void* allocate (qse_size_t n, bool raise_exception = true) QSE_CPP_THREXCEPT1(MemoryError) + void* allocate (qse_size_t n, bool raise_exception = true) /*QSE_CPP_THREXCEPT1(MemoryError)*/ { void* xptr = this->allocMem (n); if (!xptr && raise_exception) QSE_THROW (MemoryError); @@ -92,14 +92,14 @@ public: /// The callocate() function allocates memory like allocate() and /// clears the memory before returning. /// - void* callocate (qse_size_t n, bool raise_exception = true) QSE_CPP_THREXCEPT1(MemoryError); + void* callocate (qse_size_t n, bool raise_exception = true) /*QSE_CPP_THREXCEPT1(MemoryError)*/; /// /// The reallocate() function calls reallocMem() for memory /// reallocation. if it fails, it raise an exception if it's /// configured to do so. /// - void* reallocate (void* ptr, qse_size_t n, bool raise_exception = true) QSE_CPP_THREXCEPT1(MemoryError) + void* reallocate (void* ptr, qse_size_t n, bool raise_exception = true) /*QSE_CPP_THREXCEPT1(MemoryError)*/ { void* xptr = this->reallocMem (ptr, n); if (!xptr && raise_exception) QSE_THROW (MemoryError); @@ -171,7 +171,7 @@ protected: QSE_END_NAMESPACE(QSE) ///////////////////////////////// -QSE_EXPORT void* operator new (qse_size_t size, QSE::Mmgr* mmgr) QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError); +QSE_EXPORT void* operator new (qse_size_t size, QSE::Mmgr* mmgr) /*QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError)*/; #if defined(QSE_CPP_NO_OPERATOR_DELETE_OVERLOADING) QSE_EXPORT void qse_operator_delete (void* ptr, QSE::Mmgr* mmgr); @@ -179,7 +179,7 @@ QSE_EXPORT void qse_operator_delete (void* ptr, QSE::Mmgr* mmgr); QSE_EXPORT void operator delete (void* ptr, QSE::Mmgr* mmgr); #endif -QSE_EXPORT void* operator new (qse_size_t size, QSE::Mmgr* mmgr, void* existing_ptr) QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError); +QSE_EXPORT void* operator new (qse_size_t size, QSE::Mmgr* mmgr, void* existing_ptr) /*QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError)*/; #if 0 // i found no way to delete an array allocated with diff --git a/qse/lib/awk/awk-prv.h b/qse/lib/awk/awk-prv.h index a62d7d97..1d309bab 100644 --- a/qse/lib/awk/awk-prv.h +++ b/qse/lib/awk/awk-prv.h @@ -290,6 +290,7 @@ struct qse_awk_t /* housekeeping */ qse_awk_errstr_t errstr; qse_awk_errinf_t errinf; + qse_char_t errmsg_backup[256]; int stopall; qse_awk_ecb_t* ecb; @@ -426,6 +427,8 @@ struct qse_awk_rtx_t } depth; qse_awk_errinf_t errinf; + qse_char_t errmsg_backup[256]; + qse_awk_rtx_ecb_t* ecb; }; diff --git a/qse/lib/awk/err.c b/qse/lib/awk/err.c index 63ad79bc..d3fb0036 100644 --- a/qse/lib/awk/err.c +++ b/qse/lib/awk/err.c @@ -219,7 +219,11 @@ void qse_awk_geterror (const qse_awk_t* awk, qse_awk_errnum_t* errnum, const qse if (errloc) *errloc = awk->errinf.loc; } - +const qse_char_t* qse_awk_backuperrmsg (qse_awk_t* awk) +{ + qse_strxcpy (awk->errmsg_backup, QSE_COUNTOF(awk->errmsg_backup), qse_awk_geterrmsg(awk)); + return awk->errmsg_backup; +} void qse_awk_seterrnum (qse_awk_t* awk, qse_awk_errnum_t errnum, const qse_cstr_t* errarg) { @@ -299,6 +303,12 @@ void qse_awk_rtx_geterror ( } } +const qse_char_t* qse_awk_rtx_backuperrmsg (qse_awk_rtx_t* rtx) +{ + qse_strxcpy (rtx->errmsg_backup, QSE_COUNTOF(rtx->errmsg_backup), qse_awk_rtx_geterrmsg(rtx)); + return rtx->errmsg_backup; +} + void qse_awk_rtx_seterrnum ( qse_awk_rtx_t* rtx, qse_awk_errnum_t errnum, const qse_cstr_t* errarg) { diff --git a/qse/lib/awk/parse.c b/qse/lib/awk/parse.c index a5cea580..9094b63a 100644 --- a/qse/lib/awk/parse.c +++ b/qse/lib/awk/parse.c @@ -6989,7 +6989,7 @@ static qse_awk_mod_t* query_module ( /* TODO: binary search ... */ for (n = 0; n < QSE_COUNTOF(static_modtab); n++) { - if (qse_strcmp (static_modtab[n].modname, segs[0].ptr) == 0) + if (qse_strcmp(static_modtab[n].modname, segs[0].ptr) == 0) { load = static_modtab[n].modload; break; @@ -7014,7 +7014,7 @@ static qse_awk_mod_t* query_module ( /* i copy-insert 'md' into the table before calling 'load'. * to pass the same address to load(), query(), etc */ - pair = qse_rbt_insert (awk->modtab, segs[0].ptr, segs[0].len, &md, QSE_SIZEOF(md)); + pair = qse_rbt_insert(awk->modtab, segs[0].ptr, segs[0].len, &md, QSE_SIZEOF(md)); if (pair == QSE_NULL) { qse_awk_seterrnum (awk, QSE_AWK_ENOMEM, QSE_NULL); @@ -7031,10 +7031,10 @@ static qse_awk_mod_t* query_module ( goto done; } #endif + qse_awk_seterrnum (awk, QSE_AWK_ENOERR, QSE_NULL); /* attempt to find an external module */ QSE_MEMSET (&spec, 0, QSE_SIZEOF(spec)); - if (awk->opt.mod[0].len > 0) spec.prefix = awk->opt.mod[0].ptr; else spec.prefix = QSE_T(QSE_AWK_DEFAULT_MODPREFIX); @@ -7042,7 +7042,7 @@ static qse_awk_mod_t* query_module ( if (awk->opt.mod[1].len > 0) spec.postfix = awk->opt.mod[1].ptr; else spec.postfix = QSE_T(QSE_AWK_DEFAULT_MODPOSTFIX); - + QSE_MEMSET (&md, 0, QSE_SIZEOF(md)); if (awk->prm.modopen && awk->prm.modsym && awk->prm.modclose) { @@ -7053,31 +7053,44 @@ static qse_awk_mod_t* query_module ( if (md.handle == QSE_NULL) { - ea.ptr = segs[0].ptr; - ea.len = segs[0].len; - qse_awk_seterror (awk, QSE_AWK_ENOENT, &ea, QSE_NULL); + if (qse_awk_geterrnum(awk) == QSE_AWK_ENOERR) + { + qse_awk_seterrfmt (awk, QSE_AWK_ENOENT, QSE_NULL, QSE_T("module '%.*js' not found"), (int)segs[0].len, segs[0].ptr); + } + else + { + const qse_char_t* olderrmsg = qse_awk_backuperrmsg(awk); + qse_awk_seterrfmt (awk, QSE_AWK_ENOENT, QSE_NULL, QSE_T("module '%.*js' not found - %js"), (int)segs[0].len, segs[0].ptr, olderrmsg); + } return QSE_NULL; } buflen = qse_strcpy (&buf[13], segs[0].ptr); /* attempt qse_awk_mod_xxx */ - load = awk->prm.modsym (awk, md.handle, &buf[1]); + load = awk->prm.modsym(awk, md.handle, &buf[1]); if (!load) { /* attempt _qse_awk_mod_xxx */ - load = awk->prm.modsym (awk, md.handle, &buf[0]); + load = awk->prm.modsym(awk, md.handle, &buf[0]); if (!load) { + qse_awk_seterrnum (awk, QSE_AWK_ENOERR, QSE_NULL); + /* attempt qse_awk_mod_xxx_ */ buf[13 + buflen] = QSE_T('_'); buf[13 + buflen + 1] = QSE_T('\0'); - load = awk->prm.modsym (awk, md.handle, &buf[1]); + load = awk->prm.modsym(awk, md.handle, &buf[1]); if (!load) { - ea.ptr = &buf[1]; - ea.len = 12 + buflen; - qse_awk_seterror (awk, QSE_AWK_ENOENT, &ea, QSE_NULL); - + if (qse_awk_geterrnum(awk) == QSE_AWK_ENOERR) + { + qse_awk_seterrfmt (awk, QSE_AWK_ENOENT, QSE_NULL, QSE_T("module '%.*js' not found"), (int)(12 + buflen)); + } + else + { + qse_char_t* olderrmsg = qse_awk_backuperrmsg(awk); + qse_awk_seterrfmt (awk, QSE_AWK_ENOENT, QSE_NULL, QSE_T("module '%.*js' not found - %js"), (int)(12 + buflen), &buf[1], olderrmsg); + } awk->prm.modclose (awk, md.handle); return QSE_NULL; } diff --git a/qse/lib/awk/std.c b/qse/lib/awk/std.c index ca07d7cb..aa1caec2 100644 --- a/qse/lib/awk/std.c +++ b/qse/lib/awk/std.c @@ -402,6 +402,10 @@ void* qse_awk_stdmodopen (qse_awk_t* awk, const qse_awk_mod_spec_t* spec) } h = dlopen(modpath, RTLD_NOW); + if (!h) + { + qse_awk_seterrfmt (awk, QSE_AWK_ESYSERR, QSE_NULL, QSE_T("%hs"), dlerror()); + } QSE_MMGR_FREE (awk->mmgr, modpath); diff --git a/qse/lib/awkmod/mod-mysql.c b/qse/lib/awkmod/mod-mysql.c index 3cd63e6a..e4100b81 100644 --- a/qse/lib/awkmod/mod-mysql.c +++ b/qse/lib/awkmod/mod-mysql.c @@ -254,88 +254,6 @@ static int fnc_close (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) return 0; } -static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) -{ - sql_list_t* sql_list; - sql_node_t* sql_node; - int ret = -1, take_rtx_err = 0; - - qse_awk_val_t* a1, * a2, * a3; - qse_mchar_t* host = QSE_NULL; - qse_mchar_t* user = QSE_NULL; - qse_mchar_t* pass = 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) - { - 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 (!mysql_real_connect(sql_node->mysql, host, user, pass, QSE_NULL, 0, QSE_NULL, 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 */ - goto done; - } - - sql_node->connect_ever_attempted = 1; - ret = 0; - } - -done: - if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); - 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_ping (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) -{ - sql_list_t* sql_list; - sql_node_t* sql_node; - 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) - { - if (!sql_node->connect_ever_attempted) - { - set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); - goto done; - } - - if (mysql_ping(sql_node->mysql) != 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); - 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; -} - #if 0 static int fnc_get_option (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { @@ -360,12 +278,6 @@ static int fnc_get_option (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) goto oops; } - if (!sql_node->connect_ever_attempted) - { - set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); - goto done; - } - switch (id) { case MYSQL_OPT_CONNECT_TIMEOUT: @@ -484,7 +396,6 @@ static int fnc_set_option (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) goto done; } -printf ("%d %d\n", (int)id, *(int*)vptr); if (mysql_options(sql_node->mysql, id, vptr) != 0) { set_error_on_sql_list (rtx, sql_list, QSE_T("%hs"), mysql_error(sql_node->mysql)); @@ -504,6 +415,93 @@ oops: return -1; } +static int fnc_connect (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + sql_list_t* sql_list; + sql_node_t* sql_node; + int ret = -1, take_rtx_err = 0; + + qse_awk_val_t* a1, * a2, * a3; + qse_mchar_t* host = QSE_NULL; + qse_mchar_t* user = QSE_NULL; + qse_mchar_t* pass = 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) + { + 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 (!mysql_real_connect(sql_node->mysql, host, user, pass, QSE_NULL, 0, QSE_NULL, 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 */ + goto done; + } + + sql_node->connect_ever_attempted = 1; + ret = 0; + } + +done: + if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); + 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; +} + +#define ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node) \ + do { \ + if (!(sql_node)->connect_ever_attempted) \ + { \ + set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); \ + goto done; \ + } \ + } while(0) + +static int fnc_ping (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + sql_list_t* sql_list; + sql_node_t* sql_node; + 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) + { + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); + + if (mysql_ping(sql_node->mysql) != 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); + 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; @@ -519,11 +517,7 @@ static int fnc_autocommit (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); if (v <= -1) { take_rtx_err = 1; goto oops; } - if (!sql_node->connect_ever_attempted) - { - set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); - goto done; - } + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); if (mysql_autocommit(sql_node->mysql, v) != 0) { @@ -559,11 +553,7 @@ static int fnc_commit (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); if (v <= -1) { take_rtx_err = 1; goto oops; } - if (!sql_node->connect_ever_attempted) - { - set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); - goto done; - } + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); if (mysql_commit(sql_node->mysql) != 0) { @@ -599,11 +589,7 @@ static int fnc_rollback (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) v = qse_awk_rtx_valtobool(rtx, qse_awk_rtx_getarg(rtx, 1)); if (v <= -1) { take_rtx_err = 1; goto oops; } - if (!sql_node->connect_ever_attempted) - { - set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); - goto done; - } + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); if (mysql_rollback(sql_node->mysql) != 0) { @@ -624,11 +610,61 @@ oops: return -1; } +static int fnc_affected_rows (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) +{ + sql_list_t* sql_list; + sql_node_t* sql_node; + 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) + { + my_ulonglong nrows; + qse_awk_val_t* vrows; + + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); + + nrows = mysql_affected_rows(sql_node->mysql); + if (nrows == (my_ulonglong)-1) + { + set_error_on_sql_list (rtx, sql_list, QSE_T("%hs"), mysql_error(sql_node->mysql)); + goto done; + } + + vrows = qse_awk_rtx_makeintval(rtx, nrows); + if (!vrows) + { + take_rtx_err = 1; + goto oops; + } + + if (qse_awk_rtx_setrefval(rtx, (qse_awk_val_ref_t*)qse_awk_rtx_getarg(rtx, 1), vrows) <= -1) + { + qse_awk_rtx_refupval (rtx, vrows); + qse_awk_rtx_refdownval (rtx, vrows); + take_rtx_err = 1; + goto oops; + } + + ret = 0; + } + +done: + if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); + 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_escape_string (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) { sql_list_t* sql_list; sql_node_t* sql_node; - int take_rtx_err = 0; + int ret = -1, take_rtx_err = 0; qse_awk_val_t* a1, *retv; qse_mchar_t* qstr = QSE_NULL; @@ -639,7 +675,7 @@ static int fnc_escape_string (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) if (sql_node) { qse_size_t qlen; - + a1 = qse_awk_rtx_getarg(rtx, 1); qstr = qse_awk_rtx_getvalmbs(rtx, a1, &qlen); @@ -648,27 +684,38 @@ static int fnc_escape_string (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) ebuf = qse_awk_rtx_allocmem(rtx, (qlen * 2 + 1) * QSE_SIZEOF(*qstr)); if (!ebuf) { take_rtx_err = 1; goto oops; } - if (mysql_real_escape_string(sql_node->mysql, ebuf, qstr, qlen) != 0) + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); + mysql_real_escape_string(sql_node->mysql, ebuf, qstr, qlen); + + retv = qse_awk_rtx_makestrvalwithmbs(rtx, ebuf); + if (!retv) { - set_error_on_sql_list (rtx, sql_list, QSE_T("%hs"), mysql_error(sql_node->mysql)); - goto done; + take_rtx_err = 1; + goto oops; } + + if (qse_awk_rtx_setrefval(rtx, (qse_awk_val_ref_t*)qse_awk_rtx_getarg(rtx, 2), retv) <= -1) + { + qse_awk_rtx_refupval (rtx, retv); + qse_awk_rtx_refdownval (rtx, retv); + take_rtx_err = 1; + goto oops; + } + + ret = 0; } done: if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); - if (qstr) qse_awk_rtx_freevalmbs (rtx, a1, qstr); - retv = ebuf? qse_awk_rtx_makestrvalwithmbs(rtx, ebuf): qse_awk_rtx_makenilval(rtx); + if (take_rtx_err) set_error_on_sql_list (rtx, sql_list, QSE_NULL); if (ebuf) qse_awk_rtx_freemem (rtx, ebuf); - if (!retv) return -1; - - qse_awk_rtx_setretval (rtx, retv); + if (qstr) qse_awk_rtx_freevalmbs (rtx, a1, qstr); + 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); - if (qstr) qse_awk_rtx_freevalmbs (rtx, a1, qstr); if (ebuf) qse_awk_rtx_freemem (rtx, ebuf); + if (qstr) qse_awk_rtx_freevalmbs (rtx, a1, qstr); return -1; } @@ -691,11 +738,7 @@ static int fnc_query (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) qstr = qse_awk_rtx_getvalmbs(rtx, a1, &qlen); if (!qstr) { take_rtx_err = 1; goto oops; } - if (!sql_node->connect_ever_attempted) - { - set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); - goto done; - } + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); if (mysql_real_query(sql_node->mysql, qstr, qlen) != 0) { @@ -734,11 +777,7 @@ static int fnc_store_result (qse_awk_rtx_t* rtx, const qse_awk_fnc_info_t* fi) res_list = rtx_to_res_list(rtx, fi); - if (!sql_node->connect_ever_attempted) - { - set_error_on_sql_list (rtx, sql_list, QSE_T("not connected")); - goto done; - } + ENSURE_CONNECT_EVER_ATTEMPTED(rtx, sql_list, sql_node); res = mysql_store_result(sql_node->mysql); if (!res) @@ -888,21 +927,22 @@ struct inttab_t static fnctab_t fnctab[] = { /* keep this table sorted for binary search in query(). */ - { QSE_T("autocommit"), { { 1, 1, 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("errmsg"), { { 0, 0, QSE_NULL }, fnc_errmsg, 0 } }, - { QSE_T("escape_string"), { { 2, 2, QSE_NULL }, fnc_escape_string, 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("get_option"), { { 3, 3, QSE_T("vr") }, fnc_get_option, 0 } },*/ - { QSE_T("open"), { { 0, 0, QSE_NULL }, fnc_open, 0 } }, - { 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("set_option"), { { 3, 3, QSE_NULL }, fnc_set_option, 0 } }, - { QSE_T("store_result"), { { 1, 1, QSE_NULL }, fnc_store_result, 0 } } + { QSE_T("affected_rows"), { { 2, 2, QSE_T("vr") }, fnc_affected_rows, 0 } }, + { 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("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 } }, + { QSE_T("free_result"), { { 1, 1, QSE_NULL }, fnc_free_result, 0 } }, + /*{ QSE_T("get_option"), { { 3, 3, QSE_T("vr") }, fnc_get_option, 0 } },*/ + { QSE_T("open"), { { 0, 0, QSE_NULL }, fnc_open, 0 } }, + { 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("set_option"), { { 3, 3, QSE_NULL }, fnc_set_option, 0 } }, + { QSE_T("store_result"), { { 1, 1, QSE_NULL }, fnc_store_result, 0 } } }; static inttab_t inttab[] = @@ -1023,6 +1063,7 @@ static void unload (qse_awk_mod_t* mod, qse_awk_t* awk) QSE_ASSERT (QSE_RBT_SIZE(rbt) == 0); qse_rbt_close (rbt); +//mysql_library_end (); } int qse_awk_mod_mysql (qse_awk_mod_t* mod, qse_awk_t* awk) diff --git a/qse/lib/cmn/Mmgr.cpp b/qse/lib/cmn/Mmgr.cpp index 6ed74bd1..225fed36 100644 --- a/qse/lib/cmn/Mmgr.cpp +++ b/qse/lib/cmn/Mmgr.cpp @@ -47,7 +47,7 @@ void Mmgr::free_mem (mmgr_t* mmgr, void* ptr) QSE_CPP_NOEXCEPT ((Mmgr*)mmgr->ctx)->freeMem (ptr); } -void* Mmgr::callocate (qse_size_t n, bool raise_exception) QSE_CPP_THREXCEPT1(MemoryError) +void* Mmgr::callocate (qse_size_t n, bool raise_exception) /*QSE_CPP_THREXCEPT1(MemoryError)*/ { void* ptr = this->allocate(n, raise_exception); QSE_MEMSET (ptr, 0, n); @@ -90,7 +90,7 @@ void Mmgr::setDFL (Mmgr* mmgr) QSE_CPP_NOEXCEPT QSE_END_NAMESPACE(QSE) ///////////////////////////////// -void* operator new (qse_size_t size, QSE::Mmgr* mmgr) QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError) +void* operator new (qse_size_t size, QSE::Mmgr* mmgr) /*QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError)*/ { return mmgr->allocate (size); } @@ -104,7 +104,7 @@ void operator delete (void* ptr, QSE::Mmgr* mmgr) mmgr->dispose (ptr); } -void* operator new (qse_size_t size, QSE::Mmgr* mmgr, void* existing_ptr) QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError) +void* operator new (qse_size_t size, QSE::Mmgr* mmgr, void* existing_ptr) /*QSE_CPP_THREXCEPT1(QSE::Mmgr::MemoryError)*/ { // mmgr unused. i put it in the parameter list to make this function // less conflicting with the stock ::operator new() that doesn't allocate.