Tải bản đầy đủ - 0 (trang)
Chapter 16. Using PostgreSQL with Tcl and Tcl/Tk

Chapter 16. Using PostgreSQL with Tcl and Tcl/Tk

Tải bản đầy đủ - 0trang

Ifyouwanttosuppressvariableandcommandsubstitution,

surroundastringwithcurlybraces.

Ifyoudon'twanttosuppresssubstitution,surroundastring

withdoublequotes.

Ifyourememberthosesimplerules(andsuspendyour

disbeliefitreallyisthatsimple),you'llbefluentinTclinnotime.

WhenyoustartwritingTclapplications,you'llprobablyusethe

Tclshellasanexecutionenvironment.TheTclshell(tclsh)isa

simpleshell(likebashorsh)thathasbeencombinedwiththe

Tclinterpreter.Usingtclsh,youcandoallthethingsyouwould

normallydoinaUnixshell(suchasrunaprogram,change

directories,redirectoutput,andsoon)inadditiontoallthe

thingsyoucandoinaTclprogram.

TclisoftencombinedwithTk.Tkisagraphicaltoolkit.UsingTk,

youcancreatewindowsandwidgets(graphicalcontrols),and

interactwiththeuserinagraphicalinterface.YoucanuseTk

withmanydifferentlanguages,butitwasoriginallydesignedas

acompaniontoTcl.TheTcl/Tkenvironmentincludesagraphical

shellcalledwish.Thewishshellissimilartotclsh,exceptthat

ithasTkthrowninsoyoucanbuildgraphicalshellscripts.

Tclapplications(andthereforeTcl/Tkapplications)caninteract

withPostgreSQLdatabaseservers.TheTcl-to-PostgreSQL

interfaceiscontainedinalibrarynamedlibpgtcl.libpgtcl

providesasmallnumber(17)ofproceduresthatyoucancall

fromaTclscript.Inthischapter,I'lldescribeeachofthese

procedures,andyou'llbuildafewclientapplicationsthatshow

youhowtouselibpgtcltobuildPostgreSQLclientapplications.



Prerequisites

Ifyouwanttotrytheexamplesinthischapter,youwillneedto

installandconfigureTcl/Tk(version8.0orlater)andlibpgtcl.

IfyouarerunningonaLinuxhost,thechancesaregoodthat

youalreadyhaveTcl/Tkinstalledonyoursystem.Tofindout

whetherTclisreadytouse,enterthecommandtclsh,as

shownhere:

$tclsh

%exit

$

Ifyouseethe%prompt,youhaveTclinstalledonyoursystem.

Ifinstead,youseeanerrorsuchas"tcl:commandnot

found",youmaystillhaveacopyofTclinstalledonyour

system,butit'snotinyoursearchpath($PATH)askyour

systemadministratorwhetherTclisavailable.

IfyoufindthatyouneedtoinstallTcl,youcanfinditat

http://tcl.activestate.com.ActiveStatedistributesTcl/Tkin

binary(precompiled)formforLinux,Solaris,andWindows.You

canalsofindthesourcecodeforTcl/TkatActiveState.

Thesecondcomponentthatyouneedislibpgtcl.libpgtclisa

packageofTclextensionfunctionsthatenableaTclscriptto

interactwithPostgreSQL.Thiscomponentcanbealittlehardto

find.IfyouarebuildingyourcopyofPostgreSQLfromsource

code,addingthe--with-tclflagtoconfigureshouldbuild

libpgtclforyou.IfyouhaveinstalledPostgreSQLusingaRPM

package,besuretoinstallthepostgresql-tclpackage.Ifyou



areusingTclonaWindowshost,theeasiestwaytoobtainthe

libpgtcllibraryistoinstallPgAccess

(http://www.pgaccess.org).

Finally,someoftheexamplesinthischapterrequirethe

TkTableextensiontoTk.TkTableprovidesatablewidgetthat

youwillusetodisplayqueryresults.Ifyouhavealready

installedTclandTk,youmayfindthatTkTablecamewiththe

distributionthatyouloaded.Ifnot,youcanfindTkTableat

http://tktable.sourceforge.net.



PostgreSQL-RelatedTcl/TkComponents

AsImentionedintheprevioussection,libpgtclisalibraryof

PostgreSQL-relatedfunctionsthatyoucancallfromwithinaTcl

script.Thelibpgtclpackagealsoincludestwoshellprograms.

pgtclshisacopyoftheTclshell(tclsh)thatautomatically

loadsthelibpgtcllibrary.pgtkshisacopyofthewishshellthat

willautomaticallyloadlibpgtclatstartup.



Client1ConnectingtotheServer

ThefirststeptointeractingwithaPostgreSQLserveristo

establishaconnection;inthissection,you'lluseTclandTkto

buildasimplegraphicalclientthatestablishesaconnectiontoa

PostgreSQLserver.Thelibpgtcllibraryisimplementedontopof

thelibpq,somanyofthefeaturesthatyouseeinlibpgtclwill

seemfamiliarifyou'vereadthroughChapter8,"The

PostgreSQLCAPIlibpq."ToconnecttoaPostgreSQLserver,use

thepg_connectprocedure.pg_connectcomesintwoflavors:

pg_connect-conninfoconnection-string

or

pg_connectdatabase-name

[-hosthost-name]

[-portport-number]

[-ttytty-name]

[-optionsoption-string]

Thesecondformisconsideredobsolete,andI'veincludedit

hereonlyforcompleteness.

Thepreferredformusesaconnectionstringsimilartothose

usedinlibpqapplications.Aconnectionstringisalistof

keyword=valuepairs,separatedbywhitespace.Eachpairinthe

connectionstringspecifiesthevalueforaconnectionproperty.



Atypicalconnectionstringmightlooksomethinglikethis:

host=davinciuser=brucepassword=koalasdbname=movies

Thisparticularconnectionstringprovidesfourconnection

properties:ahostname,ausernameandpassword,anda

databasename.Table16.1liststhepropertiesthatmayappear

inaconnectionstring.

Table16.1.ConnectionProperties

Connect-StringProperty



EnvironmentVariable



Example



user



PGUSER



user=korry



password



PGPASSWORD



password=cows



dbname



PGDATABASE



dbname=accounting



host



PGHOST



host=jersey



hostaddr



PGHOSTADDR



hostaddr=127.0.0.1



port



PGPORT



port=5432



ThesecondcolumninTable16.1showstheenvironment

variablethatlibpgtclwilluseifyouomitthepropertyshownin

thefirstcolumn.Forexample,ifyouomitthehostproperty

fromyourconnectionstring,libpgtclwillusethevalueofthe

PGHOSTenvironmentvariable.Ifyoudon'tsupplyaparticular

propertyintheconnectionstring,andyouhaven'tdefinedthe

correspondingenvironmentvariable,libpgtclwillusehard-wired

defaultvalues.Toseethehard-wiredvalues,youcanusethe

pg_conndefaults[1]procedure:



[1]I'vecleanedupthelistingreturnedby

read.



pg_conndefaultstomakeiteasierto



$pgtclsh

%foreachprop[pg_conndefaults]{puts$prop}

authtypeDatabase-AuthtypeD20{}

serviceDatabase-Service{}20{}

userDatabase-User{}20korry

passwordDatabase-Password*20{}

dbnameDatabase-Name{}20korry

hostDatabase-Host{}40{}

hostaddrDatabase-Host-IPv4-Address{}15{}

portDatabase-Port{}65432

ttyBackend-Debug-TTYD40{}

optionsBackend-Debug-OptionsD40{}

Thefirstcolumnlistspropertynames;thelastcolumndisplays

thefinaldefaultvaluesthatwillbeusedifyoudon'tprovide

overrides.

Thepg_conndefaultsprocedurereturnsalistofsublists.The

valuesreturnedbypg_conndefaultsmightseemalittle

confusinguntilyouunderstandtheproblemthatthisprocedure

wastryingtosolve.Fromtimetotime,thePostgreSQLauthors



needtointroducenewconnectionproperties.Howcanyou

supportnewconnectionpropertieswithoutrewritingevery

PostgreSQLclientapplication?Theclientapplicationcanask

pg_conndefaultsforalistofsupportedpropertiesandthen

asktheusertoprovideavalueforeachofthoseproperties.A

robustclientapplicationwillnothavetoberecompiledeach

timeanewconnectionpropertyisintroduced;itjustprompts

theuserformoreinformation.

Havingsaidthat,youprobablywon'tletmeoffthehookunless

webuilda"robust"clientapplication(oratleastmakean

attempt).

Thefirstclientapplicationinthischapterdoeslittlemorethan

connecttoaPostgreSQLserver,butdoessousingaselfadjustinglogindialogbox.Thisparticularclientapplicationis

ratherlongbuildingagraphicallogindialogfrombarebones

Tcl/Tkisnotatrivialtask.Inareal-worldapplication,youmight

wanttoexploreadd-ontoolkitsthatmakeiteasiertodothis

sortofwork.

Let'sdiveintothecodeforclient1.tclI'llexplainthehowtouse

pg_conndefaultsaswego.You'llalsoseehowtocallthe

pg_connectprocedure.Listing16.1showsthestartofthe

client1.tclapplication.



Listing16.1client1.tclmain



1#!/usr/local/bin/wish

2#

3#Filename:client1.tcl

4



5procmain{}{

6

7loadlibpgtcl

8

9wmwithdraw.

10

11setresult"retry"

12

13while{$result=="retry"}{

14setconnstr[connect_dialog]

15

16if{[catch{pg_connect-conninfo$connstr}conn]}{

17setresult[tk_messageBox\

18-message$conn\

19-title"Connectionfailed"\

20-typeretrycancel]

21}else{

22tk_messageBox\



23-message"Connectionis:$conn"\

24-title"ConnectionOk"

25

26setresult"ok"

27}

28}

29}

Thefirstlineisusedtospecifythenameoftheinterpreterthat

shouldbeusedtorunthisscript:wishisthegraphicalTcl/Tk

shell[2].Line5definesaprocedurenamedmain.Unlikemany

otherlanguages,afunctionwiththenameofmainisnotthe

defaultentrypointforTclscriptyoucallthisfunctionmainjust

sothatitiseasilyrecognizable.InTcl,theentrypointfora

programisthefirstexecutablelineofcodeoutsideofaproc

definition.Infact,thefirstfewexecutablelinesofcodeinthis

programarerightattheendofthescript(theendofthisscript

isnotshowninListing16.1;youstillhavefourmorelistingsto

getthrough).

[2]Themagicstringatthestringatthebeginningofashellscriptsuchasthisiscalledthe

shebangline:"she"isforshelland"bang"ishowsomepeoplepronouncetheexclamationpoint.

Ashebanglinetellstheoperatingsystemwhichprogramshouldbeusedtoexecutethescript.

ShebanglinesaresupportedonUnixandLinuxhosts,butnotonWindowssystems(exceptwhen

usingtheCygwinenvironment).



Themainfunctionexpectsnoarguments(youcantellthat

becausethebracesimmediatelyfollowingthefunctionname

areempty).

Thefirstthingthatyoudointhisfunctionisloadthelibpgtcl

libraryintotheTclinterpreter(onsomesystems,youmayneed



toloadlibpgtcl.so).BeforeyoucancallanyPostgreSQLrelatedfunctions,youmustloadthelibpgtcllibrary.Ifyou

changethefirstlineofthisscripttoread

#!/usr/local/bin/pgtksh

youwon'tneedtoloadlibpgtcl;pgtkshisaTkshellthat

automaticallyloadslibpgtcl.Next,withdrawtherootwindow.If

youarenotaseasonedTkprogrammer,thatprobablysoundsa

littleominous.Whenthewishinterpreterstartsup,it

automaticallycreatesanemptywindowforyou.Thatwindowis

calledarootwindow,anditsnameissimplytheperiod

character(.).Youwithdrawthewindownowsothatyoucan

makeyourownwindowalittlelater.

Lines13through28formaloop.Insidethisloop,youcreatea

dialogboxthatpromptstheuserforconnectionproperties.

Figure16.1showsthedialogboxthatappearswhenyourun

client1.tcl.



Figure16.1.TheConnectionInfodialogbox.



IftheuserclickstheCancelbutton,theentireapplicationwill

end.IftheuserclickstheConnectbutton,ittriestoconnectto

aPostgreSQLserverusingtheinformationprovided.Ifthe

connectattemptsucceeds,amessagedisplaysandthe



applicationterminates.Ifaconnectionattemptfails,youwant

theusertoseeaRetry/Canceldialogthatdisplaystheerror

messageandoffersachancetotryagain.

Repeattheloopatlines13through28untilyouestablisha

connectionoruntiltheuserpressestheCancelbutton.

Atline14,calltheconnect_dialogprocedure(you'llseethat

procedureinamoment)todisplaytheconnectiondialogand

waitforuserinput.connect_dialogreturnsaconnection

string,whichisawfullyhandybecauseyouneedaconnection

stringbeforeyoucantalktoPostgreSQL.

Afteryouhaveaconnectionstring,callthepg_connectfunction

toattemptaconnection.Whenpg_connectiscalled,iteither

establishesaconnectionoritthrowsanerror.Youwantto

interceptanyerrormessages,soyoucallpg_connectwithina

catch{}block.Ifthecalltopg_connectsucceeds,catch{}will

return0(alsoknownasTCL_OK).Ifpg_connectthrowsan

error,thecatch{}commandwillreturnavalueotherthanzero.

Ineithercase,theconnvariable(thethirdargumenttothe

catch{}command)ismodified.Inthecaseofaconnection

failure,connwillcontainthetextoftheerrormessage.Ifthe

connectionattemptissuccessful,connwillcontainaconnection

channel.Achannelissimilartoahandle(handlesareusedin

manyprogramminglanguage/APIcombinations).Achannelis

simplyauniqueidentifierreturnedbytheAPIyougivethe

identifierbacktotheAPIwhenyouwanttodosomethingwith

thatconnection(likeexecuteacommand).Likeeverythingelse

inTcl,achannelisastring.

Ifyouwerenotabletoestablishaconnection,displaya

messagetotheuserbyusingthetk_messageBoxfunction(see

line17).AtypicalerrormessageisshowninFigure16.2.



Figure16.2.TheConnectiondialog,connection



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 16. Using PostgreSQL with Tcl and Tcl/Tk

Tải bản đầy đủ ngay(0 tr)

×