Visual C++ ile Veritabanı (BÖLÜM 4)

19 Tem

DOĞRU VERİ TABANI TEKNOLOJİSİNİ SEÇİM

 

Veri saklama çoğu yazılım uygulamasının zorunlu bir parçasıdır. Hemen hemen bütün C++ uygulamaları bazı tip verileri saklanmasını veya sürekli kalmasını gerektirir.

 

Çoğu uygulamaların veriyi verimli bir şekilde tekrar alması gerekir. Bu uygulamalar tipik olarak sırayla depo edilmiş özel bilgileri geri almak için veri boyunca arama yapmaları gereklidir. Bu arama yapma ve verinin geri alınması bir veri tabanının kullanımını gerektirir.

 

C++ programcıları için çeşitli veri tabanı teknolojileri vardır. Bugün bu veri tabanı teknolojilerini araştıracak ve uygulamalarınız için size gerekli olan uygun teknolojiyi seçmeğe çalışacağız.

 

VISUAL C++ UYGULAMALARINIZ için UYGUN VERİ TABANI TEKNOLOJİSİNE KARAR VERME

 

Doğru veri tabanı teknolojisi seçmek demek uygulamanızın gereklerini dolduran bir teknoloji bulmak demektir.

 

Çeşitli veri tabanı teknolojilerini bilmeden, uygulamanız için yanlış birini seçebilirsiniz. İlerleyen bölümde, her veri tabanı teknolojisinin yeteneklerini öğreneceksiniz.

 

Bir veri tabanı teknolojisi seçerken, uygulamanızın verilerinin önemini dikkatlice göz önünde bulundurmanız gereklidir. Sizin uygulamanız tarafından kullanılması gerekli olan veriyi düşünmek kolay olacaktır. Ancak, eğer uygulamanızı aklınızdaki bu düşünce ile yazarsanız kapalı, kimsenin anlayamayacağı veya kullanamayacağı hususi bir veri tabanına sahip bir uygulama oluşturarak bitireceksinizdir.

 

Uygulamanız için kapalı, hususi bir veri tabanının yeterli olup olmayacağını düşünmelisiniz. Çünkü uygulamanız veriye erişimi gerekli olan bir uygulamadır. Veri için gerekli değeri ve veriye erişim için gereğini eksik tahmin etmeyin.

 

C++ DA KENDİ VERİ TABANINIZI YAPMAK

 

Bir C++ programcısı genellikle yazılım yazmak için kendi yeteneğinden emindir. Buna rağmen C++ gibi kompleks ve güçlü bir dili yönetebiliyorsanız, size gerekli olacak kendi veri tabanınızı içeren bir yazılım aracını yazmakta şüpheniz olmaz.

 

Ancak şu an var olan veri tabanı teknolojilerinin olgunluğundan ötürü kendi veri tabanınızı yazmak nadiren verimli bir çaba olacaktır. Gerçi bir elektrik mühendisi muhtemelen kendi cep telefonunu yapabilir. Şu an var olan cep telefonları çok bol ve ucuz ve hücresel ağlar ve diğer cep telefonlarıyla interaktif olarak iletişim kurmak için bazı standartlara bağlıdırlar.

 

Aynı şekilde, bir C++ programcısı kendi veri tabanı sistemini yapabilir. Şu an var olan veri tabanları çok bol ve ucuz ve bilgisayar ağları ve diğer uygulamalarla interaktif olarak iletişim kurmak için standartlara bağlılar. Kendi uygulamanızı geliştirmek üzerinde yoğunlaşmalısınız.

 

Liste 1, temel bir veri tabanı oluşturmak ve yapısal veriyi disk üzerinde bir dosyaya depolamak için ne gerektiğini gösteriyor. Bu uygulamayı oluşturmak için Visual C++’ı çalıştırın ve bir Win32 konsol uygulaması olarak yeni bir proje oluşturun. Yeni projeye bir ad verin. CPPDb gibi bir ad vermek uygun olacaktır. Projede bir kaynak dosya oluşturun, muhtemelen main.cpp diye adlandırılacak ve aşağıdaki kodu onun içine girin.

 

Liste 1 Bir dosyaya veri yazan C++ Kodu

 
 1:  #include <fstream.h>
 2:  
 3:  struct Date
 4:  {
 5:     int iMonth, iDay, iYear;
 6:  };
 7:  
 8:  struct Product
 9:  {
10:     int iPartNumber;
11:     char szName[80];
12:     double dPrice;
13:  };
14:
15:  struct Customer
16:  {
17:     int iID;
18:     char szName[50];
19:     char szAddress[50];
20:     char szCity[20];
21:     char szState[20];
22:     char szZip[9];
23:  };
24:  
25:  void main()
26:  {
27:     Date dt = { 6, 10, 92 };
28:     Product prod = {122, "Vegamatic", 19.95};
29:     Customer cust = {15, "Seymore Hoskins", "300 Oak St",
                         "Boring", "Oregon", "97203"};
30:     ofstream datafile( "data.dat" , ios::binary );
31:     datafile.write( (char *) &dt, sizeof dt );
32:     datafile.write( (char *) &prod, sizeof prod );
33:     datafile.write( (char *) &cust, sizeof cust );
34:  }

 

 

Bu kod hakkında bir çift şeye dikkat edin. İlk olarak, veri yapılarının 3-23 satırları arası tanımlandığını görüyorsunuz. Yapılar, tahmin edilebilir bir şekilde belli bir kalıpta dosyaya veri yazmakta kullanılır.(31-33 satırları) Uygulamadaki diğer rutinler, bu yapıları dosyadan veri okurken ve anlarken kullanabilirler.

 

Uygulamayı yapın. Hata veya uyarılar almamalısınız. Uygulamayı çalıştırdığınız zaman, uygulamanın bulunduğu klasörde data.dat adında bir dosya oluşturacak ve dosyaya veri yazacak. Eğer data.dat dosyasını bir hex dosya göstericisi ile açarsanız veya Notepad.exe ile dosyadaki veriyi göreceksiniz.

 

 

 

 

 

VERİ TABANI ÇALIŞMASINI KULLANMAK İÇİN BİR C++ TABAN SINIFI

 

Dikkat edilmesi gereken diğer husus Liste 1 deki kaynak kod tam olarak nesneye yönelik değildir.

 

C++’ı kullanarak, diskteki dosyalara nesne verisinin okunmasını ve yazmasını kullanan bir taban sınıfı yazabilirsiniz. Bu taban sınıfını Persistent sınıf diye adlandırabilirsiniz. Örnek uygulamada, Persistent sınıftan bir Orders sınıfı türetebilirsiniz.

 

Maalesef, C++ Persistenet taban sınıfını çalışılamaz yapan birkaç kısıtlamalara daha sahiptir. Persistent taban sınıfı çalışma zamanında türetilmiş bir sınıfın bir nesnesinin ne kadar büyük olduğunu bilemez. Böylece türetilmiş bir sınıfın bir nesnesini diske saklayamaz. Çalışma zamanı içeriği veya işaretçi içerikleri ile uğraşan türetilmiş bir sınıfın bir nesnesinde veri üyeleri de olabilir. Bir Persistent taban sınıfı için bu veri üyelerini düzgünce kullanmak zor olacaktır.

 

Bu problemler sonunda bütün veri tabanı işlerini kullanmak için bir C++ taban sınıfı yazamazsınız manasına gelir. Bir sınıftan veriyi saklamak için bazı kodlar sınıfın kendi içinde olmalıdır.

 

OLE YAPISAL DEPOLAMA

 

Microsoft’un OLE teknolojisi, OLE yapısal depolama diye adlandırılan bir teknolojidir. OLE yapısal depolama, dosyalarınızın iç yapılarını keşfetmenizin potansiyelini diğer uygulamalara vermeyi taahhüt eder. OLE yapısal depolama, disk üzerindeki bir dosyanın akışlar ve depolama hiyerarşisi parçalarına bölünmesini mümkün kılan bir depolama mimarisidir. Depolamalar işletim sistemleri klasörlerine ve alt klasörlerine benzerler. Akışlar işletim sistemindeki dosyalara benzerler. Bu depolama ve akışlar tek bir disk dosyasında mevcut olabilir.

 

Liste 2 bir OLE yapısal depolama dosyası nasıl oluşturulur gösteriyor. Kök depolamada bir akış oluşturun ve dizi bilgilerini akışın içine yazın. Liste 2’deki kod, hatalar için geri dönen değerleri kontrol etmiyor, kod açıklığı ve kısalığını temin etmek için.

 

Bu örneği yapmak için Visual C++ çalıştırın ve Win32 konsol uygulaması için yeni bir proje oluşturun. Yeni projeye herhangi bir ad verebilirsiniz. OLESS diye adlandırmak uygun olacaktır. Projede bir kaynak dosya oluşturur, muhtemelen main.cpp diye adlandırılacaktır ve aşağıdaki kodu onun içine girin.

 

Liste 2 OLE Yapısal Depolama

 

 1:  #include <windows.h>
 2:  #include <ole2.h>
 3:  struct Date
 4:  {
 5:     int iMonth, iDay, iYear;
 6:  };
 7:
 8:  struct Product
 9:  {
10:     int iPartNumber;
11:     char szName[80];
12:     double dPrice;
13:  };
14:
15:  struct Customer
16:  {
17:     int iID;
18:     char szName[50];
19:     char szAddress[50];
20:     char szCity[20];
21:     char szState[20];
22:     char szZip[9];
23:  };
24:
25:  void main()
26:  {
27:     Date dt = { 6, 10, 92 };
28:     Product prod = {122, "Vegamatic", 19.95};
29:     Customer cust = {15, "Seymore Hoskins", "300 Oak St",
                         "Boring", "Oregon", "97203"};
30:
31:     IStorage * pRootStorage;
32:     IStream * pOrderInfo;
33:
34:     CoInitialize(NULL);
35:
36:     StgCreateDocfile(L"data.dat", 
         STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
         0, &pRootStorage);
37:
38:     pRootStorage->CreateStream(L"Order Information",
         STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 
         0, 0, &pOrderInfo);
39:
40:     pOrderInfo->Write(&dt, sizeof(dt), NULL);
41:     pOrderInfo->Write(&prod, sizeof(prod), NULL);
42:     pOrderInfo->Write(&cust, sizeof(cust), NULL);
43:
44:     pOrderInfo->Release();
45:     pRootStorage->Release();
46:
47:     CoUninitialize();
48:  }

 

Tek bir veri dosyası içinde akışların ve depolamaların bir hiyerarşisini oluşturdunuz. 31. ve 32. satırlar iki OLE ara yüz işaretçisini tanımlar.(IStorage ve IStream) 34. satır COM kütüphanelerini başlatmak için CoInitialize‘ı çağırır. 36.satır OLE yapısal depolama dosyasını oluşturmak için bir API fonksiyonu çağırır, StgCreateDocFile. Bu çağırma Istorage’ın başlangıcını oluşturur ve son parametrede ona bir işaretçi geri döndürür, pRootStorage. 38.satır kök depoda bir akış oluşturmak için pRootStorage işaretçisi içinden IStorage sınıfının CreateStream fonksiyonunu çağırır. CreateStream fonksiyonu geriye bir IStream sınıfı döndürür ve son parametrede ona bir işaretçi geri döndürür, pOrderInfo. 40-42 satırları akışın içindeki veriye yazmak için Istream’in Write fonksiyonunu çağırır. 44. ve 45. satırlar pOrderInfo ve pRootStorage başlamalarını silmek için Release’i çağırır. 47. satır COM kütüphanelerini durdurur.

 

Uygulamayı yapın. Hata veya uyarı almamalısınız. Uygulamayı çalıştırdığın zaman, uygulamanın olduğu klasörde data.dat adında bir OLE yapısal depolama dosyası oluşturacak ve verileri dosyaya yazacaktır.

 

Hala dizi bilgileri için metadata tanımlamalısınız. Örnek uygulama için metadata OLE yapısal depolama için temsil etmesi çok komplekstir. Bir siparişin, bir sipariş tarihi içerdiğini (ay, gün yıl olarak) bir ürün içerdiğini (ürün numarası, ismi ve değeriyle beraber) ve bir müşteri içerdiğini (isim, adres vb ile beraber) belirtmelisiniz. Aynı zamanda veri tiplerini ve uzunluklarını belirtmelisiniz. Bu detay seviyesi akışlar ve depolar hiyerarşisi kullanarak temsil edilemez.

 

Eğer OLE yapısal depolama kullanırsan, başka bir rutin veya veri dosyanı açmak isteyen ve verinin yapısını görmek isteyen uygulama bunu yapamayacaktır. Göreceği tek şey depoların ve akışların bir hiyerarşisini görecektir. Diğer rutinler ve uygulamalar hala veriyi anlamak için kaynak kodlara erişmeleri gerekmektedir. Aynı zamanda OLE yapısal depolama doğasında dosya-kitleme(file-locking) veya kayıt-kitleme(record-locking) yeteneğine sahip değildir. Böylece yazmanız gereken kilitleme kodlarının miktarını azaltmayacaktır.

 

OLE yapısal depolama öncelikle doküman-merkezi(document-centric) uygulaması tarafından, Microsoft Word ve Excel gibi, dokümanlara veri dosyaları oluşturmak için kullanılacaktır. Word ve Excel dosyaları kendilerini tanımlayamazlar. Excel verisi içeren bir OLE yapısal depolama dosyasındaki veriye erişmek isteyen herhangi bir uygulama, akışların içindeki verinin nasıl organize olduğu bilgisine sahip olmalıdır.

 

MASA ÜSTÜ VERİTABANI

 

Masaüstü veritabanı veri tabanı yazılımlarının bir sınıfıdır. Isam dosyalar kullandıkları için isam veritabanı diye de adlandırılırlar. Marketlerde birçok masaüstü veritabanı vardır. Ms access ms foxpro ve borland paradox bunlardandır. Bu veritabanlarının birçok farklılıkları olsa da ortak özellikler taşımaktadırlar.

 

Masaüstü veritabanları meta datalarını isam dosyalarında taşırlar. Veri dosyaları kendiliğinden tanımlanır. Bu çeşitli uygulamaların veri tabanındaki verilere ulaşmasını sağlar. Masaüstü veritabanları kendi dilleri , veri çeşitleri ve yorumlayıcıları vardır. Masaüstü veritabanının kendi dilini onunla uygulama geliştirmek için kullanırız.

 

Masaüstü veritabanları standart dbms fonksiyonlarını kullanmak için geliştirilirler. Bunlar veri tanımlaması veri işleme sorgulama güvenlik ve bakımdır. Masaüstü veritabanları pc’lerde çalıştırılmak için tasarlanmıştır.

 

C++ programları masaüstü veritabanlarına erişmek için ODBC API’leri kullanırlar. Bir C++ programı veri tabanına veri saklamak ve çağırmak için ODBC API’lerini çağırabilirler. ODBC’yi access yorumlayıcısına (jet database engine) dil komutlarını gönderebilirsiniz. Access bu komutun cevabını gönderecektir.

 

3 Listesi bazı ODBC API’lerini göstermektedir. Bu kısa koddur ve bu hali ile işlenmez.

 

                      1:  long      lResult;

              2:  SDWORD      cbResult;

              3:  HSTMT       hstmt;

              4:  CDatabase   mfcdb;

              5:

              6:  mfcdb.OpenEx( “DSN=MyDataSource; UID=MyUserLogin; PWD=MyPassword;”);

              7:

              8:  AFX_SQL_SYNC(::SQLAllocStmt(mfcdb.m_hdbc,&hstmt));

              9:

             10:  AFX_ODBC_CALL(::SQLExecDirect(hstmt, (UCHAR FAR*)

                                “SELECT * FROM Orders”,SQL_NTS));

             11:

             12:  while (::SQLFetch(hstmt) != SQL_NO_DATA_FOUND)

             13:  {

             14:     ::SQLGetData(hstmt, 1, SQL_C_LONG, &lResult, 0, &cbResult);

             15:  }

             16:

             17:  AFX_SQL_SYNC(::SQLFreeStmt(hstmt,SQL_CLOSE));

             18:

             19:  mfcdb.Close();

 

4. satır MFC CDatabase sınıfını tanımlamaktadır. CDatabase ODBC veritabanlarına bağlanmak için gereken kodu kapsar ve basitleştirir. 6. satır CDatabase’nin openex fonksiyonunu çağırır. Bu fonksiyon veritabanına bağlanır. 8. satır veri tabanını yorumlamak için gereken durumları tutar. 10. satır veritabanında yorumlanıp işlenen “SELECT * FROM ORDERS” SQL cümlesini gönderen sqlexecdirect’i çağırır. 12 ve 15 . satırlar veritabanından dönen veriyi alır. 14 . satır lResult değişkenine  dönen kayıtları ilk alanlara dağıtır. 17. satır satır 8 de çağırılan durumu serbest bırakır. 19. satır satır 6 da tanımlanan veritabanı bağlantısını kapatır.

 

Masaüstü veritabanları verileri daha hızlı erişim ve sorgulama için index’lerler. Masaüstü veritabanları verileri çoklu uygulamaların sıra ile kullanmaları için kilitleyebilirler.

 

Masaüstü veritabanları kayda giren verilerin türünü kontrol ederler. Bu sayede bir uygulama veri gönderdiğinde yanlış veri tipi olduğunda gerekli hatayı verebilirler. Bunu veritabanının kendisi yapar.

 

Masaüstü veritabanları kendi dillerinde küme tabanlı işlemlere izin verirler. Bir komutla binlerce kayıt işlenebilir. Örneğin bir veri tabanındaki toplam miktarı bulmak için şu komut yeterlidir.

 

SELECT SUM(price) FROM Orders

 

Masaüstü veritabanlarını bazı kısıtlamaları vardır. Veritabanının raw performansı btrive gibi direct kayıt yönetimli veritabanları kadar iyi değildir.

 

NESNE VERİTABANLARI

 

İlkel veri tabanları veriyi meta dat olmadan saklarlar. Kendinden tanımlanabilir veritabanı dosyası oluşturmak için masaüstü veritabanı ve ilişkili veritabanları meta datayı veritabanı dosyası içinde taşırlar. Object database bir adım daha ileri gider. Bu tür veri ve işlenecek kodu aynı dosyada taşırlar. Bu türe bir çok örnekler marketlerdedir tükenmeden hemen alın…

 

Nesnesel veritabanları tipik olarak bir programlama diline ihtiyaç duyarlar. C++ nesnesel veri tabanı C++ in tip sistemini (ne demekse type system ) destekler. Bir C++ nesnesel veritabanını C++ sınıflarının örneklerini doğrudan veri tabanı içinde saklamak için kullanabilirsiniz.

 

Liste 5 C+ nesnesel veri tabanını ürün bilgilerini nasıl saklanacağını gösterir. Bu kısa koddur böyle işlenmez.

 

1:  #include <string.h>

    2:

    3:  // Header file for the Object Database

    4:  // Management Group (ODMG) object model.

    5:  #include <odmg.h>

    6:

    7:  // Derive our Product class from d_Object

    8:  // so Product can persist itself in the database.

     9:  class Product : public d_Object

     10:  {

     11:  public:

     12:     int iPartNumber;

     13:     char szName[80];

     14:     double dPrice;

     15:  private:

     16:     d_Ref<Product> next;  // For iterating instances of Product

     17:                           // in the database.

     18:  };

     19:

     20:  d_Database db;          // Global instance of the object database.

     21:  const char * const db_name[] = “Products”;

     22:

     23:  void main()

     24:  {

     25:     db.Open(db_name);   // Opens the Products database.

     26:     d_Transaction tx;   // Create and begin a transaction.

     27:     tx.begin();

     28:

     29:     // Create a new product instance in the database.

     30:     Product *prod = new(&db, “Product”) Product;

     31:     prod->iPartNumber = 122;

     32:     strcpy(prod->szName, “Vegamatic”);

     33:     prod->dPrice = 19.95;

     34:

     35:     tx.commit();      // Commit the additions to the db.

     36:     db.close();       // Close the db.

     37:  }

 

            Satır 5 d_object sınıfının içerdeği tanımlamaları satan odmg.h başlık dosyasının olduğunu söylemektedir. d_object sınıfı veri tabanına bağlanmak için gereken tanımlamaları içeren c++ ana sınıflarındandır. Satır 9 d_object sınıfından product sınıfını elde eder. Product sınıfı d_ref<product> diye bir üyeye sahiptir(Satır 16). D_ref<> veritabanı sağlayıcısı tarafından sağlanan bir işaretçidir.(pointer)

 

            Satır 30 daki  “new” le çağırılan veritabanındaki product’ta   bir örnekleme oluşturur. Satır 31-32 product örneklemesindeki veri üyelerinin değerlerini değiştirirler. 35 değişiklikleri uygular. 36 veritabanını kapatır. Görüldüğü gibi C++’da veritabanı fonksiyonları çok az bir kodla kullanılabilir.

 

            Bu sıkı kaynaşma büyük veri modellerini programlamak için  güçlü bir imkan sağlar. C++’ın full kapsama miras bırakma ve ploymorfizm özelliklerini kullanabilirsiniz.

 

            Eğer nesnesel dbms kullanırsanız sizin uygulamanız karmaşık veritabanı içerebilir. Bunun yanında dezavantajları da vardır. Nesnesel veritabanları programlama dili ile çok girişik olduğu için başka uygulamalar tarafından kullanılması zordur.

 

 

 

 

 

 

VERİTABANI KARŞILAŞTIRMALARI

 

 

 

C++

OLE
SS

Record
Mgr

Desktop
Db

Object
Db

RDBMS
Server

Veri açıklığı

 

+

-?

+

Kompleks veri modelleri

 

+

 

Çok Kullanıcı

 

 

+?

+

Performans

+

 

+?

+

Kapasite

 

 

+?

+

Küme tabanlı işleme

+

+

+

Serverda işleme

-?

+

Uygulamaya adaptason

+

+

 

 

?

Veri bütünlüğü

+

+

+

Kod fonksiyonluk oranı

+

++

+

Tablo 4.1 Veritabanı karşılaştırmaları

 

ODBC

 

ODBC, Open Database Connectivity kelimesinin kısaltılmış şeklidir. ODBC, Windows uygulamalarının oluşturulmuş veri tabanı alanlarına bağlantısını sağlar.

 

Her ODBC uygulama routin’i, SQL kelimesi ile başlar. Örneğin, SQLFetch(hstmt); buna örnektir. Aşağıdaki şekil ODBC uygulaması, veri kaynakları arasındaki ilişkiyi açıklar:

ODBC uygulamaları, MFC class’larını kullanabilir yada doğrudan ODBC driver meneger’i çağırabilir. MFC class fonksiyonlarını kullanma konusunda yada ODBC driver meneger’i doğrudan kullanma konusunda herhangi bir kısıtlama yoktur. Bununla beraber, uygulamaların MFC ODBC class’ları ile birlikte yazılmasında üye fonksiyonlar kullanılmaktadır.

 

            ODBC Adımları şu şekilde gösterilebilir.

 

START

            Initialization

                        SQLAllocEnv()

                        SQLAllocConnect()

            SQLConnect() veya

            SQLDriverConnect()

            SQLAllocStmt()

 

Data Access

            Get optional into on data source

            Set up columns needed

            Fetch data using SQLFetch()

 

Termination

            SQLFreetmt()

            SQLDisconnect()

            SQLFreeConnect

            SQLFreeEnv()

DONE

 

ODBC Fonksiyonları

 

            ODBC, geniş bir fonksiyon kütüphanesini sunmaktadır.Genelde veri tabanı çalışmalarının çoğunda birkaç ODBC fonksiyonu yeterli olmaktadır.

 

            ODBC’nin işleyişi sırasıyla üç adımla gösterilebilir.

 

1.      Başlangıç olarak, yer ayırma ve bağlantı sağlanması işlemi gerçekleştirirlir.

2.      Veri kaynağı bağlantısı, veri okuma, güncelleme, ekleme, islme vb. işlemler gerçekleştirilir.

3.      Bağlantı kesme ve serbest bırakma işlemleri yapılır.

 

Veri tabanı bağlantılarında SQL’in SELECT FROM gibi basit mantık grupları kullanılabileceği gibi JOIN gibi daha karmaşık yapılarda kullanılabilir.

 

Initializaiton İşlemi

 

            Bu evrede, yer ayırma işlemi ilk adımı teşkil eder. SQLAllocEnv() fonksiyonu ile ODBC yapıları için bellek’te yer ayırma işlemi yapılır, bir HENV handle’ döndürülür. Bu handle, diğer fonksiyonların çağırılması  için gereklidir.

 

            Daha sonra, bağlantı adımına geçilir. Burada SQLAllocConnect() fonksiyonu kullanılır.

 

SQLAllocConnect()

 

SQLAllocEnv() fonksiyonundan sonra kullanılmalıdır ve bağlantıyı sağlar.

 

SQLConnect() ve CQLDriverConnect()

 

SQLConnect() veya SQLDriverConnect(), enviroment’ten sonra çağrılır ve bağlantıyı sağlarlar. Veri kaynağı ve uygulama arasında en iyi performans vereni seçilmelidir. İkisi arasındaki temel fark.

 

            SQLDriverConnect() fonksiyonunun, Network topolojileri bölümünde yüklü bulunan kullanıcı arayüzü güçlüklerini engelleyici veri kaynağı bağlantısı yapması için parametre desteğine ihtiyacının olmasıdır.

 

Data Access Aşaması

 

            Veri erişimi aşaması, SQLAllocStmt() fonksiyonunu içerir.

 

SQLAllocStmt():

 

Geçerli SQL statement handle’ı için bellekte yer ayırır.

 

            Erişim aşaması, veri tabanındaki veriler için hangi değişkenlerin kullanılacağının belirlendiği aşamadır. Her işlem için değişken kullanımı gereksiz kılınmıştırç Veriye erişim SQLFetch() fonksiyonu ile sağlanır.

 

SQLFetch():

 

Bir dizi veriyi alıp getirme işlemini yapar. SQLFetch(), tanımlanmış SQL_SUCCESS veya SQL_SUCCESS_WITH_INFO değişmezlerinden değerini geri döndürür.

 

Termination İşlemi

 

            Bağlantı kesme anlamındadır. Bu kısımda, veri kaynağındaki verilere erişim tamamlanmış, bellek serbest bırakılmıştır. Bu işlemler, SQLFreeStmt(), SQLDisconnect(), SQLFreeConnect, ve SQLFreeEnv() fonksiyonlarının çağırılması ile sağlanır.

 

MFC ve ODBC

 

            ODBC fonksiyonlarının C++ programlama ile ilişkisini açıklar.

 

            ODBC erişimi için kullanılan iki ana MFC sınıfı CRecordSet ve CRecordView isimlerini taşır.

 

            CRecordSet, ODBC erişimi için kullanılan ana sınıftır. CRecordSetView, yardımcı sınıftır. Bir veri kümesindeki kayıtlatı görmek için kullanılır.

 

            CRecordView sınıfı her zaman CRecordSet’e bağlanır. Kullanıcı eğer CRecordSet* OnGetRecordSet() üye fonksiyonu otomatik olarak bağlantıyı sağlar. ClassWizard, bu fonksiyonun kullanıcı tarafından girilmesini beklememektedir.

 

CDatabase Sınıfı

 

            CDatabase sınıfı ODBC kullanımı içinde temel yapılandırma bloğudur. CRecordSet sınıf nesnesi güncel kayıt ile arayüz oluşturabilmek için CDatabase class nesnelerini kullanır.

 

            Her programda CDatabase nesnesini yaratmaya ihtiyaç duyulmaktadır. Eğer, CRecordSet’in, yapıcısı CDatabase sınıfının işaretçisi için NULL değeri üretti ise CRecordSet sınıfı yeni bir CDatabase nesne oluşturacaktır.

 

Veri Üyeleri

 

CDatabase sınıfında bir adet veri üyesi vardır. m_hdbc: SQLAllocConnect() ile çağrılan bir ODBC bağlantı handle’ının ismidir. Üye değişkeni olan n_hdbc’nin tipi HDBC’dir

 

Fonksiyon Üyeleri

 

Açma, kapatma, tasarımcı, yok edici üyeleri. CDatabase nesnesinin constructor(yapıcı), destructor(yıkıcı), açma, kapatma fonksiyonları aşağıda belirtilmiştir.

 

            CDatabase(): Bir tasarımcıdır. Sınıf yaratıldığı zaman çağırılır. CDatabase sınıfı yaratıldıktan sonra Open() fonksiyonunu çağırmak gerekmektedir.

 

            Open():

 

            BOOL Open (LPCSTR IpszDSN, BOOL bExclusive=FALSE, BOOL bReadOnly=FALSE, LPCSTR IpszConnect=”ODBC;”, BOOL bUseCursorLib=TRUE);

 

Open() üye fonksiyonu bir veri kaynağı ile bağlantıyı açar. IpszDSN parametresi gereklidir. Fakat, tüm diğer parametreler seçimliktir.

 

            Close():

 

Virtual void Close();

 

            Bu fonksiyon, veri kaynağının açılmasından sonra veri kaynağını kapatmak için kullanılır.

 

            ~CDatabase():

 

            Virtual void ~CDatabase();

 

            Bir CDatabase nesnesi için default destructor’dır.

 

Veri Tabanı Niteliklerini Belirleyen Fonksiyonlar

 

            Veri kaynağı ile ilgili pek çok fonksiyon içerir.

 

            GetConnect():

 

            const CString& GetConnect() const;

 

            GetConnect() fonksiyonu, ODBC bağlantı stringi için bir Cstrin pointer’ı döndürür. Eğer Open() fonksiyonu çağırmaz ise bu string boştur.

 

            IsOpen():

 

                BOOL IsOpen() const;

 

            IsOpen() fonksiyonu, şayet CDatabase nesnesine veri kaynağı bağlanmış ise sıfır olmayan bir değer döndürür. Veri kaynağı CDatabase nesnesine bağlanmamış ise IsOpen() fonksiyonu False döndürür.

 

            GetDatabaseName():

 

            CString GetDatabaseName() const:

 

            Veri tabanı bağlantısı için CString işaretçisi döndürür. Geri döndürülen bu isim Open() fonksiyonunun IpszDSN parametreleri ile tanımlanmış veri kaynağının ismi değildir. Gerçek string ODBC üzerinden bağlı olup dönen string’dir. Bilindiği gibi pek çok veri tabanı tablolardan oluşmaktadır. ODBC tablonun ismini değil de veritabanının ismini geri döndürür. Herhangi bir isimle karşılaşılmaz ise GetDatabaseName() fonksiyonu boş string döndürür.

 

            CanUpdate():

 

                BOOL CanUpdate const;

 

            Güncelleme işlemi yapabilen bir CDatabase objesi var ise ve buna bağlanmış ise CanUpdate() fonksiyonu sıfır olmayan bir değer döndürür.

 

CanTransact():

 

                BOOL CanTransact() const;

 

            Veri kaynağı, güncellemeyi destekliyor ise sıfır olmayan bir değer döndürür.

 

            InWaitForDataSource():

 

                static BOOL PASCAL InWaitForDataSourca();

 

            Kullanıcı arayüzü güncellemede yardımcı fonksiyondur.

 

            SetLoginTimeOut():

 

            void SetLoginTimeOut(DWORD dwSeconds);

 

            Veri kaynağı için zaman ayarlamada kullanılır. Bu fonksiyon, Open() fonksiyonundan önce çağırılır ve normalde bekleme 15 saniye olarak belirtilmiştir.

 

            SetQueryTimeOut():

 

            void SetQueryTimeOut(DWORD dwSeconds);

 

            Bir önceki bekleme süresini değiştirmek için kullanılır.

 

            SetSyncronousMode():

 

            Void SetSyncronousMode(BOOL bSyncronous);

 

            SQL fonksiyonları ile uygulama çağırımlarını ve ODBC geri dönüşümleri kontrol amacı ile kullanılır.

 

Veri Tabanı Fonksiyonları

 

            BeginTrans():

 

            BOOL BeginTrans();

 

            Bu grup, bir seri işlemi yerine getirmek için kullanılır. AddNew(), Edit(), Update(), Delete() çağrımları yapılabilir. BeginTrans fonksiyonu kayıtların açılmasından sonra çağırılmalıdır.. BeginTrans() fonksiyonunun CommtTrans() ya da RollBack() fonksiyonlarından herhangi biri olmadan çağırılması bir hatadır.

 

            CommitTrans():

 

            BOOL CommitTrans();

 

            Veri kaynağına ekleme, yazma ya da veri kaynağından silme gibi güncelleme işlemleri yapılacağı zaman kullanılır. CommitTrans() fonksiyonu çağrılır ve sonra BeginTrans() fonksiyonu çağrılır. CommitTrans() fonksiyonun BeginTrans() olmadan çağırılması bir hata oluşturulur. Aynı şekilde CommitTrans() fonksiyonlarından sonra RollBack() fonksiyonun çağrılmasıda hataya sebep olur.

 

            Cancel():

 

            void Cancel();

 

            Askıdaki asenkron işlemleri iptal etmek için kullanılan bir fonksiyondur.

 

            ExecuteSQL():

 

            BOOL ExecuteSQL (LPCSTR IpszSQL);

 

            ExecuteSQL(), SQL komutlarını direkt çalıştırmak için kullanılan bir yöntemdir.. Şayet, ExecuteSQL() fonksiyonu başarısız olduğunda MFC Database sınıf nesneleri ilgili hata oluşur ve istisna duruma geçme anlamına gelen “CDBException” oluşur.

 

            OnSetOptions():

 

            virtual void OnSetOptions(HSTMT hstmt);

 

            OnSetOptions() fonksiyonu, ExecuteSQL() ve CRecordSer::OnSetOptions() fonksiyonları çağrılır ise işleyen bir fonksiyondur. OnSetOptions(), seçimlik bir numara atar.

 

CRecordSet Sınıfı

 

ODBC erişimleri için kullanılan MFC sınıfıdır.

 

Üye Deşkenleri

 

            m_hstmt: CrecorSet sınıfının ifade edilmesi için handle tanımlar. Bu üyenin tipi HSTMT’dir Bu handle, yalnızca Open() fonksiyonu çağrıldıktan sonra geçerli hale gelir ve sadece okunabilen bir üye değişkendir. Kullanıcı uygulamaları ile direkt olarak değiştirilmez.

 

            m_nFields: Veri kaynağındaki tablo içindeki alanların numarasını gösteren bir değişkeni ifade eder. UINT tipindedir.

 

            m_nDatabase: CDatabase sınıfını gösteren pointer türünde bir üye değişkendir.

 

            m_nParams: Veri kaynağının kayıtları içindeki veri üyelerinin numaralarını gösteren üye değişkendir. UINT tipindedir.

 

Üye fonksiyonlar altı gruba ayrılabilir:

 

1.      Tasarımcı, yokedici, açma ve kapatma fonksiyonları.

2.      Kayıt alanın niteliğini belirleyen fonksiyonlar.

3.      Kayıt alanı güncelleme fonksiyonları.

4.      Diğer kayıt fonksiyonları.

5.      Genel üye fonksiyonlar.

 

Tasarımcı, Yokedici, Açma ve Kapatma Fonksiyonları

 

            CRecordSet():

 

            CRecordSet(CDatabase* pDatabase);

 

            CRecord üye değişmezi bir CRecordSet nesnesidir. pDatabase parametresi, CDatabase pointerı yada NULL değerlerini gösterir.

 

~CRecordSet():

 

                ~CRecordSet;

 

            CRecordSet’e ait üye yok edici fonksiyondur. Otomatik olarak çağrılır.

 

            Open():

 

            virtual BOOL Open(UNIT nOpenType=snapshot, LPCSTR IpszSql=NULL, DWORD dwOptions=defaultOptions);

 

            Open() fonksiyonu bir kayıt açar, tabloları getirir veya kayıt sorgulama işlemlerini yerine getirir.

 

            nOpenType; dynaset, sanpshot ya da forwardOnly tiplerinden herhangi birine sahiptir.

 

            Close():

 

            virtual void Close();

 

            Kayıt alanını kapatır.

 

Kayıt Alanı Niteliğini Belirleyen Fonksiyonlar

 

            CanAppend():

 

            BOOL CanAppend const;

 

            Bu fonksiyon kayıt alanına yeni kayıt eklenebiliyorsa sıfır olmayan bir değer döndürür. Yeni kayıt ekleme AddNew() üye fonksiyonu ile sağlanır.

 

            CanRestart():

 

            BOOL CanRestart() const;

 

            Requery() üye fonksiyonun kayıt alanı sorgulamasını tekrar çağırması durumunda sıfır olmayan bir değer döndürür.

 

            CanUpdate():

 

            BOOL CanUpdate() const;

 

            Şayet kayıt alanın ekleme, güncelleme ya da kayıtları silme gibi özellikleri var ise sıfır olmayan bir değer döndürür.

 

            GetRecordCount():

 

            Long GetRecordCount() const;

 

            GetRecordCount(), kayıt alanındaki kayıtların numaralarını döndüren bir üye fonksiyonudur. Eğer kayıt yok ise 0 (sıfır) değerini döndürür.

 

            GetStatus():

 

            void GetStatus (CRecordSetStatus& rStatus) const;

 

            CRecordStatus yapısına bir pointer atar. Bu fonksiyon bir değer döndürmez.

 

            CRecordStatus {

                               Long m_lCurrentRecord;

                               BOOL m_bRecordCountFinal;

};

 

            m_lCurrentRecord değişkeni, kayıt alanındaki kayıtların numaralarını kapsayan long integer türü bir değişkendir.

 

            m_bRecordCountFinal değişkeni, CRecordSet kayıt alanındaki toplam kayıt sayısına sahip olduğunda sıfır olmayan herhangi bir değer kapsar.

 

            GetTableName():

 

            Const CString& GetTableName() const;

 

            Open() fonksiyonundan sonra çağrılmak zorundadır. Tablo ismini döndüren fonksiyondur.

 

            GetSQL():

 

            const CString& GetSQL() const;

 

SQL kullanılarak kayıt alanından seçilen kayıtları alıp getiren bir üye fonksiyondur.

 

            IsOpen():

 

            BOOL IsOpen const;

 

            Kayıt alanı açık ise sıfırdan başka bir değeri geri döndürür. GetTableName() ve GetSQL() gibi fonksiyon çağrımlarında kullanılan yararlı bir üye fonksiyondur.

 

 

 

            IsBOF():

 

            BOOL IsBOF() const;

 

            Eğer kayıt kümesi birinci kayıta konumlanırsa sıfırdan başka bir değer döndürür.

 

            IsEOF();

 

            BOOL IsEOF() const;

 

            Kayıt kümesi son kayıta konumlanırsa sıfırdan başka bir değer döndürür.

 

            IsDeleted():

 

            BOOL IsDeleted() const;

 

            Eğer geçerli olan kayıt silindi ise sıfırdan farklı bir değer döndürür.

 

Kayıt Alanı Güncelleme Fonksiyonları

 

            AddNew():

 

            void AddNew();

 

            AddNew() fonksiyonu, CRecordSet nesnesini yeni kayıt eklemek için hazırlar.

 

            Delete():

 

            BOOL Delete();

 

            Geçerli kayıtları kayıt alanından silmek için kullanılan üye fonksiyondur.

 

            Edit():

 

            void Edit();

 

            Kayıt yazmak için kullanılan fonksiyondur. Edit() fonksiyonu ile değişkenler değiştirilir sonra Update() fonksiyonu ile değişiklikler kayıt alanına eklenirler.

 

            Update():

 

            BOOL Update();

 

            AddNew() ya da Edit() fonksiyonlarından sonra çağrılır.

 

Kayıt Alanı Akış Fonksiyonları

 

            Move():

 

            virtual void Move (long lRows);

            Bir yada daha çok kayıtın aktarımı için kullanılır. İleri doğru aktarım için lRows parametresi pozitif değerlidir. Geriye doğru aktarım için lRows parametresi negatif değere sahiptir.

 

            MoveFirst():

 

            void MoveFirst();

 

            Kayıt alanındaki birinci kayıta aktarmak için kullanılır. Şayet kayıt alanında herhangi bir kayıt yok ise bu fonksiyon çağrılmaz.

 

            MoveLast():

 

            void MoveLast();

 

            Kayıt alanındaki en son kayıta aktarmak için kullanılır.

 

            MoveNext():

 

            void MoveNext();

 

            Bir kayıttan sonraki kayıta aktarmak için kullanılan fonksyondur.

 

Diğer Bazı Kayıt Alanı Fonksiyonları:

 

            SetFieldNull():

 

            void SetFieldNull (void* pv, BOOL bdrity=TRUE);

 

            Alan silmek, alanı boş hale getirmek için kullanılan fonksiyondur. Eğer pv parametresi NULL ise bütün alanlar boştur.

 

Genel Üye Fonksiyonlar

 

            DoFieldsExchange():

 

            virtual void DoFieldExchange(CfieldExchange* pFX)=0;

 

            Geçerli kayıt ile her sütunun bilgilerini tutan sınıf üye değişkenlerinin arasında transfer yapmak için kullanılır.

 

            GetDefaultConnect();

 

            virtual CString GetDefaultConnect();

 

            Geçerli bağlantı string’ini geri döndürür.

 

            GetDefaultSQL();

 

            virtual CString GetDefaultSQL()=0;

 

            Geçerli SQL string’ini çalıştırmak için kullanılır.

 

CRecordView Sınıfı

 

            CRecordView():

 

            CRecordView (LPCSTR lpszTemplateName);

                CrecordView (UINT nIDTemplate);

 

        Default olan yapıcı sınıfı dialog box template ismine yada bir dialog box template belirleyicisine ihtiyaç duyar. Dialog box template bulunamazsa CrecordView() fonksiyonu başarısız olur.

 

Bir Yanıt to “Visual C++ ile Veritabanı (BÖLÜM 4)”

  1. okipuki Ocak 30, 2009 10:15 am #

    faydalı olur inş

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Log Out / Değiştir )

Connecting to %s