home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / oraperl-v2 / part03 / orafns.c < prev   
Encoding:
C/C++ Source or Header  |  1992-07-06  |  23.1 KB  |  1,016 lines

  1. /* orafns.c
  2.  *
  3.  * Simple C interface to Oracle, intended to be linked to Perl.
  4.  */
  5. /* Copyright 1991, 1992 Kevin Stock.
  6.  *
  7.  * You may copy this under the terms of the GNU General Public License,
  8.  * or the Artistic License, copies of which should have accompanied your
  9.  * Perl kit.
  10.  */
  11.  
  12. #include    "INTERN.h"
  13. #include    <stdio.h>
  14. #include    <ctype.h>
  15. #include    "orafns.h"
  16. #include    "patchlevel.h"
  17.  
  18.  
  19. /* address[] is used to return cursor addresses to the perl program
  20.  * it is used so that we can get the addresses exactly right, without
  21.  * worrying about rounding errors or playing with oracle.mus
  22.  */
  23.  
  24. char    address[20];
  25.  
  26.  
  27. #ifdef    DEBUGGING
  28.     /* table of known ORACLE datatypes */
  29.  
  30.     char    *types[] =
  31.     {
  32.     /* 00 */    NULL,
  33.     /* 01 */    "character array",
  34.     /* 02 */    "number",
  35.     /* 03 */    "signed integer",
  36.     /* 04 */    "float",
  37.     /* 05 */    "null terminated string",
  38.     /* 06 */    NULL,
  39.     /* 07 */    "packed decimal",
  40.     /* 08 */    "long string",
  41.     /* 09 */    "varchar",
  42.     /* 10 */    NULL,
  43.     /* 11 */    "rowid",
  44.     /* 12 */    "date",
  45.     /* 13 */    NULL,
  46.     /* 14 */    NULL,
  47.     /* 15 */    "varraw",
  48.     /* 16 */    NULL,
  49.     /* 17 */    NULL,
  50.     /* 18 */    NULL,
  51.     /* 19 */    NULL,
  52.     /* 20 */    NULL,
  53.     /* 21 */    NULL,
  54.     /* 22 */    NULL,
  55.     /* 23 */    "raw",
  56.     /* 24 */    "long raw",
  57.     };
  58. #endif    /* DEBUGGING */
  59.  
  60. /* oracle_sid is just used so that we don't keep repeating the string */
  61.  
  62. static char *oracle_sid        = "ORACLE_SID";
  63.  
  64.  
  65. /* set_sid() uses my_setenv() to set ORACLE_SID to the required database.
  66.  * It preserves the old value of ORACLE_SID so that it can be restored
  67.  * (by calling set_sid() with NULL as its parameter.
  68.  */
  69.  
  70. void set_sid(db)
  71. char *db;
  72. {
  73.     char *h;
  74.     static char *oldsid        = NULL;
  75.  
  76.     DBUG_ENTER("set_sid");
  77.     DBUG_PRINT("entry", ("set_sid(%s)", db ? db : "<NULL>"));
  78.  
  79.     ora_errno = 0;
  80.  
  81.     if (db == NULL)
  82.     {
  83.         if (oldsid != NULL)
  84.         {
  85.             DBUG_PRINT("info", ("setting oracle_sid to %s",oldsid));
  86.             my_setenv(oracle_sid, oldsid);
  87.         }
  88.         /* no old value to restore if oldsid == NULL */
  89.     }
  90.     else
  91.     {
  92.         if (oldsid != NULL)
  93.         {
  94.             /* already have a saved value - dispose of it */
  95.             DBUG_PRINT("free", ("freeing oldsid %lx",(long)oldsid));
  96.             free(oldsid);
  97.         }
  98.  
  99.         if ((h = getenv(oracle_sid)) == NULL)
  100.         {
  101.             /* no previous value to save */
  102.             oldsid = NULL;
  103.         }
  104.         else
  105.         {
  106.             if ((oldsid = malloc(strlen(h) + 1)) == NULL)
  107.             {
  108.                 DBUG_PRINT("malloc",
  109.                     ("insufficient memory for oldsid"));
  110.                 ora_errno = ORAP_NOMEM;
  111.             }
  112.             else
  113.             {
  114.                 DBUG_PRINT("malloc",
  115.                     ("got oldsid %d bytes at %#lx",
  116.                      strlen(h) + 1, (long) oldsid));
  117.                 strcpy(oldsid, h);
  118.             }
  119.         }
  120.  
  121.         DBUG_PRINT("info", ("setting oracle_sid to %s", db));
  122.         my_setenv(oracle_sid, db);
  123.     }
  124.  
  125.     DBUG_VOID_RETURN;
  126. }
  127.  
  128.  
  129. /* ora_login(database, name, password)
  130.  *
  131.  * logs into the current database under the given name and password.
  132.  */
  133.  
  134. char *ora_login(database, name, password)
  135. char *database, *name, *password;
  136. {
  137.     int logged;
  138.     char *tmp;
  139.     struct cursor *lda;
  140.  
  141.     DBUG_ENTER("ora_login");
  142.     DBUG_PRINT("entry",
  143.         ("ora_login(\"%s\", \"%s\", \"%s\")", database, name, password));
  144.  
  145.     if ((lda = ora_getlda()) == NULL)
  146.     {
  147.         DBUG_PRINT("exit", ("couldn't get an lda, returning NULL"));
  148.         DBUG_RETURN(NULL);
  149.     }
  150.  
  151.     if (*database != '\0')
  152.     {
  153.         set_sid(database);
  154.         if (((tmp = getenv(oracle_sid)) == NULL)    ||
  155.              (strcmp(database, tmp) != 0))
  156.         {
  157.             (void) ora_dropcursor(lda);
  158.             ora_errno = ORAP_NOSID;
  159.             DBUG_PRINT("exit",
  160.                 ("%s misset to %s, returning NULL",
  161.                 oracle_sid, tmp ? tmp : "<NULL>"));
  162.             DBUG_RETURN(NULL);
  163.         }
  164.     }
  165.     /* if no database was specified, use $ORACLE_SID by default */
  166.  
  167.     logged = orlon(lda->csr, lda->hda, name, -1, password, -1, 0);
  168.  
  169.     if (*database != '\0')
  170.     {
  171.         set_sid(NULL);    /* reset ORACLE_SID to what it was before
  172.                  * don't really care if this fails
  173.                  */
  174.     }
  175.  
  176.     if (logged == 0)
  177.     {
  178.         sprintf(address, "%#lx", (long) lda);
  179.         DBUG_PRINT("conv", ("lda %#lx converted to string \"%s\"",
  180.             (long) lda, address));
  181.         ora_errno = 0;
  182.         DBUG_PRINT("exit", ("returning lda %s", address));
  183.         DBUG_RETURN(address);
  184.     }
  185.     else
  186.     {
  187.         ora_errno = lda->csr->csrrc;
  188.         (void) ora_droplda(lda);
  189.         DBUG_PRINT("exit", ("orlon failed (error %d)", ora_errno));
  190.         DBUG_RETURN((char *) NULL);
  191.     }
  192. }
  193.  
  194.  
  195. /* ora_open(lda, stmt, cache)
  196.  *
  197.  * sets and executes the specified sql statement
  198.  */
  199.  
  200. char *ora_open(lda_s, stmt, cache)
  201. char *lda_s;
  202. char *stmt;
  203. int cache;
  204. {
  205.     int i;
  206.     struct cursor *csr;
  207.     struct cursor *lda = (struct cursor *)strtoul(lda_s, (char **) NULL, 0);
  208.     short dsize;
  209.  
  210.     DBUG_ENTER("ora_open");
  211.     DBUG_PRINT("entry", ("ora_open(%s, \"%s\", %d)", lda_s, stmt, cache));
  212.     DBUG_PRINT("conv", ("string \"%s\" converted to lda %#lx", lda_s, lda));
  213.  
  214.     if (check_lda(lda) == 0)
  215.     {
  216.         ora_errno = ORAP_INVLDA;
  217.         DBUG_PRINT("exit", ("invalid lda, returning NULL"));
  218.         DBUG_RETURN((char *) NULL);
  219.     }
  220.  
  221.     if ((csr = ora_getcursor()) == NULL)
  222.     {
  223.         DBUG_PRINT("exit", ("can't get a cursor, returning NULL"));
  224.         DBUG_RETURN((char *) NULL);
  225.     }
  226.  
  227.     /* Check whether there are any substitution variables in the statement
  228.      * If there are, we don't execute the statement yet.
  229.      */
  230.     if ((csr->varfields = count_colons(stmt)) < 0)
  231.     {
  232.         ora_errno = ORAP_BADVAR;
  233.         DBUG_PRINT("exit", ("invalid variable sequence"));
  234.         DBUG_RETURN((char *) NULL);
  235.     }
  236.     DBUG_PRINT("info", ("statement contains %d colons", csr->varfields));
  237.  
  238.     /* maybe we should separate these statements so that a debugging
  239.      * trace can show exactly where any failure occurred
  240.      */
  241.     if ((oopen(csr->csr, lda->csr, (char *)-1, -1, -1, (char *)-1, -1) != 0)
  242.         || (osql3(csr->csr, stmt, -1) != 0)
  243.         || ((csr->varfields == 0) && (oexec(csr->csr) != 0)))
  244.     {
  245.         ora_errno = csr->csr->csrrc;
  246.         oclose(csr->csr);
  247.         (void) ora_dropcursor(csr);
  248.         DBUG_PRINT("exit",
  249.             ("couldn't run SQL statement (error %d)", ora_errno));
  250.         DBUG_RETURN((char *) NULL);
  251.     }
  252.  
  253.     /* count the number of fields which will be returned */
  254.  
  255.     i = 0;
  256.     do
  257.     {
  258.         odsc(csr->csr, ++i, (short *) 0, (short *) 0, (short *) 0,
  259.             (short *) 0, (char *) 0, (short *) 0, (short *) 0);
  260.     } while (csr->csr->csrrc == 0);
  261.     --i;
  262.     ora_errno = 0;
  263.  
  264.     /* set up csr->data  to receive the information when we do a fetch
  265.      *      csr->rcode to receive the column return codes
  266.      *      csr->len   with the data lengths (principally for ora_titles)
  267.      */
  268.  
  269.     if (cache < 1)
  270.     {
  271.         DBUG_PRINT("info", ("cache size %d too small - set to %d",
  272.             cache, ora_cache));
  273.         cache = ora_cache;
  274.     }
  275.  
  276.     if (i > 0)
  277.     {
  278.         DBUG_PRINT("info", ("statement returns %d fields", i));
  279.  
  280.         if ((csr->data = (char **) malloc(i * sizeof(char *))) == NULL)
  281.         {
  282.             DBUG_PRINT("malloc", ("insufficient memory for data"));
  283.             oclose(csr->csr);
  284.             (void) ora_dropcursor(csr);
  285.             ora_errno = ORAP_NOMEM;
  286.             DBUG_PRINT("exit", ("returning NULL"));
  287.             DBUG_RETURN((char *) NULL);
  288.         }
  289.         DBUG_PRINT("malloc",
  290.             ("got data array %d items %d bytes at %#lx",
  291.              i, i * sizeof(char *), (long) csr->data));
  292.         *csr->data = (char *) NULL;
  293.  
  294.         if ((csr->len = (short *) malloc(i * sizeof(short))) == NULL)
  295.         {
  296.             DBUG_PRINT("malloc", ("insufficient memory for len"));
  297.             oclose(csr->csr);
  298.             (void) ora_dropcursor(csr);
  299.             ora_errno = ORAP_NOMEM;
  300.             DBUG_PRINT("exit", ("returning NULL"));
  301.             DBUG_RETURN((char *) NULL);
  302.         }
  303.         DBUG_PRINT("malloc", ("got len array %d items %d bytes at %#lx",
  304.              i, i * sizeof(short), (long) csr->len));
  305.  
  306.         if ((csr->rcode = (short **) malloc(i*sizeof(short *))) == NULL)
  307.         {
  308.             DBUG_PRINT("malloc", ("insufficient memory for rcode"));
  309.             oclose(csr->csr);
  310.             (void) ora_dropcursor(csr);
  311.             ora_errno = ORAP_NOMEM;
  312.             DBUG_PRINT("exit", ("returning NULL"));
  313.             DBUG_RETURN((char *) NULL);
  314.         }
  315.         DBUG_PRINT("malloc",
  316.             ("got rcode array %d items %d bytes at %#lx",
  317.              i, i * sizeof(short *), (long) csr->rcode));
  318.  
  319.         if ((csr->type = (short *) malloc(i * sizeof(short))) == NULL)
  320.         {
  321.             DBUG_PRINT("malloc", ("insufficient memory for type"));
  322.             oclose(csr->csr);
  323.             (void) ora_dropcursor(csr);
  324.             ora_errno = ORAP_NOMEM;
  325.             DBUG_PRINT("exit", ("returning NULL"));
  326.             DBUG_RETURN((char *) NULL);
  327.         }
  328.         DBUG_PRINT("malloc",("got type array %d items %d bytes at %#lx",
  329.              i, i * sizeof(short), (long) csr->type));
  330.  
  331.         csr->nfields = i;
  332.  
  333.         for (i = 0 ; i < csr->nfields ; i++)
  334.         {
  335.             odsc(csr->csr, i + 1, (short *) 0, (short *) 0,
  336.                 (short *) 0, &csr->type[i], (char *) 0,
  337.                 (short *) 0, &dsize);
  338.  
  339.             if ((csr->type[i] == 8) || (csr->type[i] == 24))
  340.             {
  341.                 /* either LONG or LONGRAW */
  342.                 if (dsize < ora_long)
  343.                 {
  344.                     dsize = ora_long;
  345.                 }
  346.             }
  347.  
  348.             if ((csr->data[i] =
  349.                 (char *) malloc((dsize + 1) * cache)) == NULL)
  350.             {
  351.                 DBUG_PRINT("malloc",
  352.                     ("insufficient memory for data[%d]", i));
  353.                 oclose(csr->csr);
  354.                 (void) ora_dropcursor(csr);
  355.                 ora_errno = ORAP_NOMEM;
  356.                 DBUG_PRINT("exit", ("returning NULL"));
  357.                 DBUG_RETURN((char *) NULL);
  358.             }
  359.             DBUG_PRINT("malloc", ("got field %d, %d bytes at %#lx",
  360.                  i, (dsize + 1) * cache, csr->data[i]));
  361.  
  362.             if ((csr->rcode[i] =
  363.                 (short *) malloc(sizeof(short) * cache)) == NULL)
  364.             {
  365.                 DBUG_PRINT("malloc",
  366.                     ("insufficient memory for rcode[%d]", i));
  367.                 oclose(csr->csr);
  368.                 (void) ora_dropcursor(csr);
  369.                 ora_errno = ORAP_NOMEM;
  370.                 DBUG_PRINT("exit", ("returning NULL"));
  371.                 DBUG_RETURN((char *) NULL);
  372.             }
  373.             DBUG_PRINT("malloc", ("got rcode %d, %d bytes at %#lx",
  374.                  i, sizeof(short) * cache, csr->rcode[i]));
  375.  
  376.             odefin(csr->csr, i + 1, csr->data[i], dsize + 1, 5, 0,
  377.                 (short *) 0, (char *) 0, 0, 0, (short *) 0,
  378.                 csr->rcode[i]);
  379.             csr->len[i] = dsize;
  380.  
  381.             DBUG_PRINT("info", ("Field %d, length %d, type %d (%s)",
  382.                 i, dsize, csr->type[i], types[csr->type[i]]));
  383.         }
  384.  
  385.         if (csr->nfields > ora_nfields)
  386.         {
  387.             if (ora_result != NULL)
  388.             {
  389.                 DBUG_PRINT("free", ("freeing ora_result %lx",
  390.                     (long) ora_result));
  391.                 free(ora_result);
  392.             }
  393.  
  394.             if ((ora_result =
  395.                 (char **) malloc(csr->nfields * (sizeof(char *))))
  396.                 == NULL)
  397.             {
  398.                 ora_nfields = 0;
  399.                 DBUG_PRINT("malloc",
  400.                     ("insufficient memory for ora_result"));
  401.                 oclose(csr->csr);
  402.                 (void) ora_dropcursor(csr);
  403.                 ora_errno = ORAP_NOMEM;
  404.                 DBUG_PRINT("exit", ("returning NULL"));
  405.                 DBUG_RETURN((char *) NULL);
  406.             }
  407.             DBUG_PRINT("malloc", ("got ora_result %d bytes at %#lx",
  408.                 csr->nfields * sizeof(char *), ora_result));
  409.             ora_nfields = csr->nfields;
  410.         }
  411.     }
  412.     else
  413.     {
  414.         DBUG_PRINT("info", ("statement returns no data"));
  415.         csr->data = NULL;
  416.     }
  417.  
  418.     csr->cache_size = cache;
  419.     csr->in_cache = 0;
  420.     csr->end_of_data = 0;
  421.  
  422.     sprintf(address, "%#lx", (long) csr);
  423.     DBUG_PRINT("conv", ("csr %#lx converted to string \"%s\"",csr,address));
  424.     DBUG_PRINT("exit", ("returning csr \"%s\"", address));
  425.     DBUG_RETURN(address);
  426. }
  427.  
  428.  
  429. /* ora_titles(csr)
  430.  *
  431.  * returns the column headers for the query referenced by csr
  432.  *
  433.  * overwrites the first position in each data array,
  434.  * but this is acceptable since these values have always been returned.
  435.  */
  436.  
  437. int ora_titles(csr_s)
  438. char *csr_s;
  439. {
  440.     int i;
  441.     short len;
  442.     struct cursor *csr = (struct cursor *)strtoul(csr_s, (char **) NULL, 0);
  443.  
  444.     DBUG_ENTER("ora_titles");
  445.     DBUG_PRINT("entry", ("ora_titles(%s)", csr_s));
  446.     DBUG_PRINT("conv", ("string \"%s\" converted to csr %#lx", csr_s, csr));
  447.  
  448.     if (check_csr(csr) == 0)
  449.     {
  450.         ora_errno = ORAP_INVCSR;
  451.         DBUG_PRINT("exit", ("not a csr"));
  452.         DBUG_RETURN(0);
  453.     }
  454.     else if (csr->nfields == 0)
  455.     {
  456.         ora_errno = ORAP_NODATA;
  457.         DBUG_PRINT("exit", ("nothing to return"));
  458.         DBUG_RETURN(0);
  459.     }
  460.     else if ((ora_result == NULL) || (ora_nfields < csr->nfields))
  461.     {
  462.         ora_errno = ORAP_NOMEM;
  463.         DBUG_PRINT("exit", ("ora_result is not assigned correctly"));
  464.         DBUG_RETURN(0);
  465.     }
  466.  
  467.     for (i = 0 ; i < csr->nfields ; i++)
  468.     {
  469.         len = csr->len[i];
  470.         oname(csr->csr, i + 1, (char *) -1, (short *) -1,
  471.               csr->data[i], &len);
  472.         ora_result[i] = csr->data[i];
  473.         DBUG_PRINT("info", ("field %4d (%lx) title \"%s\"",
  474.             i, (long) csr->data[i], csr->data[i]));
  475.     }
  476.  
  477.     ora_errno = 0;
  478.     DBUG_PRINT("exit", ("returning %d items", csr->nfields));
  479.     DBUG_RETURN(csr->nfields);
  480. }
  481.  
  482. /* ora_lengths(csr)
  483.  *
  484.  * returns the return field lengths for the query referenced by csr
  485.  *
  486.  * overwrites the first position in each data array,
  487.  * but this is acceptable since these values have always been returned.
  488.  */
  489.  
  490. int ora_lengths(csr_s)
  491. char *csr_s;
  492. {
  493.     int i;
  494.     short len;
  495.     struct cursor *csr = (struct cursor *)strtoul(csr_s, (char **) NULL, 0);
  496.  
  497.     DBUG_ENTER("ora_lengths");
  498.     DBUG_PRINT("entry", ("ora_lengths(%s)", csr_s));
  499.     DBUG_PRINT("conv", ("string \"%s\" converted to csr %#lx", csr_s, csr));
  500.  
  501.     if (check_csr(csr) == 0)
  502.     {
  503.         ora_errno = ORAP_INVCSR;
  504.         DBUG_PRINT("exit", ("not a csr"));
  505.         DBUG_RETURN(0);
  506.     }
  507.     else if (csr->nfields == 0)
  508.     {
  509.         ora_errno = ORAP_NODATA;
  510.         DBUG_PRINT("exit", ("nothing to return"));
  511.         DBUG_RETURN(0);
  512.     }
  513.     else if ((ora_result == NULL) || (ora_nfields < csr->nfields))
  514.     {
  515.         ora_errno = ORAP_NOMEM;
  516.         DBUG_PRINT("exit", ("ora_result is not assigned correctly"));
  517.         DBUG_RETURN(0);
  518.     }
  519.  
  520.     for (i = 0 ; i < csr->nfields ; i++)
  521.     {
  522.         /* write the data length into the first entry in the cache */
  523.         sprintf(csr->data[i], "%d", csr->len[i]);
  524.         ora_result[i] = csr->data[i];
  525.         DBUG_PRINT("info", ("field %4d (%lx) length %s",
  526.             i, (long) csr->data[i], csr->data[i]));
  527.     }
  528.  
  529.     ora_errno = 0;
  530.     DBUG_PRINT("exit", ("returning %d items", csr->nfields));
  531.     DBUG_RETURN(csr->nfields);
  532. }
  533.  
  534.  
  535. /* ora_types(csr)
  536.  *
  537.  * returns the return field types for the query referenced by csr
  538.  * see the OCI manuals to work out what the return values mean
  539.  *
  540.  * overwrites the first position in each data array,
  541.  * but this is acceptable since these values have always been returned.
  542.  */
  543.  
  544. int ora_types(csr_s)
  545. char *csr_s;
  546. {
  547.     int i;
  548.     struct cursor *csr = (struct cursor *)strtoul(csr_s, (char **) NULL, 0);
  549.  
  550.     DBUG_ENTER("ora_types");
  551.     DBUG_PRINT("entry", ("ora_types(%s)", csr_s));
  552.     DBUG_PRINT("conv", ("string \"%s\" converted to csr %#lx", csr_s, csr));
  553.  
  554.     if (check_csr(csr) == 0)
  555.     {
  556.         ora_errno = ORAP_INVCSR;
  557.         DBUG_PRINT("exit", ("not a csr"));
  558.         DBUG_RETURN(0);
  559.     }
  560.     else if (csr->nfields == 0)
  561.     {
  562.         ora_errno = ORAP_NODATA;
  563.         DBUG_PRINT("exit", ("nothing to return"));
  564.         DBUG_RETURN(0);
  565.     }
  566.     else if ((ora_result == NULL) || (ora_nfields < csr->nfields))
  567.     {
  568.         ora_errno = ORAP_NOMEM;
  569.         DBUG_PRINT("exit", ("ora_result is not assigned correctly"));
  570.         DBUG_RETURN(0);
  571.     }
  572.  
  573.     for (i = 0 ; i < csr->nfields ; i++)
  574.     {
  575.         /* write the type into the first cache entry */
  576.         sprintf(csr->data[i], "%d", csr->type[i]);
  577.         ora_result[i] = csr->data[i];
  578.         DBUG_PRINT("info", ("field %4d (%lx) type %s (%s)",
  579.             i, (long) csr->data[i], csr->data[i],
  580.             types[csr->type[i]] ? types[csr->type[i]] : "unknown"));
  581.     }
  582.  
  583.     ora_errno = 0;
  584.     DBUG_PRINT("exit", ("returning %d items", csr->nfields));
  585.     DBUG_RETURN(csr->nfields);
  586. }
  587.  
  588.  
  589. /* ora_fetch(csr)
  590.  *
  591.  * returns the next set of data from the cursor
  592.  *
  593.  * at exit, the first entry must be returned or have already been returned,
  594.  * otherwise it may be overwritten by ora_titles().
  595.  */
  596.  
  597. int ora_fetch(csr_s, trunc)
  598. char *csr_s;
  599. int trunc;
  600. {
  601.     int i;
  602.     struct cursor *csr = (struct cursor *)strtoul(csr_s, (char **) NULL, 0);
  603.  
  604.     DBUG_ENTER("ora_fetch");
  605.     DBUG_PRINT("entry", ("ora_fetch(%s, %d)", csr_s, trunc));
  606.     DBUG_PRINT("conv", ("string \"%s\" converted to csr %#lx", csr_s, csr));
  607.  
  608.     if (check_csr(csr) == 0)
  609.     {
  610.         ora_errno = ORAP_INVCSR;
  611.         DBUG_PRINT("exit", ("not a csr"));
  612.         DBUG_RETURN(0);
  613.     }
  614.     else if (csr->nfields == 0)
  615.     {
  616.         ora_errno = ORAP_NODATA;
  617.         DBUG_PRINT("exit", ("no data to return"));
  618.         DBUG_RETURN(0);
  619.     }
  620.     else if ((ora_result == NULL) || (ora_nfields < csr->nfields))
  621.     {
  622.         ora_errno = ORAP_NOMEM;
  623.         DBUG_PRINT("exit", ("ora_result is not assigned"));
  624.         DBUG_RETURN(0);
  625.     }
  626.  
  627.     if (csr->in_cache == 0)
  628.     {
  629.         unsigned long rowcount = csr->csr->csrrpc;
  630.  
  631.         if (csr->end_of_data)
  632.         {
  633.             ora_errno = 0;
  634.             DBUG_PRINT("exit", ("end of data"));
  635.             DBUG_RETURN(0);
  636.         }
  637.  
  638.         if (i = ofen(csr->csr, csr->cache_size) == 4)
  639.         {
  640.             DBUG_PRINT("info", ("setting end_of_data"));
  641.             csr->end_of_data = 1;
  642.         }
  643.  
  644.         csr->in_cache = csr->csr->csrrpc - rowcount;
  645.         csr->next_entry = 0;
  646.  
  647.         DBUG_PRINT("info", ("fetched %d rows", csr->in_cache));
  648.  
  649.         if (csr->in_cache == 0)
  650.         {
  651.             if ((i == 1) && (csr->csr->csrrc == 4))
  652.             {
  653.                 ora_errno = 0;
  654.                 DBUG_PRINT("exit", ("end of data"));
  655.                 DBUG_RETURN(0);
  656.             }
  657.             else
  658.             {
  659.                 ora_errno = csr->csr->csrrc;
  660.                 DBUG_PRINT("exit",
  661.                     ("ofen error (%d)", ora_errno));
  662.                 DBUG_RETURN(0);
  663.             }
  664.         }
  665.     }
  666.  
  667.     DBUG_PRINT("info", ("returning row %d from cache:", csr->next_entry));
  668.  
  669.     for (i = 0 ; i < csr->nfields ; i++)
  670.     {
  671.         ora_result[i] =
  672.             &csr->data[i][csr->next_entry * (csr->len[i] + 1)];
  673.  
  674.         switch (csr->rcode[i][csr->next_entry])
  675.         {
  676.         case 0:        /* no problem */
  677.             break;
  678.  
  679.         case 1405:
  680.             DBUG_PRINT("info", ("field %d was NULL", i));
  681.             *ora_result[i] = '\0';
  682.             break;
  683.  
  684.         case 1406:
  685.             ora_errno = 1406;
  686.  
  687.             if (trunc    &&
  688.                 ((csr->type[i] == 8) || (csr->type[i] == 24)))
  689.             {
  690.                 /* truncation is allowed
  691.                  * IF  the truncation flag is set
  692.                  * AND the field type is LONG or LONGRAW
  693.                  */
  694.                 DBUG_PRINT("info", ("LONG%s field %d was truncated",
  695.                 ((csr->type[i] == 8) ? "" : "RAW"), i));
  696.             }
  697.             else    /* truncation is an error */
  698.             {
  699.                 DBUG_PRINT("exit", ("field %d truncation error",i));
  700.                 DBUG_RETURN(0);
  701.             }
  702.             break;
  703.  
  704.         default:    /* others should not happen */
  705.             DBUG_PRINT("info", ("ofetch error %d, field %d",
  706.                 csr->rcode[i][csr->next_entry], i));
  707.             ora_errno = csr->csr->csrrc;
  708.             DBUG_PRINT("exit", ("returning 0"));
  709.             DBUG_RETURN(0);
  710.         }
  711.  
  712.         DBUG_PRINT("info", ("field %4d (%lx) data \"%s\"",
  713.             i, (long) ora_result[i], ora_result[i]));
  714.     }
  715.  
  716.     ++csr->next_entry;
  717.     --csr->in_cache;
  718.  
  719.     ora_errno = 0;
  720.     DBUG_PRINT("exit", ("returning %d items", csr->nfields));
  721.     DBUG_RETURN(csr->nfields);
  722. }
  723.  
  724. /* ora_bind(csr_s, vars, nitems)
  725.  *
  726.  * binds actual values to the SQL statement associated with csr
  727.  */
  728.  
  729. int ora_bind(csr_s, vars, nitems)
  730. char *csr_s, **vars;
  731. int nitems;
  732. {
  733.     int i;
  734. #ifndef    NO_BIND_PADDING
  735.     static char small_buf[2] = " ";
  736. #endif
  737.     struct cursor *csr = (struct cursor *)strtoul(csr_s, (char **) NULL, 0);
  738.  
  739.     DBUG_ENTER("ora_bind");
  740.     DBUG_PRINT("entry", ("ora_bind(%s, %#lx, %d)",
  741.         csr_s, (long) vars, nitems));
  742.     DBUG_PRINT("conv", ("string \"%s\" converted to csr %#lx", csr_s, csr));
  743.  
  744.     if (check_csr(csr) == 0)
  745.     {
  746.         ora_errno = ORAP_INVCSR;
  747.         DBUG_PRINT("exit", ("not a csr"));
  748.         DBUG_RETURN(0);
  749.     }
  750.     else if (csr->varfields != nitems)
  751.     {
  752.         ora_errno = ORAP_NUMVARS;
  753.         DBUG_PRINT("exit", ("expected %d items, got %d",
  754.             csr->varfields, nitems));
  755.         DBUG_RETURN(0);
  756.     }
  757.  
  758.     for (i = 0 ; i < nitems ; i++)
  759.     {
  760. #ifndef    NO_BIND_PADDING
  761.         if (vars[i][0] == '\0')
  762.         {
  763.             DBUG_PRINT("info", ("field %d is empty - padding", i));
  764.             vars[i] = small_buf;
  765.         }
  766. #endif
  767.         if ((obndrn(csr->csr, i+1, vars[i], strlen(vars[i])+1,
  768.             5, -1, (short *) -1, (char *) -1, 0, 0)) != 0)
  769.         {
  770.             ora_errno = csr->csr->csrrc;
  771.             DBUG_PRINT("exit", ("obndrn failed on field %d, \"%s\"",
  772.                 i + 1, vars[i]));
  773.             DBUG_RETURN(0);
  774.         }
  775.  
  776.         DBUG_PRINT("info", ("obndrn %d, \"%s\" OK", (i + 1), vars[i]));
  777.     }
  778.  
  779.     if (oexec(csr->csr) != 0)
  780.     {
  781.         ora_errno = csr->csr->csrrc;
  782.         DBUG_PRINT("exit", ("oexec failed"));
  783.         DBUG_RETURN(0);
  784.     }
  785.  
  786.     /* any cached data is now out of date, as is the end_of data flag */
  787.     csr->in_cache = 0;
  788.     csr->end_of_data = 0;
  789.  
  790.     DBUG_PRINT("exit", ("returning OK"));
  791.     DBUG_RETURN(1);
  792. }
  793.  
  794.  
  795. char    *OK    = "OK";        /* valid return from ora_close/do/logoff */
  796.  
  797.  
  798. /* ora_do(lda, stmt)
  799.  *
  800.  * sets and executes the specified sql statement, without leaving a cursor open
  801.  */
  802.  
  803. char *ora_do(lda_s, stmt)
  804. char *lda_s;
  805. char *stmt;
  806. {
  807.     char *csr_s;
  808.  
  809.     DBUG_ENTER("ora_do");
  810.     DBUG_PRINT("entry", ("ora_do(%s, \"%s\")", lda_s, stmt));
  811.  
  812.     if ((csr_s = ora_open(lda_s, stmt)) == NULL)
  813.     {
  814.         DBUG_PRINT("exit", ("ora_open failed"));
  815.         DBUG_RETURN(NULL);
  816.     }
  817.     else if (ora_close(csr_s) == NULL)
  818.     {
  819.         DBUG_PRINT("exit", ("ora_close failed"));
  820.         DBUG_RETURN(NULL);
  821.     }
  822.     else
  823.     {
  824.         DBUG_PRINT("exit", ("command successful"));
  825.         DBUG_RETURN(OK);
  826.     }
  827.  
  828.     /* NOTREACHED */
  829. }
  830.  
  831.  
  832. /* ora_close(csr)
  833.  *
  834.  * Closes an oracle statement, releasing resources
  835.  */
  836.  
  837. char *ora_close(csr_s)
  838. char *csr_s;
  839. {
  840.     struct cursor *csr = (struct cursor *)strtoul(csr_s, (char **) NULL, 0);
  841.  
  842.     DBUG_ENTER("ora_close");
  843.     DBUG_PRINT("entry", ("ora_close(%s)", csr_s));
  844.     DBUG_PRINT("conv", ("string \"%s\" converted to csr %#lx", csr_s, csr));
  845.  
  846.     if (check_csr(csr) == 0)
  847.     {
  848.         ora_errno = ORAP_INVCSR;
  849.         DBUG_PRINT("exit", ("not a csr"));
  850.         DBUG_RETURN(NULL);
  851.     }
  852.     else if (oclose(csr->csr) != 0)
  853.     {
  854.         ora_errno = csr->csr->csrrc;
  855.         DBUG_PRINT("exit", ("oclose failed"));
  856.         DBUG_RETURN(NULL);
  857.     }
  858.     else
  859.     {
  860.         (void) ora_dropcursor(csr);
  861.         DBUG_PRINT("exit", ("returning OK"));
  862.         DBUG_RETURN(OK);
  863.     }
  864. }
  865.  
  866.  
  867. /* ora_logoff(lda)
  868.  *
  869.  * Logs the user off of Oracle, releasing all resources
  870.  */
  871.  
  872. char *ora_logoff(lda_s)
  873. char *lda_s;
  874. {
  875.     struct cursor *lda = (struct cursor *)strtoul(lda_s, (char **) NULL, 0);
  876.  
  877.     DBUG_ENTER("ora_logoff");
  878.     DBUG_PRINT("entry", ("ora_logoff(%s)", lda_s));
  879.     DBUG_PRINT("conv", ("string \"%s\" converted to lda %#lx", lda_s, lda));
  880.  
  881.     if (check_lda(lda) == 0)
  882.     {
  883.         ora_errno = ORAP_INVLDA;
  884.         DBUG_PRINT("exit", ("not an lda"));
  885.         DBUG_RETURN(NULL);
  886.     }
  887.     else if (ologof(lda->csr) != 0)
  888.     {
  889.         ora_errno = lda->csr->csrrc;
  890.         DBUG_PRINT("exit", ("ologof failed, error code %d", ora_errno));
  891.         DBUG_RETURN(NULL);
  892.     }
  893.     else
  894.     {
  895.         (void) ora_droplda(lda);
  896.         DBUG_PRINT("exit", ("returning OK"));
  897.         DBUG_RETURN(OK);
  898.     }
  899. }
  900.  
  901.  
  902. /* ora_commit(lda)
  903.  *
  904.  * Commits all pending transactions on the specified lda.
  905.  */
  906.  
  907. char *ora_commit(lda_s)
  908. char *lda_s;
  909. {
  910.     struct cursor *lda = (struct cursor *)strtoul(lda_s, (char **) NULL, 0);
  911.  
  912.     DBUG_ENTER("ora_commit");
  913.     DBUG_PRINT("entry", ("ora_commit(%s)", lda_s));
  914.     DBUG_PRINT("conv", ("string \"%s\" converted to lda %#lx", lda_s, lda));
  915.  
  916.     if (check_lda(lda) == 0)
  917.     {
  918.         ora_errno = ORAP_INVLDA;
  919.         DBUG_PRINT("exit", ("not an lda"));
  920.         DBUG_RETURN(NULL);
  921.     }
  922.     else if (ocom(lda->csr) != 0)
  923.     {
  924.         ora_errno = lda->csr->csrrc;
  925.         DBUG_PRINT("exit", ("ocom failed, error code %d", ora_errno));
  926.         DBUG_RETURN(NULL);
  927.     }
  928.     else
  929.     {
  930.         DBUG_PRINT("exit", ("returning OK"));
  931.         DBUG_RETURN(OK);
  932.     }
  933. }
  934.  
  935.  
  936. /* ora_rollback(lda)
  937.  *
  938.  * rollbacks all pending transactions on the specified lda.
  939.  */
  940.  
  941. char *ora_rollback(lda_s)
  942. char *lda_s;
  943. {
  944.     struct cursor *lda = (struct cursor *)strtoul(lda_s, (char **) NULL, 0);
  945.  
  946.     DBUG_ENTER("ora_rollback");
  947.     DBUG_PRINT("entry", ("ora_rollback(%s)", lda_s));
  948.     DBUG_PRINT("conv", ("string \"%s\" converted to lda %#lx", lda_s, lda));
  949.  
  950.     if (check_lda(lda) == 0)
  951.     {
  952.         ora_errno = ORAP_INVLDA;
  953.         DBUG_PRINT("exit", ("not an lda", stderr));
  954.         DBUG_RETURN(NULL);
  955.     }
  956.     else if (orol(lda->csr) != 0)
  957.     {
  958.         ora_errno = lda->csr->csrrc;
  959.         DBUG_PRINT("exit", ("orol failed, error code %d", ora_errno));
  960.         DBUG_RETURN(NULL);
  961.     }
  962.     else
  963.     {
  964.         DBUG_PRINT("exit", ("returning OK"));
  965.         DBUG_RETURN(OK);
  966.     }
  967. }
  968.  
  969.  
  970. /* ora_autocommit(lda, on_off)
  971.  *
  972.  * Turns autocommit for the specified lda on or off.
  973.  */
  974.  
  975. char *ora_autocommit(lda_s, on_off)
  976. char *lda_s;
  977. int on_off;
  978. {
  979.     struct cursor *lda = (struct cursor *)strtoul(lda_s, (char **) NULL, 0);
  980.  
  981.     DBUG_ENTER("ora_autocommit");
  982.     DBUG_PRINT("entry", ("ora_autocommit(%s, %d)", lda_s, on_off));
  983.     DBUG_PRINT("conv", ("string \"%s\" converted to lda %#lx", lda_s, lda));
  984.  
  985.     if (check_lda(lda) == 0)
  986.     {
  987.         ora_errno = ORAP_INVLDA;
  988.         DBUG_PRINT("exit", ("not an lda", stderr));
  989.         DBUG_RETURN(NULL);
  990.     }
  991.  
  992.     if (on_off)    /* turn autocommit on */
  993.     {
  994.         if (ocon(lda->csr) != 0)
  995.         {
  996.             ora_errno = lda->csr->csrrc;
  997.             DBUG_PRINT("exit",
  998.                 ("ocon failed, error code %d", ora_errno));
  999.             DBUG_RETURN(NULL);
  1000.         }
  1001.     }
  1002.     else        /* turn autocommit off */
  1003.     {
  1004.         if (ocof(lda->csr) != 0)
  1005.         {
  1006.             ora_errno = lda->csr->csrrc;
  1007.             DBUG_PRINT("exit",
  1008.                 ("ocof failed, error code %d", ora_errno));
  1009.             DBUG_RETURN(NULL);
  1010.         }
  1011.     }
  1012.  
  1013.     DBUG_PRINT("exit", ("returning OK"));
  1014.     DBUG_RETURN(OK);
  1015. }
  1016.