TclMySQL kütüphanesine giriş

ArticleCategory: Software Development

SoftwareDevelopment

AuthorImage:

[Photo of the Author]

TranslationInfo:

original in en Diego Alberto Arias Prad 

en to tr Okan Arı

AboutTheAuthor:

Ben Lugo İspanya'da bir Telekominikasyon mühendisiyim. Linux'u kullanmaya ne zaman başladığımı kesin olarak hatırlayamıyorum, 1995 ya da 1996 yılındaydı. Ondan önce bir Microsoft Windows kullanıcısıydım ve Linux'un varlığından haberdar değildim. İlk kez Linux'u üniversitede bir bilgisayarda gördüm. Bana çok ilgi çekici göründü ve hemen evimdeki bilgisayarıma kurdum; ilk dağıtımım Slackware'dı.

Bu yıllarda başka Linux dağıtımları, bazı BSD "flavours" ları, Java ve Tcl gibi programlama dilleri, veritabanı, web ve uygulama sunucuları kullanarak çok eğlendim. Linux benim için sadece oyuncak olmadı, Telefónica I+D'de çalışırken Linux kullanma şansı buldum.

Abstract:

Bu makalede nasıl MySQLTcl kuracağınızı ve kullanacağınızı öğreneceksiniz, Tcl kütüphanesi Tcl betiklerinden MySQL veritabanı sunucusuna SQL sorguları göndermenizi sağlar (select, insert, delete...). Kullanılan Tcl, MySQL sunucu ve MySQLTcl kütüphanesi versiyonları şunladır : 8.4.2, 4.0.15 ve 2.40.

Tcl Tool Command Language kelimelerinin baş harfleridir ve John Ousterhout [1] tarafından geliştirilmitşir. Tcl aslında iki şeydir: Bir betik dili ve bir yorumlayıcıdır. Tcl bir yapısal programlama dilidir ve 3 temel veri yapısı kullanır: Katar(strings), liste(lists) ve dizi(arrays). Tcl düzenli ifadeler(regular expressions [2]), üçüncü parti Tcl genişleme kütüphaneleri ve Tk, Tcl'de grafik uygulamalar geliştirmeye yarayan alet çantası(toolkit) özelliklerini içerir.

MySQL açık kaynak dünyasının popüler veritabanı sunucusudur, sanırım daha fazla bir tanıtım yapmaya gerek yok.

MySQLTcl Tcl betiğinden Mysql veritabanı sunucusuna sorgu göndermeye yarayan bir kütüphanedir. Tcl kütüphanesinin şu anki sağlayıcıları Paolo Brutti (Paolo.Bruti at tlsoft.it), Tobias Ritzau (tobri at ida.liu.se) ve Artur Trzewick (mail at xdobry.de)'dir..

ArticleIllustration:

MySQLTcl

ArticleBody:

MySQLTcl kütüphanesi kurulumu

Eğer sizin Linux dağıtımınız ya da *BSD işletim sisteminiz paket kurulumunu destekliyorsa (RPM veya DEB gibi) veya portları destekliyorsa (örneğin Crux Linux veya FreeBSD), bu yöntemlerden birini kullanabilir ve bu bölümü atlayabilirsiniz..

Eğer siz de "elle" kurma yöntemini tercih ediyorsanız aşağıda benim uyguladığım yöntem anlatılmıştır. Anlatılanlar bir yol gösterici olarak görülmelidir, adım adım kurulum rehberi olarak değil. Linux Mandrake dağıtımı (versiyon 9.2), bash ile:
$ ./configure --with-mysql-lib=/usr/lib
$ make
$ make install
"configure" adımında problem olursa, hata bilgisi problemin çözümü için bize ip ucu vermektedir. Genellikle problem, configure betiğinin belli dizin ya da dosyaları bulamamasıdır. Bu gibi durumlarda betik ile "oynayarak" doğru dizin ya da dosyaların parametrelerini betiği düzenleyerek belirtebilirsiniz. Başka bir örnek görelim. FreeBSD 5.0 ile bu opsiyonları kullanarak MySQLTcl kurulumu yaptım.
$ export CPP=/usr/bin/cpp
$ ./configure --with-tcl=/usr/lib/local/tcl8.3
 --with-tclinclude=/usr/local/include/tcl8.3
 --with-mysql-include=/usr/local/include/mysql
 --with-mysql-lib=/usr/local/lib/mysql
$ make
$ make install
Not almış olmanız gerektiği gibi,bu ikinci örnekte versiyonlar şöyle, Tcl 8.3; MySQLTcl kütüphanesi 2.15 ve MySQL veritabanı sunucusu 3.23.54.

Tcl Temelleri

Bu bölümde, Tcl programlama yapamayan ama bu makaleye ilgi duyanlar için Tcl Temelleri'ne giriş yapacağım. Siz zaten bir Tcl programcısı iseniz bu bölümü atlayabilirsiniz.

Bu örneği (ve tabi ki devam eden diğer örnekleri) Tcl shell (tclsh) kullanarak yeniden üretebilirsiniz.

Değişkenler. Komut ve değişken değiştirme (Command and variable substitution).

Tcl değişkenleri set konutu ile yaratıldı, bazı örnekler:
% set address {Edison Avenue, 83}
Edison Avenue, 83
% set zip_code 48631
48631
Bu iki örnekte, adları address ve zip_code olan iki değişken yarattık. Bu değişkenler tarafından saklanan değerler sırasıyla Edison Avenue, 83 ve 48631 oldu; her iki değer de katar(string) yapısında. address değişkeni yaratılırken küme parantezi(curly braces) kullanıldı çünkü katar özel karakter(white spaces) içeriyor. Değişken değerleri yeniden set komutu ile gösterilebilir:

% set address
Edison Avenue, 83
% set zip_code
48631
Şu anda ekrana address değişkeninin değerini yazdırmak istiyoruz. Bu puts komutu ile gerçekleştirilir:
% puts stdout [set address]
Edison Avenue, 83
stdout parametresi puts komutuna gönderildi. Bu parametre puts komutuna standart çıktıyı kullanmasını söyliyor ki bu bizim durumumuz için ekran. puts komutuna gönderilen ikinci parametre[set address]. Köşeli parantez içindeki komut Tcl yorumlayıcısı tarafından puts komutundan daha önce yorumlanacaktır; buna komut değiştirme (command substitution) diyoruz. (Çevirenin notu : Bu isimlendirmeyi tam çeviremediğim için İngilizce olarak kullanacağım bundan sonra). Aynı olay farklı bir yolla da yapılabilir:
% puts stdout $address
Edison Avenue, 83
Bu örnekte yaptığımıza ise değişken değiştirme (variable substitution) diyoruz. (Çevirenin notu : Bu isimlendirmeyi bundan sonra İngilizce olarak kullanacağım): değişken adından önceki $ karakteri variable substitution olmasını sağlıyor.

Dana önceki örneğimizde küme parantezi kullanarak özel karakterlerin katar olarak gruplandırılabildiğini gördük. Diğer gruplandırma yöntemi çift tırnak (karakter ") kullanmaktır.. Buna rağmen bu iki yöntem birebir aynı şekilde çalışmaz. Bir örnek görelim:
% puts stdout "the zip code is [set address]"
the zip code is 48631
% puts stdout "the zip code is $address"
the zip code is 48631
% puts stdout {the zip code is [set address]}
the zip code is [set address]
% puts stdout {the zip code is $address}
the zip code is $address
Bu örnekte şunu görüyoruz, eğer gruplandırmak için küme parantezi kullanılırsa command ve variable substitution gerçekleşmiyor ama çift tırnak kullanılırsa gerçekleşiyor.

Değişkenler unset komutu ile silinebilir:
% unset address
% set address
can't read "address": no such variable
% unset zip_code
% set zip_code
can't read "zip_code": no such variable

Tcl Katarları(Strings)

Katar veri yapısı üç temel Tcl vei yapısından birisidir. Bir katar karakterler kümesidir. Katar set komutu ile yaratılır.

% set surname Westmoreland
Westmoreland
% set number 46.625
46.625
Her iki surname ve number değişkenleri katardır. Katarlar string komutu ile yönetilebilirler, string komutunun genel kullanım yapısı(syntax) şöyledir : string işlem katardeğeri diğerargümanlar (string operation stringvalue otherargs).Bu kullanımı nasıl yapacağımızı anlatan bir kaç örnek görelim:
% string length $surname
12
% set surname [string range $surname 0 3]
West
% puts stdout $surname
West
% string tolower $surname
west
Java veya Pascal'ın aksine, Tcl bir strong-typed programlama dili değildir.(Çevirenin notu : terimi İngilizce kullanacağım.) Aşağıdaki örnek bunu göstermektedir.:
% set number [expr $number + 24.5]
70.125
% string range $number 2 5
.125
expr komutu ile, number değişkeninin 24.5 arttırıldı. Bundan sonra string komutu ile number değişkenine katar gibi işlem yaptırıldı ve son dört karakteri görünüyor.

Önceki örneklerde gösterilenden daha fazla string işlemleri mümkün..

Tcl Listeleri(Lists)

Tcl listeleri katarların özel durumudur, listenin elemanları özel karakterler ile ayrılmıştır ve özel bir yorumlamaya tabi tutulurlar.

% set friends_list {Fany John Lisa Jack Michael}
Fany John Lisa Jack Michael
% set friends_list [string tolower $friends_list]
fany john lisa jack michael
% set friends_list
fany john lisa jack michael
Liste işlemesine izin veren bir kaç Tcl komutu aşağıdadır. Bazı örnekler görelim.
% lindex 2 $friends_list
lisa
% lrange $friends_list 2 4
lisa jack michael
% set friends_list [lsort -ascii $friends_list]
fany jack john lisa michael
% set friends_list
fany jack john lisa michael
% set friends_list [linsert $friends_list 2 Peter]
fany jack Peter john lisa michael
% string toupper $friends_list
FANY JACK PETER JOHN LISA MICHAEL
Son örnek listelerin ve katarların aynı veri yapısında olduklarını gösterir.

Tcl Diziler(Arrays)

Dizi katar değeri ile indekslenmiş bir liste olarak görülebilir. Biz dizi örnekte görüldüğü şekilde yaratılır:

% set phone_numbers(fany) 629
629
% set phone_numbers(michael) 513
513
% set phone_numbers(john) 286
286
Dizi değerleri set command ve variable substitution kullanılarak gösterilebilir; daha önceki örnekte gördüğümüz gibi katar değeri indeksi parantez ile ayrılır.
% set $phone_numers(michael)
513
array komutu dizi değişkeni hakkında bilgi döndürür. Bu komutun yapabileceği hakkında bir kaç örnek görelim:
% array size phone_numbers
3
% array names phone_numbers
fany john michael

Veritabanı bağlantısı

Tcl betikten veritabanına bir sorgu göndermeden önce veritabanı sunucusuna bağlantı kurmak gereklidir. Bu bölümde nasıl bağlantı kuracağımızı ve bağlantı problemlerini nasıl aşacağımızı göreceğiz..

Bir veritabanı bağlantısı oluşturmak

Tcl betikğin MySQL veritabanı sunucusuna nasıl bağlandığını gösteren bir örnek görelim.

0:  #!/usr/bin/tclsh8.4
1: 
2:  package require mysqltcl
3:  global mysqlstatus
4: 
5:  set port {3306}
6:  set host {127.0.0.1}
7:  set user {john_smith}
8:  set password {jsmith_password}
9: 
10: set mysql_handler [mysqlconnect -host $host
    -port $port -user $user -password $password]
11: 
12: mysqlclose $mysql_handler

Lütfen sol taraftaki sütunun Tcl betikğin bir parçaşı olmadığını yalnızca gösterimi kolaylaştırmak için olduğunu untmalayım. Ayrıca kullandığınız Linux datığımında göre satır 0 daki bölümün Tcl shell'ini gösterecek path olarak ayarlanması gerektiği unutmayalım.

Satır 0 bu dosyanın bir Tcl betiği olduğunu ve Tcl yorumlayıcısının neredebulunacağını anlatır.

2. satır Tcl yorumlayıcısına komutları işlerken MySQLTcl kütüphanesinde aramasını söyler. Örneğin, 10. satırda mysqlconnect komutunu görüyoruz. Eğer 2. sanırdaki kod olmasaydı Tcl yorumlayıcısı mysqlconnect komutunu işlerken bize komut bulunamadı hatası verecekti.

5. ve 6. satırlarda Tcl betiğin bağlanmaya çalışacağı port ve host bilgileri ayarlanıyor. Bu betikte 3306 numaralı port (ki MySQL sunucusu varsayılan olarak bu portu kullanmaktadır) ve aynı makine host olarak ayarlanmış.

7. ve 8. satırlarda veritabanı kullanıcı adı ve parolası ayarlanıyor.

10. satırda veritabanı bağlantısı sağlanıyor. mysqlconnect komutunun çıktısı ismini bizim verdiğimiz mysql_handler değişkeninde saklanıyor. Bu değişken veritabanı bağlantısının tutucusu(handler) olacaktır. Bu tutucu veritabanında sorgulama yapmak ve aynı zamanda bağlantıyı sonlandırmak için kullanılacaktır, bunu 12. satırda görebiliyoruz.

Hata tutulması

Bir önceki bölümde betiğin 3. satırı anlatmadık. Şimdi onu anlatıyoruz.

MySQLTcl kütüphanesi komutları hataları tutabilmektedir. Eğer hata yakalanamazsa, betik duracaktır ve bu durum bizi ilgilendirebilir ya da ilgilendirmeyebilir. Bu yöntemle betiği biraz değiştirelim.

10: if [catch {mysqlconnect -host $host -port $port
    -user $user -password $password} mysql_handler] {
11:     puts stderr {error, the database connection could not be established}
12:     exit
13: } else {
14:     mysqlclose mysql_handler
15: }
Eğer set mysql_handler [mysqlconnect -host $host... komutu bir hata tutarsa, bu hatayı catch komutu yakalar. Eğer küme parantezi içindeki çalıştırılan komut bir hata tutarsa catch komutu 1 döndürür aksi halde 0 döndürecektir. mysql_handler değişkeni küme parantezi içerisindeki komutun çıktısını saklamaktadır.

Eğer bir hata varsa standart hata çıktısına (stderr) (ki bizim durumumuzda bu ekrandır) bir mesaj yazılır. Veritabanına bağlanırken oluşacak hatanın bir çok nedeni olabilir, yanlış parola, yanlış port numarası ya da host adı gibi... Bu durumda "bir hata oluştu" gibi basit bir hata mesajı almaktansa daha fazla bilgi edinmek çok daha yararlı olacaktır.
"there was an error" can be useful.

3. satırda, mysqlstatus değişkeni global (Çevirenin notu : global tanımını olduğu gibi kullanacağım.) olarak tanımlandı. Global değişken demek, Tcl betiğin her parçasından erişilebilen demektir; bu Tcl değişken alanı(scope) ilgilidir ve bu makalenin konusu değildir. MySQLTcl kütüphanesi mysqlstatus adında bir global dizi yaratır ve kullanımını sağlar. Bu dizi şu elemanlara sahiptir:

eleman anlamı
code Eğer hata yoksa mysqlstatus(code) sıfırdır, ama hata varsa mysqlstatus(code) MySQL sunucusunun hata numarasına eşittir. Eğer oluşan hata MySQL sunucusu tarafından yaratılmamışsa değer -1 olur.

mysqlstatus(code) değişkeninin değeri herhangi bir MySQLTcl kütüphanesi komutu çalıştırıldığında güncellenir.
command Son MySQLTcl kütüphanesi komutu, mysqlstatus(command)'de saklanan hatayı gösterir.

mysqlstatus(command)'ın değeri her başarısız MySQLTcl komutu sonrasından güncellenir, yani mysqlstatus(command)'ın değeri başarılı MySQLTcl komutu sonrasında güncellenmez.
message mysqltcl(message)'ın değeri her başarısız MySQLTcl komutu sonrasında içerisinde hata mesajı bulunduran bir katar ile güncellenir. mysqlstatus(command)'u gibi mysqlstatus(message)'un içeriği başarılı MySQLTcl komutları sonrasında güncellenmez.

Global dizi elemanları arasında, hata tutma ile ilgisi olmayan, mysqlstatus adında başka bir eleman vardır:

eleman anlamı
nullvalue SQL sorgusu sonuçları gösterilirken boş değeri temsil eden katar değeridir. Varsayılan olarak boş katar kullanılır, musqlstatus(nullvalue) herhangi başka bir katar değerine ayarlanabilir.

Global dizi mysqlstatus kullanrak daha öceki kodu tekrar yazarsak, bu şekilde veritanabını bağlantısı sağlanırken oluşacak hatalar hakkında daha çok bilgi sahibi olabiliriz.
10: catch {mysqlconnect -host $host -port $port
    -user $user -password $password} mysql_handler
11: if {$mysqltatus(code) != 0} {
12:     puts stderr $mysqlstatus(message)
13: } else {
14:     mysqlclose mysql_handler
15: }

Belli ki, global dizi mysqlstatus veritabanı bağlantısı kurulurken oluşacak hataları daha fazla göstermek için kullanılabiliir.

Temel MySQLTcl kütüphanesi komutları

Bu bölümde bir çok temel MySQLTcl kütüphanesi komutları bulunacaktır ve ben bunların nasıl kullanuılacağını bazı örnekler ile göstereceğim. Tüm komutlar hakkında bilgi için MySQLTcl kütüphanesi kullanım kılavuuzu(man) sayfalarına bakınız.
Bu bölümde işlenecek komutlar aşağıdaki tabloda gösterilmiştir. Parametrelerin altı çizilmiştir. Eğer bir parametre iki ? arasında ise, bu parametrenin opsiyonel olduğunu gösterir, | karakteri ise "veya" anlamındadır.
komut kısa açıklama
mysqlconnect ?option value ...? veritabanına bağlanır; diğer mysqltcl komutlarınca kullanılacak bir tutucu(handler) döndürür.
mysqluse handle dbname MySQL tutucusunu belirli bir veritabanı ile ilişkilendirir.
mysqsel handle sql_statement ?-list | -flatlist? veritabanına SELECT sorgusu gönderir.
mysqlexec handle sql_statement veritabanına non-SELECT ifadesi gönderir.
mysqlclose handle veritanabı bağlantısını kapatır.

mysqlconnect

Bu komut "Veritabanı bağlantısı" bölümüde zaten anlatıldı. Bu komut ekstra bir parametre kabul eder, daha önce gösterilmeyen:-db. Bu parametre -db ile, ileride kullanılarak SQL ifadeleri için veritabanı kesinleştirilir. Bir örnek görelim:

% set mysql_handler [mysqlconnect -h 127.0.0.1 -p 3306 \\
  -user john_smith -password jsmith_password -db jsmith_database]
MySQLTcl komutlarının kullanacağı mysql_handler veritabanı tutacağı(handler)nın "hedef" veritanabı jsmith_database olarak adlandırıldı.
(\\ karakterleri komutların bir parçası değldir, anların anlamı komut aşağıdaki satırda devam etmektedir..)

mysqluse

Bu komut MySQL tutacağı ile ilişkili veritanabının değiştirilmesine izin verir.

mysqlsel

Bu komut MySQL tutacağı ile ilişkilendirilmiş veritabanına SQL select ifadesi göderir. Eğer sql_statement parametresi bir SQL select ifadesi değil ise bir hata oluşacaktır.

list veya flat_list olabilen bir üçüncü opsiyonel parametre vardır, Bu parametrenin komutun çıktısını nasıl etkilediğini gösteren bir örnek görelim. MySQL tutucusu ile ilişkili veirtabanında people adında bir tablo olduğunu ve yapısının aşağıdaki gibi olduğunu kabul edelim:

id first_name last_ name phone
26 Karl Bauer 8245
47 James Brooks 1093
61 Roberto Castro Portela 6507

Veritanabına SQL select ifadesi göndermek için mysqlsel komutu kullandık:

% mysqlsel $mysql_handler {select first_name, last_name from people order by id asc} -list
{Karl Bauer} {James Brooks} {Roberto {Castro Portela}}
% mysqlsel $mysql_handler {select first_name, last_name from people order by id asc} -flatlist
Karl Bauer James Brooks Roberto {Castro Portela}
Birinci örnekte (-list parameter), komut elemanları liste olan bir liste döndürüyor. İkinci örnekte (-flatlist parameter), komut elemanları concatenate edilmiş tek bir liste döndürüyor.

Eğer mysqlsel komutu üçüncü bir parametre almazsa ne olur? Bu durumda, mysqlsel komutunun çıktsı sorgu tarafından döndürülen satır sayısı olacaktır.
% mysqlsel $mysql_handler {select first_name, last_name from people order by id asc}
3

mysqlexec

Bu komut MySQL tutacağı ile ilişkilendirilmiş veritabanına SQL non-select ifadesi göderir. Eğer sql_statement parametresi bir SQL select ifadesi ise bir hata oluşacaktır ama hiçbirşey olmayacaktır.

Daha önceki bölümde gösterilen bir örneği ele alalım:

% mysqlexec $mysql_handler {delete from people where id=26}
1
% mysqlsel $mysql_handler {select first_name, last_name, phone from people order by id asc} -list
{James Brooks 1093} {Roberto {Castro Portela} 6507}
% mysqlexec $mysql_handler \\
  {insert into people (id, first_name, last_name, phone) values (58, "Carla", "di Bella", 8925)}
1
% mysqlsel $mysql_handler {select first_name, last_name, phone from people order by id asc} -list
{James Brooks 1093} {Carla {di Bella} 8925} {Roberto {Castro Portela} 6507}
Elbette delete veya insert harici diğer SQL sorguları da bu komu tile gönderilebilir. Öğrneğin satır güncellenebilir (update):
% mysqlexec $mysql_handler {update people set phone=3749 where first_name="James"}
1
% mysqlsel $mysql_handler {select first_name, last_name, phone from people order by id asc} -list
{James Brooks 3749} {Carla {di Bella} 8925} {Roberto {Castro Portela} 6507}
Eğer ifade başarılı bir şekilde işlendiyse, mysqlexec komutu veritabanına gönderilen SQL non-select ifadesince etkilenen satır sayısını döndürür.

mysqlclose

Daha önce gördüğümüz gibi, mysqlclose komutu veritanbanı bağlantısını kapatır. Bu komuta parametre olarak hnagi bağlantıyı kapatmak istiyorsak onun MySQL tutamağını verebiliriz.

Diğer MySQLTcl kütüphanesi komutları

MySQLTcl kütüphanesi burada gösterilen 5 komuttan daha çok komuta sahiptir. Bu komutlar veritabanı hakkında bilgi edinmeye, escaping string'e izin verir, bunlar sorgu oluşturmaya ve iç içe geçmiş sorgular oluşturmaya uygundur... İyi bir kaynak, MySQLTcl kütüphanesinin kurulumunun bir parçası olan MySQLTcl kullanım kılavuzu(man) sayfalarıdır.

Kaynaklar

[1] a slightly skeptical view on John K. Ousterhout and Tcl:
http://www.softpanorama.org/People/Ousterhout/index.shtml

[2] a tutorial on Tcl regular expressions:
http://www.mapfree.com/sbf/tcl/book/select/Html/7.html

TclTutor is a free and interactive application for learning Tcl:
http://www.msen.com/~clif/TclTutor.html

MySQL documentation, in various formats (HTML, PDF...):
http://www.mysql.com/documentation/index.html