Debugowanie (gdb) :: Qt-Designer :: Perl :: Programowanie w PHP :: Linki i moje projekty :: Python :: Ruby :: Tcl/Tk :: SQL :: Erlang :: Linki

Inne języki i narzędzia programistyczne

Oczywiście opisane w osobnych artykułach języki programowania takie jak: C/C++, awk, czy też sh w żaden sposób nie wyczerpują gamy nawet tych najpopularniejszych. Poniżej opisuję pokrótce inne istotniejsze języki programowania. Wspominam także o narzędziach takich jak Qt-Designer czy też gdb.

Debugowanie (gdb)

GDB czyli GNU Debugger jest narzędziem służącym do podglądania działania innego programu. Umożliwia ustawianie pułapek (powodujących przerwanie wykonywania na wywołaniu określonej funkcji, uruchamianie programu linia po linii, podgląd wartości zmiennych, ... . Umożliwia także sprawdzenie co program robił gdy się wywalił (na podstawie pliku core). Jest to narzędzie programistyczne, które niewątpliwie warto poznać, gdyż znacznie ułatwia poprawianie błędów w programach. Na wstępie polecam lekturę man gdb, info gdb.

Dla skorzystania z części możliwości konieczne jest wkompilowanie informacji debugerowych w program (np. gcc z opcją -ggdb). Program uruchamiany jest przez wywołanie gdb, zazwyczaj z jedną lub dwiema opcjami - plikiem wykonywalny oraz (ewentualnie) plikiem core. Do najistotniejszych poleceń należy:
break nazwa_funkcji ustawiające pułapkę na daną funkcję,
run uruchamiające program (zatrzymuje się na pierwszej napotkanej pułapce),
continue powodujące kontynuację programu do następnej pułapki,
next powodujące wykonanie kolejnej linii programu,
nexti powodujące wykonanie kolejnej instrukcji procesora,
print nazwa_zmiennej powodujące wypisanie wartości podanej zmiennej,
help wyświetlające pomoc "on-line",
quit kończące pracę gdb.
Oczywiście to tylko niewielka część wszystkich poleceń gdb, polecam zapoznać się z poszczególnymi grupami poleceń opisywanymi przez help.

GDB umożliwia również debugowanie programów na zdalnych systemach (podłączonych przez port szeregowy bądź przez sieć - zobacz man gdbserver), możliwość komunikacji przez sieć wykorzystują też programy zewnętrzne (takie jak simulavr, ice-gdb, ...).

Wspomniany simulavr jest symulatorem mikrokontrolerów AVR (niestety nie działającym jeszcze idealnie ...) i z przystosowaną dla programowania AVR w C wersją gdb (avr-gdb), umożliwia stworzenie systemu do testowania i debugowania programów AVR na zwykłym komputerze. Aby programy te zechciały ze sobą współpracować należy:
Uruchomić simulavr z opcjami -g i -p oraz określeniem odpowiedniego urządzenia i pliku z skompilowanym programem, np. (dla atmega128): simulavr -d atmega128 -g -D -P simulavr-disp -p 2345 moj_program.hex.
Uruchomić avr-gdb z określeniem pliku zawierającego skompilowany program, a następnie kazać połączyć mu się z simulavr, poprzez komendę: target remote localhost:2345 (numer portu oczywiście możemy zmienić, ale w obu programach musi być ten sam).
Zamiast simulavr możemy sprobować debugowania w układzie za pomocą avarice: avarice -d -f moj_program.hex -P atmega128 --jtag /dev/ttyS0 :2345, natomiast jeżeli chcemy obejrzeć komendy asemblerowe zawarte w wygenerowanym kodzie polecam (analogicznie do objdump dla zwykłych programów): avr-objdump -d moj_program.elf lub (specjalnie dla AVR): revava -e moj_program.hex

Qt-Designer

Qt-Designer (designer) jest programem służącym do wizualnego tworzenia graficznego interfejsu opartego na bibliotece Qt. Program ten operuje na plikach xmlowych które na kod źródłowy przetwarza się poleceniem uic nazwapliku.ui. Natomiast celem zbudowania programu wystarczy wydać kolejno qmake (generuje on plik Makefile dla całego projektu qt - plików *.ui, *.ui.h) oraz make (kompilacja i linkowanie w oparciu o wygenerowany wcześniej plik Makefile). Program qmake wymaga pliku opisującego projekt (potrafi go wygenerować sam Qt-Designer, jednak można posłużyć się także samym qmake z parametrem -project (w projekcie uwzględnia wszystkie pliki o odpowiednich rozszerzeniach z bieżącego katalogu)).

Qt3

Niestety Qt-Designer nie udostępnia (a przynajmniej ja nie znalazłem) możliwości wydania tych poleceń z niego, ani nie generuje funkcji main, niezbędnej do uruchomienia przygotowanego w nim program (GUI wraz z kodem akcji, który możemy w nim edytować). Poniżej przedstawiam szablon funkcji main dla głównego okna i klasy z nim związanej o nazwie MainWindow, kod ten należy umieścić np. w swoim pliku *.ui.h :

#include <qapplication.h>

int main( int argc, char **argv ) {
	 // tworzymy obiekt zarządzający zasobami aplikacji
	QApplication apps( argc, argv );
	
	 // utworzenie obiektu z klasy moje okno
	MainWindow main_window;
	
	 // ustalamy że pudełko box0 będzie głównym oknem aplikacji
	apps.setMainWidget( &main_window );
	 // pokazujemy nasze okno ...
	main_window.show();

	// pętla główna programu i zwrócenie kodu zwróconego przez a.exec() do rodzica ...
	return apps.exec();
}

Qt4

Zobacz w dziele o c++.

Perl

Perl jest wszechstronnym językiem programowania, umożliwiającym programowanie w różnych modelach. Posiada bardzo dużą liczbę dodatkowych modułów (bibliotek) zgromadzoną w archiwach CPAN. Jest jednym z najpopularniejszych języków używanych do tworzenia CGI. Z Perla wywodzą się takie języki jak: PHP, Ruby i Python.

Do ewidentnych zalet tego języka należy wspomniana już kolekcja gotowych modułów (których wykorzystanie zdecydowanie upraszcza tworzenie programu), dynamiczne typy zmiennych, wbudowane wyrażenia regularne, tablice asocjacyjne. Niektórzy jako zaletę perla podają także "naturalny sposób zapisu" uzyskiwany przez wykorzystywanie zmiennej wbudowanej $_, która jest argumentem domyślnym wielu funkcji. Rozwiązanie to ma jednak wielu przeciwników, zwłaszcza osoby które tak jak ja lepiej czują się w językach formalnych niż naturalnych.

Perl uważany jest za język skryptowy, jednak do końca nim nie jest. Kod skryptu przed jego wykonaniem poddawany jest kompilacji do kodu pośredniego. Istnieje możliwość wykonania takiej kompilacji i wykorzystywania (oraz dystrybucji) kodu pośredniego.

podstawy

Komentarzem jest wszystko od znaku # do końca linii (uwaga: znak # może występować także w ramach jakiś operatorów - nie oznacza on wtedy komentarza).

Łańcuchy znaków umieszczane są w ramach "" (wnętrze napisu podlega interpretacji) lub '' (wnętrze napisu nie podlega interpretacji). Napisy można także ograniczać przy pomocy otwierających qqX lub qqX (gdzie X jest znakiem ogranicznika) i zamykającego znaku ogranicznika, jeżeli znak ogranicznika jest którymś z nawiasów otwierających na końcu napisu używa się odpowiedniego nawiasu zamykającego. Do łączenia napisów służy operator . (kropka).

zmienne

Nazwa zmiennej w perlu poprzedzana jest znakiem oznaczającym jej typ są to:

  • $ - zmienne skalarne (liczby, napisy, ...)
  • @ - tablice zwykłe
  • % - tablice asocjacyjne
  • & - podprogramy
  • * - zmienne globalne

Standardowo nie ma potrzeby deklarowania zmiennych - perl gdy napotka nieznaną zmienną sam utworzy "pustą" zmienną (o wartości zero/napis pusty/...). Można to zmienić umieszczając w kodzie use strict 'vars';, wymusza to jawne deklarowanie zmiennych ze słowem kluczowym my, dodanie tego słowa do deklaracji zmiennej powoduje iż zmienna staje się zmienną lokalną (domyślnie wszystkie zmienne są globalne.

zmienne przedefiniowane

  • $_ - argument domyślny
  • @_ - tablica argumentów domyślnych
  • @ARGV - tablica argumentów przekazanych do skryptu
  • %ENV - tablica zmiennych środowiskowych
  • $? - status wyjścia z funkcji system()
  • $$ - PID wykonywanego skryptu

Zobacz w Sieci: Perl @ Wikibooks

Zachęcam także do zapoznania się z kilkoma przykładami programów stworzonych przeze mnie w perlu - smtp2xmpp.pl (nowsza wersja klienta jabbera przeznaczona do wysyłania komunikatów o nowej poczcie), mail-bot.pl (bot jabberowski odpowiadający na pytania o nową pocztę - w programie pokazane deklarowanie funkcji, korzystanie z daty i czasu oraz zewnętrznych aplikacji).

Programowanie w PHP

PHP jest językiem skryptowym o składni podobnej do C pomyślanym głównie o zastosowaniach w dynamicznym tworzeniu stron WWW (w zasadzie taka mieszanka C, AWK i Bash'a z dodatkiem sporej gamy funkcji webowych). Pomimo iż skrypty CGI można tworzyć w każdym z języków - konieczne jest tylko wysłanie jako pierwszej linii nagłówka Content-type (np. "Content-type: text/html"), drugiej linii pustej a potem mamy już treść to właśnie głównie przez te funkcje oraz dobrą integrację z HTML PHP jest do tego chyba najwygodniejszy.

Podobnie jak w AWK nie musimy definiować typu zmiennej, ale możemy uczynić to tak samo jak robiliśmy w C, pętle oraz instrukcje wyboru wyglądają identycznie jak w C, również operatory matematyczne, logiczne, porównania są takie same. Funkcje deklarujemy jak w C. Możemy korzystać z komentarzy C (/* do */), C++ (// do końca linii) oraz shela (# do końca linii). Podobnie jak w AWK mamy tutaj tablice asocjacyjne (oczywiście tablice możemy też indeksować klasycznie liczbami ...):

<?php
// od takiego znacznika zaczyna się kod PHP to co poza nimi traktowane jest jako dane ...
// kiedyś często pisało się tylko <? ale obecnie jest to mocno niezalecane
// - mamy przecież też <?xml ...>
	$nasza_tablica["Ala"]="ma kota";
	$nasza_tablica["Tom"]="ma psa";

	reset ($nasza_tablica);// - ustawienie aktualnej pozycji na początek tablicy
	// w tym wypadku nie jest to niezbędne,
	// ale gdy robimy dwa kolejne przeglądania z użyciem each jest to niezbędne
	while ( list($klucz, $wartosc) = each($nasza_tablica) ) {
		echo "nasza_tablica[$klucz] = $wartosc<br />\n";
		// do wypisywania służy echo, printf, ...
	}

	// a to bardzo wygodna funkcja do debugowania/testowania
	// - rekurencyjnie wyświetla zawartośc tablicy
	print_r($nasza_tablica);
?>

XHTML generated by highlight 2.4.5 (http://www.andre-simon.de/) from tablica.php

Do ważnych instrukcji należy zaliczyć include oraz include_once, które włączają podany po nich plik (ta druga sprawdza czy nie był już włączony i włącza tylko gdy nie był - wygodne przy włączaniu plików z definicjami funkcji). Mamy tez możliwości programowania obiektowego.

Reszta programowania i (jak sądzę) siła tego języka tkwi w bogactwie funkcji - do obsługi napisów, protokołów sieciowych (np. header()), plików (np. fopen(), itd.), baz danych, połączeń sieciowych (np. fsockopen()), ... . Więcej w dokumentacji PHP.

Na koniec warto zaznaczyć że dziedziny zastosowań PHP nie ograniczają sie tylko do WWW - może służyć do pisania innego rodzaju skryptów i aplikacji. W szczególności skrypty php możemy wykonywać jak każdy inny skrypt - wykonywalny plik tekstowy z #!/usr/bin/php4 (uwagi: kod dalej musi być w <?php i ?> oraz wymaga odpowiedniej paczki PHP - np. w Debianie "php4-cli").

Linki i moje projekty

Zachęcam także do zapoznania się z moim projektem związanym z programowaniem w PHP: prosty system do publikacji news'ów, logowanie do phpmyadmin w oparciu o konto shellowe i plik ~/.my.cnf, elementem silnika tej strony opartym o php oraz system informacji o stawianiu serwerów gry sieciowej. Zamieszczam także archiwum z skryptami do prezentacji starodruków opracowanymi na potrzeby projektu DIROP prowadzonego w ICM UW (wersja rozpakowana).

Zobacz w Sieci: PHP - tutoriale i artykuły php, manual, php, skrypty, PHP @ Wikibooks.

Python

Python jest interpretowanym językiem skryptowym o dość ciekawych możliwościach. Najistotniejszą różnicą w stosunku co do innych języków jest wyznaczanie bloków kodu wyłącznie przy pomocy wcięć. Język ten posiada zaawansowaną obsługę list (m.in. operatory wykonujące działanie na każdym z elementów listy). Poniżej przedstawiam przykład prezentujący podstawowe cechy tego języka, zachęcam także do zapoznania się z podręcznikiem Pythona w Wikibooks.

#!/usr/local/bin/python
# coding: utf-8

u'''Jest to forma komentarza wielolinijkowego,
jeżeli wsytępuje on na początku bloku funkcji czy całego skryptu
pełni on funkcję dokumentacyjną
poprzedzenie otwierających 3 apostrofów literą u pozwala na zapis zanaków unikodu'''

# na początek standardowe Hello World
print "Hello World"

# teraz deklaracja funkcji
def info(napis, numer=10):
	"""to również jest komentaż wielolinijkowy
	warto zwórcić uwagę iż blok instrukcji składających się na deklarację funkcji
	wydzielony jest WYŁĄCZNIE przy pomocy wcięc"""

	# jak widać pętla for przypomina trochę tą z basha
	for i in range(numer+1):
		print napis
		if (i % 2 == 0):
			print "^^^ to był parzysty wypis (i=%d)" % i
		else:
			print ""


# a to znowu kod główny
info("Ala ma kota", 3)

print "=============="

# obsługa list ...
lista_liczb = [1, 3, 6, 3]
print "YY " .join(["XX: %d\n" % n for n in lista_liczb])

lista_napisow = ['aaa', 'bbb', 'ccc', 'ddd']
print lista_napisow[1]
print lista_napisow[-1]
print "elemnt ccc ma indeks %d" % lista_napisow.index("ccc")

XHTML generated by highlight 2.4.5 (http://www.andre-simon.de/) from przyklad.py

Ruby

Ruby jest bardzo ciekawym interpretowanym językiem skryptowym. Pozwala m.in. na: korzystanie z tablic (zarówno zwykłych jak i asocjacyjnych), łatwą konwersję między tablicami a napisami i na odwrót, wygodne operacje napisowe, korzystanie z funkcji o nie ustalonej z góry liczbie argumentów, korzystanie z wyrażeń regularnych, programowanie obiektowe. Poniżej przedstawiam przykład prezentujący podstawowe cechy tego języka, zachęcam także do zapoznania się z Ruby @ Wikibooks.

#!/usr/bin/ruby

ilosc_kotow=1
ilosc_kotow=ilosc_kotow+1
print "Ala ma #{ilosc_kotow} kotow:\n"
print "KOTY: " + " mial" * ilosc_kotow + "\n"
print "A gdy znajdzie nasteopnego bedzie miala #{ilosc_kotow+1} kotow\n"

# jak powyżej widać napisy możemy dodawać a nawt mnożyć przez liczbę
# w ramach napisu możemy wypisywać zmienną a także wynik operacji matematycznej na zmiennej

# deklaracja funkcji, pierwszy argument umieszczony będzie w zmiennej napis,
# drugi i wszystkie kolejne w elementach tablicy ile
# można także przypisać domyślne wartości poprzez podanie =wartosc
def wypisywanie(napis, *ile)
	# pętla for po liczbach z zakresu
	for i in (2..ile[0])
		print i
	end
	print "\n"

	# sprawdzamy czy tablica ile ma więcej niż 1 element
	if ile.size > 1
		# pętla while
		while (ile[1] > 0)
			ile[1]=ile[1]-2
			print napis + "\n"
		end
	end
end

# wykorzystanie funkcji - 3 argumenty
wypisywanie("Witaj świecie", 5, 6)

# wypisanie odzielacza - warto zauważyć że pierwszy \n będzie przytoczony dosłownie
# gdyż użyte zostały pojedyńcze sudzysłowia
print '==========\n==========' + "\n"

# kolejne wykorzystanie funkcji - 2 argumenty
wypisywanie("Helo World", 5)

# tablica - deklarowanie, łączenie, zamiana na napis
tablica = [2, "4", 6]
print "Elemnt -2 to: " + tablica[-2] + "\n"
	# uwaga: takie łączenie działa dlatego że ten element jest napisem ;-)
tablica = tablica + ["abc", "def"]
tablica = tablica * 2
print tablica.join(" - ") + "\n"

# zakres tablicy (można go używać np. w pętli for po in)
print tablica[0..2]
print "\n"

# przy pomocy zmienna_napisowa.split("podzial") możemy podzielić zmienną napisową
# na elementy tablicowe względem zadanego napisu
napis="Ala , ma , kota, albo , dwa"
tablica=napis.split(" , ")
print tablica.join("/") + "\n"

# tablice asocjacyjne
tablica_asocjacyjna = {1 => 2, "drugi" => 4, 2 => "kot"}
print "-==-#{tablica_asocjacyjna["drugi"]}-==-#{tablica_asocjacyjna[5]}-==-\n"

XHTML generated by highlight 2.4.5 (http://www.andre-simon.de/) from przyklad.ruby

Tcl/Tk

Tcl/Tk jest skryptowym językiem umożliwiającym budowanie graficznych interfejsów użytkownika (biblioteka Tk). Samo Tcl jest językiem komend tak jak typowe unixowate języki skryptowe takie jak sh. Tk jest z kolei biblioteką odpowiedzialną za interfejs graficzny, jest ona dostępna także dla wielu innych języków programowania, jednak pierwotnie związana jest właśnie z Tcl. Poniżej przedstawiam przykładowy skrypt obrazujący użycie Tlc/Tk. Zobacz w sieci: Tcl/Tk Tutorial.

#!/usr/bin/wish

label .info_label -text "To testowy programik"
pack .info_label

# deklaracja pola wczytywania/wypisywania tekstu
entry .pole_tekstowe
pack .pole_tekstowe

# funkcja z jednym argumentem
proc dodawanie { ctrl } {
	# deklaracja pustego napisu
	set napis ""

	# warunek if
	if { $ctrl == 2 } {
		# wypisanie (na terminal) wyniku dodawania
		puts [expr $ctrl+5]
	} elseif {$ctrl == 1} {
		set lista [list "Ala " {ma } kota]
		# pętla forech - for jak w bashu ;-)
		foreach wyraz $lista {
			set napis "$napis$wyraz"
		}
		# podnapis na terminal
		puts [string range $napis 3 end]
	} else {
		# pętla for
		for { } {$ctrl>0} { set ctrl [expr $ctrl-1] } {
			# wypisanie napisu
			puts "Hi hi hi"
		}
	}
	# wypisanie $napis w gui
	.pole_tekstowe insert end $napis
}

# funkcja z dwoma argumentami
proc odejmowanie { mode ile } {
	switch $mode {
		"pierwszy" {
			while { $ile >= 10 } {
				puts $ile
				set ile [expr $ile - $ile/2]
			}
		}
		"drugi" {
			# odczyt pliku
			set input_file [open "/etc/passwd" r]
			set zawartosc_pliku [read $input_file]
			close $input_file
			# wypisanie zawartości pliku
			puts $zawartosc_pliku
			# rozłożenie zawartości na linijki i wypisanie jednej z nich
			set linijki [split $zawartosc_pliku "\n"]
			puts [lindex $linijki 2]
			# wykorzystane tu listy mają jeszcze parę możliwości ...
		}
		default {
			set "I co ja mam robić ?"
		}
	}
}

# tworzymy przycisk
button .button1 -text "Dodaj 1" -command "dodawanie 1"
button .button2 -text "Dodaj 2" -command "dodawanie 2"
button .button3 -text "Dodaj 3" -command "dodawanie 3"
button .button4 -text "Odejmij 1" -command "odejmowanie pierwszy 100"
button .button5 -text "Odejmij 2" -command "odejmowanie drugi 10"
button .button6 -text "Odejmij 3" -command "odejmowanie trzeci"

# wyświetlamy przyciski
pack .button1
pack .button2
pack .button3
pack .button4
pack .button5
pack .button6

XHTML generated by highlight 2.4.5 (http://www.andre-simon.de/) from przykład.tcl

SQL

SQL jest językiem zapytań, wykorzystywanym do komunikacji z bazą danych, może być używany w trybie interaktywnym, lub poprzez zapytania wykonywane przez aplikację na potrzeby jej funkcjonowania. Istnieje wiele implementacji systemów bazodanowych korzystających z SQL, praktycznie każdy z nich posiada jakieś własne rozszerzenia tego standardu, lub nie implementuje pewnych jego fragmentów. Do pracy interaktywnej na ogół wykorzystuje się oprogramowanie opracowane specjalnie dla danej bazy danych i często dostarczane wraz z nią, natomiast do przesyłania zapytań z aplikacji wykorzystać można biblioteki dedykowane danemu serwerowi bazodanowemu (np. C API MySQL lub wbudowane biblioteki php dla baz danych) lub sterownik standardu ODBC.

SQL posiada polecenia umożliwiające tworzenie, modyfikowanie i usuwanie baz danych oraz tabel, jak również wstawiania, kasowania pobierania i modyfikowania danych, umożliwia także nakładanie ograniczeń (więzów) na wprowadzane dane. SQL nie rozróżnia wielkości liter w nazwach poleceń.

	-- utworzenie bazy danych
	CREATE DATABASE `test-db`;
	
	-- wybranie jej jako domyślnej, inaczej do tabeli aaa trzeba by się odwoływać przez test-db.aaa
	USE `test-db`;
	
	-- tworzymy tabele uzytkownicy
	--  z określonym kluczem głównym na kolumnie UID, która jest automatycznie zwiększana
	--  indeksem na kolumnie name (która może mieć wartość nieokreśloną)
	--  unikalnością na kolumnie PESEL (która nie może być pusta)
	CREATE TABLE `uzytkownicy` (
		`UID` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
		`name` VARCHAR( 25 ) NULL ,
		`PESEL` BIGINT( 11 ) UNSIGNED NOT NULL ,
		INDEX ( `name` ) ,
		UNIQUE ( `PESEL` )
	);
	
	-- dodaliśmy kolumnę password typu tekstowego
	-- o zmiennej długości wynoszącej maksymalnie 30 znaków
	--  została ona wstawiona po kolumnie name
	ALTER TABLE `uzytkownicy` ADD `password` VARCHAR( 30 ) NOT NULL AFTER `name`;
	
	-- zmieniliśmy definicję kolumny name tak aby napisy porównywane były wg kodowania utf8
	--  z uwzględnieniem kolejności języka polskiego
	ALTER TABLE `uzytkownicy` CHANGE `name` `name` VARCHAR( 25 )
		CHARACTER SET utf8 COLLATE utf8_polish_ci NULL DEFAULT NULL;
	
	-- wymagamy aby uzytkownicy byli urodzeni przed 1992 rokiem
	--  (ze względu na budowę peselu i prostotę tego warunku dopuszczamy urodzonych po 1999 ...)
	ALTER TABLE `uzytkownicy` ADD CONSTRAINT `wiek` CHECK(PESEL<92000000000);
	
	-- tworzymy kolejna tabelkę - na dane teleadresowe
	CREATE TABLE `dane` (`UID` INT UNSIGNED NOT NULL,
		`type` TINYINT UNSIGNED NULL, `value` VARCHAR(50));
	
	-- dodajemy wiąz unikalności określający iż cała 
	--  kombinacja identyfikatora użytkownika typu i wartości pola ma być unikalna ...
	ALTER TABLE `dane` ADD CONSTRAINT `unikalnosc` UNIQUE(`UID`, `type`, `value`);
	
	-- bawimy się wstawianiem i modyfikacją danych
	INSERT INTO `uzytkownicy` VALUES (NULL, NULL, NULL, 91000000000);
	INSERT INTO `uzytkownicy` VALUES (NULL, NULL, "super tajne", 91000000000);
	
	INSERT INTO `dane` (`UID`, `value`) VALUES (0, NULL);
	INSERT INTO `uzytkownicy` VALUES (NULL, 'rrp', "super tajne", 10000000000);
	
	-- korzystamy z podzapytania przy wstawianiu
	INSERT INTO `dane` VALUES (
		(SELECT UID FROM `uzytkownicy` WHERE name='rrp'),
		1, 'rrp@localhost' );
	
	-- podzapytań możemy używać także w warunkach oraz w części zwracającej wyniki
	SELECT name FROM `uzytkownicy` WHERE UID=(SELECT max(UID) FROM `uzytkownicy`);
	
	-- robimy join'a (połączenie kilku tabelek), korzystając z aliasów
	SELECT u.UID, u.name, d.value FROM `uzytkownicy` AS u
		JOIN `dane` AS d ON u.UID=d.UID;
	SELECT u.UID, u.name, d.value FROM `uzytkownicy` AS u
		LEFT JOIN `dane` AS d ON u.UID=d.UID;
	
	SELECT COUNT(*) AS 'ilosc' FROM `dane`;
	SELECT COUNT(*) AS 'ilosc' FROM `dane` WHERE value IS NOT NULL;
(uwaga poniższe były testowane tylko w PostgresSQL, ale myślę że conajwyżej po niewielkich zmianach powinny zadziałać w MySQL)
	-- jeżeli przed dodaniem warunku unikalności były dane z nim sprzeczne, możemy je łatwo wyszukać:
	SELECT UID, type, value FROM dane GROUP BY UID,type,value HAVING count(UID)>1;

	-- dodajemy komentarz do kolumny
	COMMENT ON COLUMN `uzytkownicy`.PESEL IS 'w przyszłości zrobić kontrolę sumy';
	
	-- gdybyśmy zapomnieli o primary key i indeksie przy tworzeniu tabeli to możemy dadać do istniejącej:
	--  ALTER TABLE uzytkownicy ADD INDEX(name);
	--  ALTER TABLE uzytkownicy ADD PRIMARY KEY (UID);
	
	-- dodawanie do tabeli klucza obcego, z kasowaniem kaskadowym
	--  usunięcie użytkownika z `uzytkownicy` spowoduje usunięcie jego wpisów z `dane`
	--   jakby było bez "ON DELETE CASCADE" to proba usunięcia gdy są wpisy w `dane`
	--   zakonczyłaby się błędem
	ALTER TABLE dane ADD FOREIGN KEY (UID) REFERENCES uzytkownicy(UID) ON DELETE CASCADE;
(uwaga poniższe były testowane tylko w MySQL)
	-- danie użytkownika TESTER z hałem ABCDEF i pełnymi prawami do bazy TESTOWA
	--  w PostgresSQL komenda createuser (więcej w man createuser)
	--  np, createuser -s -d -U postgres USERNAME utworzy uzytkownika z pełnią praw
	CREATE USER 'TESTER'@'localhost' IDENTIFIED BY 'ABCDEF';
	GRANT USAGE ON * . * TO 'TESTER'@'localhost' IDENTIFIED BY 'ABCDEF' WITH \
		MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ;
	GRANT ALL PRIVILEGES ON TESTOWA . * TO 'TESTER'@'localhost';
	
	-- usunięcie użytkownika i przyznanych mu praw
	DROP USER 'AAAAAA'@'localhost';
	
	-- wyświetlenie baz danych
	SHOW DATABASES;
	
	-- wyświetlenie tabel
	--  w PostgresSQL polecenie \d w psql
	SHOW TABLES;
	
	-- wylosowanie zbioru rekordów (losowa kolejność 5 pierwszych)
	SELECT * FROM `uzytkownicy` ORDER BY rand() LIMIT 5;

SQL umożliwia ponadto deklarowanie zmiennych, funkcji i procedur działających po stronie serwera, tworzenie widoków ("wirtualnych" tabel opartych na zapytaniu o tabele istniejące), uruchamianie zaplanowanych działań w momencie wykonywania określonej operacji na bazie danych (trigger), korzystanie z transakcji (grup poleceń, które np. w wypadku niepowodzenia któregoś z nich mogą zostać cofnięte i są wykonywane w sposób niepodzielny). Powyższe przykłady zostały przygotowane dla MySQL 5. Więcej informacji można uzyskać korzystając np. z komendy help w konsoli wywołanej poleceniem mysql - np. help CREATE TRIGGER, help START TRANSACTION. Warto wspomnieć także o mysqldump zrzucającym wybraną (lub z opcja --all-databases wszystkie) bazę danych w postaci tekstowego SQL na standardowe wyjście oraz o pg_dump -cif nazawa_pliku bazadanych pełniącym analogiczną funkcję w PostgresSQL.

Zobacz też: dokumentacja składni SQL dla MySQL , wstęp do technologii baz danych na FUW.

Erlang

Erlang jest dość oryginalnym językiem programowania. Jest to język wybitnie funkcyjny (do tego stopnia iż nie ma w nim pętli), posiada dość nietypową składnie, ale np. nie wymaga deklarowania zmiennych.

Wiele z funkcji języka możemy testować w jego linii poleceń (erl, jednak wiele z nich (np. deklarowanie funkcji) wymaga aby były umieszczone w modułach - w tym celu tworzymy plik nazwamodulu.erl, umieszczamy w nim nasz kod a w linii poleceń wydajemy c(nazwamodulu). co powoduje przebudowanie modułu, po czym możemy korzystać z zdefiniowanych w nim funkcji - nazwamodulu:funkcja(argumenty).

Poniżej prezentuję mój patch (aktualnie dodany już do głównego kodu) umożliwiający przechowywanie wiadomości offline dla użytkowników autoryzowanych przez PAM w serwerze XMPP "ejabberd". Polega on na zastąpieniu trywialnego ciała funkcji "is_user_exists" w module "ejabberd_auth_pam" następującym kodem:

is_user_exists( _User, _Server ) ->
 %% wczytujemy do FileStr plik /etc/passwd dodając na początku pustą linię
 {ok,FileBin}=file:read_file("/etc/passwd").
 Tmp=binary_to_list(FileBin).
 FileStr=string:concat("\n", Tmp).

 %% tworzymy RegExp dodając do zmiennej napisowej _User
 %% znak nowej linii na początku i : na końcu
 Tmp2=string:concat("\n", _User).
 RegExp=string:concat(Tmp2, ":").

 %% jeżeli w FileStr wystąpiło wyrażenie RegExp
 %% zwracamy true w przeciwnym razie false
 case regexp:match(FileStr, RegExp) of
   {match, _, _}  ->
       true;
   _ ->
       false
 end.

Nie jest to rozwiązanie eleganckie (odwołania do /etc/passwd to nie PAM), ale w większości wystarczające. Kod ten pokazuje korzystanie z plików i napisów w erl'angu. Obrazuje również zdefiniowanie funkcji przyjmującej dwa argumenty i zwracającej wartość true lub false, deklaracja ciała funkcji następuje po ->, a kończy się kropką.

W ramach serwisu opublikowane jest kilka patchy mojego autorstwa do serwera "ejabberd", który stworzony jest właśnie w erlangu - zachęcam do zapoznania się z nimi jako przykładami programowania w tym języku - "ejabberd_log_offline_message.diff" (łatka stanowiąca fragment system powiadomień XMPP/SMTP, pokazuje obsługę plików, operacje na napisach, a także tworzenie katalogu i formatowanie czasu), JID aliases (zestaw łatek implementujących aliasy JID, pokazuje komunikację z zewnętrzną aplikacją, instrukcję warunkowe, tworzenie funkcji i zwracanie z nich wyników.

Zobacz w Sieci: dokumentacja języka.


Copyright (c) 1999-2008, Robert Paciorek (http://www.opcode.eu.org/), BSD-type license


Redystrybucja wersji źródłowych i wynikowych, po lub bez dokonywania modyfikacji JEST DOZWOLONA, pod warunkiem zachowania niniejszej informacji o prawach autorskich. Autor NIE ponosi JAKIEJKOLWIEK odpowiedzialności za skutki użytkowania tego dokumentu/programu oraz za wykorzystanie zawartych tu informacji.

This program is free software. Redistribution and use in source and binary forms, with or without modification, ARE PERMITTED provided save this copyright notice. This document/program is distributed WITHOUT any warranty, use at YOUR own risk.

Valid XHTML 1.1 Dokument ten (URL: http://www.opcode.eu.org/programowanie) należy do serwisu OpCode. Autorem tej strony jest Robert Paciorek, wszelkie uwagi proszę kierować na adres e-mail serwisu: webmaster@opcode.eu.org.
Data ostatniej modyfikacji artykulu: 2008-07-15 23:13:45 (UTC) (data ta może być zafałszowana niemerytorycznymi modyfikacjami artykułu).