original in en Diego Alberto Arias Prad
en to nl Guus Snijders
Ik ben een telecommunicatie ingenieur in Lugo, Spanje. Ik kan me niet
precies herinneren wanneet ik ben begonnen met Linux te gebruiken, het
was in 1995 of 1996. Daarvoor was ik een Microsoft Windows gebruiker
en wist niet eens dat Linux bestond. De eerste keer dat ik Linux zag
draaien op een computer, was op de universiteit. Het zag er erg
interessant uit en al snel installeerde ik het op mijn computer thuis;
Ik herinner me dat mijn eerste Linux distro Slackware was.
In al deze jaren heb ik veel plezier gehad aan het gebruik van andere
Linux distros als ook enkele BSD "smaken", met het gebruik van
programmeertalen als Java of Tcl, met database, web en applicatie
servers... Linux betekende niet alleen plezier voor mij, ik had ook de
kans met Linux te werken toen ik werkte bij
Telefónica I+D.
Als je Linux distro of je *BSD besturingssysteem ondersteuning biedt
voor pakketten (zoals RPM of DEB bijvoorbeeld) of ports
(Crux Linux of
FreeBSD, bijvoorbeeld), kun je dit
pakket of ports systeem gebruiken om de MySQLTcl library te installeren
en deze sectie overslaan.
Als dit niet het geval is, of als je voorkeur geeft aan "met de hand"
installeren, kun je de stappen die ik heb gevolgd, gebruiken.
Deze regels moet je zien als een gids en niet als een
stap-voor-stap installatie handleiding. In een
Linux Mandrake distro
(versie 9.2), vanuit bash:
$ ./configure --with-mysql-lib=/usr/lib $ make $ make install |
$ 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 |
In deze sectie introduceren we een paar Tcl basis technieken voor die
lezers die wel in dit artikel zijn geïnteresseerd maar geen ervaring
hebben met Tcl. Als je al een Tcl programmeur bent, kun je deze sectie
overslaan.
Je kunt de voorbeelden in deze (en volgende) sectie reproduceren in de
Tcl shell (tclsh).
Tcl variabelen maak je met het commando set. Laten we een paar
voorbeelden bekijken:
% set address {Edison Avenue, 83} Edison Avenue, 83 % set zip_code 48631 48631 |
% set address Edison Avenue, 83 % set zip_code 48631Stel dat we de waarde van een variabele op het scherm willen afdrukken. Dit kun je doen met het commando puts:
% puts stdout [set address] Edison Avenue, 83De parameter stdout wordt meegegeven aan het puts commando. Deze parameter verteld het commando om af te drukken op de standaard uitvoer, in ons geval het scherm. De tweede parameter die aan het puts wordt meegeven is [set address]. De vierkante haken in de tweede parameter vertellen de Tcl interpreter dat de data binnen de haken een ander Tcl commando is, welke door de Tcl interpreter moet worden uitgevoerd voor het puts commando; dit wordt commando substitutie genoemd. Hetzelfde kan op een andere manier worden gedaan:
% puts stdout $address Edison Avenue, 83Wat we in dit voorbeeld gedaan hebben, wordt variabele substitie genoemd: het karakter $ voor de naam van de variabele zorgt ervoor dat de substitutie plaatsvindt.
% puts stdout "de postcode is [set adress]" de postcode is 48631 % puts stdout "de postcode is $address" de postcode is 48631 % puts stdout {de postcode is [set address]} de postcode is [set address] % puts stdout {de postcode is $address} de postcode is $addressIn dit voorbeeld kun je zien dat het gebruik van accolades voor het groeperen van commando en variabele substitutie niet veroorzaakt; echter deze vinden wel plaats als er dubbele aanhalingstekens worden gebruikt voor het groeperen.
% 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
De string data structuur is een van de drie basis Tcl data structuren.
Een string is een set karakters. Een string kan gecreëerd worden
met het set commando.
% set achternaam Westmoreland Westmoreland % set nummer 46.625 46.625De achternaam en nummer variabelen zijn strings. Strings kunnen gemanipuleerd worden met het string commando. De syntax van het string commando is string operatie stringwaarde anderargument. De volgende voorbeelden laten zien hoe dit commando gebruikt kan worden:
% string length $achternaam 12 % set achternaam [string range $achternaam 0 3] West % puts stdout $achternaam West % string tolower $achternaam westIn tegenstelling tot Java of Pascal is Tcl geen sterk-type programmeer taal. Het volgende voorbeeld laat dit zien:
% set nummer [expr $nummer + 24.5] 70.125 % string range $nummer 2 5 .125Met het commando expr werd de waarde van de variabele nummer verhoogd met 24,5. Daarna werd de variabele nummer behandeld als een string en werden de laatste vier karakters weergegeven.
Tcl lijsten zijn een speciaal geval van strings waarin de lijst
elementen zijn gescheiden door witruimtes en speciaal geïntepreteerd
worden.
% set vrienden_lijst {Fanny John Lisa Jack Michael} Fanny John Lisa Jack Michael % set vrienden_lijst [string tolower $vrienden_lijst] fanny john lisa jack michael % set vrienden_lijst fanny john lisa jack michaelEr zijn een aantal Tcl commando's voor het manipuleren van lijsten. Een paar voorbeelden:
% lindex 2 $vrienden_lijst lisa % lrange $vrienden_lijst 2 4 lisa jack michael % set vrienden_lijst [lsort -ascii $vrienden_lijst] fanny jack john lisa michael % set vrienden_lijst fanny jack john lisa michael % set vrienden_lijst [linsert $vrienden_lijst 2 Peter] fanny jack Peter john lisa michael % string toupper $vrienden_lijst FANNY JACK PETER JOHN LISA MICHAELHet laaste voorbeeld geeft aan dat strings en lijsten in feite dezelfde datastructuren zijn.
Een array kun je beschouwen als een lijst met een index van
string-waarden. Een array kan als volgt gecreëerd worden:
% set telefoon_nummers(fany) 629 629 % set telefoon_nummers(michael) 513 513 % set telefoon_nummers(john) 286 286Waarden uit de array kun je achterhalen met het set commando en variabele substitutie; zoals te zien is in het vorige voorbeeld, is een string-waarde index gescheiden door haakjes.
% set $telefoon_nummers(michael) 513Het commando array geeft informatie over een array variabele. Laten we een paar voorbeelden bekijken over wat dit commando kan doen:
% array size telefoon_nummers 3 % array names telefoon_nummers fany john michael
Alvorens een query op een database uit te voeren vanuit een Tcl script, moet er eerst een verbinding met de database server worden opgezet. In deze sectie zullen we zien hoe we dat kunnen doen en hoe we eventuele fouten, die kunnen optreden bij het maken van de database connectie, kunnen afhandelen.
Laten we eens een voorbeeld bekijken van een Tcl script die een
verbinding opzet met een MySQL database server:
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_handlerMerk op dat de nummers in de linker kolom en de bijbehorende dubbele punt geen deel zijn van het Tcl script; het enige doel is het labelen van de Tcl script regels. Merk ook op dat regel #0 mogelijk, afhankelijk van je Linux distributie, gewijzigd moet worden om een geldig pad naar de Tcl shell aan te geven.
In de vorige subsectie, werd regel #3 van het script niet uitgelegd.
Dat zullen we nu doen.
MySQLTcl library commando's kunnen fouten opleveren. Als een fout niet
wordt afgevangen, zal het script afbreken en het effect kan (wel of
niet) interessant zijn voor ons. Laten we het script dat in de vorige
subsectie werd getoond als volgt aanpassen:
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: }Als het commando set mysql_handler [mysqlconnect -host $host... een fout geeft, zal de foutmelding worden opgevangen door catch. Het commando catch geeft een 1 terug als het uitgevoerde commando binnen de accolades ({}) een fout opleverd of 0 als er geen fout optrad. De variabele mysql_handler slaat de uitvoer van het uitgevoerde commando, binnen de accolades, op.
element | betekenis |
code |
Als er geen fout was, dan is mysqlstatus(code) gelijk aan nul;
anders, is mysqlstatus(code) gelijk aan de foutcode van de
MySQL server. Als er een fout optrad die niet van de MySQL server kwam,
word mysqlstatus(code) gezet op -1.
De waarde van mysqlstatus(code) wordt iedere keer na het uitvoeren van een MySQLTcl library commando geüpdate. |
command |
Het laatste MySQLTcl library commando dat een fout gaf, is opgeslagen
in mysqlstatus(command)
De waarde van mysqlstatus(command) wordt na iedere niet-succesvolle uitvoering van een MySQLTcl commando geüpdate; mysqlstutus(commmand) wordt dus niet geüpdate na een succesvolle uitvoering van een MySQLTcl commmando. |
message | De waarde van mysqltcl(message wordt na iedere niet-succesvolle uitvoering van een MySQLTcl commando geüpdate, met een string die het foutbericht bevat. Net als mysqlstatus(command), wordt mysqlstatus(message) niet geüpdate na een succesvolle uitvoering van een MySQLTcl commando. |
element | betekenis |
nullvalue | String die gebruikt wordt om de null waarde te representeren bij het weergeven van SQL query resultaten. Standaard wordt er een lege string gebruikt; musqlstatus(nullvalue) kan op iedere string waarde worden gezet. |
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: }Uiteraard kan de globale array mysqlstatus worden gebruikt voor het afhandelen van meer fouten dan allen die die kunnen optreden tijdens het opzetten van de database connectie.
In deze sectie bekijken we de meest basis MySQLTcl library commando's
en zullen we aan de hand van voorbeelden zien hoe deze te gebruiken
zijn. Voor een complete referentie, zie de MySQLTcl library man pagina.
De commando's die in deze sectie beschreven worden, zijn weergegeven
in de volgende tabel. Parameters zijn onderstreept. Als een parameter
tussen twee ? karakters staat, betekend dat dat deze optioneel is;
het karakter | betekend "of".
commando | korte beschrijving |
mysqlconnect ?optionele waarde ...? | verbindt met een database; een connectie handler die gebruikt kan worden door andere mysqltcl commando's wordt geretourneerd. |
mysqluse handle dbnaam | associeert een MySQL handler met de opgegeven database |
mysqsel handle sql_statement ?-list | -flatlist? | stuurt een geselecteerd SQL statement naar de database |
mysqlexec handle sql_statement | stuurt een niet-select SQL statement naar de database |
mysqlclose handle | sluit een database connectie |
Dit commando is reeds ter sprake gekomen in de sectie "Database
connectie". Dit commando accepteert een extra parameter, die hier nog
niet is besproken: -db. Met de parameter -db, wordt altijd de hiermee
aangegeven database gebruikt in komende SQL statements. Laten we eens
kijken naar een voorbeeld:
% set mysql_handler [mysqlconnect -h 127.0.0.1 -p 3306 \\ -user john_smith -password jsmith_password -db jsmith_database]De "doel" database van MySQLTcl commando's die de mysql_handler database handler gebruiken, zullen gebruik maken van degene die jsmith_database genoemd wordt.
Dit commando staat je toe om de database die werd geassocieerd werd met de MySQL handler te veranderen, door de nieuwe database als eerste parameter mee te geven.
Dit commando stuurt een SQL select statement naar de database die
geassocieerd is met de MySQL handler. Als de parameter sql_statement
geen SQL select statement is, zal er een fout optreden.
Er is een derde optionele parameter, deze kan list zijn of flat_list.
Laten we eens in een voorbeeld bekijken hoe deze parameter de uitvoer
van dit commando beïnvloed. Stel dat we in de database die genoemd
is in de MySQL handler een tabel hebben met de naam people,
zoals hieronder weergegeven:
id | first_name | last_ name | phone |
26 | Karl | Bauer | 8245 |
47 | James | Brooks | 1093 |
61 | Roberto | Castro Portela | 6507 |
% 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}In het eerste voorbeeld (-list parameter), retourneerd het commando een lijst waarvan de elementen lijsten zijn. In het tweede voorbeeld (-flatlist parameter), retourneerd het commando een enkele lijst, waarin alle elementen samengevoegd zijn.
% mysqlsel $mysql_handler {select first_name, last_name from people order by id asc} 3
Het mysqlexec commando stuurt een non-select SQL statement
naar de database die geassocieerd is met de MySQL handler. Als de
parameter sql_statement een SQL select statement is, zal
er geen fout optreden, maar zal er ook niets gebeuren.
We nemen het voorbeeld uit de vorige subsectie:
% 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}Natuurlijk kunnen ook ander SQL queries dan delete (verwijderen) of insert (invoegen) met dit commando naar de database worden gestuurd. Zo kun je bijvoorbeeld een regel updaten:
% 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}Het commando mysqlexec geeft het aantal regels die betrekking hebben op het SQL non-select statement dat naar naar de database werd gestuurd.
Zoals we eerder hebben gezien, sluit het commando mysqlclose een database connectie. De parameter voor dit commando is de MySQL handler van de database connectie die we willen sluiten.
De MySQLTcl library kent meer commando's dan de 5 die we hebben besproken in deze sectie. Met deze commando's kun je informatie ophalen over de databases, strings formatteren zodat ze geschikt zijn voor queries, het maken van geneste queries... Een goede referentie is de eigen man pagina van MySQLTcl, welke onderdeel is van de installatie van de MySQLTcl library.
[1] Een enigzins sceptische blik op John K. Ousterhout en Tcl:
http://www.softpanorama.org/People/Ousterhout/index.shtml
[2] een tutorial over Tcl Reguliere expressies:
http://www.mapfree.com/sbf/tcl/book/select/Html/7.html
TclTutor is een vrije, interactieve applicatie voor het leren
van Tcl:
http://www.msen.com/~clif/TclTutor.html
MySQL documentatie in verscheiden formaten (HTML, PDF..):
http://www.mysql.com/documentation/index.html