written by alivardar | 1930 Views | Rating: (0 rates)
PostgreSQL istemci kütüphanesiPostgreSQL son derece güçlü ve kullanışlı bir veritabanı sunucusudur. 1996 yılında internet üzerinde Berkeley California üniversitesinde geliştirilmeye başlanmıştır. Rakipleri olan büyük ticari veritabanları ile performans, esneklik ve yetenek bakımında yarışabilecek güce sahiptir.Yaygın kullanılan programlama dillerinin hemen hepsi için desteği vardır.
PostgreSQL ile C dilini kullanarak haberleşmek için kullanılan kitaplığın adı libpq
kütüphanesidir. Kullandığınız sistemde libpq-dev kitaplıklarının bulunması gerekmektedir. Uygulamamız içine ekleyeceğimiz dosyalar genellikle /usr/include/postgresql dizini içinde bulunur. Bu durum dağıtıma göre veya kuruluma göre farklılık gösterebilir.
PosgreSQL sunucusunda örnek uygulamalarda kullanılmak üzere veritabanı ve tablo oluşturmak için bir takım ön ayarlamalara gerek vardır.PostgreSQL ilk kurulumda erişime izin vermemektedir. Erişim haklarının düzenlenmesi için pg_hba.conf dosyasının düzenlenmesi gerekmektedir. Bu dosya kullanılan dağıtıma göre farklılık gösterebilir. Genellikle /var/lib/postgresql, /etc/postgresql bulunabilir. pg_hba dosyası güvenlikaçısından önemli bir dosyadır. İşin kolayına kaçmak için herkese heryerden erişim hakkı verilmesi son derece sakıncalıdır.
Yerel makine üzerinden erişim açıktır. Ancak bu 127.0.0.1 kullanarak gerçekleşemez. Bunu sağlamak için aşağı örnekte yer alan ip alanına karşılık gelen yere trust değeri yazılabilir.
# "local" is for Unix domain socket connections only
local all all ident sameuser
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 md5
PostgreSQL bu ayarlamayı yapmadan da konsol altında bağlanabilirsiniz. Bu bağlantı TCP soketleri ile gerçekleşmez. Bunun için postgreskullanıcısına geçiş yapılmalıdır. Bazı sistemlerde bu kullanıcının adı psql veya pgsql de olabilir. Bunu anlamak için root kullanıcı olarak"cat /etc/passwd" komutun çıktısı içinden kullanıcı listesine bakılabilir. Sunucunun genel olarak çalıştırma betiği "/etc/init.d/postgresql start" komutudur. "ps aux" çıktısında sunucunun çalışıp çalışmadığı anlaşılabilir. Sonucun içinde aşağıdaki satırlara benzer şekilde bir çıktının olmasıgerekmektedir.
postgres 7150 0.0 0.5 41052 5656 ? Ss 11:24 0:00 postgres: alivardar postgres 127.0.0.1(49502) idle
postgres 7151 0.0 0.7 41528 7332 ? Ss 11:24 0:00 postgres: alivardar deneme 127.0.0.1(49503) idle
PostgreSQL konsol altında psql komutu ile yönetebilirsiniz. XWindows altında bu amaç için pgAdmin kullanılabilir. Web hizmetini kullanarak yönetmekamacıyla bir çok uygulama mevcuttur.
Yazılacak örnek uygulamada kullanmak amacıyla bir veritanabı oluşturalım. Öncelikle postgres kullanıcısına geçiş yapalım. Verilen bütün konsol örneklerinde bu kullanıcı kullanılacaktır.
avardar:~# su postgres
postgres@avardar:/root$ createdb deneme
CREATE DATABASE
Şu anda deneme isminde bir veritabanına sahibiz. Bu veritabanının içine urunler adında bir tablo oluşturalım. Bundan sonraki işlemler psql uygulaması içinden gerçekleştirilecektir.
postgres@avardar:/root$ psql deneme
Welcome to psql 8.2.4, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
deneme=#
Oluşturulacak olan tablonun SQL cümlesi aşağıdaki şekilde tanımlanır. Tablonun başarılı şekilde oluşturulması durumunda CREATE TABLE mesajı döner.
deneme=# CREATE TABLE urunler
deneme-# (
deneme(# id bigserial NOT NULL,
deneme(# urun_adi varchar(100) NOT NULL,
deneme(# fiyati float8 NOT NULL DEFAULT 0.00,
deneme(# CONSTRAINT urunler_id PRIMARY KEY (id)
deneme(# );
CREATE TABLE
deneme=#
SQL insert komutu ile 3 adet deneme kayıdı girişi gerçekleştirelim.
deneme=# INSERT INTO urunler (id, urun_adi, fiyati) VALUES (1, 'klavye', 12);
INSERT 0 1
deneme=# INSERT INTO urunler (id, urun_adi, fiyati) VALUES (2, 'fare', 17.25);
INSERT 0 1
deneme=# INSERT INTO urunler (id, urun_adi, fiyati) VALUES (3, 'kitap', 15.75);
INSERT 0 1
deneme=#
Şu ana kadar yapılan işlerin sonucu olarak tablonun içindeki verilere bakalım.
deneme=# select * from urunler;
id | urun_adi | fiyati
----+----------+--------
1 | klavye | 12
2 | fare | 17.25
3 | kitap | 15.75
(3 rows)
PosqtgreSQL sunucumuz şu andan itibaren sorgularımıza cevap verecek durumdadır. Yukarıdaki bilgilere C dilini kullanarak erişelim. PostgreSQL erişim için temel bir yol mevcuttur. Bu yol çeşitlendirilebilir ancak bu temel yapı değişmeyecektir. Bu bağlantı yapısı aşağıdaki akış diyagramı üzerinde görülebilir. PostgreSQL bağlantının kurulması verinin işlenmesi aşamalarında libpq kütüphanesine özel işaretçiler kullanır. Bağlantı bilgisi PGconn tipinde bir işaretçide saklanır. Sorgulama sonrası gelen bilgiler PGresult tipindeki bir işaretçide saklanır.
PostgreSQL istemcisi için izlenecek temel yolun akış diyagramı
Temel işleyiş şekline bağlı kalarak veritabanına girdiğimiz verileri konsoldan yazdıralım.
PostgreSQL istemci kütüphanesinin başlık dosyası dosyasıdır. Aşağıdaki şekilde uygulamaya eklenir.
#include
Bağlantı bilgisini saklayacak olan işaretçi;
PGconn *conn;
Gelen bilgilerin içinde bulunduğu işaretçi;
PGresult *res;
int i, j, pgsql_row_miktar, pgsql_field_miktar;
int main()
{
Bağlantıyı gerçekleştirmek için PQconnectdb fonksiyonu kullanılmaktadır.
conn = PQconnectdb("dbname=deneme user=alivardar
password=vardar host=localhost");
Dönen değer nedir? Bağlantı gerçekleştirildi mi? Eğer bir hata ile karşılaşılmış ise konsola bilgiyi göster ve uygulamayı sonlandır.
if (PQstatus(conn) == CONNECTION_BAD)
{
printf("SQL baglantisinda sorun olustu.");
return 1;
}
Eğer bir hata yoksa bu aşamaya gelinmiştir. Bu durumda bağlantıda bir hata yoktur ve sıra SQL dizisinin PostgreSQL sunucusuna gönderilmesine gelmiştir.
res = PQexec(conn, "select * from urunler");
Her SQL dizisi geriye bir veri göndermez. Örnek olarak delete veya insert SQL komutları ile bir işlem yapılması durumunda size bir değer döndürmeyecektir.Bunun kontrol edilmesi gerekir.
if (PQresultStatus(res) != PGRES_TUPLES_OK)
{
Dönen bir veri olmamasına rağmen bu aşamada SQL komutunun doğru bir şekilde çalıştığı anlaşılabilir.
if (PQresultStatus(res)!= PGRES_COMMAND_OK)
printf("Dönen veri yok.\n");
printf("Hata olustu\n");
SQL dizisi hatalıdır ancak daha öncede kurulmuş sağlıklı bir bağlantı mevcut, uygulamadan çıkmadan önce bu bağlantı kesilmelidir.
PQclear(res);
PQfinish(conn);
return 1;
}
Uygulamanın bu aşamasında bağlantı kurulmuş ve SQL dizisi de doğru bir şekilde çalışmıştır. Aşağıdaki satırda PQnfields fonksiyonu ile gelen her birsatırda kaç farklı alan olduğu bilgisini öğreniyoruz. Bu bilgiyi belirleyen durum SQL dizisi içinde programcı olarak da tanımlama yapılabilir. Örnek olarak “select id, fiyati from urunler” bize iki farklı alan döndürecektir.
pgsql_field_miktar = PQnfields(res);
Kaç satır bilgi döndüğünü PQntuples fonksiyonu ile alabiliriz.
pgsql_row_miktar = PQntuples(res);
Bu aşamada elimizde döngü bilgileri de mevcuttur. Bunlar işlenecek ve satır, sütun olarak konsola yazılacaktır.
for (i=0;i
{
for (j=0;j"- %s -",
PQgetvalue(res,i,j) );
printf("\n");
}
Gelen verilerin tutulduğu işaretçi serbest bırakılır ve bağlantı sonlandırılır.
PQclear(res);
PQfinish(conn);
Uygulama hatasız şekilde sonlandırılmıştır.
return 0;
}
Uygulamayı derlemek için sistemde geliştirme kütüphanesinin olması gerektiğinden bahsedilmişti. Bu geliştirme kütüphanesi genel olarak /usr/include/postgresql veya /usr/local/include/postgresql içinde bulunabilir. Bu kullanılan dağıtıma göre farklılık gösterebilir.Uygulamayı postgresilk.c adı ile kayıt edelim ve aşağıdaki şekilde derleme komutu verelim.
# gcc postgreilk.c -o postgreilk -I/usr/include/postgresql -lpq
Elimizde postgreilk adı ile çalışan bir dosya oluşacaktır. Uygulamanın çıktısı aşağıdaki şekilde olacaktır.
# ./postgreilk
- 1 -- klavye -- 12 -
- 2 -- fare -- 17.25 -
- 3 -- kitap -- 15.75 -
Uygulama içinde kullanılan fonksiyonların kullanımlarını inceleyelim.
PQconnectdb
Sunucuya bağlantıyı gerçekleştirir. Parametre olarak geliştiriciden bir dizi ister. Tüm bağlantı ile ilgili bilgiler bu dizi içinde tanımlıdır.
PGconn *PQconnectdb(const char *conninfo);
Örnek olarak uygulama içinde kullanılan dizi verilebilir.
conn = PQconnectdb("dbname=deneme user=alivardar password=vardar host=localhost");
Dizi içinde tanımlanabilecek olan parametreler aşağıdaki şekildedir. conn değişkenine aşağıdaki değerlerden birini alabilir.
CONNECTION_OK : Baglanti basarili sekilde saglandi.CONNECTION_BAD : Baglantida hata olustu. host Sunucunun adı bilgi tanımlanır. Eğer “/” karakteri ile başlaması durumunda bunun bir Unix Domain bağlantısı olduğu kabul edilir. hostaddr Sunucunun Ip adres bilgisi tanımlanır. Bu değer Ipv4 tipindedir. Örnek olarak 192.168.1.2 gibi bir değer verilebilir. Üzerinde çalışılan sistem eğer Ipv6 desteği mevcutsa kullanılabilir.port Eğer PostgreSQL varsayılandan farklı bir port ile tanımlanmışsa bu port değeri tanımlanmalıdır. dbname Kullanılacak olan veritabanın adı tanımlanır. user PostgreSQL kullanıcısının adı tanımlanır. password Kullanıcıya ait olan şifre tanımlaması yapılır. PQexec() Sunucuya bir SQL dizisi gönderir ve çalıştırır. Kullanıma örnek olarak; res = PQexec(conn, "select * from urunler"); PGresult *PQexec(PGconn *conn, const char *command); Sorgunun çalıştırılması sırasında hata olması durumunda res değişkeni null değerini alabilir. Sorgunun doğru bir şekildeçalışması durumunda res değişkeni ile istenen bilgiye erişilir. Sorgunun çalıştırılması sonucu dönemsi muhtemel değerler aşağıdaki şekildedir. PGRES_EMPTY_QUERY : Sorgunun içi boş olarak tanımlanmış PGRES_COMMAND_OK : Sorgu başarı ile gerçekleiştirildi. PGRES_TUPLES_OK : Sorgu başarı ile gerçekleşti ve veri geldi. PGRES_NONFATAL_ERROR : Kritik öneme sahip olmayan bir hata oluştu. PGRES_FATAL_ERROR :Önemli bir hata oluştu. PQgetvalue() char *PQgetvalue(const PGresult *res, int row_number, int column_number); Örnek uygulama içindeki kullanım aşağıdaki şekildedir. printf("- %s -", PQgetvalue(res,i,j) ); Dönen veri içinden hangi sıradaki değerin hangi alanına erişilmek istediğinin tanımlaması yapılarak, istenen veri alınır.Kişisel Kütüphaneler ile PostgreSQL'i ZenginleştirmePostgreSQL içinden C ile yazılmış olan kitaplıklara çağrı yapılabilir. Bu sayede çok yoğun işlemci gücü gerektiren hesaplamalar veya sistemle ilgili bir takım işlemleri yapan C kitaplıkları yazarak bütünleşik bir geliştirme ortamı sağlanabilir. Öncelikle C ile nasıl paylaşımlı kütüphaneler yazılacağı konusunun anlaşılması gerekmektedir. Aynı zamanda sistemde PostgreSQL sunucu geliştirme paketlerinin kurulu olması gerekmektedir. PostgreSQL içinde kullanılmak üzere kendisine verilen sayının karesini alan basit bir fonksiyon tanımlanmıştır. Bu fonksiyonu tek başınapaylaşımlı bir kütüphane olarak derlemek yeterli değildir. Bunun için PostgreSQL modülü olduğunu belli eden PG_MODULE_MAGIC tanımı yapılmalıdır. PostgreSQL başlık dosyası #include "postgres.h" PosgreSQL sunucu geliştirme kitaplıkları içinde bulunmaktadır. #include "fmgr.h" Bir PostgreSQL modülü olduğu bu alanda tanımlanır. Be değer fmgr.h başlık dosyasında saklıdır. PG_MODULE_MAGIC; Basit fonksiyon sadece kendisine gelen integer tipindeki sayıyı kendisi ile çarpar ve geri gönderir. long long int kare(int deger) { return deger*deger; } Uygulamayı derlemek için aşağıdaki satırlar kullanılır. -I parametresi ile hem sunucu hem istemci ait olan başlık dosyalarının yerlerinitanımladım. Bu sizin sisteminizde farklı bir yerde olabilir. # gcc -fpic -c pkitaplik.c -o pkitaplik.o \ -I/usr/include/postgresql -I/usr/include/postgresql/8.2/server # gcc -shared -o libpkitaplik.so pkitaplik.o Dosya başlıklarının yerlerinden emin olunuz. Dosyaların konumları kurulum paketleri içindeki dosyalar kontrol edilerek anlayabilirsiniz. Derleme sonrasında aşağıdaki şekilde bir dosya ilgili dizinde oluşacaktır. -rwxr-xr-x 1 root root 5473 2007-07-14 21:47 libpkitaplik.so Bu dosya için şimdi de PostgreSQL içinde tanımlama yapılmalıdır. Tanımlama öncesinde dosyanın tam yolu bilinmelidir ve erişim haklarınasahip olunmalıdır. Tanımlama fonksiyonu aşağıdaki şekildedir. Aşağıda verilen SQL cümlesi psql içinde çalıştırılmalıdır. create function kare(int) returns int as '/libpkitaplik.so' language 'C'; Fonksiyon içinde verilen kitaplık yolu tam dizini göstermelidir. Burada deneme amaçlı olarak kök dizinde kullanılmıştır.Bu şekilde kullanılmamalıdır. Diğer önemli bir nokta fonksiyonlar içinde tanımlanan değişkenler ile C kütüphanesinde yazan değişken tiplerinin aynı olmasıdır. # su postgres postgres@avardar:/root$ psql deneme Welcome to psql 8.2.4, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit deneme=# create function kare(int) returns int as '/libpkitaplik.so' language 'C';
CONNECTION_OK : Baglanti basarili sekilde saglandi.CONNECTION_BAD : Baglantida hata olustu. host Sunucunun adı bilgi tanımlanır. Eğer “/” karakteri ile başlaması durumunda bunun bir Unix Domain bağlantısı olduğu kabul edilir. hostaddr Sunucunun Ip adres bilgisi tanımlanır. Bu değer Ipv4 tipindedir. Örnek olarak 192.168.1.2 gibi bir değer verilebilir. Üzerinde çalışılan sistem eğer Ipv6 desteği mevcutsa kullanılabilir.port Eğer PostgreSQL varsayılandan farklı bir port ile tanımlanmışsa bu port değeri tanımlanmalıdır. dbname Kullanılacak olan veritabanın adı tanımlanır. user PostgreSQL kullanıcısının adı tanımlanır. password Kullanıcıya ait olan şifre tanımlaması yapılır. PQexec() Sunucuya bir SQL dizisi gönderir ve çalıştırır. Kullanıma örnek olarak; res = PQexec(conn, "select * from urunler"); PGresult *PQexec(PGconn *conn, const char *command); Sorgunun çalıştırılması sırasında hata olması durumunda res değişkeni null değerini alabilir. Sorgunun doğru bir şekildeçalışması durumunda res değişkeni ile istenen bilgiye erişilir. Sorgunun çalıştırılması sonucu dönemsi muhtemel değerler aşağıdaki şekildedir. PGRES_EMPTY_QUERY : Sorgunun içi boş olarak tanımlanmış PGRES_COMMAND_OK : Sorgu başarı ile gerçekleiştirildi. PGRES_TUPLES_OK : Sorgu başarı ile gerçekleşti ve veri geldi. PGRES_NONFATAL_ERROR : Kritik öneme sahip olmayan bir hata oluştu. PGRES_FATAL_ERROR :Önemli bir hata oluştu. PQgetvalue() char *PQgetvalue(const PGresult *res, int row_number, int column_number); Örnek uygulama içindeki kullanım aşağıdaki şekildedir. printf("- %s -", PQgetvalue(res,i,j) ); Dönen veri içinden hangi sıradaki değerin hangi alanına erişilmek istediğinin tanımlaması yapılarak, istenen veri alınır.Kişisel Kütüphaneler ile PostgreSQL'i ZenginleştirmePostgreSQL içinden C ile yazılmış olan kitaplıklara çağrı yapılabilir. Bu sayede çok yoğun işlemci gücü gerektiren hesaplamalar veya sistemle ilgili bir takım işlemleri yapan C kitaplıkları yazarak bütünleşik bir geliştirme ortamı sağlanabilir. Öncelikle C ile nasıl paylaşımlı kütüphaneler yazılacağı konusunun anlaşılması gerekmektedir. Aynı zamanda sistemde PostgreSQL sunucu geliştirme paketlerinin kurulu olması gerekmektedir. PostgreSQL içinde kullanılmak üzere kendisine verilen sayının karesini alan basit bir fonksiyon tanımlanmıştır. Bu fonksiyonu tek başınapaylaşımlı bir kütüphane olarak derlemek yeterli değildir. Bunun için PostgreSQL modülü olduğunu belli eden PG_MODULE_MAGIC tanımı yapılmalıdır. PostgreSQL başlık dosyası #include "postgres.h" PosgreSQL sunucu geliştirme kitaplıkları içinde bulunmaktadır. #include "fmgr.h" Bir PostgreSQL modülü olduğu bu alanda tanımlanır. Be değer fmgr.h başlık dosyasında saklıdır. PG_MODULE_MAGIC; Basit fonksiyon sadece kendisine gelen integer tipindeki sayıyı kendisi ile çarpar ve geri gönderir. long long int kare(int deger) { return deger*deger; } Uygulamayı derlemek için aşağıdaki satırlar kullanılır. -I parametresi ile hem sunucu hem istemci ait olan başlık dosyalarının yerlerinitanımladım. Bu sizin sisteminizde farklı bir yerde olabilir. # gcc -fpic -c pkitaplik.c -o pkitaplik.o \ -I/usr/include/postgresql -I/usr/include/postgresql/8.2/server # gcc -shared -o libpkitaplik.so pkitaplik.o Dosya başlıklarının yerlerinden emin olunuz. Dosyaların konumları kurulum paketleri içindeki dosyalar kontrol edilerek anlayabilirsiniz. Derleme sonrasında aşağıdaki şekilde bir dosya ilgili dizinde oluşacaktır. -rwxr-xr-x 1 root root 5473 2007-07-14 21:47 libpkitaplik.so Bu dosya için şimdi de PostgreSQL içinde tanımlama yapılmalıdır. Tanımlama öncesinde dosyanın tam yolu bilinmelidir ve erişim haklarınasahip olunmalıdır. Tanımlama fonksiyonu aşağıdaki şekildedir. Aşağıda verilen SQL cümlesi psql içinde çalıştırılmalıdır. create function kare(int) returns int as '/libpkitaplik.so' language 'C'; Fonksiyon içinde verilen kitaplık yolu tam dizini göstermelidir. Burada deneme amaçlı olarak kök dizinde kullanılmıştır.Bu şekilde kullanılmamalıdır. Diğer önemli bir nokta fonksiyonlar içinde tanımlanan değişkenler ile C kütüphanesinde yazan değişken tiplerinin aynı olmasıdır. # su postgres postgres@avardar:/root$ psql deneme Welcome to psql 8.2.4, the PostgreSQL interactive terminal. Type: \copyright for distribution terms \h for help with SQL commands \? for help with psql commands \g or terminate with semicolon to execute query \q to quit deneme=# create function kare(int) returns int as '/libpkitaplik.so' language 'C';

Downloads




