[Info-vax] VMS databases
Arne Vajhøj
arne at vajhoej.dk
Sun Nov 19 11:50:55 EST 2023
On 11/19/2023 4:47 AM, Neil Rieck wrote:
> On Saturday, November 18, 2023 at 6:47:22 PM UTC-5, Arne Vajhøj wrote:
>> On 11/18/2023 9:22 AM, Arne Vajhøj wrote:
>>> VMS Basic is as it is and the libmysql API is what it is and
>>> any solution is constrained by that.
>>>
>>> I do not have any magic solution for the problem. I would
>>> probably have made the API differently (but differently does
>>> not necessarily mean better).
>> I could not resist trying.
>>
>> This is first attempt. But I think it is a relative clean API.
> Could you post the included code: "b.bas"
B.BAS is not so interesting:
external integer function bmysql_open(string, integer, string, string,
string)
external integer function bmysql_stmt_prepare(integer, string)
external integer function bmysql_outparam_init(integer)
external integer function bmysql_inparam_init(integer)
external sub bmysql_outparam_integer(integer, integer, integer)
external sub bmysql_inparam_integer(integer, integer, integer)
external sub bmysql_outparam_string(integer, integer, string)
external sub bmysql_inparam_string(integer, integer, string)
external sub bmysql_stmt_execute(integer, integer, integer)
external integer function bmysql_stmt_fetch(integer, integer)
external sub bmysql_outparam_free(integer)
external sub bmysql_inparam_free(integer)
external sub bmysql_stmt_free(integer)
external sub bmysql_close(integer)
B2C.C has the interesting stuff:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <descrip.h>
#include <lib$routines.h>
#define SOCKET int
#include <mysql.h>
#define MAX_LEN 32000
struct b_param
{
int n;
struct dsc$descriptor_d **bstr;
MYSQL_BIND *bind;
};
static char *cstr(struct dsc$descriptor_d *s)
{
char *s2 = malloc(s->dsc$w_length + 1);
memcpy(s2, s->dsc$a_pointer, s->dsc$w_length);
s2[s->dsc$w_length] = 0;
return s2;
}
static void bstr(char *buf, int buflen, struct dsc$descriptor_d *d)
{
lib$sget1_dd(&buflen, d);
d->dsc$b_dtype = DSC$K_DTYPE_T;
memcpy(d->dsc$a_pointer, buf, buflen);
}
static MYSQL *realcon(int *con)
{
return (MYSQL *)(*con);
}
static MYSQL_STMT *realstmt(int *stmt)
{
return (MYSQL_STMT *)(*stmt);
}
static struct b_param *realparam(int *param)
{
return (struct b_param *)(*param);
}
int BMYSQL_OPEN(struct dsc$descriptor_d *host,
int *port,
struct dsc$descriptor_d *usr,
struct dsc$descriptor_d *pwd,
struct dsc$descriptor_d *db)
{
char *host2 = cstr(host);
char *usr2 = cstr(usr);
char *pwd2 = cstr(pwd);
char *db2 = cstr(db);
MYSQL *con = mysql_init(NULL);
con = mysql_real_connect(con, host2, usr2, pwd2, db2, *port, NULL, 0);
free(host2);
free(usr2);
free(pwd2);
free(db2);
return (int)con;
}
int BMYSQL_STMT_PREPARE(int *con, struct dsc$descriptor_d *sql)
{
char *sql2 = cstr(sql);
MYSQL_STMT *stmt = mysql_stmt_init(realcon(con));
int stat = mysql_stmt_prepare(stmt, sql2, strlen(sql2));
if(stat != 0) printf("mysql_stmt_prepare error : %s\n",
mysql_error(realcon(con)));
free(sql2);
return (int)stmt;
}
int BMYSQL_OUTPARAM_INIT(int *nparam)
{
struct b_param *p = malloc(sizeof(struct b_param));
p->n = *nparam;
p->bstr = malloc(*nparam * sizeof(struct dsc$descriptor_d));
p->bind = malloc(*nparam * sizeof(MYSQL_BIND));
return (int)p;
}
int BMYSQL_INPARAM_INIT(int *nparam)
{
struct b_param *p = malloc(sizeof(struct b_param));
p->n = *nparam;
p->bstr = NULL;
p->bind = malloc(*nparam * sizeof(MYSQL_BIND));
return (int)p;
}
void BMYSQL_OUTPARAM_INTEGER(int *param, int *ix, int *val)
{
struct b_param *p = realparam(param);
p->bstr[*ix] = NULL;
memset(&p->bind[*ix], 0, sizeof(MYSQL_BIND));
p->bind[*ix].buffer_type = MYSQL_TYPE_LONG;
p->bind[*ix].buffer = (char *)val;
p->bind[*ix].buffer_length = sizeof(int);
}
void BMYSQL_INPARAM_INTEGER(int *param, int *ix, int *val)
{
struct b_param *p = realparam(param);
memset(&p->bind[*ix], 0, sizeof(MYSQL_BIND));
p->bind[*ix].buffer_type = MYSQL_TYPE_LONG;
p->bind[*ix].buffer = (char *)val;
p->bind[*ix].buffer_length = sizeof(int);
}
void BMYSQL_OUTPARAM_STRING(int *param, int *ix, struct dsc$descriptor_d
*val)
{
struct b_param *p = realparam(param);
memset(&p->bind[*ix], 0, sizeof(MYSQL_BIND));
p->bstr[*ix] = val;
p->bind[*ix].buffer_type = MYSQL_TYPE_STRING;
p->bind[*ix].buffer = malloc(MAX_LEN);
p->bind[*ix].buffer_length = MAX_LEN;
p->bind[*ix].length = (unsigned long *)malloc(sizeof(unsigned long));
}
void BMYSQL_INPARAM_STRING(int *param, int *ix, struct dsc$descriptor_d
*val)
{
struct b_param *p = realparam(param);
memset(&p->bind[*ix], 0, sizeof(MYSQL_BIND));
p->bind[*ix].buffer_type = MYSQL_TYPE_STRING;
p->bind[*ix].buffer = val->dsc$a_pointer;
p->bind[*ix].buffer_length = val->dsc$w_length;
}
void BMYSQL_STMT_EXECUTE(int *stmt, int *inparam, int *outparam)
{
int stat;
struct b_param *pin = realparam(inparam);
struct b_param *pout = realparam(outparam);
if(*inparam != 0)
{
stat = mysql_stmt_bind_param(realstmt(stmt), pin->bind);
if(stat != 0) printf("mysql_stmt_bind_param error : %s\n",
mysql_stmt_error(realstmt(stmt)));
}
stat = mysql_stmt_execute(realstmt(stmt));
if(stat != 0) printf("mysql_stmt_execute error : %s\n",
mysql_stmt_error(realstmt(stmt)));
if(*outparam != 0)
{
stat = mysql_stmt_bind_result(realstmt(stmt), pout->bind);
if(stat != 0) printf("mysql_stmt_bind_result error : %s\n",
mysql_stmt_error(realstmt(stmt)));
}
stat = mysql_stmt_store_result(realstmt(stmt));
if(stat != 0) printf("mysql_stmt_store_result error : %s\n",
mysql_stmt_error(realstmt(stmt)));
}
int BMYSQL_STMT_FETCH(int *stmt, int *param)
{
struct b_param *p = realparam(param);
int stat = mysql_stmt_fetch(realstmt(stmt));
for(int i = 0; i < p->n; i++)
{
if(p->bind[i].buffer_type == MYSQL_TYPE_STRING)
{
char *buf = (char *)p->bind[i].buffer;
int buflen = (int)*(p->bind[i].length);
bstr(buf, buflen, p->bstr[i]);
}
}
return stat;
}
void BMYSQL_OUTPARAM_FREE(int *param)
{
struct b_param *p = realparam(param);
for(int i = 0; i < p->n; i++)
{
if(p->bind[i].buffer_type == MYSQL_TYPE_STRING)
{
free(p->bind[i].buffer);
free(p->bind[i].length);
}
}
free(p->bind);
free(p->bstr);
free(p);
}
void BMYSQL_INPARAM_FREE(int *param)
{
struct b_param *p = realparam(param);
free(p->bind);
free(p);
}
void BMYSQL_STMT_FREE(int *stmt)
{
mysql_stmt_free_result(realstmt(stmt));
}
void BMYSQL_CLOSE(int *con)
{
mysql_close(realcon(con));
}
Arne
More information about the Info-vax
mailing list