<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>pamiętnik programisty &#187; pejotr</title>
	<atom:link href="http://piotr.doniec.eu/devlog/author/admin/feed/" rel="self" type="application/rss+xml" />
	<link>http://piotr.doniec.eu/devlog</link>
	<description></description>
	<lastBuildDate>Wed, 28 Dec 2011 23:52:24 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>O JSP słów kilka</title>
		<link>http://piotr.doniec.eu/devlog/2009/07/o-jsp-slow-kilka/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/07/o-jsp-slow-kilka/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 14:58:46 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[jee]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=226</guid>
		<description><![CDATA[W swoim wcześniejszym wpisie, zatytułowanym JSP, JSF, GlassFish &#8211; mini słowniczek napisałem że JSP jest wykorzystywane jako warstwa widoku w modelu MVC. Jest to oczywiście prawda ale jak się niedawno dowiedziałem, w znaczny sposób spłyciłem zastosowanie JSP. Okazuje się bowiem że samo JSP jest idealnym sposobem na tworzenie prostych aczkolwiek dynamicznych stron WWW w których [...]]]></description>
			<content:encoded><![CDATA[<p>W swoim wcześniejszym wpisie, zatytułowanym <a href="http://piotr.doniec.eu/devlog/2009/03/jsp-jsf-glassfish-mini-slowniczek/">JSP, JSF, GlassFish &#8211; mini słowniczek</a> napisałem że JSP jest wykorzystywane jako warstwa widoku w modelu MVC. Jest to oczywiście prawda ale jak się niedawno dowiedziałem, w znaczny sposób spłyciłem zastosowanie JSP. Okazuje się bowiem że samo JSP jest idealnym sposobem na tworzenie prostych aczkolwiek dynamicznych stron WWW w których nie ma potrzeby podziału na poszczególne warstwy Model &#8211; Widok &#8211; Kontroler. Co więcej okazuję się że każda strona JSP również jest servletem i zachowuję się w sposób podobny.<br />
<span id="more-226"></span><br />
Strona JSP to na dobrą sprawę kod HTML/XHTML z pewnymi dodatkami które zapewniają dynamiczność takiej strony. Te &#8222;pewne dodatki&#8221; to tzw. skryptlety, czyli poprstu kod Javy umieszczony w kodzie stron JSP pomiędzy znacznikami <code><% ... %></code>. Jest to rozwiązanie bardzo podobne do umieszczania kodu PHP w ramach kodu HTML. Jak wiadomo mieszanie logiki aplikacji ze sposobem prezentacji nie jest dobrym pomysłem, ale na dobry początek trzeba zacząć od czegoś prostego. Aby nie był to &#8222;suchy wpis&#8221; przedstawiam przykład(pochodzi książki Head First Servlets &#038; JSP):</p>
<pre class="brush: java">
package foo;

public class Licznik {
    private static int liczba;
    public static synchronized int getLiczba() {
        liczba++;
        return liczba;
    }
}
</pre>
<p>to kod wstawiony do strony JSP korzystający z licznika powinien wyglądać następująco:<br />
<code><% out.println(foo.licznik.getLiczba());  %></code></p>
<p>Oprócz znacznika skryptletu który został przed chwilą zaprezentowane w stronach JSP można spotkać również inne, np.</p>
<ul>
<li>Dyrektywa: <%@ ... %>, np: <code><%@page contentType="text/html; charset=UTF-8" %></code> ustawia typ treści</li>
<li>Wyrażenie <%= ... %>, np. <code><%= Licznik.getLiczba() %> spowoduje wyświetlenie aktualnego stanu licznika. </code></li>
<li>Definicja: <%! ... %>, umożliwia definiowanie zmiennych i metod które są później &#8222;wstrzykiwane&#8221; do tworzonej klasy servletu. W ramach tych znaczników jesteśmy upoważnieni do przeciążenia metod <code>jspInit</code> oraz <code>jspDestroy</code> które są wywoływane odpowiednio przy powoływaniu servletu do życia i przy jego usuwaniuz kontenera. Z uwagi na fakt że definicje metod zawartych w obrębie znacznika defincji stają metodami servletu, nie ma tu dostępu do zmienny <code>request</code> i <code>response</code></li>
</ul>
<p>Jak wspomniałem każda strona JSP jest servletem. Strona jest tłumaczona przez kontener na odpowiedni servlet. Wykorzystanie różnych znaczników do zaprezentowania innego typu zawartości ułatwia kontenerowi konwersję. I tak dyrektywy są używane aby kontrolować jak kontener ma przetłumaczyć a następnie wykonać kod strony, skryptlety są po prostu przepisywane do kodu servletu natomiast wyrażenia są przekazywane jako parametry odpowiednich funkcji.</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/07/o-jsp-slow-kilka/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Wstęp do servlet&#8217;ów</title>
		<link>http://piotr.doniec.eu/devlog/2009/06/wstep-do-servletow/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/06/wstep-do-servletow/#comments</comments>
		<pubDate>Sun, 28 Jun 2009 21:47:53 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[J2EE]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[jee]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=214</guid>
		<description><![CDATA[A czym że to jest ? Servlet API to zbiór klas i interface&#8217;ów które umożliwiają komunikację z użytkownikiem i dynamicznie przygotowywanie treści w odpowiedzi na żądanie. Servlet jest to napisana w języku Java klasa, ładowana i obsługiwana poprzez serwer WWW lub serwer aplikacji współpracujący z serwerem WWW, która umie odebrać żądanie i odpowiednio obrobić i [...]]]></description>
			<content:encoded><![CDATA[<p>A czym że to jest ? Servlet API to zbiór klas i interface&#8217;ów które umożliwiają komunikację z użytkownikiem i dynamicznie przygotowywanie treści w odpowiedzi na żądanie. Servlet jest to napisana w języku Java klasa, ładowana i obsługiwana poprzez serwer WWW lub serwer aplikacji współpracujący z serwerem WWW, która umie odebrać żądanie i odpowiednio obrobić i wygenerować odpowiedź. Ci którzy mieli styczność ze skryptami CGI zapewne zauważą podobieństwa, Servlet jest prawie tym samym co skrypt PHP. Jednak ja mówi stare chińskie przysłowie &#8222;prawie robi wielką różnicę&#8221;.<br />
<span id="more-214"></span><br />
Niezaprzeczalne zalety servletów to większa szybkość działania (każde żądanie jest obsługiwane w nowym wątku) oraz większe bezpieczeństwo. Do wad należy zaliczyć wymaganie na dość silną maszynę, w szczególności chodzi tu o dostępną pamięć.</p>
<p>Aby servlet mógł być servletem a nie zwykłą klasą musi implementować interface javax.servlet.Servlet. </p>
<pre class="brush: java">
interface javax.servlet.Servlet
{
  void destroy();
  ServletConfig getServletConfig();
  String getServletInfo();
  void init(ServletConfig config);
  void service(ServletRequest req, ServletResponse res);
}
</pre>
<p>Metoda <code>destroy</code> jest uruchamiana przez serwer aplikacji celem zniszczenia servletu. Dwie metody <code>init</code> oraz <code>service</code> mają za zadanie &#8222;zarządzanie&#8221; cyklem życia servletu. Pierwsza z wyżej wymienionych metod jest wywoływana tylko raz w całym cyklu życia servletu. Ma to zawsze miejsce przed obsługą przez servlet jakichkolwiek żądań klientów. Natomiast zadaniem metody <code>service</code> jest obsługa żądania. Metoda przyjmuje 2 parametry, pierwszy z nich definiuje żądanie skierowane do serwera, a drugi będzie zawierał wygenerowaną odpowiedź. </p>
<p>Tworzenie za każdym razem klasy implementującej ten interface może się okazać zadaniem dosyć żmudnym dlatego do dyspozycji mamy jeszcze 2 klasy: <code>GenericServlet</code> &#8211; klasa obsługująca żadania nie zależenie od protokołu, jednak wymaga samodzielnej implementacji metody <code>service</code>, oraz klasa <code>HttpServlet</code> do wykorzystania wraz z protokołem HTTP. Oczywistą zaletą tej klasy jest w pełni zaimplementowany mechanizm sterownia życiem servletu. Rola programisty ogranicza się właściwie do przysłonięcia metod typowych dla żadań HTTP takich jak POST (metoda doPost), GET (doGet), HEAD, OPTIONS, PUT, TRACE, DELETE. Nie trzeba chyba nikogo przekonywać że w 99% przypadków nadpisywana jest jedna z dówch pierwszych metod lub obie.</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/06/wstep-do-servletow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Magiczne delete []</title>
		<link>http://piotr.doniec.eu/devlog/2009/06/magiczne-delete/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/06/magiczne-delete/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 18:09:35 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=209</guid>
		<description><![CDATA[Prawdopodobnie nikt się nie zastanawiał jak dokładnie działa delete [], wystarczy wiedzieć że usuwa wszystkie obiekty umieszczone w dynamicznie zaalokowanej tablicy. Jeżeli obiekty posiadają destruktor to jest on uruchamiany, a jeśli nie to pamięć jest po prostu zwalniana. Muszę przyznać że mnie samemu też nigdy nie przyszło na myśl że może się tam kryć coś [...]]]></description>
			<content:encoded><![CDATA[<p>Prawdopodobnie nikt się nie zastanawiał jak dokładnie działa <code>delete []</code>, wystarczy wiedzieć że usuwa wszystkie obiekty umieszczone w dynamicznie zaalokowanej tablicy. Jeżeli obiekty posiadają destruktor to jest on uruchamiany, a jeśli nie to pamięć jest po prostu zwalniana. Muszę przyznać że mnie samemu też nigdy nie przyszło na myśl że może się tam kryć coś &#8222;magicznego&#8221;. Trawało to do czasu aż zupełnie przypadkiem trafiłem na wpis na blogu który opisuje SKĄD DELETE [] WIE ILE OBIEKTÓW NALEŻY USUNĄĆ.<br />
Nie będę kopiował cudzego wpisy/odkrycia jedynie po przetłumaczeniu na język ojczysty więc odsyłam do źródła oraz zachęcam do lektury (tytuł dodatkowo mówi sam za siebie): <a href="http://mdzahidh.wordpress.com/2007/08/24/a-little-cc-recipe-you-can-live-without-knowing/">http://mdzahidh.wordpress.com/2007/08/24/a-little-cc-recipe-you-can-live-without-knowing/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/06/magiczne-delete/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Z C++ zagadka nr 3</title>
		<link>http://piotr.doniec.eu/devlog/2009/06/z-c-zagadka-nr-3/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/06/z-c-zagadka-nr-3/#comments</comments>
		<pubDate>Thu, 11 Jun 2009 23:40:33 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=197</guid>
		<description><![CDATA[Kompilator zrobi dokładnie to co chcesz. DOKŁADNIE! i właśnie dlatego trzeba uważać. Ta zagadka jak i pozostałe ma na celu zwrócenie uwagi na miejsca które wydają się oczywiste a moga wprowadzić wiele zamieszania i niepotrzebnych nerwów. W końcu nie od dziś wiadomo że najgroźniejsze błędy znajdują się w &#8222;kodzie który napewno jest dobrze&#8221;. Tym razem [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Kompilator zrobi dokładnie to co chcesz. DOKŁADNIE!</p></blockquote>
<p> i właśnie dlatego trzeba uważać. Ta zagadka jak i pozostałe ma na celu zwrócenie uwagi na miejsca które wydają się oczywiste a moga wprowadzić wiele zamieszania i niepotrzebnych nerwów. W końcu nie od dziś wiadomo że najgroźniejsze błędy znajdują się w &#8222;kodzie który napewno jest dobrze&#8221;. Tym razem zagadka wymaga trochę więcej od czytelnika, nie wystarczy znajmość C++, trzeba się jeszcze wykazać odrobiną znajomości biblioteki boost. <span id="more-197"></span><br />
Na problem oczywiście musiałem trafić na klika godzin przed oddaniem projektu, była godzina 5:14 i nie trudno zgadnąć że odchodził istny eXtreme programming &#8211; programowanie gry sieciowej &#8211; 2 osoby &#8211; 24h. Dojście do tego co jest źle zajęło dobrą godzinę&#8230;<br />
Poniższy kod przdstawia 4 najprostsze możliwe przypadki użycia boost::bind w połączeniu z boost::signal, nie różnią się między sobą bardzo:</p>
<pre class="brush: cpp">
#include &lt;boost/signal.hpp&gt;
#include &lt;boost/bind.hpp&gt;

#include &lt;iostream&gt;	

class Test
{
public:
  Test(int x) : x_(x)
  {}

  void metoda1(int i);

  int x_;
};

void Test::metoda1(int i)
{
  x_ += i;
}

int main()
{
  typedef boost::signal&lt;void (int)&gt; event_sig;
  event_sig signal;

  Test* t1 = new Test(0);
  Test* t2 = new Test(0);
  Test t3(0);
  Test t4(0);

  signal.connect(boost::bind(&amp;Test::metoda1, *t1, _1));
  signal.connect(boost::bind(&amp;Test::metoda1,  t2, _1));
  signal.connect(boost::bind(&amp;Test::metoda1, &amp;t3, _1));
  signal.connect(boost::bind(&amp;Test::metoda1,  t4, _1));

  for(int i = 0; i &lt; 10; ++i)
  {
    signal(1);
  }

  std::cout &lt;&lt; &quot;t1::x = &quot; &lt;&lt; t1-&gt;x_ &lt;&lt; std::endl;
  std::cout &lt;&lt; &quot;t2::x = &quot; &lt;&lt; t2-&gt;x_ &lt;&lt; std::endl;
  std::cout &lt;&lt; &quot;t3::x = &quot; &lt;&lt; t3.x_ &lt;&lt; std::endl;
  std::cout &lt;&lt; &quot;t4::x = &quot; &lt;&lt; t4.x_ &lt;&lt; std::endl;
  std::cout &lt;&lt; &quot;Powinno(?) byc 10&quot; &lt;&lt; std::endl;
}
</pre>
<p>Mogło by się wydawać że w wyniku, na ekran zostanie wypisana 4 razy liczba 10. Ci bardziej podejrzliwi zaczną się zastanawiać, jaki wpływ mogą mieć te &#8222;dodatkowe&#8221; symbole dostawione wewnątrz boost::bind. Okazuje się że w przypadkach 1 i 4 ( t1 i t4 ), mimo wysyłania sygnału, wartość pola x_ nie ulega zmianie, natomiast w pozostałych ulega. Dlaczego ?<br />
Rozwiązanie tego problemu jest bardo proste, otóż tworząc binda, biblioteka boost w zależności od sposobu przekazania obiektu na rzecz którego zostanie wywołana metoda, utworzy jego kopię (internal copy) lub będzie operować na przekazanym obiekcie.<br />
Niby proste, ale trzeba mieć świadomość o istnieniu takiego mechanizmu. Nie trudno się &#8222;przejechać&#8221; na złym przekazaniu obiektu, a tu nie będzie sugestywnego &#8222;segmentation fault&#8221;&#8230;.</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/06/z-c-zagadka-nr-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Z C++ zagadka nr 2</title>
		<link>http://piotr.doniec.eu/devlog/2009/06/z-c-zagadka-nr-2/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/06/z-c-zagadka-nr-2/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 11:49:26 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[tricky]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=188</guid>
		<description><![CDATA[Zagadka nr 2 bardzo blisko związana z zawiłościami języka programowania c++, choć okazuje się że dotyczy także innych, w tym np. Javy. Kod wydaje się banalnie prosty. Jednak jak mówi &#8222;stare chińskie przysłowie&#8221;  &#8211; &#8222;Diabeł tkwi w szczegółach&#8221;. Czego można by się spodziewać po wykonaniu takiego kodu ? #include &#60;iostream&#62; int main() { for(double i [...]]]></description>
			<content:encoded><![CDATA[<p>Zagadka nr 2 bardzo blisko związana z zawiłościami języka programowania c++, choć okazuje się że dotyczy także innych, w tym np. Javy. Kod wydaje się banalnie prosty. Jednak jak mówi &#8222;stare chińskie przysłowie&#8221;  &#8211; &#8222;Diabeł tkwi w szczegółach&#8221;.<br />
<span id="more-188"></span><br />
Czego można by się spodziewać po wykonaniu takiego kodu ?</p>
<pre class="brush: cpp">
#include &lt;iostream&gt;

int main()
{
    for(double i = 0; i != 1; i+= 0.1)
    {
        std::cout &lt;&lt; &quot;Obrot petli i = &quot; &lt;&lt; i &lt;&lt; std::endl;
    }
}
</pre>
<p>Odpowiedź na to pytania wymaga trochę więcej niż tylko znajomości składni języka. Na pierwszy rzut oka wydawać się może że pętla dokona 10 obrotów a następnie program się skończy. Gdyby to był 1 kwietnia wiele osób uznało by za żart stwierdzenie że pętla będzie działać w nieskończoność, choć tak naprawdę jest !! Program nie zauważy że dobił do 1 i powinien przestać działać. Co więcej, na ekran zostanie wypisana liczba 1 a mimo to działanie nie zostanie przerwane. Wyjaśnienia tego przypadku, trzeba szukać w komputerowej reprezentacji liczby 0.1 <img src='http://piotr.doniec.eu/devlog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  </p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/06/z-c-zagadka-nr-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Funkcje wirtualne w c++</title>
		<link>http://piotr.doniec.eu/devlog/2009/05/funkcje-wirtualne-w-c/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/05/funkcje-wirtualne-w-c/#comments</comments>
		<pubDate>Fri, 15 May 2009 14:26:11 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[wirtualność]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=179</guid>
		<description><![CDATA[Mechanizm funkcji wirtualnych, występujący także pod nazwą &#8222;późnego wiązania&#8221;, jest bardzo ważny elementem języka programowania. Pozwala na wywołania innej wersji metody w zależności od obiektu na rzecz którego metoda jest wywoływana.  Największe zastosowanie funkcji wirtualnych to umożliwienie przechowywanie obiektów w kolekcjach jako obiektów klasy bazowej, a wywoływanie metod które dotyczą faktycznego typu obiektu. O ile [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Mechanizm funkcji wirtualnych, występujący także pod nazwą &#8222;późnego wiązania&#8221;, jest bardzo ważny elementem języka programowania. Pozwala na wywołania innej wersji metody w zależności od obiektu na rzecz którego metoda jest wywoływana.  Największe zastosowanie funkcji wirtualnych to umożliwienie przechowywanie obiektów w kolekcjach jako obiektów klasy bazowej, a wywoływanie metod które dotyczą faktycznego typu obiektu.<span id="more-179"></span><br />
O ile w przypadku funkcji niewirtualnych kompilator nie ma problemu z obliczeniem adresu funkcji w czasie kompilacji i konsolidacji, a wywołanie odnosi się do obliczonego statycznego adresu.<br />
W przypadku funkcji wirtualnych sprawa wygląda trochę inaczej, ponieważ funkcja którą należy wywołać zależy również od typu obiektu na rzecz którego następuje próba wywołania. Dlatego kompilator tworzy sobie dla każdej klasy tabelę wywołań funkcji wirtualnych v-table. Tabela jest tworzona 1 dla jednej klasy i jest wspólna dla wszystkich obiektów danej klasy. Tabela v-table jest tworzona tylko wtedy gdy została zadeklarowana przynajmniej jedna funkcja wirtualna. Każda klasa ma wskaźnik na tabelę funkcji wirtualnych z której korzysta kiedy ma wywołać metodę która została zadeklarowana jako wirtualna. Wskaźnik tablicy wirtualnej jest zazwyczaj pierwszym elementem obiektu. Wynikający z istnienia vtable narzut pamięciowy jest raczej skromny. Rozmiar obiektu rośnie o wielkość samego wskaźnika, czyli o 4KB a zapotrzebowanie całego programu jest wprost proporcjonalne do ilości funkcji wirtualnych.<br />
<img class="size-full wp-image-180 alignnone" title="ovp-fig6" src="http://piotr.doniec.eu/devlog/wp-content/uploads/2009/05/ovp-fig6.gif" alt="ovp-fig6" width="314" height="314" /></p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/05/funkcje-wirtualne-w-c/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Zend_Auth i Doctrine</title>
		<link>http://piotr.doniec.eu/devlog/2009/04/zend_auth-i-doctrine/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/04/zend_auth-i-doctrine/#comments</comments>
		<pubDate>Sat, 18 Apr 2009 09:38:42 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[doctrine]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=166</guid>
		<description><![CDATA[O łączeniu frameworku Zenda z ORM Doctrine wiele w internecie napisano. Ale trzeba pamiętać że wiele bibliotek zawartych w frameworku również może wymagać połączenia z bazą danych, a domyślnie wymagają użycia Zend_Db_Table. Na szczęście taka sytuacja została przewidziana przez twórców którzy udostępnili odpowiedni zestaw interface&#8217;ów umożliwiając w ten sposób tworzenie własnych adapterów a tym samym [...]]]></description>
			<content:encoded><![CDATA[<p>O łączeniu frameworku Zenda z ORM Doctrine wiele w internecie napisano. Ale trzeba pamiętać że wiele bibliotek zawartych w frameworku również może wymagać połączenia z bazą danych, a domyślnie wymagają użycia Zend_Db_Table. Na szczęście taka sytuacja została przewidziana przez twórców którzy udostępnili odpowiedni zestaw interface&#8217;ów umożliwiając w ten sposób tworzenie własnych adapterów a tym samym dostosowanie komponentów wedle własnych zachcianek.<span id="more-166"></span><br />
Jak połączyć Doctrine i Zend_Session napisał Zyx na swoim blogu(www.zyxist.com). W podobny sposób można podpiąć Zend_Auth, ale klasa już została napisana i można ją pobrać stąd <a href="http://http://framework.zend.com/wiki/pages/viewpage.action?pageId=3866950&#038;focusedCommentId=10944686">Zend_Auth_Adapter_Doctrine_Table</a>. Do tego miejsca wszystko jest jasne i proste, dziwi mnie za to trochę sposób używania tego w aplikacji.<br />
Zakładając że mamy prostą tabele użytkowników opisaną następująco</p>
<pre class="brush: php">
WebsiteUser:
  tableName: website_users
  columns:
    UserId:   { type: integer(8), primary: true, autoincrement: true }
    GroupId:  { type: integer(8), notnull: true  }
    Username: { type: string(255), notnull: true }
    Password: { type: string(255), notnull: true }
    Email:    { type: string(255), notnull: true }
  indexes:
    uniqueusername: { fields: [Username], type: unique }
    uniqueemail:    { fields: [Email], type: unique    }
  relations:
    WebsiteGroup: { class: RuczajGroup, local: GroupId, foreign: GroupId }
  options: { type: INNODB, collate: utf8_polish_ci, charset: utf8 }
</pre>
<p>to ustawienia nazwy tabeli i pól wygląda dość dziwnie, mianowicie nazwa tabeli nie jest faktyczną nazwą tabeli tylko czymś w rodzaju nazwy encji. Pola też należy pisać dokładnie takimi samymi literami(chodzi o wielkość) jak w pliku YAML, mimo że tworzone tabele składają się wyłącznie z małych liter. W sumie wydaje się to logiczne, ale trochę czasu mi zajęło dojście co oni tak naprawdę chcą a wyjątek typu<br />
<code>('The supplied parameters to Zend_Auth_Adapter_Doctrine_Record failed to produce a valid sql statement, please check table and column names for validity');</code> nie podpowiada zbyt wiele.</p>
<p>Poprawny kod autoryzacji wygląda zatem tak:</p>
<pre class="brush: php">
$dbConnection = Doctrine::getConnectionByTableName(&#039;website_users&#039;);
$authAdapter = new Zend_Auth_Adapter_Doctrine_Table($dbConnection);
$authAdapter-&gt;setTableName(&#039;WebsitejUser&#039;)
                  -&gt;setIdentityColumn(&#039;Username&#039;)
    		  -&gt;setCredentialColumn(&#039;Password&#039;)
		  -&gt;setCredentialTreatment(&#039;md5(?)&#039;);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/04/zend_auth-i-doctrine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Konto FTP dla każdego użytkownika</title>
		<link>http://piotr.doniec.eu/devlog/2009/04/konto-ftp-dla-kazdego-uzytkownika/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/04/konto-ftp-dla-kazdego-uzytkownika/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 17:24:53 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[IIS]]></category>
		<category><![CDATA[Windows 2008]]></category>
		<category><![CDATA[webhosting]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=142</guid>
		<description><![CDATA[Aby każdy użytkownik mógł zarządzać swoją stroną WWW, trzeba dać mu jakiś dostęp do zasobów. Może to być jakiegoś rodzaju interface dostępny przez przeglądarkę, albo konto FTP z którego korzysta zapewne niemal każdy webdeveloper. Można oczywiście dać każdemu dostęp do katalogu ftproot i mieć nadzieję że nikt nie będzie chciał złośliwie zmieniać plików innego użytkownika. [...]]]></description>
			<content:encoded><![CDATA[<p>Aby każdy użytkownik mógł zarządzać swoją stroną WWW, trzeba dać mu jakiś dostęp do zasobów. Może to być jakiegoś rodzaju interface dostępny przez przeglądarkę, albo konto FTP z którego korzysta zapewne niemal każdy webdeveloper. Można oczywiście dać każdemu dostęp do katalogu ftproot i mieć nadzieję że nikt nie będzie chciał złośliwie zmieniać plików innego użytkownika. Aby jednak nie polegać na ludzkich intencja należy odpowiednio skonfigurować sobie serwer.<span id="more-142"></span><br />
Instalacja samej usługi FTP i jej podstawowa konfiguracja nie jest większym problemem, dodaje się kolejną rolę jaka ma pełnić serwer. Co chcemy osiągnąć to odseparować konta użytkowników od siebie. Zatem w konfiguracji <code>"Domyślej strony FTP" (Default FTP Site)</code> klikamy w FTP User Isolation i z grupy <code>"Isolate Users. Restrict users to following directory"</code> opcję <code>"User name directory"</code>.<br />
<img class="aligncenter size-full wp-image-156" title="ftp-step2" src="http://piotr.doniec.eu/devlog/wp-content/uploads/2009/04/ftp-step2.png" alt="ftp-step2" width="600" height="450" /></p>
<p>Teraz należy utworzyć nowy katalog, koniecznie musi się nazywać <code>LocalUser</code> i być umieszczony w głównym katalogu FTP, przeważnie ftproot w inetpub. Dla każdego użytkownika możemy utworzyć <code>VirtualDirectory</code> i wskazać miejsce do którego ma mieć dostęp użytkownik. Ważne jest aby nazwa katalogu była identyczna jak nazwa użytkownika. Zadziała to w ten spsób że podczas logowania użytkownika np. <code>jankowalski</code> zostanie przeszukany katalog <code>LocalUser</code> w poszukiwania katalogu <code>jankowalski</code>, jeżeli się taki znajdzie to użytkownik zostaje zalogowany i skierowany do tego katalogu. W przeciwnym wypadku najprawdopodobniej spotka się on z odmową dostępu. <code>VirtualDirecotry</code> ma to do siebie że tylko wskazuje na jakiś fizyczny katalog, zatem można go ustawić aby wskazywał na katalog w którym można umieścić swoją stronę WWW i potem ją obejrzeć w przeglądarce np. <code>C:\Sites\JanCompany\</code>.<br />
<img class="aligncenter size-full wp-image-157" title="ftp-step3" src="http://piotr.doniec.eu/devlog/wp-content/uploads/2009/04/ftp-step3.png" alt="ftp-step3" width="600" height="451" /></p>
<p>Aby wszystko działało należy pamiętać o nadaniu odpowiednich praw dostępu dla odpowiednich użytkowników. Użytkownik <code>jankowalski</code> powinien móc zapisywać i odczytywać dane ze swojego katalogu i to jest oczywiste. Nie oczywiste jest to że musi on mieć także prawo do wyświetlenia katalogu głównego ftproot mimo że nie ma do niego bezpośredniego dostępu. Tak więc należy zezwolić użytkownikowi <code>jankowalski</code> na <code>List</code> katalogu głównego, ustawia się to we właściwościach folderu.</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/04/konto-ftp-dla-kazdego-uzytkownika/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Z C++ zagadka</title>
		<link>http://piotr.doniec.eu/devlog/2009/03/z-c-zagadka/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/03/z-c-zagadka/#comments</comments>
		<pubDate>Sat, 28 Mar 2009 10:29:17 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[tricky]]></category>
		<category><![CDATA[wirtualność]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=132</guid>
		<description><![CDATA[Na ostatnich inżynierskich targach pracy i praktytk trafiłem na dość trudny test z C++. Pojawiło się na nim zadanie co do którego miałem wątpliwości szczególnie że sprawdzający stwierdził że nie mam racji. Treść zapamiętałem i postanowiłem sprawdzić nie teoretycznie na kartce, ale po prostu jak się zachowa prawdziwy kompilator. Treść jest bardzo prosta, jaki będzie [...]]]></description>
			<content:encoded><![CDATA[<p>Na ostatnich inżynierskich targach pracy i praktytk trafiłem na dość trudny test z C++. Pojawiło się na nim zadanie co do którego miałem wątpliwości szczególnie że sprawdzający stwierdził że nie mam racji. Treść zapamiętałem i postanowiłem sprawdzić nie teoretycznie na kartce, ale po prostu jak się zachowa prawdziwy kompilator. <span id="more-132"></span>Treść jest bardzo prosta, jaki będzie efekt kompilacji i uruchomienia poniższego kodu:</p>
<pre class="brush: cpp">
class A
{
public:
  A() {
    fun();
  }

  virtual void fun()  {
    std::cout &lt;&lt; &quot;A::fun&quot; &lt;&lt; std::endl;
  }

  void fun2()  {
    fun();
  }
};

class B : public A
{
  void fun()  {
    std::cout &lt;&lt; &quot;B::fun&quot; &lt;&lt; std::endl;
  }
};

int main() {
  A* a = new B();
}
</pre>
<p>Poprawna odpowiedź:<br />
<code>A::fun</code><br />
dlaczego? W konstruktorze nie działa wirtualność. Zatem to ja miałem racje !<br />
Za to gdyby dopisać jeszcze </p>
<pre class="brush: cpp">
a-&gt;fun2();
</pre>
<p>to byśmy zobaczyli już <code>B::fun</code>. Problem zapewne rzadko w praktyce występuje ale jest to genialne zadanie na wszelkiej maści testy mające sprawdzić zaawansowaną znajomość mechanizmów języka C++</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/03/z-c-zagadka/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>A może jednak Python?</title>
		<link>http://piotr.doniec.eu/devlog/2009/03/a-moze-jednak-python/</link>
		<comments>http://piotr.doniec.eu/devlog/2009/03/a-moze-jednak-python/#comments</comments>
		<pubDate>Wed, 18 Mar 2009 19:14:53 +0000</pubDate>
		<dc:creator>pejotr</dc:creator>
				<category><![CDATA[Odkurzone]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://piotr.doniec.eu/devlog/?p=125</guid>
		<description><![CDATA[Do odkurzenia tego artykułu skusił mnie link przekazany przez kolegę: http://www.artima.com/weblogs/viewpost.jsp?thread=252441 . Związek jest dość luźny, pod linkiem jest raczej rozważanie na temat przyszłości języków programowania ich mutacji i wspomniane co nieco o Jython&#8217;ie. Poniższy wpis jest odkurzony i lekko przeredagowny. Python to język bardzo wysokiego poziomu w związku z tym tworzenie aplikacji w nim [...]]]></description>
			<content:encoded><![CDATA[<p>Do odkurzenia tego artykułu skusił mnie link przekazany przez kolegę: http://www.artima.com/weblogs/viewpost.jsp?thread=252441 . Związek jest dość luźny, pod linkiem jest raczej rozważanie na temat przyszłości języków programowania ich mutacji i wspomniane co nieco o Jython&#8217;ie. Poniższy wpis jest odkurzony i lekko przeredagowny.</p>
<p>Python to język bardzo wysokiego poziomu w związku z tym tworzenie aplikacji w nim powinno być szybkie. I może samo tworzenie jest, ale jak już się Pythona dobrze zna. Dostarczona dokumentacja jest średnio czytelna i korzystanie z niej nie było zbyt wygodne. Żeby korzystać z docs&#8217;ów Pythona trzeba mieć chyba jakiś dar.<br />
<span id="more-125"></span></p>
<h2><a id="core-documentation" name="core-documentation"></a></h2>
<blockquote><p>&#8222;Although both PHP and Python have excellent core documentation, Python&#8217;s is more extensive and generally higher quality.&#8221;</p></blockquote>
<p>No niestety nie moge się z tym zgodzić&#8230;<br />
Nie wiem jakie są powody że ludzie tak się zachwycają owym Pythonem. Ja bardzo się zniechęciłem gdy zobaczyłem że nie ma ani kwantyfikatowór dostępu, ani definicji pól klasy. Pola można sobie dodawać dowolnie w tracie działania, żadne deklaracje nie są wymagane. To takie wbudowane <em>__set</em> i <em>_call</em> z php.<br />
Napisanie programiku do logowania się do &#8222;wioski&#8221; w grze plemiona zajęło mi koło 2,5h.<br />
Linii mamy 32, co daje jakie 4,5 minuty na napisanie linii, a wiadomo że nie wszystkie linie są sobie równe.</p>
<pre class="brush: python">
import urllib, urllib2, cookielib

class PlemionaTool :
  def connect(self, username, password, world) :
    try:
      cookies = cookielib.CookieJar()
      self._world = world
      self._connection_handler = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookies))
      headers = {&quot;User-Agent&quot;: &quot;Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127 Firefox/2.0.0.11&quot;}
      login_data = urllib.urlencode({&quot;user&quot;: username,
                                              &quot;clear&quot;: &quot;true&quot;,
                                              &quot;password&quot;: password,
                                              &quot;server&quot;: world,
                                              &quot;login-btn-input&quot;: &quot;&quot;,
                                              &quot;cookie&quot; : &quot;false&quot;})
      request_http = &quot;http://www.plemiona.pl/index.php?action=login&quot;
      req = urllib2.Request(request_http, login_data, headers)
      self._connection_handler.open(req)
    except urllib2.HTTPError:
        print &quot;Jakis zonk&quot;

  def headquater(self) :
    response = self._connection_handler.open(&quot;http://&quot; + self._world +     &quot;.plemiona.pl/game.php?village=NUMER_WIOSKI&amp;amp;amp;amp;amp;amp;screen=main&quot;)
    page = response.read()
    return page

def main():
  pt = PlemionaTool()
  pt.connect(&quot;LOGIN&quot;, &quot;HASLO&quot;, &quot;SWIAT&quot;)
  print pt.headquater()

if __name__ == &#039;__main__&#039;:
  main()
</pre>
<p>Z zalet można wymienić wysokopoziomowość. Nie trzeba się męczyć z odbiorem, obróbką i wysyłaniem cookies, nie trzeba się też bawić z przechwytywć żadnego wyjątku  jak np. HTTPRedirect z Delphi.</p>
]]></content:encoded>
			<wfw:commentRss>http://piotr.doniec.eu/devlog/2009/03/a-moze-jednak-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

