[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