]>
jfr.im git - irc/quakenet/newserv.git/blob - pqsql/pqsql.c
4 * 99% of the handling is stolen from Q9.
7 #include "../core/config.h"
8 #include "../core/error.h"
9 #include "../irc/irc_config.h"
10 #include "../core/events.h"
11 #include "../core/hooks.h"
12 #include "../lib/version.h"
21 typedef struct pqasyncquery_s
{
24 PQQueryHandler handler
;
26 struct pqasyncquery_s
*next
;
29 pqasyncquery_s
*queryhead
= NULL
, *querytail
= NULL
;
34 void dbhandler(int fd
, short revents
);
35 void dbstatus(int hooknum
, void *arg
);
36 void disconnectdb(void);
47 void connectdb(void) {
48 sstring
*dbhost
, *dbusername
, *dbpassword
, *dbdatabase
, *dbport
;
49 char connectstr
[1024];
54 /* stolen from chanserv as I'm lazy */
55 dbhost
= getcopyconfigitem("pqsql", "host", "localhost", HOSTLEN
);
56 dbusername
= getcopyconfigitem("pqsql", "username", "newserv", 20);
57 dbpassword
= getcopyconfigitem("pqsql", "password", "moo", 20);
58 dbdatabase
= getcopyconfigitem("pqsql", "database", "newserv", 20);
59 dbport
= getcopyconfigitem("pqsql", "port", "431", 8);
61 if(!dbhost
|| !dbusername
|| !dbpassword
|| !dbdatabase
|| !dbport
) {
62 /* freesstring allows NULL */
64 freesstring(dbusername
);
65 freesstring(dbpassword
);
66 freesstring(dbdatabase
);
71 snprintf(connectstr
, sizeof(connectstr
), "dbname=%s user=%s password=%s", dbdatabase
->content
, dbusername
->content
, dbpassword
->content
);
74 freesstring(dbusername
);
75 freesstring(dbpassword
);
76 freesstring(dbdatabase
);
79 Error("pqsql", ERR_INFO
, "Attempting database connection: %s", connectstr
);
81 /* Blocking connect for now.. */
82 dbconn
= PQconnectdb(connectstr
);
84 if (!dbconn
|| (PQstatus(dbconn
) != CONNECTION_OK
)) {
85 Error("pqsql", ERR_ERROR
, "Unable to connect to db.");
88 Error("pqsql", ERR_INFO
, "Connected!");
92 PQsetnonblocking(dbconn
, 1);
94 /* this kicks ass, thanks splidge! */
95 registerhandler(PQsocket(dbconn
), POLLIN
, dbhandler
);
96 registerhook(HOOK_CORE_STATSREQUEST
, dbstatus
);
99 void dbhandler(int fd
, short revents
) {
103 if(revents
& POLLIN
) {
104 PQconsumeInput(dbconn
);
106 if(!PQisBusy(dbconn
)) { /* query is complete */
107 if(queryhead
->handler
)
108 (queryhead
->handler
)(dbconn
, queryhead
->tag
);
110 while((res
= PQgetResult(dbconn
))) {
111 switch(PQresultStatus(res
)) {
112 case PGRES_TUPLES_OK
:
113 Error("pqsql", ERR_WARNING
, "Unhandled tuples output (query: %s)", queryhead
->query
->content
);
116 case PGRES_NONFATAL_ERROR
:
117 case PGRES_FATAL_ERROR
:
118 /* if a create query returns an error assume it went ok, paul will winge about this */
119 if(!(queryhead
->flags
& QH_CREATE
))
120 Error("pqsql", ERR_WARNING
, "Unhandled error response (query: %s)", queryhead
->query
->content
);
130 /* Free the query and advance */
132 if(queryhead
== querytail
)
135 queryhead
= queryhead
->next
;
137 freesstring(qqp
->query
);
140 if(queryhead
) { /* Submit the next query */
141 PQsendQuery(dbconn
, queryhead
->query
->content
);
149 void pqasyncqueryf(PQQueryHandler handler
, void *tag
, int flags
, char *format
, ...) {
158 va_start(va
, format
);
159 len
= vsnprintf(querybuf
, sizeof(querybuf
), format
, va
);
162 /* PPA: no check here... */
163 qp
= (pqasyncquery_s
*)malloc(sizeof(pqasyncquery_s
));
167 qp
->query
= getsstring(querybuf
, len
);
169 qp
->handler
= handler
;
170 qp
->next
= NULL
; /* shove them at the end */
174 querytail
->next
= qp
;
177 querytail
= queryhead
= qp
;
178 PQsendQuery(dbconn
, qp
->query
->content
);
183 void disconnectdb(void) {
184 pqasyncquery_s
*qqp
= queryhead
, *nqqp
;
189 /* do this first else we may get conflicts */
190 deregisterhandler(PQsocket(dbconn
), 0);
192 /* Throw all the queued queries away, beware of data malloc()ed inside the query item.. */
195 freesstring(qqp
->query
);
200 deregisterhook(HOOK_CORE_STATSREQUEST
, dbstatus
);
202 dbconn
= NULL
; /* hmm? */
207 /* more stolen code from Q9 */
208 void dbstatus(int hooknum
, void *arg
) {
215 for(qqp
=queryhead
;qqp
;qqp
=qqp
->next
)
218 snprintf(message
, sizeof(message
), "PQSQL : %6d queries queued.",i
);
220 triggerhook(HOOK_CORE_STATSREPLY
, message
);
224 int pqconnected(void) {