home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / sybperl / part01 < prev    next >
Encoding:
Text File  |  1993-05-04  |  53.3 KB  |  1,998 lines

  1. Newsgroups: comp.sources.misc
  2. From: mpeppler@itf0.itf.ch (Michael Peppler)
  3. Subject: v37i033:  sybperl - Sybase DB-library extensions to Perl, v1.6, Part01/02
  4. Message-ID: <csm-v37i033=sybperl.114102@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 7715119c3a5bb5d4ddf90672f2e3cb6b
  6. Date: Wed, 28 Apr 1993 16:41:32 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: mpeppler@itf0.itf.ch (Michael Peppler)
  10. Posting-number: Volume 37, Issue 33
  11. Archive-name: sybperl/part01
  12. Environment: UNIX, Perl, Sybase
  13. Supersedes: sybperl: Volume 28, Issue 33
  14.  
  15. This is Sybperl release 1.6.
  16.  
  17. Sybperl is an extension to Perl which allows you to access Sybase
  18. databases directly from Perl scripts using standard OpenClient (aka
  19. DB-Library) calls.
  20.  
  21. >From the CHANGES file:
  22.     1.006    Added contributed patches: &dbwritetext(),
  23.         &dbsafestr() and a modified &dblogin().
  24.         Added &dbhasretstats() and &dbretstatus(), as well as
  25.         some calls to DBlib macros such as DBCMD(),
  26.         DBMORECMD(), etc.
  27.         Received a patch to eg/space.pl from Wolfgang Richter.
  28.         Code that was defined to compile if BROKER_DBCMD was
  29.         defined has been removed. It was only a hack, making
  30.         use of knowledge of the structure of the DBPROCESS
  31.         data type.
  32.         Added the possibility to return an associative array
  33.         from &dbnextrow.
  34.         Added support for new datatypes (SYBREAL, SYBDATETIME4).
  35.         NULL values retrieved using &dbnextrow can be returned
  36.         as 'undef' instead of 'NULL' (this is a compile-time
  37.         option).
  38.  
  39. --
  40. Michael Peppler                           mpeppler@itf.ch
  41. ITF Management SA                      mpeppler@bix.com                         
  42. 13 Rue de la Fontaine                  Phone: (+4122) 312 1311  
  43. CH-1204 Geneva, Switzerland            Fax:   (+4122) 312 1322
  44. -------------------
  45. #! /bin/sh
  46. # This is a shell archive.  Remove anything before this line, then feed it
  47. # into a shell via "sh file" or similar.  To overwrite existing files,
  48. # type "sh file -c".
  49. # Contents:  README Makefile eg eg/dbschema.pl lib patchlevel.h
  50. #   sybperl.1 sybperl.c t
  51. # Wrapped by kent@sparky on Wed Apr 28 08:40:08 1993
  52. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  53. echo If this archive is complete, you will see the following message:
  54. echo '          "shar: End of archive 1 (of 2)."'
  55. if test -f 'README' -a "${1}" != "-c" ; then 
  56.   echo shar: Will not clobber existing file \"'README'\"
  57. else
  58.   echo shar: Extracting \"'README'\" \(3696 characters\)
  59.   sed "s/^X//" >'README' <<'END_OF_FILE'
  60. X
  61. X                 Sybperl, version 1.0
  62. X
  63. X
  64. X
  65. X   Sybperl is a set of user-defined subroutines letting you access a
  66. X   Sybase data server using Perl.
  67. X
  68. X   Requirements: Perl ver 3.0.27 or higher (4.035 strongly suggested!).
  69. X         Sybase DB-Library (aka Open Client)
  70. X
  71. X
  72. X   Compiling & Installing Sybperl:
  73. X   
  74. X   Unshar somewhere convenient, and edit Makefile to reflect your
  75. X   system setup. The following macros/defines may need to be set:
  76. X
  77. X       PERL_VERSION     Uncomment if you're using a Perl version
  78. X             earlier than 4.03
  79. X       UPERL/SAVESTR     See the comments in the Makefile, and the
  80. X             BUGS file. The defaults should work.
  81. X       HAS_CALLBACK     This enables the use of Perl subroutines as
  82. X             DB-Library error & message handlers. This is
  83. X             a new feature of Perl 4.018, but it might
  84. X             work with earlier versions.
  85. X       DBLIB42          If this Makefile macro is defined, then the
  86. X             newer datatypes (such as SYBREAL) will be
  87. X             handled correctly, and dbsafestr() will be
  88. X             implemented.
  89. X       SET_VAL         If this macro is set, then attempts to set a
  90. X             Sybperl user-variable (such as
  91. X             $NO_MORE_RESULTS) will result in a fatal
  92. X             error. Otherwise such attempts are silently
  93. X             ignored.
  94. X       NULL_UNDEF     If this macro is set, then NULL values
  95. X             returned from a select statement will be
  96. X             returned as 'undef' values. Otherwise, they
  97. X             are returned as the string 'NULL'.
  98. X       OLD_SYBPERL     This is a backwards compatibility flag -
  99. X             mainly for myself :-). It's main impact is to
  100. X             silently call dblogin()/dbopen() with default
  101. X             arguments if you omit to do so in the script.
  102. X
  103. X   The Makefile will not attempt to build uperl.o if it can't find it.
  104. X
  105. X   You may also need to edit the lib/sybperl.pl file to addapt it to
  106. X   your environment.
  107. X
  108. X   There are some test scripts in the t directory which you can run to
  109. X   see if all is well, and to get an idea of what can be done with
  110. X   sybperl. There are also some example scripts in the 'eg' directory.
  111. X
  112. X   Sybperl has been tested succesfully in the following environments:
  113. X
  114. X   Sun Sparc, SunOS 4.1.1, Sybase 4.0.1, Perl 4.010
  115. X   Sun 3/80, SunOS 4.0.3, Sybase 4.0.1, Perl 4.010
  116. X   Sun Sparc, SunOS 4.1, Sybase 4.2, Perl 4.010
  117. X   Pyramid MIServer 2/2, OSx V5.1a, Sybase 4.0, Perl 4.010
  118. X   
  119. X   I use sybperl daily in a production environment on a Sun 4/65 under
  120. X   SunOS 4.1.1, with Sybase version 4.0.1 and Perl 4.035
  121. X
  122. X   BUGS:
  123. X
  124. X   Both DBlibrary and Perl define a symbol named 'savestr', resulting
  125. X   in the Perl version being called from DBlibrary. See the BUGS file
  126. X   for ways to get around this problem.
  127. X
  128. X   Memory usage can also be a problem in certain cases. Again see the
  129. X   BUGS file for details.
  130. X
  131. X   BCP functions are not available, but would probably be useful.
  132. X
  133. X   Access to IMAGE datatypes isn't handled in &dbnextrow().
  134. X
  135. X
  136. X
  137. X   
  138. X   Have fun using it and let me know of any improvements, problems,
  139. X   whatever...
  140. X
  141. X   Michael Peppler            mpeppler@itf.ch    mpeppler@bix.com
  142. X   ITF Management SA            BIX:   mpeppler                         
  143. X   13 Rue de la Fontaine        Phone: (+4122) 312 1311  
  144. X   CH-1204 Geneva, Switzerland  Fax:   (+4122) 312 1322  
  145. X
  146. X   
  147. X
  148. X                   NOTICE - Warranty and Copyright
  149. X
  150. X           
  151. X   Sybperl is not a product of ITF Management. There is no warranty,
  152. X   and no official support.
  153. X
  154. X   Sybperl is copyright, but may be freely distributed under the
  155. X   same terms as Perl itself.
  156. X
  157. X
  158. X
  159. X   My thanks to the following people for testing Perl, and suggesting
  160. X   improvements:
  161. X
  162. X   Teemu Torma            Brent Milnor
  163. X   Matthew Merzbacher        Eric Fifer
  164. X   Dan Banay            Mark Lawrence
  165. X   Jeffrey Wong            Wolfgang Richter
  166. X   Anders Ardo            Gijs Mos
  167. X   Minh Ton Ha            G. Roderick Singleton
  168. X   Peter Gutmann
  169. X   
  170. END_OF_FILE
  171.   if test 3696 -ne `wc -c <'README'`; then
  172.     echo shar: \"'README'\" unpacked with wrong size!
  173.   fi
  174.   # end of 'README'
  175. fi
  176. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  177.   echo shar: Will not clobber existing file \"'Makefile'\"
  178. else
  179.   echo shar: Extracting \"'Makefile'\" \(3245 characters\)
  180.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  181. X#    @(#)Makefile    1.13    4/6/93
  182. X#
  183. X    
  184. XCC = gcc
  185. XPERLSRC = ..                # where to find uperl.o
  186. XSYBINCS = /usr/local/sybase/include    # where to find the sybase .h files
  187. XLOCINCS =                # other includes ?
  188. XSYBLIBDIR = /usr/local/lib        # Sybase libraries
  189. XSYBLIBS = -lsybdb            # db-library
  190. X
  191. X# Uncomment this if you are compiling sybperl for Perl version 3.xx
  192. X
  193. X# PERL_VERSION = -DVERSION3
  194. X
  195. X# The Perl/Sybase savestr() conflict.
  196. X# Both Perl and Sybase DB-Library have a function called savestr(),
  197. X# and this creates a problem when using functions such as dbcmd().
  198. X# There are several ways around this.
  199. X# You can:
  200. X#
  201. X#    - Recompile uperl.o with a -Dsavestr=psvestr (or something similar).
  202. X#    - Edit an existing uperl.o and change _savestr to _psvestr.
  203. X#
  204. X#
  205. X# To use the first option, you have to reconfigure & recompile Perl
  206. X# manually, and then set compile sybperl with the following line
  207. X# uncommented:
  208. X# UPERL = $(PERLSRC)/uperl.o
  209. X#
  210. X# The default is to use the third solution:
  211. XUPERL = uperl2.o
  212. X
  213. X
  214. XHAS_CALLBACK= -DHAS_CALLBACK        # Remove this if you don't
  215. X                    # have Perl 4 patchlevel 18
  216. X                    # User defined, perl based
  217. X                    # error/message handlers are
  218. X                    # not possible without this, however.
  219. XOLD_SYBPERL= -DOLD_SYBPERL        # some backward compatibility stuff.
  220. X
  221. X#DBLIB42 = -DDBLIB42            # Comment this if your version
  222. X                    # of DBlib is older than
  223. X                    # version 4.2
  224. X
  225. X#SET_VAL = -DUSERVAL_SET_FATAL        # Uncomment this if you wish
  226. X                    # to get a fatal error message
  227. X                    # if you attempt to set on of
  228. X                    # Sybperl's variables from a
  229. X                    # script. Normally such
  230. X                    # actions are silently ignored.
  231. X
  232. X#NULL_UNDEF = -DNULL_IS_UNDEF           # Uncomment this to get
  233. X                    # 'undef' values returned by
  234. X                    # &dbnextrow when NULL values
  235. X                    # are retrieved. Otherwise,
  236. X                    # the string 'NULL' is returned.
  237. X
  238. XCFLAGS = -O2 -g
  239. XCPPFLAGS = -I$(PERLSRC) -I$(LOCINCS) -I$(SYBINCS) $(PERL_VERSION) \
  240. X        $(SAVESTR) $(HAS_CALLBACK) $(OLD_SYBPERL) $(DBLIB42) \
  241. X        $(SET_VAL)
  242. XBINDIR = /usr/local/bin            # where does the executable go
  243. XPERLLIB = /usr/local/lib/perl        # where does lib/sybperl.pl
  244. X                    # and lib/sybdb.ph go
  245. XMANDIR = /usr/local/man            # where do we put the manual page
  246. XMANEXT = l
  247. X
  248. X
  249. Xsybperl: $(UPERL) sybperl.o
  250. X    $(CC) $(CFLAGS) -L$(SYBLIBDIR) $(UPERL) sybperl.o $(SYBLIBS) -lm -o sybperl
  251. X
  252. Xsybperl.o: sybperl.c
  253. X    $(CC) -c $(CFLAGS) $(CPPFLAGS) sybperl.c
  254. X
  255. X# Create uperl.o IF you wish to use the 3rd way of resolving the
  256. X# Perl/Sybase savestr conflict.
  257. X$(UPERL): $(PERLSRC)/uperl.o
  258. X    cp $(PERLSRC)/uperl.o $(UPERL)
  259. X    perl -p -i.bak -e 's/savestr/psvestr/g;' $(UPERL)
  260. X    rm -f $(UPERL).bak
  261. X
  262. X
  263. Xclean:
  264. X    rm -f sybperl *.o *~ core
  265. X
  266. Xinstall: sybperl
  267. X    install -s -m 775 sybperl $(BINDIR)
  268. X    cp lib/syb*.p? $(PERLLIB)/perllib.pl
  269. X    cp sybperl.1 $(MANDIR)/man$(MANEXT)/sybperl.$(MANEXT)
  270. X
  271. Xshar:
  272. X    rm -f sybperl.shar
  273. X    shar.pl README PACKING.LST BUGS CHANGES Makefile sybperl.c \
  274. X    sybperl.1 patchlevel.h lib/sybperl.pl lib/sybdb.ph t/sbex.pl \
  275. X    eg/sql.pl eg/space.pl eg/capture.pl eg/report.pl \
  276. X    eg/dbschema.pl eg/dbtext.pl eg/README >sybperl.shar
  277. X
  278. X
  279. Xtar:
  280. X    rm -f sybperl.tar
  281. X    tar cvfB sybperl.tar README PACKING.LST BUGS CHANGES Makefile sybperl.c \
  282. X    sybperl.1 patchlevel.h lib/sybperl.pl lib/sybdb.ph t/sbex.pl \
  283. X    eg/sql.pl eg/space.pl eg/capture.pl eg/report.pl \
  284. X    eg/dbschema.pl eg/dbtext.pl eg/README
  285. X
  286. X
  287. X
  288. X
  289. X
  290. END_OF_FILE
  291.   if test 3245 -ne `wc -c <'Makefile'`; then
  292.     echo shar: \"'Makefile'\" unpacked with wrong size!
  293.   fi
  294.   # end of 'Makefile'
  295. fi
  296. if test ! -d 'eg' ; then
  297.     echo shar: Creating directory \"'eg'\"
  298.     mkdir 'eg'
  299. fi
  300. if test -f 'eg/dbschema.pl' -a "${1}" != "-c" ; then 
  301.   echo shar: Will not clobber existing file \"'eg/dbschema.pl'\"
  302. else
  303.   echo shar: Extracting \"'eg/dbschema.pl'\" \(9358 characters\)
  304.   sed "s/^X//" >'eg/dbschema.pl' <<'END_OF_FILE'
  305. X#! /usr/local/bin/sybperl
  306. X#
  307. X#    @(#)dbschema.pl    1.3    6/24/92
  308. X#
  309. X#
  310. X#    dbschema.pl    A script to extract a database structure from
  311. X#            a Sybase database
  312. X#
  313. X#    Written by:    Michael Peppler (mpeppler@itf.ch)
  314. X#    Last Modified:  24 June 1992
  315. X#
  316. X#    Usage:        dbschema.pl -d database -o script.name -t pattern -v
  317. X#                where   database is self-explanatory (default: master)
  318. X#                                   script.name is the output file (default: script.isql)
  319. X#                                   pattern is the pattern of object names (in sysobjects)
  320. X#                                           that we will look at (default: %)
  321. X#
  322. X#                -v turns on a verbose switch.
  323. X#
  324. X
  325. X
  326. Xrequire 'sybperl.pl';
  327. Xrequire 'getopts.pl';
  328. Xrequire 'ctime.pl';
  329. X
  330. X@nul = ('not null','null');
  331. X
  332. Xselect(STDOUT); $| = 1;        # make unbuffered
  333. X
  334. Xdo Getopts('d:t:o:v');
  335. X
  336. X$opt_d = 'master' unless $opt_d;
  337. X$opt_o = 'script.isql' unless $opt_o;
  338. X$opt_t = '%' unless $opt_t;
  339. X
  340. Xopen(SCRIPT, "> $opt_o") || die "Can't open $opt_o: $!\n";
  341. Xopen(LOG, "> $opt_o.log") || die "Can't open $opt_o.log: $!\n";
  342. X
  343. X#
  344. X# NOTE: We login to Sybase with the default (Unix) user id.
  345. X#       We should probably login as 'SA', and get the passwd
  346. X#       from the user at run time.
  347. X#
  348. X$dbproc = &dblogin;
  349. X&dbuse($dproc, $opt_d);
  350. X
  351. Xchop($date = &ctime(time));
  352. X
  353. X
  354. Xprint "dbschema.pl on Database $opt_d\n";
  355. X
  356. Xprint LOG "Error log from dbschema.pl on Database $opt_d on $date\n\n";
  357. Xprint LOG "The following objects cannot be reliably created from the script in $opt_o.
  358. XPlease correct the script to remove any inconsistencies.\n\n";
  359. X
  360. Xprint SCRIPT
  361. X    "/* This Isql script was generated by dbschema.pl on $date.
  362. X** The indexes need to be checked: column names & index names
  363. X** might be truncated!
  364. X*/\n";
  365. X
  366. Xprint SCRIPT "\nuse $opt_d\ngo\n"; # Change to the appropriate database
  367. X
  368. X
  369. X# first, Add the appropriate user data types:
  370. X#
  371. X
  372. Xprint "Add user-defined data types...";
  373. Xprint SCRIPT
  374. X    "/* Add user-defined data types: */\n\n";
  375. X
  376. X&dbcmd($dbproc, "select s.length, s.name, st.name,\n");
  377. X&dbcmd($dbproc, "       object_name(s.tdefault),\n");
  378. X&dbcmd($dbproc, "       object_name(s.domain)\n");
  379. X&dbcmd($dbproc, "from   $opt_d.dbo.systypes s, $opt_d.dbo.systypes st\n");
  380. X&dbcmd($dbproc, "where  st.type = s.type\n");
  381. X&dbcmd($dbproc, "and s.usertype > 100 and st.usertype < 100 and st.usertype != 18\n");
  382. X&dbsqlexec($dbproc);
  383. X&dbresults($dbproc);
  384. X
  385. X
  386. Xwhile((@dat = &dbnextrow($dbproc)))
  387. X{
  388. X    print SCRIPT "sp_addtype $dat[1],";
  389. X    if ($dat[2] =~ /char|binary/)
  390. X    {
  391. X        print SCRIPT "'$dat[2]($dat[0])'";
  392. X    }
  393. X    else
  394. X    {
  395. X        print SCRIPT "$dat[2]";
  396. X    }
  397. X    print SCRIPT "\ngo\n";
  398. X                # Now remeber the default & rule for later.
  399. X    $urule{$dat[1]} = $dat[4] if $dat[4] !~ /NULL/;
  400. X    $udflt{$dat[1]} = $dat[3] if $dat[3] !~ /NULL/;
  401. X}
  402. X
  403. Xprint "Done\n";
  404. X
  405. Xprint "Create rules...";
  406. Xprint SCRIPT
  407. X    "\n/* Now we add the rules... */\n\n";
  408. X
  409. X&getObj('Rule', 'R');
  410. Xprint "Done\n";
  411. X
  412. Xprint "Create defaults...";
  413. Xprint SCRIPT
  414. X    "\n/* Now we add the defaults... */\n\n";
  415. X
  416. X&getObj('Default', 'D');
  417. Xprint "Done\n";
  418. X
  419. Xprint "Bind rules & defaults to user data types...";
  420. Xprint SCRIPT "/* Bind rules & defaults to user data types... */\n\n";
  421. X
  422. Xwhile(($dat, $dflt)=each(%udflt))
  423. X{
  424. X    print SCRIPT "sp_bindefault $dflt, $dat\ngo\n";
  425. X}
  426. Xwhile(($dat, $rule) = each(%urule))
  427. X{
  428. X    print SCRIPT "sp_bindrule $rule, $dat\ngo\n";
  429. X}
  430. Xprint "Done\n";
  431. X
  432. Xprint "Create Tables & Indices...";
  433. Xprint "\n" if $opt_v;
  434. X
  435. X&dbcmd($dbproc, "select o.name,u.name, o.id\n");
  436. X&dbcmd($dbproc, "from $opt_d.dbo.sysobjects o, $opt_d.dbo.sysusers u\n");
  437. X&dbcmd($dbproc, "where o.type = 'U' and o.name like '$opt_t' and u.uid = o.uid\n");
  438. X&dbcmd($dbproc, "order by o.name\n");
  439. X
  440. X&dbsqlexec($dbproc);
  441. X&dbresults($dbproc);
  442. X
  443. Xwhile((@dat = &dbnextrow($dbproc)))
  444. X{
  445. X    $_ = join('@', @dat);    # join the data together on a line
  446. X    push(@tables,$_);        # and save it in a list
  447. X}
  448. X
  449. X
  450. Xforeach (@tables)        # For each line in the list
  451. X{
  452. X    @tab = split(/@/, $_);
  453. X
  454. X    print "Creating table $tab[0], owner $tab[1]\n" if $opt_v;
  455. X
  456. X    print SCRIPT "/* Start of description of table $tab[1].$tab[0] */\n\n";
  457. X
  458. X    &dbcmd($dbproc, "select Column_name = c.name, \n");
  459. X    &dbcmd($dbproc, "       Type = t.name, \n");
  460. X    &dbcmd($dbproc, "       Length = c.length, \n");
  461. X    &dbcmd($dbproc, "       Nulls = convert(bit, (c.status & 8)),\n");
  462. X    &dbcmd($dbproc, "       Default_name = object_name(c.cdefault),\n");
  463. X    &dbcmd($dbproc, "       Rule_name = object_name(c.domain)\n");
  464. X    &dbcmd($dbproc, "from   $opt_d.dbo.syscolumns c, $opt_d.dbo.systypes t\n");
  465. X    &dbcmd($dbproc, "where  c.id = $tab[2]\n");
  466. X    &dbcmd($dbproc, "and    c.usertype *= t.usertype\n");
  467. X
  468. X    &dbsqlexec($dbproc);
  469. X    &dbresults($dbproc);
  470. X
  471. X    undef(%rule);
  472. X    undef(%dflt);
  473. X
  474. X    print SCRIPT "\n\nCREATE TABLE $opt_d.$tab[1].$tab[0]\n ("; 
  475. X    $first = 1;
  476. X    while((@field = &dbnextrow($dbproc)))
  477. X    {
  478. X        print SCRIPT ",\n" if !$first;        # add a , and a \n if not first field in table
  479. X        
  480. X        print SCRIPT "\t$field[0] \t$field[1]";
  481. X        print SCRIPT "($field[2])" if $field[1] =~ /char|bin/;
  482. X        print SCRIPT " $nul[$field[3]]";
  483. X    
  484. X    $rule{"$tab[0].$field[0]"} = $field[5] if ($field[5] !~ /NULL/ && $urule{$field[1]} ne $field[5]);
  485. X    $dflt{"$tab[0].$field[0]"} = $field[4] if ($field[4] !~ /NULL/ && $udflt{$field[1]} ne $field[4]);;
  486. X        $first = 0 if $first;
  487. X        
  488. X    }
  489. X    print SCRIPT " )\n";
  490. X
  491. X# now get the indexes...
  492. X#
  493. X
  494. X    print "Indexes for table $tab[1].$tab[0]\n" if $opt_v;
  495. X    
  496. X    &dbcmd($dbproc, "sp_helpindex '$tab[1].$tab[0]'\n");
  497. X
  498. X    &dbsqlexec($dbproc);
  499. X    &dbresults($dbproc);
  500. X
  501. X    while((@field = &dbnextrow($dbproc)))
  502. X    {
  503. X        print SCRIPT "\nCREATE ";
  504. X        print SCRIPT "unique " if $field[1] =~ /unique/;
  505. X        print SCRIPT "clustered " if $field[1] =~ /^clust/;
  506. X        print SCRIPT "index $field[0]\n";
  507. X        @col = split(/,/,$field[2]);
  508. X        print SCRIPT "on $opt_d.$tab[1].$tab[0] (";
  509. X        $first = 1;
  510. X        foreach (@col)
  511. X        {
  512. X            print SCRIPT ", " if !$first;
  513. X            $first = 0;
  514. X            print SCRIPT "$_";
  515. X        }
  516. X        print SCRIPT ")\n";
  517. X    }
  518. X
  519. X    &getPerms("$tab[1].$tab[0]");
  520. X
  521. X    print SCRIPT "go\n";
  522. X
  523. X    print "Bind rules & defaults to columns...\n" if $opt_v;
  524. X    print SCRIPT "/* Bind rules & defaults to columns... */\n\n";
  525. X
  526. X    if($tab[1] ne 'dbo' && (keys(%dflt) || keys(%rules)))
  527. X    {
  528. X    print SCRIPT "/* The owner of the table is $tab[1].
  529. X** I can't bind the rules/defaults to a table of which I am not the owner.
  530. X** The procedures below will have to be run manualy by user $tab[1].
  531. X*/";
  532. X    print LOG "Defaults/Rules for $tab[1].$tab[0] could not be bound\n";
  533. X    }
  534. X
  535. X    while(($dat, $dflt)=each(%dflt))
  536. X    {
  537. X    print SCRIPT "/* " if $tab[1] ne 'dbo';
  538. X    print SCRIPT "sp_bindefault $dflt, '$dat'";
  539. X    if($tab[1] ne 'dbo')
  540. X    {
  541. X        print SCRIPT " */\n";
  542. X    }
  543. X    else
  544. X    {
  545. X        print SCRIPT "\ngo\n";
  546. X    }
  547. X    }
  548. X    while(($dat, $rule) = each(%rule))
  549. X    {
  550. X    print SCRIPT "/* " if $tab[1] ne 'dbo';
  551. X    print SCRIPT "sp_bindrule $rule, '$dat'";
  552. X    if($tab[1] ne 'dbo')
  553. X    {
  554. X        print SCRIPT " */\n";
  555. X    }
  556. X    else
  557. X    {
  558. X        print SCRIPT "\ngo\n";
  559. X    }
  560. X    }
  561. X    print SCRIPT "\n/* End of description of table $tab[1].$tab[0] */\n";
  562. X
  563. X}
  564. X
  565. Xprint "Done\n";
  566. X
  567. X
  568. X#
  569. X# Now create any views that might exist
  570. X#
  571. X
  572. Xprint "Create views...";
  573. Xprint SCRIPT
  574. X    "\n/* Now we add the views... */\n\n";
  575. X
  576. X&getObj('View', 'V');
  577. X
  578. Xprint "Done\n";
  579. X
  580. X#
  581. X# Now create any stored procs that might exist
  582. X#
  583. X
  584. Xprint "Create stored procs...";
  585. Xprint SCRIPT
  586. X    "\n/* Now we add the stored procedures... */\n\n";
  587. X&getObj('Stored Proc', 'P');
  588. X
  589. Xprint "Done\n";
  590. X
  591. X#
  592. X# Now create the triggers
  593. X#
  594. X
  595. Xprint "Create triggers...";
  596. Xprint SCRIPT
  597. X    "\n/* Now we add the triggers... */\n\n";
  598. X
  599. X&getObj('Trigger', 'TR');
  600. X
  601. X
  602. Xprint "Done\n";
  603. X
  604. Xprint "\nLooks like I'm all done!\n";
  605. Xclose(SCRIPT);
  606. Xclose(LOG);
  607. X
  608. X&dbexit;
  609. X
  610. X
  611. Xsub getPerms
  612. X{
  613. X    local($obj) = $_[0];
  614. X    local($ret, @dat, $act, $cnt);
  615. X
  616. X    &dbcmd($dbproc, "sp_helprotect '$obj'\n");
  617. X    &dbsqlexec;
  618. X
  619. X    $cnt = 0;
  620. X    while(($ret = &dbresults) != $NO_MORE_RESULTS && $ret != $FAIL)
  621. X    {
  622. X    while(@dat = &dbnextrow)
  623. X    {
  624. X        $act = 'to';
  625. X        $act = 'from' if $dat[0] =~ /Revoke/;
  626. X        print SCRIPT "$dat[0] $dat[1] on $obj $act $dat[2]\n";
  627. X        ++$cnt;
  628. X    }
  629. X    }
  630. X    $cnt;
  631. X}
  632. X
  633. Xsub getObj
  634. X{
  635. X    local($objname, $obj) = @_;
  636. X    local(@dat, @items, @vi, $found);
  637. X    
  638. X    &dbcmd($dbproc, "select o.name, u.name, o.id\n");
  639. X    &dbcmd($dbproc, "from $opt_d.dbo.sysobjects o, $opt_d.dbo.sysusers u\n");
  640. X    &dbcmd($dbproc, "where o.type = '$obj' and o.name like '$opt_t' and u.uid = o.uid\n");
  641. X    &dbcmd($dbproc, "order by o.name\n");
  642. X
  643. X    &dbsqlexec($dbproc);
  644. X    &dbresults($dbproc);
  645. X
  646. X    while((@dat = &dbnextrow($dbproc)))
  647. X    {                # 
  648. X    $_ = join('@', @dat);    # join the data together on a line
  649. X    push(@items, $_);    # and save it in a list
  650. X    }
  651. X
  652. X    foreach (@items)
  653. X    {
  654. X    @vi = split(/@/, $_);
  655. X    $found = 0;
  656. X
  657. X    &dbcmd($dbproc, "select text from syscomments where id = $vi[2]");
  658. X    &dbsqlexec;
  659. X    &dbresults;
  660. X    
  661. X    print SCRIPT
  662. X        "/* $objname $vi[0], owner $vi[1] */\n";
  663. X
  664. X    while(($text) = &dbnextrow)
  665. X    {
  666. X        if(!$found && $vi[1] ne 'dbo')
  667. X        {
  668. X        ++$found if($text =~ /$vi[1]/);
  669. X        }
  670. X        print SCRIPT $text;
  671. X    }
  672. X    print SCRIPT "\ngo\n";
  673. X    if(!$found && $vi[1] ne 'dbo')
  674. X    {
  675. X        print "**Warning**\n$objname $vi[0] has owner $vi[1]\nbut this is not mentioned in the CREATE PROC statement!!\n";
  676. X        print LOG "$objname $vi[0] (owner $vi[1])\n";
  677. X    }
  678. X    }
  679. X}
  680. X
  681. X
  682. END_OF_FILE
  683.   if test 9358 -ne `wc -c <'eg/dbschema.pl'`; then
  684.     echo shar: \"'eg/dbschema.pl'\" unpacked with wrong size!
  685.   fi
  686.   chmod +x 'eg/dbschema.pl'
  687.   # end of 'eg/dbschema.pl'
  688. fi
  689. if test ! -d 'lib' ; then
  690.     echo shar: Creating directory \"'lib'\"
  691.     mkdir 'lib'
  692. fi
  693. if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  694.   echo shar: Will not clobber existing file \"'patchlevel.h'\"
  695. else
  696.   echo shar: Extracting \"'patchlevel.h'\" \(41 characters\)
  697.   sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
  698. X#define VERSION 1
  699. X#define PATCHLEVEL 6
  700. X
  701. X
  702. END_OF_FILE
  703.   if test 41 -ne `wc -c <'patchlevel.h'`; then
  704.     echo shar: \"'patchlevel.h'\" unpacked with wrong size!
  705.   fi
  706.   # end of 'patchlevel.h'
  707. fi
  708. if test -f 'sybperl.1' -a "${1}" != "-c" ; then 
  709.   echo shar: Will not clobber existing file \"'sybperl.1'\"
  710. else
  711.   echo shar: Extracting \"'sybperl.1'\" \(5452 characters\)
  712.   sed "s/^X//" >'sybperl.1' <<'END_OF_FILE'
  713. X.\".po 4
  714. X.TH SYBPERL 1 "2 April 1993"
  715. X.ad
  716. X.nh
  717. X.SH NAME
  718. Xsybperl \- Perl access to Sybase databases
  719. X.SH SYNOPSIS
  720. X.nf
  721. X$dbproc  = &dblogin([$user[, $pwd[, $server]]])
  722. X$dbproc1 = &dbopen([$server])
  723. X       &dbclose($dbproc)
  724. X$ret     = &dbcmd($dbproc, $sql_cmd)
  725. X$ret     = &dbsqlexec($dbproc)
  726. X$ret     = &dbresults($dbproc)
  727. X@data    = &dbnextrow($dbproc [, $doAssoc])
  728. X$ret     = &dbuse($dbproc, $database)
  729. X$ret     = &dbcancel($dbproc)
  730. X$ret     = &dbcanquery($dbproc)
  731. X$ret     = &dbexit($dbproc)
  732. X$string  = &dbstrcpy($dbproc)
  733. X$string  = &dbsafestr($dbproc,$instring[,$quote_char])
  734. X$status  = &dbwritetext($dbproc_1, $col_name, $dbproc_2, $select_col, $text)
  735. X$ret     = &dberrhandle($handler)
  736. X$ret     = &dbmsghandle($handler)
  737. X
  738. X$SUCCEED
  739. X$FAIL
  740. X$NO_MORE_ROWS
  741. X$NO_MORE_RESULTS
  742. X$ComputeId
  743. X$DBstatus
  744. X$SybperlVer
  745. X$DBReturnAssoc
  746. X.fi
  747. X.SH DESCRIPTION
  748. X\fBSybperl\fP is a version of \fIPerl\fP which has been extended (via
  749. Xthe \fIusersubs\fP feature) to allow access to \fISybase\fP databases.
  750. X.SH Functions
  751. X\fBSybperl\fP basically maps the calls existing in the \fISybase
  752. XDB-Library\fP to \fIPerl\fP. The usage of these functions is the same
  753. Xas in \fIDB-Library\fP, unless specifically noted.
  754. X
  755. XThe following functions are provided:
  756. X
  757. X.nf
  758. X\fB$dbproc  = &dblogin([$user[, $pwd[, $server]]])\fP
  759. X\fB&dbproc1 = &dbopen([$server])\fP
  760. X\fB          &dbclose($dbproc)\fP
  761. X\fB$status  = &dbcmd($dbproc, $sql_cmd)\fP
  762. X\fB$status  = &dbsqlexec($dbproc)\fP
  763. X\fB$status  = &dbresults($dbproc)\fP
  764. X\fB@data    = &dbnextrow($dbproc [, $doAssoc])\fP
  765. X\fB$status  = &dbuse($dbproc, $database)\fP
  766. X\fB$status  = &dbcancel($dbproc)\fP
  767. X\fB$status  = &dbcanquery($dbproc)\fP
  768. X\fB$status  = &dbexit($dbproc)\fP
  769. X\fB$string  = &dbstrcpy($dbproc)\fP
  770. X\fB$string  = &dbsafestr($dbproc,$instring[,$quote_char])\fP
  771. X\fB$old_handler  = &dberrhandle($handler)\fP
  772. X\fB$old_handler  = &dbmsghandle($handler)\fP
  773. X\fB$status  = &dbwritetext($dbproc_1, $col_name, $select_proc,
  774. X$select_col, $text)\fP
  775. X.fi
  776. X
  777. XDifferences with DB-Library:
  778. X
  779. X\fB&dblogin\fP takes 3 optional arguements (the userid, the
  780. Xpassword and the server to connect to). These default to the Unix
  781. Xuserid, the null password and the default server (from the DSQUERY
  782. Xenvironment variable).
  783. X
  784. X\fB&dblogin\fP returns a \fBDBPROCESS\fP, not a \fBLOGINREC\fP. This
  785. Xsimplifies the call to open a connection to a Sybase dataserver
  786. Xsomewhat. If the login fails for any reason \fB&dblogin\fP returns -1.
  787. X\fB&dblogin\fP can be called multiple times to login to different
  788. Xservers, or to login as several users simultaneously.
  789. X
  790. XFurther \fBDBPROCESSes\fP can be opened using
  791. X\fB&dbopen([$server])\fP, using the login information from the
  792. Xlast call to \fB&dblogin()\fP. The number of simultaneous DBPROCESSes
  793. Xis limited to 25 (This can be changed by altering a #define in sybperl.c).
  794. X
  795. XThe \fB$dbproc\fP parameter used by most subroutines is optional,
  796. Xand defaults to the DBPROCESS returned
  797. Xby the first call to \fB&dblogin\fP (exceptions: \fB&dbsafestr()\fP and
  798. X\fB&dbwritetext()\fP require explicit \fB$dbproc\fP parameters.)
  799. X
  800. X
  801. X\fB&dbnextrow\fP returns an array of formatted data, based on the
  802. Xdatatype of the corresponding columns. \fB&dbnextrow\fP sets the
  803. Xvariable \fB$ComputeId\fP when the result row is a computed row (the
  804. Xresult of a \fIcompute by\fP clause). If the optional \fB$doAssoc\fP
  805. Xparameter is non-zero \fB&dbnextrow\fP returns an
  806. Xassociative array keyed on the column name of each returned field.
  807. X
  808. X\fB&dbsafestr\fP takes a string literal ' or " as the third [optional] argument
  809. Xand means \fBDBSINGLE\fP or \fBDBDOUBLE\fP, respectively.
  810. XOmission of the third argument means \fBDBBOTH\fP.
  811. X
  812. XIn order to simplify its use somewhat, the calling sequence of
  813. X\fB&dbwritetext\fP has been changed. \fI$select_proc\f and
  814. X\fI$select_col\fP are the dbproc and column number of a currently
  815. Xactive query. Logging is always off.
  816. X
  817. X
  818. X.SH "UNIMPLEMENTED FEATURES"
  819. X
  820. XThe \fBSYBIMAGE\fP data type is not implemented.
  821. X
  822. X\fB&dbfcmd\fP is not implemented, but can be emulated by using
  823. X\fIsprintf\fP as in \fI&dbcmd($dbproc, sprintf("%d", $num_val))\;\fP
  824. X
  825. X
  826. X.SH OPTIONS
  827. X
  828. XSee the \fIPerl(1)\fP manual page.
  829. X
  830. X.SH BUGS
  831. X
  832. XMemory usage can become very large in certain conditions when
  833. Xusing a version of Perl prior to 4.035. This
  834. Xcan be circumvented - see the BUGS file in the Sybperl distribution.
  835. X
  836. XIf \fB&dbnextrow\fP encounters a datatype that it does not know about,
  837. Xit tries to convert it to SYBCHAR, and to store it in a 256 byte
  838. Xbuffer - without checking for overflow.
  839. X
  840. XThe handling of multiple logins isn't really clean. A call to
  841. X\fB&dblogin\fP sets the values for the User name and Password. These
  842. Xvalues are remembered - and used in calls to \fB&dbopen\fP - until
  843. Xthey are changed in a new call to \fB&dblogin()\fP. It is possible to
  844. Xavoid the use of \fB&dbopen\fP alltogether, and simply call
  845. X\fB&dblogin\fP each time a new \fBDBPROCESS\fP is required.
  846. X
  847. X.SH FILES
  848. X
  849. X\fI$PERLLIB/sybperl.pl\fP should be called in all \fBsybperl\fP
  850. Xscripts to set the correct environment variables used by DB-Library.
  851. XA sample \fI$PERLLIB/sybdb.ph\fP is provided with sybperl. You may
  852. Xwant to use \fBh2ph\fP to add definitions to this file.
  853. X
  854. X.SH "SEE ALSO"
  855. X
  856. X\fIPerl(1L), Sybase Open Client DB Library Reference Manual, h2ph(1L).\fP
  857. X
  858. X.SH AUTHOR
  859. X
  860. XMichael Peppler, ITF Management SA \- mpeppler@itf.ch
  861. XBrent Milnor (brent@oceania.com) contributed &dbwritetext().
  862. XEric Fifer (egf@sbi.com) contributed corrections to the
  863. X&dblogin()/&dbopen() sequence
  864. XMark Lawrence (mark@drd.com) contributed &dbsafestr().
  865. END_OF_FILE
  866.   if test 5452 -ne `wc -c <'sybperl.1'`; then
  867.     echo shar: \"'sybperl.1'\" unpacked with wrong size!
  868.   fi
  869.   # end of 'sybperl.1'
  870. fi
  871. if test -f 'sybperl.c' -a "${1}" != "-c" ; then 
  872.   echo shar: Will not clobber existing file \"'sybperl.c'\"
  873. else
  874.   echo shar: Extracting \"'sybperl.c'\" \(25807 characters\)
  875.   sed "s/^X//" >'sybperl.c' <<'END_OF_FILE'
  876. Xstatic char SccsId[] = "@(#)sybperl.c    1.14    4/6/93";
  877. X/************************************************************************/
  878. X/*    Copyright 1991, 1992, 1993 by Michael Peppler            */
  879. X/*                               and ITF Management SA             */
  880. X/*                                    */
  881. X/*    Full ownership of this software, and all rights pertaining to     */
  882. X/*    the for-profit distribution of this software, are retained by     */
  883. X/*    Michael Peppler and ITF Management SA.  You are permitted to     */
  884. X/*    use this software without fee.  This software is provided "as     */
  885. X/*    is" without express or implied warranty.  You may redistribute     */
  886. X/*    this software, provided that this copyright notice is retained,    */
  887. X/*    and that the software is not distributed for profit.  If you     */
  888. X/*    wish to use this software in a profit-making venture, you must     */
  889. X/*    first license this code and its underlying technology from     */
  890. X/*    ITF Management SA.                         */
  891. X/*                                    */
  892. X/*    Bottom line: you can have this software, you can use it, you     */
  893. X/*    can give it away.  You just can't sell any or all parts of it     */
  894. X/*    without prior permission from ITF Management SA.        */
  895. X/************************************************************************/
  896. X
  897. X/* sybperl.c
  898. X *
  899. X * Call Sybase DB-Library functions from Perl.
  900. X * Written by Michael Peppler (mpeppler@itf.ch)
  901. X * ITF Management SA, 13 rue de la Fontaine
  902. X * CH-1204 Geneva, Switzerland
  903. X * Tel: (+4122) 312 1311 Fax: (+4122) 312 1322
  904. X */
  905. X
  906. X#include "EXTERN.h"
  907. X#include "perl.h"
  908. X#undef MAX
  909. X#undef MIN
  910. X
  911. X#if defined(VERSION3)
  912. X#define str_2mortal(s)        str_2static(s)
  913. X#endif
  914. X
  915. X#include <sybfront.h>
  916. X#include <sybdb.h>
  917. X#include <syberror.h>
  918. X
  919. X#include "patchlevel.h"
  920. X
  921. Xextern int wantarray;
  922. X
  923. X/* 
  924. X * The variables that the Sybase routines set, and that you may want 
  925. X * to test in your Perl script. These variables are READ-ONLY.
  926. X */
  927. Xstatic enum uservars
  928. X{
  929. X    UV_SUCCEED,            /* Returns SUCCEED */
  930. X    UV_FAIL,            /* Returns FAIL */
  931. X    UV_NO_MORE_ROWS,        /* Returns NO_MORE_ROWS */
  932. X    UV_NO_MORE_RESULTS,        /* Returns NO_MORE_RESULTS */
  933. X    UV_ComputeId,        /* Returns the compute id of the row (in dbnextrow()) */
  934. X    UV_SybperlVer,        /* Returns Sybperl Version/Patchlevel */
  935. X    UV_DBstatus,        /* The value status value of the last dbnextrow() call */
  936. X};
  937. X
  938. X/* 
  939. X * User subroutines that we have implemented. I've found that I can do 
  940. X * all the stuff I want to with this subset of DB-Library. Let me know 
  941. X * if you implement further routines.
  942. X * The names are self-explanatory.
  943. X */
  944. Xstatic enum usersubs
  945. X{
  946. X    US_dblogin,            /* This also performs the first dbopen()  */
  947. X    US_dbopen,
  948. X    US_dbclose,
  949. X    US_dbcmd,
  950. X    US_dbsqlexec,
  951. X    US_dbresults,
  952. X    US_dbnextrow,
  953. X    US_dbcancel,
  954. X    US_dbcanquery,
  955. X    US_dbexit,
  956. X    US_dbuse,
  957. X#ifdef HAS_CALLBACK
  958. X    US_dberrhandle,
  959. X    US_dbmsghandle,
  960. X#endif
  961. X    US_dbstrcpy,
  962. X    US_DBMORECMDS,
  963. X    US_DBCMDROW,
  964. X    US_DBROWS,
  965. X    US_DBCOUNT,
  966. X    US_DBCURCMD,
  967. X    US_dbhasretstat,
  968. X    US_dbretstatus,
  969. X#if defined(DBLIB42)
  970. X    US_dbsafestr,
  971. X#endif
  972. X    US_dbwritetext,
  973. X};
  974. X
  975. X#ifndef MAX_DBPROCS
  976. X#define MAX_DBPROCS 25        /* Change this if you really want your perl script to talk to */
  977. X                /* more than 25 dataserver connections at a time ...*/
  978. X#endif
  979. X
  980. Xstatic LOGINREC *login;
  981. Xstatic DBPROCESS *dbproc[MAX_DBPROCS];
  982. Xstatic int exitCalled = 0;    /* Set to 1 if dbexit() has been called. */
  983. Xstatic int ComputeId;
  984. Xstatic int DBstatus;        /* Set by dbnextrow() */
  985. Xstatic int DBReturnAssoc;    /* If true, dbnextrow returns an associative array */
  986. X
  987. X/* Stack pointer for the error routines.  This is set to the stack pointer
  988. X   when entering into the sybase subroutines.  Error and message
  989. X   handling needs this.  */
  990. X
  991. Xstatic int perl_sp;
  992. X
  993. X/* Current error handler name. */
  994. X
  995. Xstatic char *err_handler_sub;
  996. X
  997. X/* Current message handler subroutine name */
  998. X
  999. Xstatic char *msg_handler_sub;
  1000. X
  1001. X/* Macro to access the stack.  This is necessary since error handlers may
  1002. X   call perl routines and thus the stack may change.  I hope most compilers
  1003. X   will optimize this reasonably. */
  1004. X
  1005. X#define STACK(SP) (stack->ary_array + (SP))
  1006. X
  1007. X
  1008. Xstatic int usersub();
  1009. Xstatic int userset();
  1010. Xstatic int userval();
  1011. Xstatic int err_handler(), msg_handler();
  1012. X
  1013. Xint userinit()
  1014. X{
  1015. X    init_sybase();
  1016. X}
  1017. X
  1018. Xint
  1019. Xinit_sybase()
  1020. X{
  1021. X    struct ufuncs uf;
  1022. X    char *filename = "sybase.c";
  1023. X
  1024. X    if (dbinit() == FAIL)    /* initialize dblibrary */
  1025. X    exit(ERREXIT);
  1026. X/*
  1027. X * Install the user-supplied error-handling and message-handling routines.
  1028. X * They are defined at the bottom of this source file.
  1029. X */
  1030. X    dberrhandle(err_handler);
  1031. X    dbmsghandle(msg_handler);
  1032. X
  1033. X    if(MAX_DBPROCS > 25)
  1034. X    dbsetmaxprocs(MAX_DBPROCS);
  1035. X    
  1036. X    uf.uf_set = userset;
  1037. X    uf.uf_val = userval;
  1038. X
  1039. X#define MAGICVAR(name, ix) uf.uf_index = ix, magicname(name, &uf, sizeof uf)
  1040. X
  1041. X    MAGICVAR("SUCCEED",    UV_SUCCEED);
  1042. X    MAGICVAR("FAIL",UV_FAIL);
  1043. X    MAGICVAR("NO_MORE_ROWS",    UV_NO_MORE_ROWS);
  1044. X    MAGICVAR("NO_MORE_RESULTS",    UV_NO_MORE_RESULTS);
  1045. X    MAGICVAR("ComputeId",    UV_ComputeId);
  1046. X    MAGICVAR("SybperlVer",    UV_SybperlVer);
  1047. X
  1048. X    make_usub("dblogin",    US_dblogin,    usersub, filename);
  1049. X    make_usub("dbopen",        US_dbopen,    usersub, filename);
  1050. X    make_usub("dbclose",    US_dbclose,    usersub, filename);
  1051. X    make_usub("dbcmd",        US_dbcmd,    usersub, filename);
  1052. X    make_usub("dbsqlexec",    US_dbsqlexec,    usersub, filename);
  1053. X    make_usub("dbresults",    US_dbresults,    usersub, filename);
  1054. X    make_usub("dbnextrow",    US_dbnextrow,    usersub, filename);
  1055. X    make_usub("dbcancel",    US_dbcancel,    usersub, filename);
  1056. X    make_usub("dbcanquery",    US_dbcanquery,    usersub, filename);
  1057. X    make_usub("dbexit",    US_dbexit,    usersub, filename);
  1058. X    make_usub("dbuse",    US_dbuse,    usersub, filename);
  1059. X#ifdef HAS_CALLBACK
  1060. X    make_usub("dberrhandle", US_dberrhandle, usersub, filename);
  1061. X    make_usub("dbmsghandle", US_dbmsghandle, usersub, filename);
  1062. X#endif
  1063. X    make_usub("dbstrcpy", US_dbstrcpy, usersub, filename);
  1064. X    make_usub("DBCURCMD", US_DBCURCMD, usersub, filename);
  1065. X    make_usub("DBMORECMDS", US_DBMORECMDS, usersub, filename);
  1066. X    make_usub("DBCMDROW", US_DBCMDROW, usersub, filename);
  1067. X    make_usub("DBROWS", US_DBROWS, usersub, filename);
  1068. X    make_usub("DBCOUNT", US_DBCOUNT, usersub, filename);
  1069. X    make_usub("dbhasretstat", US_dbhasretstat, usersub, filename);
  1070. X    make_usub("dbretstatus", US_dbretstatus, usersub, filename);
  1071. X#if defined(DBLIB42)
  1072. X    make_usub("dbsafestr", US_dbsafestr, usersub, filename);
  1073. X#endif
  1074. X    make_usub("dbwritetext", US_dbwritetext, usersub, filename);
  1075. X}
  1076. X
  1077. Xstatic int
  1078. Xusersub(ix, sp, items)
  1079. Xint ix;
  1080. Xregister int sp;
  1081. Xregister int items;
  1082. X{
  1083. X    STR **st = stack->ary_array + sp;
  1084. X    ARRAY *ary = stack;    
  1085. X    register STR *Str;        /* used in str_get and str_gnum macros */
  1086. X    int inx = -1;        /* Index into dbproc[] array. Passed as first parameter to nearly all &dbxxx() calls */
  1087. X
  1088. X
  1089. X    if(exitCalled)
  1090. X    fatal("&dbexit() has been called. Access to Sybase impossible.");
  1091. X
  1092. X    perl_sp = sp + items;
  1093. X
  1094. X    /* 
  1095. X     * We're calling some dblib function, but dblogin has not been 
  1096. X     * called. Two actions are possible: either fail the call, or call 
  1097. X     * dblogin/dbopen with the default info. The second option is used 
  1098. X     * to keep backwards compatibility with an older version of 
  1099. X     * sybperl. A call to fatal(msg) is probably better.
  1100. X     */
  1101. X    if(!login && (ix != US_dblogin) && (ix != US_dbmsghandle) && (ix != US_dberrhandle))
  1102. X    {                /* You can call &dbmsghandle/errhandle before calling &dblogin */
  1103. X#ifdef OLD_SYBPERL
  1104. X    login = dblogin();
  1105. X    dbproc[0] = dbopen(login, NULL);
  1106. X#else
  1107. X    fatal("&dblogin has not been called yet!");
  1108. X#endif
  1109. X    }
  1110. X    
  1111. X    switch (ix)
  1112. X    {
  1113. X      case US_dblogin:
  1114. X    if (items > 3)
  1115. X        fatal("Usage: &dblogin([user[,pwd[,server]]])");
  1116. X    else
  1117. X    {
  1118. X        int j = 0;
  1119. X        char *server = NULL, *user = NULL, *pwd = NULL;
  1120. X
  1121. X        if (!login)
  1122. X        login = dblogin();
  1123. X        switch(items)
  1124. X        {
  1125. X          case 3:
  1126. X        server = (char *)str_get(STACK(sp)[3]);
  1127. X          case 2:
  1128. X        if(STACK(sp)[2] != &str_undef)
  1129. X        {
  1130. X            pwd = (char *)str_get(STACK(sp)[2]);
  1131. X            if(pwd && strlen(pwd))
  1132. X            DBSETLPWD(login, pwd);
  1133. X        }
  1134. X          case 1:
  1135. X        if(STACK(sp)[1] != &str_undef)
  1136. X        {
  1137. X            user = (char *)str_get(STACK(sp)[1]);
  1138. X            if(user && strlen(user))
  1139. X            DBSETLUSER(login, user);
  1140. X        }
  1141. X        }
  1142. X
  1143. X        for(j = 0; j < MAX_DBPROCS; ++j)
  1144. X        if(dbproc[j] == NULL)
  1145. X            break;
  1146. X        if(j == MAX_DBPROCS)
  1147. X        fatal ("&dblogin: No more dbprocs available.");
  1148. X        if((dbproc[j] = dbopen(login, server)) == NULL)
  1149. X        j = -1;
  1150. X
  1151. X        str_numset(STACK(sp)[0], (double) j);
  1152. X    }
  1153. X    break;
  1154. X      case US_dbopen:
  1155. X    if (items > 1)
  1156. X        fatal("Usage: $dbproc = &dbopen([server]);");
  1157. X    else
  1158. X    {
  1159. X        int j;
  1160. X        char *server = NULL;
  1161. X        
  1162. X        for(j = 0; j < MAX_DBPROCS; ++j)
  1163. X        if(dbproc[j] == NULL)
  1164. X            break;
  1165. X        if(j == MAX_DBPROCS)
  1166. X        fatal("&dbopen: No more dbprocs available.");
  1167. X        if(items == 1)
  1168. X        server = (char *)str_get(STACK(sp)[1]);
  1169. X        
  1170. X        dbproc[j] = dbopen(login, server);
  1171. X        str_numset(STACK(sp)[0], (double) j);
  1172. X    }
  1173. X    break;
  1174. X      case US_dbclose:
  1175. X    if (items != 1)
  1176. X        fatal("Usage: $ret = &dbclose($dbproc);");
  1177. X    else
  1178. X    {
  1179. X        inx = getDbProc(STACK(sp)[1]);
  1180. X
  1181. X        dbclose(dbproc[inx]);
  1182. X        dbproc[inx] = (DBPROCESS *)NULL;
  1183. X    }
  1184. X    break;
  1185. X      case US_dbcancel:
  1186. X    if (items > 1)
  1187. X        fatal("Usage: &dbcancel($dbproc)");
  1188. X    else
  1189. X    {
  1190. X        int retval;
  1191. X
  1192. X        if(items)
  1193. X        inx = getDbProc(STACK(sp)[1]);
  1194. X        else
  1195. X        inx = 0;
  1196. X
  1197. X        retval = dbcancel(dbproc[inx]);
  1198. X        str_numset(STACK(sp)[0], (double) retval);
  1199. X    }
  1200. X    break;
  1201. X
  1202. X      case US_dbcanquery:
  1203. X    if (items > 1)
  1204. X        fatal("Usage: &dbcanquery($dbproc)");
  1205. X    else
  1206. X    {
  1207. X        int retval;
  1208. X
  1209. X        if(items)
  1210. X        inx = getDbProc(STACK(sp)[1]);
  1211. X        else
  1212. X        inx = 0;
  1213. X
  1214. X        retval = dbcanquery(dbproc[inx]);
  1215. X        str_numset(STACK(sp)[0], (double) retval);
  1216. X    }
  1217. X    break;
  1218. X
  1219. X      case US_dbexit:
  1220. X    if (items != 0)
  1221. X        fatal("Usage: &dbexit()");
  1222. X    else
  1223. X    {
  1224. X        dbexit(dbproc[0]);
  1225. X        exitCalled++;
  1226. X        str_numset(STACK(sp)[0], (double) 1);
  1227. X    }
  1228. X    break;
  1229. X
  1230. X      case US_dbuse:
  1231. X    if (items > 2)
  1232. X        fatal("Usage: &dbuse($dbproc, $database)");
  1233. X    else
  1234. X    {
  1235. X        int retval, off;
  1236. X        char str[255];
  1237. X        
  1238. X        if(items == 2)
  1239. X        {
  1240. X        inx = getDbProc(STACK(sp)[1]);
  1241. X        off = 2;
  1242. X        }
  1243. X        else
  1244. X        inx = 0, off = 1;
  1245. X        
  1246. X        strcpy(str, (char *)str_get(STACK(sp)[off]));
  1247. X
  1248. X
  1249. X        retval = dbuse(dbproc[inx], str);
  1250. X        str_numset(STACK(sp)[0], (double) retval);
  1251. X    }
  1252. X    break;
  1253. X
  1254. X      case US_dbsqlexec:
  1255. X    if (items > 1)
  1256. X        fatal("Usage: &dbsqlexec($dbproc)");
  1257. X    else
  1258. X    {
  1259. X        int retval;
  1260. X        if(items)
  1261. X        inx = getDbProc(STACK(sp)[1]);
  1262. X        else
  1263. X        inx = 0;
  1264. X
  1265. X        retval = dbsqlexec(dbproc[inx]);
  1266. X        str_numset(STACK(sp)[0], (double) retval);
  1267. X    }
  1268. X    break;
  1269. X
  1270. X      case US_dbresults:
  1271. X    if (items > 1)
  1272. X        fatal("Usage: &dbresults($dbproc)");
  1273. X    else
  1274. X    {
  1275. X        int retval;
  1276. X
  1277. X        if(items)
  1278. X        inx = getDbProc(STACK(sp)[1]);
  1279. X        else
  1280. X        inx = 0;
  1281. X
  1282. X        retval = dbresults(dbproc[inx]);
  1283. X        str_numset(STACK(sp)[0], (double) retval);
  1284. X    }
  1285. X    break;
  1286. X
  1287. X      case US_dbcmd:
  1288. X    if (items > 2)
  1289. X        fatal("Usage: &dbcmd($dbproc, $str)");
  1290. X    else
  1291. X    {
  1292. X        int retval, off;
  1293. X
  1294. X        if(items == 2)
  1295. X        {
  1296. X        inx = getDbProc(STACK(sp)[1]);
  1297. X        off = 2;
  1298. X        }
  1299. X        else
  1300. X        inx = 0, off = 1;
  1301. X        retval = dbcmd(dbproc[inx], (char *)str_get(STACK(sp)[off]));
  1302. X        str_numset(STACK(sp)[0], (double) retval);
  1303. X    }
  1304. X    break;
  1305. X
  1306. X    case US_dbnextrow:
  1307. X    if (items > 2)
  1308. X        fatal("Usage: @arr = &dbnextrow([$dbproc [, $returnAssoc]])");
  1309. X    else
  1310. X    {
  1311. X        int retval;
  1312. X        char buff[1024], *p = NULL, *t;
  1313. X        BYTE *data;
  1314. X        int col, type, numcols;
  1315. X        int len;
  1316. X        int doAssoc = 0;
  1317. X        DBFLT8 tmp;
  1318. X        char *colname;
  1319. X        char cname[64];
  1320. X
  1321. X        inx = 0;
  1322. X        switch(items)
  1323. X        {
  1324. X          case 2:
  1325. X        doAssoc = (int)str_gnum(STACK(sp)[2]);
  1326. X          case 1:
  1327. X        inx = getDbProc(STACK(sp)[1]);
  1328. X        break;
  1329. X        }
  1330. X
  1331. X        --sp;        /* otherwise you get an empty element at the beginning of the results array! */
  1332. X
  1333. X        DBstatus = retval = dbnextrow(dbproc[inx]);
  1334. X        if(retval == REG_ROW)
  1335. X        {
  1336. X        ComputeId = 0;
  1337. X        numcols = dbnumcols(dbproc[inx]);
  1338. X        }
  1339. X        else
  1340. X        {
  1341. X        ComputeId = retval;
  1342. X        numcols = dbnumalts(dbproc[inx], ComputeId);
  1343. X        }
  1344. X        for(col = 1, buff[0] = 0; col <= numcols; ++col)
  1345. X        {
  1346. X        colname = NULL;
  1347. X        if(!ComputeId)
  1348. X        {
  1349. X            type = dbcoltype(dbproc[inx], col);
  1350. X            len = dbdatlen(dbproc[inx],col);
  1351. X            data = (BYTE *)dbdata(dbproc[inx],col);
  1352. X            colname = dbcolname(dbproc[inx], col);
  1353. X            if(!colname || !colname[0])
  1354. X            {
  1355. X            sprintf(cname, "Col %d", col);
  1356. X            colname = cname;
  1357. X            }
  1358. X        }
  1359. X        else
  1360. X        {
  1361. X            int colid = dbaltcolid(dbproc[inx], ComputeId, col);
  1362. X            type = dbalttype(dbproc[inx], ComputeId, col);
  1363. X            len = dbadlen(dbproc[inx], ComputeId, col);
  1364. X            data = (BYTE *)dbadata(dbproc[inx], ComputeId, col);
  1365. X            if(colid > 0)
  1366. X            colname = dbcolname(dbproc[inx], colid);
  1367. X            if(!colname || !colname[0])
  1368. X            {
  1369. X            sprintf(cname, "Col %d", col);
  1370. X            colname = cname;
  1371. X            }
  1372. X        }
  1373. X        t = &buff[0];
  1374. X        if(!data && !len)
  1375. X        {
  1376. X#if defined(NULL_IS_UNDEF)
  1377. X            t = &str_undef;
  1378. X#else
  1379. X            strcpy(buff,"NULL");
  1380. X#endif
  1381. X        }
  1382. X        else
  1383. X        {
  1384. X            switch(type)
  1385. X            {
  1386. X              case SYBCHAR:
  1387. X            strncpy(buff,data,len);
  1388. X            buff[len] = 0;
  1389. X            break;
  1390. X              case SYBTEXT:
  1391. X            New(902, p, len + 1, char);
  1392. X            strncpy(p, data, len);
  1393. X            p[len] = 0;
  1394. X            t = p;
  1395. X            break;
  1396. X              case SYBINT1:
  1397. X              case SYBBIT: /* a bit is at least a byte long... */
  1398. X            sprintf(buff,"%u",*(unsigned char *)data);
  1399. X            break;
  1400. X              case SYBINT2:
  1401. X            sprintf(buff,"%d",*(short *)data);
  1402. X            break;
  1403. X              case SYBINT4:
  1404. X            sprintf(buff,"%d",*(long *)data);
  1405. X            break;
  1406. X              case SYBFLT8:
  1407. X            sprintf(buff,"%.6f",*(double *)data);
  1408. X            break;
  1409. X              case SYBMONEY:
  1410. X            dbconvert(dbproc[inx], SYBMONEY, data, len, SYBFLT8, &tmp, -1);
  1411. X            sprintf(buff,"%.6f",tmp);
  1412. X            break;
  1413. X              case SYBDATETIME:
  1414. X            dbconvert(dbproc[inx], SYBDATETIME, data, len, SYBCHAR, buff, -1);
  1415. X            break;
  1416. X              case SYBBINARY:
  1417. X            dbconvert(dbproc[inx], type, data, len, SYBCHAR, buff, -1);
  1418. X            break;
  1419. X#if defined(DBLIB42)
  1420. X              case SYBREAL:
  1421. X            sprintf(buff, "%.6f", *(float *)data);
  1422. X            break;
  1423. X              case SYBDATETIME4:
  1424. X            dbconvert(dbproc[inx], SYBDATETIME4, data, len, SYBCHAR, buff, -1);
  1425. X            break;
  1426. X#endif
  1427. X              case SYBIMAGE:
  1428. X            fatal ("&dbnextrow: SYBIMAGE datatypes are not handled at the moment!");
  1429. X            break;
  1430. X            
  1431. X              default:
  1432. X            /* 
  1433. X             * WARNING!
  1434. X             * 
  1435. X             * We convert unknown data types to SYBCHAR 
  1436. X             * without checking to see if the resulting 
  1437. X             * string will fit in the 'buff' variable. 
  1438. X             * This isn't very pretty...
  1439. X             */
  1440. X            dbconvert(dbproc[inx], type, data, len, SYBCHAR, buff, -1);
  1441. X            break;
  1442. X            }
  1443. X        }
  1444. X        if(doAssoc)
  1445. X            (void)astore(ary,++sp,str_2mortal(str_make(colname, 0)));
  1446. X        
  1447. X        (void)astore(ary,++sp,str_2mortal(str_make(t, 0)));
  1448. X        /* 
  1449. X         * If we've allocated some space to retrieve a 
  1450. X         * SYBTEXT field, then free it now.
  1451. X         */
  1452. X        if(t == p)
  1453. X        {
  1454. X            Safefree(p);
  1455. X            p = NULL;
  1456. X        }
  1457. X        }
  1458. X    }
  1459. X    break;
  1460. X#ifdef HAS_CALLBACK
  1461. X      case US_dberrhandle:
  1462. X    if (items > 1)
  1463. X        fatal ("Usage: &dberrhandle($handler)");
  1464. X    else
  1465. X    {
  1466. X        char *old = err_handler_sub;
  1467. X        if (items == 1)
  1468. X        {
  1469. X        if (STACK (sp)[1] == &str_undef)
  1470. X            err_handler_sub = 0;
  1471. X        else
  1472. X        {
  1473. X            char *sub = (char *) str_get (STACK (sp)[1]);    
  1474. X            New (902, err_handler_sub, strlen (sub) + 1, char);
  1475. X            strcpy (err_handler_sub, sub);
  1476. X        }
  1477. X        }
  1478. X
  1479. X        if (old)
  1480. X        {
  1481. X        STACK (sp)[0] = str_2mortal (str_make (old, strlen (old)));
  1482. X        if (items == 1)
  1483. X            Safefree (old);
  1484. X        }
  1485. X        else
  1486. X        STACK (sp)[0] = &str_undef;
  1487. X    }
  1488. X    break;
  1489. X      case US_dbmsghandle:
  1490. X    if (items > 1)
  1491. X        fatal ("Usage: &dbmsghandle($handler)");
  1492. X    else
  1493. X    {
  1494. X        char *old = msg_handler_sub;
  1495. X        if (items == 1)
  1496. X        {
  1497. X        if (STACK (sp)[1] == &str_undef)
  1498. X            msg_handler_sub = 0;
  1499. X        else
  1500. X        {
  1501. X            char *sub = (char *) str_get (STACK (sp)[1]);    
  1502. X            New (902, msg_handler_sub, strlen (sub) + 1, char);
  1503. X            strcpy (msg_handler_sub, sub);
  1504. X        }
  1505. X        }
  1506. X
  1507. X        if (old)
  1508. X        {
  1509. X        STACK (sp)[0] = str_2mortal (str_make (old, strlen (old)));
  1510. X        if (items == 1)
  1511. X            Safefree (old);
  1512. X        }
  1513. X        else
  1514. X        STACK (sp)[0] = &str_undef;
  1515. X    }
  1516. X    break;
  1517. X#endif                /* HAS_CALLBACK */
  1518. X      case US_dbstrcpy:
  1519. X    if (items > 1)
  1520. X        fatal("Usage: $string = &dbstrcpy($dbproc)");
  1521. X    else
  1522. X    {
  1523. X        int retval, len;
  1524. X        char *buff;
  1525. X
  1526. X        if(items)
  1527. X        inx = getDbProc(STACK(sp)[1]);
  1528. X        else
  1529. X        inx = 0;
  1530. X
  1531. X        if(dbproc[inx] && (len = dbstrlen(dbproc[inx])))
  1532. X        {
  1533. X        New(902, buff, len+1, char);
  1534. X        retval = dbstrcpy(dbproc[inx], 0, -1, buff);
  1535. X        str_set(STACK(sp)[0], buff);
  1536. X        Safefree(buff);
  1537. X        }
  1538. X        else
  1539. X        str_set(STACK(sp)[0], "");
  1540. X    }
  1541. X    break;
  1542. X
  1543. X      case US_DBCURCMD:
  1544. X    if (items > 1)
  1545. X        fatal("Usage: $num = &DBCURCMD($dbproc)");
  1546. X    else
  1547. X    {
  1548. X        int retval = 0;
  1549. X
  1550. X        if(items)
  1551. X        inx = getDbProc(STACK(sp)[1]);
  1552. X        else
  1553. X        inx = 0;
  1554. X
  1555. X        if(dbproc[inx])
  1556. X        retval = DBCURCMD(dbproc[inx]);
  1557. X
  1558. X        str_numset(STACK(sp)[0], (double) retval);
  1559. X    }
  1560. X    break;
  1561. X      case US_DBMORECMDS:
  1562. X    if (items > 1)
  1563. X        fatal("Usage: $rc = &DBMORECMDS($dbproc)");
  1564. X    else
  1565. X    {
  1566. X        int retval = 0;
  1567. X
  1568. X        if(items)
  1569. X        inx = getDbProc(STACK(sp)[1]);
  1570. X        else
  1571. X        inx = 0;
  1572. X
  1573. X        if(dbproc[inx])
  1574. X        retval = DBMORECMDS(dbproc[inx]);
  1575. X
  1576. X        str_numset(STACK(sp)[0], (double) retval);
  1577. X    }
  1578. X    break;
  1579. X      case US_DBCMDROW:
  1580. X    if (items > 1)
  1581. X        fatal("Usage: $rc = &DBCMDROW($dbproc)");
  1582. X    else
  1583. X    {
  1584. X        int retval = 0;
  1585. X
  1586. X        if(items)
  1587. X        inx = getDbProc(STACK(sp)[1]);
  1588. X        else
  1589. X        inx = 0;
  1590. X
  1591. X        if(dbproc[inx])
  1592. X        retval = DBCMDROW(dbproc[inx]);
  1593. X
  1594. X        str_numset(STACK(sp)[0], (double) retval);
  1595. X    }
  1596. X    break;
  1597. X      case US_DBROWS:
  1598. X    if (items > 1)
  1599. X        fatal("Usage: $rc = &DBROWS($dbproc)");
  1600. X    else
  1601. X    {
  1602. X        int retval = 0;
  1603. X
  1604. X        if(items)
  1605. X        inx = getDbProc(STACK(sp)[1]);
  1606. X        else
  1607. X        inx = 0;
  1608. X
  1609. X        if(dbproc[inx])
  1610. X        retval = DBROWS(dbproc[inx]);
  1611. X
  1612. X        str_numset(STACK(sp)[0], (double) retval);
  1613. X    }
  1614. X    break;
  1615. X      case US_DBCOUNT:
  1616. X    if (items > 1)
  1617. X        fatal("Usage: $ret = &DBCOUNT($dbproc)");
  1618. X    else
  1619. X    {
  1620. X        int retval = 0;
  1621. X
  1622. X        if(items)
  1623. X        inx = getDbProc(STACK(sp)[1]);
  1624. X        else
  1625. X        inx = 0;
  1626. X
  1627. X        if(dbproc[inx])
  1628. X        retval = DBCOUNT(dbproc[inx]);
  1629. X
  1630. X        str_numset(STACK(sp)[0], (double) retval);
  1631. X    }
  1632. X    break;
  1633. X      case US_dbhasretstat:
  1634. X    if (items > 1)
  1635. X        fatal("Usage: $rc = &dbhasretstat($dbproc)");
  1636. X    else
  1637. X    {
  1638. X        int retval = 0;
  1639. X
  1640. X        if(items)
  1641. X        inx = getDbProc(STACK(sp)[1]);
  1642. X        else
  1643. X        inx = 0;
  1644. X
  1645. X        if(dbproc[inx])
  1646. X        retval = dbhasretstat(dbproc[inx]);
  1647. X
  1648. X        str_numset(STACK(sp)[0], (double) retval);
  1649. X    }
  1650. X    break;
  1651. X      case US_dbretstatus:
  1652. X    if (items > 1)
  1653. X        fatal("Usage: $rc = &dbretstatus($dbproc)");
  1654. X    else
  1655. X    {
  1656. X        int retval = 0;
  1657. X
  1658. X        if(items)
  1659. X        inx = getDbProc(STACK(sp)[1]);
  1660. X        else
  1661. X        inx = 0;
  1662. X
  1663. X        if(dbproc[inx])
  1664. X        retval = dbretstatus(dbproc[inx]);
  1665. X
  1666. X        str_numset(STACK(sp)[0], (double) retval);
  1667. X    }
  1668. X    break;
  1669. X#if defined(DBLIB42)
  1670. X      case US_dbsafestr:
  1671. X    if (items > 3 || items != 2)
  1672. X        fatal ("Usage: $string = &dbsafestr($dbproc,$instring[,$quote_char])");
  1673. X    else
  1674. X    {
  1675. X        int retval, len, quote;
  1676. X        char *buff, *instr;
  1677. X        
  1678. X        inx = getDbProc (STACK (sp)[1]);
  1679. X        
  1680. X        instr = (char *) str_get (STACK (sp)[2]);
  1681. X        if (items != 3)
  1682. X        quote = DBBOTH;
  1683. X        else
  1684. X        {
  1685. X        char *quote_char = (char *) str_get (STACK (sp)[3]);
  1686. X        if (*quote_char == '\"')
  1687. X            quote = DBDOUBLE;
  1688. X        else if (*quote_char == '\'')
  1689. X            quote = DBSINGLE;
  1690. X        else
  1691. X        { /* invalid  */
  1692. X            str_set (STACK (sp)[0], "");
  1693. X            break;
  1694. X        }
  1695. X        }
  1696. X        if (dbproc[inx] && (len = strlen (instr)))
  1697. X        {
  1698. X        /* twice as much space needed worst case */
  1699. X        New (902, buff, len * 2 + 1, char);
  1700. X        retval = dbsafestr (dbproc[inx], instr, -1, buff, -1, quote);
  1701. X                str_set (STACK (sp)[0], buff);
  1702. X                Safefree (buff);
  1703. X        }
  1704. X    }
  1705. X    break;
  1706. X#endif
  1707. X      case US_dbwritetext:
  1708. X        if (items != 5)
  1709. X            fatal ("Usage: dbwritetext($dbproc1,$column,$dbproc2,$col,$text");
  1710. X    else
  1711. X    {
  1712. X        int inx2, wcolnum;
  1713. X        char *wcolname, *wtext;
  1714. X        int ret;
  1715. X        
  1716. X        inx = getDbProc(STACK(sp)[1]);
  1717. X        wcolname = str_get(STACK(sp)[2]);
  1718. X        inx2 = getDbProc(STACK(sp)[3]);
  1719. X        wcolnum = (int)str_gnum(STACK(sp)[4]);
  1720. X        wtext = str_get(STACK(sp)[5]);
  1721. X        ret = dbwritetext (dbproc[inx], wcolname, dbtxptr(dbproc[inx2], wcolnum),
  1722. X                   DBTXPLEN, dbtxtimestamp(dbproc[inx2], wcolnum), 0,
  1723. X                   strlen(wtext), wtext);
  1724. X        str_numset(STACK(sp)[0], (double) ret);
  1725. X    }
  1726. X        break;
  1727. X
  1728. X      default:
  1729. X    fatal("Unimplemented user-defined subroutine");
  1730. X    }
  1731. X    return sp;
  1732. X}
  1733. X
  1734. X/* 
  1735. X * Return the value of a userdefined variable. These variables are all 
  1736. X * READ-ONLY in Perl.
  1737. X */
  1738. Xstatic int
  1739. Xuserval(ix, str)
  1740. Xint ix;
  1741. XSTR *str;
  1742. X{
  1743. X    char buff[24];
  1744. X    
  1745. X    switch (ix)
  1746. X    {
  1747. X      case UV_SUCCEED:
  1748. X    str_numset(str, (double)SUCCEED);
  1749. X    break;
  1750. X      case UV_FAIL:
  1751. X    str_numset(str, (double)FAIL);
  1752. X    break;
  1753. X      case UV_NO_MORE_ROWS:
  1754. X    str_numset(str, (double)NO_MORE_ROWS);
  1755. X    break;
  1756. X      case UV_NO_MORE_RESULTS:
  1757. X    str_numset(str, (double)NO_MORE_RESULTS);
  1758. X    break;
  1759. X      case UV_ComputeId:
  1760. X    str_numset(str, (double)ComputeId);
  1761. X    break;
  1762. X      case UV_SybperlVer:
  1763. X    sprintf(buff, "%d.%3.3d", VERSION, PATCHLEVEL);
  1764. X    str_set(str, buff);
  1765. X    break;
  1766. X      case UV_DBstatus:
  1767. X    str_numset(str, (double)DBstatus);
  1768. X    break;
  1769. X     }
  1770. X    return 0;
  1771. X}
  1772. X
  1773. Xstatic int
  1774. Xuserset(ix, str)
  1775. Xint ix;
  1776. XSTR *str;
  1777. X{
  1778. X#if defined(USERVAL_SET_FATAL)
  1779. X    fatal("sybperl: trying to write to a read-only variable.");
  1780. X#else
  1781. X    return 0;
  1782. X#endif
  1783. X}
  1784. X
  1785. X
  1786. X/*ARGSUSED*/
  1787. Xstatic int err_handler(db, severity, dberr, oserr, dberrstring, oserrstr)
  1788. X    DBPROCESS *db;
  1789. X    int severity;
  1790. X    int dberr;
  1791. X    int oserr;
  1792. X    char *dberrstring;
  1793. X    char *oserrstr;
  1794. X{
  1795. X#ifdef HAS_CALLBACK
  1796. X    /* If we have error handler subroutine, use it. */
  1797. X    if (err_handler_sub)
  1798. X    {
  1799. X    int sp = perl_sp;
  1800. X    int j;
  1801. X
  1802. X    for(j = 0; j < MAX_DBPROCS; ++j)
  1803. X        if(db == dbproc[j])
  1804. X        break;
  1805. X    if(j == MAX_DBPROCS)
  1806. X        j = 0;
  1807. X    
  1808. X    /* Reserve spot for return value. */
  1809. X    astore (stack, ++ sp, Nullstr);
  1810. X    
  1811. X    /* Set up arguments. */
  1812. X    astore (stack, ++ sp,
  1813. X        str_2mortal (str_nmake ((double) j)));
  1814. X    astore (stack, ++ sp, str_2mortal (str_nmake ((double) severity)));
  1815. X    astore (stack, ++ sp, str_2mortal (str_nmake ((double) dberr)));
  1816. X    astore (stack, ++ sp, str_2mortal (str_nmake ((double) oserr)));
  1817. X    if (dberrstring && *dberrstring)
  1818. X        astore (stack, ++ sp, str_2mortal (str_make (dberrstring, 0)));
  1819. X    else
  1820. X        astore (stack, ++ sp, &str_undef);
  1821. X    if (oserrstr && *oserrstr)
  1822. X        astore (stack, ++ sp, str_2mortal (str_make (oserrstr, 0)));
  1823. X    else
  1824. X        astore (stack, ++ sp, &str_undef);
  1825. X    
  1826. X    /* Call it. */
  1827. X    sp = callback (err_handler_sub, sp, 0, 1, 6);
  1828. X    
  1829. X    /* Return whatever it returned. */
  1830. X    return (int) str_gnum (STACK (sp)[0]);
  1831. X    }
  1832. X#endif                /* HAS_CALLBACK */
  1833. X    if ((db == NULL) || (DBDEAD(db)))
  1834. X    return(INT_EXIT);
  1835. X    else 
  1836. X    {
  1837. X    fprintf(stderr,"DB-Library error:\n\t%s\n", dberrstring);
  1838. X    
  1839. X    if (oserr != DBNOERR)
  1840. X        fprintf(stderr,"Operating-system error:\n\t%s\n", oserrstr);
  1841. X    
  1842. X    return(INT_CANCEL);
  1843. X    }
  1844. X}
  1845. X
  1846. X/*ARGSUSED*/
  1847. X
  1848. Xstatic int msg_handler(db, msgno, msgstate, severity, msgtext, srvname, procname, line)
  1849. X    DBPROCESS *db;
  1850. X    DBINT msgno;
  1851. X    int msgstate;
  1852. X    int severity;
  1853. X    char *msgtext;
  1854. X    char *srvname;
  1855. X    char *procname;
  1856. X    DBUSMALLINT line;
  1857. X{
  1858. X#ifdef HAS_CALLBACK
  1859. X    /* If we have message handler subroutine, use it. */
  1860. X    if (msg_handler_sub)
  1861. X    {
  1862. X    int sp = perl_sp;
  1863. X    int j;
  1864. X
  1865. X    for(j = 0; j < MAX_DBPROCS; ++j)
  1866. X        if(db == dbproc[j])
  1867. X        break;
  1868. X    if(j == MAX_DBPROCS)
  1869. X        j = 0;
  1870. X    
  1871. X    /* Reserve spot for return value. */
  1872. X    astore (stack, ++ sp, Nullstr);
  1873. X    
  1874. X    /* Set up arguments. */
  1875. X    astore (stack, ++ sp,
  1876. X        str_2mortal (str_nmake ((double) j)));
  1877. X    astore (stack, ++ sp, str_2mortal (str_nmake ((double) msgno)));
  1878. X    astore (stack, ++ sp, str_2mortal (str_nmake ((double) msgstate)));
  1879. X    astore (stack, ++ sp, str_2mortal (str_nmake ((double) severity)));
  1880. X    if (msgtext && *msgtext)
  1881. X        astore (stack, ++ sp, str_2mortal (str_make (msgtext, 0)));
  1882. X    else
  1883. X        astore (stack, ++ sp, &str_undef);
  1884. X    if (srvname && *srvname)
  1885. X        astore (stack, ++ sp, str_2mortal (str_make (srvname, 0)));
  1886. X    else
  1887. X        astore (stack, ++ sp, &str_undef);
  1888. X    if (procname && *procname)
  1889. X        astore (stack, ++ sp, str_2mortal (str_make (procname, 0)));
  1890. X    else
  1891. X        astore (stack, ++ sp, &str_undef);
  1892. X    astore (stack, ++ sp, str_2mortal (str_nmake ((double) line)));
  1893. X    
  1894. X    /* Call it. */
  1895. X    sp = callback (msg_handler_sub, sp, 0, 1, 8);
  1896. X    
  1897. X    /* Return whatever it returned. */
  1898. X    return (int) str_gnum (STACK (sp)[0]);
  1899. X    }
  1900. X#endif                /* HAS_CALLBACK */
  1901. X#ifdef OLD_SYBPERL
  1902. X    if(!severity)
  1903. X    return 0;
  1904. X#endif
  1905. X    fprintf (stderr,"Msg %ld, Level %d, State %d\n", 
  1906. X         msgno, severity, msgstate);
  1907. X    if (strlen(srvname) > 0)
  1908. X    fprintf (stderr,"Server '%s', ", srvname);
  1909. X    if (strlen(procname) > 0)
  1910. X    fprintf (stderr,"Procedure '%s', ", procname);
  1911. X    if (line > 0)
  1912. X    fprintf (stderr,"Line %d", line);
  1913. X    
  1914. X    fprintf(stderr,"\n\t%s\n", msgtext);
  1915. X    
  1916. X    return(0);
  1917. X}
  1918. X
  1919. X/* 
  1920. X * Get the index into the dbproc[] array from a Perl STR datatype. 
  1921. X * Check that the index is reasonably valid...
  1922. X */
  1923. Xint getDbProc(Str)
  1924. X    STR *Str;
  1925. X{
  1926. X    int ix = (int)str_gnum(Str);
  1927. X
  1928. X    if(ix < 0 || ix >= MAX_DBPROCS)
  1929. X    fatal("$dbproc parameter is out of range.");
  1930. X    if(dbproc[ix] == NULL || DBDEAD(dbproc[ix]))
  1931. X    fatal("$dbproc parameter is NULL or the connection to the server has been closed.");
  1932. X    return ix;
  1933. X}
  1934. X
  1935. X#ifdef HAS_CALLBACK
  1936. X
  1937. X/* Taken from Perl 4.018 usub/usersub.c. mp. */
  1938. X
  1939. X/* Be sure to refetch the stack pointer after calling these routines. */
  1940. X
  1941. Xint
  1942. Xcallback(subname, sp, gimme, hasargs, numargs)
  1943. Xchar *subname;
  1944. Xint sp;            /* stack pointer after args are pushed */
  1945. Xint gimme;        /* called in array or scalar context */
  1946. Xint hasargs;        /* whether to create a @_ array for routine */
  1947. Xint numargs;        /* how many args are pushed on the stack */
  1948. X{
  1949. X    static ARG myarg[3];    /* fake syntax tree node */
  1950. X    int arglast[3];
  1951. X    
  1952. X    arglast[2] = sp;
  1953. X    sp -= numargs;
  1954. X    arglast[1] = sp--;
  1955. X    arglast[0] = sp;
  1956. X
  1957. X    if (!myarg[0].arg_ptr.arg_str)
  1958. X    myarg[0].arg_ptr.arg_str = str_make("",0);
  1959. X
  1960. X    myarg[1].arg_type = A_WORD;
  1961. X    myarg[1].arg_ptr.arg_stab = stabent(subname, FALSE);
  1962. X
  1963. X    myarg[2].arg_type = hasargs ? A_EXPR : A_NULL;
  1964. X
  1965. X    return do_subr(myarg, gimme, arglast);
  1966. X}
  1967. X
  1968. X#endif                /* HAS_CALLBACK */
  1969. X
  1970. END_OF_FILE
  1971.   if test 25807 -ne `wc -c <'sybperl.c'`; then
  1972.     echo shar: \"'sybperl.c'\" unpacked with wrong size!
  1973.   fi
  1974.   # end of 'sybperl.c'
  1975. fi
  1976. if test ! -d 't' ; then
  1977.     echo shar: Creating directory \"'t'\"
  1978.     mkdir 't'
  1979. fi
  1980. echo shar: End of archive 1 \(of 2\).
  1981. cp /dev/null ark1isdone
  1982. MISSING=""
  1983. for I in 1 2 ; do
  1984.     if test ! -f ark${I}isdone ; then
  1985.     MISSING="${MISSING} ${I}"
  1986.     fi
  1987. done
  1988. if test "${MISSING}" = "" ; then
  1989.     echo You have unpacked both archives.
  1990.     rm -f ark[1-9]isdone
  1991. else
  1992.     echo You still must unpack the following archives:
  1993.     echo "        " ${MISSING}
  1994. fi
  1995. exit 0
  1996. exit 0 # Just in case...
  1997.