mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-09 08:10:09 +08:00
b81844b173
tests pass.
366 lines
5.9 KiB
C
366 lines
5.9 KiB
C
#include <time.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include "msql.h"
|
|
#include "libpq-fe.h"
|
|
|
|
#define HNDMAX 10
|
|
|
|
PGconn *PGh[HNDMAX] = {
|
|
NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
#define E_NOHANDLERS 0
|
|
|
|
char *msqlErrors[] = {
|
|
"Out of database handlers."
|
|
};
|
|
|
|
char msqlErrMsg[BUFSIZ],
|
|
*tfrom = "dunno";
|
|
PGresult *queryres = NULL;
|
|
|
|
int
|
|
msqlConnect(char *host)
|
|
{
|
|
int count;
|
|
|
|
for (count = 0; count < HNDMAX; count++)
|
|
if (PGh[count] == NULL)
|
|
break;
|
|
|
|
if (count == HNDMAX)
|
|
{
|
|
strncpy(msqlErrMsg, msqlErrors[E_NOHANDLERS], BUFSIZ);
|
|
return -1;
|
|
}
|
|
|
|
PGh[count] = malloc(sizeof(PGconn));
|
|
PGh[count]->pghost = host ? strdup(host) : NULL;
|
|
return count;
|
|
}
|
|
|
|
int
|
|
msqlSelectDB(int handle, char *dbname)
|
|
{
|
|
char *options = calloc(1, BUFSIZ);
|
|
char *e = getenv("PG_OPTIONS");
|
|
|
|
if (e == NULL)
|
|
e = "";
|
|
|
|
if (PGh[handle]->pghost)
|
|
{
|
|
strcat(options, "host=");
|
|
strncat(options, PGh[handle]->pghost, BUFSIZ);
|
|
strncat(options, " ", BUFSIZ);
|
|
free(PGh[handle]->pghost);
|
|
PGh[handle]->pghost = NULL;
|
|
}
|
|
strncat(options, "dbname=", BUFSIZ);
|
|
strncat(options, dbname, BUFSIZ);
|
|
strncat(options, " ", BUFSIZ);
|
|
strncat(options, e, BUFSIZ);
|
|
free(PGh[handle]);
|
|
PGh[handle] = PQconnectdb(options);
|
|
free(options);
|
|
strncpy(msqlErrMsg, PQerrorMessage(PGh[handle]), BUFSIZ);
|
|
return (PQstatus(PGh[handle]) == CONNECTION_BAD ? -1 : 0);
|
|
}
|
|
|
|
int
|
|
msqlQuery(int handle, char *query)
|
|
{
|
|
char *tq = strdup(query);
|
|
char *p = tq;
|
|
PGresult *res;
|
|
PGconn *conn = PGh[handle];
|
|
ExecStatusType rcode;
|
|
|
|
res = PQexec(conn, p);
|
|
|
|
rcode = PQresultStatus(res);
|
|
|
|
if (rcode == PGRES_TUPLES_OK)
|
|
{
|
|
queryres = res;
|
|
return PQntuples(res);
|
|
}
|
|
else if (rcode == PGRES_FATAL_ERROR || rcode == PGRES_NONFATAL_ERROR)
|
|
{
|
|
PQclear(res);
|
|
queryres = NULL;
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
PQclear(res);
|
|
queryres = NULL;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int
|
|
msqlCreateDB(int a, char *b)
|
|
{
|
|
char tbuf[BUFSIZ];
|
|
|
|
sprintf(tbuf, "create database %s", b);
|
|
return msqlQuery(a, tbuf) >= 0 ? 0 : -1;
|
|
}
|
|
|
|
int
|
|
msqlDropDB(int a, char *b)
|
|
{
|
|
char tbuf[BUFSIZ];
|
|
|
|
sprintf(tbuf, "drop database %s", b);
|
|
return msqlQuery(a, tbuf) >= 0 ? 0 : -1;
|
|
}
|
|
|
|
int
|
|
msqlShutdown(int a)
|
|
{
|
|
}
|
|
|
|
int
|
|
msqlGetProtoInfo(void)
|
|
{
|
|
}
|
|
|
|
int
|
|
msqlReloadAcls(int a)
|
|
{
|
|
}
|
|
|
|
char *
|
|
msqlGetServerInfo(void)
|
|
{
|
|
}
|
|
|
|
char *
|
|
msqlGetHostInfo(void)
|
|
{
|
|
}
|
|
|
|
char *
|
|
msqlUnixTimeToDate(time_t date)
|
|
{
|
|
}
|
|
|
|
char *
|
|
msqlUnixTimeToTime(time_t time)
|
|
{
|
|
}
|
|
|
|
void
|
|
msqlClose(int a)
|
|
{
|
|
PQfinish(PGh[a]);
|
|
PGh[a] = NULL;
|
|
if (queryres)
|
|
{
|
|
free(queryres);
|
|
queryres = NULL;
|
|
}
|
|
}
|
|
|
|
void
|
|
msqlDataSeek(m_result * result, int count)
|
|
{
|
|
int c;
|
|
|
|
result->cursor = result->queryData;
|
|
for (c = 1; c < count; c++)
|
|
if (result->cursor->next)
|
|
result->cursor = result->cursor->next;
|
|
}
|
|
|
|
void
|
|
msqlFieldSeek(m_result * result, int count)
|
|
{
|
|
int c;
|
|
|
|
result->fieldCursor = result->fieldData;
|
|
for (c = 1; c < count; c++)
|
|
if (result->fieldCursor->next)
|
|
result->fieldCursor = result->fieldCursor->next;
|
|
}
|
|
|
|
void
|
|
msqlFreeResult(m_result * result)
|
|
{
|
|
if (result)
|
|
{
|
|
/* Clears fields */
|
|
free(result->fieldData);
|
|
result->cursor = result->queryData;
|
|
while (result->cursor)
|
|
{
|
|
int c;
|
|
m_row m = result->cursor->data;
|
|
|
|
for (c = 0; m[c]; c++)
|
|
free(m[c]);
|
|
|
|
result->cursor = result->cursor->next;
|
|
}
|
|
free(result->queryData);
|
|
free(result);
|
|
}
|
|
}
|
|
|
|
m_row
|
|
msqlFetchRow(m_result * row)
|
|
{
|
|
m_data *r = row->cursor;
|
|
|
|
if (r)
|
|
{
|
|
row->cursor = row->cursor->next;
|
|
return (m_row) r->data;
|
|
}
|
|
return (m_row) NULL;
|
|
}
|
|
|
|
m_seq *
|
|
msqlGetSequenceInfo(int a, char *b)
|
|
{
|
|
}
|
|
|
|
m_field *
|
|
msqlFetchField(m_result * mr)
|
|
{
|
|
m_field *m = (m_field *) mr->fieldCursor;
|
|
|
|
if (m)
|
|
{
|
|
mr->fieldCursor = mr->fieldCursor->next;
|
|
return m;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
m_result *
|
|
msqlListDBs(int a)
|
|
{
|
|
m_result *m;
|
|
|
|
if (msqlQuery(a, "select datname from pg_database") > 0)
|
|
{
|
|
m = msqlStoreResult();
|
|
return m;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
m_result *
|
|
msqlListTables(int a)
|
|
{
|
|
m_result *m;
|
|
char tbuf[BUFSIZ];
|
|
|
|
sprintf(tbuf, "select relname from pg_class where relkind='r' and relowner=%d", getuid());
|
|
if (msqlQuery(a, tbuf) > 0)
|
|
{
|
|
m = msqlStoreResult();
|
|
return m;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
m_result *
|
|
msqlListFields(int a, char *b)
|
|
{
|
|
|
|
}
|
|
|
|
m_result *
|
|
msqlListIndex(int a, char *b, char *c)
|
|
{
|
|
m_result *m;
|
|
char tbuf[BUFSIZ];
|
|
|
|
sprintf(tbuf, "select relname from pg_class where relkind='i' and relowner=%d", getuid());
|
|
if (msqlQuery(a, tbuf) > 0)
|
|
{
|
|
m = msqlStoreResult();
|
|
return m;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
m_result *
|
|
msqlStoreResult(void)
|
|
{
|
|
if (queryres)
|
|
{
|
|
m_result *mr = malloc(sizeof(m_result));
|
|
m_fdata *mf;
|
|
m_data *md;
|
|
int count;
|
|
|
|
mr->queryData = mr->cursor = NULL;
|
|
mr->numRows = PQntuples(queryres);
|
|
mr->numFields = PQnfields(queryres);
|
|
|
|
mf = calloc(PQnfields(queryres), sizeof(m_fdata));
|
|
for (count = 0; count < PQnfields(queryres); count++)
|
|
{
|
|
(m_fdata *) (mf + count)->field.name = strdup(PQfname(queryres, count));
|
|
(m_fdata *) (mf + count)->field.table = tfrom;
|
|
(m_fdata *) (mf + count)->field.type = CHAR_TYPE;
|
|
(m_fdata *) (mf + count)->field.length = PQfsize(queryres, count);
|
|
(m_fdata *) (mf + count)->next = (m_fdata *) (mf + count + 1);
|
|
}
|
|
(m_fdata *) (mf + count - 1)->next = NULL;
|
|
|
|
md = calloc(PQntuples(queryres), sizeof(m_data));
|
|
for (count = 0; count < PQntuples(queryres); count++)
|
|
{
|
|
m_row rows = calloc(PQnfields(queryres) * sizeof(m_row) + 1, 1);
|
|
int c;
|
|
|
|
for (c = 0; c < PQnfields(queryres); c++)
|
|
rows[c] = strdup(PQgetvalue(queryres, count, c));
|
|
(m_data *) (md + count)->data = rows;
|
|
|
|
(m_data *) (md + count)->width = PQnfields(queryres);
|
|
(m_data *) (md + count)->next = (m_data *) (md + count + 1);
|
|
}
|
|
(m_data *) (md + count - 1)->next = NULL;
|
|
|
|
mr->queryData = mr->cursor = md;
|
|
mr->fieldCursor = mr->fieldData = mf;
|
|
|
|
return mr;
|
|
}
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
time_t
|
|
msqlDateToUnixTime(char *a)
|
|
{
|
|
}
|
|
|
|
time_t
|
|
msqlTimeToUnixTime(char *b)
|
|
{
|
|
}
|
|
|
|
char *
|
|
msql_tmpnam(void)
|
|
{
|
|
return tmpnam("/tmp/msql.XXXXXX");
|
|
}
|
|
|
|
int
|
|
msqlLoadConfigFile(char *a)
|
|
{
|
|
}
|