Tải bản đầy đủ - 0 (trang)
Chapter 8.  The PostgreSQL C APIlibpq

Chapter 8.  The PostgreSQL C APIlibpq

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

PostgreSQLserver.Inlaterchapters,Iwillcoverlibpgeasyand

ODBC,aswellasafewAPIsdesignedforlanguagesotherthan

C.

ThelibpqAPIisusedtoimplementmostoftheotherclient

APIs.AfteryouunderstandhowtointeractwithaPostgreSQL

serverusinglibpq,youwillfindthatmostoftheotherAPIs

simplywrapupthelibpqAPIindifferentflavors.Forexample,

thelibpgeasyAPIcombinessomeofthemorecommonlibpq

operationsintoasetofhigher-levelfunctions.Thelibpgeasy

functionsareeasiertouse,butyoudon'thavequiteasmuch

powerandflexibilityasyouwouldwithalibpqapplication.



Prerequisites

Whenyouwriteaclientapplicationusinglibpq,you'llneedaC

compiler.I'llassumethatyouhavetheGNUCcompiler(gcc)

installedandreadytouse.I'llalsoassumethatyouhaveGNU

makeavailable,andI'llusethattooltoactuallyinvokethe

compiler(andlinker).

APIsthatareusedwithinaCapplicationareusuallymadeupof

twocomponents:asetofheaderfilesandanobjectcode

library.

Theheaderfilescontaindatatypedefinitionsandfunction

prototypes(inotherwords,theheaderfilesdescribetheAPIto

yourCcompiler).Theobjectcodelibrarycontainstheactual

implementationforeachfunctioncontainedintheAPI.When

youuselibpq,youwillneedtoincludethelibpq-fe.hheaderfile

withinyourCcode(usingthe#includedirective).Youwillalso

needtolinkyourprogramagainstthelibpqobjectlibrary.



Client1ConnectingtotheServer

Ourfirstclientisverysimpleitconnectstoaserver,

disconnects,andthenexits.

Therearetwosetsoffunctionsthatyoucanusetoconnecttoa

PostgreSQLserver:thesimpleformusesthePQconnectdb()

function,whereasthemorecomplexformusesPQconnectStart()

andPQconnectPoll().PQconnectdb()iseasiertousebecauseitisa

synchronousfunction;whenyoucallPQconnectdb(),yourprogram

willnotcontinueuntiltheconnectionattemptsucceedsorfails.

ThePQconnectStart()andPQconnectPoll()functionsgiveyour

applicationawaytoconnecttoaserverasynchronously.Acall

toPQconnectStart()returnsimmediatelyitwon'twaitforthe

connectionattempttocomplete.ThePQconnectPoll()functioncan

beusedtomonitortheprogressofaconnectionattemptstarted

byPQconnectStart().Iusethesynchronousforminthischapter:

/*

**File:client1.c

*/

#include"libpq-fe.h"

intmain(void)

{

PGconn*connection;

connection=PQconnectdb("");

PQfinish(connection);

return(0);

}



client1.cstartsbyincludingasingleheaderfile:libpq-fe.h.The

libpq-fe.hfiledefinesthedatatypesthatweneedto



communicatewithlibpq.libpq-fe.halsocontainsfunction

prototypesforthelibpqAPIfunctions.

ConnectingtoaPostgreSQLdatabasefromlibpqcanbevery

simple.ThePQconnectdb()functionreturnsahandletoa

connectionobject.PQconnectdb()issynchronousitwillnotreturn

tothecalleruntiltheconnectionattemptsucceedsorfails.Here

istheprototypeforPQconnectdb():

externPGconn*PQconnectdb(constchar*conninfo);



PQconnectdb()takesasingleargumentapointertoanull-



terminatedconnectionstring.Aconnectionstringisalistof

zeroormoreconnectionattributes.Forexample,theconnection

string"dbname=accountinguser=korry"specifiesthatwewantto

connecttoadatabasenamed"accounting"asuser"korry".Each

optionisoftheformkeyword=value.Multipleattributesare

separatedbywhitespace.

NoticethatIspecifiedanemptyconnectionstringinthis

example.WhenPQconnectdb()findsanemptyconnectionstring,it

connectstothedefaultdatabaseusingadefaultsetof

attributes.AnemptystringisnotthesameasaNULLpointer.

Don'tpassaNULLpointertoPQconnectdb()unlessyouwanttosee

libpq(andyourapplication)dieafierydeath.

I'lldescribeconnectionattributesandtheirdefaultvaluesin

moredetailabitlater.WhenyoucallPQconnectdb(),yougetback

apointertoaPGconn.PGconnisconsideredahandle.Ahandleis

anopaquedatatype,meaningthatthereissomethingbehinda

PGconnpointer,butyoucan'tseeit.Theinformationbehinda



handleisfor"internaluseonly."Thelibpqlibraryhasaccessto

theimplementationdetails,butAPIusersdonot.APGconnobject

representsadatabaseconnectionwithinyourapplication.You

willusethisobjectwhenyoucallotherlibpqfunctions.



CompilingtheClient

Nowlet'scompileclient1.candtrytorunit.Youwillusea

simplemakefiletodrivetheCcompilerandlinker.Hereisthe

makefileyouwillusethroughoutthischapterasyouaddnew

clients,youwilljustaddnewtargetstothemakefile:

##File:Makefile

##

##Rulestocreatelibpqsampleapplications

CPPFLAGS+=-I/usr/local/pgsql/include

CFLAGS+=-g

LDFLAGS+=-g

LDLIBS+=-L/usr/local/pgsql/lib-lpq

client1:client1.o



IfyouhaveinstalledPostgreSQLintoadirectoryotherthan

/usr/local/pgsql,youshouldsubstituteyourdirectorynamesin

themakefile.

Tobuildclient1withthismakefile,youcanusethefollowing

command:

$makeclient1

cc-g-I/usr/local/pgsql/include-c-oclient1.oclient1.c

cc-gclient1.o-L/usr/local/pgsql/lib-lpq-oclient1

$



Theclient1applicationdoesn'texpectanycommand-line

parameterssoyoucanrunitlikethis:

$./client1



UsingGNUmaketoBuildlibpqApplications

Themakeutilityisusedtoperformtheoperationsrequiredtoturnasourcefile

(suchasclient1.c)intoanapplication.makedoestwo(extremelyuseful)things

foryou.First,makedeterminestheminimumsetofoperationsrequiredtobuild

anapplication.Second,makeinvokesthevariouspreprocessors,compilers,and

linkerstoactuallycarryoutminimumrequiredoperations.

Themakeutilitylearnshowtobuildanapplicationbyconsultingtwosourcesof

information.makehasahugecollectionofbuilt-inrulesthatdescribehowto

convertonetypeoffileintoanothertypeoffile.Forexample,makeknowshow

converta".c"fileintoanexecutable.First,makeconvertsasourcefileintoa".o"

(object)modulebyaskingtheCcompilertocompilethesourcefile.Then,make

convertsthe".o"intoanexecutablebyinvokingthelinker.

Thesecondinformationsourcethatmakeusesisknownasamakefile(probably

becausethefileisusuallynamed"makefile"cleverhuh?).Amakefileisasetof

rulesthatdefinehowtobuildyourspecificapplication(orapplications).makefiles

areusuallywrittenintermsoftargetsandprerequisites.Atargetissomething

thatyouwanttobuild.Aprerequisiteisafilethatthetargetdependson.Inthis

case,youwanttobuildanapplicationnamedclient1that'syourtarget.The

prerequisiteforyourtargetisclient1.c.Themakefilerulethatdescribesthis

relationshipis"client1:client1.c".Thislineisreadas"client1dependson

client1.c".Whenmakeseesthisrule,itlooksthroughitsdatabaseofbuilt-inrules

tofindawaytoconvertclient1.cintoclient1.Itfindstherule(oractually,rules)

toperformthisconversion,invokestheCcompilertoproduceclient1.ofrom

client1.c,andtheninvokesthelinkertoconvertclient1.ointotheclient1

executable.

Themakefilethatyouwillusefortheexamplesinthischapterisalittlemore

complexthanthesinglerulethatIjustdescribed.

Thebuilt-inrulethatproducesanobjectmodule(.o)fromaCsourcefile(.c)

lookslikethis:

$(CC)-c$(CPPFLAGS)$(CFLAGS)



ThiscommandinvokestheCcompiler,passingitthecommand-lineflags-c,

$(CPPFLAGS),and$(CFLAGS).$(CPPFLAGS)and$(CFLAGS)arevariablesthatyoucan

modifywithinthemakefile.Tobuildalibpqapplication,youhavetotelltheC

compilerhowtofindthePostgreSQLheaderfiles.Youcandothatbymodifying

the$(CPPFLAGS)variable:

CPPFLAGS+=-I/usr/local/pg800/include



Tofindthecorrectdirectoryname,executethecommand



$pg_config--includedir



IfyouwanttheCcompilertoproducedebuggablecode,youcanmodifythe

$(CFLAGS)variabletoincludethe-gflag:

CFLAGS+=-g



NowwhenmakeinvokestheCcompilertocompileclient1.c,thecommandwill

looklikethis:

cc-c-I/usr/local/pg800/include-g-oclient1.oclient1.c



Ifthecompilerdoesnotfindanyseriouserrorsinclient1.c,youwillendupwith

anobjectmodulenamedclient1.o.Yourtargetisnotclient1.o,butclient1:

client1.oisjustanintermediatetarget.Tobuildclient1fromclient1.o,makewill

invokethelinkerusingthefollowingbuilt-inrule:

$(CC)$(LDFLAGS)prerequisite.o$(LOADLIBES)$(LDLIBS)



Youwanttolinkclient1.owiththelibpqlibrarytoproduceclient1.Thelibpq

libraryisfoundin/usr/local/pg800/libonmysystem,soI'lltellmaketoinclude

libpqbymodifying$(LDLIBS).Iwantdebuggingsymbolsinmyexecutable,soI

alsowilladdthe-gflagto$(LDFLAGS):

LDLIBS+=-L/usr/local/pg800/lib-lpq

LDFLAGS+=-g



Again,youcanusethepg_configcommandtofindthedirectorythatcontainsthe

libpqlibrary:

$pg_config--libdir



Thefinalcommandproducedbymakeis

cc-gclient1.o-L/usr/local/pg800/lib-lpq-oclient1



Thecompletemakefilelookslikethis:

CPPFLAGS+=-I$(shellpg_config--includedir)

CFLAGS+=-g



LDFLAGS+=-g

LDLIBS+=-L$(shellpg_config--libdir)-lpq

client1:client1.o



IdentifyingtheServer

IfyouprovideanemptyconnectionstringtoPQconnectdb(),how

doesitfindadatabaseserver?libpqusesahierarchyofdefault

valuestodecidewhichservertotrytoconnectto.

Thelibpqlibraryusesthreedifferentsourceswhentryingtofind

eachconnectionattribute.

First,theconnectionstring(giventoPQconnectedb())cancontain

asetofkeyword=valuepairs.

Next,libpqlooksforasetofspecificallynamedenvironment

variables.Eachenvironmentvariablecorrespondstooneofthe

keyword=valuepairsthatyoucanuseintheconnectionstring.

Finally,libpqusesasetofvaluesthatarehard-wiredintothe

libraryatbuild-time.

Table8.2showshowthekeywordsandenvironmentvariables

correspondtoeachother.

Table8.2.ConnectionAttributes

Connect-String

Keyword



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



service



PGSERVICE



service=accounting



port



PGPORT



port=5432



YoucanusethePQconndefaults()functiontofindthedefaultvalue

foreachconnectionattribute.



1/*

2**File:get_dflts.c

3*/

4

5#include

6#include

7

8intmain(void)

9{

10PQconninfoOption*d;

11PQconninfoOption*start;

12/*

13**Getthedefaultconnectionattributes

14*/

15start=d=PQconndefaults();

16

17while(d->keyword!=NULL)

18{

19printf("keyword=%s\n",d->keyword?d->keyword:"

20printf("envvar=%s\n",d->envvar?d->envvar:"



21printf("label=%s\n",d->label?d->label:"

22printf("compiled=%s\n",d->compiled?d->compiled:"

23printf("val=%s\n",d->val?d->val:"

24printf("\n");

25

26d++;

27}

28

29/*

30**Freeupthememorythatlipqallocatedonourbehalf

31*/

32

33PQconninfoFree(start);

34

35return(0);



WhenyoucallthePQconndefaults()function,yougetbacka

pointertothefirstmemberofanarrayofPQconninfoOption

structures.Eachstructurecontains(amongotherthings)a

keyword,thenameofanenvironmentvariable,ahard-wired

(orcompiled-in)value,andacurrentvalue.Ifyouiterate

throughthemembersofthisarray,youcanrecognizetheend

ofthelistbylookingforamemberwherethekeywordpointeris

NULL.

Youcancompilethisprogrambyaddinganotherentrytothe

makefileandthentypingmakeget_dflts:

$catmakefile

##

##File:Makefile

##

##Rulesforbuildinglibpqsampleapplications

##



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

Chapter 8.  The PostgreSQL C APIlibpq

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

×