home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume22 / oraperl / patch02 / Patch02 < prev   
Encoding:
Text File  |  1991-08-25  |  23.4 KB  |  806 lines

  1. diff -c /user/mis/kstock/tmp/CHANGES ./CHANGES
  2. *** /user/mis/kstock/tmp/CHANGES    Fri Aug 23 08:50:45 1991
  3. --- ./CHANGES    Fri Aug 23 09:10:27 1991
  4. ***************
  5. *** 8,10 ****
  6. --- 8,16 ----
  7.   Added network addresses to the manual pages
  8.   Added a PATCHLEVEL file
  9.   No functional changes
  10. + Patch 02
  11. + ========
  12. + Added support for dynamically modifiable SQL statements
  13. + Added a Hints file
  14. + Corrected an error in the quick-reference sheet
  15. diff -c /user/mis/kstock/tmp/Makefile ./Makefile
  16. *** /user/mis/kstock/tmp/Makefile    Fri Aug 23 08:50:56 1991
  17. --- ./Makefile    Mon Aug  5 11:01:38 1991
  18. ***************
  19. *** 3,9 ****
  20.   # Change these to your ORACLE installation directory and Perl source directory
  21.   
  22.   ORACLE_HOME    = /usr/soft/oracle
  23. ! SRC        = /usr/soft/public/perl_4.0.09
  24.   
  25.   # Oracle Definitions, taken from proc.mk
  26.   
  27. --- 3,9 ----
  28.   # Change these to your ORACLE installation directory and Perl source directory
  29.   
  30.   ORACLE_HOME    = /usr/soft/oracle
  31. ! SRC        = /usr/soft/public/perl_4.0.10
  32.   
  33.   # Oracle Definitions, taken from proc.mk
  34.   
  35. ***************
  36. *** 27,48 ****
  37.   DEBUG        = -DPERL_DEBUGGING
  38.   CFLAGS        = $(DEBUG) -I$(SRC) $(GLOBINCS) -O
  39.   
  40. ! oraperl: $(SRC)/uperl.o usersub.o oracle.o orafns.o getcursor.o
  41. !     cc -o oraperl $(SRC)/uperl.o usersub.o oracle.o orafns.o getcursor.o \
  42. !         -lm $(OCILIB) $(NETLIBS) $(ORALIBS) $(CLIBS) $(LIBS)
  43.   
  44.   oracle.c: $(SRC)/usub/mus oracle.mus
  45. -     chmod +x $(SRC)/usub/mus
  46.       $(SRC)/usub/mus oracle.mus >oracle.c
  47.   
  48. ! usersub.o oracle.o orafns.o getcursor.o:    orafns.h
  49. ! print:    Makefile orafns.h orafns.c oracle.mus usersub.c getcursor.c
  50. !     pr -fn Makefile orafns.h getcursor.c orafns.c oracle.mus usersub.c | \
  51. !         pr -fto4 -e > Print
  52. ! man: oraperl.1
  53. !     nroff -man oraperl.1 >oraperl.man
  54.   
  55.   clean:
  56.       rm -f nohup.out oraperl *.o oracle.c oraperl.man Print tags out core
  57. --- 27,44 ----
  58.   DEBUG        = -DPERL_DEBUGGING
  59.   CFLAGS        = $(DEBUG) -I$(SRC) $(GLOBINCS) -O
  60.   
  61. ! SRCS        = usersub.c oracle.c orafns.c getcursor.c colons.c
  62. ! OBJS        = usersub.o oracle.o orafns.o getcursor.o colons.o
  63. ! HDRS        = orafns.h
  64. ! oraperl: $(SRC)/uperl.o $(OBJS)
  65. !     cc -o oraperl $(SRC)/uperl.o $(OBJS)                \
  66. !           -lm $(OCILIB) $(NETLIBS) $(ORALIBS) $(CLIBS) $(LIBS)
  67.   
  68.   oracle.c: $(SRC)/usub/mus oracle.mus
  69.       $(SRC)/usub/mus oracle.mus >oracle.c
  70.   
  71. ! $(OBJS):    $(HDRS)
  72.   
  73.   clean:
  74.       rm -f nohup.out oraperl *.o oracle.c oraperl.man Print tags out core
  75. diff -c /user/mis/kstock/tmp/Oracle-v5 ./Oracle-v5
  76. *** /user/mis/kstock/tmp/Oracle-v5    Fri Aug 23 08:50:46 1991
  77. --- ./Oracle-v5    Wed Aug  7 09:24:00 1991
  78. ***************
  79. *** 20,28 ****
  80.   >
  81.   > LDFLAGS    = -L$(ORACLE_HOME)/c/libs -L$(ORACLE_HOME)/rdbms/libs
  82.   >
  83. ! > oraperl: $(SRC)/uperl.o usersub.o oracle.o orafns.o getcursor.o
  84. ! >     $(CC) -o oraperl $(LDFLAGS) $(SRC)/uperl.o usersub.o oracle.o orafns.o \
  85. ! >         getcursor.o $(ORALIBS) $(LIBS)
  86.   
  87.   Second method - much simpler. Only seems to require the first two libraries
  88.   (libocic and liboracle) of the previous method, but this time they live under
  89. --- 20,27 ----
  90.   >
  91.   > LDFLAGS    = -L$(ORACLE_HOME)/c/libs -L$(ORACLE_HOME)/rdbms/libs
  92.   >
  93. ! > oraperl: $(SRC)/uperl.o $(OBJS)
  94. ! >     $(CC) -o oraperl $(LDFLAGS) $(SRC)/uperl.o $(OBJS) $(ORALIBS) $(LIBS)
  95.   
  96.   Second method - much simpler. Only seems to require the first two libraries
  97.   (libocic and liboracle) of the previous method, but this time they live under
  98. diff -c /user/mis/kstock/tmp/PATCHLEVEL ./PATCHLEVEL
  99. *** /user/mis/kstock/tmp/PATCHLEVEL    Fri Aug 23 08:50:47 1991
  100. --- ./PATCHLEVEL    Mon Aug  5 11:01:39 1991
  101. ***************
  102. *** 1 ****
  103. ! 1
  104. --- 1 ----
  105. ! 2
  106. diff -c /user/mis/kstock/tmp/README ./README
  107. *** /user/mis/kstock/tmp/README    Fri Aug 23 08:50:56 1991
  108. --- ./README    Fri Aug 23 08:53:04 1991
  109. ***************
  110. *** 24,30 ****
  111.   be changed to  str_2static()  with the same arguments.
  112.   
  113.   I've only tested this on an Encore Multimax 520 running UMAX V (Sys Vr3.2),
  114. ! using Perl 3.0.34, 4.0.00 4.0.03 and 4.0.09 with Oracle version 6, as I don't
  115.   have access to any other system with Pro*C. I'd appreciate any comments,
  116.   bug-reports etc.
  117.   
  118. --- 24,30 ----
  119.   be changed to  str_2static()  with the same arguments.
  120.   
  121.   I've only tested this on an Encore Multimax 520 running UMAX V (Sys Vr3.2),
  122. ! using Perl 3.0.34, 4.0.00 4.0.03 and 4.0.10 with Oracle version 6, as I don't
  123.   have access to any other system with Pro*C. I'd appreciate any comments,
  124.   bug-reports etc.
  125.   
  126. ***************
  127. *** 37,52 ****
  128.       getcursor.c    functions to deal with the cursor pool
  129.       orafns.c    actual functions to interact with oracle
  130.       usersub.c    initialisation routine
  131.   
  132. ! Examples (taken from the manual page)
  133.       debug-p        tests to see if debugging is available
  134.       ex.pl        simple example of using the functions
  135.   
  136.   Documentation
  137.       oraperl.doc    explains some of the thinking behind Oraperl
  138.       oraperl.ref    quick reference (troff format)
  139.       oraperl.1    manual page
  140.       Oracle-v5    Hints for compiling Oraperl with Oracle v5
  141.   
  142.   Many thanks to Larry for Perl. Now if only we could get the Camel book
  143.   into France! Hmm. Any plans for "Le Livre Chameau"?
  144. --- 37,59 ----
  145.       getcursor.c    functions to deal with the cursor pool
  146.       orafns.c    actual functions to interact with oracle
  147.       usersub.c    initialisation routine
  148. +     colons.c    counts substitution variables in a statement
  149.   
  150. ! Examples
  151.       debug-p        tests to see if debugging is available
  152.       ex.pl        simple example of using the functions
  153. +     mkdb.pl        more extensive example, showing the use of ora_bind()
  154.   
  155.   Documentation
  156.       oraperl.doc    explains some of the thinking behind Oraperl
  157.       oraperl.ref    quick reference (troff format)
  158.       oraperl.1    manual page
  159. +     Hints        notes on using oraperl
  160.       Oracle-v5    Hints for compiling Oraperl with Oracle v5
  161. + Miscellaneous
  162. +     CHANGES        Summary of changes to Oraperl
  163. +     PATCHLEVEL    current patchlevel (2)
  164.   
  165.   Many thanks to Larry for Perl. Now if only we could get the Camel book
  166.   into France! Hmm. Any plans for "Le Livre Chameau"?
  167. diff -c /user/mis/kstock/tmp/getcursor.c ./getcursor.c
  168. *** /user/mis/kstock/tmp/getcursor.c    Fri Aug 23 08:50:57 1991
  169. --- ./getcursor.c    Mon Aug  5 11:01:39 1991
  170. ***************
  171. *** 269,275 ****
  172.    {
  173.       DEBUG(8, (fprintf(stderr, "check_csr(%#lx)\n", (long) csr)));
  174.   
  175. !     if (ora_findcursor(csr) && (csr->hda == NULL) && (csr->data != NULL))
  176.       {
  177.           DEBUG(8, (fputs("check_csr: valid\n", stderr)));
  178.           return (1);
  179. --- 269,275 ----
  180.    {
  181.       DEBUG(8, (fprintf(stderr, "check_csr(%#lx)\n", (long) csr)));
  182.   
  183. !     if (ora_findcursor(csr) && (csr->hda == NULL))
  184.       {
  185.           DEBUG(8, (fputs("check_csr: valid\n", stderr)));
  186.           return (1);
  187. diff -c /user/mis/kstock/tmp/oracle.mus ./oracle.mus
  188. *** /user/mis/kstock/tmp/oracle.mus    Fri Aug 23 08:50:57 1991
  189. --- ./oracle.mus    Mon Aug  5 11:01:39 1991
  190. ***************
  191. *** 25,30 ****
  192. --- 25,31 ----
  193.   static enum usersubs {
  194.       US_ora_login,
  195.       US_ora_open,
  196. +     US_ora_bind,
  197.       US_ora_fetch,
  198.       US_ora_close,
  199.       US_ora_logoff,
  200. ***************
  201. *** 53,58 ****
  202. --- 54,60 ----
  203.   
  204.       make_usub("ora_login",    US_ora_login,    usersub, filename);
  205.       make_usub("ora_open",    US_ora_open,    usersub, filename);
  206. +     make_usub("ora_bind",    US_ora_bind,    usersub, filename);
  207.       make_usub("ora_fetch",    US_ora_fetch,    usersub, filename);
  208.       make_usub("ora_close",    US_ora_close,    usersub, filename);
  209.       make_usub("ora_logoff",    US_ora_logoff,    usersub, filename);
  210. ***************
  211. *** 115,120 ****
  212. --- 117,148 ----
  213.       }
  214.       /* NOTREACHED */
  215.   
  216. +     case US_ora_bind:
  217. +     if (items < 2)
  218. +         fatal("Usage: &ora_bind($csr, $var ...)");
  219. +     else {
  220. +         char *csr        = (char *) str_get(st[1]);
  221. +         char **vars        = (char **) malloc((items-1) * sizeof(char *));
  222. +         int i, retval;
  223. +         if (vars == NULL)
  224. +         {
  225. +         ora_errno = ORAP_NOMEM;
  226. +         retval = 0;
  227. +         }
  228. +         else
  229. +         {
  230. +         for (i = 0 ; i < items - 1 ; i++)
  231. +         {
  232. +             vars[i] = (char *) str_get(st[i+2]);
  233. +         }
  234. +         retval = ora_bind(csr, vars, items - 1);
  235. +         }
  236. +         str_numset(st[0], (double) retval);
  237. +     }
  238. +     return sp;
  239.   CASE    char *    ora_close
  240.   I    char *    csr
  241.   END
  242. ***************
  243. *** 202,207 ****
  244. --- 230,243 ----
  245.   
  246.               case ORAP_NOSID:
  247.                   str_set(str, "couldn't set ORACLE_SID");
  248. +                 break;
  249. +             case ORAP_BADVAR:
  250. +                 str_set(str, "bad colon variable sequence");
  251. +                 break;
  252. +             case ORAP_NUMVARS:
  253. +                 str_set(str, "wrong number of variables");
  254.                   break;
  255.   
  256.               default:
  257. diff -c /user/mis/kstock/tmp/orafns.c ./orafns.c
  258. *** /user/mis/kstock/tmp/orafns.c    Fri Aug 23 08:50:57 1991
  259. --- ./orafns.c    Mon Aug  5 11:01:40 1991
  260. ***************
  261. *** 186,199 ****
  262.   }
  263.   
  264.   
  265. ! /* ora_open(lda, query)
  266.    *
  267. !  * sets and executes the specified sql query
  268.    */
  269.   
  270. ! char *ora_open(lda_s, query)
  271.   char *lda_s;
  272. ! char *query;
  273.   {
  274.       int i;
  275.       struct cursor *csr;
  276. --- 186,199 ----
  277.   }
  278.   
  279.   
  280. ! /* ora_open(lda, stmt)
  281.    *
  282. !  * sets and executes the specified sql statement
  283.    */
  284.   
  285. ! char *ora_open(lda_s, stmt)
  286.   char *lda_s;
  287. ! char *stmt;
  288.   {
  289.       int i;
  290.       struct cursor *csr;
  291. ***************
  292. *** 200,206 ****
  293.       struct cursor *lda = (struct cursor *) strtol(lda_s, (char **) NULL, 0);
  294.       short dbsize;
  295.   
  296. !     DEBUG(8, (fprintf(stderr, "ora_open(%#lx, %s)\n", (long) lda, query)));
  297.   
  298.       if (check_lda(lda) == 0)
  299.       {
  300. --- 200,206 ----
  301.       struct cursor *lda = (struct cursor *) strtol(lda_s, (char **) NULL, 0);
  302.       short dbsize;
  303.   
  304. !     DEBUG(8, (fprintf(stderr, "ora_open(%#lx, %s)\n", (long) lda, stmt)));
  305.   
  306.       if (check_lda(lda) == 0)
  307.       {
  308. ***************
  309. *** 216,224 ****
  310.           return((char *) NULL);
  311.       }
  312.   
  313.       if ((oopen(csr->csr, lda->csr, (char *)-1, -1, -1, (char *)-1, -1) != 0)
  314. !         || (osql3(csr->csr, query, -1) != 0)
  315. !         || (oexec(csr->csr) != 0))
  316.       {
  317.           ora_errno = csr->csr->csrrc;
  318.           ora_dropcursor(csr);
  319. --- 216,238 ----
  320.           return((char *) NULL);
  321.       }
  322.   
  323. +     /* Check whether there are any substitution variables in the statement
  324. +      * If there are, we don't execute the statement yet.
  325. +      */
  326. +     if ((csr->varfields = count_colons(stmt)) < 0)
  327. +     {
  328. +         DEBUG(8, (fputs("ora_open: invalid variable sequence\n",
  329. +             stderr)));
  330. +         ora_errno = ORAP_BADVAR;
  331. +         return((char *) NULL);
  332. +     }
  333. +     DEBUG(8, (fprintf(stderr,
  334. +         "ora_open: statement contains %d colons\n", csr->varfields)));
  335.       if ((oopen(csr->csr, lda->csr, (char *)-1, -1, -1, (char *)-1, -1) != 0)
  336. !         || (osql3(csr->csr, stmt, -1) != 0)
  337. !         || ((csr->varfields == 0) && (oexec(csr->csr) != 0)))
  338.       {
  339.           ora_errno = csr->csr->csrrc;
  340.           ora_dropcursor(csr);
  341. ***************
  342. *** 239,274 ****
  343.   
  344.       ora_errno = 0;
  345.   
  346. !     if ((csr->data = (char **) malloc(i * sizeof(char *))) == NULL)
  347. !     {
  348. !         DEBUG(128, (fputs("ora_open: out of memory\n", stderr)));
  349. !         DEBUG(8, (fputs("ora_open: returning NOMEM\n", stderr)));
  350. !         ora_errno = ORAP_NOMEM;
  351. !         ora_dropcursor(csr);
  352. !         return(0);
  353. !     }
  354. !     DEBUG(128, (fprintf(stderr, "ora_open: got data at %#lx\n",csr->data)));
  355. !     csr->nfields = i;
  356. !     for (i = 0 ; i < csr->nfields ; i++)
  357.       {
  358. !         odsc(csr->csr, i + 1, &dbsize, (short *) 0, (short *) 0,
  359. !             (short *) 0, (char *) 0, (short *) 0, (short *) 0);
  360. !         if ((csr->data[i] = (char *) malloc(dbsize + 1)) == NULL)
  361.           {
  362. -             csr->nfields = i;
  363. -             ora_dropcursor(csr);
  364.               DEBUG(128, (fputs("ora_open: out of memory\n",stderr)));
  365.               DEBUG(8, (fputs("ora_open: returning NOMEM\n",stderr)));
  366.               ora_errno = ORAP_NOMEM;
  367. !             return((char *) NULL);
  368.           }
  369. !         DEBUG(128, (fprintf(stderr, "ora_open: got field %d at %#lx\n",
  370. !             i, csr->data[i])));
  371. !         odefin(csr->csr, i + 1, csr->data[i], dbsize + 1, 5, 0,
  372. !             (short *) 0, (char *) 0, 0, 0, (short *) 0, (char *) 0);
  373.       }
  374.   
  375.       sprintf(address, "%#lx", (long) csr);
  376. --- 253,300 ----
  377.   
  378.       ora_errno = 0;
  379.   
  380. !     if (i > 0)
  381.       {
  382. !         if ((csr->data = (char **) malloc(i * sizeof(char *))) == NULL)
  383.           {
  384.               DEBUG(128, (fputs("ora_open: out of memory\n",stderr)));
  385.               DEBUG(8, (fputs("ora_open: returning NOMEM\n",stderr)));
  386.               ora_errno = ORAP_NOMEM;
  387. !             ora_dropcursor(csr);
  388. !             return(0);
  389. !         }
  390. !         DEBUG(128, (fprintf(stderr,
  391. !             "ora_open: got data at %#lx\n",csr->data)));
  392. !         csr->nfields = i;
  393. !         for (i = 0 ; i < csr->nfields ; i++)
  394. !         {
  395. !             odsc(csr->csr, i + 1, &dbsize, (short *) 0, (short *) 0,
  396. !                 (short *) 0, (char *) 0, (short *) 0, (short *) 0);
  397. !             if ((csr->data[i] = (char *) malloc(dbsize+1)) == NULL)
  398. !             {
  399. !                 csr->nfields = i;
  400. !                 ora_dropcursor(csr);
  401. !                 DEBUG(128, (fputs("ora_open: out of memory\n",
  402. !                     stderr)));
  403. !                 DEBUG(8, (fputs("ora_open: returning NOMEM\n",
  404. !                     stderr)));
  405. !                 ora_errno = ORAP_NOMEM;
  406. !                 return((char *) NULL);
  407. !             }
  408. !             DEBUG(128, (fprintf(stderr,
  409. !                 "ora_open: got field %d at %#lx\n",
  410. !                 i, csr->data[i])));
  411. !             odefin(csr->csr, i + 1, csr->data[i], dbsize + 1, 5, 0,
  412. !                 (short *) 0, (char *) 0, 0, 0, (short *) 0,
  413. !                 (char *) 0);
  414.           }
  415. !     }
  416. !     else
  417. !     {
  418. !         DEBUG(128, (fputs("ora_open: no data to return\n", stderr)));
  419. !         csr->data = NULL;
  420.       }
  421.   
  422.       sprintf(address, "%#lx", (long) csr);
  423. ***************
  424. *** 309,314 ****
  425. --- 335,397 ----
  426.       ora_errno = 0;
  427.       DEBUG(8, (fprintf(stderr,"ora_fetch: returning <%d>\n", csr->nfields)));
  428.       return(csr->nfields);
  429. + }
  430. + /* ora_bind(csr_s, vars, nitems)
  431. +  *
  432. +  * binds actual values to the SQL statement associated with csr
  433. +  */
  434. + int ora_bind(csr_s, vars, nitems)
  435. + char *csr_s, **vars;
  436. + int nitems;
  437. + {
  438. +     int i, ret;
  439. +     struct cursor *csr = (struct cursor *) strtol(csr_s, (char **) NULL, 0);
  440. +     DEBUG(8, (fprintf(stderr, "ora_bind(%#lx, %#lx, %d)\n",
  441. +         (long) csr, (long) vars, nitems)));
  442. +     if (check_csr(csr) == 0)
  443. +     {
  444. +         DEBUG(8, (fputs("ora_bind: returning 0\n", stderr)));
  445. +         ora_errno = ORAP_INVCSR;
  446. +         return(0);
  447. +     }
  448. +     if (csr->varfields != nitems)
  449. +     {
  450. +         DEBUG(8, (fprintf("ora_bind: expected %d items, got %d\n",
  451. +             csr->varfields, nitems)));
  452. +         ora_errno = ORAP_NUMVARS;
  453. +         return(0);
  454. +     }
  455. +     for (i = 0 ; i < nitems ; i++)
  456. +     {
  457. +         if ((ret = obndrn(csr->csr, i+1, vars[i], strlen(vars[i])+1,
  458. +             5, -1, (short *) -1, (char *) -1, 0, 0)) != 0)
  459. +         {
  460. +             ora_errno = csr->csr->csrrc;
  461. +             DEBUG(8, (fputs("ora_bind: returning 0\n", stderr)));
  462. +             return(0);
  463. +         }
  464. +         DEBUG(8, (fprintf(stderr, "ora_bind: obndrv %d %s OK\n",
  465. +             i + 1, vars[i])));
  466. +     }
  467. +     if (oexec(csr->csr) != 0)
  468. +     {
  469. +         ora_errno = csr->csr->csrrc;
  470. +         DEBUG(8, (fputs("ora_bind: returning 0\n", stderr)));
  471. +         return(0);
  472. +     }
  473. +     DEBUG(8, (fputs("ora_bind: oexec successful\n", stderr)));
  474. +     DEBUG(8, (fputs("ora_bind: returning 1\n", stderr)));
  475. +     return(1);
  476.   }
  477.   
  478.   
  479. diff -c /user/mis/kstock/tmp/orafns.h ./orafns.h
  480. *** /user/mis/kstock/tmp/orafns.h    Fri Aug 23 08:50:57 1991
  481. --- ./orafns.h    Mon Aug  5 11:01:40 1991
  482. ***************
  483. *** 17,23 ****
  484.           *ora_close(),
  485.           *ora_logoff();
  486.   
  487. ! int         ora_fetch();
  488.   
  489.   
  490.   /* These functions are internal to the system, not for public consumption */
  491. --- 17,24 ----
  492.           *ora_close(),
  493.           *ora_logoff();
  494.   
  495. ! int        ora_bind(),
  496. !         ora_fetch();
  497.   
  498.   
  499.   /* These functions are internal to the system, not for public consumption */
  500. ***************
  501. *** 66,72 ****
  502.       struct    csrdef    *csr;
  503.       char        *hda,        /* used if this cursor is an lda     */
  504.               **data;        /* used to receive database contents */
  505. !     int        nfields;    /* number of fields to retrieve         */
  506.       struct    cursor    *next;        /* list pointer                 */
  507.   };
  508.   
  509. --- 67,74 ----
  510.       struct    csrdef    *csr;
  511.       char        *hda,        /* used if this cursor is an lda     */
  512.               **data;        /* used to receive database contents */
  513. !     int        nfields,    /* number of fields to retrieve         */
  514. !             varfields;    /* number of modifiable variables    */
  515.       struct    cursor    *next;        /* list pointer                 */
  516.   };
  517.   
  518. ***************
  519. *** 73,78 ****
  520. --- 75,81 ----
  521.   
  522.   /* functions that we use */
  523.   
  524. + int    count_colons();
  525.   long    strtol();
  526.   char    *getenv(), *malloc();
  527.   
  528. ***************
  529. *** 125,131 ****
  530.   
  531.   #define    ORAP_ERRMIN    100000    /* lowest value allowed for an oraperl error */
  532.   
  533. ! #define    ORAP_NOMEM    100001    /* out of memory        */
  534. ! #define    ORAP_INVCSR    100002    /* invalid cursor supplied    */
  535. ! #define    ORAP_INVLDA    100003    /* invalid lda supplied        */
  536. ! #define    ORAP_NOSID    100004    /* couldn't set ORACLE_SID    */
  537. --- 128,136 ----
  538.   
  539.   #define    ORAP_ERRMIN    100000    /* lowest value allowed for an oraperl error */
  540.   
  541. ! #define    ORAP_NOMEM    100001    /* out of memory            */
  542. ! #define    ORAP_INVCSR    100002    /* invalid cursor supplied        */
  543. ! #define    ORAP_INVLDA    100003    /* invalid lda supplied            */
  544. ! #define    ORAP_NOSID    100004    /* couldn't set ORACLE_SID        */
  545. ! #define    ORAP_BADVAR    100005    /* bad colon variable sequence        */
  546. ! #define    ORAP_NUMVARS    100006    /* wrong number of colon variables    */
  547. diff -c /user/mis/kstock/tmp/oraperl.1 ./oraperl.1
  548. *** /user/mis/kstock/tmp/oraperl.1    Fri Aug 23 08:50:58 1991
  549. --- ./oraperl.1    Mon Aug  5 11:01:41 1991
  550. ***************
  551. *** 8,13 ****
  552. --- 8,14 ----
  553.   .nf
  554.   $lda = &ora_login($database, $name, $password)
  555.   $csr = &ora_open($lda, $stmt)
  556. + &ora_bind($csr, $var, ...)
  557.   &ora_fetch($csr)
  558.   &ora_close($csr)
  559.   &ora_logoff($lda)
  560. ***************
  561. *** 26,33 ****
  562.   using \fIora_login\fP.
  563.   This is called with three parameters, 
  564.   the system ID of the \fIOracle\fP database to be used,
  565. - (which \fIOracle\fP products expect
  566. - in the \fBORACLE_SID\fP environment variable)
  567.   and the \fIOracle\fP username and password.
  568.   The return value is a login identifier
  569.   (an \fIORACLE Login Data Area\fP).
  570. --- 27,32 ----
  571. ***************
  572. *** 40,45 ****
  573. --- 39,51 ----
  574.   The return value is a statement identifier
  575.   (an \fIORACLE cursor\fP).
  576.   
  577. + If the SQL statement contains substitution variables
  578. + (see later)
  579. + \fIora_bind\fP is used to assign values to them.
  580. + This takes a statement identifier (obtained from \fIora_open\fP)
  581. + as its first parameter,
  582. + followed by as many parameters as are required by the statement.
  583.   To retrieve the data returned from an \fISQL\fP \fBSELECT\fP statement,
  584.   the program should make successive calls to \fIora_fetch\fP.
  585.   This function takes a single parameter,
  586. ***************
  587. *** 71,76 ****
  588. --- 77,106 ----
  589.   from the last function call, and
  590.   \fIora_errstr\fP contains the \fIOracle\fP error message
  591.   corresponding to the current value of \fIora_errno\fP.
  592. + .SH SUBSTITUTION VARIABLES
  593. + \fIOraperl\fP allows an SQL statement to contain substitution variables.
  594. + These consist of a colon (\fB:\fP) followed by a number.
  595. + For example, a program which added records to a telephone list
  596. + might use the following call to \fIora_open\fP:
  597. + .ti +.5i
  598. + \f(CW$csr = &ora_open($csr, "insert into phonelist values(:1, :2)");\fP
  599. + The two names \fB:1\fP and \fB:2\fP are called substitution variables.
  600. + The function \fIora_bind\fP is used to assign values to these variables.
  601. + For example, the following statements would add two new people to the list:
  602. + .ti +.5i
  603. + \f(CW&ora_bind($csr, "Annette", "472-8836");\fP
  604. + .ti +.5i
  605. + \f(CW&ora_bind($csr, "Brian", "937-1823");\fP
  606. + Note that the substitution variables must be assigned consecutively
  607. + beginning from \fB1\fP for each SQL statement,
  608. + as \fBora_bind()\fP assigns its parameters in this order.
  609. + Named substitution variables
  610. + (for example, \fB:NAME\fP, \fB:TELNO\fP)
  611. + are not permitted.
  612.   .ne 28
  613.   .SH EXAMPLE
  614.   .if t .ft C
  615. ***************
  616. *** 90,96 ****
  617.   
  618.   die ("You should use oraperl, not perl\n") unless defined &ora_login;
  619.   
  620. ! $lda = &ora_login("t", "name", "password")
  621.       || die $ora_errstr;
  622.   $csr = &ora_open($lda, "select * from telno order by name")
  623.       || die $ora_errstr;
  624. --- 120,126 ----
  625.   
  626.   die ("You should use oraperl, not perl\n") unless defined &ora_login;
  627.   
  628. ! $lda = &ora_login("t", "kstock", "kstock")
  629.       || die $ora_errstr;
  630.   $csr = &ora_open($lda, "select * from telno order by name")
  631.       || die $ora_errstr;
  632. ***************
  633. *** 151,157 ****
  634.   \fIORACLE\fP by Oracle Corporation, California.
  635.   .br
  636.   \fIPerl\fP by Larry Wall, Netlabs
  637. ! (\f(CWlwall@netlabs.com\fP, \f(CWlwall@netlabs.com\fP).
  638.   .br
  639.   \fIOraperl\fP by Kevin Stock, Encore Computer SA, France
  640.   (\f(CWkstock@gouldfr.encore.fr\fP).
  641. --- 181,187 ----
  642.   \fIORACLE\fP by Oracle Corporation, California.
  643.   .br
  644.   \fIPerl\fP by Larry Wall, Netlabs
  645. ! (\f(CWlwall@netlabs.com\fP).
  646.   .br
  647.   \fIOraperl\fP by Kevin Stock, Encore Computer SA, France
  648.   (\f(CWkstock@gouldfr.encore.fr\fP).
  649. diff -c /user/mis/kstock/tmp/oraperl.doc ./oraperl.doc
  650. *** /user/mis/kstock/tmp/oraperl.doc    Fri Aug 23 08:50:23 1991
  651. --- ./oraperl.doc    Mon Aug  5 11:01:41 1991
  652. ***************
  653. *** 27,33 ****
  654.   because it requires fixed addresses to be specified for receipt of data.
  655.   A new interface was therefore created for \fBOraperl\fP.
  656.   
  657. ! The interface follows the idiom of the following five tasks:
  658.   
  659.   .in +5
  660.   .ta .4i 4.4i
  661. --- 27,33 ----
  662.   because it requires fixed addresses to be specified for receipt of data.
  663.   A new interface was therefore created for \fBOraperl\fP.
  664.   
  665. ! The interface follows the idiom of the following six tasks:
  666.   
  667.   .in +5
  668.   .ta .4i 4.4i
  669. ***************
  670. *** 34,51 ****
  671.   .nf
  672.   \fBTask        Interface\fP
  673.   
  674. ! \fB1\fP    log in to the database    ora_login
  675. ! \fB2\fP    open a stream for an SQL statement    ora_open
  676. ! \fB3\fP    get the data    ora_fetch
  677. ! \fB4\fP    close the stream    ora_close
  678. ! \fB5\fP    log off of the database    ora_logoff
  679.   .fi
  680.   .in -5
  681.   
  682. - Steps \fB2\fP and \fB3\fP are kept separate
  683. - because a single query may produce a large amount of data.
  684.   
  685.   .ce 2
  686.   \fBCursors\fP
  687.   _______
  688. --- 34,49 ----
  689.   .nf
  690.   \fBTask        Interface\fP
  691.   
  692. ! \fB1\fP    log in to the database    \fIora_login\fP
  693. ! \fB2\fP    open a stream for an SQL statement    \fIora_open\fP
  694. ! \fB3\fP    modify the statement    \fIora_bind\fP
  695. ! \fB4\fP    get the data    \fIora_fetch\fP
  696. ! \fB5\fP    close the stream    \fIora_close\fP
  697. ! \fB6\fP    log off of the database    \fIora_logoff\fP
  698.   .fi
  699.   .in -5
  700.   
  701.   
  702.   .ce 2
  703.   \fBCursors\fP
  704.   _______
  705. ***************
  706. *** 96,103 ****
  707.   
  708.   Requests a cursor (\fIcsr\fP)
  709.   and calls \fBOCI\ oopen\fP to connect it the the specified \fIlda\fP.
  710. ! It then calls \fBOCI\ osql3\fP to attach the SQL statement
  711. ! and \fBOCI\ oexec\fP to instruct \fIOracle\fP to execute it.
  712.   
  713.   If these three steps succeed,
  714.   \fBora_open\fP then makes successive calls to \fBOCI\ odsc\fP
  715. --- 94,102 ----
  716.   
  717.   Requests a cursor (\fIcsr\fP)
  718.   and calls \fBOCI\ oopen\fP to connect it the the specified \fIlda\fP.
  719. ! It then calls \fBOCI\ osql3\fP to attach the SQL statement.
  720. ! If the statement does not contain any substitution variables,
  721. ! \fIora_open\fP calls \fBOCI\ oexec\fP to instruct \fIOracle\fP to execute it.
  722.   
  723.   If these three steps succeed,
  724.   \fBora_open\fP then makes successive calls to \fBOCI\ odsc\fP
  725. ***************
  726. *** 105,110 ****
  727. --- 104,118 ----
  728.   It allocates memory for these fields within \fIcsr\fP
  729.   and attaches them to the cursor using \fBOCI\ odefin\fP.
  730.   It returns the address of the \fIcsr\fP.
  731. + \fBora_bind(csr, var, ...)\fP
  732. + Binds the specified \fIvar\fPs to the substitution variables
  733. + in the SQL statement identified by \fIcsr\fP
  734. + and calls \fBOCI\ oexec\fP to execute the resulting statement.
  735. + Assumes that the substitution variables are \fB:1\fP, \fB:2\fP, \fB:3\fP, etc
  736. + in the order that they appear in the \fBora_bind\fP call.
  737.   
  738.   
  739.   \fBora_fetch(csr)\fP
  740. diff -c /user/mis/kstock/tmp/oraperl.ref ./oraperl.ref
  741. *** /user/mis/kstock/tmp/oraperl.ref    Fri Aug 23 08:50:24 1991
  742. --- ./oraperl.ref    Mon Aug  5 11:01:41 1991
  743. ***************
  744. *** 17,25 ****
  745.   Returns an \fIlda\fP for use with \fIora_open()\fP.
  746.   .sp
  747.   .ti -2m
  748. ! \fB$csr = &ora_login($lda, $statement)\fP
  749. ! Executes the given SQL statement in the database identified by $lda.
  750.   Returns a \fIcsr\fP for use with \fIora_fetch()\fP.
  751.   .sp
  752.   .ti -2m
  753.   \fB$n = &ora_fetch($csr)\fP
  754. --- 17,31 ----
  755.   Returns an \fIlda\fP for use with \fIora_open()\fP.
  756.   .sp
  757.   .ti -2m
  758. ! \fB$csr = &ora_open($lda, $statement)\fP
  759. ! Associates the given SQL statement in the database identified by $lda.
  760. ! Executes it if it contains no substitution variables.
  761.   Returns a \fIcsr\fP for use with \fIora_fetch()\fP.
  762. + .sp
  763. + .ti -2m
  764. + \fB&ora_bind($csr, $var, ...)\fP
  765. + Binds the given values to the substition variables in the SQL statement
  766. + associated with $csr, and executes the resulting statement.
  767.   .sp
  768.   .ti -2m
  769.   \fB$n = &ora_fetch($csr)\fP
  770.