W kontekście dzisiejszego Święta wzięło mnie na refleksje i miedzy innymi zastanowiłem się nad słusznością mojego początkowego założenia, żeby pisać bloga głównie po polsku, kontra okazjonalnych postów na blogu anglojęzycznym piczkowski.blogspot.com, dotyczących głównie jakichś wydarzeń międzynarodowych (Google Developer Day, 33rd Degree, itp)
Blog po polsku dotyczący polskich realiów, w których chcąc nie chcąc jestem obecnie osadzony, miał być szansą dla innych Polaków, developerów, biegaczy.. innych osób mniej lub bardziej dotkniętych tematyką, którą poruszam, na lepszy przekaz, czegoś co po angielsku w moim ujęciu mogłoby być zbyt płytkie. W końcu nie władam tym językiem w równym stopniu co polskim.
Z drugiej jednak strony, dlaczego zawężać dostęp do moich wypocin obcokrajowcom zamykając się na być może konstruktywny odzew z ich strony? Czy w dzisiejszych czasach młodzi ludzie nie są wstanie przetrawić tekstu po angielsku? Czy tym bardziej ja który na co dzień wertuje Internet w poszukiwaniu odpowiedzi na zagwozdki napotykane w pracy nie powinien być w stanie jasno się wyrazić po angielsku?
Być może pora przesiąść się troche z piczkowskipl.blogspot.com na piczkowski.blogspot.com
Jeśli masz swoje osobiste przemyślenia w tym temacie chętnie podyskutuję.
piątek, 1 listopada 2013
poniedziałek, 28 października 2013
IV Półmaraton Szakala
W niedzielne południe, miły, ciepły jak na październik dzień, odbył się w Arturówku bieg na dystansie 21km.
W taką pogodę ruch na świeżym powietrzu to sama przyjemność.
Po Maratonie Warszawskim troche 'rozluźniłem łyde' więc nie spodziewalem sie cudu, ale zdaje sie ze poszlo nad wyraz dobrze - 01:58:50 (miejsce nr 233), jedynie 39min. 20 sec. pozniej od zwycięzcy :D
Czytaj więcej na http://szakalebalut.pl/node/279
W taką pogodę ruch na świeżym powietrzu to sama przyjemność.
Po Maratonie Warszawskim troche 'rozluźniłem łyde' więc nie spodziewalem sie cudu, ale zdaje sie ze poszlo nad wyraz dobrze - 01:58:50 (miejsce nr 233), jedynie 39min. 20 sec. pozniej od zwycięzcy :D
Zapisy z Endomondo:
Czytaj więcej na http://szakalebalut.pl/node/279
poniedziałek, 30 września 2013
35 Maraton Warszawski (2013)
Mój osobisty debiut zakończony powodzeniem. Pogoda dopisała znakomicie. Przyjemnie było w słoneczny niedzielny poranek zrobić 42 kilometrową przebieżkę ulicami Warszawy w towarzystwie tysiąca innych zapaleńców.
Kilka minut po godz. 9.00 zgraja uczestników wyruszyła spod Stadionu Narodowego. Do 20km dawałem radę bez przystanków na picie/jedzenie/siku. Na 20km a potem na 30km i 35km już nie przesadzałem i łykałem trochę PowerRade, wody i przegryzałem banana. Wszystko to dostarczone przez organizatorów. Poza tym co parę kilometrów na trasie słychać było zagrzewające do walki zespoły różnej maści - bębny, saksofon, rock, reggae, gospel.. dla każdego coś miłego.
Na ok. 35km zaczęły się schody - ucisk na stawach kolanowych, odrętwienie i ból nóg, każdy krok powodował ból. Kondycji, sił i chęci jeszcze miałem sporo, ale nogi już nie dawały rady. Trochę pomagał postój na wodopojach, raz też zatrzymałem się żeby rozciągnąć nogi na ok. 38km. Potem już tylko walka żeby nie zatrzymać się, żeby ciągle biec i żeby to się już skończyło :) Ogólnie polecam, wrażenia niezapomniane, szczególnie doping kibiców przy trasie, ludzi w różnym wieku i narodowości.
Moją trasę nagraną Endomondo można przejrzeć tutaj:
Z oficjalnych wyników:
Wszystkie wyniki są tutaj
Więcej zdjęć i informacji na stronie: http://pzumaratonwarszawski.com
Kilka minut po godz. 9.00 zgraja uczestników wyruszyła spod Stadionu Narodowego. Do 20km dawałem radę bez przystanków na picie/jedzenie/siku. Na 20km a potem na 30km i 35km już nie przesadzałem i łykałem trochę PowerRade, wody i przegryzałem banana. Wszystko to dostarczone przez organizatorów. Poza tym co parę kilometrów na trasie słychać było zagrzewające do walki zespoły różnej maści - bębny, saksofon, rock, reggae, gospel.. dla każdego coś miłego.
Na ok. 35km zaczęły się schody - ucisk na stawach kolanowych, odrętwienie i ból nóg, każdy krok powodował ból. Kondycji, sił i chęci jeszcze miałem sporo, ale nogi już nie dawały rady. Trochę pomagał postój na wodopojach, raz też zatrzymałem się żeby rozciągnąć nogi na ok. 38km. Potem już tylko walka żeby nie zatrzymać się, żeby ciągle biec i żeby to się już skończyło :) Ogólnie polecam, wrażenia niezapomniane, szczególnie doping kibiców przy trasie, ludzi w różnym wieku i narodowości.
Moją trasę nagraną Endomondo można przejrzeć tutaj:
Z oficjalnych wyników:
Miejsce
|
7068
|
Nr startowy
|
2383
|
Kat. wiekowa
|
30
|
Miejsce w kat. wiekowej
|
2635
|
Czas netto
|
04:39:24
|
Czas brutto
|
04:53:01
|
Miejsce brutto / netto
|
6415-6288
|
5km
|
00:32:37
|
10km
|
01:04:18
|
15km
|
01:35:56
|
20km
|
02:07:29
|
21km
|
02:16:11
|
25km
|
02:39:15
|
30km
|
03:12:44
|
35km
|
03:47:36
|
40km
|
04:24:06
|
Wszystkie wyniki są tutaj
Więcej zdjęć i informacji na stronie: http://pzumaratonwarszawski.com
niedziela, 1 września 2013
Biegowa Bitwa o Lodz
W sobote 27go lipca 2013 r. odbyła się druga Biegowa Bitwa o Łódź.
Start i meta znalazły się przy krańcówce lini autobusowej nr 51 w Łagiewnikach.
Trasa długości 12 km urozmaicona atrakcjami. Już na początku szlauch strażacki z zimną wodą dla ochłody. To akurat chyba najprzyjemniejszy element programu biorac pod uwagę temperaturę.
Potem pare przeszkód w postaci ławeczek, zwalonych drzew pod którymi trzeba było sie przeczołgać, mordercze podbiegi i zbiegi, rów z wodą, do którego zjeżdżało sie z nasypu, więc chcąc nie chcąc każdy musiał się skompać po szyję w gnojówce :) Potem jeszze pare podbiegów i zbiegów, czołganie, przeskoki przez skrzynie, bieg przez opony i kółeczko z jedna oponą na grzbiecie a potem jeszcze 500m, czołganie sie przez tunel z materiału i meta.
Fotki, filmy i inne relacje można znaleść tu:
http://biegampolodzi.pl/biegowa-bitwa-o-lodz
Start i meta znalazły się przy krańcówce lini autobusowej nr 51 w Łagiewnikach.
Trasa długości 12 km urozmaicona atrakcjami. Już na początku szlauch strażacki z zimną wodą dla ochłody. To akurat chyba najprzyjemniejszy element programu biorac pod uwagę temperaturę.
Potem pare przeszkód w postaci ławeczek, zwalonych drzew pod którymi trzeba było sie przeczołgać, mordercze podbiegi i zbiegi, rów z wodą, do którego zjeżdżało sie z nasypu, więc chcąc nie chcąc każdy musiał się skompać po szyję w gnojówce :) Potem jeszze pare podbiegów i zbiegów, czołganie, przeskoki przez skrzynie, bieg przez opony i kółeczko z jedna oponą na grzbiecie a potem jeszcze 500m, czołganie sie przez tunel z materiału i meta.
Fotki, filmy i inne relacje można znaleść tu:
http://biegampolodzi.pl/biegowa-bitwa-o-lodz
poniedziałek, 19 sierpnia 2013
IV Triatlon Siedlecki
18 sierpnia 2013 odbył się IV Triatlon Siedlecki. Pogoda dopisała a wręcz było zbyt słonecznie i parno.
Na miejscu pojawiłem się przed 12.00 po czym wspólnie z kolega objechaliśmy parę razy trasę rowerowa za każdym razem gubiąc właściwą drogę. Właściwie nikt z organizatorów nie był w stanie wskazać właściwej drogi ale nic to, bo w czasie zawodów trasa była już dobrze oznaczona i nie można było się zgubić.
Po 13.00 wstawiliśmy rowery do boksów i trochę zestresowani oczekiwaliśmy na start. Dla mnie i kolegi był to pierwszy triatlon wiec niemałe emocje.
O 15.00 zaczęło się. Wystartowaliśmy z linii pierwszej boi. Brzmi jakby było to daleko od brzegu ale w rzeczywistości przy samej boi dotykałem nogami dna.
W wodzie znalazło sie ok 150 uczestników wiec było trochę tłoczno ale powoli udało sie wyminąć kilka osób. Atmosfera rywalizacji sprawiła ze nim sie spostrzegłem juz bylem przy drugiej boi, którą trzebabylo opłynąć z prawej i z powrotem do pierwszej boi. Poszło całkiem sprawnie. Wszystkich uczestników miałem nagle po prawej stronie i mogłem swobodnie płynąc przed siebie przez nikogo nieblokowany.
Wybieg z wody, parę zasapanych oddechów przy boksie z rowerem. Wycieram szybko stopy, wciągam skarpety i buty biegowe, wciągam kaszulke z uprzednio przypiętym numerem startowym, zapinam kask, biorę rower i gnam na trasę.
Rower po pływaniu to kolejna cześć triatlonu co do której miałem obawy (nie tak duże, jak co do pływania, bo nigdy nie pływałem zbyt wiele na otwartym akwenie) gdyż mój rower jest juz trochę wysłużony i na około tygodnia przed startem odkryłem ze support potrafi mi przeskakiwać przy zbyt dużym nacisku na pedał. Na naprawę nie było zbytnio czasu. Wolałem juz jechać na takim jak jest z nadzieja ze jakoś to będzie niz rozgrzebać rower na części i nie mieć w ogole na czym pojechać. Jak sie okazało potem na trasie przede mną trafił sie zawodnik który miał dokładnie ten sam problem. Na grząskim piachu słychać bylo tylko trzaski przeskakującego suportu i widać zawodnika kręcącego pedałami w miejscu. Całe szczęście ze wymieniłem opony na grubsze 2.1 cala bo z cienkimi na takim piachu byłoby trudno, chociaż widziałem parę rowerów z oponami na oko 1-1.5 cala.
Jakos udało sie przejechać na tak zwalonym rowerze 2 kolka po 5 km. Na pierwszym zaliczyłem glebe na zakręcie, kiedy to rozpędzony ugrzązłem przednim kołem w muldzie piachu i przeleciałem przez kierownice, na szczęście na ręce a nie nosa. Szybko sie zwlekłem nie tarasując zbytnio ruchu i pognałem dalej, trochę biegnąc po piachu z rowerem, trochę jadąc.
Najlżejsza cześć dla mnie to ostatnia część - bieg 3km. tutaj nie było już problemow sprzętowych ani obawy ze się utopie :) Poszło gładko. Sam się dziwie ale udało mi się uplasować na pozycji 62 z czasem o 18 minut późniejszym od najszybszego uczestnika.
Kolejne moje czasy na odcinkach to:
pływanie (400m): 00:09:40
http://www.maratonczyk.pl/ wyniki_2013/triathlon_ siedlecki_open_18.08.2013.pdf
Zdjęcia z imprezy:
http://www.spin.siedlce.pl/2013/08/18/iv-triathlon-siedlecki/
Inne relacje:
http://akademiatriathlonu.pl/newsy/aktualnosci/wydarzenia/1507-iv-triathlon-siedlecki-czyli-debiut-sprinterki-na-dystansie-sprinterskim
Na miejscu pojawiłem się przed 12.00 po czym wspólnie z kolega objechaliśmy parę razy trasę rowerowa za każdym razem gubiąc właściwą drogę. Właściwie nikt z organizatorów nie był w stanie wskazać właściwej drogi ale nic to, bo w czasie zawodów trasa była już dobrze oznaczona i nie można było się zgubić.
Po 13.00 wstawiliśmy rowery do boksów i trochę zestresowani oczekiwaliśmy na start. Dla mnie i kolegi był to pierwszy triatlon wiec niemałe emocje.
O 15.00 zaczęło się. Wystartowaliśmy z linii pierwszej boi. Brzmi jakby było to daleko od brzegu ale w rzeczywistości przy samej boi dotykałem nogami dna.
W wodzie znalazło sie ok 150 uczestników wiec było trochę tłoczno ale powoli udało sie wyminąć kilka osób. Atmosfera rywalizacji sprawiła ze nim sie spostrzegłem juz bylem przy drugiej boi, którą trzebabylo opłynąć z prawej i z powrotem do pierwszej boi. Poszło całkiem sprawnie. Wszystkich uczestników miałem nagle po prawej stronie i mogłem swobodnie płynąc przed siebie przez nikogo nieblokowany.
Wybieg z wody, parę zasapanych oddechów przy boksie z rowerem. Wycieram szybko stopy, wciągam skarpety i buty biegowe, wciągam kaszulke z uprzednio przypiętym numerem startowym, zapinam kask, biorę rower i gnam na trasę.
Rower po pływaniu to kolejna cześć triatlonu co do której miałem obawy (nie tak duże, jak co do pływania, bo nigdy nie pływałem zbyt wiele na otwartym akwenie) gdyż mój rower jest juz trochę wysłużony i na około tygodnia przed startem odkryłem ze support potrafi mi przeskakiwać przy zbyt dużym nacisku na pedał. Na naprawę nie było zbytnio czasu. Wolałem juz jechać na takim jak jest z nadzieja ze jakoś to będzie niz rozgrzebać rower na części i nie mieć w ogole na czym pojechać. Jak sie okazało potem na trasie przede mną trafił sie zawodnik który miał dokładnie ten sam problem. Na grząskim piachu słychać bylo tylko trzaski przeskakującego suportu i widać zawodnika kręcącego pedałami w miejscu. Całe szczęście ze wymieniłem opony na grubsze 2.1 cala bo z cienkimi na takim piachu byłoby trudno, chociaż widziałem parę rowerów z oponami na oko 1-1.5 cala.
Jakos udało sie przejechać na tak zwalonym rowerze 2 kolka po 5 km. Na pierwszym zaliczyłem glebe na zakręcie, kiedy to rozpędzony ugrzązłem przednim kołem w muldzie piachu i przeleciałem przez kierownice, na szczęście na ręce a nie nosa. Szybko sie zwlekłem nie tarasując zbytnio ruchu i pognałem dalej, trochę biegnąc po piachu z rowerem, trochę jadąc.
Najlżejsza cześć dla mnie to ostatnia część - bieg 3km. tutaj nie było już problemow sprzętowych ani obawy ze się utopie :) Poszło gładko. Sam się dziwie ale udało mi się uplasować na pozycji 62 z czasem o 18 minut późniejszym od najszybszego uczestnika.
Kolejne moje czasy na odcinkach to:
pływanie (400m): 00:09:40
rower pierwsza pętla (5km): 00:37:23
rower druga pętla (5km): 00:14:31
bieganie (3km): 00:18:05
Ogólnie jestem bardzo zadowolony, za rok poprawie wyniki :)
Wyniki:http://www.maratonczyk.pl/
Zdjęcia z imprezy:
http://www.spin.siedlce.pl/2013/08/18/iv-triathlon-siedlecki/
Inne relacje:
http://akademiatriathlonu.pl/newsy/aktualnosci/wydarzenia/1507-iv-triathlon-siedlecki-czyli-debiut-sprinterki-na-dystansie-sprinterskim
poniedziałek, 29 lipca 2013
wtorek, 23 lipca 2013
MongoDB 10gen DB Admin
Idąc za ciosem po ostatnim kursie dla Java developerow przejrzałem też ostatni kurs dla DB Adminów i poza powtórką większości rzeczy znalazłem też pare ciekawostek, np: o komendach:
Web admin page:
Wyjasnienie write concern i cluster-wide commit:
Rekomendowane konfiguracje:
Uzywanie Mongo Profiler:
show profile
db.setProfilingLevel(2) // operacje trwajace ponad 100ms
db.setProfilingLevel(1,3) // operacje trwajace ponad 3ms
db.system.profile.find().sort({$natural: -1}).limit(1).pretty() // last profile entry
db.getProfilingStatus()
db.system.namespaces.find() // info o kolekcjach
mongostat [--port <port number>]
mongotop [--port <port number>]
Pokaż aktywne operacje z ich statystykami:
db.currentOp()
db.killOp(<opid>) // zabicie operacji po id
Kommpaktowanie kolekcji:
db.runCommand ( { compact: '<nazwa kolekcji>', force:true})
Mongo Security:
> use admin
> db.addUser('the_admin','password')
mongo localhost/admin -u the_admin -p password
> db.system.users.find()
Backup:
- mongodump [--db dbname] [--oplog] / mongorestore [--oplogReplay]
- kopia plikow 'data' systemowych (shutdown server, kopia plików) - baza musi byc 'journaling enabled'. Pomocne jest db.fsyncLock() / db.fsyncUnlock() lub jesli backupujemy sharded cluster:
sh.stopBalancer() / sh.startBalancer()
Kolejny kurs ukonczony z dobrym wynikiem 96% z egzaminu koncowego:
i kolejny tez nienajgorzej:
poniedziałek, 17 czerwca 2013
Startup Weekend Lodz 2013
Pierwsze tego typu wydarzenie w Lodzi ale kolejne z kolei w historii. Ludzie z roznych dziedzin spotkali sie w ten weekend w Lodzi, aby wspolnie zrealizowac niezwykle pomysly. Niektórzy przyszli ze swoimi pomysłami, inni przyszli nawiązać nowe znajomości, jeszcze inni pokodować itd.
Ostatecznie spośród wszystkich pomysłów do realizacji zostało wybranych 6:
Creative Learning ! Platforma edukacyjna i rozrywkowa dla dzieci. Oferujemy 2 opcje: 1) aplikacje zajmujące i uciszające dzieci (wyjdą pierwsze!) & 2) aplkaje interaktywne dziecko-dziadek, dziecko-rodzic ( któtkie i proste aplikacje przyciągające dzieci z pomocą rodzica lub dziadka).
Zabawne, kreatywne, edukacyjne i estetyczne aplikacje, o to chodzi w Creative Learning - aplikacje które staną się legendą dziecięcych gier. Jeśli chcesz by Twoje dziecko uczyło się nowych rzeczy i jednocześnie bawiło śledź naszą stronę i FB. Pomóż nam testować produkt i spodziewaj się ich wkrótce na iTunes & Google Play.
- Creative Learning - SHAPES
- Creative Learning - LETTERS
- Creative Learning - NUMBERS
-Creative Learning - ANIMALS
i więcej!
http://www.creative-learning.eu/
Space Lawyer! Najlepsze serwisy prawnicze online, wszędzie i o każdej porze.
ADS ON PETS! Dajemy firmom nowy kanał komunikacji. Przez danie możliwośći miłośnikom zwierząt wyróżnienie się ich pupili, dajemy im też możliwość zarobienia, żeby jeszcze bardziej mogli 'rozpuszczać' swoje pociechy.
Video Pediatric Advice! Platforma, która pozwala pediatrom dawać porady pacjentom przez kamerę.
"Gamming for Cats and feed it"
Idea jest całkiem prosta, kot gra na Ipadzie, jeśli zdobędzie 100 punktów dostanie jedzenie.
W planach rozwoju jeśli przećwiczy 200 kkalori dostaje większą porcję !.
Aplus - to jeden z pomysłów ze startup weekendu. Naucz się matematyki Online. Kamil Kamiński odpowie na wszystkie Wasze pytania z matmy ONLINE.
Ostatecznie do Kaliforni jedzie Dominik z Creative Cats i karmnikiem dla kotów.
2 miejsce - nasz team z serwisem prosteumowy.pl
3 miejsce - allSpotted oraz Video Pediatric Advice!
Media:
http://moya.toya.net.pl/site_aktualnosci.php?news_id=4708&s=6c6d4ca73d8dabf0b3e6558c4704d4b6
http://moya.toya.net.pl/site_aktualnosci.php?news_id=4708&s=6c6d4ca73d8dabf0b3e6558c4704d4b6
Ostatecznie spośród wszystkich pomysłów do realizacji zostało wybranych 6:
Creative Learning ! Platforma edukacyjna i rozrywkowa dla dzieci. Oferujemy 2 opcje: 1) aplikacje zajmujące i uciszające dzieci (wyjdą pierwsze!) & 2) aplkaje interaktywne dziecko-dziadek, dziecko-rodzic ( któtkie i proste aplikacje przyciągające dzieci z pomocą rodzica lub dziadka).
Zabawne, kreatywne, edukacyjne i estetyczne aplikacje, o to chodzi w Creative Learning - aplikacje które staną się legendą dziecięcych gier. Jeśli chcesz by Twoje dziecko uczyło się nowych rzeczy i jednocześnie bawiło śledź naszą stronę i FB. Pomóż nam testować produkt i spodziewaj się ich wkrótce na iTunes & Google Play.
- Creative Learning - SHAPES
- Creative Learning - LETTERS
- Creative Learning - NUMBERS
-Creative Learning - ANIMALS
i więcej!
http://www.creative-learning.eu/
allSpotted! - team stworzy aplikację mobilną na FaceBook-owy rych Spotted ( anonimowej komunikacji pomiędzy użytkownikami przebywającymi w tym samym miejscu). Pozwoli ona znaleść ponownie osobę spotkana czy widzianą ale do której nie masz kontaktu. Aplikacja używa ruch na forach społecznościowych i informację GPS.
Space Lawyer! Najlepsze serwisy prawnicze online, wszędzie i o każdej porze.
ADS ON PETS! Dajemy firmom nowy kanał komunikacji. Przez danie możliwośći miłośnikom zwierząt wyróżnienie się ich pupili, dajemy im też możliwość zarobienia, żeby jeszcze bardziej mogli 'rozpuszczać' swoje pociechy.
Video Pediatric Advice! Platforma, która pozwala pediatrom dawać porady pacjentom przez kamerę.
"Gamming for Cats and feed it"
Idea jest całkiem prosta, kot gra na Ipadzie, jeśli zdobędzie 100 punktów dostanie jedzenie.
W planach rozwoju jeśli przećwiczy 200 kkalori dostaje większą porcję !.
Aplus - to jeden z pomysłów ze startup weekendu. Naucz się matematyki Online. Kamil Kamiński odpowie na wszystkie Wasze pytania z matmy ONLINE.
Ostatecznie do Kaliforni jedzie Dominik z Creative Cats i karmnikiem dla kotów.
2 miejsce - nasz team z serwisem prosteumowy.pl
3 miejsce - allSpotted oraz Video Pediatric Advice!
Media:
http://moya.toya.net.pl/site_aktualnosci.php?news_id=4708&s=6c6d4ca73d8dabf0b3e6558c4704d4b6
http://moya.toya.net.pl/site_aktualnosci.php?news_id=4708&s=6c6d4ca73d8dabf0b3e6558c4704d4b6
wtorek, 11 czerwca 2013
Dzem malinowy
Wczoraj dotarla do mnie zamowiona na Allegro malinka. Swieża i pachnaca nowoscią Raspberry Pi. Dzis postawnowilem ja wypróbowac.
Zgodnie z tutorialem na stronie zbootowalem system po podlaczeniu tego malego cuda do telewizora.
Uprzednio zainstalowalem na karcie SD 4GB obraz "New Out of Box Software".
Po podlaczeniu zasilania obraz zbootowal sie bezproblemowo, wykryl klawiature i odpalil UI graficzny z wyborem systemu do instalacji.
Wybralem instalacje zalecaną - Raspbian
OK, wszystko fajnie, tylko brakuje mi monitora a sleczenie przy telewizorze za kazdym razem jest malo wygodne, dlatego potrzebowalem skonfigurowac polaczenie SSH.
Tu pojawil sie drobny klopot. Mam w domu router DHCP ale jak znalesc jaki adres IP zostal przydzielony Raspberry Pi?
Z pomocą przyszlo narzędzie nmap
Na innym kompie z Ubuntu podlaczonym do tej samej sieci odpalam:
gdzie XXXX w wpa-ssid to nazwa naszej sieci WIFI a XXXXX w wpa-psk to hasło do sieci.
Zgodnie z tutorialem na stronie zbootowalem system po podlaczeniu tego malego cuda do telewizora.
Uprzednio zainstalowalem na karcie SD 4GB obraz "New Out of Box Software".
Po podlaczeniu zasilania obraz zbootowal sie bezproblemowo, wykryl klawiature i odpalil UI graficzny z wyborem systemu do instalacji.
Wybralem instalacje zalecaną - Raspbian
OK, wszystko fajnie, tylko brakuje mi monitora a sleczenie przy telewizorze za kazdym razem jest malo wygodne, dlatego potrzebowalem skonfigurowac polaczenie SSH.
Tu pojawil sie drobny klopot. Mam w domu router DHCP ale jak znalesc jaki adres IP zostal przydzielony Raspberry Pi?
Z pomocą przyszlo narzędzie nmap
Na innym kompie z Ubuntu podlaczonym do tej samej sieci odpalam:
nmap -sP 192.168.1.0/24
i otrzymuje:
Starting Nmap 6.00 ( http://nmap.org ) at 2013-06-11 17:45 CEST Nmap scan report for 192.168.1.1 Host is up (0.00082s latency). Nmap scan report for 192.168.1.103 Host is up (0.061s latency). Nmap scan report for 192.168.1.105 Host is up (0.00011s latency). Nmap scan report for 192.168.1.106 Host is up (0.00065s latency). Nmap done: 256 IP addresses (4 hosts up) scanned in 2.65 seconds
Przy okazji, podobny efekt mozna uzyskac na Windows uzywajac:
arp -a
otrzymuje:
Interfejs: 192.168.1.104 --- 0xf Adres internetowy Adres fizyczny Typ 192.168.1.1 00-22-6b-fb-a3-17 dynamiczne
192.168.1.103 78-d6-f0-65-4e-a7 dynamiczne192.168.1.105 14-da-e9-11-6f-93 dynamiczne 192.168.1.106 00-0b-81-87-d8-b9 dynamiczne
Dostalem wiec adresy 3ch urzadzen, tylko ktore z nich to RPi ? Jedyne wyjscie jakie znalazlem to sprawdzenie IP na dwóch pozostałych i dojscie do rozwiazania droga eliminacji.
Następnie:
ssh pi@192.168.1.106
i jestem podłączony w trybie 'headless' tyle ze kablem.
Fajnie byloby sie poczuc wireless :)
Nie ma problemu, trzeba tylko zakupic male urządzonko - koncowke usb wifi na chipsecie Realtek RTL8188CUS. Nastepnie postępujemy dokladnie tak jak w linku:
Zmieniamy zawartość pliku
/etc/network/interfacestak jak poniżej:
auto lo iface lo inet loopback iface eth0 inet dhcp allow-hotplug wlan0 auto wlan0 iface wlan0 inet dhcp wpa-ssid “XXXXXX-XXXXXX” wpa-psk “XXXXXXXXX”
gdzie XXXX w wpa-ssid to nazwa naszej sieci WIFI a XXXXX w wpa-psk to hasło do sieci.
Teraz przydałoby się przekierować display z RPi na Ubuntu zeby troche sobie poklikac w Raspbianie.
Nic prostszego pod Ubuntu.
Najpierw pozwalamy Ubuntu akceptowac polaczenia z zewnatrz
sudo xhost +
sprawdzamy swoje IP:
ifconfig
wlan0 Link encap:Ethernet HWaddr 10:0b:a9:ca:23:78
inet addr:192.168.1.106 Bcast:192.168.1.255 Mask:255.255.255.0
logujemy sie przez ssh do Raspberry i przeierowujemy display:
ssh -XY pi@192.168.1.107
export DISPLAY=192.168.1.106:10
gotowe, teraz np mozemy uruchomic konfigurator ustawien:
sudo raspi-config
Jesli chcesz dowiedzieć sie co jeszcze możesz zrobić, zerknij na mój angielski blog:
http://piczkowski.blogspot.com/2013/11/raspberry-magic.html
http://piczkowski.blogspot.com/2013/11/rspberry-pi-webcam.html
Nic prostszego pod Ubuntu.
Najpierw pozwalamy Ubuntu akceptowac polaczenia z zewnatrz
sudo xhost +
sprawdzamy swoje IP:
ifconfig
wlan0 Link encap:Ethernet HWaddr 10:0b:a9:ca:23:78
inet addr:192.168.1.106 Bcast:192.168.1.255 Mask:255.255.255.0
logujemy sie przez ssh do Raspberry i przeierowujemy display:
ssh -XY pi@192.168.1.107
export DISPLAY=192.168.1.106:10
gotowe, teraz np mozemy uruchomic konfigurator ustawien:
sudo raspi-config
Jesli chcesz dowiedzieć sie co jeszcze możesz zrobić, zerknij na mój angielski blog:
http://piczkowski.blogspot.com/2013/11/raspberry-magic.html
http://piczkowski.blogspot.com/2013/11/rspberry-pi-webcam.html
wtorek, 5 marca 2013
Indie 04.2013
W tym roku pora na Indie. Wyjazd firmowy na tydzien ale potem daje sobie jeszcze jeden tydzien na zwiedzanie.
Co przed wyjazdem? W pierwszej kolenosci wiza, na ktora sie czeka do 3 tyg.
Wymagane dokumenty to*:
1. Wniosek wizowy wypelniany online i drukowany
2. List polecajacy z firmy (w przypadku wizy biznesowej
3. Zaproszenie z firmy w Indiach (w przypadku wizy biznesowej)
4. Zdjęcie paszportowe (3,5 x 4,5cm)
5. Oryginal paszportu
6. Kopia biletu lotniczego lub rezerwacji (w obie strony)
Do tego przy skladaniu wniosku nalezy uiscic oplate eg. cennika:
Lp. | Rodzaj wizy | Opłatawizowa (PLN) | ICWF | Opłata z tytułu kosztów obsługi BLS (w PLN) | Całkowity koszt (w PLN) |
1 | Wiza turystyczna | 184 | 8 | 40 | 232 |
2 | Wiza biznesowa | 667 | 8 | 40 | 175 |
*informacje zaczerpniete ze strony Ambasady Indii
Wiecej wiesci z planowania podróży i pobytu niebawem...
czwartek, 28 lutego 2013
Konkurs OneWebSQL
Ostatnimi czasy zajmuje sie glownie budowaniem mojego ego :))
Pierwszy raz od dawien dawna udalo mi sie nawet cos wygrac
http://onewebsql.com/konkurs-spring
http://e-point.pl/co-nowego?news_id=1500144,rozstrzygniecie-konkursu-na-najlepsza-aplikacje-webowa
Zaproponowane przeze mnie rozwiazanie jest upublicznione na githubie. Przyznam szczerze ze zmienilbym w nim jeszcze pare rzeczy, glownie zwiazanych z warstwa widoku. Najlepiej przepisal JSP na AngularJS.
Pierwszy raz od dawien dawna udalo mi sie nawet cos wygrac
http://onewebsql.com/konkurs-spring
http://e-point.pl/co-nowego?news_id=1500144,rozstrzygniecie-konkursu-na-najlepsza-aplikacje-webowa
Zaproponowane przeze mnie rozwiazanie jest upublicznione na githubie. Przyznam szczerze ze zmienilbym w nim jeszcze pare rzeczy, glownie zwiazanych z warstwa widoku. Najlepiej przepisal JSP na AngularJS.
wtorek, 26 lutego 2013
MongoDB 10gen Kurs
Kurs wystartował kolejny raz.
Przeszedłem instalacje MongoDB, podstawowe query z mongo shell i aplikacji Javowej.
Poznałem Spark Micro Web Framework i FreeMarket templaty.
Jak narazie OK, niezbyt trudne cwiczenia do przejscia w jedną noc.
Założyłem projekt github na potrzeby szkolenia https://github.com/piczmar/MongoDB4JavaDev/
2 czesc kursu
to podstawy CRUD i zapoznanie z Mongo Shell - interaktywna konsola dostepu do bazy, ktora jest interpretorem JavaScript.
Przydatne skroty klawiszowe:
- przywolanie ostatniej komendy: strzalka do gory
- przeskoczenie na poczatek linii: CTRL+A
- przeskoczenie na koniec linii: END
- dokonczenie polecenia/metody: TABrepli
Przydatne komendy:
help - wyswietla liste komend
help keys - wyswietla skroty klawiszowe
Mozna wykonywac pliki json z konsoli, np stworzmy plik o nazwie popAvg.json ktory chcemy wykonac na bazie o nazwie week5
use week5
db.zips.aggregate([{
$group:{
_id:'$state',
average_pop:{$avg:'$pop'}
}
}])
plik mozemy uruchomic:
mongo < popAvg.json
Zapoznanie z podstawami JavaScript, np definiowanie obiektow i odwolywanie sie do ich wlasnosci:
x = {a:"test"} // tworzy nowy obiekt
x.a // odwolanie do atrybutu a jako literalu
z="a"
x[z] //odwolanie do atrybutu jako wartosci slownikowej (ang. dictionary) klucz : wartość
Mongo zapisuje obiekty w formacie BSON
Podstawowe typy danych:
NumberInt - integer 32bity
NumerLong - integer 64bity
ISODate - date, new Date() tworzy ten typ danych
Zapisywanie obiektow:
db - zmienna trzymajaca aktualna baze
db.nazwa - kolekcja o nazwie 'nazwa' w bazie, zeby do niej zapisac nalezy wykonac metode insert np:
db.nazwa.insert(doc)
Wyszukiwanie:
db.people.find() - zwraca wszystkie obiekty, jesli podamy kryteria wyniki beda przefiltrowane, np:
db.people.find({name:"John"})
db.scores.find({score:200}).pretty() - wyswietla sformatowany wynik
db.people.findOne() - zwraca pierwszy lepszy rekord z kolekcji jesli nie podamy kryteriow, drugi argument po kryteriach prezycuje jakie pola chcemy w wyniku
> db.people.findOne({name:"Smith"})
{ "_id" : ObjectId("513ba7e947631d66ce571e99"), "name" : "Smith" }
> db.people.findOne({name:"Smith"},{"name":true, "_id":false})
{ "name" : "Smith" }
Wypisanie obiektu jako json:
var obj = db.people.findOne()
printjson(obj)
Wyszukiwanie za pomoca wyrazen:
db.scores.find({score:{$gt:10, $lte:20}}) - znajdz rekordy ktorych 'score'>10 && 'score'<20
Kryteria uzywaja porownania leksygraficznego tzn ze jesli w tej samej kolekcji pole jest typu string dla jednego rekordy a typu numerycznego dla innego i w kryterium uzywamy porownania dla stringow to rekordy w ktorych to pole nie jest stringiem sa w ogole pomijane.
Mozna tez przefiltrowac rekordy ktore maja dany atrybut, np:
db.people.find({profession: {$exists: true}}) - zwraca tylko te rekordy ktore maja atrybut 'profession'
lub atrybut okreslonego typu:
db.people.find({profession: {$type: 2}}) - rekordy z atrybutem 'profession' typu string, numery dla typow sa zdefiniowane w specyfikacji BSON
lub uzyc wyrazenie regularne:
db.people.find({name: {$regex: "m$"}}) - tylko rekordy ktorych 'name' konczy sie na litere 'm'
db.people.find({name: {$regex:'q'}})- rekordy ktorych 'name' zawiera litere 'q'
Unia OR:
db.people.find( { $or: [{name:"Adam"}, {profession:{$lte:"programmer"}}] })
Koniunkcja AND:
db.people.find( { $and: [{name:{$gt:"C"}}, {name:{$regex:"a"}}]}) - mozna to zapisac prosciej jako:
db.people.find( { name:{$gt:"C", $regex:"a"} })
Kryteria dla kolekcji
{ "_id" : ObjectId("513bb7374802e675111ba1c9"), "name" : "Howard", "favourites" : [ "pretzels", "beer" ] }
db.accounts.find({favourites:{$in:["pretzels", "chease"]}}) - wrzystkie rekordy zawierajace w polu 'favourites' wartosci 'pretzels' lub 'chease'
db.accounts.find({favourites:{$all:["pretzels", "chease"]}}) - wrzystkie rekordy zawierajace w polu 'favourites' wartosci 'pretzels' i 'chease' w dowolnej kolejnosci
Kryteria dla zagnieżdżonych dokumentow:
{ product : "Super Duper-o-phonic", price : 100000000000, reviews : [ { user : "fred", comment : "Great!" , rating : 5 }, { user : "tom" , comment : "I agree with Fred, somewhat!" , rating : 4 } ], ... }
db.catalog.find({price: {$gt:10000}, "reviews.rating": {$gte:5}}) - zwraca wszystkie produkty z price > 10000 i rating >=5
metoda find() zwraca kursor ktory ma metody: hasNext() i next() przydatne do nawigowania po wynikach, np:
> cur = db.people.find(); null; // null jako druga komenda zapobiega drukowaniu wyniku
> cur.limit(5); null; // limit do 5 rekordow
> cur.skip(2); null; // pomiń 2 recordy z wyniku
> cur.sort({name: -1}); null; // sortuj wynik po 'name' w odwrotnym porządku leksykograficznym
> cur.hasNext()
> cur.next()
Liczenie recordow:
db.scores.count({type:"essay", score: {$gt:90}})
Update:
db.people.update({name:"Adam"}, {profession: "seller"}) - update bierze 2 argumenty, 1: query, 2: nowe wartosci pól, pola pominiete zostana usunięte z dokumentu
np.:
{ "_id" : "Texas", "population" : 2500000, "land_locked" : 1 }
db.foo.update({_id:"Texas"},{population:30000000})
wynik: { "_id" : "Texas", "population" : 30000000 }
Inny sposob ktory modyfikuje tylko wybrane pola:
db.foo.update(_id:"Texas", {$set: {population: 30000}})
lub inkrementacja:
db.foo.update(_id:"Texas", {$inc: {population: 1}})
Jesli nie podamy kryterium to domyslnie zostanie updatowany pierwszy znaleziony a nie wszystkie jak to jest w SQL. Zeby updatowac wszystkie trzeba podac dodatkowy argument {mutil:true}
db.people.update({}, {$set:{title:"Dr"}}, {multi : true})
db.people.update({}, {$set:{title:"Dr"}}, {upsert : true}) //updatuje istniejace dokumenty lub utworzy nowy jesli nie znalazl dokumentow do updatowania
Iindywidualny dokument jest updatowany atomowo, ale Mongo nie wspiera izolowanych tranzakcji przy updacie wielu dokumentow na raz.
Usuwanie pol:
db.foo.update(_id:"Texas", {$unset: {population: 1}})
Operatory tablicowe:
$push, $pop, $pull, $pushAll, $pullAll, $addToSet
np:
> db.arrays.insert({_id:0, a:[1, 2, 3, 4]}) //tworzymy nowy obiekt z tablicą 'a'
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 1, 2, 3, 4 ] }
> db.arrays.update({_id:0}, {$set: {"a.2":5}}) //zmien element tbalicy o indeksie 2
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 1, 2, 5, 4 ] }
> db.arrays.update({_id:0}, {$push:{a:6}}) //dodaj nowy element na koniec tablicy
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 1, 2, 5, 4, 6 ] }
> db.arrays.update({_id:0}, {$pop:{a:1}}) //usun element z konca tablicy
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 1, 2, 5, 4 ] }
> db.arrays.update({_id:0}, {$pop:{a:-1}}) // usun element z poczatku tablicy
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 2, 5, 4 ] }
> db.arrays.update({_id:0}, {$pushAll:{a:[7,8,9]}}) // dodaj kilka elem. na koniec tablicy
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 2, 5, 4, 7, 8, 9 ] }
> db.arrays.update({_id:0}, {$pullAll:{a:[7,8,9]}}) //usun wszystkie elementy jak podane w liscie
^[db.arrays.findOne()
{ "_id" : 0, "a" : [ 2, 5, 4 ] }
> db.arrays.update({_id:0}, {$pull:{a:5}}) // usun pojedynczy element
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 2, 4 ] }
> db.arrays.update({_id:0}, {$addToSet:{a:5}}) // dodaj nowy element jesli jeszcze nie istnieje
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 2, 4, 5 ] }
> db.arrays.update({_id:0}, {$addToSet:{a:5}}) //dodaj nowy element jesli jeszcze nie istnieje
> db.arrays.findOne()
{ "_id" : 0, "a" : [ 2, 4, 5 ] }
Usuwanie rekordow:
db.people.remove({}) //usuwa wszystkie dokumenty z kolekcji, jeden po jednym
db.people.drop() //usuwa wszystkie dokumenty z kolekcji bardziej efektywnie niz powyzsze remove({}) bo nie pojedynczo tylko cala kolekcje
db.people.remove({name: "Adam"}) // usuwa dokumenty spelniajace okreslone kryteria
Usuwanie wielu rekordow nie jest atomowe, ale pojedynczego juz tak. Zaden reader nie zobaczy dokumenty Mongo w polowie usunietego.
Jak sprawdzic czy ostatnio wykonana operacja przebiegla poprawnie czy nie:
db.runCommand({getLastError: 1})
przyklad wyniku:
{
"err" : "E11000 duplicate key error index: test.people.$_id_ dup key: { : \"Smith\" }",
"code" : 11000,
"n" : 0,
"connectionId" : 3,
"ok" : 1
}
To samo co w konsoli mozemy zrobic przy użyciu Java API, demo dostepne na githubie.
W dalszej czesci kursu bedziemy budowac aplikacje webowa. Zasa dzialania zostala opisana na filmie:
Porzyteczne narzedzia do profilowania w Mongo to:
z konsoli Mongo:
db.getProfilingStatus() - zwtaca aktualny status logowania
db.setProfilingLevel(1,3) - poziom logowania 1, trwajace dluzej niz 3ms, dostepne poziomy:
0 - logowanie wylaczone
1 - pokazuj tylko wolne operacje
2- pokazuj wszystkie operacje
Logi sa zapisywane do db.system.profile i moga byc przeszukiwane np:
db.system.profile.find({millis:{$gt: 1000}}).sort({ts:-1})
programy ktore sa instalowane razem z mongo:
mongotop - dostarcza statystyki na poziomie kolekcji mowiace ile Mongo spedza czasu na operacjach zapisu/odczytu
mongostat -statustyki operacji mongo zwlaszcza pozyteczne - wykorzystanie indeksow
Tydzien 5:
Agregacje w Mongo.
W SQL odpowiednikiem jest GROUP BY.
Zalozmy ze mamy kolekcje car zawierajaca dokumenty:
{name: 'car', price: '12}
{name: 'car', price: '2'}
> db.manuf.aggregate([{$group: { _id:'$name', num_car:{$sum:1}}}])
{ "result" : [ { "_id" : "car", "num_car" : 2 } ], "ok" : 1 }
dostajemy w wyniku liczbe dokumentow z name='car'
jesli chcielibysmy zsumowac ceny w grupie:
> db.manuf.aggregate([{$group: { _id:'$name', prices:{$sum: '$price'}}}])
Elementy pipline aggregacji:
$project - wybiera ktore atrybuty chcemy w wyniku
$match - filtruje kolekcje po jakims kryterium, jak WHERE w SQL
$group - grupuje wynik poprzedniego kroku pipeline
$sort - jak ORDER BY w SQL, sortuje wynik
$skip - omija iles poczatkowych rekordow
$limit - ogranicza wynik do iluś rekordow.
$inwind - normalizuje dane, jesli dokument ma tablice 3 rekordow to inwind utworzy 3 oddzielne dokumenty z jednym elementem tablicy
Compound grouping by multiple group:
mamy dokumenty:
{ "_id" : ObjectId("5154ba3f7b1fda1c6b22429b"), "category" : "drive", "name" : "car", "price" : 12 }
{ "_id" : ObjectId("5154ba437b1fda1c6b22429c"), "category" : "drive", "name" : "car", "price" : 23 }
{ "_id" : ObjectId("5154bf547b1fda1c6b22429d"), "category" : "drive", "name" : "bike", "price" : 10 }
{ "_id" : ObjectId("5154c1247b1fda1c6b22429e"), "category" : "swim", "name" : "canoo", "price" : 100 }
{ "_id" : ObjectId("5154c12f7b1fda1c6b22429f"), "category" : "swim", "name" : "boat", "price" : 101 }
db.manuf.aggregate([{$group:{_id:{name:'$name',categ:'$category'},sum:{$sum:1}}}])
dostaniemy:
{
"result" : [
{
"_id" : {
"name" : "boat",
"categ" : "swim"
},
"sum" : 1
},
{
"_id" : {
"name" : "canoo",
"categ" : "swim"
},
"sum" : 1
},
{
"_id" : {
"name" : "bike",
"categ" : "drive"
},
"sum" : 1
},
{
"_id" : {
"name" : "car",
"categ" : "drive"
},
"sum" : 2
}
],
"ok" : 1
}
Inne wyrazenia uzywane w grupowaniu:
$sum
$avg
$min
$max
$push
$addToSet
$first - uzywane z sort, daje pierwszy dokument
$last - uzywane z sort, daje ostatni dokument
Przyklady zastosowania niektorych operatorow na githubie.
Ograniczenia aggregacji:
- rozmiar wyniku ograniczony do 16MB (jako że wynik jest pojedynczym dokumentem)
- nie mozna uzyc wiecej niz 10% pamieci maszyny
- sharding: kolekcje sa na rozych nodach klastra, po pierwszym pipe $sort lub $group wynik musi byc zwrocony na klienta (tam gdzie dziala process 'mongos')
Jesli z powodu tych ograniczen nie mizna uzyc agregacji mozemy zamiast tego uzyc:
- mapreduce
- hadoop (jest konektor do mongo)
Tworzenie klastra na pojedynczej maszynie - koniecznie na roznych portach, normalnie stworzylibysmy na roznych serwerach:
1. tworzymy foldery danych dla 3ch replik:
mkdir c:\data\rs1
mkdir c:\data\rs2
mkdir c:\data\rs3
mongod --replSet rs1 --logpath "1.log" --dbpath c:\data\rs1 --port 27017
mongod --replSet rs1 --logpath "2.log" --dbpath c:\data\rs2 --port 27018
mongod --replSet rs1 --logpath "3.log" --dbpath c:\data\rs3 --port 27019
re
wszystie sa czescia tego samego zbiory replik rs1
Tworzymy konfiguracje dla zbioru w pliku init_replica.js:
config = { _id: "rs1", members:[
{ _id : 0, host : "localhost:27017", priority:0, slaveDelay:5},
{ _id : 1, host : "localhost:27018"},
{ _id : 2, host : "localhost:27019"} ]
};
rs.initiate(config);
rs.status();
Plik ten ladujemy do jednego z wezlow:
mongo --port 27018 < init_replica.js
Teraz laczymy sie do jednego z nodow i drukujemy status
mongo --port 27018
rs.status()
Mozemy sie polaczyc do jednego z SECONDARY node i sprawdzic ze nie mozemy do nich pisac, tylko mozna pisac do PRIMARY.
Jesli chcemy czytac z SECONDARY musimy najpierw powiadomic go o tym i po polaczeniu sie do niego wywolac:
rs.slaveOK()
rs.isMaster() - sprawdzenie czy node do ktoredo sie zalogowalismy jest MASTERem
Jak sprawdzic co sie dzieje podczas replikacji? Mamy w tym celu kolekcje oplog.rs:
use local
show collections
Tydzien 6. Sharding
Co to jest sharding? Jest to dzielenie kolekcji na wiele serwerów.
Po polaczeniu do mongo konsoli na domyslnym porcie ('mongo') mozemy sprawdzic status sharda:
sh.status()
oraz informacje o shardowanej kolekcji:
db.grades.stats()
Kazdy dokument miec shard key.
Shard key jest niezmienny.
Indexy musza sie zaczynac od shard key, np jesli jest shard key 'student_id'
to pozostale indeksy np:
(student_id, class)
(student_id, name)
Przy zapytaniach jesli nie uzyjemy shard key to zapytanie bedzie rozpropagowane na wszystkie nody w klastrze zamiast do poprawnego sharda.
Egzamin koncowy zdany na 95%, chyba powinienem czuć sie MongoDB expertem, jednak czuje ze ta wiedza szybko wyparuje jeśli nie będę jej używać.
sobota, 23 lutego 2013
Wykonanie SQLi przy starcie aplikacji Grails
Jak wrzucic do Grails dataSource zdefiniowanego w DataSource.groovy jakies dane wykonujac skrypty SQL?
1. Dodaj nowy plik grails-app/config/spring/resources.xml a w nim:
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="classpath:/com/initdb/data.sql" />
<jdbc:script location="classpath:/com/initdb/data2.sql" />
</jdbc:initialize-database>
2. Umiesc skrypty zdefiniowane w kroku 1. w class path, czyli stworz nowy folder w src/java lub src/groovy
com/initdb
i dodaj w nim swoje skrypty SQL: data.sql, data2.sql
i dodaj w nim swoje skrypty SQL: data.sql, data2.sql
sobota, 12 stycznia 2013
Code Retreat Warszawa 2013
Swoj drugi w zyciu code retreat minął pomyślnie. Bylo ciekawie i owocnie. W odróżnieniu od pierwszego code retreat ktory skupiał sie na czystej Javie i TDD tym razem rozwijalismy aplikacje w Androidzie.
Od czasu kiedy uczylem się Androida i pisalem pierwsze aplikacje na tą platforme minęło kilka lat. Nic dziwnego ze w tym czasie wiele sie zmieniło w kwestii narządzi deweloperskich. Pomysł pokazania w jaki sposob Groovy moze zaistniec na tym polu przynajmniej dla mnie była trafiona.
Chłopaki z Polidea zrobili kawal dobrej roboty integrujac Roboelectric ze Spockframework z czego powstalo RoboSpock. Co więcej, przed spotkaniem przygotowali nawet startowy projekt. O ile Spockframework mialem okazje używać przy testowaniu aplikacji w Grails, zachwycony łatwością pisania testow, o tyle Roboelectric i buildy w Gradle byly dla mnie czyms zupelnie nowym.
Na poczatku mieliśmy trochę kłopotów z uruchomieniem projektu w IDE (Eclipse, Idea) ale wkrótce wiekszosci udało się to naprawić. W czasie sesji panowała zupełna dowolność. To para wybierała sobie temat - m.in. ćwiczenie TDD, nauka skrótów klawiszowych, kodowanie na kartce, ustalenie utrudnień (max 2 pola na klasę, max 4 linijki na metodę), testowanie widoków (Android View). W przerwie można było pograć w Quoridor.
Mnie udało się w pierwszej sesji poćwiczyć TDD na zwykłym projekcie Javowym, potem powalczyłem z postawieniem projektu w Idei, następnie parę testów TDD w projekcie Androidowym.
Organizatorzy postawili nam również obiad, nie byle jaki ale składający się z pierwszego, drugiego dania i deseru :) Szacun dla nich.
Po obiedzie jeszcze parę sesji ale ogólny pęd do kodowania został trochę uśpiony (być może z powodu dobrego posiłku). W tej części poznałem bliżej roboguice i nauczyłem paru nowych skrótów klawiszowych w Idei. Dla szybszej nauki skrótów może być przydatny plugin Key Promoter
(mousefeed to plugin dla Eclipse)
Niektóre przydatne skróty:
ctrl + j - wrzuć template kodu np. psvm rozwija domyślnie na public static void main (String[]args)...
ctrl + alt + N - na metodzie zamienia wszystkie wywołania tego kodu ciałem metody i usuwa metodę
ctrl + alt + M - ekstrakt metody
ctrl + alt + V - ekstrakt zmiennej
ctrl + alt + F - ekstrakt pola
ctrl + alt + C - ekstrakt stałej
ctrl + alt + P - ekstrakt do paramertu metody
f2 - przenosi do najbliższego błędu kompilacji
alt + enter - autogenerate (metody lub przypisanie do zmiennej)
alt ~ - diff repo
ctrl + shift + 1 - podlinkowanie linii do 'ulubionych' pod pierwsza pozycja, analogicznie dla 2, 3..
ctrl +1 - skok do linku z ulubionych pod pierwszą pozycją
shift + f11 - wyświetlenie listy ulubionych
ctrl + q - wyświetla javadoc dla metody
ctrl + shift + f10 - run projektu
shift + f9 - debug projektu
ctrl + shift +strzałka góra/dół - przenoszenie linii kodu lub całej metody w dórę/dół pliku
Na koniec jedni się rozeszli a inni zostali jeszcze by kontynuować dyskusje przy browarze u Znajomych Znajomych ;)
A oto jak się skupiałem podczas jednej z sesji :D
Od czasu kiedy uczylem się Androida i pisalem pierwsze aplikacje na tą platforme minęło kilka lat. Nic dziwnego ze w tym czasie wiele sie zmieniło w kwestii narządzi deweloperskich. Pomysł pokazania w jaki sposob Groovy moze zaistniec na tym polu przynajmniej dla mnie była trafiona.
Chłopaki z Polidea zrobili kawal dobrej roboty integrujac Roboelectric ze Spockframework z czego powstalo RoboSpock. Co więcej, przed spotkaniem przygotowali nawet startowy projekt. O ile Spockframework mialem okazje używać przy testowaniu aplikacji w Grails, zachwycony łatwością pisania testow, o tyle Roboelectric i buildy w Gradle byly dla mnie czyms zupelnie nowym.
Na poczatku mieliśmy trochę kłopotów z uruchomieniem projektu w IDE (Eclipse, Idea) ale wkrótce wiekszosci udało się to naprawić. W czasie sesji panowała zupełna dowolność. To para wybierała sobie temat - m.in. ćwiczenie TDD, nauka skrótów klawiszowych, kodowanie na kartce, ustalenie utrudnień (max 2 pola na klasę, max 4 linijki na metodę), testowanie widoków (Android View). W przerwie można było pograć w Quoridor.
Mnie udało się w pierwszej sesji poćwiczyć TDD na zwykłym projekcie Javowym, potem powalczyłem z postawieniem projektu w Idei, następnie parę testów TDD w projekcie Androidowym.
Organizatorzy postawili nam również obiad, nie byle jaki ale składający się z pierwszego, drugiego dania i deseru :) Szacun dla nich.
Po obiedzie jeszcze parę sesji ale ogólny pęd do kodowania został trochę uśpiony (być może z powodu dobrego posiłku). W tej części poznałem bliżej roboguice i nauczyłem paru nowych skrótów klawiszowych w Idei. Dla szybszej nauki skrótów może być przydatny plugin Key Promoter
(mousefeed to plugin dla Eclipse)
Niektóre przydatne skróty:
ctrl + j - wrzuć template kodu np. psvm rozwija domyślnie na public static void main (String[]args)...
ctrl + alt + N - na metodzie zamienia wszystkie wywołania tego kodu ciałem metody i usuwa metodę
ctrl + alt + M - ekstrakt metody
ctrl + alt + V - ekstrakt zmiennej
ctrl + alt + F - ekstrakt pola
ctrl + alt + C - ekstrakt stałej
ctrl + alt + P - ekstrakt do paramertu metody
f2 - przenosi do najbliższego błędu kompilacji
alt + enter - autogenerate (metody lub przypisanie do zmiennej)
alt ~ - diff repo
ctrl + shift + 1 - podlinkowanie linii do 'ulubionych' pod pierwsza pozycja, analogicznie dla 2, 3..
ctrl +1 - skok do linku z ulubionych pod pierwszą pozycją
shift + f11 - wyświetlenie listy ulubionych
ctrl + q - wyświetla javadoc dla metody
ctrl + shift + f10 - run projektu
shift + f9 - debug projektu
ctrl + shift +strzałka góra/dół - przenoszenie linii kodu lub całej metody w dórę/dół pliku
Na koniec jedni się rozeszli a inni zostali jeszcze by kontynuować dyskusje przy browarze u Znajomych Znajomych ;)
A oto jak się skupiałem podczas jednej z sesji :D
środa, 2 stycznia 2013
Grails - klasa domenowa tylko do odczytu
Grails domyślnie nie wspiera oznaczenia klasy domenowej jako tylko do odczyty, tzn. tak żeby dynamiczne metody 'find' (find, get, list..) działały OK ale zapis, edycja encji nie była możliwa. Opcja taka jest szczególnie przydatna przy pracy z legacy bazami danych. Możemy jednak małym nakładem pracy zapewnić podobną funkcjonalność samemu. Udało mi się znaleźć przynajmniej 2 sposoby:
1. listenery beforeXXX w klasie domenowej np.:
class Demo {
static constraints = {
}
String name
transient beforeUpdate = {
throw new RuntimeException('update not allowed')
}
}
2. zwracanie kodu błędu z kontrolera dla niedozwolonych metod, np.:
def delete(Long id) {
response.sendError(405)
}
Natomiast jeśli chcemy tylko wyłączyć z edycji w widoku wygenerowanym ze scaffoldingu jakieś pole klasy domenowe dostępna jest opcja w constrains:
class Demo {
static constraints = {
name(editable: false)
}
String name
1. listenery beforeXXX w klasie domenowej np.:
class Demo {
static constraints = {
}
String name
transient beforeUpdate = {
throw new RuntimeException('update not allowed')
}
}
2. zwracanie kodu błędu z kontrolera dla niedozwolonych metod, np.:
def delete(Long id) {
response.sendError(405)
}
Natomiast jeśli chcemy tylko wyłączyć z edycji w widoku wygenerowanym ze scaffoldingu jakieś pole klasy domenowe dostępna jest opcja w constrains:
class Demo {
static constraints = {
name(editable: false)
}
String name
}
Subskrybuj:
Posty (Atom)