Home Map Index Search News Archives Links About LF
[Top Bar]
[Bottom Bar]
[Photo of the Author]
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.

Yazara yaz�n

��indekiler:
Giri�
Motivasyon
M4
Nas�l �al���r
Kullan�c�dan CGI'a veri aktar�m�
Y�reye�ekim

G�rsel Sanalortamdan Veritaban�na PG2CGI Giri�i

�eviri: G�rkem �evik

[Ilustration]

�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.


Giri�

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.

Motivasyon

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:

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

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:

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.

D�zg�n Anlat�mlar:

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:

PG2CGI, kullan�lacak bi�imlendirme kural�n� do�rularken, d�zg�n anlat�mlar� kullan�r.

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.

Nas�l �al���r?

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:

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.

Kullan�c�daki Bilgi CGI'a Nas�l Ula��r?

�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:

`NAME=JOSE&FAMNAME1=DE+LA+FUENTE&FAMNAME2=LOPEZ'

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";
}

/usr/local/etc/httpd/plantillas_m4/avisos.m4
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>
  <BODY BGCOLOR="#ffffff">
    <CENTER>
      <H1>AVISOS A LOS NAVEGANTES QUE PASAN POR SLUG</h1>
    </center>
    <B>Nota:</b> Esta secci&oacute;n ha sido creada para dar a conocer
    cualquier noticia de inter&eacute;s relacionada con
    <A HREF="http://slug.ctv.es/">SLUG</a>,
    <A HREF="http://LuCAS.ctv.es/">LuCAS</a>,
    <A HREF="http://www.HispaLinux.ctv.es/">HispaLinux</a>
    y en general, cualquier servicio prestado por <B>slug.ctv.es</b>.<p>
    <CENTER><HR WIDTH=100></center>
ifelse(PGRES_RESULTSTATUS, <<<PGRES_TUPLES_OK>>>,<<<dnl
ifelse(PGRES_NTUPLES, 0,<<<dnl

      <!-- la tabla est\xe1 vac\xeda -->
      No hay avisos.<p>

>>>,<<<dnl /* PGRES_NTUPLES != 0 )( */
      <CENTER>
        <!-- contenido de la tabla -->
        <TABLE>
          <TR>
            <TH></th>
            <TH ALIGN="LEFT">Fecha-Hora&nbsp;</th>
            <TH ALIGN="LEFT">Asunto&nbsp;</th>
          </tr>

for(<<<i>>>,0,eval(PGRES_NTUPLES-1),<<<dnl
          <TR>
            <TD>
              <A HREF="/cgi-bin/pg2cgi/avisos/cell(i,0)">
                <IMG SRC="/icons/burst.gif">
              </a>
            </td>
            <TD><B>cell(i,1)&nbsp;</b></td>
            <TD>cell(i,2)&nbsp;</td>
          </tr>
>>>)dnl /* for */

        </table>
      </center>

>>>)dnl /* PGRES_NTUPLES */

>>>,<<<dnl /* ifelse PGRES_RESULTSTATUS )(*/

      Error en el resultado: <B>PGRES_RESULTSTATUS</b><BR>
      Mensaje del servidor: PGRES_ERRORMSG<P>

>>>)dnl

      <CENTER><HR WIDTH=100></center>
      <FONT SIZE=-2>
        <A HREF="mailto:WEBMASTER?subject=TABLON DE ANUNCIOS"><CODE>WEBMASTER</code></a>
      </font>
  </body>
</html>


/usr/local/etc/httpd/plantillas_m4/avisos_oid.m4
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>
  <BODY BGCOLOR="#ffffff">
    <CENTER>
      <H1>AVISO OID</h1>
    </center>
    <CENTER><HR WIDTH=100></center>

ifelse(PGRES_RESULTSTATUS, <<<PGRES_TUPLES_OK>>>,<<<dnl
ifelse(PGRES_NTUPLES, 0,<<<dnl

      <!-- la tabla est\xe1 vac\xeda -->
      No existe el aviso OID, o ha caducado.<p>

>>>,<<<dnl /* PGRES_NTUPLES != 0 )( */
      <CENTER>
        <!-- contenido de la tabla -->
        <TABLE>
          <TR VALIGN="BASELINE">
            <TD ALIGN="RIGHT" NOWRAP><font color="#808000"><B>Fecha de entrada:</b></font> </td>
            <TD width="80%">cell(0,1)</td>
          </tr><TR VALIGN="BASELINE">
            <TD ALIGN="RIGHT" NOWRAP><font color="#808000"><B>Fecha &uacute;ltima modif:</b></font> </td>
            <TD>cell(0,4)</td>
          </tr><TR VALIGN="BASELINE">
            <TD ALIGN="RIGHT" NOWRAP><font color="#808000"><B>Fecha eliminaci&oacute;n:</b></font> </td>
            <TD WIDTH=*>cell(0,5)</td>
          </tr><TR VALIGN="BASELINE">
            <TD ALIGN="RIGHT" NOWRAP><font color="#808000"><B>Autor:</b></font> </td>
            <TD><font size=+1><a href="mailto:cell(0,6)?subject=[TABLON-SLUG] cell(0,2)">cell(0,6)</a></font></td>
          </tr><TR VALIGN="BASELINE">
            <TD ALIGN="RIGHT" NOWRAP><font color="#808000"><B>Asunto:</b></font> </td>
            <TD><font size=+1><B>cell(0,2)<B></font></td>
          </tr><TR>
            <TD COLSPAN=2 BGCOLOR="#c0ffff"><font color="#404040">cell(0,3)</font></td>
          </tr>
        </table>
      </center>

>>>)dnl /* PGRES_NTUPLES */

>>>,<<<dnl /* ifelse PGRES_RESULTSTATUS )(*/

      Error en el resultado: <B>PGRES_RESULTSTATUS</b><BR>
      Mensaje del servidor: PGRES_ERRORMSG<P>

>>>)dnl

      <CENTER><HR WIDTH=100></center>
      <FONT SIZE=-2>
        <A HREF="mailto:WEBMASTER?subject=TABLON DE ANUNCIOS"><CODE>WEBMASTER</code></a>
      </font>
  </body>
</html>

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.gz
http://slug.ctv.es/~luis/utils/pg2cgi.README
ftp://slug.ctv.es/pub/slug/luis/pg2cgi.tar.gz
ftp://slug.ctv.es/pub/slug/luis/pg2cgi.README

Miguel 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