You are on page 1of 4

Accessing PostgreSQL in C/C++

Aug 03, 2009 By Mike Diehl For some, databases can be pretty intimidating. remember some o! the con"oluted code #rote years ago in order to a"oid ha"ing to learn ho# to access a database !rom my programs. But it$s actually not that hard to access a database, e"en in %&%''. t seems like (ust about any application you could #ant to #rite re)uires, or could bene!it !rom being able to access, a database. %ertainly, most applications don$t need a complete *DBM+ like ,ostgre+-., but !or those that do, there$s no substitute. For those applications that don$t need a complete *DBM+, accessing an +-.ite database might be a good step up !rom managing a bunch o! !lat !iles. n this article, #ill demonstrate ho# easy it is to access a ,ostgre+-. database. n my ne/t article, $ll demonstrate access to an +-.ite database and compare the t#o. Be!ore #e can ha"e any meaning!ul con"ersation about databases, #e need to ha"e a simple table de!inition, and some data to put in it. For our purposes, this should be good enough0
create table people ( id firstname lastname phonenumber ); integer, varchar(20), varchar(20), char(10)

insert into people (id, firstname, lastname, phonenumber) values (1, 'Fred', 'Flintstone', '505555123 '); insert into people (id, firstname, lastname, phonenumber) values (2, '!ilma', 'Flintstone', '505555123 '); insert into people (id, firstname, lastname, phonenumber) values (3, '"arn#', '$ubble', '505555 321');

1his is (ust a simple table to hold some o! my ,rehistoric !riends. Miraculously, they managed to get telephone ser"ice. 2o !igure. For this program, $m using the %'' library, libp) to access the database. As a % programmer, pre!er nati"e % libraries o"er %'' libraries But as you #ill see, the libp) library is "ery approachable, e"en !or non3%'' programmers. +o, let$s take a look at some source code.
1 %include &stdio'h( 2 %include &postgres)l*libp)+fe'h( 3 %include &string( 5 int - ./conn main() , 0conn;

1 ./result 0res; 2 int rec3count; 4 int ro5; 10 int col; 11 12 13 1 conn 6 .7connectdb(8dbname6l9data host6localhost user6dataman pass5ord6supersecret8); 15 1if (.7status(conn) 66 :;<<=:>?;<3"@A) , 11 puts(8!e 5ere unable to connect to the database8); 12 eBit(0); 14 C 20 21 res 6 .7eBec(conn, 22 8update people set phonenumber6D'5055554444D' 5here id638); 23 2 res 6 .7eBec(conn, 25 8select lastname,firstname,phonenumber from people order b# id8); 221 if (.7resultEtatus(res) F6 ./$=E3>G.H=E3;I) , 22 puts(8!e did not get an# dataF8); 24 eBit(0); 30 C 31 32 rec3count 6 .7ntuples(res); 33 3 printf(8!e received Jd records'Dn8, rec3count); 35 puts(8666666666666666666666666668); 331 for (ro560; ro5&rec3count; ro5KK) , 32 for (col60; col&3; colKK) , 34 printf(8JsDt8, .7getvalue(res, ro5, col)); 0 C 1 puts(88); 2 C 3 puts(8666666666666666666666666668); 5 .7clear(res); 1 2 .7finish(conn); 4 50 return 0; 51 C

4eighing in at 56 lines, you can tell that this code isn$t going to be complicated. At the top, on line 2, #e see the obligatory inclusion o! the ,ostgre+-.$s library declarations. 7n lines 5360 #e see the beginning o! main89 and some local "ariable declarations. 4e$ll use ro# and col in order to loop o"er the ro#s and columns that result !rom our )uery. 1he rec:count #ill hold a count o! ho# many records our )uery returns; #e$ll use this "alue in our loop. 1he conn "ariable points to a connection handle that holds all o! the in!ormation that the library needs to establish, maintain and terminate a connection to our database. Finally, the res "ariable points to a results handle that contains in!ormation about the current database )uery.

4e actually connect to the database on line 6<. 1his is a !airly straight!or#ard piece o! code. 4e simply supply the name o! a database, the host it resides on, and our connection credentials. ! this !unction returns %7==>%1 7=:BAD, #e kno# #e$"e not gotten connected and it$s time to bail out. 4e check !or this condition in lines 6?369. n lines 26322, #e per!orm a simple database update. @ere #e simply pass in our connection handle, and a string&charAB that contains our +-. update statement. 7! course, our +-. statement could ha"e contained any "alid +-.. 1he ,-e/ec89 !unction returns a results handle, #hich #e don$t need !or this particular +-. statement. 1hings get more interesting starting !rom line 2<. @ere #e begin #ith an +-. select statement. 4e$re going to get the lastname, !irstname and phonenumber !ields !or e"ery record in our table. .ines 2C330 check to make sure that #e actually recei"ed some data !rom our )uery. n the real #orld, #e might do some error reco"ery here. But !or our purposes, printing an error message and e/iting is good enough. +ince #e kno# that #e did recei"e data, it #ould be nice to kno# ho# much data #e got. 4e get a record count on line 32. 4e$ll use this count on line 3< to tell the user ho# much data to e/pect. .ines 3C3<2 are #here #e actually process the results o! our )uery. n this case, #e ha"e a nested loop that loops o"er each ro# o! our result set. For each ro#, #e loop o"er each !ield. Finally, #e print each !ield !ollo#ed by a tab character. At the end o! each ro#, #e print an additional carriage return so each ro# appears on it$s o#n line. 1here are a !e# things #orth mentioning about the ,-get"alue89 !unction on line 39. First, notice that #e passed in the results handle #e recei"ed !rom ,-e/ec89 #hen #e started the )uery. Also notice that both the ro# and col parameters are 03inde/ed. 1hat is, the !irst !ield is gotten by setting col to 0, not 6. 7n lines <? and <D, #e do some housekeeping chores. First, #e tell the database that #e are !inished #ith the last results and no longer need the results handle. 1hen, since our program is almost !inished, #e disconnect !rom the database on line <D. 4e compile this program #ith a comand like0
gKK +lp) db'cpp +o db

And once the program has been compiled, #e ha"e an e/ecutable called db. =ote that #e had to link to the p) library. As you$"e probably guessed by no#, running the db program results in this output0
!e received 3 records' 66666666666666666666666666 Flintstone Fred 505555123 Flintstone !ilma 505555123 $ubble "arn# 5055554444 66666666666666666666666666

+o, as you can see, accessing a ,ostgre+-. database in %&%'' isn$t that hard. #ould suggest encapsulating all o! the database !unctionality in stand3alone !unctions and keep them all in a single source !ile. 1hen the rest o! your program can simply call your !unctions to get results and not ha"e to #orry about error corrections, etc. =e/t time, $ll discuss a similar program that uses a +-.ite database. An +-.ite database does ha"e some limitations, but doesn$t re)uire a database ser"er and is easy to manage. But, as said earlier, i! your program re)uires the scalability and per!ormance o! a *DBM+, ,ostgre+-. is a good choice and is easy to program against.

You might also like