Welcome, Guest. Please login or register.
Did you miss your activation email?
07 September, 2010, 07:59:13 pm
Home | Help | Search | Login | Register

Lazarus and FreePascal

Nov 13 2009 PostgreSQL ve C
written by alivardar | 1930 Views | Rating: (0 rates)
Dökümanlar
PostgreSQL istemci kütüphanesi
PostgreSQL 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üvenlik
açı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 postgres
kullanı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önetmek
amacı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 bir
satı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ştirme
PostgreSQL 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şına
paylaşı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 yerlerini
tanı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ına
sahip 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';
Digg this story! Del.icio.us Share on Facebook! Technorati Reddit StumbleUpon

Forum / Destek

Hakkımızda

GPL Applications

Stats

Members
  • Total Members: 683
  • Latest: sriman
Stats
  • Total Posts: 114
  • Total Topics: 39
  • Online Today: 9
  • Online Ever: 31
  • (15 March, 2010, 09:08:04 pm)
Users Online
Users: 0
Guests: 7
Total: 7
 
TinyPortal v1.0 beta 4 © Bloc


Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!