Tải bản đầy đủ - 0 (trang)
Chapter 11. Embedding SQL Commands in C Programs - ecpg

Chapter 11. Embedding SQL Commands in C Programs - ecpg

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

Prerequisites

BecauseanecpgapplicationiswritteninC,youwillneedaC

compiler,theGNUmakeutility,andtheecpgpreprocessorand

libraryonyoursystembeforeyoucantrytheexamplesinthis

chapter.

Themakefileforthischapterfollows:

1#

2#Filename:makefile

3#

4INCLUDES=-I/usr/include/pgsql

5

6CFLAGS+=$(INCLUDES)-g

7LDFLAGS+=-g

8LDLIBS+=-lecpg-lpq

9ECPGFLAGS+=-c$(INCLUDES)

10ECPG=/usr/bin/ecpg

11

12.SUFFIXES:.pgc

13.pgc.c:



14$(ECPG)$(ECPGFLAGS)$?

15

16ALL=client1aclient1bclient2aclient2bclient2c



17ALL+=client3aclient3bclient3cclient3dclient3eclient3f

18ALL+=client4.pgc

19

20all:$(ALL)

21

22clean:

23rm-f$(ALL)*~

TheexamplesinthischapterfollowthenormalPostgreSQL

conventionofnamingecpgsourcefileswiththeextension.pgc.

Themakefilerulesonlines11through13tellmakethatitcan

converta.pgcfileintoa.cfilebyrunningtheecpg

preprocessor.

Fortheexamplesinthischapter,Ihaveusedaversionofthe

ecpgpackagethathasnotbeenreleasedinanofficial

distributionatthetimeofwriting.Youneedtouseaversionof

PostgreSQLlaterthanversion7.2.1tocompilesomeofthe

sampleapplications.(Version7.2.1didnotincludethe-cflag

thatIwilldiscusslater,butreleasesafter7.2.1shouldinclude

thatfeature.)Thisfeatureisnotrequiredformostecpg

applications.

Assumingthatyouhavetheprerequisitesinplace,let'sstart



outbydevelopingasimpleclientthatwillconnecttoadatabase

usingecpg.



Client1ConnectingtotheServer

Ifyouhavereadthepreviousthreechapters,youknowthat

therearetwoschemesformanagingPostgreSQLconnections.

InlibpqandODBC,youasktheAPItocreateaconnection

object(ahandle)andthenyourapplicationkeepstrackofthe

connection.Whenyouneedtointeractwiththedatabase,you

callanAPIfunctionandpasstheconnectionobjecttotheAPI.

Whenyouarefinishedinteractingwiththedatabase,youask

theAPItoteardowntheconnectionanddestroytheconnection

object.Whenyouuselibpgeasy,theAPIkeepstrackofthe

connectionobjectforyou.YoustillhavetoasktheAPItocreate

aconnectionand,whenyouarefinished,youmustasktheAPI

toteardowntheconnection,butlibpgeasystoresthe

connectionobjectitselfandyouneverneedtoworryaboutit.

Theecpginterfacegivesyouamixtureofthesetwoschemes.

Mostecpgapplicationsuseasingledatabaseconnection.Ifyou

onlyneedoneconnection,ecpgwillkeeptrackofitforyou.If

yourapplicationneedstoworkwithmultipleconnections,you

canswitchbetweenthem.

InthelibpqandODBCAPIs,adatabaseconnectionis

representedbyahandleofsometype.Inanecpgapplication,a

databaseconnectionissimplyaname[1].

[1]Laterinthischapter,I'llshowyouhowtouseCvariables(calledhostvariablesinecpg)



EXECSQL



within

statements.Ifyouuseahostvariabletospecifyaconnectionname,the

variableshouldbeapointertoanull-terminatedstring.



Let'sstartbybuildingasimpleclientapplicationthatconnects

toadatabaseandthendisconnects:

/*client1a.pgc*/



intmain()

{

EXECSQLCONNECTTOmoviesASmyconnection;



EXECSQLDISCONNECTmyconnection;



return(0);

}

Inclient1a,youcreateadatabaseconnectionnamed

myconnection.Assumingthattheconnectionattemptis

successful,myconnectioncanbeusedtoaccessthemovies

database.YouwillnoticethatyoudidnothavetodeclareanyC

variablestokeeptrackoftheconnection;theecpgAPIdoes

thatforyouallyouhavetodoisrememberthenameofthe

connection.JustlikenormalCstatements,EXECSQL

statementsareterminatedwithasemicolon.

Ifyourapplicationdoesn'tneedmorethanonedatabase

connection,youcanomittheASdatabaseclausewhenyou

createtheconnection.Youcanalsoomitthenameinthe

DISCONNECTstatement:

/*client1b.pgc*/



intmain()

{

EXECSQLCONNECTTOmovies;



EXECSQLDISCONNECT;



return(0);

}



client1a.pgcandclient2a.pgcarefunctionallyequivalent

applications.

YoucanassociateaSQLstatementwithanamedconnection

usinganextendedformoftheEXECSQLprefix:

EXECSQLATconnection_namesql_statement;

Ifyoudon'tspecifyanATconnection_nameclause,ecpgwill

executestatementsusingthecurrentconnection.Whenyou

createanewconnection,thatconnectionbecomesthecurrent

one.YoucanchangethecurrentconnectionusingtheSET

CONNECTIONTOcommand:

SETCONNECTIONTOconnection_name;



Whenyoucloseaconnection,youcanspecifyanyofthe

statementsshowninTable11.1.

Table11.1.VariousApproachestoDISCONNECT

Statement



Explanation



EXECSQLDISCONNECTconnection-name;



Closesthenamedconnection



EXECSQLDISCONNECT;



Closesthecurrentconnection



EXECSQLDISCONNECTCURRENT;



Closesthecurrentconnection



EXECSQLDISCONNECTALL;



Closesallconnections



TheecpgPreprocessor

TheCcompilerobviouslywon'tunderstandtheEXECSQL

statementsthatyoumustincludeinanecpgapplication.Tofix

thisproblem,youhavetorunthesourcecodeforyour

applicationsthroughapreprocessornamedecpg.

Youcanviewthesyntaxexpectedbytheecpgpreprocessor

usingthe--helpoption:

$ecpg--help

ecpg-thepostgresqlpreprocessor,version:2.8.0

Usage:ecpg:[-v][-t]

[-Iincludepath]

[-ooutputfilename]



[-Ddefinename]

file1[file2]...

Let'stakeaquickpeekunderthehoodtoseewhattheecpg

preprocessorisdoingwithoursourcecode.I'llrunthe

client1b.pgcprogramthroughecpg:

$ecpgclient1b.pgc

$catclient1b.c

/*Processedbyecpg(2.8.0)*/

/*Thesethreeincludefilesareaddedbythepreprocessor*/

#include

#include

#include

#line1"client1b.pgc"



/*client1b.pgc*/



intmain()

{



{ECPGconnect(__LINE__,"movies",NULL,NULL,NULL,0);}

#line5"client1b.pgc"



{ECPGdisconnect(__LINE__,"CURRENT");}

#line7"client1b.pgc"



return(0);

}

Theecpgpreprocessorconvertsclient1b.pgcinto

client1b.c.Youcanseethatecpghasinsertedquiteabitof

codeintoourapplication.

First,ecpghasinsertedsomecommentsandafew#include

statements.Youcanusuallyignorethe#includefilesthey

declarethefunctionsanddatatypesthatarerequiredbythe

ecpglibrary.

Followingthe#includes,ecpghasinsertedaCpreprocessor

directivethatyoumightnothaveseenbefore.The#line

directivetellstheCcompilertopretendthatitiscompilingthe

givenline(andsourcefile)ecpginsertsthesedirectivessothat

anyerrormessagesproducedbytheCcompilercorrespondto

thecorrectlinenumbersinyouroriginalsourcefile.For

example,considerwhatwouldhappenifyouhadasyntaxerror



inyourdeclarationofthemain()function.Inyouroriginal

sourcefile(client1b.pgc),main()isdeclaredatline4.Inthe

post-processedfile,main()isdeclaredatline10.Withoutthe

#linedirectives,theCcompilerwouldtellyouthatanerror

occurredatline10ofclient1b.c.Withthe#linedirectives,

theCcompilerwillreporttheerroratline4ofclient1b.pgc.



DebuggingecpgApplications

Unfortunately,the#linedirectivesinsertedbytheecpgpreprocessorcanreally

confusemostsource-leveldebuggers.Ifyoufindthatyouneedtodebuganecpg

application,youshouldruntheecpgpreprocessoroveryoursourcecode,strip

the#linedirectivesfromtheresulting.cfile,andthencompilethe.cfileinto

anexecutable.Atthatpoint,youwillhaveaprograminwhichthedebug

symbolscorrespondtothe.cfileandyourdebuggershouldbehaveproperly.



Theinterestingpartofclient1b.cstartswherethe

preprocessortranslated

EXECSQLCONNECTTOmovies;

into

{ECPGconnect(__LINE__,"movies",NULL,NULL,NULL,0);}

YoucanseethatecpgparsedouttheEXECSQLCONNECT

commandintoasimplefunctioncall.Thisisreallywhatecpgis

allabouttranslatingEXECSQLstatementsintofunctioncalls.

Theresultingcodecallsfunctionsdefinedintheecpglibrary.



ConnectionStrings

Whenyoucreateaclientapplicationusinglibpqorlibpgeasy,

youspecifyaconnectionstringasaseriesofkeyword=value

properties.Connectingtoadatabaseusingecpgisabit

different.Whenyouconnecttoadatabaseusingecpg,youcan

useanyofthreeforms.Thefirstformisconsideredobsolete

butisstillacceptedbythemostrecentreleasesofPostgreSQL:



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

Chapter 11. Embedding SQL Commands in C Programs - ecpg

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

×