1 /*
2    Copyright (C) 2002-2005  Ulric Eriksson <ulric@siag.nu>
3 
4    This library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the Licence, or (at your option) any later version.
8 
9    This library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public
15    License along with this library; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston,
17    MA 02111-1307, USA.
18  */
19 
20 #ifdef HAVE_LIBMSQL
21 
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <msql.h>
25 #include "common.h"
26 #include "sdb.h"
27 
28 struct conn_info {
29 	int sock;
30 };
31 
sdb_msql_open(char * url)32 static void *sdb_msql_open(char *url)
33 {
34 	char *host = sdb_url_value(url, "host");
35 	char *db = sdb_url_value(url, "db");
36 	int sock;
37 	struct conn_info *ci;
38 
39 	if (db == NULL) {
40 		sdb_debug("No db in %s", url);
41 		return NULL;
42 	}
43 	if ((sock = msqlConnect(host)) < 0) {
44 		sdb_debug("Can't connect to %s: %s", host, msqlErrMsg);
45 		return NULL;
46 	}
47 	if (msqlSelectDB(sock, db) < 0) {
48 		sdb_debug("Can't select %s: %s", db, msqlErrMsg);
49 		msqlClose(sock);
50 		return NULL;
51 	}
52 	ci = sdb_malloc(sizeof *ci);
53 	ci->sock = sock;
54 	return ci;
55 }
56 
sdb_msql_close(void * db)57 static int sdb_msql_close(void *db)
58 {
59 	struct conn_info *ci = db;
60 	if (ci && ci->sock >= 0) {
61 		msqlClose(ci->sock);
62 	}
63 	return 0;
64 }
65 
66 /* Parameters:
67    pdb = pointer to previously opened database connection, or NULL
68    d = url string
69    q = query string
70    callback = function to send the data to
71    closure = pointer to data passed from application
72 */
msql_driver(void * pdb,char * d,char * q,int (* callback)(int,char **,void *),void * closure)73 static int msql_driver(void *pdb, char *d, char *q,
74 	int (*callback)(int, char **, void *), void *closure)
75 {
76 	int n, off;
77 	struct conn_info *ci;
78 	m_result *result;
79 	m_row cur;
80 	char **row;
81 
82 	if (pdb == NULL) ci = sdb_msql_open(d);
83 	else ci = pdb;
84 
85 	if (!ci) {
86 		sdb_debug("Can't open database");
87 		return -1;
88 	}
89 	n = msqlQuery(ci->sock, q);
90 	if (n < 0) {
91 		sdb_debug("Query failed: %s", msqlErrMsg);
92 		n = -1;
93 		goto Done;
94 	}
95 	result = msqlStoreResult();
96 	if (result == NULL) {
97 		sdb_debug("null result");
98 		n = -1;
99 		goto Done;
100 	}
101 
102 	n = 0;
103 	row = sdb_malloc(msqlNumFields(result)*sizeof *row);
104 	while ((cur = msqlFetchRow(result))) {
105 		for (off = 0; off < msqlNumFields(result); off++)
106 			row[off] = cur[off];
107 		(*callback)(msqlNumFields(result), row, closure);
108 		n++;
109 	}
110 	sdb_free(row);
111 
112 Done:
113 	if (pdb == NULL) sdb_msql_close(ci);
114 
115 	return n;
116 }
117 
sdb_init_msql(void)118 void sdb_init_msql(void)
119 {
120 	sdb_register_driver("msql", msql_driver,
121 		sdb_msql_open, sdb_msql_close);
122 }
123 
124 #else
125 
sdb_init_msql(void)126 void sdb_init_msql(void)
127 {
128 	;
129 }
130 
131 #endif	/* MSQL */
132