home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / www / ncsa / tools / gsql / sybproc.c.Z / sybproc.c
Encoding:
C/C++ Source or Header  |  1994-06-26  |  6.7 KB  |  293 lines

  1. /* --------------------------------
  2. Sample database backend program function
  3. This works for Sybase.
  4.  
  5. Jason Ng NCSA Dec 1993 likkai@ncsa.uiuc.edu
  6.  
  7. * ------------------------------------- */
  8. #include <sybfront.h>
  9. #include <sybdb.h>
  10. #include <syberror.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13.  
  14. static DBPROCESS  *dbproc;
  15.  
  16. /*
  17. / procedure:  msg_handler
  18. / desc:       This procedure handles any messages from sybase.  It stores
  19. /             the messages in sbymsg so that the error handler
  20. /             (err_handler) can check for certain errors.
  21. */
  22.  
  23. #define MAXMSG 500
  24.  
  25. static int nmsg = 0;
  26. static char *mymsg[MAXMSG];
  27. int msg_handler(dbproc,msgno,msgstate,severity,msgtext,srvname,procname,line)
  28.  
  29. DBPROCESS    *dbproc;
  30. DBINT         msgno;
  31. int           msgstate, severity;
  32. char         *msgtext, *srvname, *procname;
  33. DBUSMALLINT  line;
  34.  
  35. {
  36.       if (1)
  37.      {
  38.           /***
  39.            printf("Message:\n%s\n",msgtext); fflush(stdout);
  40.           ***/
  41.           mymsg[nmsg] =  (char*) strdup(msgtext);
  42.           nmsg++; if(nmsg>=MAXMSG-1) nmsg=0; 
  43.          return(0);
  44.       }
  45. }
  46.  
  47. dumpmessages()
  48. {
  49.   int i;
  50.   for(i=0;i<nmsg;i++) printf(" Message: %s \n", mymsg[i]);
  51. }
  52.  
  53. /*
  54. / procedure:  err_handler
  55. / returns:    INT_EXIT if Sybase process died or else INT_CANCEL
  56. / desc:       This procedure is called if Sybase returns an error
  57. /             while processing data.  If an error occurs and Sybase
  58. /             sends the message:"Unclosed quote before the
  59. /             character string ')'." then assume a " was placed in
  60. /             the data field.  In this case, call correct_error
  61. /             to try and correct the error.
  62. */
  63.  
  64. int err_handler(dbproc, severity, dberr, oserr, dberrstr, oserrstr)
  65.  
  66. DBPROCESS *dbproc;
  67. int        severity, dberr, oserr;
  68. char      *dberrstr, *oserrstr;
  69.  
  70. {
  71.       if ((dbproc == NULL) || (DBDEAD(dbproc)))
  72.           return(INT_EXIT);
  73.      else
  74.      {
  75.           printf("DB-Library error:\n%s\n", dberrstr); fflush(stdout);
  76.  
  77.           if (oserr != DBNOERR)
  78.                printf("Operating system error:\n%s\n", oserrstr);
  79.  
  80.              dumpmessages();
  81.           return(INT_CANCEL);
  82.      } 
  83. }
  84.  
  85. /*
  86. / procedure:  init_sybase
  87. / desc:       This procedure initializes the connection to Sybase
  88. /             and sets up a db process.  If errors occur at this
  89. /             point the program will exit.
  90. */
  91.  
  92. void init_sybase(char* login, char* passwd)
  93.  
  94. {
  95.      LOGINREC   *glblogin;
  96.       if (dbinit() == FAIL)
  97.      {
  98.           printf("Error initializing db - aborting program\n");
  99.           exit(ERREXIT);
  100.       }
  101.  
  102.     dberrhandle(err_handler);
  103.     dbmsghandle(msg_handler);
  104.  
  105.    if ((glblogin = dblogin()) == NULL)
  106.    {
  107.           printf("Error allocating login struct - aborting program\n");
  108.             exit(ERREXIT);
  109.     }
  110.  
  111.      DBSETLUSER(glblogin, login);
  112.     DBSETLPWD(glblogin, passwd);
  113.      DBSETLAPP(glblogin, "import");
  114.  
  115.  
  116.      if ((dbproc = dbopen(glblogin, NULL)) == NULL)
  117.      {
  118.           printf("Error getting a DBPROCESS struct - aborting program\n");
  119.           exit(ERREXIT);
  120.      }
  121. }
  122.  
  123. /*================================================================== */
  124.  
  125. /* This is the program that you (the SQL programmer) get to write */
  126.  
  127. #define MAXITEMS 200
  128. int execute_sql (char *sqlstring) /* sybase */
  129.  
  130. {
  131.     char *bindvals[MAXITEMS];
  132.     int width[MAXITEMS]; /* for output formatting */
  133.     int ndisplayitems;
  134.     int i,j,k,t,  return_code;
  135.     char *ss;
  136.     char * app_getdefine();
  137.  
  138.  
  139. # define MARGIN 2
  140. # define BUFSIZE 1000  /* malloc size - must be big, and >> STRSIZE */
  141. # define STRSIZE 80   /* this is just for output to screen */
  142. # define LONGSTRSIZE 300  /* threshold when it should be treated as long text */
  143.     
  144.      putenv((char*) app_getdefine("SYBASE_ENV"));
  145.     init_sybase((char*) app_getdefine("LOGIN"), (char*) app_getdefine("PASSWORD"));
  146.  
  147.  
  148.      dbcmd(dbproc, sqlstring); /* send the SQL query to sybase */
  149.  
  150.      dbsqlexec(dbproc);
  151.  
  152.      printf("<P><H2> OK.. RESULTS: </H2><P>" );
  153.      /* printf("<PLAINTEXT>");  */
  154.      printf("<PRE>"); 
  155.  
  156.  
  157.      /* --- now print out all the records --- */
  158.      while ((return_code = dbresults(dbproc)) != NO_MORE_RESULTS)
  159.      {
  160.         if (return_code == SUCCEED)
  161.         {
  162.           ndisplayitems = (int) dbnumcols(dbproc);
  163.           /*  printf("<li> found  %d cols <p>\n", ndisplayitems);  */
  164.           if(ndisplayitems > MAXITEMS) ndisplayitems = MAXITEMS;
  165.           for(i=0;i<ndisplayitems;i++) { width[i] = STRSIZE; }
  166.  
  167.             for(i=0;i<ndisplayitems;i++) {
  168.                t = dbcollen(dbproc,i+1); 
  169.                 if (t > BUFSIZE+5)
  170.                   bindvals[i] = (char*) malloc(t);
  171.                else 
  172.                     bindvals[i] = (char*) malloc(BUFSIZE+5);
  173.                 }
  174.  
  175.             for(i=0;i<ndisplayitems;i++) 
  176.                dbbind(dbproc, i+1, STRINGBIND, (DBINT) 0, bindvals[i]);
  177.  
  178.  
  179.             /* ================================== */
  180.  
  181.          /* buffer them up */
  182.             initsaveoutput (ndisplayitems);
  183.             while (dbnextrow(dbproc) != NO_MORE_ROWS) {
  184.                 saveoutput(bindvals);
  185.                 }
  186.          displayoutput();
  187.  
  188.             /* ================================== */
  189.  
  190.  
  191.             for(i=0;i<ndisplayitems;i++) free(bindvals[i]);
  192.         }
  193.     }
  194.     dbclose(dbproc);
  195.  
  196.      printf("</PRE>"); 
  197.  
  198. }
  199.  
  200. formatlongtext (text) char * text;
  201. {
  202.  
  203.   printf("</PRE>"); 
  204.   printf("\n%s\n", text);
  205.   printf("<PRE>"); 
  206.  
  207. }
  208.  
  209. showimage() {
  210.   int i = rand() %3;
  211.  
  212.   printf("<IMG SRC=http://www/SDG/People/jason/pub/color%d.gif>",i);
  213.   fflush(stdout);
  214. }
  215.  
  216. /* ------------------------------------------------------------------ */
  217. struct o_store_struct { char **text;  struct o_store_struct *next; };
  218. typedef struct o_store_struct O_STORE; 
  219. static O_STORE *o_head  = NULL;
  220. static O_STORE * o_tail = NULL;
  221. static int o_nitems = 0;
  222. static int o_nrows = 0;
  223. static int * o_maxlen = NULL;
  224. static int o_count = 0;
  225.  
  226. initsaveoutput (num_items) int num_items;
  227. {
  228.   int i;
  229.   o_nitems =  num_items;
  230.   o_maxlen = (int*) malloc(sizeof(int) * o_nitems);
  231.   for(i=0;i<o_nitems;i++) o_maxlen[i] = 0;
  232. }
  233.  
  234. saveoutput( bvals) char *bvals[];
  235. {
  236.   int i, slen;
  237.   O_STORE * o;
  238.  
  239.  
  240.   o = (O_STORE *) malloc(sizeof(O_STORE));
  241.   o->next = NULL;
  242.   o->text = (char**) malloc(sizeof(char *) * o_nitems);
  243.   for(i=0;i<o_nitems;i++) {
  244.       /* trimblanks(bvals[i]); */
  245.       slen = strlen(bvals[i]);
  246.       if (slen > o_maxlen[i]) o_maxlen[i] = slen;
  247.       o->text[i] = strdup(bvals[i]);
  248.       }
  249.    o_count++;
  250.  
  251.   if (o_tail) {
  252.      o_tail->next  = o;  
  253.      o_tail  = o;  
  254.       }
  255.   else  {
  256.       o_head = o;
  257.       o_tail = o;
  258.       }
  259.  
  260. }
  261. trimblanks(ss) char *ss;
  262. {
  263.    int i,n;
  264.     n = strlen(ss);
  265.    for(i=n-1;i>=0;i--)
  266.       if(ss[i] != ' ') { ss[i+1] = '\0'; return; }
  267. }
  268.  
  269. displayoutput() 
  270. {
  271.      int i;
  272.      O_STORE *o = o_head ;
  273.  
  274.     /* --- first print the titles of fields */
  275.     printf("</PRE>");
  276.      for(i=0;i<o_nitems; i++)
  277.           printf("<b> %3d </b> %s    ", i+1, dbcolname(dbproc, i+1));
  278.     printf("<PRE>\n\n\n");
  279.               
  280.      /* --- then print all the query results */
  281.     while(o!= NULL) {
  282.         for(i=0;i<o_nitems;i++) {
  283.             if (o_maxlen[i] >LONGSTRSIZE)   /* long text here */
  284.                 formatlongtext(o->text[i]);
  285.              else
  286.             printf("%-*.*s", o_maxlen[i]+MARGIN, o_maxlen[i], o->text[i]); 
  287.              }
  288.          printf("\n");
  289.        o = o->next;
  290.         }
  291. }
  292.  
  293.