IBX (InterBase eXpess)

IBX (InterBase eXpress)

Bu yazımızda Interbase ve FireBird veritabanlarına direk erişim için kulanılan IBX setine bir giriş yapacağız. Bildiğiniz gibi Interbase veritabanını Borland üretiyor ve çok iyi bir Delphi desteği olması için Delphi'ye IBX seti eklendi.

Borland, bir süre önce artık InterBase veritabanını üretmeyeceğini duyurdu ve kodlarını açtı. Bu açık kodlarla Interbase 6 sürümü yayınlandı. Bu sürüm çok tutuldu. Bunun üzerine Borland kararından vazgeçti ve Interbase'i tekrar geliştirmeye ve satmaya başladı. Bunun üzerine açık koddan geliştirme yapan ekip (ki bunların çoğu eski Interbase ekibinden) kendi veritabanlarının ismini FireBird yaptılar ve geliştirmeye devam ettiler. Şu an FireBird, özellikle Delphi kullanan geliştiriciler arasında çok yaygın olarak kullanılıyor. Bedava, çok iyi bir Delphi desteği var, ufak ve orta çaplı projeler için çok uygun, kararlı bir veritabanı. Gözlemlediğim kadarıyla FireBird, Interbase 7'den daha çok tutuluyor ve kullanılıyor.

Delphi 7 ile gelen IBX seti, Interbase sekmesinde 13 veri erişim bileşeni ve Interbase Admin kısmında 11 yönetim bileşeni içerir. Interbase kısmında, verilere erişim için birçok bileşen var. Bunların kısa bir açıklamasından sonra adım adım bir InterBase/FireBird uygulaması geliştireceğiz. Gerisi size kalıyor :)

Veri Erişim (Data Access) Bileşenleri

- IBDatabase : Bu BDE uygulamalarındaki Database bileşenine benzer. Interbase veritabanına erişim sağlar. IBDatabase bileşeni transaction desteği sağlamaz. Tüm IBX dataset bileşenlerinde IBDatabase bileşeni belirtilmelidir.
- IBTransaction : Transaction desteği sağlar. Tüm IBX dataset bileşenlerinde transaction bileşeni bağlamak gerekmektedir. Transaction olayının böyle ayrı bir bileşene bağlanmış olması, aynı anda birden fazla transaction'ın aktif olmasına olanak sağlamaktadır.
- IBTable : Bir table ve view'ın tüm alanlarına ve tüm kayıtlarına ulaşmak için kullanılır. Mevcut kayıtlar filtre edilebilir.
- IBQuery : Bir veya birden tabledan, view'dan veya stored procedure'den yazılan SQL cümlesine uygun kayıtları döndürür. Dönen veri kümesi read only (salt okunur) dir.
- IBStoredProc : Bir sonuç döndürmeyen stored procedure'leri çalıştırmak için kullanılır.
- IBUpdateSQL : IBTable ve IBQuery ile cachedupdate çalışmak isterseniz, bu bileşeni kullanmanız gerekir.
- IBDataset : Genelde IBX'te en sık kullanılan veri erişim bileşenidir. Select, Insert, Update ve Delete işlemleri için SQL ifadeleri girmenize olanak tanır.
- IBSQL : Bir sonuç döndürmeyen SQL cümlelerini çalıştırmak için idealdir.
- IBDatabaseInfo : Tam olarak bir veri erişim bileşeni değildir. Bağlı olduğunuz Interbase veritabanı hakkında bazı bilgileri almanızı sağlar. ODS sürümü, page size, kaç kullanıcı bağlı vb.
- IBSQLMonitor : Uygulamanızdan Interbase veritabanına gönderilen SQL cümlelerini kaydetmek ve göstermek için kullanılır. Bir şeyler ters gittiğinde teşhis için kulanılabilir.
- IBEvents : Interbase'de trigger ve stored procedure'lerde event (mesaj) yayınlama olanağı vardır. Bu mesaj o veritabanına bağlı tüm client'lara gönderilir. IBEvents ile bu mesajları yakalayıp, işeyebilirsiniz.

Bir IBX Uygulaması Geliştirelim

Temel işlemlerde, diğer veritabanı uygulamaları geliştirmeden bir farkı yoktur. Sırasıyla

  • Yeni bir uygulama oluşturun.
  • Projeye bir datamodule ekleyin
  • Datamodule'e IBDatabase ve IBTransation bileşenlerini koyun.

IBDatabase'in Ayarları

Aşağıdaki iki ayarı mutlaka yapmalısınız :

1. DatabaseName : Bağlanacağımız veritabanı dosyasının yolu (path) ve ismi. Veritabanı dosyası kendi diskimizde olabileceği gibi ağ üzerinde bir bilgisayarda da olabilir.

2. DefaultTransaction : Koyduğumuz IBTransaction bileşenini atayın.

Bunun dışındaki diğer ayarlar seçimliktir. Bunlar :

- IdleTimer : IBDatabase belli bir süre işlem yapmazsa otomatik kapatmak için. Bu değer 0 olursa otomatik olarak kapatılmaz.
- LoginPrompt : Bu seçenek aktif ise kullanıcıdan programın çalışması esnasında geçerli bir veritabanı kullanıcısı ve şifresi girmesi istenir. Kafadan False ayarlayın :)
- Params : Veritabanına bağlantı için gerekli kullanıcı ismi, şifre ve charset gibi parametreleri girmenizi sağlar. bunları kolay bir şekilde nasıl girebileceğiniz aşağıda anlatacağım.
- SQLDialect : Interbase 6 için 3, Interbase 5 ve öncesi için 1 girin.
- TraceFlags : IBSQLMonitor tarafından hangi işlemlerin kaydedileceği seçilir.

IBDatabase'de ayarları yapmanın en kolay yolu Database Component Editor'ü kullanmaktır. IBDatabase'e sağ tıklayıp, Database Editor komutunu verin. Karşınıza aşağıdaki pencere gelecektir.

Burada;

- Dosyanın kendi bilgisayarınızda mı (local), yoksa başka bir bilgisayarda mı (Remote) olduğunu seçebilirsiniz.
- Browse butonu ile veritabanı dosyasını seçebilirsiniz.
- Veritabanı parametrelerini ayarlayabilirsiniz :
    - Username (kullanıcı ismi) : Varsayılan kullanıcı ismi SYSDBA'dır.
    - Password (şifre) : Varsayılan şifre masterkey'dir.
    - Character Set olarak Win1254 seçin, bu Türkçenin kodudur.
- LoginPrompt seçeneğinin işaretini kaldırın.
- Test butonu ile veritabanına bağlantıyı deneyebilirsiniz. Eğer ayarlar doğru ise "Successful connection" mesajı çıkmalı.
- OK butonu basarak ayarları tamamlayın.

IBTransaction'ın Ayarları

DefaultDatabase : Koyduğumuz IBDatabase'i seçin.

IdleTimer : İşlem yaparken belli bir süre uygulamada hiç bir işlem yapılmazsa, transaction'ı otomatik olarak Commit veya Rollback yapabilirsiniz. Böyle birşey yapmak istiyorsanız, buraya bu süreyi girmelisiniz. DefaultAction özelliği ile de bu süre sonunda hangi işlemin gerçekleşmesini istediğinizi seçebilirsiniz.

Params : Burda Transaction parametrelerini girebilirsiniz. Ancak biz yine editor ile yapacağız bu işlemi. IBTransaction bileşenine sağ tıklatıp, Transaction Editor komutunu verin. Karşınıza aşağıdaki pencere gelir.

Burada transaction'un isolation level'ı seçilir. Dört seçeneğiniz var, bunlar :

Snapshot Bu varsayılan isolation level'dır. Diğer transaction'lar sizin transaction'ınınız açıkken tablolarda değişiklik yapabilir ve bunları commit edebilirler. Sizin transaction'ınız aktifken bu değişiklikleri göremezsiniz.
Read committed Sizin transaction'ınız, diğer transaction'ların commit ettiği verileri görebilir.
Read-Only Table Stability Diğer transaction'lar, sizin transaction'ınız commit veya rollback yapana kadar, tabloları değiştiremezler.
Read-Write Table Stability

 Snapshot veya Read committed'ı seçerseniz, nowait seçeneği de eklenir. Bu parametre diğer transaction'lar tarafında kitlenmiş (lock) kayıtlara karşı nasıl davranılacağını belirler. Mesela bir kaydı silmek istediniz ve bu başka bir transaction tarafından kitli. nowait ayarlanmışsa, hemen bir hata döndürülür, eğer wait ayarlanmışsa diğer transaction'ın kayıtı serbest bırakması beklenir ve serbest kalınca kayıt silinir.

IBDataset'in Kullanımı

Bundan sonraki adım data modüle bir veri erişim bileşeni koymak. Eğer yeni bir Interbase uygulaması oluşturuyorsanız, IBDataset bileşenini kullanmanız iyi olur. Diğer veri erişim bileşenleri özel amaçlar için veya BDE tabanlı uygulamalar için uyumluluk için eklenmiştir.

İlk olarak Database özelliğini ayarlayın. Burdan koyduğumuz IBDatabase bileşenini seçin. Bu özellik ile hangi veritabanına bağlanacağımızı seçiyoruz. Daha sonra kayıtları seçmek için gerekli SQL cümlesini SelectSQL kısmına yazmamız lazım. Mesela örnek olarak:

Select * From EMPLOYEE where Dept_No=:Dept_No

Gördüğünüz gibi IBDataset bileşeninde verilere erişmek ve verileri yönetmek için sonu SQL ile biten birçok özellik var. bunlar :

Özellik Açıklama
SelectSQL Bir veya birden fazla tablodan bazı kayıtları seçmek için kullanılan SQL ifadesi
RefreshSQL Sadece bir kayıt seçmek için kullanılan SQL ifadesi
InsertSQL Yeni bir kayıt eklemek için kullanılan SQL ifadesi
ModifySQL Bir kayıtı güncellemek için kullanılan SQL ifadesi
DeleteSQL Bir kayıtı silmek için kullanılan SQL ifadesi

Tabi yine Delphi güzelliği bu SQL ifadelerini elle yazmak zorunda değilsiniz. IBDataset'e sağ tıklayın ve Dataset Editor komutunu verin. Karşınıza aşağıdaki pencere gelecektir.

Get Table Fields butonuna tıklatın. Key Fields ve Update Fields kısımlarına tablonun tüm alanları getirilir. Her iki kısımda da tüm alanları seçmek için Dataset Defaults butonuna tıklatın. Key fields kımında otomatik olarak sadece primary key'in seçilmesi için Select Primary Keys butonuna tıklatın. Bunlar (Key fields) güncellenecek kayıtları tesbit için kullanılır. Update fields kısmında güncellenecek alanların listesi yer alır. Bazı durumlarda tüm kayıtları güncelemek istemeyebilirsiniz. Mesela burda FULL_NAME alanı bunun için güzel bir örnektir. Bu alan FIRST_NAME ve LAST_NAME alanlarının runtime birleştirilmesinden oluşmaktadır ve güncellenmemesi gerekir. Onun için bu alanı listeden çıkardık. Son olarak Generate SQL butonuna basıp SQL cümlelerini oluşturun. Cümleler oluşturulur ve SQL sekmesine geçilir.

Burda Statement Type kısmındaki radio butonlara tıklayarak SQL cümleleri arasında gezebilirsiniz. Otomatik olarak oluşturulan Modify SQL cümlesi aşağıdaki gibidir :

update EMPLOYEE
set
  EMP_NO = :EMP_NO,
  FIRST_NAME = :FIRST_NAME,
  LAST_NAME = :LAST_NAME,
  PHONE_EXT = :PHONE_EXT,
  HIRE_DATE = :HIRE_DATE,
  DEPT_NO = :DEPT_NO,
  JOB_CODE = :JOB_CODE,
  JOB_GRADE = :JOB_GRADE,
  JOB_COUNTRY = :JOB_COUNTRY,
  SALARY = :SALARY
where
  EMP_NO = :OLD_EMP_NO
 

IBDataset bileşeni SQL cümlelerini oluştururken 2 tip parametre sunar. Birinci tipin isimleri çalıştığınız tablodaki alanların isimleridir. Bu parametreler her bir alanın yeni değerini içerir. İkinci tip parametrede alan isminin önünde OLD_ ifadesi bulunur. Bu parametre o alanın orjinal değerini döndürür. Burda gördüğünüz gibi her alanın yeni değeri atanmışken, where kısmında primary keyin eski değeri ile kayıta konumlanıp, değiştirilir.

Gördüğünüz gibi çok basit birkaç buton tıklatma ile gerekli tüm SQL cümlelerini oluşturduk, işte Delphi'nin gücü :)

Son olarak bu bileşende ayarlamak isteyebileceğimiz bir özellik daha var. Unidirectional. Interbase (ve diğer SQL veritabanları da) tek yönlü cursor'ler sunarlar ve bu ileri doğrudur. Geri dönülmesi gereken durumlar için Delphi bir bufferlama şeması sunar (buffering scheme). Bu ise daha fazla hafıza kullanıma ve daha uzun işlem süresi demektir. Bazı durumlarda, mesela raporlarda bu geri dönüşlere ihtiyacımız olmaz. Bu durumda bu özelliği True yaparak performansı artırabilirsiniz.

IBSQL'in Kullanımı

Client/Server uygulumada kullanıcını mümkün olduğu kadar az kayıtla çalışması iyidir. Bazen kullanıcıyı buna zorlamalısınız. Mesela kullandığımız IBDataset'te belli bir departmanda çalışan, işçileri seçmiştik. Bunun için kullanıcının bir yerden departmanları seçmesi lazım ki, bizde seçilen departmana göre çalışanları getirelim. Mesela bunu bir ComboBox'tan seçebilir. Bu durumda departman isimlerini ComboBox'a doldurmalıyız. Bu iş için IBSQL bileşeni idealdir. Bufferlaması olmadığından, sadece unidirectional hareket sağladığından ve data-aware(veri bilinçli) kontrolleri desteklemediğinden çok daha az kaynak harcar.

Bu bileşeni kullanmak için data module bir IBSQL bileşeni koyup, database özelliğini ayarlayın. SQL kısmına aşağıdaki SQL cümlesini yazın :

select DEPT_NO, DEPARTMENT from DEPARTMENT
order by DEPARTMENT

bu cümle departmanları, departman ismine göre sıralı seçecektir. Bunu bir döngü yardımı ile ComboBox'a doldurabilirsiniz. Burada dikkat etmeniz gereken, IBSQL bileşeninin Active özelliği ve Open metodu yoktur. IBSQL'i ExecQuery ile açmalı ve Close ile de kapatmalısınız. Örneğin Formun OnShow olayında doldurabilirsiniz ComboBox'ı. ismi CB_Departman olsun,

procedure TForm1.FormShow(Sender: TObject);
begin
  with DataModul, DataModul.IBSQL1 do
  begin
    IBTransaction1.StartTransaction;
    ExecQuery;
    while not EOF do
    begin
      Cb_Departman.Items.Add(FieldByName('Dept_No').Value + ' - ' +
      FieldByName('Department').Value);
      Next;
    end; {while}
    Close;
    IBTransaction1.Commit;
  end; {with}
end;

Aşağıdaki durumlarda da IBSQL'i kullanmak iyi bir seçenek olacaktır.

* Bir tablodan diğerine veri aktarırken
* Veri export ederken
* Generator'den bir değer alırken
* DDL (Data Definition Language) ifadeleri (UPDATE vs.) çalıştırırken.

Kullanıcı Arabirimini Tamamlayalım

Kullanıcı arabirimini tamamlamak için bir DataSource bileşenini data module koyun ve dataset özelliğini IBDataset1 olarak ayarlayın. Daha sonra bir DBGrid koyup, DataSource özelliğini DataSource1 olarak ayarlayın. Daha önce CB_Departman isimli comboBox içine departman numaralarını ve isimlerini doldurmuştuk. Şimdi kullanıcı burdan bir departman seçtiği zaman, o departmanda çalışan işçileri seçmeliyiz. Bunun için Cb_Departmanın OnChange olayına aşağıdaki kodu yazın :

procedure TForm1.Cb_DepartmanChange(Sender: TObject);
var
  DeptNo: Integer;
begin
  DeptNo := StrToInt(Copy(Cb_Departman.Text, 1, 3));
  with DataModul, DataModul.IBDataSet1 do
  begin
    Close;
    if not IBTransaction1.InTransaction then
      IBTransaction1.StartTransaction;
    Params.ByName('Dept_No').AsInteger := DeptNo;
    Open;
  end; {with}
end;

Bu kod seçilen öğenin ilk üç karakterini alır, bu departman kodudur. Bunu parametre olarak IBDataset1'e geçer ve o departmandaki işçiler seçilir.

Transaction'larla Çalışma

Interbase ile çalışırken herşey transaction'ların içinde olur. Birkaç kayıt seçen basit bir SQL cümlesi bile transaction içinde olmak zorundadır. Siz bu Select ifadesi için herhangi bir transaction'ı açıkca başlatmasanız bile IBX arka planda bir transaction kullanır.

Mesela yukarda CB_Departman isimli comboBox'a departman isimlerini alırken kullandığımız StartTransaction ve Commit ifadelerini kullanmaya gerek yoktur. Burda örnek vermek amacıyla kullandık :)

IBTransaction, Commit ve Rollback dışında transaction'ları bitirmek için iki metoda daha sahiptir : CommitRetainig ve RollbackRetaining. CommitRetainig aktif transaction'da yapılan tüm değişiklikleri veritabanına (dosyaya) yazar ve transaction'un içeriği tutulur. RoolbackRetaining'te aktif transaction'da yapılan tüm değişiklikler iptal edilir ve transaction'un içeriği tutulur.

Transaction bileşeninin bir faydası da uygulamanız aynı anda birden fazla transaction ile çalışabilir. Bunu BDE ile yapamazsınız. Mesela iki tane IBDataset bileşenine iki ayrı IBTransaction bağlayıp, ikisininde ayrı transactionlara sahip olmasını sağlayabilirsiniz. Bu iki IBDataset birbirinden bağımsız olarak yaptıkları değişikleri commit veya rollback yapabilir. Eğer Midas kullanıyorsanız bu bir zorunluluktur, her IBDataset'e ayrı IBTransaction bağlamalısınız.

Diğer Veri Erişim (Data Access) Bileşenleri

IBQuery ve IBTable bileşenleri mevcut BDE uygulamalarınızı kolayca IBX'e geçirmeniz için tasarlanmıştır. Eğer yeni bir projeye başlıyor iseniz IBDataset kullanmanız şiddetle önerilir. Bazen IBTable'da kullanışlı olabilir. Mesela çok az kaydı olan küçük tabloları düzenlemede kullanabilirsiniz.

Bu bölümde inceleyeceğimiz diğer bir bileşen IBStoredProc. Bu bileşen BDE'deki adaşına çok benzer bir görev icra eder ve herhnagi bir kayıt döndürmeyen Stored Procedure'ler için kullanılır.

IBTable'ı Kullanma

IBTable, BDE'deki Table bileşenine çok benzer ama ondan daha hızlı çalışır. Görünür olarak benzer olsalarda IBTable'daki tüm kayıt seçimleri arka planda SQL cümleleri ile olmaktadır. Mesela tüm kayıtları seçmek istemiyorsanız FILTER özelliğini kullanabilirsiniz. Bu arka planda SQL cümlesinde WHERE kısmına yazılmakta, ve kayıtlar SQL cümlesi ile seçilmektedir. FILTER özelliğinin çalışması için Filtered özelliğini True yapmanız ve tabloyu açmanız yeter.

Tabi yine de IBDataset kadar esnek değildir, örneğin IBTable'da tüm alanlar seçilir. Ancak kullanımı son derece kolaydır. Sadece Database, Transaction ve TableName özelliklerini ayarlayın o kadar. Herhangi bir SQL cümlesi yazmanız gerekmez. IBTable'ın döndürdüğü kayıtları görebildiğiniz gibi düzeltebilirsiniz de (edit).

Verileri sıralamak için IndexName ve IndexFieldNames özelliklerini kullanabilirsiniz. IndexName kısmından sıralama yapmak için mevcut indekslerden birini seçebilirsiniz. IndexFieldNames kısmına sıralama yapmak istediğiniz alanı veya ; ile ayırarak birden fazla alanı girebilirsiniz.

IBQuery'i Kullanma

IBQuery, SQL cümlesi ile yazılan kayıtları salt okunur (read only) olarak döndürür. IBQuery ile SELECT cümlelerini Open ile açabileceğiniz gibi, herhangi bir sonuç döndürmeyen SQL cümlelerini de ExecSQL ile açabilirsiniz. Ancak hiçbir sonuç döndürmeyen SQL cümleleri için daha az kaynak harcayan ve daha hızlı çalışan IBSQL bileşenini kullanmak daha doğru olur.

IBQuery, salt okunur sonuçlar döndürür. Sonuçları düzenlemek için IBUpdateSQL bileşeni kullanmalı ve CachedUpdates özelliğini True yapmalısınız. IBQuery'nin UpdateObject özelliğinden koyduğunuz IBUpdateSQL bileşenini seçin ve IBUpdateSQL'e sağ tıklayıp UpdateSQL Editor'ü açın. Burda gerekli SQL cümleciklerini oluşturun. Bu ekran IBDataset kısmındaki ekrana benzerdir, aynı şekilde kullanabilirsiniz.

Midas Server için IBQuery iyi bir seçimdir. Midas Server'da güncellemeler DatasetProvider bileşeni tarafından idare edildiğinden, IBUpdateSQL bileşeni kullanmanıza gerek yoktur.

IBStoredProc'u Kullanma

Interbase stored procedure'lerini iki gruba ayırabiliriz : sonuç (kayıt) döndürenler ve sonuç döndürmeyenler. Sonuç döndüren stored procedure'leri IBDataset veya IBQuery gibi bileşenler ile kullanabilirsiniz. Herhangi bir sonuç döndürmeyen Stored procedure'ler için IBStoredProc bileşenini kullanın.

IBStoredProc'u forma veya data module koyduktan sonra Database, Transaction özelliklerini ayarlayın. StoredProcName kısmından stored procedure'ün ismini seçin. Params özelliği stored procedure parametrelerinin tipini ayarlamak ve varsayılan değer atamak için kullanılır. 

Mesela örnek veritabanımızdaki EMPLOYEE_DELETE isimli stored procedure'le bir örnek yapalım. Bu stored procedure parametre olarak işçi numarasını (EMP_NUM) alıyor, bu işçiyi veritabanından siliyor ve diğer tablolarda gerekli değişiklikleri yapıyor. Ayarları yaptınız, forma işçi numarasını almak için bir Edit koyun. Sonra aşağıdaki kodu yazın :

with StoredProc1 do
  begin
    Prepare;
    Params.ParamByName('EMP_NUM').Value := StrToInt(Edit1.Text);
    ExecProc;
    Unprepare;
  end; {with}
end;

Bu kod parametre olarak Edit'e girdiğiniz numarayı alıp, stored procedure'ü çalıştırmaktadır. Koddaki Prepare ve Unprepare ifadeleri seçimliktir. İsterseniz yazmayabilirsiniz. Bu ifadeler stored procedure'ü birden çok kez çalıştıracaksanız faydalıdır. Mesela peş peşe 3 işçi silecekseniz Prepare komutunu verin, 3 işçiyi silin, Unprepare komutunu verin. İşlem daha hızlı yapılacaktır.

bimeks borland component database delphi delphi.net delphi dersleri firebird help interbase makale oracle seminer software sybase veritabanı web