W listopadzie zapraszałem Was na pierwsze wrocławskie edycje Meet.JS i GTUG. Dzisiaj jesteśmy już po drugiej edycji każdej z imprez. Na obu – Meet.JS Wrocław i GTUG Wrocław przedstawiałem ten sam temat – Node.JS. Na szczęście okazało się, że zbiór wspólny uczestników był bardzo mały i chyba nawet nikt nie przysnął :). Poniżej link do prezentacji.
Dodatkowo zapraszam (w szczególności uczestników GTUG-a, na którym było więcej kodu) do projektu na Githubie, gdzie wgrałem źródła.
Na koniec chciałem jeszcze podziękować organizatorom za trud włożony w dogranie tych spotkań i Wam, uczestnikom, za przybycie i zadawanie ciekawych pytań :). Do zobaczenia na następnych imprezach.
PostgreSQL: Reset wszystkich sekwencji

Problem
Czasami udaje się nam doprowadzić swoją niemałą bazę danych do takiego stanu, w którym część sekwencji będzie źle ustawiona, a tym samym nie będzie możliwe dodawanie nowych danych w standardowy sposób, gdyż kolejnym id wg sekwencji, będzie takie, które już w bazie istnieje.
Możemy wtedy ręcznie naprawić daną sekwencję, zgodnie z manualem:
ALTER SEQUENCE serial RESTART WITH 105;
Gdzie serial to nazwa sekwencji. Co jednak, gdy mamy kilkaset popsutych tabelek?
Rozwiązanie — teoria
Na szczęście PostgreSQL udostępnia nam duuużo informacji o każdej swojej bazie danych w schemie information_schema, która to zawiera zestaw zawsze dostępnych widoków. My tutaj wykorzystamy dwa:
columns— informacje o wszystkich kolumnach i widokach w bazieconstraint_column_usage— informacje o kolumnach, które są obłożone jakimśconstraintem
To co chcemy zrobić to:
- Znaleźć wszystkie zestawy tabela-kolumna-sekwencja (bazując na tym, że definicja sekwencji jest stała, zawiera wywołanie
nextval(). - Dla każdej kolumny znaleźć największą wartość identyfikatora.
- Zrestartować każdą sekwencję z wartością znalezioną w poprzednim kroku i zwiększoną o 1.
Rozwiązanie — praktyka
W praktyce wystarczy wykonać poniższy kod w swojej bazie danych. Tworzy on funkcję naprawiającą sekwencje, wykonuje ją raz i a następnie ją kasuje. Należy pamiętać, że działanie jest ograniczone do schemy public. Jeśli chcemy naprawić inną, trzeba sobie kod lekko zmodyfikować (np. dodając nazwę schemy jako paramert).
CREATE OR REPLACE FUNCTION rebuild_sequences() RETURNS INTEGER AS $body$ DECLARE sequencedefs RECORD; c INTEGER; BEGIN -- Find sequence name and primary key column for every table FOR sequencedefs IN SELECT DISTINCT constraint_column_usage.TABLE_NAME AS TABLE_NAME, constraint_column_usage.column_name AS column_name, REPLACE(REPLACE(COLUMNS.column_default,'''::regclass)',''),'nextval(''','') AS sequence_name FROM information_schema.constraint_column_usage, information_schema.COLUMNS WHERE constraint_column_usage.table_schema = 'public' AND COLUMNS.table_schema = 'public' AND COLUMNS.TABLE_NAME = constraint_column_usage.TABLE_NAME AND constraint_column_usage.column_name = COLUMNS.column_name AND COLUMNS.column_default IS NOT NULL AND COLUMNS.column_default LIKE ('nextval%') LOOP -- Find current max PK value EXECUTE 'SELECT max('||sequencedefs.column_name||') FROM ' || sequencedefs.TABLE_NAME INTO c; IF c IS NULL THEN c = 1; ELSE c = c + 1; END IF; -- Rebuild sequence EXECUTE 'ALTER SEQUENCE ' || sequencedefs.sequence_name ||' RESTART WITH ' || c; END LOOP; RETURN 1; END; $body$ LANGUAGE plpgsql; SELECT rebuild_sequences(); DROP FUNCTION rebuild_sequences();
Pierwsza wersja funkcji została napisana przez Klausa ze StackOverflow. Wersja powyżej zawiera poprawki błędów, niedociągnięć oraz formatowania.
Myślałem, że nie napiszę nic o Darcie, bo cała historia z nim związana z początku nie wywoływała we mnie żadnych specjalnie negatywnych czy pozytywnych emocji. Dzięki Zbyszkowi Branieckiemu i Markowi Stępniowi trochę szerzej spojrzałem na temat, biorąc pod uwagę też historie o których, czy to z racji mojego krótkiego życia, czy braku wiedzy o pracach komitetów i producentów przeglądarek, nie wiedziałem i… sami przeczytajcie. Załączam poniżej coś co miało stać się przydługim komentarzem na forum Goldenline.
Pożal się Google
To co zrobiło Google, to żart. Cała historia z wewnętrznymi, nie do końca miłymi mailami z Google’a, które wyszły na światło dzienne, sam Dart i otoczka PR-owa jaką ma, to jedno wielkie nieporozumienie. Google się nie popisało i, moim skronym zdaniem, wyjdzie to tylko na dobre open webowi.
Wyobraźmy sobie, co by się stało gdyby Dart rzeczywiście powalał na kolana i miałby świetnie zaimplementowaną, super wydajną i dostępną out of the box w Chrome maszynę. Szybko znalazłoby się grono fan boy’ów, którzy bez zastanowienia zaczęliby pisać aplikacje „only for Chrome”, bądź „works best with Chrome”, z ewentualną, wątpliwej jakości, kompilacją do powolnego i starego JavaScriptu dla „gorszych przeglądarek”. (BTW. hello world w Dartcie skompilowany do JS to 17000 linii kodu :D).
Trzy tygodnie temu zapraszałem Was na warsztaty DevMeetings z middle-endu, które prowadziłem. Dodatkowo, czego jeszcze wtedy nie wiedziałem, zostałem zaproszony jako speaker na MeetJS do Krakowa, gdzie zdecydowałem się opowiedzieć o jednym wątku z DevMeetingu – asynchronicznej pułapce. Poniżej zamieszczam linki do tych prezentacji.


