⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch18.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<HTML>



<HEAD>

   <TITLE>Chapter 18 -- Databases for Perl</TITLE>

   <META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">

</HEAD>

<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">

<H1><FONT COLOR=#FF0000>Chapter 18</FONT></H1>

<H1><B><FONT SIZE=5 COLOR=#FF0000>Databases for Perl</FONT></B>

</H1>

<P>

<HR WIDTH="100%"></P>

<P>

<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>

</FONT></FONT></H3>



<UL>

<LI><A HREF="#TheDBMPackages" >The DBM Packages</A>

<LI><A HREF="#ViewingYourData" >Viewing Your Data</A>

<LI><A HREF="#AddingandRemovingItems" >Adding and Removing Items</A>

<LI><A HREF="#OperationsonaDBMFile" >Operations on a DBM File</A>

<LI><A HREF="#UsingDBMinModules" >Using DBM in Modules</A>

<LI><A HREF="#MultipleDBMFiles" >Multiple DBM Files</A>

<LI><A HREF="#TheCatchwithDBMUtilities" >The Catch with DBM Utilities</A>

<LI><A HREF="#WhatIstheDBIPackage" >What Is the DBI Package?</A>

<UL>

<LI><A HREF="#AvailablePackages" >Available Packages</A>

</UL>

<LI><A HREF="#RDB" >RDB</A>

<LI><A HREF="#Summary" >Summary</A>

</UL>

<HR>

<P>

There are two ways to look at working with databases in Perl.

You can either implement the database entirely in Perl or use

Perl as an interface to existing database engines on your machine.

You can use stand-alone database packages, such as the DBM package

that comes with Perl, or you can get other packages, such as the

RDBM package, off the Internet. To use Perl as an interface to

a commercial package, you can use driver front-ends to the database

engine for the package.

<H2><A NAME="TheDBMPackages"><FONT SIZE=5 COLOR=#FF0000>The DBM

Packages</FONT></A></H2>

<P>

Perl comes with a set of database management (DBM) library files.

Here's the list of packages that come with the latest version

of Perl (5.002):

<UL>

<LI><TT><FONT FACE="Courier">GDBM_File.pm</FONT></TT>-GNU's database

interface files

<LI><TT><FONT FACE="Courier">NDBM_File.pm</FONT></TT>-Berkeley

UNIX compatibility

<LI><TT><FONT FACE="Courier">ODBM_File.pm</FONT></TT>-Standard

Perl package

<LI><TT><FONT FACE="Courier">SDBM_File.pm</FONT></TT>-Standard

Perl package

<LI><TT><FONT FACE="Courier">AnyDBM_File.pm</FONT></TT>-Virtual

classes for any of the above database interfaces

</UL>

<P>

The <TT><FONT FACE="Courier">AnyDBM_File</FONT></TT> package encapsulates

the rest of the packages. If you use the <TT><FONT FACE="Courier">AnyDBM</FONT></TT>

file, you'll automatically load one of the standard packages from

the previous list. To use the <TT><FONT FACE="Courier">AnyDBM_File</FONT></TT>

package, insert the following statement at the start of your Perl

script:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">use AnyDBM_File;</FONT></TT>

</BLOCKQUOTE>

<P>

There is nothing preventing you from explicitly naming a particular

DBM package to override the defaults used by the <TT><FONT FACE="Courier">AnyDBM_file</FONT></TT>

package. To use the <TT><FONT FACE="Courier">GDBM_File</FONT></TT>

explicitly, insert this statement instead:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">use GDBM_File;</FONT></TT>

</BLOCKQUOTE>

<P>

A DBM, when used with these packages, is a mapping of an associative

array to a file on disk. To map the associative array to disk,

you use <TT><FONT FACE="Courier">dbmopen()</FONT></TT> to create

or open an existing file, make all the modifications to the associative

array, and then close the file with a call to <TT><FONT FACE="Courier">dmbclose()</FONT></TT>.

<P>

I covered how to bind variables to associative arrays and how

to use the <TT><FONT FACE="Courier">tie()</FONT></TT> function

in <A HREF="ch6.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch6.htm" >Chapter 6</A>, &quot;Binding Variables to

Objects.&quot; In the future, most <TT><FONT FACE="Courier">dbmopen()</FONT></TT>

function calls will be replaced by, or at least internally work

as, <TT><FONT FACE="Courier">tie()</FONT></TT> function calls.

Basically, a DBM file will be tied to an associative array. Subsequent

updates to the associative array will be reflected in the file

on disk. However, you will come across legacy code that does use

the <TT><FONT FACE="Courier">dbmopen()</FONT></TT> and <TT><FONT FACE="Courier">dbmclose()</FONT></TT>

functions, so it's important to see how these work together. Also,

you may find it easier to use these DBM functions to program for

quick prototyping than to have to code the callback functions

required for the <TT><FONT FACE="Courier">tie()</FONT></TT> function.

After you've read this chapter, you should be able to decide whether

to use DBM functions or write the functions for database access

using the <TT><FONT FACE="Courier">tie()</FONT></TT> function.

<P>

Here's an example to illustrate how the DBM files work. First,

I'll create a small database of some stock symbols and the names

of the companies. The file containing this data sample is called

<TT><FONT FACE="Courier">sym.txt</FONT></TT> and is partially

shown here: 

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$ <B>head sym.txt<BR>

</B>ASZ&nbsp;&nbsp;AMSCO INTL Inc<BR>

AMSR&nbsp;&nbsp;AMSERV HEALTHCARE<BR>

ASO&nbsp;&nbsp;AMSOUTH BAncORP<BR>

AMTC&nbsp;&nbsp;AMTEch<BR>

AMTL&nbsp;&nbsp;AMTROL<BR>

AVFC&nbsp;&nbsp;AMVESTORS FIN CORP<BR>

AMW&nbsp;&nbsp;AMWEST INSURAncE GROUP<BR>

AMLN&nbsp;&nbsp;AMYLIN PHARMACEUTICALS<BR>

AAC&nbsp;&nbsp;ANACOMP Inc<BR>

Apc&nbsp;&nbsp;ANADARKO PETROLEUM CORP<BR>

$</FONT></TT>

</BLOCKQUOTE>

<P>

This file contains several lines of records where each record

has two items of data: the first column is the stock ticker symbol

followed by the company name. Note that a company name can contain

one or more space characters.

<P>

Now I'll construct a mini-database of all company names indexed

by their stock symbol. To use the DBM utilities for this endeavor,

I would use the script shown in Listing 18.1.

<HR>

<BLOCKQUOTE>

<B>Listing 18.1. Creating a DBM file.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2 # --------------------------------------------------------

<BR>

&nbsp;3 # Sample script to create a DBM repository.<BR>

&nbsp;4 # Input file &quot;sym.txt&quot; to the script has the

format:<BR>

&nbsp;5 #&nbsp;&nbsp;&nbsp;&nbsp;SYMBOL&nbsp;&nbsp;Company Name

<BR>

&nbsp;6 # --------------------------------------------------------

<BR>

&nbsp;7 #<BR>

&nbsp;8 # Use the default DBM utilites<BR>

&nbsp;9 #<BR>

10 use AnyDBM_File;<BR>

11 open(SFILE, &quot;sym.txt&quot;) || die &quot;\n Cannot open

sym.txt $!\n&quot;;<BR>

12 #<BR>

13 # Open the database &quot;ticker&quot;. If it does not exist,

create it.<BR>

14 # Map the hash stocks to this database.<BR>

15 #<BR>

16 dbmopen(%stocks,&quot;ticker&quot;,0666);<BR>

17 while (&lt;SFILE&gt;) {<BR>

18&nbsp;&nbsp;&nbsp;&nbsp; chop;<BR>

19&nbsp;&nbsp;&nbsp;&nbsp; ($symbol,@name) =&nbsp;&nbsp;split('

',$_);<BR>

20<BR>

21&nbsp;&nbsp;&nbsp;&nbsp; $stocks{$symbol} = join(' ',@name);

<BR>

22&nbsp;&nbsp;&nbsp;&nbsp; # print &quot; $symbol [ @name ] \n&quot;;

<BR>

23&nbsp;&nbsp;&nbsp;&nbsp; }<BR>

24 #<BR>

25 # Close the input file<BR>

26 #<BR>

27 close(SFILE);<BR>

28 #<BR>

29 # Commit changes in hash to disk for the next flush.<BR>

30 #<BR>

31 dbmclose(%stocks);</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

In Listing 18.1, the <TT><FONT FACE="Courier">AnyDBM_File</FONT></TT>

package is used at line 10 to get the best available package for

the system. You can override the type by replacing the <TT><FONT FACE="Courier">AnyDBM_File</FONT></TT>

package with a DBM package of your choice. In line 11, the input

file is opened.

<P>

Line 16 creates a DBM called <TT><FONT FACE="Courier">ticker</FONT></TT>

and maps it onto an associative array called <TT><FONT FACE="Courier">%stocks{}</FONT></TT>.

Note that you are actually creating two files called <TT><FONT FACE="Courier">ticker.pag</FONT></TT>.

The file permissions given for this <TT><FONT FACE="Courier">open</FONT></TT>

are 0666 so that it's possible for all other users to use this

DBM. 

<P>

In lines 17 through 23, the symbol names are read in, and the

values are assigned to the newly created hash, called <TT><FONT FACE="Courier">stocks</FONT></TT>.

Lines 18 and 19 simply take the text input from the <TT><FONT FACE="Courier">sym.txt</FONT></TT>

file and separate it into a symbol and a company name. At line

21 a value is assigned to the associative array using the symbol

as the index into the array. Now that this array has been mapped

to the disk, the data can be kept in the array even after the

script that created this file is long gone.

<P>

Note also that the <TT><FONT FACE="Courier">join() </FONT></TT>function

is used in line 21 to piece together the items of names of the

companies into one string. Had the <TT><FONT FACE="Courier">join()</FONT></TT>

function not been used, <TT><FONT FACE="Courier">$stocks{$symbol}</FONT></TT>

would contain the number of items of the <TT><FONT FACE="Courier">@names</FONT></TT>

array and not the contents.

<P>

In line 31 the <TT><FONT FACE="Courier">dbmclose()</FONT></TT>

function is used to commit the changes to disk. If you do not

use <TT><FONT FACE="Courier">dbmclose()</FONT></TT>, your DBM

file modifications are not be saved to disk. The <TT><FONT FACE="Courier">dbmclose()</FONT></TT>

function disconnects (or un-<I>tie</I>s) the hash from the file

on disk so that any changes made to the hash after the <TT><FONT FACE="Courier">dbmclose()</FONT></TT>

function are made as if to an uninitialized associative array.

When the contents of the hash will be flushed to disk depends

on the underlying system. As far as the program is concerned,

the hash connected to the underlying database is not initialized

anymore.

<P>

Two files are created with the use of the <TT><FONT FACE="Courier">AnyDBM_File</FONT></TT>

package. These are the two files that were created by the script

in Listing 18.1 when I ran it:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">-rw-r--r--&nbsp;&nbsp;&nbsp;2 khusain&nbsp;&nbsp;users&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6608

Mar 26 08:08 scripts/ticker.dir<BR>

-rw-r--r--&nbsp;&nbsp;&nbsp;2 khusain&nbsp;&nbsp;users&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6608

Mar 26 08:08 scripts/ticker.pag</FONT></TT>

</BLOCKQUOTE>

<P>

Of course, because you do not have access to the original files

that I used in this example, the sizes shown here will be different

for the data file that you use. Just note that the size of both

the files is the same. 

<P>

If the <TT><FONT FACE="Courier">AnyDBM_File</FONT></TT> package

had been substituted with the <TT><FONT FACE="Courier">GDBM_File</FONT></TT>

page, we would only get one file:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">-rw-r--r--&nbsp;&nbsp;&nbsp;1 khusain&nbsp;&nbsp;users&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;6608

Mar 26 08:06 scripts/ticker</FONT></TT>

</BLOCKQUOTE>

<P>

Again, the size of the <TT><FONT FACE="Courier">ticker</FONT></TT>

file will be different depending on the input data file that you

use. However, you should note that the size of the ticker file

is the same as that of the two files created by the <TT><FONT FACE="Courier">AnyDBM-File</FONT></TT>

package. 

<H2><A NAME="ViewingYourData"><FONT SIZE=5 COLOR=#FF0000>Viewing

Your Data</FONT></A></H2>

<P>

The database has now been created on disk. Whether it consists

of one file or two is not important in the application that will

access the database because all the internals are hidden with

the DBM function calls. 

<P>

In order for us to look at the data in the newly created DBM file,

another script needs to be created. The viewing script is shown

in Listing 18.2.

<HR>

<BLOCKQUOTE>

<B>Listing 18.2. Viewing the contents of a DBM file.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2 # --------------------------------------------------------

<BR>

&nbsp;3 # Sample script to list contents of a DBM repository.

<BR>

&nbsp;4 # --------------------------------------------------------

<BR>

&nbsp;5 #<BR>

&nbsp;6 # Use the default DBM utilites<BR>

&nbsp;7 #<BR>

&nbsp;8 use AnyDBM_File;<BR>

&nbsp;9 #<BR>

10 # Open the database &quot;ticker&quot;. (If it does not exist,

create it.)<BR>

11 # Map the hash stocks to this database.<BR>

12 #<BR>

13 dbmopen(%stocks,&quot;ticker&quot;,0666);<BR>

14 while (($symbol,$name) = each(%stocks)) {<BR>

15&nbsp;&nbsp;&nbsp;&nbsp; print &quot;Symbol [$symbol] for [$name]\n&quot;;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -