<?xml version="1.0" encoding="iso-8859-15"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>TWiki Blog (combined)</title>
<subtitle type="html">Blogi deweloperów PLD/FreeBSD</subtitle>
<updated>2008-01-27T20:31:36Z</updated><link rel="self" type="application/atom+xml" href="http://wiki.pld-freebsd.org/bin/view/Blog/WebAtomCombined" />
<link rel="alternate" type="text/html" hreflang="cs,da,de,en,es,fr,it,nl,pl,pt,ru,sv,zh-cn,zh-tw" href="http://wiki.pld-freebsd.org/bin/view/Blog/WebAtomCombined" /><logo>http://wiki.pld-freebsd.org/pub/TWiki/TWikiLogos/T-logo-140x40-t.gif</logo><generator uri="http://wiki.pld-freebsd.org/bin/view/TWiki/BlogPlugin">
  TWiki TWiki-4.1.2, Sat, 03 Mar 2007, build 13046, BlogPlugin $Rev: 11407$
</generator>
<id>tag:wiki.pld-freebsd.org,2008-05-18:Blog.WebAtomCombined</id>
<rights>Copyright &#169; 2008</rights>
<entry>
<title>Eppur si muove...</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry8" />
<id>tag:wiki.pld-freebsd.org,2008-01-27:Blog.BlogEntry8</id>
<updated>2008-01-27T20:31:36Z</updated>
<published>2008-01-27T19:11:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Niniejszym mog&#281; z ca&#322;ym spokojem og&#322;osi&#263; oficjalne wydanie pierwszego j&#261;dra PLD/FreeBSD, kernel posiada numerek 6.3.0.0 i zamyka pewien etap tego projektu. Z wydaniem tego j&#261;dra wi&#261;&#380;e si&#281; bowiem to, &#380;e do przebudowania ca&#322;o&#347;ci nie bedzie ju&#380; nigdy potrzebny FreeBSD (na którym do tej pory by&#322;o produkowane j&#261;dro dla PLD/FreeBSD).
<p />
Z ciekawostek, jako &#380;e nikt mi nigdy nie powiedzia&#322;, &#380;e do budowania j&#261;dra nie da si&#281; zaprz&#261;c autoconfa i automake'a. I z drugiej strony, z braku pomys&#322;u na szybkie w implementacji narz&#281;dzie do budowania tego&#380;, spróbowa&#322;em u&#380;y&#263; do tego celu w&#322;a&#347;nie autotoolsy... I uda&#322;o si&#281;. Pomijam, &#380;e regeneracja plików configure i wszystkich Makefile'ów trwa d&#322;uzej ni&#380; samo budowanie kernela, kto by sie tym przejmowa&#322;.
<p />
Teraz, kolejny du&#380;y krok to b&#281;dzie instalator... ale kiedy?
<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="PLDFreeBSD" label="PLDFreeBSD" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>TomaszTrojanowski replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment8" />
<id>tag:wiki.pld-freebsd.org,2007-07-13:Blog.BlogComment8</id>
<updated>2007-07-13T10:37:15Z</updated>
<published>2007-07-13T10:37:15Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Posypa&#322; si&#281; RAID, a ja niestety nie mam czasu &#380;eby przywróci&#263; go z backupów. azazel wróci jak tylko ukradn&#281; z czego&#347; troch&#281; czasu.<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/</uri></author>
<category term="" label="" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>spider replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment7" />
<id>tag:wiki.pld-freebsd.org,2007-07-13:Blog.BlogComment7</id>
<updated>2007-07-13T08:32:56Z</updated>
<published>2007-07-13T08:32:56Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />azazel did not response<!-- -->
<!-- --></div>
</content>
<author>
<name> spider</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/</uri></author>
<category term="" label="" />
<contributor>
<name>PiotrSkwarna</name>
</contributor>
</entry>
<entry>
<title>Winowajca odnaleziony</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry7" />
<id>tag:wiki.pld-freebsd.org,2007-04-24:Blog.BlogEntry7</id>
<updated>2007-04-24T07:18:54Z</updated>
<published>2007-04-24T07:10:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Znalaz&#322;em winnego.
By&#322;em prawie pewien, &#380;e to by&#322; aniou, ale wydawa&#322;o mi si&#281; &#380;e to by&#322;o rok albo dwa wcze&#347;niej. W ka&#380;dym razie taka jest geneza PLD/FreeBSD.<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="PLDFreeBSD" label="PLDFreeBSD" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>New look and feel</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry6" />
<id>tag:wiki.pld-freebsd.org,2007-04-19:Blog.BlogEntry6</id>
<updated>2007-04-19T13:07:10Z</updated>
<published>2007-04-19T12:52:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Tak si&#281; z&#322;o&#380;y&#322;o, &#380;e dysponuj&#261;c chwil&#261; wolnego czasu zabra&#322;em si&#281; do realizacji od dawna odk&#322;adanych zada&#324;. Skutkiem czego wiki (a zatem i blog) doczeka&#322;o si&#281; w ko&#324;cu nowego, lepszego wygl&#261;du. Stare skórki s&#261; (dla ciekawych) nadal dost&#281;pne, np. http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry6?skin=pattern
<p />
<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="BlogDev" label="BlogDev" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>PLD/FreeBSD Preview 1</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry5" />
<id>tag:wiki.pld-freebsd.org,2007-03-07:Blog.BlogEntry5</id>
<updated>2007-03-07T09:14:00Z</updated>
<published>2007-03-07T08:51:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Poniewa&#380; zg&#322;osi&#322;o si&#281; do mnie ju&#380; kilka osób z pytaniem jak mo&#380;na zainstalowa&#263; PLD/FreeBSD postanowi&#322;em co&#347; z tym zrobi&#263;. Na pocz&#261;tek PLD/FreeBSD Preview 1 w postaci spakowanej maszyny wirtualnej do VMWare Workstation. Do pobrania tutaj (41.5 MB). System minimalny jak tylko si&#281; da&#322;o, wi&#281;c mo&#380;na sobie popoldkowa&#263;.
<p />
Po uruchomieniu maszyny i zalogowaniu si&#281; na <code>roota</code> (has&#322;o puste) trzeba skonfigurowa&#263; sie&#263;:
<pre>
ifconfig lnc0 192.168.1.2
route add default 192.168.1.1
echo &#34;nameserver 192.168.1.1&#34; &#62; /etc/resolv.conf
</pre>
albo wyedytowa&#263; znane z PLD pliki odpowiedzialne za powy&#380;sze i zrestartowa&#263; us&#322;ug&#281; <code>network</code>
<pre>
/etc/rc.d/init.d/network restart
</pre>
I ju&#380; mo&#380;na dzia&#322;a&#263;. Nie polecam instalowania pakietu <code>kernel</code> i <code>loader</code> bo te które s&#261; na FTPie mog&#261; kompletnie rozwali&#263; system.
<p />
Zainteresowanym &#380;ycz&#281; mi&#322;ej zabawy.
<p />
Jak tylko znajd&#281; chwil&#281; czasu postaram si&#281; opisa&#263; jak zainstalowa&#263; PLD/FreeBSD na fizycznej maszynie przy pomocy p&#322;yty instalacyjnej FreeBSD.
<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="PLDFreeBSD" label="PLDFreeBSD" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>Do builderów podejscie trzecie</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry4" />
<id>tag:wiki.pld-freebsd.org,2007-03-05:Blog.BlogEntry4</id>
<updated>2007-03-05T15:08:01Z</updated>
<published>2007-03-05T15:04:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Po raz trzeci zabra&#322;em si&#281; za pisanie builderów dla PLD/FreeBSD. Efekt jest taki, &#380;e podstawowe funkcjonalno&#347;ci s&#261; ju&#380; gotowe, a w czasie kiedy na nowych builderach testowo przebudowywane s&#261; wszystkie pakiety sp&#322;odzi&#322;em krótki tekst opisujacy ich dzia&#322;anie. Zainteresowanych zapraszam do lektury.<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="PLDFreeBSD" label="PLDFreeBSD" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>TomaszTrojanowski replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment6" />
<id>tag:wiki.pld-freebsd.org,2007-02-16:Blog.BlogComment6</id>
<updated>2007-02-16T21:11:06Z</updated>
<published>2007-02-16T21:11:06Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Nie jestem do ko&#324;ca przekonany, czy b&#281;dzie szybsze. Nawet je&#380;eli tak, to najprawdopodobniej
<pre>
SELECT DISTINCT id&#95;process AS p1 FROM task
  WHERE status &#61; &#39;completed&#39; AND
  NOT EXISTS (SELECT &#42; FROM task WHERE status &#60;&#62; &#39;completed&#39;  AND id&#95;process &#61; p1);
</pre>
b&#281;dzie jeszcze szybsze. Ale to nie o to chodzi.
<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/</uri></author>
<category term="" label="" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>MarcinGajda replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment5" />
<id>tag:wiki.pld-freebsd.org,2007-02-16:Blog.BlogComment5</id>
<updated>2007-02-16T10:07:37Z</updated>
<published>2007-02-16T10:07:37Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>Wszystkie...</b> <p />No tak - maj&#261; by&#263; wszystkie. Wobec tego bij&#281; si&#281; w piersi, rzeczywi&#347;cie moje zapytanie nie daje poprawnego wyniku.
<p />
Mimo wszystko napisa&#322;bym to inaczej:
<p />
<pre>
SELECT id_process
  FROM task
  WHERE status = 'completed'
  GROUP BY id_process
EXCEPT
SELECT id_process
  FROM task
  WHERE status <> 'completed'
  GROUP BY id_process
</pre>
<p />
To zapytanie wci&#261;&#380; b&#281;dzie szybsze w planie wykonania od Twojego.
<!-- -->
<!-- --></div>
</content>
<author>
<name>MarcinGajda</name><uri>http://zboczuch.jogger.pl/</uri></author>
<category term="" label="" />
<contributor>
<name>MarcinGajda</name>
</contributor>
</entry>
<entry>
<title>TomaszTrojanowski replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment4" />
<id>tag:wiki.pld-freebsd.org,2007-02-16:Blog.BlogComment4</id>
<updated>2007-02-16T09:28:14Z</updated>
<published>2007-02-16T09:28:14Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Przecie&#380; <code>SELECT id_process FROM task WHERE status = 'completed' GROUP BY id_process;</code> zwróci liste procesów które maj&#261; przynajmniej jedno zadanie zako&#324;czone, a nie liste procesów, w których wszystkie zadania zosta&#322;y zako&#324;czone. Nie widzisz tego?
<p />
Ca&#322;y problem le&#380;y w tym, &#380;eby uzyska&#263; list&#281; procesów, w których wszystkie zadania si&#281; zako&#324;czy&#322;y, u&#380;ycie <code>WHERE</code> w tym przypadku nic nie da, bo przed wykonaniem funkcji <code>COUNT</code> ograniczy zbiór poczatkowy do zada&#324; które si&#281; nie zako&#324;czy&#322;y (w przypadku <code>WHERE status &lt;&gt; 'completed'</code>) albo do zada&#324; które si&#281; zako&#324;czy&#322;y w przypadku <code>WHERE status = 'completed'</code>). Czyli u&#380;ywaj&#261;c <code>WHERE status = 'completed'</code> nie wiemy czy s&#261; w tak ograniczonej tabeli rekordy z status &lt;&gt; 'completed'
<p />
Na przyk&#322;adzie b&#281;dzie pro&#347;ciej. Przyjmijmy, &#380;e w tabela "task" wygl&#261;da tak (pomin&#261;&#322;em pierwsze pole bo jest nieistotne w tym wypadki):
<table style="border-width:1px;" cellspacing="0" cellpadding="0" class="twikiTable" border="1"><tr class="twikiTableEven"><th bgcolor="#6b7f93" align="center" valign="top" style="text-align:center;vertical-align:top;" class="twikiFirstCol" maxcols="0"> id_process </th><th bgcolor="#6b7f93" align="center" valign="top" style="text-align:center;vertical-align:top;" maxcols="0"> status </th></tr>
<tr class="twikiTableOdd"><td bgcolor="#ffffff" valign="top" style="vertical-align:top;" class="twikiFirstCol"> 1 </td><td bgcolor="#ffffff" valign="top" style="vertical-align:top;"> none </td></tr>
<tr class="twikiTableEven"><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;" class="twikiFirstCol"> 1 </td><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;"> running </td></tr>
<tr class="twikiTableOdd"><td bgcolor="#ffffff" valign="top" style="vertical-align:top;" class="twikiFirstCol"> 2 </td><td bgcolor="#ffffff" valign="top" style="vertical-align:top;"> completed </td></tr>
<tr class="twikiTableEven"><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;" class="twikiFirstCol"> 2 </td><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;"> completed </td></tr>
<tr class="twikiTableOdd"><td bgcolor="#ffffff" valign="top" style="vertical-align:top;" class="twikiFirstCol"> 3 </td><td bgcolor="#ffffff" valign="top" style="vertical-align:top;"> completed </td></tr>
<tr class="twikiTableEven"><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;" class="twikiFirstCol twikiLast"> 3 </td><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;" class="twikiLast"> running </td></tr>
</table>
Moje
<pre>
SELECT id&#95;process, COUNT(status !&#61; &#39;completed&#39; OR NULL) AS count FROM task
GROUP BY id&#95;process HAVING count &#61; 0;
</pre>
zwróci:
<table style="border-width:1px;" cellspacing="0" cellpadding="0" class="twikiTable" border="1"><tr class="twikiTableEven"><th bgcolor="#6b7f93" align="center" valign="top" style="text-align:center;vertical-align:top;" class="twikiFirstCol" maxcols="0"> id_process </th><th bgcolor="#6b7f93" align="center" valign="top" style="text-align:center;vertical-align:top;" maxcols="0"> count </th></tr>
<tr class="twikiTableOdd"><td bgcolor="#ffffff" valign="top" style="vertical-align:top;" class="twikiFirstCol twikiLast"> 2 </td><td bgcolor="#ffffff" valign="top" style="vertical-align:top;" class="twikiLast"> 0 </td></tr>
</table>
Twoje
<pre>
SELECT id&#95;process, COUNT(&#42;) AS count FROM task WHERE status &#61; &#39;completed&#39; GROUP BY id&#95;process;
</pre>
zwróci
<table style="border-width:1px;" cellspacing="0" cellpadding="0" class="twikiTable" border="1"><tr class="twikiTableEven"><th bgcolor="#6b7f93" align="center" valign="top" style="text-align:center;vertical-align:top;" class="twikiFirstCol" maxcols="0"> id_process </th><th bgcolor="#6b7f93" align="center" valign="top" style="text-align:center;vertical-align:top;" maxcols="0"> count </th></tr>
<tr class="twikiTableOdd"><td bgcolor="#ffffff" valign="top" style="vertical-align:top;" class="twikiFirstCol"> 2 </td><td bgcolor="#ffffff" valign="top" style="vertical-align:top;"> 2 </td></tr>
<tr class="twikiTableEven"><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;" class="twikiFirstCol twikiLast"> 3 </td><td bgcolor="#edf4f9" valign="top" style="vertical-align:top;" class="twikiLast"> 1 </td></tr>
</table>
Oczywiscie <code>count</code> jest nieistotne, ale te zapytania zwracaja zupe&#322;nie ró&#380;n&#261; liste procesów.
<p />
Rozumiesz juz o co chodzi czy mam t&#322;umaczy&#263; dalej.<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/</uri></author>
<category term="" label="" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>MarcinGajda replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment3" />
<id>tag:wiki.pld-freebsd.org,2007-02-16:Blog.BlogComment3</id>
<updated>2007-02-16T08:25:07Z</updated>
<published>2007-02-16T08:25:07Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>Ale&#380;...</b> <p />SELECT id_process
  FROM task
  WHERE status = 'completed'
  GROUP BY id_process;
<p />
Co&#347; mi si&#281; wydaje, &#380;e owracasz jednak kota ogonem, zupe&#322;nie niepotrzebnie. Przeczytaj o WHERE, zanim zaczniej kombinowa&#263; po górk&#281;.
<p />
Dobrze by&#322;oby, gdyby&#347; te&#380; obejrza&#322; plan dla Twojego i mojego zapytania. Mo&#380;e wtedy by&#263; zrozumia&#322;, dlaczego Twoje podej&#347;cie jest co najmniej niew&#322;a&#347;ciwe.<!-- -->
<!-- --></div>
</content>
<author>
<name>MarcinGajda</name><uri>http://zboczuch.jogger.pl/</uri></author>
<category term="" label="" />
<contributor>
<name>MarcinGajda</name>
</contributor>
</entry>
<entry>
<title>TomaszTrojanowski replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment2" />
<id>tag:wiki.pld-freebsd.org,2007-02-15:Blog.BlogComment2</id>
<updated>2007-02-15T14:46:54Z</updated>
<published>2007-02-15T14:46:54Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Fakt, b&#322;edem by&#322;o nie napisanie bezpo&#347;rednio do czego mi to pos&#322;u&#380;y. Wi&#281;c naprawiam ten b&#322;&#261;d, bo widz&#281; czytanie ze zrozumieniem to rzadka sztuka.
<p />
U&#380;ywaj&#261;c tej swojej klauzuli <code>WHERE</code> wylistuj wszystkie takie procesy, dla których wszystkie zadania (z tabeli "task") maj&#261; status 'completed'. Bo ja to zrobi&#281; tak:
<pre>
SELECT id&#95;process, COUNT(status !&#61; &#39;completed&#39; OR NULL) AS count FROM task GROUP BY id&#95;process HAVING count &#61; 0;
</pre>
<p />
Tylko &#380;eby Ci&#281; &#380;o&#322;&#261;dek nie rozbola&#322;, jak b&#281;dziesz si&#281; gimnastykowa&#322;.
<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/</uri></author>
<category term="" label="" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>Marcin Gajda  replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment1" />
<id>tag:wiki.pld-freebsd.org,2007-02-15:Blog.BlogComment1</id>
<updated>2007-02-15T13:07:55Z</updated>
<published>2007-02-15T13:07:55Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"><b>Tak...</b> <p />&#346;liczne? Prymitywne, hack taki, &#380;e a&#380; &#380;o&#322;&#261;dek boli. Wygl&#261;da na to, &#380;e nie doszed&#322;e&#347; jeszcze w nauce SQL do klauzuli WHERE...
<p />
SELECT id_process, COUNT(*)
  FROM task
  WHERE status &lt;&gt; 'completed'
  GROUP BY id_process;
<p />
Móg&#322;by&#347; te&#380; pomy&#347;le&#263; o przesiadce na baz&#281; danych (np. PostgreSQL), a nie korzysta&#263; z &#380;a&#322;osnej imitacji.<!-- -->
<!-- --></div>
</content>
<author>
<name>Marcin Gajda </name><uri>http://zboczuch.jogger.pl/</uri></author>
<category term="" label="" />
<contributor>
<name>MarcinGajda</name>
</contributor>
</entry>
<entry>
<title>Ciekawa w&#322;asno&#347;&#263; NULLa</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry3" />
<id>tag:wiki.pld-freebsd.org,2007-02-14:Blog.BlogEntry3</id>
<updated>2007-02-14T22:35:21Z</updated>
<published>2007-02-14T22:08:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />W bólach implementacji swoich builderów natkn&#261;&#322;em si&#281; na ciekaw&#261; w&#322;asno&#347;&#263; NULLa w MySQL. Nie wiem czy pojawia sie ona równie&#380; innych SQLach.
<p />
Najpro&#347;ciej bedzie na przykladzie. Za&#322;ózmy, &#380;e mamy dwie tabele "process" i "task". Tabela "process" zawiera list&#281; procesów wykonywanych przez pewien abstrakcyjny procesor, na ka&#380;dy proces sk&#322;ada si&#281; pewna ilo&#347;&#263; zada&#324;, przy czym ka&#380;de zadanie mo&#380;e nale&#380;e&#263; tylko do jednego procesu; czyli prosta relacja jeden do wielu. Dodatkowo ka&#380;de zadanie posiada w&#322;a&#347;ciwo&#347;&#263; "status" okre&#347;laj&#261;ca stan tego zadania. Dla ustalenia uwagi niech pole "status" mo&#380;e przyjmowa&#263; trzy warto&#347;ci: "none", "running" lub "completed". Definicja tych tabel mo&#380;e wygl&#261;dac tak:
<pre>
CREATE TABLE process (
    id INT UNSIGNED PRIMARY KEY NOT NULL auto&#95;increment,
    name VARCHAR);
CREATE TABLE task (
    id INT UNSIGNED PRIMARY KEY NOT NULL auto&#95;increment,
    id&#95;process INT UNSIGNED NOT NULL,
    status ENUM(&#39;none&#39;, &#39;running&#39;, &#39;completed&#39;) NOT NULL);
</pre>
<p />
Zapytanie które zwróci nam identyfikator procesu wraz z ilo&#347;ci&#261; zada&#324; przyporzadkowanych do tego procesu jest oczywi&#347;cie trywialne i wyglada tak:
<pre>
SELECT id&#95;process, COUNT(&#42;) FROM task GROUP BY id&#95;process;
</pre>
<p />
Problemem natomiast jest zapytanie zwracajace identyfikator procesu wraz z ilo&#347;ci&#261; zada&#324; przyporzadkowanych do tego procesu, ale takich które nie zosta&#322;y jeszcze zako&#324;czone, czyli maj&#261; status ró&#380;ny od 'completed'. Proste:
<pre>
SELECT id&#95;process, COUNT(status !&#61; &#39;completed&#39;) FROM task GROUP BY id&#95;process;
</pre>
nie wystarcza poniewa&#380; <code>COUNT</code> zlicza zgrupowane warto&#347;ci bez wzgledu na ich warto&#347;&#263;. W tym przypadku zarówno <code>TRUE</code> jak i <code>FALSE</code> jest traktowane jako element to zliczenia. Zatem powy&#380;sze zapytanie zwraca to samo co poprzednie, czyli identyfikator procesu wraz z ilo&#347;ci&#261; zada&#324; przyporzadkowanych do tego procesu.
<p />
Mo&#380;naby oczywi&#347;cie uzy&#263; funkcji <code>SUM</code> i <code>IF</code> w nast&#281;puj&#261;cy sposób:
<pre>
SELECT id&#95;process, SUM(IF(status !&#61; &#39;completed), 1, 0) FROM task GROUP BY id&#95;process;
</pre>
Ale to nie do&#347;&#263;, &#380;e niezgodne z zasadami sztuki, to jeszcze ma&#322;o czytelne i pewnie ma&#322;o wydajne.
<p />
Aby w prosty sposób uzyska&#263; oczekiwany wynik wystarczy wykorzysta&#263; to &#380;e warto&#347;ci <code>NULL</code> s&#261; <strong>niepoliczalne</strong> dla funkcji <code>COUNT</code>. Je&#380;eli zgrupujemy rekordy które w zadanym polu maja cztery warto&#347;ci z czego dwie s&#261; równe <code>NULL</code> to funkcja <code>COUNT</code> na tym polu zwróci nam <code>2</code>, a nie <code>4</code>.
<p />
Wystarczy zatem doprowadzi&#263; ostatnie zapytanie wykorzystuj&#261;ce funkcj&#281; <code>COUNT</code> do takiej postaci, w której warto&#347;&#263; argumentu jest policzalna gdy pole "status" jest inne ni&#380; 'completed', a niepoliczalna (czyli równa <code>NULL</code>) w przeciwnym wypadku. Wyra&#380;enie
<pre>
status !&#61; &#39;completed&#39; OR NULL
</pre>
spe&#322;nia te za&#322;o&#380;enia poniewa&#380; przyjmuje jedn&#261; z dwóch warto&#347;ci: <code>TRUE</code> dla pola "status" ró&#380;nego od 'completed', albo <code>NULL</code> w przeciwnym wypadku.
<p />
Ostatecznie zapytanie zwracajace identyfikator procesu wraz z ilo&#347;ci&#261; zada&#324; przyporzadkowanych do tego procesu, takich które nie zosta&#322;y jeszcze zako&#324;czone wygl&#261;da tak:
<pre>
SELECT id&#95;process, COUNT(status !&#61; &#39;completed&#39; OR NULL) FROM task GROUP BY id&#95;process;
</pre>
<p />
&#346;liczne, prawda?
<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="MySQL" label="MySQL" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>Dlaczego CVS ssie...</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry2" />
<id>tag:wiki.pld-freebsd.org,2007-02-06:Blog.BlogEntry2</id>
<updated>2007-02-06T14:11:36Z</updated>
<published>2007-02-06T14:11:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />W gruncie rzeczy tekst ma by&#263; o tym dlaczego SVN jest lepszym wyborem w przypadku repozytorium pakietów. Swoje przemy&#347;lenia opieram na bez ma&#322;a trzy i pó&#322; rocznym do&#347;wiadczeniu z repozytorium http://svn.pld-freebsd.org/svn/packages, dostepnym równiez przez ViewCVS: http://svn.pld-freebsd.org/cgi-bin/viewsvn/.
<p />
Struktura repozytorium ró&#380;ni sie znacz&#261;co od p&#322;askiego modelu repozytorium stosowanego w PLD. W du&#380;ym uproszczeniu wygl&#261;da ona tak:
<p />
<pre>
packages
 +- trunk
 &#124;    +- db
 &#124;    &#124;    +- SOURCES
 &#124;    &#124;    &#124;    +- patch1.patch
 &#124;    &#124;    &#124;    +- patch2.patch
 &#124;    &#124;    +- SPECS
 &#124;    &#124;         +- db.spec
 &#124;    +- rpm
 &#124;         +- SOURCES
 &#124;         &#124;    +- patch1.patch
 &#124;         &#124;    +- patch2.patch
 &#124;         +- SPECS
 &#124;              +- rpm.spec
 +- branches
 &#124;    +- rpm-4.1.1
 &#124;    &#124;    +- db
 &#124;    &#124;    &#124;    +- SOURCES
 &#124;    &#124;    &#124;    &#124;    +- patch1.patch
 &#124;    &#124;    &#124;    &#124;    +- patch2.patch
 &#124;    &#124;    &#124;    +- SPECS
 &#124;    &#124;    &#124;         +- db.spec
 &#124;    &#124;    +- rpm
 &#124;    &#124;         +- SOURCES
 &#124;    &#124;         &#124;    +- patch1.patch
 &#124;    &#124;         &#124;    +- patch2.patch
 &#124;    &#124;         +- SPECS
 &#124;    &#124;              +- rpm.spec
 &#124;    +- rpm-4.4.1
 &#124;         +- db
 &#124;         &#124;    +- SOURCES
 &#124;         &#124;    &#124;    +- patch1.patch
 &#124;         &#124;    &#124;    +- patch2.patch
 &#124;         &#124;    +- SPECS
 &#124;         &#124;         +- rpm.spec
 &#124;         +- rpm
 &#124;              +- SOURCES
 &#124;              &#124;    +- patch1.patch
 &#124;              &#124;    +- patch2.patch
 &#124;              +- SPECS
 &#124;                   +- rpm.spec
 +- tags
      +- Ac-rpm-4.4.1-2
           +- db
           &#124;    +- SOURCES
           &#124;    &#124;    +- patch1.patch
           &#124;    &#124;    +- patch2.patch
           &#124;    +- SPECS
           &#124;         +- rpm.spec
           +- rpm
                +- SOURCES
                &#124;    +- patch1.patch
                &#124;    +- patch2.patch
                +- SPECS
                     +- rpm.spec
</pre>
<p />
Jak wida&#263; na powy&#380;szym schemacie dla ka&#380;dego pakietu zosta&#322;a wydzielona osobna ga&#322;&#261;&#378; w drzewie repozytorium. Taki zabieg, poza uporzadkowaniem i separacj&#261; sk&#322;adników poszczególnych pakietów, pozwala na rozdzielenie przestrzeni nazw plików w pakietach. A co za tym idzie, powoduje &#380;e np. nazwa patcha mo&#380;e by&#263; dowolna dla zadanego pakietu i nie istnieje konieczno&#347;&#263; pilnowania &#380;eby nazwy &#322;atek dla ró&#380;nych pakietów nie kolidowa&#322;y ze sob&#261;. W szczególno&#347;ci, nie ma potrzeby narzucania nazewnictwa tych &#322;atek do postaci <code>nazwa_pakietu-nazwa_&#322;atki.patch</code> jak ma to miejsce w PLD.
<p />
&#346;ciagni&#281;cie ca&#322;ego drzewa <code>trunk</code> mo&#380;e wygl&#261;da nastepuj&#261;co:
<pre>
svn checkout http://svn.pld-freebsd.org/svn/packages/trunk packages
</pre>
Natomiast &#347;ciagniecie i kompilacja pakietu db z takiego repozytorium wygl&#261;da tak:
<pre>
$ cd ~/packages
$ svn checkout http://svn.pld-freebsd.org/svn/packages/trunk/db
$ cd db/SPECS
$ rpmbuild -ba --define &#34;&#95;topdir ~/packages/db&#34; db.spec
</pre>
Powy&#380;szy przyk&#322;ad nie uwzgl&#281;dnia oczywi&#347;cie &#347;ciagni&#281;cia ewentualnych tarballi z distfiles.
<p />
Drzewiastej strukturze repozytorium mo&#380;na zarzuca&#263; niemozliwo&#347;&#263; "przegrepowania" wszystkich specy, albo wprowadzania masowych zmian w specach. Wad&#281; t&#261; mo&#380;na wyeliminowa&#263; u&#380;ywaj&#261;c polecenia <code>find</code>. I tak odpowiednikiem <code>grep jakisstring *</code> w katalogu SPECS jest 
<pre>
find . -name &#34;&#42;.spec&#34; -exec grep -H jakisstring {} \;
</pre>
 w katalogu packages/trunk.
<p />
Praca z takim repozytorium nie jest du&#380;o bardziej skomplikowana, ni&#380; z p&#322;askim repozytorium CVSowym. A prawie zupe&#322;nie nie ró&#380;ni si&#281; gdy u&#380;yjemy odpowiednio zmodyfikowanego skryptu builder.
<p />
Kolejn&#261; przewag&#261; nad CVSem s&#261; "atomowe" commity. Polega to na tym, &#380;e po wprowadzeniu zmian z pakiecie, zmiany s&#261; przekazywane do repozytorium jednym poleceniem, np.
<pre>
$ cd ~/packages
$ svn commit -m &#34;- updated to 4.5\n- updated patch1 patch&#34; db
</pre>
Co najwa&#380;niejsze, takie dokonanie zmiany jest traktowane w repozytorium jako integralna ca&#322;o&#347;&#263; identyfikowana numerem rewizji w repozytorium, a nie jest z&#322;o&#380;eniem zmian w poszczególnych plikach. Co za tym idzie mo&#380;emy &#322;atwo odszuka&#263;, &#380;e np. update db do wersji 4.5 poci&#261;gne&#322;o za sob&#261; usuniecie pliku SOURCES/patch1.patch.
W CVSie, niestety, ka&#380;da tego typu zmiana jest w repozytorium traktowana osobno, dlatego du&#380;o wiecej pracy kosztuje odnalezienie jak zmieni&#322;y si&#281; pozosta&#322;e pliki pakietu, podczas okre&#347;lonej zmiany pliku spec. Takie zachowanie CVSa jest dla mnie szczególnie uci&#261;&#380;liwe, poniewa&#380; w swojej pracy intensywnie &#347;ledz&#281; zmiany w repozytorium PLD w celu nanoszenia niektórych z nich w PLD/FreeBSD.
<p />
Atomowo&#347;&#263; commitów w repozytorium pociaga za sob&#261; równie&#380; zwiekszenie przejrzysto&#347;ci commitlogów, dzi&#281;ki temu s&#261; one generowane jako pojedynczy mail, a nie dwa osobne maile zawierajace zmiany odpowiednio, w module SPECS i w module SOURCES.
<p />
Kolejna przewag&#261; Subversion jest mo&#380;liwo&#347;&#263; przenoszenia plików (z zachowaniem historii zmian) z poziomu u&#380;ytkownika. W CVSie taka operacja wymaga zaanga&#380;owania administratora repozytorium, który musi dokona&#263; takiej zmiany po stronie serwera.
<p />
Dla niektórych kolejn&#261; wad&#261; SVNa mo&#380;e by&#263; niemo&#380;liwo&#347;&#263; generowania sekcji <code>%changelog</code>, tak jak ma to miejsce w chwili obecnej w PLD. Wed&#322;ug mnie u&#380;ywanie <code>$Log$</code> do generowania loga to &#347;rednio dobry pomys&#322;, tym bardziej, &#380;e taki log nie jest tworzony w formacie przyjmowanym przez RPMa. S&#322;uszniej by&#322;oby gdyby <code>%changelog</code> by&#322; generowany z loga SVNa na source-builderach w formacie natywnym dla RPMa.
<p />
Na koniec wypada jeszcze wspomnie&#263; o &#322;atwo&#347;ci instalacji serwera Subversion. Po raz pierwszy zaje&#322;o mi to kilkana&#347;cie minut, podczas gdy na instalacj&#281; serwera CVSu straci&#322;em kilka(na&#347;cie) godzin.
<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="PLDFreeBSD" label="PLDFreeBSD" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry>
<entry>
<title>JohnDoe replies on ""</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogComment0" />
<id>tag:wiki.pld-freebsd.org,2007-01-31:Blog.BlogComment0</id>
<updated>2007-01-31T21:24:25Z</updated>
<published>2007-01-31T21:24:25Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Tylko test<!-- -->
<!-- --></div>
</content>
<author>
<name>JohnDoe</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/</uri></author>
<category term="" label="" />
<contributor>
<name>JohnDoe</name>
</contributor>
</entry>
<entry>
<title>In the Beginning... umar&#322; blog, niech &#380;yje blog</title>
<link rel="alternate" type="text/html" href="http://wiki.pld-freebsd.org/bin/view/Blog/BlogEntry1" />
<id>tag:wiki.pld-freebsd.org,2007-01-31:Blog.BlogEntry1</id>
<updated>2007-01-31T14:19:50Z</updated>
<published>2007-01-31T14:19:00Z</published>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml"> <p />Poprzedni blog umar&#322; &#347;merci&#261; naturaln&#261;. Nie &#380;a&#322;uj&#281;. Z pocz&#261;tku NewsBruiser nawet mi si&#281; podoba&#322;, zapewne dlatego &#380;e pierwsze wra&#380;enie pochodzi&#322;o ze sfery u&#380;ytkownika. Pó&#378;niej zacz&#281;&#322;y si&#281; problemy, a to jaka&#347; ikona si&#281; nie wy&#347;wietla, a to nie mam kontroli nad layoutem. Dlaczego? Nie wiem, i nawet nie chce mi si&#281; tego analizowa&#263;. Po prostu organicznie nie cierpi&#281; Pythona.
<p />
Tak si&#281; z&#322;o&#380;y&#322;o &#380;e powzi&#261;&#322;em noworoczne postanowienie, &#380;e w ko&#324;cu zaczn&#281; pracowa&#263; nad serwisem WWW dla PLD/FreeBSD. Niech &#347;wiat si&#281; dowie &#380;e istnieje co&#347; takiego jak PLD/FreeBSD, a nu&#380; kto&#347; sie zlituje i pomo&#380;e, albo jeszcze lepiej przekona, &#380;e to nie ma sensu. Jak to z postanowieniami bywa, zacz&#261;&#322;em je realizowa&#263; z "niewielkim" opó&#378;nieniem.
<p />
Poniewa&#380; wszelkiego rodzaju Wiki s&#261; obecnie na topie (czyt. trendi, albo dzezi, albo je&#347;li kto&#347; woli kaczi), tam te&#380; postanowi&#322;em szuka&#263; silnika do serwisu. Drugim wa&#380;nym kryterium jakie powinien spe&#322;nia&#263; silnik by&#322;o to &#380;e musia&#322; by&#263; napisany w Jedynym S&#322;usznym J&#281;zyku Skryptowym(TM) czyli perlu. W&#347;ród tak ograniczajacych kryteriów jedynym godnym uwagi silnikiem okaza&#322; sie TWiki. I tak zosta&#322;o.
<p />
Przy okazji przewalania dokumentacji TWiki okaza&#322;o si&#281;, &#380;e posiada od rozbudowany system wtyczek, w&#347;ród których jest jedna zmieniaj&#261;ca dzia&#322; TWiki w do&#347;&#263; zaawansowany system blogowy. Po drobnych problemach z instalacj&#261;, system stan&#261;&#322; i zapad&#322;a decyzja o wskrzeszeniu bloga. I oto jest.
<p />
Do mojego prywatnego TODO pow&#281;drowa&#322;y dodatkowo: spolszczenie systemu do u&#380;ywalnej postaci i stworzenie jakiego&#347; &#347;licznego layoutu. Do tego drugiego zatrudni&#322;bym którego&#347; ze znajomych web-grafików. Zobaczymy.<!-- -->
<!-- --></div>
</content>
<author>
<name>TomaszTrojanowski</name><uri>http://wiki.pld-freebsd.org/bin/viewMain/TomaszTrojanowski</uri></author>
<category term="PLDFreeBSD" label="PLDFreeBSD" />
<contributor>
<name>TomaszTrojanowski</name>
</contributor>
</entry> </feed>