diff options
Diffstat (limited to 'Modules/sybasemodule.c')
-rw-r--r-- | Modules/sybasemodule.c | 309 |
1 files changed, 309 insertions, 0 deletions
diff --git a/Modules/sybasemodule.c b/Modules/sybasemodule.c new file mode 100644 index 0000000..860203f --- /dev/null +++ b/Modules/sybasemodule.c @@ -0,0 +1,309 @@ +/* +Subject: Re: Sybase module -- input sought +From: jredford@lehman.com +To: ags@uncompaghre.informatics.jax.org (Alexander G. Smith) +Cc: python-list@cwi.nl +Date: Tue, 10 May 94 11:53:13 -0400 + + +input sought? how about a complete module? :) + +This is a fairly incomplete work.. but I have done things dramatically +differently than sybperl would. Given the nature of the language I +find it is easier to simply get ALL results & then muck with the rows +later as parts of the data. This is a subset of the functionality of a +Modula-3 interface to Sybase that I wrote.. I could send you that if +you are interested in a more complete picture. +*/ + +#include <stdio.h> + +#include <sybfront.h> +#include <sybdb.h> + +#include "allobjects.h" +#include "modsupport.h" + + +static object *SybaseError; /* exception sybase.error */ + + +typedef struct { + OB_HEAD + LOGINREC *login; /* login record */ + DBPROCESS *dbproc; /* login record */ +} sybdbobject; + +extern typeobject SybDbtype; /* Forward */ + + +static sybdbobject * + newsybdbobject(char *user, char *passwd, char *server) +{ + sybdbobject *s; + + s = NEWOBJ(sybdbobject, &SybDbtype); + if (s != NULL) { + s->login = dblogin(); + if (user) { + (void)DBSETLUSER(s->login, user); + } + if (passwd) { + (void)DBSETLPWD(s->login, passwd); + } + if(!(s->dbproc = dbopen(s->login, server))) { + dbloginfree(s->login); + DEL(s); + return (NULL); + } + } + return s; +} + +/* OBJECT FUNCTIONS: sybdb */ + +/* Common code for returning pending results */ +static object + *getresults (DBPROCESS *dbp) +{ + object *results; + object *list; + object *tuple; + object *o; + int retcode; + int cols; + int *fmt; + int i; + + results = newlistobject(0); + while ((retcode = dbresults(dbp)) != NO_MORE_RESULTS) { + if (retcode == SUCCEED && DBROWS(dbp) == SUCCEED) { + list = newlistobject(0); + cols = dbnumcols(dbp); + fmt = (int *)malloc(sizeof(int) * cols); + for (i = 1; i <= cols; i++) { + switch(dbcoltype(dbp, i)) { + case SYBCHAR: + fmt[i-1] = SYBCHAR; + break; + case SYBINT1: + fmt[i-1] = SYBINT1; + break; + case SYBINT2: + fmt[i-1] = SYBINT2; + break; + case SYBINT4: + fmt[i-1] = SYBINT4; + break; + case SYBFLT8: + fmt[i-1] = SYBFLT8; + break; + } + } + while (dbnextrow(dbp) != NO_MORE_ROWS) { + tuple = newtupleobject(cols); + for (i = 1; i <= cols; i++) { + switch(fmt[i-1]) { + case SYBCHAR: + o = newsizedstringobject((char *)dbdata(dbp, i), dbdatlen(dbp, i)); + settupleitem(tuple, i-1, o); + break; + case SYBINT1: + o = newintobject(*((char *)dbdata(dbp, i))); + settupleitem(tuple, i-1, o); + break; + case SYBINT2: + o = newintobject(*((short *)dbdata(dbp, i))); + settupleitem(tuple, i-1, o); + break; + case SYBINT4: + o = newintobject(*((int *)dbdata(dbp, i))); + settupleitem(tuple, i-1, o); + break; + case SYBFLT8: + o = newfloatobject(*((double *)dbdata(dbp, i))); + settupleitem(tuple, i-1, o); + break; + } + } + addlistitem(list,tuple); + } + free(fmt); + addlistitem(results,list); + } + } + return (results); +} + +static object + *sybdb_sql (self, args) +object *self; +object *args; +{ + char *sql; + DBPROCESS *dbp; + + dbp = ((sybdbobject *)self)->dbproc; + err_clear (); + if (!getargs (args, "s", &sql)) { + return NULL; + } + dbcancel(dbp); + dbcmd(dbp, sql); + dbsqlexec(dbp); + return getresults(dbp); +} + +static object + *sybdb_sp (self, args) +object *self; +object *args; +{ + char *sp; + DBPROCESS *dbp; + object *spargs; + object *sparg; + object *results; + object *r; + int spargcnt; + int i; + int retstatus; + + dbp = ((sybdbobject *)self)->dbproc; + err_clear (); + if (!getargs (args, "(sO)", &sp, &spargs)) { + return NULL; + } + + dbcancel(dbp); + dbrpcinit(dbp, sp, 0); + + if (is_tupleobject(spargs)) { + spargcnt=gettuplesize(spargs); + for (i=0; i < spargcnt; i++) { + sparg = gettupleitem(spargs,i); + if (is_intobject(sparg)) { + int i; + i = getintvalue(sparg); + dbrpcparam(dbp, NULL, 0, SYBINT4, -1, -1, &i); + } else if (is_floatobject(sparg)) { + double i; + i = getfloatvalue(sparg); + dbrpcparam(dbp, NULL, 0, SYBFLT8, -1, -1, &i); + } else if (is_stringobject(sparg)) { + dbrpcparam(dbp, NULL, 0, SYBCHAR, -1, getstringsize(sparg), getstringvalue(sparg)); + } else { + err_setstr (SybaseError, "Could not handle paramaters to procedure."); + return NULL; + } + } + } else if (spargs != None) { + err_setstr (SybaseError, "Could not handle paramaters to procedure."); + return NULL; + } + dbrpcsend(dbp); + dbsqlok(dbp); + + results = getresults(dbp); + retstatus = dbretstatus(dbp); + + r = mkvalue("(iO)", retstatus, results); + DECREF(results); + return (r); +} + + +static struct methodlist sybdb_methods[] = { + {"sql", sybdb_sql}, + {"sp", sybdb_sp}, + {NULL, NULL} /* sentinel */ +}; + +static void +sybdb_dealloc(s) + sybdbobject *s; +{ + dbloginfree(s->login); + dbclose(s->dbproc); + DEL(s); +} + +static object * +sybdb_getattr(s, name) + sybdbobject *s; + char *name; +{ + return findmethod(sybdb_methods, (object *) s, name); +} + + +typeobject SybDbtype = { + OB_HEAD_INIT(&Typetype) + 0, + "sybdb", + sizeof(sybdbobject), + 0, + sybdb_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + sybdb_getattr, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ +}; + + + + + +/* MODULE FUNCTIONS: sybase */ + +static object + *sybase_new (self, args) +object *self; /* Not used */ +object *args; +{ + char *user, *passwd, *server; + object *db; + + err_clear (); + if (!getargs (args, "(zzz)", &user, &passwd, &server)) { + return NULL; + } + db = (object *) newsybdbobject(user, passwd, server); + if (!db) { + /* XXX Should be setting some errstr stuff here based on sybase errors */ + err_setstr (SybaseError, "Could not open connection to server."); + return NULL; + } + return db; +} + + +/* List of module functions */ +static struct methodlist sybase_methods[]= +{ + {"new", sybase_new}, + {NULL, NULL} /* sentinel */ +}; + +/* Module initialisation */ +void initsybase () +{ + object *m, *d; + + /* Create the module and add the functions */ + m = initmodule ("sybase", sybase_methods); + /* Add some symbolic constants to the module */ + d = getmoduledict (m); + SybaseError = newstringobject ("sybase.error"); + if (SybaseError == NULL || dictinsert (d, "error", SybaseError) != 0) { + fatal ("can't define sybase.error"); + } + /* Check for errors */ + if (err_occurred ()){ + fatal ("can't initialize module sybase"); + } +} |