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

  1. Newsgroups: comp.sources.misc
  2. From: mpeppler@itf0.itf.ch (Michael Peppler)
  3. Subject: v37i034:  sybperl - Sybase DB-library extensions to Perl, v1.6, Part02/02
  4. Message-ID: <1993Apr28.164156.12825@sparky.imd.sterling.com>
  5. X-Md4-Signature: 432fbb5d8027b7f5639c5aae29ca6811
  6. Date: Wed, 28 Apr 1993 16:41:56 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: mpeppler@itf0.itf.ch (Michael Peppler)
  10. Posting-number: Volume 37, Issue 34
  11. Archive-name: sybperl/part02
  12. Environment: UNIX, Perl, Sybase
  13. Supersedes: sybperl: Volume 28, Issue 33
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then feed it
  17. # into a shell via "sh file" or similar.  To overwrite existing files,
  18. # type "sh file -c".
  19. # Contents:  BUGS CHANGES PACKING.LST eg/README eg/capture.pl
  20. #   eg/dbtext.pl eg/report.pl eg/space.pl eg/sql.pl lib/sybdb.ph
  21. #   lib/sybperl.pl t/sbex.pl
  22. # Wrapped by kent@sparky on Wed Apr 28 08:40:08 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 2 (of 2)."'
  26. if test -f 'BUGS' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'BUGS'\"
  28. else
  29.   echo shar: Extracting \"'BUGS'\" \(2818 characters\)
  30.   sed "s/^X//" >'BUGS' <<'END_OF_FILE'
  31. X
  32. X    
  33. X    The Sybase DB-Library - Perl savestr() conflict
  34. X    ------------------------------------------------
  35. X
  36. X
  37. X    Ah! The joys of tying different packages together!
  38. X
  39. X    Both Perl and DB-Library have a function called savestr(). The
  40. X    DB-Library version is used in dbcmd() to add an SQL command to the
  41. X    list of commands pointed to by dpproc->dbcmdbuf, and in dbuse() as
  42. X    well. Now there are several ways to work around this problem.
  43. X
  44. X    1) Compile sybperl.c with -DBROKEN_DBCMD. I've written some code
  45. X       that emulates calls to dbcmd() and dbuse(). This works OK on my
  46. X       machine/OS/Version of Perl/Version of DBlib, but it relies on
  47. X       the internal storing method used by DBlib, and that might
  48. X       change in the future.
  49. X
  50. X    2) Recompile Perl (specifically, uperl.o in the Perl source
  51. X       directory) with some suitable flags (eg -Dsavestr=p_savestr).
  52. X       This does not create any compatibility problems, but is a
  53. X       lengthy procedure.
  54. X
  55. X    3) Do something like:
  56. X       cc -c sybperl.c
  57. X       ld -r -o sybperl2.o sybperl.o -lsybdb
  58. X       [edit sybperl2.o and replace `_savestr' with something like `_savest1']
  59. X       cc -o sybperl uperl.o sybperl2.o
  60. X       This is not a bad solution, but won't work if you have shared
  61. X       library versions of libsybdb.a
  62. X
  63. X    4) Edit uperl.o and replace savestr with something else. This is
  64. X       the solution I've chosen as the default. It is relatively fast,
  65. X       does not rely on any internal knowledge of DB-Library, and does
  66. X       not require Perl to be recompiled.
  67. X
  68. X    The Makefile gives some information on how to achieve these
  69. X    different options.
  70. X       
  71. X    Thanks to Teemu Torma for providing the initial input on this problem.    
  72. X
  73. X
  74. X
  75. X    Sybperl Memory Usage
  76. X    --------------------
  77. X
  78. X    The general format of a Sybperl script usually looks somewhat like
  79. X    this:
  80. X
  81. X    #!/usr/local/bin/sybperl
  82. X
  83. X    &dbcmd( query text );
  84. X    &dbsqlexec;
  85. X    &dbresults;
  86. X
  87. X    while(@data = &dbnextrow)
  88. X    {
  89. X       process data
  90. X    }
  91. X
  92. X
  93. X    If you are using a version of Perl prior to release 4, patchlevel
  94. X    35, then this method will result in a rather important memory
  95. X    leak. There are two ways around this problem:
  96. X
  97. X    1) Upgrade to Perl 4, patchlevel 35 :-)
  98. X
  99. X    2) Write a subroutine that calls &dbnextrow and stores the returned
  100. X       array to a local variable, and which in turn returns that array to
  101. X       the main while() loop, like so:
  102. X
  103. X    sub getRow
  104. X    {
  105. X        local(@data);
  106. X
  107. X    @data = &dbnextrow;
  108. X
  109. X    @data;
  110. X    }
  111. X
  112. X    while(@data = &getRow)
  113. X    {
  114. X       etc.
  115. X    }
  116. X
  117. X
  118. X    This technique should keep the memory usage of Sybperl to a
  119. X    manageable level.
  120. X
  121. X
  122. X
  123. X
  124. X
  125. X
  126. X
  127. X
  128. X    Please let me know if you find any other problems with Sybperl so
  129. X    that I can look into it.
  130. X
  131. X    Thank you.
  132. X
  133. X    Michael Peppler    <mpeppler@itf.ch>
  134. X
  135. X    
  136. END_OF_FILE
  137.   if test 2818 -ne `wc -c <'BUGS'`; then
  138.     echo shar: \"'BUGS'\" unpacked with wrong size!
  139.   fi
  140.   # end of 'BUGS'
  141. fi
  142. if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  143.   echo shar: Will not clobber existing file \"'CHANGES'\"
  144. else
  145.   echo shar: Extracting \"'CHANGES'\" \(1782 characters\)
  146.   sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
  147. X    Sybperl CHANGES:
  148. X
  149. X    1.006    Added contributed patches: &dbwritetext(),
  150. X        &dbsafestr() and a modified &dblogin().
  151. X        Added &dbhasretstats() and &dbretstatus(), as well as
  152. X        some calls to DBlib macros such as DBCMD(),
  153. X        DBMORECMD(), etc.
  154. X        Received a patch to eg/space.pl from Wolfgang Richter.
  155. X        Code that was defined to compile if BROKER_DBCMD was
  156. X        defined has been removed. It was only a hack, making
  157. X        use of knowledge of the structure of the DBPROCESS
  158. X        data type.
  159. X        Added the possibility to return an associative array
  160. X        from &dbnextrow.
  161. X        Added support for new datatypes (SYBREAL, SYBDATETIME4).
  162. X        NULL values retrieved using &dbnextrow can be returned
  163. X        as 'undef' instead of 'NULL' (this is a compile-time
  164. X        option).
  165. X    1.005   Sybperl would core dump if you used a uninitialized
  166. X            DBPROCESS.
  167. X        A solution to the sometime pathological    memory usage
  168. X        observed when using a release of Perl lower than 4.035
  169. X        is also described in BUGS.
  170. X        &dblogin now returns -1 if the dblogin() or dbopen()
  171. X        calls fail.
  172. X        Added the possibility to login to a specific server
  173. X        without setting the DSQUERY environment variable.
  174. X        Added a script to extract the information regarding
  175. X        the database from the databases' system tables. See
  176. X        eg/dbschema.pl.
  177. X    1.004    Added support for Perl based error and message
  178. X        handlers (as made possible by Perl 4.018). Many Thanks
  179. X        to Teemu Torma for this code.
  180. X        Added limited support for SYBTEXT datatypes.
  181. X        Added &dbstrcpy() to retrieve the current command buffer.
  182. X        The DBPROCESS parameter to most &db*() calls can now
  183. X        be omitted: it will default to the first DBPROCESS
  184. X        opened (the one that is returned by &dblogin()).
  185. X        Added lib/sybdb.ph
  186. X        Added a couple of example scripts in eg/*.pl, courtesy
  187. X        of Gijs Mos (Thank You!).
  188. X    1.003    Base version.
  189. X
  190. END_OF_FILE
  191.   if test 1782 -ne `wc -c <'CHANGES'`; then
  192.     echo shar: \"'CHANGES'\" unpacked with wrong size!
  193.   fi
  194.   # end of 'CHANGES'
  195. fi
  196. if test -f 'PACKING.LST' -a "${1}" != "-c" ; then 
  197.   echo shar: Will not clobber existing file \"'PACKING.LST'\"
  198. else
  199.   echo shar: Extracting \"'PACKING.LST'\" \(1175 characters\)
  200.   sed "s/^X//" >'PACKING.LST' <<'END_OF_FILE'
  201. X
  202. X
  203. X    
  204. X    The Sybperl package should contain the following files:
  205. X
  206. X
  207. X        PACKING.LST        This file
  208. X        README        Read Me!
  209. X        BUGS        Perl/DB-library incompatibility description
  210. X        CHANGES
  211. X        Makefile
  212. X        sybperl.c        Sybperl source
  213. X        sybperl.1        Man page
  214. X        patchlevel.h
  215. X        t/sbex.pl        Example of sybperl script
  216. X        lib/sybperl.pl  A Perl library file.
  217. X        lib/sybdb.ph    Some of the DB-Library include files, run
  218. X                through h2ph.
  219. X        eg/space.pl        How much space does your sybase databases use?
  220. X        eg/capture.pl   Create a table extracted from /etc/passwd
  221. X        eg/report.pl    Report from table created by capture.pl
  222. X        eg/sql.pl        Utility routines used by the above example programs.
  223. X
  224. X        eg/dbtext.pl    Example of &dbwritetext() usage. This
  225. X                script will NOT work out of the box. Read
  226. X                the code to see what requires doing first.
  227. X
  228. X        eg/dbschema.pl  Create an Isql script that will to
  229. X                        recreate your database(s) structure (data
  230. X                types, tables, indexes, rules, defaults,
  231. X                views, triggers and stored procedures),
  232. X                extracting the information from the
  233. X                database's system tables.
  234. X        
  235. END_OF_FILE
  236.   if test 1175 -ne `wc -c <'PACKING.LST'`; then
  237.     echo shar: \"'PACKING.LST'\" unpacked with wrong size!
  238.   fi
  239.   # end of 'PACKING.LST'
  240. fi
  241. if test -f 'eg/README' -a "${1}" != "-c" ; then 
  242.   echo shar: Will not clobber existing file \"'eg/README'\"
  243. else
  244.   echo shar: Extracting \"'eg/README'\" \(1741 characters\)
  245.   sed "s/^X//" >'eg/README' <<'END_OF_FILE'
  246. X    @(#)README    1.4    4/2/93
  247. X
  248. X
  249. X    This directory contains a number of example scripts for Sybperl.
  250. X
  251. X
  252. X    
  253. X    space.pl        Report the space used by your database.
  254. X    capture.pl        Create a table with information from
  255. X            /etc/passwd.
  256. X    report.pl        Report information from the above table.
  257. X    sql.pl        Utility used by the above three scripts.
  258. X    dbschema.pl        Extract an Isql script to re-create a database
  259. X    dbtext.pl        A very simple example of usage of dbwritetext.
  260. X            Read the code before using!
  261. X
  262. X
  263. X    
  264. X    Dbschema.pl Documentation:
  265. X    --------------------------
  266. X    
  267. X    This is a Sybperl script that extracts a Sybase database definition
  268. X    and creates an Isql script to rebuild the database.
  269. X
  270. X    dbschema.pl is NOT a production script, in the sense that it does
  271. X    not do ALL the necessary work. The script tries to do the right
  272. X    thing, but in certain cases (mainly where the owner of an object
  273. X    is not the DBO) it creates an invalid or incorrect Isql command. I
  274. X    have tried to detect these cases, and log them both to stdout and to a
  275. X    file, so that the script can be corrected.
  276. X    Please note also that dbschema.pl logs in to Sybase with the
  277. X    default (Unix) user id, and a NULL password. This behaviour is
  278. X    maybe not OK for your site.
  279. X
  280. X    Usage:
  281. X
  282. X        itf1% dbschema.pl -d excalibur -o excalibur.isql -v
  283. X
  284. X    Run dbschema on database 'excalibur', place the resulting script
  285. X    in 'excalibur.isql' (and the error log in 'excalibur.isql.log')
  286. X    and turn on verbose output on the console. The default database is
  287. X    'master', the default output file is 'script.isql'.
  288. X
  289. X
  290. X    I hope this will prove of some use, and I would be more than happy
  291. X    to hear of any improvements :-)
  292. X
  293. X
  294. X    Michael Peppler        mpeppler@itf.ch
  295. X
  296. END_OF_FILE
  297.   if test 1741 -ne `wc -c <'eg/README'`; then
  298.     echo shar: \"'eg/README'\" unpacked with wrong size!
  299.   fi
  300.   # end of 'eg/README'
  301. fi
  302. if test -f 'eg/capture.pl' -a "${1}" != "-c" ; then 
  303.   echo shar: Will not clobber existing file \"'eg/capture.pl'\"
  304. else
  305.   echo shar: Extracting \"'eg/capture.pl'\" \(1640 characters\)
  306.   sed "s/^X//" >'eg/capture.pl' <<'END_OF_FILE'
  307. X#! /usr/local/bin/sybperl
  308. X
  309. X#
  310. X#    @(#)capture.pl    1.1    6/24/92
  311. X#
  312. X
  313. Xrequire "sybperl.pl";
  314. Xrequire "sql.pl";
  315. X
  316. X#
  317. X# Log us in to Sybase.
  318. X#
  319. X$d = &dblogin;
  320. X
  321. X&sql($d, "set statistics io on");
  322. X&sql($d, "set statistics time on");
  323. X
  324. X#
  325. X# Count the number off password tables.
  326. X#
  327. X@results = &sql($d, '
  328. X        select count(*) from sysobjects
  329. X        where name = "password" and type = "U"'
  330. X       );
  331. X
  332. X#
  333. X# If there is none create it else truncate it.
  334. X#
  335. Xif(@results[0] == 0) {
  336. X    &sql($d, '
  337. X        create table password(
  338. X            username char(8),
  339. X            uid int,
  340. X            gid int,
  341. X            shell varchar(30),
  342. X            home varchar(30)
  343. X        )'
  344. X    );
  345. X    print "The password table has been created.\n";
  346. X} else {
  347. X    &sql($d, 'truncate table password');
  348. X    print "The password table already exists. Table truncated!\n";
  349. X};
  350. X
  351. X#
  352. X# Read the password entries and add them to the database.
  353. X#
  354. Xwhile (($n,$p,$u,$g,$q,$c,$gc,$d,$s)= getpwent) {
  355. X    print "Adding $n.\n";
  356. X    &sql($d, "
  357. X        insert password
  358. X        values(\"$n\", $u, $g, \"$s\", \"$d\")
  359. X        "
  360. X    );
  361. X};
  362. Xendpwent;
  363. X
  364. X#
  365. X# Count the number off group tables.
  366. X#
  367. X@results = &sql($d, '
  368. X        select count(*) from sysobjects
  369. X        where name = "groups" and type = "U"'
  370. X       );
  371. X
  372. X#
  373. X# If there is none create it else truncate it.
  374. X#
  375. Xif(@results[0] == 0) {
  376. X    &sql($d, '
  377. X        create table groups(
  378. X            groupname char(8),
  379. X            gid int
  380. X        )'
  381. X    );
  382. X    print "The groups table has been created.\n";
  383. X} else {
  384. X    &sql($d, 'truncate table groups');
  385. X    print "The groups table already exists. Table truncated!\n";
  386. X};
  387. X
  388. X#
  389. X# Read the group entries and add them to the database.
  390. X#
  391. Xwhile (($gn,$gp,$gg,$gm)= getgrent) {
  392. X    print "Adding group $gn.\n";
  393. X    &sql($d, "
  394. X        insert groups
  395. X        values(\"$gn\", $gg)
  396. X        "
  397. X    );
  398. X};
  399. Xendgrent;
  400. X
  401. END_OF_FILE
  402.   if test 1640 -ne `wc -c <'eg/capture.pl'`; then
  403.     echo shar: \"'eg/capture.pl'\" unpacked with wrong size!
  404.   fi
  405.   chmod +x 'eg/capture.pl'
  406.   # end of 'eg/capture.pl'
  407. fi
  408. if test -f 'eg/dbtext.pl' -a "${1}" != "-c" ; then 
  409.   echo shar: Will not clobber existing file \"'eg/dbtext.pl'\"
  410. else
  411.   echo shar: Extracting \"'eg/dbtext.pl'\" \(708 characters\)
  412.   sed "s/^X//" >'eg/dbtext.pl' <<'END_OF_FILE'
  413. X#  Script which demonstrates dbwrite routine.
  414. X#
  415. X#  In isql do something like:
  416. X#       create table text_table (t_index int, the_text text)
  417. X#
  418. X
  419. Xrequire "sybperl.pl";
  420. Xrequire "sql.pl";
  421. X
  422. X$d = &dblogin;
  423. X$d2 = &dbopen;
  424. X
  425. X&sql ($d, 'delete from text_table');
  426. X&sql ($d, 'insert into text_table (t_index, the_text) values (5,"")');
  427. X
  428. X
  429. X&dbcmd($d,'select the_text, t_index from text_table where t_index = 5');
  430. X&dbsqlexec($d);                         # execute sql
  431. X
  432. X&dbresults($d);
  433. X@data = &dbnextrow($d);
  434. X
  435. X&dbwritetext ($d2, "text_table.the_text", $d, 1, "This is text which was added with Sybperl");
  436. X
  437. X@result = &sql($d,'select t_index, the_text from text_table where t_index = 5');
  438. X
  439. Xprint @result, "\n";
  440. X
  441. X&dbclose($d);
  442. X
  443. END_OF_FILE
  444.   if test 708 -ne `wc -c <'eg/dbtext.pl'`; then
  445.     echo shar: \"'eg/dbtext.pl'\" unpacked with wrong size!
  446.   fi
  447.   # end of 'eg/dbtext.pl'
  448. fi
  449. if test -f 'eg/report.pl' -a "${1}" != "-c" ; then 
  450.   echo shar: Will not clobber existing file \"'eg/report.pl'\"
  451. else
  452.   echo shar: Extracting \"'eg/report.pl'\" \(753 characters\)
  453.   sed "s/^X//" >'eg/report.pl' <<'END_OF_FILE'
  454. X#! /usr/local/bin/sybperl
  455. X
  456. X#
  457. X#    @(#)report.pl    1.1    6/24/92
  458. X#
  459. X
  460. Xrequire "sybperl.pl";
  461. Xrequire "sql.pl";
  462. X
  463. X#
  464. X# Log us in to Sybase.
  465. X#
  466. X$d = &dblogin;
  467. X
  468. X#
  469. X# define the format
  470. X#
  471. Xformat top=
  472. X             PASSWORD FILE
  473. XLogin      Uid Group      Shell                   Home directory
  474. X-------- ----- ---------- ----------------------- ----------------------
  475. X. 
  476. Xformat stdout=
  477. X@<<<<<<< @>>>> @<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<
  478. X$n,      $u,   $gn,       $s,                     $d
  479. X. 
  480. X
  481. X#
  482. X# See if everything is there.
  483. X#
  484. X@results = &sql($d, '
  485. X    select username, uid, isnull(groupname,convert(char,p.gid)), shell, home
  486. X    from password p, groups g
  487. X    where    p.gid *= g.gid
  488. X    order by uid
  489. X    ');
  490. Xforeach $x (@results) {
  491. X    ($n,$u,$gn,$s,$d) = split("~",$x);
  492. X    write;
  493. X}
  494. X
  495. END_OF_FILE
  496.   if test 753 -ne `wc -c <'eg/report.pl'`; then
  497.     echo shar: \"'eg/report.pl'\" unpacked with wrong size!
  498.   fi
  499.   chmod +x 'eg/report.pl'
  500.   # end of 'eg/report.pl'
  501. fi
  502. if test -f 'eg/space.pl' -a "${1}" != "-c" ; then 
  503.   echo shar: Will not clobber existing file \"'eg/space.pl'\"
  504. else
  505.   echo shar: Extracting \"'eg/space.pl'\" \(1494 characters\)
  506.   sed "s/^X//" >'eg/space.pl' <<'END_OF_FILE'
  507. X#! /usr/local/bin/sybperl
  508. X#
  509. X#    @(#)space.pl    1.2    4/2/93
  510. X
  511. Xrequire "sybperl.pl";
  512. Xrequire "sql.pl";
  513. X
  514. X#
  515. X# Log us in to Sybase.
  516. X#
  517. Xprint "Name of Sybase server: ";
  518. X$server = <>; chop($server);
  519. Xif($server ne '')
  520. X{
  521. X    $ENV{'DSQUERY'} = $server;
  522. X}
  523. Xelse
  524. X{
  525. X    $server = $ENV{'DSQUERY'};
  526. X}
  527. X
  528. Xprint "Administrative account password: ";
  529. Xeval `stty -echo`;
  530. X$sapw = <>; chop($sapw);
  531. Xeval `stty echo`;
  532. X
  533. X$d = &dblogin("sa", $sapw);
  534. X
  535. X
  536. X$server = $server . '.';
  537. X
  538. X
  539. X&sql($d, "use master");
  540. X@dbs = &sql($d, "select name from sysdatabases order by name");
  541. X
  542. Xforeach $n (@dbs) {
  543. X    &sql($d, "use $n");
  544. X    $x = join('~', &sql($d, 'sp_spaceused'));
  545. X    $x =~ s/ //g;
  546. X    $x =~ s/MB|KB//g;
  547. X    ($name, $size, $res, $data, $index, $free ) = split("~",$x);
  548. X    $unused = $size * 1024 - $res;
  549. X    write;
  550. X    $ts += $size;
  551. X    $tr += $res;
  552. X    $td += $data;
  553. X    $ti += $index;
  554. X    $tf += $free;
  555. X}
  556. X
  557. Xprint '-' x 78, "\n"; 
  558. X$name = 'TOTAL';
  559. X$size = $ts;
  560. X$res = $tr;
  561. X$data = $td;
  562. X$index = $ti;
  563. X$free = $tf;
  564. X$unused = $size * 1024 - $res;
  565. Xwrite;
  566. X
  567. Xformat top=
  568. XSpace usage per database for server @<<<<<<<<<<<<<<<
  569. X                    $server
  570. XName             Size    Reserved       Data      Index       Free     Unused
  571. X             (MB)        (KB)       (KB)       (KB)       (KB)       (KB)
  572. X-----------------------------------------------------------------------------
  573. X. 
  574. Xformat stdout=
  575. X@<<<<<<<<<  @>>>>>>>>  @>>>>>>>>>  @>>>>>>>>  @>>>>>>>>  @>>>>>>>>  @>>>>>>>>
  576. X$name,      $size,     $res,       $data,     $index,    $free,     $unused
  577. X. 
  578. X
  579. X
  580. END_OF_FILE
  581.   if test 1494 -ne `wc -c <'eg/space.pl'`; then
  582.     echo shar: \"'eg/space.pl'\" unpacked with wrong size!
  583.   fi
  584.   chmod +x 'eg/space.pl'
  585.   # end of 'eg/space.pl'
  586. fi
  587. if test -f 'eg/sql.pl' -a "${1}" != "-c" ; then 
  588.   echo shar: Will not clobber existing file \"'eg/sql.pl'\"
  589. else
  590.   echo shar: Extracting \"'eg/sql.pl'\" \(1738 characters\)
  591.   sed "s/^X//" >'eg/sql.pl' <<'END_OF_FILE'
  592. X#
  593. X#    @(#)sql.pl    1.1    6/24/92
  594. X#
  595. X
  596. Xsub sql {
  597. X    local($db,$sql,$sep)=@_;            # local copy parameters
  598. X
  599. X    $sep = '~' unless $sep;            # provide default for sep
  600. X
  601. X    @res = ();                    # clear result array
  602. X
  603. X    &dbcmd($db,$sql);                # pass sql to server
  604. X    &dbsqlexec($db);                # execute sql
  605. X
  606. X    while(&dbresults($db) != $NO_MORE_RESULTS) {    # copy all results
  607. X    while (@data = &dbnextrow($db1)) {
  608. X        push(@res,join($sep,@data));
  609. X    }
  610. X    }
  611. X
  612. X    @res;                    # return the result array
  613. X}
  614. X
  615. X
  616. X# Message and error handlers.
  617. X
  618. Xsub sql_message_handler
  619. X{
  620. X    local ($db, $message, $state, $severity, $text, $server, $procedure, $line)
  621. X    = @_;
  622. X
  623. X    if ($severity > 0)
  624. X    {
  625. X    print ("Sybase message ", $message, ", Severity ", $severity,
  626. X           ", state ", $state);
  627. X    print ("\nServer `", $server, "'") if defined ($server);
  628. X    print ("\nProcedure `", $procedure, "'") if defined ($procedure);
  629. X    print ("\nLine ", $line) if defined ($line);
  630. X    print ("\n    ", $text, "\n\n");
  631. X
  632. X# &dbstrcpy returns the command buffer.
  633. X
  634. X    local ($lineno) = 1;    # 
  635. X    foreach $row (split (/\n/, &dbstrcpy ($db)))
  636. X    {
  637. X        print (sprintf ("%5d", $lineno ++), "> ", $row, "\n");
  638. X    }
  639. X    }
  640. X    elsif ($message == 0)
  641. X    {
  642. X    print ($text, "\n");
  643. X    }
  644. X    
  645. X    0;
  646. X}
  647. X
  648. Xsub sql_error_handler {
  649. X    # Check the error code to see if we should report this.
  650. X    if ($_[2] != &SYBESMSG) {
  651. X    local ($db, $severity, $error, $os_error, $error_msg, $os_error_msg)
  652. X        = @_;
  653. X    print ("Sybase error: ", $error_msg, "\n");
  654. X    print ("OS Error: ", $os_error_msg, "\n") if defined ($os_error_msg);
  655. X    }
  656. X
  657. X    &INT_CANCEL;
  658. X}
  659. X
  660. X
  661. Xif( defined(&dbmsghandle))    # Is this a modern version of sybperl? ;-)
  662. X{
  663. X    &dbmsghandle ("sql_message_handler"); # Some user defined error handlers
  664. X    &dberrhandle ("sql_error_handler");
  665. X}
  666. X
  667. X
  668. X1;
  669. X
  670. END_OF_FILE
  671.   if test 1738 -ne `wc -c <'eg/sql.pl'`; then
  672.     echo shar: \"'eg/sql.pl'\" unpacked with wrong size!
  673.   fi
  674.   chmod +x 'eg/sql.pl'
  675.   # end of 'eg/sql.pl'
  676. fi
  677. if test -f 'lib/sybdb.ph' -a "${1}" != "-c" ; then 
  678.   echo shar: Will not clobber existing file \"'lib/sybdb.ph'\"
  679. else
  680.   echo shar: Extracting \"'lib/sybdb.ph'\" \(2788 characters\)
  681.   sed "s/^X//" >'lib/sybdb.ph' <<'END_OF_FILE'
  682. X;#    @(#)sybdb.ph    1.1    11/8/91
  683. X;#
  684. X;#
  685. X
  686. Xsub SYBESYNC {20001;}
  687. Xsub SYBEFCON {20002;}
  688. Xsub SYBETIME {20003;}
  689. Xsub SYBEREAD {20004;}
  690. Xsub SYBEBUFL {20005;}
  691. Xsub SYBEWRIT {20006;}
  692. Xsub SYBEVMS {20007;}
  693. Xsub SYBESOCK {20008;}
  694. Xsub SYBECONN {20009;}
  695. Xsub SYBEMEM {20010;}
  696. Xsub SYBEDBPS {20011;}
  697. Xsub SYBEINTF {20012;}
  698. Xsub SYBEUHST {20013;}
  699. Xsub SYBEPWD {20014;}
  700. Xsub SYBEOPIN {20015;}
  701. Xsub SYBEINLN {20016;}
  702. Xsub SYBESEOF {20017;}
  703. Xsub SYBESMSG {20018;}
  704. Xsub SYBERPND {20019;}
  705. Xsub SYBEBTOK {20020;}
  706. Xsub SYBEITIM {20021;}
  707. Xsub SYBEOOB {20022;}
  708. Xsub SYBEBTYP {20023;}
  709. Xsub SYBEBNCR {20024;}
  710. Xsub SYBEIICL {20025;}
  711. Xsub SYBECNOR {20026;}
  712. Xsub SYBENPRM {20027;}
  713. Xsub SYBEUVDT {20028;}
  714. Xsub SYBEUFDT {20029;}
  715. Xsub SYBEWAID {20030;}
  716. Xsub SYBECDNS {20031;}
  717. Xsub SYBEABNC {20032;}
  718. Xsub SYBEABMT {20033;}
  719. Xsub SYBEABNP {20034;}
  720. Xsub SYBEAAMT {20035;}
  721. Xsub SYBENXID {20036;}
  722. Xsub SYBERXID {20037;}
  723. Xsub SYBEICN {20038;}
  724. Xsub SYBENMOB {20039;}
  725. Xsub SYBEAPUT {20040;}
  726. Xsub SYBEASNL {20041;}
  727. Xsub SYBENTLL {20042;}
  728. Xsub SYBEASUL {20043;}
  729. Xsub SYBERDNR {20044;}
  730. Xsub SYBENSIP {20045;}
  731. Xsub SYBEABNV {20046;}
  732. Xsub SYBEDDNE {20047;}
  733. Xsub SYBECUFL {20048;}
  734. Xsub SYBECOFL {20049;}
  735. Xsub SYBECSYN {20050;}
  736. Xsub SYBECLPR {20051;}
  737. Xsub SYBECNOV {20052;}
  738. Xsub SYBERDCN {20053;}
  739. Xsub SYBESFOV {20054;}
  740. Xsub SYBEUNT {20055;}
  741. Xsub SYBECLOS {20056;}
  742. Xsub SYBEUAVE {20057;}
  743. Xsub SYBEUSCT {20058;}
  744. Xsub SYBEEQVA {20059;}
  745. Xsub SYBEUDTY {20060;}
  746. Xsub SYBETSIT {20061;}
  747. Xsub SYBEAUTN {20062;}
  748. Xsub SYBEBDIO {20063;}
  749. Xsub SYBEBCNT {20064;}
  750. Xsub SYBEIFNB {20065;}
  751. Xsub SYBETTS {20066;}
  752. Xsub SYBEKBCO {20067;}
  753. Xsub SYBEBBCI {20068;}
  754. Xsub SYBEKBCI {20069;}
  755. Xsub SYBEBCRE {20070;}
  756. Xsub SYBETPTN {20071;}
  757. Xsub SYBEBCWE {20072;}
  758. Xsub SYBEBCNN {20073;}
  759. Xsub SYBEBCOR {20074;}
  760. Xsub SYBEBCIS {20075;}
  761. Xsub SYBEBCPI {20076;}
  762. Xsub SYBEBCPN {20077;}
  763. Xsub SYBEBCPB {20078;}
  764. Xsub SYBEVDPT {20079;}
  765. Xsub SYBEBIVI {20080;}
  766. Xsub SYBEBCBC {20081;}
  767. Xsub SYBEBCFO {20082;}
  768. Xsub SYBEBCVH {20083;}
  769. Xsub SYBEBCUO {20084;}
  770. Xsub SYBEBCUC {20085;}
  771. Xsub SYBEBUOE {20086;}
  772. Xsub SYBEBUCE {20087;}
  773. Xsub SYBEBWEF {20088;}
  774. Xsub SYBEASTF {20089;}
  775. Xsub SYBEUACS {20090;}
  776. Xsub SYBEASEC {20091;}
  777. Xsub SYBETMTD {20092;}
  778. Xsub SYBENTTN {20093;}
  779. Xsub SYBEDNTI {20094;}
  780. Xsub SYBEBTMT {20095;}
  781. Xsub SYBEORPF {20096;}
  782. Xsub SYBEUVBF {20097;}
  783. Xsub SYBEBUOF {20098;}
  784. Xsub SYBEBUCF {20099;}
  785. Xsub SYBEBRFF {20100;}
  786. Xsub SYBEBWFF {20101;}
  787. Xsub SYBEBUDF {20102;}
  788. Xsub SYBEBIHC {20103;}
  789. Xsub SYBEBEOF {20104;}
  790. Xsub SYBEBCNL {20105;}
  791. Xsub SYBEBCSI {20106;}
  792. Xsub SYBEBCIT {20107;}
  793. Xsub SYBEBCSA {20108;}
  794. Xsub SYBENULL {20109;}
  795. Xsub SYBEUNAM {20110;}
  796. Xsub SYBEBCRO {20111;}
  797. Xsub SYBEMPLL {20112;}
  798. Xsub SYBERPIL {20113;}
  799. Xsub SYBERPUL {20114;}
  800. Xsub SYBEUNOP {20115;}
  801. Xsub SYBECRNC {20116;}
  802. Xsub SYBERTCC {20117;}
  803. Xsub SYBERTSC {20118;}
  804. Xsub SYBEUCRR {20119;}
  805. Xsub SYBERPNA {20120;}
  806. Xsub SYBEOPNA {20121;}
  807. X
  808. Xsub SUCCEED {1;}
  809. Xsub FAIL {0;}
  810. X
  811. Xsub INT_EXIT {0;}
  812. Xsub INT_CONTINUE {1;}
  813. Xsub INT_CANCEL {2;}
  814. X
  815. X1;
  816. X
  817. END_OF_FILE
  818.   if test 2788 -ne `wc -c <'lib/sybdb.ph'`; then
  819.     echo shar: \"'lib/sybdb.ph'\" unpacked with wrong size!
  820.   fi
  821.   # end of 'lib/sybdb.ph'
  822. fi
  823. if test -f 'lib/sybperl.pl' -a "${1}" != "-c" ; then 
  824.   echo shar: Will not clobber existing file \"'lib/sybperl.pl'\"
  825. else
  826.   echo shar: Extracting \"'lib/sybperl.pl'\" \(464 characters\)
  827.   sed "s/^X//" >'lib/sybperl.pl' <<'END_OF_FILE'
  828. X;#     @(#)sybperl.pl    1.2    11/25/91
  829. X
  830. X;# This file, when interpreted, sets the appropriate environment
  831. X;# variables for Sybase's use DB-Library & isql.
  832. X;#
  833. X;# usage:
  834. X;#    require 'sybperl.pl';
  835. X;#
  836. X;# We don't set the environment if it is already set.
  837. X
  838. Xrequire 'sybdb.ph';
  839. X
  840. X$ENV{'SYBASE'} = "/usr/local/sybase" unless $ENV{'SYBASE'};
  841. X$ENV{'DSQUERY'}= "SYBASE" unless $ENV{'DSQUERY'};
  842. X$ENV{'PATH'}="$ENV{'PATH'}:$ENV{'SYBASE'}/bin" unless $ENV{'PATH'} =~ /$ENV{'SYBASE'}/;
  843. X
  844. X
  845. END_OF_FILE
  846.   if test 464 -ne `wc -c <'lib/sybperl.pl'`; then
  847.     echo shar: \"'lib/sybperl.pl'\" unpacked with wrong size!
  848.   fi
  849.   # end of 'lib/sybperl.pl'
  850. fi
  851. if test -f 't/sbex.pl' -a "${1}" != "-c" ; then 
  852.   echo shar: Will not clobber existing file \"'t/sbex.pl'\"
  853. else
  854.   echo shar: Extracting \"'t/sbex.pl'\" \(4974 characters\)
  855.   sed "s/^X//" >'t/sbex.pl' <<'END_OF_FILE'
  856. X#!../sybperl
  857. X
  858. X
  859. X@nul = ('not null','null');
  860. X@sysdb = ('master', 'model', 'tempdb');
  861. X
  862. Xrequire "../lib/sybperl.pl";
  863. Xrequire "../lib/sybdb.ph";
  864. X
  865. Xprint "Sybperl version $SybperlVer\n\n";
  866. X
  867. Xprint "This script tests some of sybperl's functions, and prints out\n";
  868. Xprint "description of the databases that are defined in your Sybase\n";
  869. Xprint "dataserver.\n\n";
  870. X
  871. X
  872. X$dbproc = &dblogin("sa");    # Login to sybase
  873. X&dbmsghandle ("message_handler"); # Some user defined error handlers
  874. X&dberrhandle ("error_handler");
  875. X
  876. X$dbproc2 = &dbopen;        # Get a second dbprocess, so that we can select from several
  877. X                                # chanels simultaneously. We could code things so that this
  878. X                # feature is unnecessary, but it's good to exercise it.
  879. X
  880. X                # First, find out what databases exist:
  881. X&dbcmd($dbproc, "select name from sysdatabases order by crdate\n");
  882. X&dbsqlexec($dbproc);
  883. X&dbresults($dbproc);
  884. X
  885. Xdatabase: while((@db = &dbnextrow($dbproc)))
  886. X{
  887. X    foreach $nm (@sysdb)
  888. X    {
  889. X    if($db[0] =~ /$nm/)
  890. X    {
  891. X        print "'$db[0]' is a system database\n";
  892. X        next database;
  893. X    }
  894. X    }
  895. X    print "Finding user tables in user database $db[0]...";
  896. X
  897. X    &dbcmd($dbproc2, "select o.name, u.name, o.id\n"); # 
  898. X    &dbcmd($dbproc2, "from $db[0].dbo.sysobjects o, $db[0].dbo.sysusers u\n");
  899. X    &dbcmd($dbproc2, "where o.type = 'U' and u.uid = o.uid\n");
  900. X    &dbcmd($dbproc2, "order by o.name\n");
  901. X
  902. X    &dbsqlexec($dbproc2);
  903. X    &dbresults($dbproc2);
  904. X
  905. X    while((@dat = &dbnextrow($dbproc2)))
  906. X    {
  907. X    $tab = join('@', @dat);    # Save the information
  908. X    push(@tables, $tab);    # for later use...
  909. X    }
  910. X    print "Done.\n";
  911. X
  912. X    print "Finding user defined datatypes in database $db[0]...\n";
  913. X
  914. X    &dbcmd($dbproc2, "select s.length,substring(s.name,1,30),substring(st.name,1,30)\n");
  915. X    &dbcmd($dbproc2, "from $db[0].dbo.systypes s, $db[0].dbo.systypes st\n");
  916. X    &dbcmd($dbproc2, "where  st.type = s.type\n");
  917. X    &dbcmd($dbproc2, "and s.usertype > 100 and st.usertype < 100 and st.usertype != 18\n");
  918. X    &dbsqlexec($dbproc2);
  919. X    &dbresults($dbproc2);
  920. X
  921. X    while((@dat = &dbnextrow($dbproc2)))
  922. X    {
  923. X    print "sp_addtype $dat[1],";
  924. X    if ($dat[2] =~ /char|binary/)
  925. X    {
  926. X        print "'$dat[2]($dat[0])'";
  927. X    }
  928. X    else
  929. X    {
  930. X        print "$dat[2]";
  931. X    }
  932. X    print "\n";
  933. X
  934. X    }
  935. X    print "Done.\n";
  936. X
  937. X    print "Now we find the table definition for each user table\nin database $db[0]...\n";
  938. X
  939. X    foreach $ln (@tables)        # For each line in the list
  940. X    {
  941. X    @tab = split('@',$ln);
  942. X
  943. X    &dbcmd($dbproc2, "select Column_name = c.name, \n");
  944. X    &dbcmd($dbproc2, "       Type = t.name, \n");
  945. X    &dbcmd($dbproc2, "       Length = c.length, \n");
  946. X    &dbcmd($dbproc2, "       Nulls = convert(bit, (c.status & 8))\n");
  947. X    &dbcmd($dbproc2, "from   $db[0].dbo.syscolumns c, $db[0].dbo.systypes t\n");
  948. X    &dbcmd($dbproc2, "where  c.id = $tab[2]\n");
  949. X    &dbcmd($dbproc2, "and    c.usertype *= t.usertype\n");
  950. X    
  951. X    &dbsqlexec($dbproc2);
  952. X    &dbresults($dbproc2);
  953. X
  954. X    print "\nTABLE $db[0].$tab[1].$tab[0]\n ("; 
  955. X    $first = 1;
  956. X    while((@field = &dbnextrow($dbproc2)))
  957. X    {
  958. X        print ",\n" if !$first;        # add a , and a \n if not first field in table
  959. X        
  960. X        print "\t$field[0] \t$field[1]";
  961. X        print "($field[2])" if $field[1] =~ /char|bin/;
  962. X        print " $nul[$field[3]]";
  963. X
  964. X        $first = 0 if $first;
  965. X    }
  966. X    print " )\n";
  967. X
  968. X# now get the indexes...
  969. X#
  970. X    print "\nIndexes on $db[0].$tab[0].$tab[1]...\n\n";
  971. X    &dbuse($dbproc2, $db[0]);
  972. X    &dbcmd($dbproc2, "sp_helpindex '$tab[1].$tab[0]'\n");
  973. X
  974. X    &dbsqlexec($dbproc2);
  975. X    &dbresults($dbproc2);
  976. X
  977. X    while((@field = &dbnextrow($dbproc2)))
  978. X    {
  979. X        print "unique " if $field[1] =~ /unique/;
  980. X        print "clustered " if $field[1] =~ /^clust/;
  981. X        print "index $field[0]\n";
  982. X        @col = split(/,/,$field[2]);
  983. X        print "on $db[0].$tab[1].$tab[0] (";
  984. X        $first = 1;
  985. X        foreach $ln1 (@col)
  986. X        {
  987. X        print ", " if !$first;
  988. X        $first = 0;
  989. X        print "$ln1";
  990. X        }
  991. X        print ")\n";
  992. X    }
  993. X    print "\nDone.\n";
  994. X    }
  995. X    &dbuse($dbproc2, "master");
  996. X    @tables = ();
  997. X}
  998. X
  999. X&dbexit;
  1000. X
  1001. X
  1002. X# Message and error handlers.
  1003. X
  1004. Xsub message_handler
  1005. X{
  1006. X    local ($db, $message, $state, $severity, $text, $server, $procedure, $line)
  1007. X    = @_;
  1008. X
  1009. X    if ($severity > 0)
  1010. X    {
  1011. X    print ("Sybase message ", $message, ", Severity ", $severity,
  1012. X           ", state ", $state);
  1013. X    print ("\nServer `", $server, "'") if defined ($server);
  1014. X    print ("\nProcedure `", $procedure, "'") if defined ($procedure);
  1015. X    print ("\nLine ", $line) if defined ($line);
  1016. X    print ("\n    ", $text, "\n\n");
  1017. X
  1018. X# &dbstrcpy returns the command buffer.
  1019. X
  1020. X    local ($lineno) = 1;    # 
  1021. X    foreach $row (split (/\n/, &dbstrcpy ($db)))
  1022. X    {
  1023. X        print (sprintf ("%5d", $lineno ++), "> ", $row, "\n");
  1024. X    }
  1025. X    }
  1026. X    elsif ($message == 0)
  1027. X    {
  1028. X    print ($text, "\n");
  1029. X    }
  1030. X    
  1031. X    0;
  1032. X}
  1033. X
  1034. Xsub error_handler {
  1035. X    # Check the error code to see if we should report this.
  1036. X    if ($_[2] != &SYBESMSG) {
  1037. X    local ($db, $severity, $error, $os_error, $error_msg, $os_error_msg)
  1038. X        = @_;
  1039. X    print ("Sybase error: ", $error_msg, "\n");
  1040. X    print ("OS Error: ", $os_error_msg, "\n") if defined ($os_error_msg);
  1041. X    }
  1042. X
  1043. X    &INT_CANCEL;
  1044. X}
  1045. X
  1046. X
  1047. X
  1048. END_OF_FILE
  1049.   if test 4974 -ne `wc -c <'t/sbex.pl'`; then
  1050.     echo shar: \"'t/sbex.pl'\" unpacked with wrong size!
  1051.   fi
  1052.   chmod +x 't/sbex.pl'
  1053.   # end of 't/sbex.pl'
  1054. fi
  1055. echo shar: End of archive 2 \(of 2\).
  1056. cp /dev/null ark2isdone
  1057. MISSING=""
  1058. for I in 1 2 ; do
  1059.     if test ! -f ark${I}isdone ; then
  1060.     MISSING="${MISSING} ${I}"
  1061.     fi
  1062. done
  1063. if test "${MISSING}" = "" ; then
  1064.     echo You have unpacked both archives.
  1065.     rm -f ark[1-9]isdone
  1066. else
  1067.     echo You still must unpack the following archives:
  1068.     echo "        " ${MISSING}
  1069. fi
  1070. exit 0
  1071. exit 0 # Just in case...
  1072.