From 31d92b929271878bbaa08557f0e337d36ce531dd Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 21 Jun 2020 08:42:36 +0000 Subject: [PATCH] enhancing the mariadb client service --- mio/bin/t04.c | 32 +++++++++++++-- mio/lib/mar-cli.c | 100 ++++++++++++++++++++++------------------------ mio/lib/mar.c | 10 ++++- mio/lib/mio-mar.h | 52 ++++++++++++++++-------- 4 files changed, 119 insertions(+), 75 deletions(-) diff --git a/mio/bin/t04.c b/mio/bin/t04.c index 364e2f1..a1b2adb 100644 --- a/mio/bin/t04.c +++ b/mio/bin/t04.c @@ -20,7 +20,7 @@ printf ("CONNECTED...\n"); } } -static void mar_on_query_started (mio_dev_mar_t* dev, int mar_ret) +static void mar_on_query_started (mio_dev_mar_t* dev, int mar_ret, const mio_bch_t* mar_errmsg) { if (mar_ret != 0) { @@ -31,7 +31,7 @@ printf ("QUERY NOT SENT PROPERLY..%s\n", mysql_error(dev->hnd)); printf ("QUERY SENT..\n"); if (mio_dev_mar_fetchrows(dev) <= -1) { -printf ("FETCH ROW FAILURE - %s\n", mysql_error(dev->hnd)); +printf ("FETCH ROW FAILURE - %s\n", errmsg); mio_dev_mar_halt (dev); } } @@ -118,9 +118,30 @@ oops: +static void on_result (mio_svc_marc_t* svc, mio_oow_t sid, mio_svc_marc_rcode_t rcode, void* data, void* qctx) +{ + switch (rcode) + { + case MIO_SVC_MARC_RCODE_ROW: + { + MYSQL_ROW row = (MYSQL_ROW)data; +// if (x == 0) + printf ("[%lu] %s %s\n", sid, row[0], row[1]); +// else if (x == 1) +// printf ("%s %s %s %s %s\n", row[0], row[1], row[2], row[3], row[4]); + //printf ("GOT ROW\n"); + break; + } + case MIO_SVC_MARC_RCODE_DONE: +printf ("[%lu] NO DATA..\n", sid); + break; - + case MIO_SVC_MARC_RCODE_ERROR: + printf ("QUERY ERROR - %s\n", data); /* TODO: how to get both error code and error message? */ + break; + } +} int main (int argc, char* argv[]) { @@ -157,7 +178,10 @@ int main (int argc, char* argv[]) goto oops; } - mio_svc_mar_querywithbchars (marc, 0, "SHOW STATUS", 11, MIO_NULL); + mio_svc_mar_querywithbchars (marc, 0, MIO_SVC_MARC_QTYPE_SELECT, "SHOW STATUS", 11, on_result, MIO_NULL); + mio_svc_mar_querywithbchars (marc, 0, MIO_SVC_MARC_QTYPE_ACTION, "DELETE FROM", 11, on_result, MIO_NULL); +// mio_svc_mar_querywithbchars (marc, 0, MIO_SVC_MARC_QTYPE_SELECT, "SHOW STATUS", 11, on_result, MIO_NULL); + mio_svc_mar_querywithbchars (marc, 0, MIO_SVC_MARC_QTYPE_ACTION, "DELETE FROM XXX", 14, on_result, MIO_NULL); #if 0 memset (&mi, 0, MIO_SIZEOF(mi)); diff --git a/mio/lib/mar-cli.c b/mio/lib/mar-cli.c index 67589e0..c94fab7 100644 --- a/mio/lib/mar-cli.c +++ b/mio/lib/mar-cli.c @@ -44,8 +44,6 @@ struct mio_svc_marc_t mio_oow_t capa; } sess; - - }; struct sess_qry_t @@ -53,8 +51,10 @@ struct sess_qry_t mio_bch_t* qptr; mio_oow_t qlen; void* qctx; - int sent; + unsigned int sent: 1; + unsigned int need_fetch: 1; + mio_svc_marc_on_result_t on_result; sess_qry_t* sq_next; }; @@ -111,7 +111,7 @@ void mio_svc_marc_stop (mio_svc_marc_t* marc) /* ------------------------------------------------------------------- */ -static sess_qry_t* make_session_query (mio_t* mio, const mio_bch_t* qptr, mio_oow_t qlen, void* qctx) +static sess_qry_t* make_session_query (mio_t* mio, mio_svc_marc_qtype_t qtype, const mio_bch_t* qptr, mio_oow_t qlen, void* qctx, mio_svc_marc_on_result_t on_result) { sess_qry_t* sq; @@ -121,9 +121,11 @@ static sess_qry_t* make_session_query (mio_t* mio, const mio_bch_t* qptr, mio_oo MIO_MEMCPY (sq + 1, qptr, (MIO_SIZEOF(*qptr) * qlen)); sq->sent = 0; + sq->need_fetch = (qtype == MIO_SVC_MARC_QTYPE_SELECT); sq->qptr = (mio_bch_t*)(sq + 1); sq->qlen = qlen; sq->qctx = qctx; + sq->on_result = on_result; sq->sq_next = MIO_NULL; return sq; @@ -209,71 +211,63 @@ printf ("connected on sid %d\n", sess->sid); } } -static void mar_on_query_started (mio_dev_mar_t* dev, int mar_ret) +static void mar_on_query_started (mio_dev_mar_t* dev, int mar_ret, const mio_bch_t* mar_errmsg) { - if (mar_ret != 0) + dev_xtn_t* xtn = (dev_xtn_t*)mio_dev_mar_getxtn(dev); + sess_t* sess = xtn->sess; + sess_qry_t* sq = get_first_session_query(sess); + + if (mar_ret) { - } - else - { - if (mio_dev_mar_fetchrows(dev) <= -1) - { - mio_dev_mar_halt (dev); - } - } +printf ("QUERY FAILED...%d -> %s\n", mar_ret, mar_errmsg); #if 0 - if (mar_ret != 0) - { -printf ("QUERY NOT SENT PROPERLY..%s\n", mysql_error(dev->hnd)); + if (mar_ret == CR_SERVER_GONE_ERROR || /* server gone away between queries */ + mar_ret == CR_SERVER_LOST) /* server gone away during a query */ +#endif + + sq->on_result(sess->svc, sess->sid, MIO_SVC_MARC_RCODE_ERROR, mysql_error(dev->hnd), sq->qctx); + + dequeue_session_query (sess->svc->mio, sess); + send_pending_query_if_any (sess); } else { -printf ("QUERY SENT..\n"); - if (mio_dev_mar_fetchrows(dev) <= -1) +printf ("QUERY STARTED\n"); + if (sq->need_fetch) { -printf ("FETCH ROW FAILURE - %s\n", mysql_error(dev->hnd)); - mio_dev_mar_halt (dev); + if (mio_dev_mar_fetchrows(dev) <= -1) + { +//printf ("FETCH ROW FAILURE - %s\n", mysql_error(dev->hnd)); + mio_dev_mar_halt (dev); + } + } + else + { + if (sq->on_result) + sq->on_result (sess->svc, sess->sid, MIO_SVC_MARC_RCODE_DONE, MIO_NULL, sq->qctx); + + dequeue_session_query (sess->svc->mio, sess); + send_pending_query_if_any (sess); } } -#endif } static void mar_on_row_fetched (mio_dev_mar_t* dev, void* data) { -#if 0 - MYSQL_ROW row = (MYSQL_ROW)data; - static int x = 0; - if (!row) - { - printf ("NO MORE ROW..\n"); - if (x == 0 && mio_dev_mar_querywithbchars(dev, "SELECT * FROM pdns.records", 26) <= -1) mio_dev_mar_halt (dev); - x++; - } - else - { - if (x == 0) - printf ("%s %s\n", row[0], row[1]); - else if (x == 1) - printf ("%s %s %s %s %s\n", row[0], row[1], row[2], row[3], row[4]); - //printf ("GOT ROW\n"); - } -#endif - dev_xtn_t* xtn = (dev_xtn_t*)mio_dev_mar_getxtn(dev); sess_t* sess = xtn->sess; + sess_qry_t* sq = get_first_session_query(sess); - if (!data) + if (sq->on_result) { - /* no more rows */ - - //marc->on_row_fetched (marc, void* data, sess->sid, sess->qctx); -printf ("there is no more row...\n"); - } - else - { -printf ("there is row...\n"); + sq->on_result (sess->svc, sess->sid, (data? MIO_SVC_MARC_RCODE_ROW: MIO_SVC_MARC_RCODE_DONE), data, sq->qctx); } + if (!data) + { + dequeue_session_query (sess->svc->mio, sess); + send_pending_query_if_any (sess); + } } static mio_dev_mar_t* alloc_device (mio_svc_marc_t* marc, sess_t* sess) @@ -340,7 +334,7 @@ static sess_t* get_session (mio_svc_marc_t* marc, mio_oow_t sid) { sess_qry_t* sq; - sq = make_session_query(mio, "", 0, MIO_NULL); /* this is a place holder */ + sq = make_session_query(mio, MIO_SVC_MARC_QTYPE_ACTION, "", 0, MIO_NULL, 0); /* this is a place holder */ if (MIO_UNLIKELY(!sq)) return MIO_NULL; sess->dev = alloc_device(marc, sess); @@ -358,7 +352,7 @@ static sess_t* get_session (mio_svc_marc_t* marc, mio_oow_t sid) } -int mio_svc_mar_querywithbchars (mio_svc_marc_t* marc, mio_oow_t sid, const mio_bch_t* qptr, mio_oow_t qlen, void* qctx) +int mio_svc_mar_querywithbchars (mio_svc_marc_t* marc, mio_oow_t sid, mio_svc_marc_qtype_t qtype, const mio_bch_t* qptr, mio_oow_t qlen, mio_svc_marc_on_result_t on_result, void* qctx) { mio_t* mio = marc->mio; sess_t* sess; @@ -367,7 +361,7 @@ int mio_svc_mar_querywithbchars (mio_svc_marc_t* marc, mio_oow_t sid, const mio_ sess = get_session(marc, sid); if (MIO_UNLIKELY(!sess)) return -1; - sq = make_session_query(mio, qptr, qlen, qctx); + sq = make_session_query(mio, qtype, qptr, qlen, qctx, on_result); if (MIO_UNLIKELY(!sq)) return -1; if (get_first_session_query(sess)) diff --git a/mio/lib/mar.c b/mio/lib/mar.c index dbd9e1a..9c4357a 100644 --- a/mio/lib/mar.c +++ b/mio/lib/mar.c @@ -217,6 +217,11 @@ static int dev_mar_ioctl (mio_dev_t* dev, int cmd, void* arg) else { /* query sent immediately */ + if (err) + { + if (err == 1) err = mysql_errno(rdev->hnd); + mio_copy_bcstr (rdev->errbuf, MIO_COUNTOF(rdev->errbuf), mysql_error(rdev->hnd)); + } rdev->query_started = 1; rdev->query_ret = err; watch_mysql (rdev, MYSQL_WAIT_READ | MYSQL_WAIT_WRITE); @@ -322,7 +327,7 @@ static int dev_evcb_mar_ready (mio_dev_t* dev, int events) { rdev->query_started = 0; MIO_DEV_MAR_SET_PROGRESS (rdev, MIO_DEV_MAR_QUERY_STARTED); - if (rdev->on_query_started) rdev->on_query_started (rdev, rdev->query_ret); + if (rdev->on_query_started) rdev->on_query_started (rdev, rdev->query_ret, (rdev->query_ret? rdev->errbuf: MIO_NULL)); } else { @@ -336,7 +341,8 @@ static int dev_evcb_mar_ready (mio_dev_t* dev, int events) { /* query sent */ MIO_DEV_MAR_SET_PROGRESS (rdev, MIO_DEV_MAR_QUERY_STARTED); - if (rdev->on_query_started) rdev->on_query_started (rdev, tmp); + if (tmp == 1) tmp = mysql_errno(rdev->hnd); /* tmp is set to 1 by mariadb-connector-c 3.1 as of this writing. let me work around it by fetching the error code */ + if (rdev->on_query_started) rdev->on_query_started (rdev, tmp, (tmp? mysql_error(rdev->hnd): MIO_NULL)); } } diff --git a/mio/lib/mio-mar.h b/mio/lib/mio-mar.h index 071c0aa..10f8cea 100644 --- a/mio/lib/mio-mar.h +++ b/mio/lib/mio-mar.h @@ -68,14 +68,14 @@ typedef enum mio_dev_mar_state_t mio_dev_mar_state_t; typedef int (*mio_dev_mar_on_read_t) ( mio_dev_mar_t* dev, - const void* data, - mio_iolen_t len + const void* data, + mio_iolen_t len ); typedef int (*mio_dev_mar_on_write_t) ( mio_dev_mar_t* dev, - mio_iolen_t wrlen, - void* wrctx + mio_iolen_t wrlen, + void* wrctx ); typedef void (*mio_dev_mar_on_connect_t) ( @@ -88,12 +88,13 @@ typedef void (*mio_dev_mar_on_disconnect_t) ( typedef void (*mio_dev_mar_on_query_started_t) ( mio_dev_mar_t* dev, - int mar_ret + int mar_ret, + const mio_bch_t* mar_errmsg ); typedef void (*mio_dev_mar_on_row_fetched_t) ( mio_dev_mar_t* dev, - void* row_data + void* row_data ); struct mio_dev_mar_t @@ -108,6 +109,7 @@ struct mio_dev_mar_t unsigned int query_started; unsigned int row_fetched; + char errbuf[256]; int query_ret; int row_wstatus; void* row; @@ -155,11 +157,27 @@ typedef enum mio_dev_mar_ioctl_cmd_t mio_dev_mar_ioctl_cmd_t; typedef struct mio_svc_marc_t mio_svc_marc_t; typedef mio_dev_mar_connect_t mio_svc_marc_connect_t; -typedef void (*mio_svc_marc_on_row_fetched) ( - mio_svc_marc_t* marc, - mio_oow_t sid, - void* data, - void* qctx +enum mio_svc_marc_qtype_t +{ + MIO_SVC_MARC_QTYPE_SELECT, /* SELECT, SHOW, ... */ + MIO_SVC_MARC_QTYPE_ACTION /* UPDATE, INSERT, DELETE, ALTER ... */ +}; +typedef enum mio_svc_marc_qtype_t mio_svc_marc_qtype_t; + +enum mio_svc_marc_rcode_t +{ + MIO_SVC_MARC_RCODE_ROW, /* has row *- data is MYSQL_ROW */ + MIO_SVC_MARC_RCODE_DONE, /* completed or no more row - data is NULL */ + MIO_SVC_MARC_RCODE_ERROR /* query error - data is a numeric database error code cast to void* */ +}; +typedef enum mio_svc_marc_rcode_t mio_svc_marc_rcode_t; + +typedef void (*mio_svc_marc_on_result_t) ( + mio_svc_marc_t* marc, + mio_oow_t sid, + mio_svc_marc_rcode_t rcode, + void* data, + void* qctx ); /* -------------------------------------------------------------- */ @@ -232,11 +250,13 @@ static MIO_INLINE mio_t* mio_svc_marc_getmio(mio_svc_marc_t* svc) { return mio_s MIO_EXPORT int mio_svc_mar_querywithbchars ( - mio_svc_marc_t* marc, - mio_oow_t sid, - const mio_bch_t* qptr, - mio_oow_t qlen, - void* qctx + mio_svc_marc_t* marc, + mio_oow_t sid, + mio_svc_marc_qtype_t qtype, + const mio_bch_t* qptr, + mio_oow_t qlen, + mio_svc_marc_on_result_t on_result, + void* qctx ); #ifdef __cplusplus