]>
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"
18 typedef struct pqasyncquery_s
{
21 PQQueryHandler handler
;
23 struct pqasyncquery_s
*next
;
26 pqasyncquery_s
*queryhead
= NULL
, *querytail
= NULL
;
31 void dbhandler(int fd
, short revents
);
32 void dbstatus(int hooknum
, void *arg
);
33 void disconnectdb(void);
44 void connectdb(void) {
45 sstring
*dbhost
, *dbusername
, *dbpassword
, *dbdatabase
, *dbport
;
46 char connectstr
[1024];
51 /* stolen from chanserv as I'm lazy */
52 dbhost
= getcopyconfigitem("pqsql", "host", "localhost", HOSTLEN
);
53 dbusername
= getcopyconfigitem("pqsql", "username", "newserv", 20);
54 dbpassword
= getcopyconfigitem("pqsql", "password", "moo", 20);
55 dbdatabase
= getcopyconfigitem("pqsql", "database", "newserv", 20);
56 dbport
= getcopyconfigitem("pqsql", "port", "431", 8);
58 if(!dbhost
|| !dbusername
|| !dbpassword
|| !dbdatabase
|| !dbport
) {
59 /* freesstring allows NULL */
61 freesstring(dbusername
);
62 freesstring(dbpassword
);
63 freesstring(dbdatabase
);
68 snprintf(connectstr
, sizeof(connectstr
), "dbname=%s user=%s password=%s", dbdatabase
->content
, dbusername
->content
, dbpassword
->content
);
71 freesstring(dbusername
);
72 freesstring(dbpassword
);
73 freesstring(dbdatabase
);
76 Error("pqsql", ERR_INFO
, "Attempting database connection: %s", connectstr
);
78 /* Blocking connect for now.. */
79 dbconn
= PQconnectdb(connectstr
);
81 if (!dbconn
|| (PQstatus(dbconn
) != CONNECTION_OK
)) {
82 Error("pqsql", ERR_ERROR
, "Unable to connect to db.");
85 Error("pqsql", ERR_INFO
, "Connected!");
89 PQsetnonblocking(dbconn
, 1);
91 /* this kicks ass, thanks splidge! */
92 registerhandler(PQsocket(dbconn
), POLLIN
, dbhandler
);
93 registerhook(HOOK_CORE_STATSREQUEST
, dbstatus
);
96 void dbhandler(int fd
, short revents
) {
100 if(revents
& POLLIN
) {
101 PQconsumeInput(dbconn
);
103 if(!PQisBusy(dbconn
)) { /* query is complete */
104 if(queryhead
->handler
)
105 (queryhead
->handler
)(dbconn
, queryhead
->tag
);
107 while((res
= PQgetResult(dbconn
))) {
108 switch(PQresultStatus(res
)) {
109 case PGRES_TUPLES_OK
:
110 Error("pqsql", ERR_WARNING
, "Unhandled tuples output (query: %s)", queryhead
->query
->content
);
113 case PGRES_NONFATAL_ERROR
:
114 case PGRES_FATAL_ERROR
:
115 /* if a create query returns an error assume it went ok, paul will winge about this */
116 if(!(queryhead
->flags
& QH_CREATE
))
117 Error("pqsql", ERR_WARNING
, "Unhandled error response (query: %s)", queryhead
->query
->content
);
127 /* Free the query and advance */
129 if(queryhead
== querytail
)
132 queryhead
= queryhead
->next
;
134 freesstring(qqp
->query
);
137 if(queryhead
) { /* Submit the next query */
138 PQsendQuery(dbconn
, queryhead
->query
->content
);
146 void pqasyncqueryf(PQQueryHandler handler
, void *tag
, int flags
, char *format
, ...) {
155 va_start(va
, format
);
156 len
= vsnprintf(querybuf
, sizeof(querybuf
), format
, va
);
159 /* PPA: no check here... */
160 qp
= (pqasyncquery_s
*)malloc(sizeof(pqasyncquery_s
));
164 qp
->query
= getsstring(querybuf
, len
);
166 qp
->handler
= handler
;
167 qp
->next
= NULL
; /* shove them at the end */
171 querytail
->next
= qp
;
174 querytail
= queryhead
= qp
;
175 PQsendQuery(dbconn
, qp
->query
->content
);
180 void disconnectdb(void) {
181 pqasyncquery_s
*qqp
= queryhead
, *nqqp
;
186 /* do this first else we may get conflicts */
187 deregisterhandler(PQsocket(dbconn
), 0);
189 /* Throw all the queued queries away, beware of data malloc()ed inside the query item.. */
192 freesstring(qqp
->query
);
197 deregisterhook(HOOK_CORE_STATSREQUEST
, dbstatus
);
199 dbconn
= NULL
; /* hmm? */
204 /* more stolen code from Q9 */
205 void dbstatus(int hooknum
, void *arg
) {
212 for(qqp
=queryhead
;qqp
;qqp
=qqp
->next
)
215 snprintf(message
, sizeof(message
), "PQSQL : %6d queries queued.",i
);
217 triggerhook(HOOK_CORE_STATSREPLY
, message
);
221 int pqconnected(void) {