Luis Colorado Yazar Hakkında: Luis Colorado UNIX sistemleri ve Telefónica Sistemas S.A. için Internet erişim yönetmeni olarak İspanya'da calışmaktadır. Universidad Complutense of Madrid'in Fizik bölümünü bitirmiş olup çeşitli açık kaynak UNIX kullandırımları (utility) olusturmuştur. İçindekiler:Giriş Motivasyon M4 Nasıl çalışır Kullanıcıdan CGI'a veri aktarımı Yöreyeçekim |
Özet:
HTML sayfalarından veritabanı girişini sağlayan yeni bir program
betimliyoruz. Programın tasarım amaçları veri girişini denetleme,
düzenlemedeki esneklik ve biçimden bağımsızlıktı. Bu program son 12
ay boyunca Linux Journal ve
LinuxFocus(www.linuxfocus.org)
dergilerinde okuduğum M4 ile ilgili pekçok yazı sonucu kafamda
oluşan fikirlerle sonuçlanmıştır.
Bu yazı görselerişim'den veritabanı girişini sağlayacak paketi oluşturmama neden olan düşünce ve akıl yürütmeleri anlatmaktadır. PG2CGI paketi hakkında bir elyordamı yazmak eğiliminde değildim (bir yolgösteren kaynağı zaten yazılımın dağıtımında içerilmektedir, bu paket için URL daha sonra verilecektir), aslında amacım kısa bir tanıtım yapmak ve okuyucuları bunu kullanmak ve geribeslemelerini göndermek için iteklemektir.
Bu programı Linux Journal ve LinuxFocus'da yayınlanan M4'ün HTML kaynaklarını yönetme ile ilgili yazılara yanıt olarak yazdım. Bu yazılar M4'ün görsel sanalyöre sayfalarının bakımını ve dinamik içerik üretimini sağlayan bir araç olarak avantajlarını ve potansıyellerini kanıtlamaktadır.
Diğer taraftan sayısız görsel sanalyöre sunucusu ve veritabanlarının elde edilebilirliği ile iki çevrenin arasındaki arayüzlerin eksikliği çelişmektedir (bu arayüz uygulamalarının çoğu tecimseldir (ticari) ya da kotarılabilecek (handled) biçimlerle ilgili eksiklikleri bulunmaktadİr).
Aşağıdaki yazılım paketi verıtabanı ve görselerişim çevrelerini birleştirmektedir. Şu gereksinimleri karşılamak için düzenlenmiştir:
HTML'in sanalyöre gezginlerinde (browsers) görüntülenebilen kaynakyazıları biçimlendirim için bir biçimlendirme dili olduğu iyice bilinmektedir. İyi bir metin oluşturucunun ortak özelliği paragrafların düzeninde ve en sondaki dizgilenmiş (typeset) sayfadaki metin parçalarında güçlü bir denetime sahip olan metin düzenlemeyi sağlayan yaygın kabul gören bir dil olmasıdır. Çoğu biçimlendirici dilde daima, kaynakyazıda, tablolar, görüntüler vs. gibi koşturum sürecinde sayfa üzerinde dinamik olarak düzenlenebilen yüzer elemanları ele almayı sağlayan bır altyordamlar kümesi bulunmaktadır.
HTML'i ve verıtabanlarına arayüz görevi gören bildiğim çoğu yazılım HTML etiketlerinin genişleterek çıkış metnindeki bilgileri üretirler; o zaman bu yeni etiketler altyordam rolünü üstlenirler. Bu yaklaşımın ciddi sıkıntıları vardır: çoğu zaman doğal HTML etiketlerindeki elemanları ayırmak zorundayız ve bu büyük bır kısıtlamadır. Çoğu zaman bu kullandırımlar (utilities) varolan HTML etiketlerinde belirli bir etkiyi sağlamak icin yeni etiketler oluşturmak zorundadırlar. Benim programı M4'ü gerektiği yerde makroların yerdeğişimini başarmak için derinlemesine kullanır. Program herhangi bir biçimlendirilmiş metin oluşturmaz ve bu yüzden en son kullanılan çıkış metnı biçimlendirme dilinden bağımsızdır. Program sorgulama sonucu olarak makrolar kümesi oluşturmakta ve zamanla M4 üzerinde bu makrolar kümesini ve verilen bir HTML şablonunu kullanarak bir HTML kaynakyazısı oluşturur.
Burada sunulan kullandırım bu gerektirimleri (requirement) verimdeki küçük bir azalma karşılığında sağlamaktadır (çalıştırım sürecinde M4'ü birkaç kez çağırmalıdır) fakat çoğu zaman sonuçlar doyurucu olmaktadır (çoğu durumda veritabanı sorgulamasının HTML metinlerinin dinamik oluşturumundan daha uzun zaman aldığını hesaba katmak gereklidir).
M4 çok daha önceden oluşturulmuş bulunan bir makro üretici aygıttır. Bizim yazılımımız bu makro içlemcinin yoğun kullanımını gündeme getirir:
M4 gerçekte CGI (Genel Geçit Arayüzü, İngilizcesi: Common Gateway Interface) ve PostgreSQL veritabanı arasındaki bağlantıyı sağlamak için geliştirilmişti. Sonraları insanlar onun CGI dışında diğer arayüzlerde de genel olduğunun farkına vardılar (örneğin LDAP sunucusu ile Informix ve Oracle gibi diğer veritabanları arasında bir geçit oluşturabilmesi). Daha sonra arayüz bütün gerekli özellikleri birleştirilerek standartlaştırıldı ve PostgreSQL modülü yeni arayüze göre yeniden yazıldı. Şimdi programların diğer veritabanlarının işletmenleriyle bağlantısını sağlayan yeni sürücüler oluşturmak mümkündür. |
Makro işlemcinin yinelemeli kullanımı, GNU M4 özellikleri ile yaptığımız sınamaların doyurucu olmasına karşın, verimin azalması anlamına gelebilir.
Yazılımımız biçimlendirme kurallarının uygulanmasını doğrulamak için düzgün anlatımların (regular expressions) yoğun kullanımını gündeme getirmektedir. Düzgün anlatımlar basit karşılaştırmalara göre daha çok yeğlenmektedirler, çünkü bize daha fazla işlevsellik sağlamkatadırlar. Düzgün anlatımlar şu üstünlüklere de sahiptir:
|
Anlatımların sözdizimi ve düzgün anlatımlarda geçen sürücüler için veri incelenmesi tek bir düzgün anlatımda yan zincirlerin toplanması sayesinde kolayca yapılabilir.
Bir örnek: diyelim ki müşteri query_string'e bazı bılgıler girmek zorunda ve bu bılgıler şu söz dizimine uyacak:
FIELD=value
Bunun da ötesinde, query_string bu biçime uymalı ve katarda hiçbir ek bilgi olmamalı.
Bu sözdizimine uymayı zorlamak seçim kuralında aşağıdaki terimi yazarak kolayca başarılabilir:
QUERY_STRING: "^FIELD=[^&]*$";
Önceki satırlar sadece QUERY_STRING sözdizimine uyduğunda kuralın çağrılmasına izin verir. Sadece bu da değil, eğer tümcedeki değeri parantezler arasına alırsak, program karşı gelen değerin alınmasına izin verir:
QUERY_STRING: "^FIELD=([^&]*)$";İşlem sırasında program kaçış ardıllarını %xx formunda gezginde tanıtarak da gönderebilir.
Programın nasıl çalıştığını anlatma zamanı geldi. İlk başlatıldığında görselerişim sunucusu cevresinden değişkenleri alır ve bu değişkenlere göre kendisini biçimlendirir. Çevre değişkenleri programın bulmak zorunda olduğu şeylerdir: Peki ya istemciler? İstemlerin kökenleri nerede? İstemciler tarafından hangi tür bilgiler (MIME türü) destekleniyor? vs. PG2CGI sol tarafa dayalı olan kuralı kullanacak olan kuralı seçer. Aynı zamanda üç çeşit kural vardır:
QUERY_STRING: "^FIELD=([^&]*)$";
! HTTP_ADDRESS: "^194\.142\.12\.";(Bu örnek eğer istek 194.142.12.xxx'ten gelirse, kuralı geçersiz kılacaktır.)
[ QUERY_STRING: "USER=([^&]*)" ];Bu terim, eğer istemci sağlarsa, kullanıcının değerini geçirtmemizi sağlar, ama eğer istemci belirtmezse kuralı geçersiz saymaz.
Bütün bunlarla kuralları oluşturmaya başlayabiliriz. Daha sonra kural için geçerli bir değer bulacak olan bazı durumlar gruplayacağız. Bu durumlar küme parantezleri "{}" içinde yer alacak.
Bir kuralın sol ve sağ tarafları küme parantezleri "{}" ile sınırlandırılacak ve `->' ile ayrılacak.
Sağ taraf aynı sözdizimli durumları icermektedir: bir değişken adı, ':' karakteri, karakterler zinciri ve ';' sonuçlandırıcısı. Sağ taraftaki tüm durumlar değişkenlere atanacak M4 tarafından yerine getirilecek degerlerdir:
Diğer değişkenler ya şablon dosyası ile ya da karşı gelen sürücü ile kullanılabilir.
Çok kolay. Her kuralın sol tarafındaki terimlerin içindeki düzgün anlatımlardan oluşan gruplar değişkenlere çevrilir (bu yeni değişkenler için kullanılan adlar şu şekli alır: `term_<i>_match_<j>', burada <i> terimin kuraldaki sırasının sayısını göstermektedir (böylece ilk terim 1, ikinci bölüm 2, ... şeklinde olacaktır) ve <j> açıklayıcı tümcenin solundan itibaren sayarak grubun derecesini gösterir. Sonra query_string istemci tarafından geçilirse:
ve görsel sanalyörede belirtimi yapılan kural:
QUERY_STRING: "NAME=([^&]*)"; QUERY_STRING: "FAMNAME1=([^&]*)"; QUERY_STRING: "FAMNAME2=([^&]*)";sonuç:
term_0_match_0 <- "NAME=JOSE"; term_0_match_1 <- "JOSE"; term_1_match_0 <- "FAMNAME1=DE LA FUENTE"; (noticed the replacement of the + characters by ` ') term_1_match_1 <- "DE LA FUENTE"; term_2_match_0 <- "FAMNAME2=LOPEZ"; term_2_match_1 <- "LOPEZ";Sürücüler:
Bu makalede sürücülerin kullanımını anlatmayacağız, bütün bunlar PG2CGI 'ın dağıtımında içerilen kaynakyazılarda anlatılmıştır. İlgilenen okuyucular içerilen kaynak elyordamına bakabilirler.
Şu an sadece bir sürücü bulunmaktadır, o da POSTGRESQL veritabanının bağlantısı içindir. Yazar LDAP türünde veritabanları için yeni bir sürücü yazma planlamasında bulunmaktadır.
Bir Örnek:
Haydi, şimdi tam bir örnek vermek amacıyla kaynakları inceleyelim.
Duyurular tablosunu slug.ctv.es deki duyuruların veritabanından duyurular çizelgesini gözönüne alalım. ( AVISO A LOS NAVEGANTES bağlantısını izleyelim) Bu bir tablodan bireysel kayıtları incelemek veya tam bir liste yapmak için iki şablon kullanan çok basit bir örnektir. /etc/html2sql.cfg
{ PATH_INFO: "^/avisos/?$"; # PATH_INFO tarafından seçiliyor [SERVER_ADMIN: ".*"]; # SERVER_ADMIN'den bilgi alıyor. Seçmeli } -> { DRIVER: "POSTGRESQL"; PGTTY: "/dev/console"; # Konsola kayıtlar gönderir PGDATABASE: "postgres"; # Bir sorgu yaratıyoruz (OID'yi her zaman öylesine yazın ki # o şablon dosyasında bireysel kayıtlara bağlantı kurmak için # içeriden çalışsın) PGQUERY: "select oid,ct,titulo,texto,mt" " from avisos" " where (dt is NULL or dt > 'now')" " order by mt desc"; # Şablonu içeren dosya M4FILE: "/usr/local/etc/httpd/plantillas_m4/avisos.m4"; WEBMASTER: "term_1_match_0"; #TESTMODE: "TRUE"; } # Sonraki seçim kuralı, bilinen bir OID (birincil açkı) ile # duyuruyu (aviso)seçmeyi sağlamaktadır. Bilgi CGI'daki PATH_INFO # değişkeninde içerilir. { PATH_INFO: "^/avisos/([0-9]+)/?$"; SERVER_ADMIN: ".*"; } -> { DRIVER: "POSTGRESQL"; PGTTY: "/dev/console"; # önceden olduğu gibi kayıtları konsola yazar PGDATABASE: "postgres"; OID: "term_0_match_1"; # bir OID atar # Bir kez daha seçim önem kazanmaktadır. Bu kayıdı silmek için bir hiperlink # yazamak istediğimizde alanın başlangıcında OID içeririz. PGQUERY: "select oid,ct,titulo,texto,mt,dt,autor" " from avisos" " where (dt is NULL or dt > 'now') and oid=OID"; # Şimdi şablon değişmiş olmaktadır. M4FILE: "/usr/local/etc/httpd/plantillas_m4/avisos_oid.m4"; WEBMASTER: "term_1_match_0"; #TESTMODE: "TRUE"; } |
define(<<<for>>>, <<<dnl
ifelse(eval((<<<$2>>>) <= (<<<$3>>>)), 1, <<<define(<<<$1>>>,<<<$2>>>)$4<<<>>>dnl for(<<<$1>>>,eval(<<<$2>>>+1),<<<$3>>>, <<<$4>>>)dnl >>>)dnl >>>)dnl divert(0)dnl Mime-Version: 1.0 Content-type: text/html <HTML>
<!-- la tabla est\xe1 vac\xeda -->
>>>,<<<dnl /* PGRES_NTUPLES != 0 )( */
for(<<<i>>>,0,eval(PGRES_NTUPLES-1),<<<dnl
</table>
>>>)dnl /* PGRES_NTUPLES */ >>>,<<<dnl /* ifelse PGRES_RESULTSTATUS )(*/ Error en el resultado: <B>PGRES_RESULTSTATUS</b><BR>
>>>)dnl <CENTER><HR WIDTH=100></center>
|
divert(-1)
$Id: generic_list.m4,v 1.1 1998/07/06 17:13:33 luis Exp $ define(<<<cell>>>, <<<PGRES_CELL_$1_$2>>>) define(<<<field>>>, <<<PGRES_FNAME_$1>>>) define(<<<for>>>, <<<dnl ifelse(eval((<<<$2>>>) <= (<<<$3>>>)), 1, <<<define(<<<$1>>>,<<<$2>>>)$4<<<>>>dnl for(<<<$1>>>,eval(<<<$2>>>+1),<<<$3>>>, <<<$4>>>)dnl >>>)dnl >>>)dnl divert(0)dnl Mime-Version: 1.0 Content-type: text/html <HTML>
ifelse(PGRES_RESULTSTATUS, <<<PGRES_TUPLES_OK>>>,<<<dnl
<!-- la tabla est\xe1 vac\xeda -->
>>>,<<<dnl /* PGRES_NTUPLES != 0 )( */
>>>)dnl /* PGRES_NTUPLES */ >>>,<<<dnl /* ifelse PGRES_RESULTSTATUS )(*/ Error en el resultado: <B>PGRES_RESULTSTATUS</b><BR>
>>>)dnl <CENTER><HR WIDTH=100></center>
|
Sonuçlar bu URL'lardan görülebilir:
http://slug.ctv.es/cgi-bin/pg2cgi/avisos/
or
http://slug.ctv.es/cgi-bin/pg2cgi/avisos/20384
Yöreyeçekim
PG2CGI programı izleyen URL'lerden yöreyeçekilebilir :
http://slug.ctv.es/~luis/utils/pg2cgi.tar.gzMiguel A Sepulveda tarafından İngilizce'ye çevrilmiştir
Bu görsel sanalyörenin bakımını Miguel Ángel Sepúlveda
yapmaktadır © Luis Colorado 1998 LinuxFocus 1999 |