Jul 10 2008

Presja czasu czyli złośliwości timestampa w MySQL

Tag: MySQLmyszaq @ 09:07

Niedawno natrafiłem na dosyć osobliwy problem podczas definiowania kolumn w jednej z tabeli. Okazuje się, że wszystkim dobrze znany (mam taką nadzieję:)) typ TIMESTAMP rządzi się swoimi własnymi prawami i potrafi w pewnych sytuacjach namieszać dość konkretnie. O co chodzi? Wyobraźmy sobie, że chcemy stworzyć w tabeli ‘czasy’ 2 pola:

updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
edited_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP

Niby wszystko jest w porządku, jednak pojawia się komunikat:

Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause.

Niestety twórcy MySQL, chociaż opisali taką sytuację, nie raczyli napisać dlaczego tak się dzieje. Próba zastąpienia CURRENT_TIMESTAMP przez NOW() tudzież LOCALTIME() też nic nie daje, jako że są to wartości równoznaczne tej pierwszej. Warto przy tym wspomnieć, że typ TIMESTAMP daje dość duże możliwości, jeżeli chcemy dać polu wartość domyślną i/lub automatycznie uaktualniać przy użyciu nieszczęsnego CURRENT_TIMESTAMP. Możemy użyć go np. do czegoś takiego:
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
lub
updated_at TIMESTAMP DEFAULT 0 ON UPDATE CURRENT_TIMESTAMP.

Wspaniale, tylko że dotyczy to pierwszej kolumny. Próba użycia CURRENT_TIMESTAMP w kolejnej kolumnie zakończy się powyższym błędem.
Co więc zrobić, gdy chcemy koniecznie mieć możliwość zdefiniowania defaultowej wartości dla obu takich pól czasowych (o aktualizacji nie wspominając)? Możemy zdefiniować pola następująco:

updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
edited_at TIMESTAMP NOT NULL DEFAULT '2008-01-01 00:00:00'

Zamiast jakiejś daty w polu DEFAULT możemy umieścić 0 lub nawet NULL, ale w tym ostatnim przypadku trzeba również pamiętać o zadeklarowaniu pola jako NULL. Takie pośrednie rozwiązania zapewne jednak nas nie satysfakcjonują - data w drugim polu stanie się szybko przestarzała a wartość zerowa do niczego się raczej nie przyda. Niestety tylko takie wyjście proponuje
manual.
Najlepiej jest zatem zapewnić samemu wstawianie odpowiednich wartości. I tu można się bardzo zdziwić - nie trzeba bowiem pisać
INSERT INTO czasy VALUES (NOW(), CURRENT_TIMESTAMP);

Jak to? Definiujemy tabelę ‘czasy’ w ten sposób:
create table czasy (
created_at timestamp NOT NULL default '0000-00-00 00:00:00',
updated_at timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP
);

Następnie wykonujemy zapytanie
INSERT INTO czasy(created_at,updated_at) VALUES (NULL,NULL);

Jaki będzie efekt? Obie kolumny będą zawierać tą samą wartość - CURRENT_TIMESTAMP :) Dzieje się tak dlatego, że przypisanie kolumnie zdefiniowanej jako NOT NULL wartości NULL zamieni ją na aktualny czas.
A powiadają, że szczęśliwi czasu nie liczą…


Jul 09 2008

Nowy Fireshot

Tag: Programy, Przeglądarkiradmen @ 08:41
fireshot.png

Niedawno ukazała się nowa wersja rozszerzenia
FireShot. FireShot służy do robienia zrzutów ekranu przeglądanej strony. Rozszerzenie udostępnia sporo możliwości. Poza dodawaniem tekstu, możemy oznaczyć jakiś element strzałką, lub nawet zaznaczyć cały blok i go opisać. Jeśli tego nam mało to możemy pobawić się prostymi efektami graficznymi.

Dawniej FireShot był rozszerzeniem tylko dla
Firefoksa. Wraz z nową wersją mamy możliwość korzystać z tego programu jako rozszerzenie dla IE. Jest to o tyle przydatne, że nie musimy się bawić w robienie zrzutu, wrzucanie go do edytora i zapisywanie. Teraz, dzięki FireShot, możemy bez problemu zaznaczyć to co się krzaczy pod IE, szybko i bezboleśnie :)