kore

An easy to use, scalable and secure web application framework for writing web APIs in C.
Commits | Files | Refs | README | LICENSE | git clone https://git.kore.io/kore.git

pgsql_cb.c (3437B)



      1 /*
      2  * Copyright (c) 2018 Joris Vink <joris@coders.se>
      3  *
      4  * Permission to use, copy, modify, and distribute this software for any
      5  * purpose with or without fee is hereby granted, provided that the above
      6  * copyright notice and this permission notice appear in all copies.
      7  *
      8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     15  */
     16 
     17 /*
     18  * This is the same as pgsql.c except the query is fired off when
     19  * a new connection is made to Kore on port 8889.
     20  *
     21  * Instead of binding an http_request to the pgsql data structure we
     22  * use a callback function that is called for every state change.
     23  *
     24  * We pass the connection as an argument to this function.
     25  */
     26 
     27 #include <kore/kore.h>
     28 #include <kore/http.h>
     29 #include <kore/pgsql.h>
     30 
     31 void	connection_del(struct connection *c);
     32 void	connection_new(struct connection *);
     33 
     34 void	db_state_change(struct kore_pgsql *, void *);
     35 void	db_init(struct connection *, struct kore_pgsql *);
     36 void	db_results(struct kore_pgsql *, struct connection *);
     37 
     38 void
     39 connection_new(struct connection *c)
     40 {
     41 	struct kore_pgsql	*pgsql;
     42 
     43 	c->disconnect = connection_del;
     44 	c->proto = CONN_PROTO_UNKNOWN;
     45 	c->state = CONN_STATE_ESTABLISHED;
     46 
     47 	pgsql = kore_calloc(1, sizeof(*pgsql));
     48 
     49 	kore_pgsql_init(pgsql);
     50 	kore_pgsql_bind_callback(pgsql, db_state_change, c);
     51 
     52 	c->hdlr_extra = pgsql;
     53 	printf("new connection %p\n", (void *)c);
     54 
     55 	db_init(c, pgsql);
     56 }
     57 
     58 void
     59 db_init(struct connection *c, struct kore_pgsql *pgsql)
     60 {
     61 	if (!kore_pgsql_setup(pgsql, "db", KORE_PGSQL_ASYNC)) {
     62 		if (pgsql->state == KORE_PGSQL_STATE_INIT) {
     63 			printf("\twaiting for available pgsql connection\n");
     64 			return;
     65 		}
     66 
     67 		kore_pgsql_logerror(pgsql);
     68 		kore_connection_disconnect(c);
     69 		return;
     70 	}
     71 
     72 	printf("\tgot pgsql connection\n");
     73 	if (!kore_pgsql_query(pgsql, "SELECT * FROM coders, pg_sleep(5)")) {
     74 		kore_pgsql_logerror(pgsql);
     75 		kore_connection_disconnect(c);
     76 		return;
     77 	}
     78 	printf("\tquery fired off!\n");
     79 }
     80 
     81 void
     82 connection_del(struct connection *c)
     83 {
     84 	printf("%p: disconnecting\n", (void *)c);
     85 
     86 	if (c->hdlr_extra != NULL)
     87 		kore_pgsql_cleanup(c->hdlr_extra);
     88 
     89 	kore_free(c->hdlr_extra);
     90 	c->hdlr_extra = NULL;
     91 }
     92 
     93 void
     94 db_state_change(struct kore_pgsql *pgsql, void *arg)
     95 {
     96 	struct connection	*c = arg;
     97 
     98 	printf("%p: state change on pgsql %d\n", arg, pgsql->state);
     99 
    100 	switch (pgsql->state) {
    101 	case KORE_PGSQL_STATE_INIT:
    102 		db_init(c, pgsql);
    103 		break;
    104 	case KORE_PGSQL_STATE_WAIT:
    105 		break;
    106 	case KORE_PGSQL_STATE_COMPLETE:
    107 		kore_connection_disconnect(c);
    108 		break;
    109 	case KORE_PGSQL_STATE_ERROR:
    110 		kore_pgsql_logerror(pgsql);
    111 		kore_connection_disconnect(c);
    112 		break;
    113 	case KORE_PGSQL_STATE_RESULT:
    114 		db_results(pgsql, c);
    115 		break;
    116 	default:
    117 		kore_pgsql_continue(pgsql);
    118 		break;
    119 	}
    120 }
    121 
    122 void
    123 db_results(struct kore_pgsql *pgsql, struct connection *c)
    124 {
    125 	char		*name;
    126 	int		i, rows;
    127 
    128 	rows = kore_pgsql_ntuples(pgsql);
    129 	for (i = 0; i < rows; i++) {
    130 		name = kore_pgsql_getvalue(pgsql, i, 0);
    131 		net_send_queue(c, name, strlen(name));
    132 	}
    133 
    134 	net_send_flush(c);
    135 	kore_pgsql_continue(pgsql);
    136 }