poniedziałek, 1 września 2008

Struktura drzewa w Symfony

Na devzone (http://dev.mysql.com/tech-resources/articles/hierarchical-data.html) MySQLa znajduje się artykuł o tworzeniu hierarchicznych struktur danych. Popularnym zastosowaniem takiej struktury jest menu strony internetowej, gdzie mamy do czynienia z drzewem linków (kategorii).
W artykule omówione są dwa podejścia Adjacency List Model i Nested Set. Pierwsze doskonale sprawdza się w przypadku 2, no góra trzech zagnieżdżeć ale jest łatwiejsze do zaimplementowania. Nested Set sprawdza się gdy chcemy jednym zapytaniem pobrać całe drzewo lub całą ścieżkę.

Jeżeli chcemy skorzystać z Nested Net w projekcie opartym o symfony, należy w strukturze danych (schema.yml), ktore kolumny zawierają TREE_LEFT, TREE_RIGHT, TREE_SCOPE, np:

categories:
_attributes: { phpName: Category, treeMode: NestedSet}
id:          ~ #symfony default
lft:         { type: integer, required: true, 
nestedSetLeftKey: true, phpName: Left }
rgt:         { type: integer, required: true, 
nestedSetRightKey: true, phpName: Right }
level:       { type: integer, required: true }
name:        { type: varchar(100), required: true }
photo:       { type: varchar(255) }


Nested Set jest dostępny dopiero od ostatniej wersji propela 1.3. W symfony 1.1 musimy zainstalowac plugin Propel 1.3 z repozytorium http://svn.symfony-project.com/plugins/sfPropelPlugin/branches/1.3
Z moich dotychczasowych doświadczeń mogę powiedzieć, że rozwiązanie nie jest jeszcze w pełni stabilne. W przypadku modyfikacji, przenoszenia gałęzi czasem gubiona jest struktura.

Innym rozwiązaniem dla symfony jest plugin sfPropelActAsNestedSetBehaviorPlugin. Ten plugin zdaje się być w pełni stabilny. Z kolei nie bedzie w pełni działał pod Propelem 1.3.

Podsumowując, zarówno dla symfony 1.0, jak i dla symfony 1.1 polecam sfPropelActAsNestedSetBehaviorPlugin.

czwartek, 28 sierpnia 2008

Poruszające i takie prawdziwe (Hug a developer)

http://develop-one.net/blog/2008/08/27/HugADeveloper.aspx

środa, 20 sierpnia 2008

Could not reliably determine the server's fully qualified domain name

apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName

Zapewne taki notice widział niemal każdy. Ja się z nim spotykam prawie zawsze kiedy przychodzi do firmy nowy Junior Developer, który używa Ubuntu/Kubuntu. Oczywiście komunikat w niczym nie przeszkadza, nie zakłóca działania Apacha, ale po co.. skoro można go w bardzo prosty sposób usunąć.

Wystarczy dodać linię w pliku apache2.conf (jeżeli używasz linuxa powinien się znajdować gdzieś w /etc/apache2/apache2.conf lub /usr/local/apache2/...):
sudo vim /etc/apache2/apache2.conf
ServerName localhost

Można ustawić dowolną nazwę serwera (np ServerName blabla) ale w tym wypadku należy "domenę" blabla dodać do pliku hosts (/etc/hosts).
sudo vim /etc/hosts
127.0.0.1 blabla

Po restarcie Apacha (sudo /etc/init.d/apache2 restart) już nie ujrzymy komunikatu, a także możemy korzystać z domeny http://blabla/ w przeglądarce.

Warto przy okazji dodać, że dawno dawno temu plik hosts był jedyną formą systemu DNS jaką posługiwali się użytkownicy internetu. Przesyłano sobie plik z komputera na komputer, dzięki temu można było wpisywać w przeglądarkę nazę zamiast numeru IP. Nietrudno sobie wyobrazić do jakich rozmiarów musiał dochodził taki plik :)

Symfony, propel, struktura bazy danych, unikalne kolumny

Definiowanie unikalnych kolumn, to w zasadzie dodanie 2 linii w pliku schema.yml (schema.yml to plik, w którym definiujemy strukturę bazy w projektach opartych na Propelu / Symfony).

Mamy tabelę books:
books:
_attributes:       { phpName: Book }
id:                ~ #symfony default
title:             { type: varchar(255) }
ISBN:              { type: varchar(255) }


Chcemy teraz, aby nasza tabela nie zawierała duplikatów. Dla przykładu książek o tym samym numerze ISBN.

W tym celu dodajemy atrybut _uniques a następnie podajemy nazwę klucza books_unique_isbn oraz nazwę kolumny (lub po przecinku kolumn). W efekcie nowa definicja tabeli books:

books:
_attributes:        { phpName: Book }
id:                 ~ #symfony default
title:              { type: varchar(255) }
ISBN:               { type: varchar(255) }
_uniques:
books_unique_isbn: [ISBN]


Jeżeli chcemy aby 2 lub więcej kolumn tworzyło klucz unikalny podajemy ich nazwy rozdzielone przecinkami, np:
books_unique:    [ISBN, title]

Jak założyć nowego użytkownika MySQL przez konsole?

Umieszczam małą ściągę pt. Jak założyć nową bazę mysql i użytkownika, który będzie miał pełne prawa dostępu do tej bazy (create table, drop table, delete, update etc). Użytkownik ten jednak nie może mieć prawa nawet odczytu z innych baz na serwerze MySQLa.

Załóżmy, że projekt nazywa się owidiusz. Najpierw zakładam bazę:
create database owidiusz;

Jeżeli ta baza będzie przechowywać dane w kodowaniu UTF8, dodajemy:
create database owidiusz character set utf8 collate utf8_polish_ci;

(collate pozwala na poprawne sortowanie poslkich znaków!)

Następnie uzytkownika, nadajemy mu od razu hasło:
create user owidiusz identified by 'owidiusz123';

Nadajemy uprawnienia do bazy:
GRANT ALL PRIVILEGES ON owidiusz.* TO 'owidiusz'@'localhost';

I odświeżamy uprawnienia:
flush privileges;

I to wszystko :), można korzystać z bazy.