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 }