Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d1c5021

Browse files
committed
From: "Aldrin L." <aldrin@americasnet.com> Subject: [INTERFACES] mSQL Compatibility Library (fwd)
1 parent 4587891 commit d1c5021

File tree

2 files changed

+360
-0
lines changed

2 files changed

+360
-0
lines changed

contrib/mSQL-interface/README

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
Hello! :)
2+
3+
(Sorry for my english. But if i wrote in portuguese, you wouldn't
4+
understand nothing. :])
5+
6+
I found it's the right place to post this. I'm a newcomer in these
7+
lists. I hope i did it right. :]
8+
9+
<BOREDOM>
10+
When i started using SQL, i started with mSQL. I developed a lot
11+
of useful apps for me and my job with C, mainly because i loved it's
12+
elegant, simple api. But for a large project i'm doing in these days, i
13+
thought is was not enough, because it felt a lot of features i started to
14+
need, like security and subselects. (and it's not free :))
15+
So after looking at the options, choose to start again with
16+
postgres. It offered everything that i needed, and the documentation is
17+
really good (remember me to thank the one who wrote'em).
18+
But for my little apps, i needed to start porting them to libpq.
19+
After looking at pq's syntax, i found it was better to write a bridge
20+
between the mSQL api and libpq. I found that rewriting the libmsql.a
21+
routines that calls libpq would made things much easier. I guess the
22+
results are quite good right now.
23+
</BOREDOM>
24+
25+
Ok. Lets' summarize it:
26+
27+
mpgsql.c is the bridge. Acting as a wrapper, it's really good,
28+
since i could run mSQL. But it's not accurate. Some highlights:
29+
30+
CONS:
31+
* It's not well documented
32+
(this post is it's first documentation attempt, in fact);
33+
* It doesn't handle field types correctly. I plan to fix it,
34+
if people start doing feedbacks;
35+
* It's limited to 10 simultaneous connections. I plan to enhance
36+
this, i'm just figuring out;
37+
* I'd like to make it reentrant/thread safe, although i don't
38+
think this could be done without changing the API structure;
39+
* Error Management should be better. This is my first priority
40+
now;
41+
* Some calls are just empty implementations.
42+
43+
PROS:
44+
* the mSQL Monitor runs Okay. :]
45+
* It's really cool. :)
46+
* Make mSQL-made applications compatible with postgresql just by
47+
changing link options.
48+
* Uses postgreSQL. :]
49+
* the mSQL API it's far easier to use and understand than libpq.
50+
Consider this example:
51+
52+
#include "msql.h"
53+
54+
void main(int argc, char **argv, char **envp) {
55+
int sid;
56+
57+
sid = msqlConnect(NULL); /* Connects via unix socket */
58+
59+
if (sid >= 0) {
60+
m_result *rlt;
61+
m_row *row;
62+
msqlSelectDB(sid, "hosts");
63+
if (msqlQuery(sid, "select host_id from hosts")) {
64+
rlt = msqlStoreResult();
65+
while (row = (m_row*)msqlFetchRow(rlt))
66+
printf("hostid: %s\n", row[0]);
67+
msqlFreeResult(rlt);
68+
}
69+
msqlClose(sid);
70+
}
71+
}
72+
73+
I enclose mpgsql.c inside. I'd like to maintain it, and (maybe, am
74+
i dreaming) make it as part of the pgsql distribution. I guess it doesn't
75+
depends on me, but mainly on it's acceptance by its users.
76+
77+
Hm... i forgot: you'll need a msql.h copy, since it's copyrighted
78+
by Hughes Technologies Pty Ltd. If you haven't it yes, fetch one
79+
from www.hughes.com.au.
80+
81+
I would like to catch users ideas. My next goal is to add better
82+
error handling, and to make it better documented, and try to let relshow
83+
run through it. :)
84+
85+
done. Aldrin Leal <aldrin@americasnet.com>

contrib/mSQL-interface/mpgsql.c

+275
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
#include <time.h>
2+
#include <string.h>
3+
#include <stdlib.h>
4+
#include "msql.h"
5+
#include "libpq-fe.h"
6+
7+
#define HNDMAX 10
8+
9+
PGconn *PGh[HNDMAX] = {
10+
NULL, NULL, NULL, NULL, NULL,
11+
NULL, NULL, NULL, NULL, NULL
12+
};
13+
14+
#define E_NOHANDLERS 0
15+
16+
char *msqlErrors[] = {
17+
"Out of database handlers."
18+
};
19+
20+
char msqlErrMsg[BUFSIZ], *tfrom = "dunno";
21+
PGresult *queryres = NULL;
22+
23+
int msqlConnect (char *host) {
24+
int count;
25+
26+
for (count = 0; count < HNDMAX; count++)
27+
if (PGh[count] == NULL) break;
28+
29+
if (count == HNDMAX) {
30+
strncpy(msqlErrMsg, msqlErrors[E_NOHANDLERS], BUFSIZ);
31+
return -1;
32+
}
33+
34+
PGh[count] = malloc(sizeof (PGconn));
35+
PGh[count]->pghost = host ? strdup(host) : NULL;
36+
return count;
37+
}
38+
39+
int msqlSelectDB(int handle, char *dbname) {
40+
char *options = calloc(1, BUFSIZ);
41+
char *e = getenv("PG_OPTIONS");
42+
43+
if (e == NULL)
44+
e = "";
45+
46+
if (PGh[handle]->pghost) {
47+
strcat(options, "host=");
48+
strncat(options, PGh[handle]->pghost, BUFSIZ);
49+
strncat(options, " ", BUFSIZ);
50+
free(PGh[handle]->pghost);
51+
PGh[handle]->pghost = NULL;
52+
}
53+
strncat(options, "dbname=", BUFSIZ);
54+
strncat(options, dbname, BUFSIZ);
55+
strncat(options, " ", BUFSIZ);
56+
strncat(options, e, BUFSIZ);
57+
free(PGh[handle]);
58+
PGh[handle] = PQconnectdb(options);
59+
free(options);
60+
strncpy(msqlErrMsg, PQerrorMessage(PGh[handle]), BUFSIZ);
61+
return (PQstatus(PGh[handle]) == CONNECTION_BAD ? -1 : 0);
62+
}
63+
64+
int msqlQuery(int handle, char *query) {
65+
char *tq = strdup(query);
66+
char *p = tq;
67+
PGresult *res;
68+
PGconn *conn = PGh[handle];
69+
ExecStatusType rcode;
70+
71+
res = PQexec(conn, p);
72+
73+
rcode = PQresultStatus(res);
74+
75+
if (rcode == PGRES_TUPLES_OK) {
76+
queryres = res;
77+
return PQntuples(res);
78+
} else if (rcode == PGRES_FATAL_ERROR || rcode == PGRES_NONFATAL_ERROR) {
79+
PQclear(res);
80+
queryres = NULL;
81+
return -1;
82+
} else {
83+
PQclear(res);
84+
queryres = NULL;
85+
return 0;
86+
}
87+
}
88+
89+
int msqlCreateDB (int a, char*b) {
90+
char tbuf[BUFSIZ];
91+
sprintf(tbuf, "create database %s", b);
92+
return msqlQuery(a, tbuf) >= 0 ? 0 : -1;
93+
}
94+
95+
int msqlDropDB (int a, char* b) {
96+
char tbuf[BUFSIZ];
97+
sprintf(tbuf, "drop database %s", b);
98+
return msqlQuery(a, tbuf) >= 0 ? 0 : -1;
99+
}
100+
101+
int msqlShutdown(int a) {
102+
}
103+
104+
int msqlGetProtoInfo(void) {
105+
}
106+
107+
int msqlReloadAcls(int a) {
108+
}
109+
110+
char *msqlGetServerInfo(void) {
111+
}
112+
113+
char *msqlGetHostInfo(void) {
114+
}
115+
116+
char *msqlUnixTimeToDate(time_t date) {
117+
}
118+
119+
char *msqlUnixTimeToTime(time_t time) {
120+
}
121+
122+
void msqlClose(int a) {
123+
PQfinish(PGh[a]);
124+
PGh[a] = NULL;
125+
if (queryres) {
126+
free(queryres);
127+
queryres = NULL;
128+
}
129+
}
130+
131+
void msqlDataSeek(m_result *result, int count) {
132+
int c;
133+
result->cursor = result->queryData;
134+
for (c = 1; c < count; c++)
135+
if (result->cursor->next)
136+
result->cursor = result->cursor->next;
137+
}
138+
139+
void msqlFieldSeek(m_result *result, int count) {
140+
int c;
141+
result->fieldCursor = result->fieldData;
142+
for (c = 1; c < count; c++)
143+
if (result->fieldCursor->next)
144+
result->fieldCursor = result->fieldCursor->next;
145+
}
146+
147+
void msqlFreeResult(m_result *result) {
148+
if (result) {
149+
/* Clears fields */
150+
free(result->fieldData);
151+
result->cursor = result->queryData;
152+
while (result->cursor) {
153+
int c;
154+
m_row m = result->cursor->data;
155+
156+
for (c = 0; m[c]; c++)
157+
free(m[c]);
158+
159+
result->cursor = result->cursor->next;
160+
}
161+
free(result->queryData);
162+
free(result);
163+
}
164+
}
165+
166+
m_row msqlFetchRow(m_result *row) {
167+
m_data *r = row->cursor;
168+
if (r) {
169+
row->cursor = row->cursor->next;
170+
return (m_row)r->data;
171+
}
172+
return (m_row)NULL;
173+
}
174+
175+
m_seq *msqlGetSequenceInfo(int a, char *b) {
176+
}
177+
178+
m_field *msqlFetchField (m_result *mr) {
179+
m_field *m = (m_field*)mr->fieldCursor;
180+
if (m) {
181+
mr->fieldCursor = mr->fieldCursor->next;
182+
return m;
183+
}
184+
return NULL;
185+
}
186+
187+
m_result *msqlListDBs(int a) {
188+
m_result *m;
189+
if (msqlQuery(a, "select datname from pg_database") > 0) {
190+
m = msqlStoreResult();
191+
return m;
192+
} else return NULL;
193+
}
194+
195+
m_result *msqlListTables(int a) {
196+
m_result *m;
197+
char tbuf[BUFSIZ];
198+
199+
sprintf(tbuf, "select relname from pg_class where relkind='r' and relowner=%d", getuid());
200+
if (msqlQuery(a, tbuf) > 0) {
201+
m = msqlStoreResult();
202+
return m;
203+
} else return NULL;
204+
}
205+
206+
m_result *msqlListFields(int a, char *b) {
207+
208+
}
209+
210+
m_result *msqlListIndex(int a, char *b, char *c) {
211+
m_result *m;
212+
char tbuf[BUFSIZ];
213+
214+
sprintf(tbuf, "select relname from pg_class where relkind='i' and relowner=%d", getuid());
215+
if (msqlQuery(a, tbuf) > 0) {
216+
m = msqlStoreResult();
217+
return m;
218+
} else return NULL;
219+
}
220+
221+
m_result *msqlStoreResult(void) {
222+
if (queryres) {
223+
m_result *mr = malloc(sizeof(m_result));
224+
m_fdata *mf;
225+
m_data *md;
226+
int count;
227+
mr->queryData = mr->cursor = NULL;
228+
mr->numRows = PQntuples(queryres);
229+
mr->numFields = PQnfields(queryres);
230+
231+
mf = calloc(PQnfields(queryres), sizeof(m_fdata));
232+
for (count = 0; count < PQnfields(queryres); count++) {
233+
(m_fdata*)(mf+count)->field.name = strdup(PQfname(queryres, count));
234+
(m_fdata*)(mf+count)->field.table = tfrom;
235+
(m_fdata*)(mf+count)->field.type = CHAR_TYPE;
236+
(m_fdata*)(mf+count)->field.length = PQfsize(queryres, count);
237+
(m_fdata*)(mf+count)->next = (m_fdata*)(mf+count+1);
238+
}
239+
(m_fdata*)(mf+count-1)->next = NULL;
240+
241+
md = calloc(PQntuples(queryres), sizeof(m_data));
242+
for (count = 0; count < PQntuples(queryres); count++) {
243+
m_row rows = calloc(PQnfields(queryres)*sizeof(m_row)+1, 1);
244+
int c;
245+
246+
for (c = 0; c < PQnfields(queryres); c++) {
247+
rows[c] = strdup(PQgetvalue(queryres, count, c));
248+
}
249+
(m_data*)(md+count)->data = rows;
250+
251+
(m_data*)(md+count)->width = PQnfields(queryres);
252+
(m_data*)(md+count)->next = (m_data*)(md+count+1);
253+
}
254+
(m_data*)(md+count-1)->next = NULL;
255+
256+
mr->queryData = mr->cursor = md;
257+
mr->fieldCursor = mr->fieldData = mf;
258+
259+
return mr;
260+
} else return NULL;
261+
}
262+
263+
time_t msqlDateToUnixTime(char *a) {
264+
}
265+
266+
time_t msqlTimeToUnixTime(char *b) {
267+
}
268+
269+
char *msql_tmpnam(void) {
270+
return tmpnam("/tmp/msql.XXXXXX");
271+
}
272+
273+
int msqlLoadConfigFile(char *a) {
274+
}
275+

0 commit comments

Comments
 (0)