[MANUAL] English:
[zend.git] / documentation / manual / pl / module_specs / Zend_Db_Adapter.xml
blobc55d8526bb212c70ad3c1351d1ffc18803a3f994
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- EN-Revision: 21740 -->
3 <!-- Reviewed: no -->
4 <sect1 id="zend.db.adapter">
5     <title>Zend_Db_Adapter</title>
7     <para>
8         <classname>Zend_Db</classname> i powiązane z nim klasy udostępniają prosty interfejs
9         dla baz danych <acronym>SQL</acronym> z poziomu Zend Framework. Klasa 
10         <classname>Zend_Db_Adapter</classname> jest podstawowym komponentem potrzebnym by
11         połączyć aplikację PHP z systemem zarządzania bazą danych (<acronym>RDBMS</acronym>).
12         Dla każdego rodzaju bazy danych istnieje oddzielna klasa adaptera 
13         <classname>Zend_Db</classname>.
14     </para>
16     <para>
17         Adaptery <classname>Zend_Db</classname> tworzą połączenie pomiędzy rozszerzeniami 
18         <acronym>PHP</acronym> dla konkretnych rodzajów baz danych a wspólnym interfejsem,
19         dzięki czemu można napisać aplikację raz i w nieskomplikowany sposób uruchamiać 
20         ją z wieloma rodzajami <acronym>RDBMS</acronym>
21     </para>
23     <para>
24         Interfejs klasy adaptera jest podobny do interfejsu rozszerzenia
25         <ulink url="http://www.php.net/pdo">PHP Data Objects</ulink>. <classname>Zend_Db</classname>
26         zawiera klasy adapterów dla sterowników <acronym>PDO</acronym> następujących rodzajów
27         baz danych:
28     </para>
30     <itemizedlist>
31         <listitem>
32             <para>
33                 IBM DB2 oraz Informix Dynamic Server (IDS), poprzez rozszerzenie
34                 <acronym>PHP</acronym>
35                 <ulink url="http://www.php.net/pdo-ibm">pdo_ibm</ulink>.
36             </para>
37         </listitem>
39         <listitem>
40             <para>
41                 MySQL, poprzez rozszerzenie <acronym>PHP</acronym>
42                 <ulink url="http://www.php.net/pdo-mysql">pdo_mysql</ulink>
43             </para>
44         </listitem>
46         <listitem>
47             <para>
48                 Microsoft <acronym>SQL</acronym> Server, używając rozszerzenia
49                 <acronym>PHP</acronym>
50                 <ulink url="http://www.php.net/pdo-dblib">pdo_dblib</ulink>
51             </para>
52         </listitem>
54         <listitem>
55             <para>
56                 Oracle, poprzez rozszerzenie <acronym>PHP</acronym>
57                 <ulink url="http://www.php.net/pdo-oci">pdo_oci</ulink>
58             </para>
59         </listitem>
61         <listitem>
62             <para>
63                 PostgreSQL, poprzez rozszerzenie <acronym>PHP</acronym>
64                 <ulink url="http://www.php.net/pdo-pgsql">pdo_pgsql</ulink>
65             </para>
66         </listitem>
68         <listitem>
69             <para>
70                 SQLite, używając rozszerzenia <acronym>PHP</acronym>
71                 <ulink url="http://www.php.net/pdo-sqlite">pdo_sqlite</ulink>
72             </para>
73         </listitem>
74     </itemizedlist>
76     <para>
77         Dodatkowo <classname>Zend_Db</classname> dostarcza klas adapterów korzystających
78         z rozszerzeń <acronym>PHP</acronym> dla następujących rodzajów
79         baz danych:
80     </para>
82     <itemizedlist>
83         <listitem>
84             <para>
85                 MySQL, poprzez rozszerzenie <acronym>PHP</acronym>
86                 <ulink url="http://www.php.net/mysqli">mysqli</ulink>
87             </para>
88         </listitem>
90         <listitem>
91             <para>
92                 Oracle, poprzez rozszerzenie <acronym>PHP</acronym>
93                 <ulink url="http://www.php.net/oci8">oci8</ulink>
94             </para>
95         </listitem>
97         <listitem>
98             <para>
99                 IBM DB2 oraz DB2/i5, poprzez rozszerzenie <acronym>PHP</acronym>
100                 <ulink url="http://www.php.net/ibm_db2">ibm_db2</ulink>
101             </para>
102         </listitem>
104         <listitem>
105             <para>
106                 Firebird/Interbase, poprzez rozszerzenie <acronym>PHP</acronym>
107                 <ulink url="http://www.php.net/ibase">php_interbase</ulink>
108             </para>
109         </listitem>
110     </itemizedlist>
112     <note>
113         <para>
114             Każdy adapter <classname>Zend_Db</classname> używa określonego rozszerzenia
115             <acronym>PHP</acronym>. Aby użyć adaptera należy mieć zainstalowane i włączone
116             odpowiadające mu rozszerzenie <acronym>PHP</acronym>. Np. aby użyć dowolnego
117             adaptera <acronym>PDO</acronym> <classname>Zend_Db</classname>, wymagane jest
118             posiadanie włączonego rozszerzenia <acronym>PDO</acronym> oraz sterownika dla 
119             danego rodzaju <acronym>RDBMS</acronym>.
120         </para>
121     </note>
123     <sect2 id="zend.db.adapter.connecting">
124         <title>Połączenie z bazą danych za pomocą adaptera</title>
126         <para>
127             Ta część opisuje jak tworzy się instancję adaptera bazy danych. Jest to odpowiednik
128             połączenia z bazą danych w aplikacji <acronym>PHP</acronym>.
129         </para>
131         <sect3 id="zend.db.adapter.connecting.constructor">
132             <title>Użycie konstruktora adaptera Zend_Db</title>
134             <para>
135                 Można utworzyć instancję adaptera za pomocą konstruktora. Przyjmuje on
136                 pojedynczy argument - tablicę parametrów używanych do deklaracji połączenia. 
137             </para>
139             <example id="zend.db.adapter.connecting.constructor.example">
140                 <title>Użycie konstruktora adaptera</title>
142                 <programlisting language="php"><![CDATA[
143 $db = new Zend_Db_Adapter_Pdo_Mysql(array(
144     'host'     => '127.0.0.1',
145     'username' => 'webuser',
146     'password' => 'xxxxxxxx',
147     'dbname'   => 'test'
149 ]]></programlisting>
150             </example>
151         </sect3>
153         <sect3 id="zend.db.adapter.connecting.factory">
154             <title>Użycie fabryki Zend_Db</title>
156             <para>
157                 Alternatywą w stosunku do bezpośredniego używania konstruktora jest utworzenie
158                 instancji adaptera za pomocą statycznej metody 
159                 <methodname>Zend_Db::factory()</methodname>. Ta metoda dynamicznie ładuje plik
160                 klasy adaptera używając
161                 <link linkend="zend.loader.load.class">Zend_Loader::loadClass()</link>.
162             </para>
164             <para>
165                 Pierwszy argument metody to łańcuch znaków, który wyznacza nazwę bazową klasy
166                 adaptera. Np. string '<classname>Pdo_Mysql</classname>' odpowiada klasie
167                 <classname>Zend_Db_Adapter_Pdo_Mysql</classname>. Drugi argument to ta sama
168                 tablica parametrów, którą należało podać adapterowi konstruktora.
169             </para>
171             <example id="zend.db.adapter.connecting.factory.example">
172                 <title>Użycie metody fabryki adaptera</title>
174                 <programlisting language="php"><![CDATA[
175 // Poniższa instrukcja jest zbędna ponieważ plik z klasą
176 // Zend_Db_Adapter_Pdo_Mysql zostanie załadowany przez fabrykę
177 // Zend_Db
179 // require_once 'Zend/Db/Adapter/Pdo/Mysql.php';
181 // Załaduj klasę Zend_Db_Adapter_Pdo_Mysql automatycznie
182 // i utwórz jej instancję
183 $db = Zend_Db::factory('Pdo_Mysql', array(
184     'host'     => '127.0.0.1',
185     'username' => 'webuser',
186     'password' => 'xxxxxxxx',
187     'dbname'   => 'test'
189 ]]></programlisting>
190             </example>
192             <para>
193                 Jeśli jest zdefiniowana własna klasa dziedzicząca po
194                 <classname>Zend_Db_Adapter_Abstract</classname> ale jej nazwa nie zawiera
195                 "<classname>Zend_Db_Adapter</classname>", można użyć metody
196                 <methodname>factory()</methodname> do załadowania adaptera jedynie jeśli
197                 poda się swój prefiks nazwy adaptera z kluczem 'adapterNamespace' do
198                 argumentu zawierającego parametry połączenia.
199             </para>
201             <example id="zend.db.adapter.connecting.factory.example2">
202                 <title>Użycie metody fabryki dla własnej klasy adaptera</title>
203                 <programlisting language="php"><![CDATA[
204 // Nie trzeba ładować pliku klasy adaptera
205 // bo robi to metoda fabryki Zend_Db
207 // Załadowanie klasy MyProject_Db_Adapter_Pdo_Mysql automatycznie
208 // i utworzenie jej instancji
209 $db = Zend_Db::factory('Pdo_Mysql', array(
210     'host'             => '127.0.0.1',
211     'username'         => 'webuser',
212     'password'         => 'xxxxxxxx',
213     'dbname'           => 'test',
214     'adapterNamespace' => 'MyProject_Db_Adapter'
216 ]]></programlisting>
217             </example>
218         </sect3>
220         <sect3 id="zend.db.adapter.connecting.factory-config">
221             <title>Użycie Zend_Config z fabryką Zend_Db</title>
223             <para>
224                 Każdy z argumentów metody <methodname>factory()</methodname> może również zostać
225                 podany w formie obiektu klasy <link linkend="zend.config">Zend_Config</link>.
226             </para>
228             <para>
229                 Jeśli pierwszy argument jest obiektem <classname>Zend_Config</classname>
230                 to wymagane jest aby posiadał właściwość o nazwie
231                 <property>adapter</property>, w której będzie zapisany łańcuch znaków
232                 określający nazwę bazową klasy adaptera. Opcjonalnie, obiekt ten może zawierać
233                 właściwość '<property>params</property>' z właściwościami potomnymi
234                 odpowiadającymi nazwom parametrów adaptera. Będą one użyte jedynie w
235                 przypadku braku drugiego argumentu metody
236                 <methodname>factory()</methodname>.
237             </para>
239             <example id="zend.db.adapter.connecting.factory.example1">
240                 <title>Użycie metody fabryki adaptera z obiektem Zend_Config</title>
242                 <para>
243                     W poniższym przykładzie, obiekt <classname>Zend_Config</classname>
244                     jest utworzony z tablicy.
245                     Można również załadować dane z pliku zewnętrznego poprzez klasy
246                     <link linkend="zend.config.adapters.ini">Zend_Config_Ini</link> oraz
247                     <link linkend="zend.config.adapters.xml">Zend_Config_Xml</link>.
248                 </para>
250                 <programlisting language="php"><![CDATA[
251 $config = new Zend_Config(
252     array(
253         'database' => array(
254             'adapter' => 'Mysqli',
255             'params'  => array(
256                 'host'     => '127.0.0.1',
257                 'dbname'   => 'test',
258                 'username' => 'webuser',
259                 'password' => 'secret',
260             )
261         )
262     )
265 $db = Zend_Db::factory($config->database);
266 ]]></programlisting>
267             </example>
269             <para>
270                 Drugi argument metody <methodname>factory()</methodname> może stanowić tablicę
271                 asocjacyjną zawierającą wartości odpowiadające parametrom adaptera. Ten argument 
272                 jest opcjonalny. Jeśli pierwszy argument jest obiektem klasy 
273                 <classname>Zend_Config</classname> to powinien zawierać wszystkie parametry a
274                 drugi argument jest ignorowany. 
275             </para>
276         </sect3>
278         <sect3 id="zend.db.adapter.connecting.parameters">
279             <title>Parametry adaptera</title>
281             <para>
282                 Poniższa lista opisuje parametry wspólne dla klas adapterów 
283                 <classname>Zend_Db</classname>.
284             </para>
286             <itemizedlist>
287                 <listitem>
288                     <para>
289                         <emphasis>host</emphasis>:
290                         łańcuch znaków zawierający nazwę hosta lub adres IP serwera bazy danych.
291                         Jeśli baza danych jest uruchomiona na tej samej maszynie co aplikacja to
292                         można tu umieścić 'localhost' lub '127.0.0.1'.
293                     </para>
294                 </listitem>
296                 <listitem>
297                     <para>
298                         <emphasis>username</emphasis>:
299                         identyfikator użytkownika używany do autoryzacji połączenia z serwerem 
300                         bazy danych.
301                     </para>
302                 </listitem>
304                 <listitem>
305                     <para>
306                         <emphasis>password</emphasis>:
307                         hasło użytkownika używane do autoryzacji połączenia z serwerem 
308                         bazy danych.
309                     </para>
310                 </listitem>
312                 <listitem>
313                     <para>
314                         <emphasis>dbname</emphasis>:
315                         nazwa instancji bazy danych na serwerze.
316                     </para>
317                 </listitem>
319                 <listitem>
320                     <para>
321                         <emphasis>port</emphasis>:
322                         niektóre serwery bazy danych używają do komunikacji numeru portu określonego 
323                         przez administratora. Ten parametr pozwala na ustawienie numeru portu przez 
324                         który aplikacja <acronym>PHP</acronym> się łączy tak aby zgadzał się z tym
325                         ustawionym na serwerze bazy danych.
326                     </para>
327                 </listitem>
329                 <listitem>
330                     <para>
331                         <emphasis>charset</emphasis>:
332                         określenie zestawu znaków używanego podczas połączenia.
333                     </para>
334                 </listitem>
336                 <listitem>
337                     <para>
338                         <emphasis>options</emphasis>:
339                         ten parametr to tablica asocjacyjna opcji obsługiwanych przez wszystkie
340                         klasy <classname>Zend_Db_Adapter</classname>.
341                     </para>
342                 </listitem>
344                 <listitem>
345                     <para>
346                         <emphasis>driver_options</emphasis>:
347                         ten parametr to tablica asocjacyjna zawierająca dodatkowe opcje
348                         specyficzne dla każdego rozszerzenia bazy danych. Typowym przykładem
349                         użycia tego parametru jest zbiór atrybutów sterownika
350                         <acronym>PDO</acronym>.
351                     </para>
352                 </listitem>
354                 <listitem>
355                     <para>
356                         <emphasis>adapterNamespace</emphasis>:
357                         początkowa część nazwy klasy używanego adaptera, używana zamiast
358                         '<classname>Zend_Db_Adapter</classname>'. Przydatna w przypadku użycia
359                         metody <methodname>factory()</methodname> do załadowana własnej klasy
360                         adaptera.
361                     </para>
362                 </listitem>
363             </itemizedlist>
365             <example id="zend.db.adapter.connecting.parameters.example1">
366                 <title>Przekazanie do fabryki opcji zmiany wielkości znaków</title>
368                 <para>
369                     Opcję tą można podać za pomocą stałej
370                     <constant>Zend_Db::CASE_FOLDING</constant>.
371                     Odpowiada ona atrybutowi <constant>ATTR_CASE</constant> w <acronym>PDO</acronym>
372                     oraz rozszerzeniu IBM DB2, który zmienia wielkość znaków w nazwach kolumn 
373                     zwracanych w rezultacie zapytania. Opcja przybiera wartości
374                     <constant>Zend_Db::CASE_NATURAL</constant> (bez zmiany - domyślnie),
375                     <constant>Zend_Db::CASE_UPPER</constant> (zmiana na wielkie znaki) oraz
376                     <constant>Zend_Db::CASE_LOWER</constant> (zmiana na małe znaki).
377                 </para>
379                 <programlisting language="php"><![CDATA[
380 $options = array(
381     Zend_Db::CASE_FOLDING => Zend_Db::CASE_UPPER
384 $params = array(
385     'host'           => '127.0.0.1',
386     'username'       => 'webuser',
387     'password'       => 'xxxxxxxx',
388     'dbname'         => 'test',
389     'options'        => $options
392 $db = Zend_Db::factory('Db2', $params);
393 ]]></programlisting>
394             </example>
396             <example id="zend.db.adapter.connecting.parameters.example2">
397                 <title>Przekazanie do fabryki opcji automatycznego umieszczania
398                 w cudzysłowie</title>
400                 <para>
401                     Tą opcję można podać za pomocą stałej
402                     <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant>.
403                     Jeśli jej wartość wynosi <constant>TRUE</constant> (domyślnie) to identyfikatory
404                     takie jak nazwy tabel, kolumn oraz aliasy w składni każdego    polecenia 
405                     <acronym>SQL</acronym> generowanego za pomocą danego adaptera będą 
406                     umieszczane w cudzysłowie. Takie podejście upraszcza używanie identyfikatorów
407                     zawierających słowa kluczowe <acronym>SQL</acronym> lub znaki specjalne. Jeśli
408                     wartość opcji wynosi <constant>FALSE</constant> to identyfikatory nie są
409                     umieszczane w cudzysłowie. Jeśli zachodzi potrzeba owinięcia identyfikatorów
410                     cudzysłowami należy to zrobić samodzielnie za pomocą metody
411                     <methodname>quoteIdentifier()</methodname>.
412                 </para>
414                 <programlisting language="php"><![CDATA[
415 $options = array(
416     Zend_Db::AUTO_QUOTE_IDENTIFIERS => false
419 $params = array(
420     'host'           => '127.0.0.1',
421     'username'       => 'webuser',
422     'password'       => 'xxxxxxxx',
423     'dbname'         => 'test',
424     'options'        => $options
427 $db = Zend_Db::factory('Pdo_Mysql', $params);
428 ]]></programlisting>
429             </example>
431             <example id="zend.db.adapter.connecting.parameters.example3">
432                 <title>Przekazanie do fabryki opcji sterownika PDO</title>
434                 <programlisting language="php"><![CDATA[
435 $pdoParams = array(
436     PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true
439 $params = array(
440     'host'           => '127.0.0.1',
441     'username'       => 'webuser',
442     'password'       => 'xxxxxxxx',
443     'dbname'         => 'test',
444     'driver_options' => $pdoParams
447 $db = Zend_Db::factory('Pdo_Mysql', $params);
449 echo $db->getConnection()
450         ->getAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY);
451 ]]></programlisting>
452             </example>
454             <example id="zend.db.adapter.connecting.parameters.example4">
455                 <title>Przekazanie do fabryki opcji serializacji</title>
457                 <programlisting language="php"><![CDATA[
458 $options = array(
459     Zend_Db::ALLOW_SERIALIZATION => false
462 $params = array(
463     'host'           => '127.0.0.1',
464     'username'       => 'webuser',
465     'password'       => 'xxxxxxxx',
466     'dbname'         => 'test',
467     'options'        => $options
470 $db = Zend_Db::factory('Pdo_Mysql', $params);
471 ]]></programlisting>
472             </example>
473         </sect3>
475         <sect3 id="zend.db.adapter.connecting.getconnection">
476             <title>Zarządzanie leniwymi połączeniami</title>
478             <para>
479                 Utworzenie instancji klasy adaptera nie powoduje natychmiastowego połączenia
480                 z serwerem bazy danych. Adapter zachowuje parametry połączenia ale łączy się
481                 na żądanie - w momencie pierwszego wywołania zapytania. Dzięki temu zainicjowanie
482                 adaptera jest szybkie i tanie. Można utworzyć adapter nawet jeśli nie jest
483                 się pewnym czy wykonanie jakiegokolwiek zapytania przy danym połączeniu będzie
484                 niezbędne.
485             </para>
487             <para>
488                 Jeśli zajdzie potrzeba zmuszenia adaptera do połączenia z bazą danych,
489                 należy wówczas wywołać metodę <methodname>getConnection()</methodname>.
490                 Zwraca ona obiekt połączenia odpowiednio do rozszerzenia
491                 <acronym>PHP</acronym> używanego do połączenia. Jeśli
492                 używa się adaptera korzystającego z <acronym>PDO</acronym>, to metoda
493                 <methodname>getConnection()</methodname>, po zainicjowaniu połączenia
494                 z serwerem bazy danych, zwróci obiekt <acronym>PDO</acronym>.
495             </para>
497             <para>
498                 Możliwość wymuszenia połączenia z bazą danych może być przydatna gdy chce się
499                 złapać wyjątki rzucane przez adapter powstałe w rezultacie podania złych danych
500                 uwierzytelniających lub innych błędów połączenia. Te wyjątki nie są rzucane dopóki
501                 nie jest ustanowiona próba połączenia, więc można uprościć kod aplikacji i obsłużyć
502                 je w jednym miejscu. W przeciwnym razie należałoby je przechwycać w momencie 
503                 wywołania pierwszego zapytania do bazy danych.
504             </para>
506             <para>
507                 Dodatkowo adapter może zostać poddany serializacji i przechowany
508                 np. w zmiennej sesyjnej.
509                 Może to być pomocne nie tylko dla adaptera ale również z punktu widzenia obiektów,
510                 które z niego korzystają, takich jak <classname>Zend_Db_Select</classname>.
511                 Domyślnie serializacja adapterów jest dozwolona ale jeśli jest taka
512                 potrzeba - można ją wyłączyć poprzez podanie opcji
513                 <constant>Zend_Db::ALLOW_SERIALIZATION</constant> z wartością 
514                 <constant>FALSE</constant> (przykład niżej).
515                 Aby pozostać w zgodzie z zasadą leniwego połączenia, adapter nie połączy się
516                 automatycznie po odserializowaniu. Należy zatem
517                 wywołać metodę <methodname>getConnection()</methodname>.
518                 Można również zmusić adapter aby po odserializowaniu łączył się z bazą
519                 danych automatycznie poprzez podanie opcji
520                 <constant>Zend_Db::AUTO_RECONNECT_ON_UNSERIALIZE</constant>
521                 z wartością <constant>TRUE</constant>.
522             </para>
524             <example id="zend.db.adapter.connecting.getconnection.example">
525                 <title>Obsługa wyjątków połączenia</title>
527                 <programlisting language="php"><![CDATA[
528 try {
529     $db = Zend_Db::factory('Pdo_Mysql', $parameters);
530     $db->getConnection();
531 } catch (Zend_Db_Adapter_Exception $e) {
532     // przyczyną problemów mogą być złe dane uwierzytelniające lub np. baza danych
533     // nie jest uruchomiona
534 } catch (Zend_Exception $e) {
535     // przyczyną może być np. problem z załadowaniem odpowiedniej klasy adaptera
537 ]]></programlisting>
538             </example>
540         </sect3>
542     </sect2>
544     <sect2 id="zend.db.adapter.example-database">
546         <title>Przykładowa baza danych</title>
548         <para>
549             W dokumentacji klas <classname>Zend_Db</classname> używany jest prosty zestaw tabel w
550             celu zilustrowania użycia klas i metod. Te tabele mogą przechowywać dane związane z
551             przechowywaniem błędów (bugs) powstałych podczas rozwijania projektu informatycznego.
552             Baza danych zawiera cztery tabele:
553         </para>
555         <itemizedlist>
556             <listitem>
557                 <para>
558                     <emphasis>accounts</emphasis> przechowuje informacje o każdym użytkowniku
559                     bazy danych błędów.
560                 </para>
561             </listitem>
562             <listitem>
563                 <para>
564                     <emphasis>products</emphasis> przechowuje informacje o każdym produkcie,
565                     dla którego można zapisać wystąpienie usterki.
566                 </para>
567             </listitem>
568             <listitem>
569                 <para>
570                     <emphasis>bugs</emphasis> przechowuje informacje o błędach, włączając
571                     jego obecny stan, osobę zgłaszającą, osobę przypisaną do rozwiązania
572                     problemu oraz osobę przeznaczoną do zweryfikowania poprawności 
573                     zastosowanego rozwiązania.
574                 </para>
575             </listitem>
576             <listitem>
577                 <para>
578                     <emphasis>bugs_products</emphasis> przechowuje relację pomiędzy usterkami
579                     a produktami. To odzwierciedla połączenie wiele-do-wielu, ponieważ dany błąd
580                     może się odnosić do wielu produktów a jeden produkt może posiadać wiele usterek.
581                 </para>
582             </listitem>
583         </itemizedlist>
585         <para>
586             Poniższy pseudokod definicji danych <acronym>SQL</acronym> opisuje tabele z tego
587             przykładu. Te tabele są bardzo często używane w testach jednostkowych
588             <classname>Zend_Db</classname>.
589         </para>
591         <programlisting language="sql"><![CDATA[
592 CREATE TABLE accounts (
593   account_name      VARCHAR(100) NOT NULL PRIMARY KEY
596 CREATE TABLE products (
597   product_id        INTEGER NOT NULL PRIMARY KEY,
598   product_name      VARCHAR(100)
601 CREATE TABLE bugs (
602   bug_id            INTEGER NOT NULL PRIMARY KEY,
603   bug_description   VARCHAR(100),
604   bug_status        VARCHAR(20),
605   reported_by       VARCHAR(100) REFERENCES accounts(account_name),
606   assigned_to       VARCHAR(100) REFERENCES accounts(account_name),
607   verified_by       VARCHAR(100) REFERENCES accounts(account_name)
610 CREATE TABLE bugs_products (
611   bug_id            INTEGER NOT NULL REFERENCES bugs,
612   product_id        INTEGER NOT NULL REFERENCES products,
613   PRIMARY KEY       (bug_id, product_id)
615 ]]></programlisting>
617         <para>
618             Należy zwrócić uwagę, iż tabela 'bugs' zawiera wiele kluczy obcych
619             odnoszących się do tabeli 'accounts'. Każdy z nich może prowadzić do
620             innego wiersza tabeli 'accounts' w ramach jednego bugu.
621         </para>
623         <para>
624             Poniższy diagram ilustruje fizyczny model danych przykładowej bazy danych
625         </para>
627         <para>
628             <inlinegraphic width="387" scale="100" align="center" valign="middle"
629                 fileref="figures/zend.db.adapter.example-database.png" format="PNG" />
630         </para>
632     </sect2>
634     <sect2 id="zend.db.adapter.select">
636         <title>Pobranie rezultatów zapytania</title>
638         <para>
639             Ta część opisuje metody klasy adaptera za pomocą których można wywołać
640             zapytania <acronym>SELECT</acronym> oraz pobrać ich rezultaty.
641         </para>
643         <sect3 id="zend.db.adapter.select.fetchall">
645             <title>Pobranie całego zbioru rezultatów</title>
647             <para>
648                 Za pomocą metody <methodname>fetchAll()</methodname> można wywołać zapytanie 
649                 <acronym>SQL</acronym> <acronym>SELECT</acronym> oraz pobrać jego rezultaty
650                 w jednym kroku.
651             </para>
653             <para>
654                 Pierwszym argumentem metody jest łańcuch znaków zawierający polecenie 
655                 <acronym>SELECT</acronym>. Alternatywnie, w pierwszym argumencie można umieścić
656                 obiekt klasy <link linkend="zend.db.select">Zend_Db_Select</link>. Adapter
657                 automatycznie dokonuje konwersji tego obiektu do łańcucha znaków zawierającego
658                 zapytanie <acronym>SELECT</acronym>.
659             </para>
661             <para>
662                 Drugi argument metody <methodname>fetchAll()</methodname> to tablica wartości
663                 używanych do zastąpienia parametrów wiązanych w zapytaniu <acronym>SQL</acronym>.
664             </para>
666             <example id="zend.db.adapter.select.fetchall.example">
667                 <title>Użycie metody fetchAll()</title>
668                 <programlisting language="php"><![CDATA[
669 $sql = 'SELECT * FROM bugs WHERE bug_id = ?';
671 $result = $db->fetchAll($sql, 2);
672 ]]></programlisting>
673             </example>
675         </sect3>
677         <sect3 id="zend.db.adapter.select.fetch-mode">
679             <title>Zmiana trybu zwracania danych</title>
681             <para>
682                 Domyślnie <methodname>fetchAll()</methodname> zwraca tablicę wierszy, z których
683                 każdy jest tablicą asocjacyjną. Kluczami tablicy asocjacyjnej są kolumny lub ich 
684                 aliasy podane w zapytaniu <acronym>SELECT</acronym>.
685             </para>
687             <para>
688                 Można ustawić inny tryb zwracania rezultatów poprzez metodę
689                 <methodname>setFetchMode()</methodname>. Dopuszczalne tryby są identyfikowane
690                 przez stałe:
691             </para>
693             <itemizedlist>
694                 <listitem>
695                     <para>
696                         <emphasis>Zend_Db::FETCH_ASSOC</emphasis>:
697                         zwraca dane w postaci tablicy tablic asocjacyjnych.
698                         Klucze tablicy asocjacyjnej
699                         to nazwy kolumn. To jest domyślny tryb zwrotu danych w klasach
700                          <classname>Zend_Db_Adapter</classname>.
701                     </para>
702                     <para>
703                         Należy zwrócić uwagę na fakt iż jeśli lista kolumn do zwrotu
704                         zawiera więcej niż     jedną kolumnę o określonej nazwie,
705                         np. jeśli pochodzą one z różnych tabel 
706                         połączonych klauzulą <acronym>JOIN</acronym>, to w asocjacyjnej
707                         tablicy wynikowej może być tylko jeden klucz o podanej nazwie.
708                         Jeśli używany jest tryb <acronym>FETCH_ASSOC</acronym>,
709                         należy upewnić się, że kolumny w zapytaniu
710                         <acronym>SELECT</acronym> posiadają aliasy, dzięki czemu rezultat zapytania
711                         będzie zawierał unikatowe nazwy kolumn.
712                     </para>
713                     <para>
714                         Domyślnie, łańcuchy znaków z nazwami kolumn są zwracane w taki sposób w jaki
715                         zostały otrzymane przez sterownik bazy danych. Przeważnie jest odpowiada to
716                         stylowi nazw kolumn używanego rodzaju bazy danych. Dzięki opcji
717                         <constant>Zend_Db::CASE_FOLDING</constant> można określić wielkość
718                         zwracanych znaków.
719                         Opcji tej można użyć podczas inicjowania adaptera.
720                         Przykład: <xref linkend="zend.db.adapter.connecting.parameters.example1" />.
721                     </para>
722                 </listitem>
723                 <listitem>
724                     <para>
725                         <emphasis>Zend_Db::FETCH_NUM</emphasis>:
726                         zwraca dane jako tablicę tablic. Indeksami tablicy są liczby całkowite 
727                         odpowiadające pozycji danej kolumny w liście <acronym>SELECT</acronym>
728                         zapytania.
729                     </para>
730                 </listitem>
731                 <listitem>
732                     <para>
733                         <emphasis>Zend_Db::FETCH_BOTH</emphasis>:
734                         zwraca dane jako tablicę tablic. Kluczami tablicy są zarówno łańcuchy znaków
735                         (tak jak w trybie FETCH_ASSOC) oraz liczby całkowite (tak jak w trybie
736                         FETCH_NUM). Należy zwrócić uwagę na fakt iż liczba elementów
737                         tablicy wynikowej będzie dwukrotnie większa niż w przypadku
738                         użycia trybów  FETCH_ASSOC lub FETCH_NUM.
739                     </para>
740                 </listitem>
741                 <listitem>
742                     <para>
743                         <emphasis>Zend_Db::FETCH_COLUMN</emphasis>:
744                         zwraca dane jako tablicę wartości. Wartości odpowiadają rezultatom
745                         zapytania przypisanym jednej kolumnie zbioru wynikowego.
746                         Domyślnie, jest to pierwsza kolumna,
747                         indeksy rozpoczynają się od 0.
748                     </para>
749                 </listitem>
750                 <listitem>
751                     <para>
752                         <emphasis>Zend_Db::FETCH_OBJ</emphasis>:
753                         zwraca dane jako tablicę obiektów. Domyślną klasą jest wbudowana
754                         w <acronym>PHP</acronym> klasa stdClass.
755                         Kolumny rezultatu zapytania stają się właściwościami powstałego obiektu.
756                     </para>
757                 </listitem>
758             </itemizedlist>
760             <example id="zend.db.adapter.select.fetch-mode.example">
761                 <title>Użycie metody setFetchMode()</title>
762                 <programlisting language="php"><![CDATA[
763 $db->setFetchMode(Zend_Db::FETCH_OBJ);
765 $result = $db->fetchAll('SELECT * FROM bugs WHERE bug_id = ?', 2);
767 // $result jest tablicą obiektów 
768 echo $result[0]->bug_description;
769 ]]></programlisting>
770             </example>
772         </sect3>
774         <sect3 id="zend.db.adapter.select.fetchassoc">
776             <title>Pobranie rezultatów jako tablicy asocjacyjnej</title>
778             <para>
779                 Metoda <methodname>fetchAssoc()</methodname> zwraca dane w formie tablicy tablic
780                 asocjacyjnych, niezależnie od wartości ustalonej jako tryb
781                 zwracania rezultatów zapytania.
782             </para>
784             <example id="zend.db.adapter.select.fetchassoc.example">
785                 <title>Użycie fetchAssoc()</title>
786                 <programlisting language="php"><![CDATA[
787 $db->setFetchMode(Zend_Db::FETCH_OBJ);
789 $result = $db->fetchAssoc('SELECT * FROM bugs WHERE bug_id = ?', 2);
791 // $result staje się tablicą tablic asocjacyjnych, mimo ustawionego
792 // trybu zwracania rezultatów zapytania
793 echo $result[0]['bug_description'];
794 ]]></programlisting>
795             </example>
797         </sect3>
799         <sect3 id="zend.db.adapter.select.fetchcol">
801             <title>Zwrócenie pojedynczej kolumny ze zbioru wynikowego</title>
803             <para>
804                 Metoda <methodname>fetchCol()</methodname> zwraca dane w postaci tablicy wartości
805                 niezależnie od wartości ustalonej jako tryb zwrcania rezultatów zapytania. Ta
806                 metoda zwraca pierwszą kolumnę ze zbioru powstałego na skutek wywołania zapytania.
807                 Inne kolumny znajdujące się w tym zbiorze są ignorowane. Aby zwrócić inną niż 
808                 pierwsza kolumnę należy skorzystać z przykładu
809                 <xref linkend="zend.db.statement.fetching.fetchcolumn" />.
810             </para>
812             <example id="zend.db.adapter.select.fetchcol.example">
813                 <title>Użycie fetchCol()</title>
814                 <programlisting language="php"><![CDATA[
815 $db->setFetchMode(Zend_Db::FETCH_OBJ);
817 $result = $db->fetchCol(
818     'SELECT bug_description, bug_id FROM bugs WHERE bug_id = ?', 2);
820 // zawiera bug_description; bug_id nie zostanie zwrócona
821 echo $result[0];
822 ]]></programlisting>
823             </example>
825         </sect3>
827         <sect3 id="zend.db.adapter.select.fetchpairs">
829             <title>Zwrócenie ze zbioru wynikowego par klucz-wartość</title>
831             <para>
832                 Metoda <methodname>fetchPairs()</methodname> zwraca dane w postaci tablicy
833                 par klucz-wartość. Zwracana jest to tablica asocjacyjna z pojedynczą wartością
834                 w każdym polu. Wartości z pierwszej kolumny zapytania <acronym>SELECT</acronym>
835                 stają się kluczami tablicy wynikowej zaś wartości drugiej zostają umieszczone
836                 jako wartości tablicy. Pozostałe kolumny zwracane przez zapytanie są ignorowane.
837             </para>
839             <para>
840                 Należy konstruować zapytanie <acronym>SELECT</acronym> w taki sposób aby pierwsza
841                 kolumna posiadała unikalne wartości. W przeciwnym wypadku wartości
842                 tablicy asocjacyjnej zostaną nadpisane.
843             </para>
845             <example id="zend.db.adapter.select.fetchpairs.example">
846                 <title>Użycie fetchPairs()</title>
847                 <programlisting language="php"><![CDATA[
848 $db->setFetchMode(Zend_Db::FETCH_OBJ);
850 $result = $db->fetchPairs('SELECT bug_id, bug_status FROM bugs');
852 echo $result[2];
853 ]]></programlisting>
854             </example>
855         </sect3>
857         <sect3 id="zend.db.adapter.select.fetchrow">
859             <title>Zwrócenie pojedynczego wiersza ze zbioru wynikowego</title>
861             <para>
862                 Metoda <methodname>fetchRow()</methodname> pobiera dane używając bieżącego 
863                 trybu zwracania rezultatów ale zwraca jedynie pierwszy wiersz ze zbioru
864                 wynikowego.
865             </para>
867             <example id="zend.db.adapter.select.fetchrow.example">
868                 <title>Using fetchRow()</title>
869                 <programlisting language="php"><![CDATA[
870 $db->setFetchMode(Zend_Db::FETCH_OBJ);
872 $result = $db->fetchRow('SELECT * FROM bugs WHERE bug_id = 2');
874 // $result to pojedynczy obiekt a nie tablica obiektów
875 echo $result->bug_description;
876 ]]></programlisting>
877             </example>
878         </sect3>
880         <sect3 id="zend.db.adapter.select.fetchone">
882             <title>Zwrócenie pojedynczej wartości ze zbioru wynikowego</title>
884             <para>
885                 Metoda <methodname>fetchOne()</methodname> można opisać jako kombinacja 
886                 <methodname>fetchRow()</methodname> oraz <methodname>fetchCol()</methodname>
887                 bo zwraca dane pochodzące z pierwszego wiersza zbioru wynikowego ograniczając
888                 kolumny do pierwszej w wierszu. Ostatecznie zostaje zwrócona pojedyncza
889                 wartość skalarna a nie tablica czy obiekt
890             </para>
892             <example id="zend.db.adapter.select.fetchone.example">
893                 <title>Using fetchOne()</title>
894                 <programlisting language="php"><![CDATA[
895 $result = $db->fetchOne('SELECT bug_status FROM bugs WHERE bug_id = 2');
897 // pojedyncza wartość string
898 echo $result;
899 ]]></programlisting>
900             </example>
901         </sect3>
903     </sect2>
905     <sect2 id="zend.db.adapter.write">
907         <title>Zapisywanie zmian do bazy danych</title>
909         <para>
910             Adaptera klasy można użyć również do zapisania nowych, bądź do zmiany
911             istniejących danych w bazie. Ta część opisuje metody włąściwe dla tych operacji.
912         </para>
914         <sect3 id="zend.db.adapter.write.insert">
916             <title>Dodawanie danych</title>
918             <para>
919                 Za pomocą metody <methodname>insert()</methodname> można dodać nowe wiersze
920                 do tabeli bazy danych. Jej pierwszym argumentem jest łańcuch znaków oznaczający
921                 nazwę tabeli. Drugim - tablica asocjacyjna z odwzorowaniem nazw kolumn i wartości
922                 jakie mają zostać w nich zapisane.
923             </para>
925             <example id="zend.db.adapter.write.insert.example">
926                 <title>Dodawanie danych do tabeli</title>
927                 <programlisting language="php"><![CDATA[
928 $data = array(
929     'created_on'      => '2007-03-22',
930     'bug_description' => 'Something wrong',
931     'bug_status'      => 'NEW'
934 $db->insert('bugs', $data);
935 ]]></programlisting>
936             </example>
938             <para>
939                 Kolumny, które nie zostały podane w tablicy z danymi nie będą umieszczone
940                 w zapytaniu na zasadzie analogicznej do użycia polecenia
941                 <acronym>SQL</acronym> <acronym>INSERT</acronym>:
942                 Jeśli kolumna ma podaną wartość domyślną (<acronym>DEFAULT</acronym>)
943                 to ta wartość zostanie zapisana w nowym wierszu.
944                 W przeciwnym przypadku kolumna nie będzie miała żadnej 
945                 wartości (<constant>NULL</constant>).
946             </para>
948             <para>
949                 Domyślnym sposobem zapisu danych jest użycie parametrów wiązanych.
950                 Dzięki temu ryzyko wystąpienia niektórych form zagrożenia
951                 bezpieczeństwa aplikacji jest ograniczone.
952                 W tablicy z danymi nie trzeba używać unikania
953                 lub umieszczania wartości w cudzysłowiu.
954             </para>
956             <para>
957                 Może wystąpić potrzeba potraktowania wartości w tablicy danych jako wyrażeń
958                 <acronym>SQL</acronym>. W takim wypadku nie powinno się stosować
959                 umieszczania w cudzysłowiu.
960                 Domyślnie wszystkie podane wartości string są traktowane jak literały.
961                 Aby upewnić się, że
962                 wartość jest wyrażeniem <acronym>SQL</acronym> i nie powinna zostać umieszczona w 
963                 cudzysłowie, należy ją podać jako obiekt klasy
964                 <classname>Zend_Db_Expr</classname> zamiast
965                 prostego łańcucha znaków.
966             </para>
968             <example id="zend.db.adapter.write.insert.example2">
969                 <title>Umieszczanie wyrażeń w tabeli</title>
970                 <programlisting language="php"><![CDATA[
971 $data = array(
972     'created_on'      => new Zend_Db_Expr('CURDATE()'),
973     'bug_description' => 'Something wrong',
974     'bug_status'      => 'NEW'
977 $db->insert('bugs', $data);
978 ]]></programlisting>
979             </example>
981         </sect3>
983         <sect3 id="zend.db.adapter.write.lastinsertid">
985             <title>Pobranie wygenerowanej wartości</title>
987             <para>
988                 Niektóre systemy zarządzania bazą danych wspierają klucze pierwotne o automatycznie 
989                 zwiększanych wartościach. Tabela zdefiniowana w ten sposób generuje wartość klucza
990                 pierwotnego automatycznie przy każdym poleceniu <acronym>INSERT</acronym>.
991                 Wartością zwracaną przez metodę
992                 <methodname>insert()</methodname> <emphasis>nie</emphasis> jest
993                 ostatni zapisany identyfikator, ponieważ tabela mogła nie posiadać automatycznie 
994                 inkrementowanej kolumny.
995                 Zamiast tego wartością zwrotną jest ilość zapisanych wierszy (przeważnie 1). 
996             </para>
998             <para>
999                 Jeśli tabela jest zdefiniowana za pomocą automatycznego klucza pierwotnego to można
1000                 użyć metody <methodname>lastInsertId()</methodname>.
1001                 Po udanym dodaniu wiersza metoda
1002                 ta zwraca ostatnią wartość klucza wygenerowaną w ramach bieżącego połączenia.
1003             </para>
1005             <example id="zend.db.adapter.write.lastinsertid.example-1">
1006                 <title>Użycie lastInsertId() dla automatycznego klucza pierwotnego</title>
1007                 <programlisting language="php"><![CDATA[
1008 $db->insert('bugs', $data);
1010 // zwrócenie ostatniej wartości wygenerowanej przez automatyczną kolumnę
1011 $id = $db->lastInsertId();
1012 ]]></programlisting>
1013             </example>
1015             <para>
1016                 Niektóre systemy zarządzania bazą danych wspierają obiekt sekwencji, który służy
1017                 do generowania unikalnych wartości, które mogą posłużyć jako klucz pierwotny.
1018                 Aby obsługiwać również sekwencje metoda <methodname>lastInsertId()</methodname>
1019                 akceptuje dodatkowe dwa argumenty. Pierwszym z nich jest nazwa tabeli zaś 
1020                 drugim - nazwa kolumny. Założona jest konwencja według której sekwencja ma nazwę
1021                 składającą się z nazwy tabeli oraz kolumny do której generuje wartości z dodatkowym
1022                 sufiksem "_seq". Podstawą tego założenia są domyślne ustawienia PostgreSQL.
1023                 Przykładowo tabela "bugs" z kluczem pierwotnym w kolumnie "bug_id"
1024                 będzie używała sekwencji o nazwie "bugs_bug_id_seq".
1025             </para>
1027             <example id="zend.db.adapter.write.lastinsertid.example-2">
1028                 <title>Użycie lastInsertId() dla sekwencji</title>
1029                 <programlisting language="php"><![CDATA[
1030 $db->insert('bugs', $data);
1032 // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_bug_id_seq'
1033 $id = $db->lastInsertId('bugs', 'bug_id');
1035 // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_seq'
1036 $id = $db->lastInsertId('bugs');
1037 ]]></programlisting>
1038             </example>
1040             <para>
1041                 Jeśli nazwa obiektu sekwencji nie podąża za tą konwencją można użyć metody
1042                 <methodname>lastSequenceId()</methodname>, która przyjmuje pojedynczy łańcuch
1043                 znaków - nazwę sekwencji - jako argument.
1044             </para>
1046             <example id="zend.db.adapter.write.lastinsertid.example-3">
1047                 <title>Użycie lastSequenceId()</title>
1048                 <programlisting language="php"><![CDATA[
1049 $db->insert('bugs', $data);
1051 // zwrócenie ostatniej wartości wygenerowanej przez sekwencję 'bugs_id_gen'
1052 $id = $db->lastSequenceId('bugs_id_gen');
1053 ]]></programlisting>
1054             </example>
1056             <para>
1057                 Dla systemów zarządzania bazą danych które nie wspierają sekwencji, włączając MySQL,
1058                 Microsoft <acronym>SQL</acronym> Server, oraz SQLite dodatkowe argumenty podane do
1059                 metody <methodname>lastInsertId()</methodname> są ignorowane a zwrócona jest
1060                 ostatnia wartość wygenerowana dla dowolnej tabeli poprzez polecenie
1061                 <acronym>INSERT</acronym>
1062                 podczas bieżącego połączenia. Dla tych <acronym>RDBMS</acronym> metoda 
1063                 <methodname>lastSequenceId()</methodname> zawsze zwraca <constant>NULL</constant>.
1064             </para>
1066             <note>
1067                 <title>Dlaczego nie należy używać "SELECT MAX(id) FROM table"?</title>
1068                 <para>
1069                     Powyższe zapytanie często zwraca ostatni klucz pierwotny, jaki został zapisany
1070                     w wierszu tabeli. Ten sposób nie jest jednak bezpieczny w przypadku, gdy
1071                     wiele klientów zapisuje rekordy do bazy danych. Jest możliwe, że w momencie 
1072                     pomiędzy zapisaniem jednego rekordu a zapytaniem o 
1073                     <methodname>MAX(id)</methodname>, do tabeli zostanie zapisany kolejny rekord, 
1074                     wprowadzony przez innego użytkownika. Przez to zwrócona wartość nie będzie 
1075                     identyfikowała pierwszego wprowadzonego wiersza tylko drugi - wprowadzony przez
1076                     inne połączenie. Nie ma pewnego sposobu na wykrycie, że do takiego zdarzenia
1077                     doszło.
1078                 </para>
1079                 <para>
1080                     Zastosowanie mocnej izolacji transakcji, tak jak przy trybie
1081                     "repeatable read" może pomóc w ograniczeniu ryzyka wystąpienia takiej
1082                     sytuacji ale niektóre systemy zarządzania bazą danych nie wspierają
1083                     izolacji transakcji w wystarczającym stopniu lub aplikacja może
1084                     intencjonalnie korzystać jedynie z niskiego trybu izolacji transakcji.
1085                 </para>
1087                 <para>
1088                     Dodatkowo, używanie wyrażeń takich jak "MAX(id)+1" do generowania
1089                     nowych wartości klucza głównego nie jest bezpieczne bo
1090                     dwa połączenia mogą wykonać to zapytanie 
1091                     praktycznie jednocześnie i w rezultacie próbować użyć jednakowej wartości 
1092                     dla kolejnego polecenia <acronym>INSERT</acronym>.
1093                 </para>
1095                 <para>
1096                     Wszystkie systemy zarządzania bazą danych udostępniają
1097                     mechanizmy służące generowaniu
1098                     unikalnych wartości oraz zwracaniu ostatniej z nich.
1099                     Mechanizmy te intencjonalnie działają poza zasięgiem izolacji
1100                     transakcji więc nie jest możliwe aby wartość wygenerowana dla jednego
1101                     klienta pojawiła się jako ostatnia wygenerowana dla innego połączenia.
1102                 </para>
1103             </note>
1105         </sect3>
1107         <sect3 id="zend.db.adapter.write.update">
1108             <title>Aktualizacja danych</title>
1110             <para>
1111                 Aktualizacji wierszy tabeli w bazie danych można dokonać poprzez metodę adaptera
1112                 <methodname>update()</methodname> . Metoda przyjmuje trzy argumenty: pierwszym 
1113                 jest nazwa tabeli; drugim - tablica asocjacyjna mapująca kolumny, które mają ulec
1114                 zmianie oraz wartości jakie kolumny przybiorą; trzecim - warunek
1115                 wyznaczający wiersze do zmiany.
1116             </para>
1118             <para>
1119                 Wartości w tablicy z danymi są traktowane jak literały znakowe. Należy zapoznać
1120                 się z akapitem <xref linkend="zend.db.adapter.write.insert" /> aby uzyskać więcej
1121                 informacji na temat użyci w niej wyrażeń <acronym>SQL</acronym>. 
1122             </para>
1124             <para>
1125                 Trzecim argumentem metody jest string zawierający wyrażenie <acronym>SQL</acronym>
1126                 będące kryterium wyznaczającym wiersze do zmiany. Wartości i identyfikatory w tym
1127                 argumencie nie są umieszczane w cudzysłowie ani unikane. Należy, więc, zadbać o to
1128                 samemu. Należy zapoznać się z akapitem <xref linkend="zend.db.adapter.quoting" />
1129                 aby zasięgnąć dodatkowych informacji.
1130             </para>
1132             <para>
1133                 Wartością zwracaną jest ilość wierszy zmienionych przez operację aktualizacji.
1134             </para>
1136             <example id="zend.db.adapter.write.update.example">
1137                 <title>Aktualizacja wierszy</title>
1138                 <programlisting language="php"><![CDATA[
1139 $data = array(
1140     'updated_on'      => '2007-03-23',
1141     'bug_status'      => 'FIXED'
1144 $n = $db->update('bugs', $data, 'bug_id = 2');
1145 ]]></programlisting>
1146             </example>
1148             <para>
1149                 Jeśli trzeci argument nie zostanie podany to wszystkie wiersze w tabeli
1150                 zostaną zaktualizowane zgodnie z kolumnami i wartościami podanymi w 
1151                 drugim argumencie.
1152             </para>
1154             <para>
1155                 Jeśli trzeci argument zostanie podany jako tablica łańcuchów znakowych to
1156                 w zapytaniu łańcuchy zostaną połączone za pomocą operatorów 
1157                 <constant>AND</constant>.
1158             </para>
1160             <para>
1161                 Przy podaniu trzeciego argumentu jako tablicy tablic, ich wartości
1162                 zostaną automatycznie
1163                 otoczone cudzysłowami i umieszczone w kluczach tych tablic. Po czym zostaną
1164                 połączone za pomocą operatorów <constant>AND</constant>.
1165             </para>
1167             <example id="zend.db.adapter.write.update.example-array">
1168                 <title>Aktualizacja wierszy tablicy za pomocą tablicy wyrażeń</title>
1169                 <programlisting language="php"><![CDATA[
1170 $data = array(
1171     'updated_on'      => '2007-03-23',
1172     'bug_status'      => 'FIXED'
1175 $where[] = "reported_by = 'goofy'";
1176 $where[] = "bug_status = 'OPEN'";
1178 $n = $db->update('bugs', $data, $where);
1180 // Powstałe wyrażenie SQL to:
1181 //  UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
1182 //  WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
1183 ]]></programlisting>
1184             </example>
1186             <example id="zend.db.adapter.write.update.example-arrayofarrays">
1187                 <title>Aktualizacja wierszy tablicy za pomocą tablicy tablic</title>
1188                 <programlisting language="php"><![CDATA[
1189 $data = array(
1190     'updated_on'      => '2007-03-23',
1191     'bug_status'      => 'FIXED'
1194 $where['reported_by = ?'] = 'goofy';
1195 $where['bug_status = ?']  = 'OPEN';
1197 $n = $db->update('bugs', $data, $where);
1199 // Powstałe wyrażenie SQL to:
1200 //  UPDATE "bugs" SET "update_on" = '2007-03-23', "bug_status" = 'FIXED'
1201 //  WHERE ("reported_by" = 'goofy') AND ("bug_status" = 'OPEN')
1202 ]]></programlisting>
1203             </example>
1204         </sect3>
1206         <sect3 id="zend.db.adapter.write.delete">
1207             <title>Usuwanie danych</title>
1208             <para>
1209                 Usuwania danych można dokonać używając metody <methodname>delete()</methodname>.
1210                 Przyjmuje ona dwa argumenty: pierwszym z nich jest łańcuch znaków z nazwą tabeli; 
1211                 Drugim - warunek określający wiersze do usunięcia.
1212             </para>
1214             <para>
1215                 Drugi argument to string zawierający wyrażenie <acronym>SQL</acronym> użyte jako
1216                 kryterium wyznaczania usuwanych wierszy. Wartości i identyfikatory nie są
1217                 unikane ani umieszczane w cudzysłowie - należy zatroszczyć się o to samemu. Aby
1218                 dowiedzieć się więcej na ten temat
1219                 można skorzystać z akapitu <xref linkend="zend.db.adapter.quoting" />.
1220             </para>
1222             <para>
1223                 Wartość zwrotna to ilość wierszy, jakie uległy zmianie w wyniku zadziałania
1224                 operacji usuwania.
1225             </para>
1227             <example id="zend.db.adapter.write.delete.example">
1228                 <title>Usuwanie wierszy</title>
1229                 <programlisting language="php"><![CDATA[
1230 $n = $db->delete('bugs', 'bug_id = 3');
1231 ]]></programlisting>
1232             </example>
1234             <para>
1235                 Jeśli drugi argument nie zostanie podany to wszystkie wiersze z tabeli
1236                 ulegną usunięciu.
1237             </para>
1239             <para>
1240                 Jeśli drugi argument zostanie podany jako tablica łańcuchów znaków to
1241                 te łańcuchy ulegną konkatenacji jako wyrażenia logiczne połączone
1242                 operatorem <constant>AND</constant>.
1243             </para>
1245             <para>
1246                 Jeśli trzeci argument będzie tablicą tablic to jej wartości zostaną
1247                 automatycznie otoczone cudzysłowami i umieszczona w kluczach tablic. Potem
1248                 zostaną połączone razem za pomocą operatora <constant>AND</constant>.
1249             </para>
1251         </sect3>
1253     </sect2>
1255     <sect2 id="zend.db.adapter.quoting">
1257         <title>Umieszczanie wartości i identyfikatorów w cudzysłowie</title>
1259         <para>
1260             Podczas tworzenia zapytań <acronym>SQL</acronym> często dochodzi do sytuacji, w której
1261             niezbędne jest umieszczenie wartości zmiennych <acronym>PHP</acronym> w wyrażeniach
1262             <acronym>SQL</acronym>. Stanowi to zagrożenie, ponieważ jeśli wartość
1263             łańcuchowej zmiennej <acronym>PHP</acronym> zawiera określone znaki, takie jak symbol
1264             cudzysłowu, to mogą one spowodować błąd w poleceniu <acronym>SQL</acronym>. Poniżej
1265             znajduje się przykład zapytania zawierającego niespójną liczbę symboli cudzysłowu:
1266             <programlisting language="php"><![CDATA[
1267 $name = "O'Reilly";
1268 $sql = "SELECT * FROM bugs WHERE reported_by = '$name'";
1270 echo $sql;
1271 // SELECT * FROM bugs WHERE reported_by = 'O'Reilly'
1272 ]]></programlisting>
1273         </para>
1275         <para>
1276             
1277             
1278             Zagrożenie potęguje fakt iż podobne błędy mogą zostać wykorzystane przez osobę
1279             próbującą zmanipulować działanie funkcji aplikacji. Jeśli takiej osobie
1280             uda się wpłynąć na wartość zmiennej <acronym>PHP</acronym> poprzez
1281             parametr <acronym>HTTP</acronym>
1282             (bądź inny mechanizm), to będzie mogła zmienić zapytanie <acronym>SQL</acronym>
1283             tak by dokonywało operacji zupełnie niezamierzonych przez twórców, takich jak
1284             zwrócenie danych, do których osoba nie powinna mieć dostępu. To jest poważny i szeroko
1285             rozpowszechniony sposób łamania zabezpieczeń aplikacji znany pod nazwą "SQL Injection"
1286             (wstrzyknięcie SQL - <ulink url="http://en.wikipedia.org/wiki/SQL_Injection">
1287             http://en.wikipedia.org/wiki/SQL_Injection</ulink>).
1288         </para>
1290         <para>
1291             Adaptery klasy <classname>Zend_Db</classname> udostępniają funkcje przydatne
1292             do zredukowania zagrożenia atakiem <acronym>SQL</acronym> Injection w kodzie
1293             <acronym>PHP</acronym>.
1294             Przyjętym rozwiązaniem jest unikanie znaków specjalnych takich jak cudzysłów w 
1295             wartościach zmiennych <acronym>PHP</acronym>
1296             przed umieszczeniem ich w poleceniu <acronym>SQL</acronym>.
1297             Takie podejście zapewnia ochronę przed przypadkową jak i intencjonalną zmianą
1298             znaczenia poleceń <acronym>SQL</acronym> przez
1299             zmienne <acronym>PHP</acronym> zawierające znaki specjalne.
1300         </para>
1302         <sect3 id="zend.db.adapter.quoting.quote">
1304             <title>Użycie quote()</title>
1306             <para>
1307                 Metoda <methodname>quote()</methodname> przyjmuje pojedynczy
1308                 argument - łańcuch znaków.
1309                 Na wyjściu zwraca podany argument ze wszystkimi znakami specjalnymi
1310                 poddanymi uniknięciu w sposób właściwy dla używanego
1311                 <acronym>RDBMS</acronym> i otoczony znakami ograniczającymi
1312                 łańcuchy znakowe. Standardowym znakiem ograniczającym
1313                 stringi w <acronym>SQL</acronym> jest pojedynczy cudzysłów (').
1314             </para>
1316             <example id="zend.db.adapter.quoting.quote.example">
1317                 <title>Użycie quote()</title>
1318                 <programlisting language="php"><![CDATA[
1319 $name = $db->quote("O'Reilly");
1320 echo $name;
1321 // 'O\'Reilly'
1323 $sql = "SELECT * FROM bugs WHERE reported_by = $name";
1325 echo $sql;
1326 // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
1327 ]]></programlisting>
1328             </example>
1330             <para>
1331                 Należy zwrócić uwagę, że wartość zwrotna metody <methodname>quote()</methodname>
1332                 zawiera znaki ograniczające stringi. Jest to zachowanie różne od niektórych funkcji
1333                 które unikają specjalne znaki ale nie ujmują całego łańcucha w znaki ograniczające,
1334                 tak jak <ulink url="http://www.php.net/mysqli_real_escape_string">
1335                 mysql_real_escape_string()</ulink>.
1336             </para>
1338             <para>
1339                 Wartości mogą wymagać umieszczenia w cudzysłowach lub nie, zgodnie z
1340                 kontekstem używanego typu danych <acronym>SQL</acronym>.
1341                 W przypadku niektórych rodzajów systemów zarządzania
1342                 bazą danych liczby całkowite nie mogą być ograniczane cudzysłowami
1343                 jeśli są porównywane z kolumną lub wyrażeniem zwracającym inną liczbę całkowitą.
1344                 Innymi słowy, poniższy zapis może wywołać błąd w niektórych
1345                 implementacjach <acronym>SQL</acronym> zakładając, że
1346                 <property>intColumn</property> jest określona
1347                 typem danych <constant>INTEGER</constant>.
1349                 <programlisting language="php"><![CDATA[
1350 SELECT * FROM atable WHERE intColumn = '123'
1351 ]]></programlisting>
1352             </para>
1354             <para>
1355                 Można użyć opcjonalnego, drugiego argumentu metody <methodname>quote()</methodname>
1356                 aby określić typ danych <acronym>SQL</acronym> i ograniczyć stosowanie cudzysłowu.
1357             </para>
1359             <example id="zend.db.adapter.quoting.quote.example-2">
1360                 <title>Użycie quote() z podanym typem danych SQL</title>
1362                 <programlisting language="php"><![CDATA[
1363 $value = '1234';
1364 $sql = 'SELECT * FROM atable WHERE intColumn = '
1365      . $db->quote($value, 'INTEGER');
1366 ]]></programlisting>
1367             </example>
1369             <para>
1370                 Każda klasa <classname>Zend_Db_Adapter</classname> ma zapisane nazwy numerycznych
1371                 typów danych <acronym>SQL</acronym> odpowiednio do swojego rodzaju
1372                 <acronym>RDBMS</acronym>.
1373                 Zamiast tego można w tym miejscu również korzystać ze stałych  
1374                 <constant>Zend_Db::INT_TYPE</constant>,
1375                 <constant>Zend_Db::BIGINT_TYPE</constant> oraz
1376                 <constant>Zend_Db::FLOAT_TYPE</constant> aby uniezależnić kod
1377                 od rodzaju bazy danych.
1378             </para>
1380             <para>
1381                 <classname>Zend_Db_Table</classname> automatycznie określa
1382                 typy danych <acronym>SQL</acronym>
1383                 dla metody <methodname>quote()</methodname> podczas generowania
1384                 zapytań <acronym>SQL</acronym> odnoszących się do klucza pierwotnego tabeli.
1385             </para>
1387         </sect3>
1389         <sect3 id="zend.db.adapter.quoting.quote-into">
1391             <title>Użycie quoteInto()</title>
1393             <para>
1394                 Najbardziej typowym przypadkiem użycia cudzysłowu do ograniczania zmiennych jest
1395                 umieszczenie zmiennej <acronym>PHP</acronym> w zapytaniu <acronym>SQL</acronym>.
1396                 Aby to osiągnąć można użyć metody <methodname>quoteInto()</methodname>.
1397                 Przyjmuje ona dwa argumenty: pierwszym jest łańcuch znaków zawierający
1398                 symbol "?", który zostanie zastąpiony; drugim jest zmienna
1399                 <acronym>PHP</acronym>, która ma trafić na miejsce "?".
1400             </para>
1402             <para>
1403                 Zastępowany symbol jest używany przez wielu producentów baz danych do oznaczenia
1404                 pozycyjnych parametrów wiązanych ale metoda <methodname>quoteInto()</methodname>
1405                 jedynie emuluje takie parametry. W wyniku jej działania wartość zmiennej jest
1406                 zwyczajnie umieszczana w łańcuchu z zapytaniem, po wstępnym uniknięciu specjalnych
1407                 znaków i umieszczeniu w cudzysłowie. Prawdziwa implementacja parametrów wiązanych
1408                 zakłada separację łańcucha znaków polecenia <acronym>SQL</acronym> od samych
1409                 parametrów oraz wstępne parsowanie polecenia na serwerze bazy danych.
1410             </para>
1412             <example id="zend.db.adapter.quoting.quote-into.example">
1413                 <title>Użycie quoteInto()</title>
1414                 <programlisting language="php"><![CDATA[
1415 $sql = $db->quoteInto("SELECT * FROM bugs WHERE reported_by = ?", "O'Reilly");
1417 echo $sql;
1418 // SELECT * FROM bugs WHERE reported_by = 'O\'Reilly'
1419 ]]></programlisting>
1420             </example>
1422             <para>
1423                 Można użyć opcjonalnego, trzeciego parametru metody
1424                 <methodname>quoteInto()</methodname>
1425                 aby określić typ danych <acronym>SQL</acronym>.
1426                 Numeryczne typy danych (w przeciwieństwie
1427                 do innych typów) nie podlegają umieszczaniu w cudzysłowie.
1428             </para>
1430             <example id="zend.db.adapter.quoting.quote-into.example-2">
1431                 <title>Użycie quoteInto() z podaniem typu danych SQL</title>
1432                 <programlisting language="php"><![CDATA[
1433 $sql = $db
1434     ->quoteInto("SELECT * FROM bugs WHERE bug_id = ?", '1234', 'INTEGER');
1436 echo $sql;
1437 // SELECT * FROM bugs WHERE reported_by = 1234
1438 ]]></programlisting>
1439             </example>
1441         </sect3>
1442         <sect3 id="zend.db.adapter.quoting.quote-identifier">
1444             <title>Użycie quoteIdentifier()</title>
1446             <para>
1447                 Wartości nie są jedyną częścią składni polecenia <acronym>SQL</acronym>, która może
1448                 być zmienna. W przypadku użycia zmiennych <acronym>PHP</acronym> do określenia
1449                 tabel, kolumn lub innych identyfikatorów zapytania <acronym>SQL</acronym>,
1450                 może zajść potrzeba umieszczenia również tych elementów w cudzysłowie.
1451                 Domyślnie identyfikatory <acronym>SQL</acronym> muszą przestrzegać określonych
1452                 reguł - podobnie jak w <acronym>PHP</acronym> oraz większości innych
1453                 języków programowania. Przykładem takiej reguły jest zakaz używania spacji
1454                 lub określonych znaków interpunkcyjnych, specjalnych ani też znaków spoza ASCII.
1455                 Poza tym istnieje lista określonych słów, które służą
1456                 do tworzenia zapytań - ich też nie powinno się używać jako identyfikatorów.
1457             </para>
1459             <para>
1460                 Mimo to <acronym>SQL</acronym> posiada
1461                 <emphasis>ograniczone identyfikatory</emphasis> (delimited identifiers),
1462                 dzięki którym można skorzystać z większego wachlarza znaków
1463                 do nazywania obiektów.
1464                 Jeśli określony identyfikator zostanie ograniczony odpowiednim
1465                 rodzajem cudzysłowu to będzie można użyć znaków, które bez tego ograniczenia 
1466                 spowodowałyby błąd. Identyfikatory ograniczone mogą zawierać spacje,
1467                 znaki interpunkcyjne czy lokalne litery.
1468                 Można nawet używać zarezerwowanych słów <acronym>SQL</acronym> jeśli
1469                 zostaną otoczone odpowiednimi znakami ograniczającymi.
1470             </para>
1472             <para>
1473                 Metoda <methodname>quoteIdentifier()</methodname> zachowuje się podobnie jak
1474                 <methodname>quote()</methodname> ale otacza podany łańcuch znaków za pomocą
1475                 znaków ograniczających zgodnie z rodzajem używanego adaptera.
1476                 Standardowy <acronym>SQL</acronym>
1477                 używa podwójnego cudzysłowu (") jako znaku ograniczającego a większość systemów
1478                 zarządzania bazą danych podąża za tym przykładem. MySQL domyślnie używa znaków 
1479                 back-tick (`). Metoda <methodname>quoteIdentifier()</methodname> dokonuje również
1480                 unikania znaków specjalnych znajdujących się w przekazanym argumencie.
1481             </para>
1483             <example id="zend.db.adapter.quoting.quote-identifier.example">
1484                 <title>Użycie quoteIdentifier()</title>
1485                 <programlisting language="php"><![CDATA[
1486 // można użyć tabeli o nazwie takiej samej jak słowo zarezerwowane SQL
1487 $tableName = $db->quoteIdentifier("order");
1489 $sql = "SELECT * FROM $tableName";
1491 echo $sql
1492 // SELECT * FROM "order"
1493 ]]></programlisting>
1494             </example>
1496             <para>
1497                 W <acronym>SQL</acronym> identyfikatory ograniczone są wrażliwe na wielkość liter,
1498                 w przeciwieństwie do zwykłych identyfikatorów. Przez to, należy upewnić się, że
1499                 pisownia identyfikatora w 100% odpowiada pisowni zapisanej w schemacie, włącznie
1500                 z wielkością liter.
1501             </para>
1503             <para>
1504                 W większości przypadków gdzie polecenie <acronym>SQL</acronym> jest
1505                 generowane wewnątrz klas <classname>Zend_Db</classname>,
1506                 domyślnym zachowaniem jest automatyczne ograniczanie 
1507                 identyfikatorów. Można to zmienić poprzez opcję
1508                 <constant>Zend_Db::AUTO_QUOTE_IDENTIFIERS</constant> wywoływaną
1509                 podczas inicjalizacji adaptera.
1510                 Więcej informacji:
1511                 <xref linkend="zend.db.adapter.connecting.parameters.example2" />.
1512             </para>
1514         </sect3>
1516     </sect2>
1518     <sect2 id="zend.db.adapter.transactions">
1520         <title>Kontrolowanie transakcji bazy danych</title>
1522         <para>
1523             W świecie baz danych transakcja to zbiór operacji, który może zostać zapisany
1524             bądź cofnięty za pomocą jednej instrukcji, nawet jeśli zmiany wynikające z tych operacji
1525             dotyczyły wielu tabel. Wszystkie zapytania do bazy danych są przeprowadzane w 
1526             kontekście transakcji. Jeśli nie są zarządzane jawnie to sterownik bazy danych używa ich
1527             w sposób przezroczysty dla użytkownika. Takie podejście nazywa się trybem 
1528             <emphasis>auto-commit</emphasis> - sterownik bazy danych tworzy transakcje dla każdego
1529             tworzonego polecenia i zapisuje efekty jego działania po każdym wywołaniu polecenia 
1530             <acronym>SQL</acronym>. Domyślnie wszystkie adaptery <classname>Zend_Db</classname>
1531             działają w trybie <emphasis>auto-commit</emphasis>.
1532         </para>
1534         <para>
1535             Można również bezpośrednio wskazać początek i koniec transakcji i w ten sposób 
1536             kontrolować ilość zapytań <acronym>SQL</acronym> jakie trafiają do zapisania (bądź 
1537             cofnięcia) jako pojedyncza operacja. Aby rozpocząć transakcję należy wywołać metodę
1538             <methodname>beginTransaction()</methodname>. Następujące po niej polecenia
1539             <acronym>SQL</acronym> są wykonywane w kontekście wspólnej transakcji do momentu
1540             zasygnalizowania jej końca.
1541         </para>
1543         <para>
1544             Aby zakończyć transakcję należy użyć metody <methodname>commit()</methodname> lub
1545             <methodname>rollBack()</methodname>.
1546             Pierwsza z nich powoduje zapisanie zmian wynikających
1547             z operacji przeprowadzonych w czasie transakcji.
1548             Oznacza to, że efekty tych zmian będą
1549             widoczne w wynikach zapytań wywołanych w ramach innych transakcji.
1550         </para>
1552         <para>
1553             Metoda <methodname>rollBack()</methodname> dokonuje odwrotnej operacji: cofa zmiany
1554             dokonane podczas transakcji.
1555             W efekcie wszystkie dane zmienione podczas transakcji zostają cofnięte do
1556             wartości z momentu przed jej rozpoczęciem. Cofnięcie zmian jednej transakcji nie
1557             ma wpływu na zmiany dokonane przez inną transakcję trwającą nawet w tym samym czasie.
1558         </para>
1560         <para>
1561             Po skończonej transakcji <classname>Zend_Db_Adapter</classname> wraca
1562             do trybu auto-commit do momentu ponownego wywołania metody
1563             <methodname>beginTransaction()</methodname> i ręcznego
1564             rozpoczęcia nowej transakcji.
1565         </para>
1567         <example id="zend.db.adapter.transactions.example">
1568             <title>Kontrolowanie transakcjami dla zachowania spójności</title>
1569             <programlisting language="php"><![CDATA[
1570 // Ręczne rozpoczęcie transakcji
1571 $db->beginTransaction();
1573 try {
1574     // Próba wywołania jednego bądź wielu zapytań:
1575     $db->query(...);
1576     $db->query(...);
1577     $db->query(...);
1579     // Jeśli wszystkie odniosły sukces - zapisanie transakcji, dzięki czemu wszystkie rezultaty
1580     // zostaną zapisane za jednym razem.
1581     $db->commit();
1583 } catch (Exception $e) {
1584     // Jeśli któreś z zapytań zakończyło się niepowodzeniem i został wyrzucony wyjątek, należy
1585     // cofnąć całą transakcję odwracając zmiany w niej dokonane (nawet te które zakończyły się
1586     // sukcesem). Przez to albo wszystkie zmiany zostają zapisane albo żadna.
1587     $db->rollBack();
1588     echo $e->getMessage();
1590 ]]></programlisting>
1591         </example>
1593     </sect2>
1595     <sect2 id="zend.db.adapter.list-describe">
1597         <title>Uzyskiwanie listy i opisu tabel</title>
1599         <para>
1600             Metoda <methodname>listTables()</methodname> zwraca tablicę łańcuchów znakowych,
1601             zawierającą wszystkie tabele w bieżącej bazie danych.
1602         </para>
1604         <para>
1605             Metoda <methodname>describeTable()</methodname> zwraca tablicę asocjacyjną metadanych
1606             tabeli. Jako argument należy podać nazwę tabeli.
1607             Drugi argument jest opcjonalny - wskazuje
1608             nazwę schematu w którym tabela się znajduje.
1609         </para>
1611         <para>
1612             Kluczami zwracanej tablicy asocjacyjnej są nazwy kolumn tabeli. Wartość przy każdej 
1613             kolumnie to następna tablica asocjacyjna z następującymi kluczami i wartościami:
1614         </para>
1616         <table frame="all" cellpadding="5" id="zend.db.adapter.list-describe.metadata">
1617             <title>Metadane zwracane przez describeTable()</title>
1618             <tgroup cols="3" align="left" colsep="1" rowsep="1">
1619                 <thead>
1620                     <row>
1621                         <entry>Klucz</entry>
1622                         <entry>Typ</entry>
1623                         <entry>Opis</entry>
1624                     </row>
1625                 </thead>
1626                 <tbody>
1627                     <row>
1628                         <entry><constant>SCHEMA_NAME</constant></entry>
1629                         <entry>(string)</entry>
1630                         <entry>Nazwa schematu bazy danych, w którym tabela się znajduje.</entry>
1631                     </row>
1632                     <row>
1633                         <entry><constant>TABLE_NAME</constant></entry>
1634                         <entry>(string)</entry>
1635                         <entry>Nazwa tabeli zawierającej daną kolumnę.</entry>
1636                     </row>
1637                     <row>
1638                         <entry><constant>COLUMN_NAME</constant></entry>
1639                         <entry>(string)</entry>
1640                         <entry>Nazwa kolumny.</entry>
1641                     </row>
1642                     <row>
1643                         <entry><constant>COLUMN_POSITION</constant></entry>
1644                         <entry>(integer)</entry>
1645                         <entry>Liczba porządkowa wskazująca na miejsce kolumny w tabeli.</entry>
1646                     </row>
1647                     <row>
1648                         <entry><constant>DATA_TYPE</constant></entry>
1649                         <entry>(string)</entry>
1650                         <entry>Nazwa typu danych dozwolonych w kolumnie.</entry>
1651                     </row>
1652                     <row>
1653                         <entry><constant>DEFAULT</constant></entry>
1654                         <entry>(string)</entry>
1655                         <entry>Domyślna wartość kolumny (jeśli istnieje).</entry>
1656                     </row>
1657                     <row>
1658                         <entry><constant>NULLABLE</constant></entry>
1659                         <entry>(boolean)</entry>
1660                         <entry>
1661                             <constant>TRUE</constant> jeśli columna dopuszcza wartości
1662                             <acronym>SQL</acronym>
1663                             <constant>NULL</constant>, <constant>FALSE</constant>
1664                             jeśli kolumna zawiera 
1665                             ograniczenie <constant>NOT</constant> <constant>NULL</constant>.
1666                         </entry>
1667                     </row>
1668                     <row>
1669                         <entry><constant>LENGTH</constant></entry>
1670                         <entry>(integer)</entry>
1671                         <entry>
1672                             Dopuszczalny rozmiar kolumny, w formie zgłoszonej przez serwer
1673                             bazy danych.
1674                         </entry>
1675                     </row>
1676                     <row>
1677                         <entry><constant>SCALE</constant></entry>
1678                         <entry>(integer)</entry>
1679                         <entry>
1680                             Skala typów <acronym>SQL</acronym> NUMERIC lub
1681                             <constant>DECIMAL</constant>.
1682                         </entry>
1683                     </row>
1684                     <row>
1685                         <entry><constant>PRECISION</constant></entry>
1686                         <entry>(integer)</entry>
1687                         <entry>
1688                             Precyzja typów <acronym>SQL</acronym> NUMERIC
1689                             lub <constant>DECIMAL</constant>.
1690                         </entry>
1691                     </row>
1692                     <row>
1693                         <entry><constant>UNSIGNED</constant></entry>
1694                         <entry>(boolean)</entry>
1696                         <entry>
1697                             <constant>TRUE</constant> jeśli typ danych liczbowych ma klauzulę
1698                             <constant>UNSIGNED</constant>.
1699                         </entry>
1700                     </row>
1701                     <row>
1702                         <entry><constant>PRIMARY</constant></entry>
1703                         <entry>(boolean)</entry>
1705                         <entry>
1706                             <constant>TRUE</constant> jeśli kolumna jest częścią
1707                             klucza pierwotnego tabeli.
1708                         </entry>
1709                     </row>
1710                     <row>
1711                         <entry><constant>PRIMARY_POSITION</constant></entry>
1712                         <entry>(integer)</entry>
1713                         <entry>
1714                             Liczba porządkowa (min. 1) oznaczająca pozycję
1715                             kolumny w kluczu pierwotnym.
1716                         </entry>
1717                     </row>
1718                     <row>
1719                         <entry><constant>IDENTITY</constant></entry>
1720                         <entry>(boolean)</entry>
1722                         <entry>
1723                             <constant>TRUE</constant> jeśli kolumna korzysta
1724                             z wartości automatycznie generowanych.
1725                         </entry>
1726                     </row>
1727                 </tbody>
1728             </tgroup>
1729         </table>
1731         <note>
1732             <title>Pole metadanych IDENTITY w różnych systemach zarządzania bazą danych</title>
1733             <para>
1734                 Pole metadanych IDENTITY zostało wybrane jako ogólny
1735                 termin określający relację do klucza tabeli. Może być znany
1736                 pod następującymi nazwami:
1737             </para>
1738             <itemizedlist>
1739                 <listitem>
1740                     <para>
1741                         <constant>IDENTITY</constant> - DB2, MSSQL
1742                     </para>
1743                 </listitem>
1744                 <listitem>
1745                     <para>
1746                         <constant>AUTO_INCREMENT</constant> - MySQL
1747                     </para>
1748                 </listitem>
1749                 <listitem>
1750                     <para>
1751                         <constant>SERIAL</constant> - PostgreSQL
1752                     </para>
1753                 </listitem>
1754                 <listitem>
1755                     <para>
1756                         <constant>SEQUENCE</constant> - Oracle
1757                     </para>
1758                 </listitem>
1759             </itemizedlist>
1760         </note>
1762         <para>
1763             Jeśli w bazie danych nie istnieje tabela i schemat o podanych nazwach to
1764             <methodname>describeTable()</methodname> zwraca pustą tablicę. 
1765         </para>
1767     </sect2>
1769     <sect2 id="zend.db.adapter.closing">
1771         <title>Zamykanie połączenia</title>
1773         <para>
1774             Najczęściej nie ma potrzeby zamykać połączenia z bazą danych. <acronym>PHP</acronym>
1775             automatycznie czyści wszystkie zasoby pod koniec działania. Rozszerzenia bazy danych są
1776             zaprojektowane w taki sposób aby połączenie zostało zamknięte w momencie usunięcia 
1777             referencji do obiektu zasobu.
1778         </para>
1780         <para>
1781             Jednak w przypadku skryptu <acronym>PHP</acronym>, którego czas wykonania jest znaczący, 
1782             który inicjuje wiele połączeń z bazą danych, może zajść potrzeba
1783             ręcznego zamknięcia połączenia aby ograniczyć wykorzystanie
1784             zasobów serwera bazy danych. Aby wymusić zamknięcie połączenia
1785             z bazą danych należy użyć metody adaptera <methodname>closeConnection()</methodname>.
1786         </para>
1788         <para>
1789             Od wersji 1.7.2 istnieje możliwość sprawdzenia czy w obecnej chwili
1790             połączenie z serwerem bazy danych występuje za pomocą metody
1791             <methodname>isConnected()</methodname>.
1792             Jej rezultat oznacza czy zasób połączenia został ustanowiony i nie został zamknięty.
1793             Ta metoda nie jest zdolna sprawdzić zamknięcia połączenia od strony
1794             serwera bazy danych.
1795             Dzięki użyciu jej w wewnętrznych metodach zamykających połączenie
1796             można dokonywać wielokrotnego zamknięcia połączenia bez ryzyka wystąpienia błędów.
1797             Przed wersją 1.7.2 było to możliwe jedynie w
1798             przypadku adapterów <acronym>PDO</acronym>.
1799         </para>
1801         <example id="zend.db.adapter.closing.example">
1802             <title>Zamknięcie połączenia z bazą danych</title>
1803             <programlisting language="php"><![CDATA[
1804 $db->closeConnection();
1805 ]]></programlisting>
1806         </example>
1808         <note>
1809             <title>Czy Zend_Db wspiera połączenia trwałe (Persistent Connections)?</title>
1810             <para>
1811                 Tak, trwałe połączenia są wspierane poprzez flagę <property>persistent</property>
1812                 ustawioną na wartość <constant>TRUE</constant> w konfiguracji
1813                 adaptera <classname>Zend_Db</classname> (a nie sterownika bazy danych).
1814             </para>
1816             <example id="zend.db.adapter.connecting.persistence.example">
1817                 <title>Użycie flagi stałego połączenia z adapterem Oracle</title>
1818                 <programlisting language="php"><![CDATA[
1819 $db = Zend_Db::factory('Oracle', array(
1820     'host'       => '127.0.0.1',
1821     'username'   => 'webuser',
1822     'password'   => 'xxxxxxxx',
1823     'dbname'     => 'test',
1824     'persistent' => true
1826 ]]></programlisting>
1827             </example>
1829             <para>
1830                 Należy zwrócić uwagę, że używanie połączeń stałych może zwiększyć ilość
1831                 nieużywanych połączeń na serwerze bazy danych. Przez to, korzyści
1832                 w wydajności (wynikające z wykluczenia potrzeby nawiązywania połączenia
1833                 przy każdym żądaniu) mogą zostać skutecznie przeważone przez problemy
1834                 spowodowane przez tą technikę.
1835             </para>
1836             <para>
1837                 Połączenia z bazą danych mają stany. Oznacza to, że pewne obiekty na serwerze
1838                 bazy danych istnieją w kontekście sesji. Chodzi o blokady, zmienne użytkownika,
1839                 tabele tymczasowe, informacje o ostatnio wykonanym zapytaniu - takie jak
1840                 ilość pobranych wierszy, ostatnia wygenerowana wartość identyfikatora. W 
1841                 przypadku użycia połączeń stałych istnieje ryzyko, że aplikacja uzyska
1842                 dostęp do niepoprawnych bądź zastrzeżonych danych, które zostały utworzone
1843                 podczas poprzedniego żądania.
1844             </para>
1845             <para>
1846                 W obecnym stanie jedynie adaptery Oracle, DB2 oraz <acronym>PDO</acronym> 
1847                 (zgodnie z dokumentacją <acronym>PHP</acronym>) wspierają połączenia stałe
1848                 w <classname>Zend_Db</classname>.
1849             </para>
1850         </note>
1852     </sect2>
1854     <sect2 id="zend.db.adapter.other-statements">
1856         <title>Wykonywanie innych poleceń na bazie danych</title>
1858         <para>
1859             Podczas tworzenia kodu może zajść potrzeba uzyskania dostępu bezpośrednio do 
1860             obiektu połączenia tak jak udostępnia to używane rozszerzenie bazy danych 
1861             <acronym>PHP</acronym>. Niektóre rozszerzenia mogą oferować funkcje nieodzwierciedlone
1862             w metodach klasy <classname>Zend_Db_Adapter_Abstract</classname>.
1863         </para>
1865         <para>
1866             Wszystkie polecenia <acronym>SQL</acronym> w <classname>Zend_Db</classname>
1867             są wywoływane poprzez instrukcje preparowane (prepared statement). Jednak niektóre
1868             funkcje bazy danych są z nimi niekompatybilne. Polecenia <acronym>DDL</acronym> takie 
1869             jak CREATE czy ALTER nie mogą być wywoływane w ten sposób w MySQL. Dodatkowo polecenia
1870             <acronym>SQL</acronym> nie korzystają z 
1871             <ulink url="http://dev.mysql.com/doc/refman/5.1/en/query-cache-how.html">cache'u zapytań
1872             MySQL (MySQL Query Cache)</ulink> dla wersji wcześniejszej niż MySQL 5.1.17.
1873         </para>
1875         <para>
1876             Większość rozszerzeń baz danych <acronym>PHP</acronym> umożliwia wywoływanie poleceń
1877             <acronym>SQL</acronym> bez preparowania. W przypadku <acronym>PDO</acronym> jest to
1878             możliwe poprzez metodę <methodname>exec()</methodname>. Aby uzyskać dostęp do obiektu
1879             połączenia odpowiedniego rozszerzenia <acronym>PHP</acronym> należy wywołać metodę
1880             <methodname>getConnection()</methodname>.
1881         </para>
1883         <example id="zend.db.adapter.other-statements.example">
1884             <title>Wywołanie polecenia niepreparowanego dla adaptera PDO</title>
1885             <programlisting language="php"><![CDATA[
1886 $result = $db->getConnection()->exec('DROP TABLE bugs');
1887 ]]></programlisting>
1888         </example>
1890         <para>
1891             W podobny sposób można korzystać z innych metod szczególnych dla konkretnego
1892             rozszerzenia <acronym>PHP</acronym>. Należy jednak mieć w pamięci, iż w ten
1893             sposób ogranicza się tworzoną aplikację do współpracy z interfejsem oferowanym
1894             jedynie przez konkretne rozszerzenie konkretnej bazy danych.
1895         </para>
1897         <para>
1898             W przyszłych wersjach <classname>Zend_Db</classname> planowane jest umieszczanie 
1899             dodatkowych metod służących do obejmowania funkcjonalności wspólnych dla wielu
1900             rozszerzeń baz danych <acronym>PHP</acronym> ale wsteczna kompatybilność zostanie
1901             zachowana.
1902         </para>
1904     </sect2>
1906     <sect2 id="zend.db.adapter.server-version">
1907         <title>Pobranie wersji serwera</title>
1909         <para>
1910             Począwszy od wersji 1.7.2 można pobrać wersję serwera bazy danych w formie podobnej do
1911             numeru wersji <acronym>PHP</acronym> tak aby można było skorzystać z funkcji
1912             <methodname>version_compare()</methodname>. Jeśli taka informacja nie jest dostępna
1913             to zostanie zwrócona wartość <constant>NULL</constant>.
1914         </para>
1916         <example id="zend.db.adapter.server-version.example">
1917             <title>Weryfikacja wersji serwera przed wywołaniem zapytania</title>
1918             <programlisting language="php"><![CDATA[
1919 $version = $db->getServerVersion();
1920 if (!is_null($version)) {
1921     if (version_compare($version, '5.0.0', '>=')) {
1922         // wykonanie zapytania
1923     } else {
1924         // wykonanie innego zapytania
1925     }
1926 } else {
1927     // wersja serwera niedostępna
1929 ]]></programlisting>
1930         </example>
1931     </sect2>
1933     <sect2 id="zend.db.adapter.adapter-notes">
1935         <title>Informacje o konkretnych adapterach</title>
1937         <para>
1938             Ten akapit wymienia różnice pomiędzy klasami adapterów, z istnienia których
1939             należy sobie zdawać sprawę.
1940         </para>
1942         <sect3 id="zend.db.adapter.adapter-notes.ibm-db2">
1943             <title>IBM DB2</title>
1944             <itemizedlist>
1945                 <listitem>
1946                     <para>
1947                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
1948                         należy użyć nazwy 'Db2'.
1949                     </para>
1950                 </listitem>
1951                 <listitem>
1952                     <para>
1953                         Ten adapter używa rozszerzenia <acronym>PHP</acronym> ibm_db2.
1954                     </para>
1955                 </listitem>
1956                 <listitem>
1957                     <para>
1958                         IBM DB2 wspiera sekwencje oraz klucze automatycznie zwiększające.
1959                         Przez to argumenty dla <methodname>lastInsertId()</methodname> są
1960                         opcjonalne. Jeśli nie poda się argumentów adapter zwróci ostatnią
1961                         wartość wygenerowaną dla klucza automatycznego. Jeśli argumenty zostaną
1962                         podane to adapter zwróci ostatnią wartość wygenerowaną przez sekwencję
1963                         o nazwie zgodnej z konwencją 
1964                         '<emphasis>tabela</emphasis>_<emphasis>kolumna</emphasis>_seq'.
1965                     </para>
1966                 </listitem>
1967             </itemizedlist>
1968         </sect3>
1970         <sect3 id="zend.db.adapter.adapter-notes.mysqli">
1971             <title>MySQLi</title>
1972             <itemizedlist>
1973                 <listitem>
1974                     <para>
1975                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
1976                         należy użyć nazwy 'Mysqli'.
1977                     </para>
1978                 </listitem>
1979                 <listitem>
1980                     <para>
1981                         Ten adapter używa rozszerzenia <acronym>PHP</acronym> mysqli.
1982                     </para>
1983                 </listitem>
1984                 <listitem>
1985                     <para>
1986                         MySQL nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
1987                         ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
1988                         automatycznego. Metoda <methodname>lastSequenceId()</methodname>
1989                         zwraca <constant>NULL</constant>.
1990                     </para>
1991                 </listitem>
1992             </itemizedlist>
1993         </sect3>
1995         <sect3 id="zend.db.adapter.adapter-notes.oracle">
1996             <title>Oracle</title>
1997             <itemizedlist>
1998                 <listitem>
1999                     <para>
2000                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2001                         należy użyć nazwy 'Oracle'.
2002                     </para>
2003                 </listitem>
2004                 <listitem>
2005                     <para>
2006                         Ten adapter używa rozszerzenia <acronym>PHP</acronym> oci8.
2007                     </para>
2008                 </listitem>
2009                 <listitem>
2010                     <para>
2011                         Oracle nie wspiera kluczy automatycznych więc należy podać nazwę
2012                         sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
2013                         <methodname>lastSequenceId()</methodname>.
2014                     </para>
2015                 </listitem>
2016                 <listitem>
2017                     <para>
2018                         Rozszerzenie Oracle nie wspiera parametrów pozycyjnych. Należy
2019                         używać nazwanych parametrów.
2020                     </para>
2021                 </listitem>
2022                 <listitem>
2023                     <para>
2024                         Obecnie, opcja <constant>Zend_Db::CASE_FOLDING</constant> nie jest
2025                         zaimplementowana w tym adapterze. Aby użyć tej opcji z Oracle zalecane
2026                         jest korzystanie z adaptera <acronym>PDO</acronym> OCI.
2027                     </para>
2028                 </listitem>
2029                 <listitem>
2030                     <para>
2031                         Domyślnie pola LOB są zwracane jako obiekty OCI-Lob. Można ustawić
2032                         pobieranie ich w formie łańcuchów znakowych dla wszystkich żądań
2033                         poprzez opcję sterownika '<property>lob_as_string</property>'. Aby
2034                         jednorazowo pobrać obiekt Lob jako string należy użyć metody
2035                         <methodname>setLobAsString(boolean)</methodname>  na adapterze lub
2036                         na obiekcie zapytania.
2037                     </para>
2038                 </listitem>
2039             </itemizedlist>
2040         </sect3>
2042         <sect3 id="zend.db.adapter.adapter-notes.sqlsrv">
2043             <title>Microsoft SQL Server</title>
2044             <itemizedlist>
2045                 <listitem>
2046                     <para>
2047                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2048                         należy użyć nazwy 'Sqlsrv'.
2049                     </para>
2050                 </listitem>
2051                 <listitem>
2052                     <para>
2053                         Ten adapter używa rozszerzenia <acronym>PHP</acronym> sqlsrv.
2054                     </para>
2055                 </listitem>
2056                 <listitem>
2057                     <para>
2058                         Microsoft <acronym>SQL</acronym> Server nie wspiera sekwencji więc
2059                         <methodname>lastInsertId()</methodname> ignoruje argument określający
2060                         klucz pierwotny i zwraca ostatnią wartość wygenerowaną przez automatyczny
2061                         klucz (jeśli jest podana nazwa tabeli) lub identyfikator zwrócony przez
2062                         ostatnie polecenie INSERT. Metoda <methodname>lastSequenceId()</methodname> 
2063                         zwraca <constant>NULL</constant>.
2064                     </para>
2065                 </listitem>
2066                 <listitem>
2067                     <para>
2068                         <classname>Zend_Db_Adapter_Sqlsrv</classname> ustawia opcję
2069                         <constant>QUOTED_IDENTIFIER ON</constant> bezpośrednio po połączeniu się
2070                         z bazą danych <acronym>SQL</acronym> Server. To powoduje, że sterownik
2071                         zaczyna używać standardowego znaku cudzysłowu (<emphasis>"</emphasis>) jako
2072                         ograniczenia identyfikatorów zamiast - charakterystycznych dla produktu 
2073                         Microsoftu - nawiasów kwadratowych.
2074                     </para>
2075                 </listitem>
2076                 <listitem>
2077                     <para>
2078                         Jednym z kluczy podawanych do tablicy opcji może być
2079                         <property>driver_options</property>
2080                         dzięki czemu można skorzystać z wartości podanych w dokumentacji
2081                         <acronym>SQL</acronym> Server
2082                         <ulink url="http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx">
2083                         http://msdn.microsoft.com/en-us/library/cc296161(SQL.90).aspx</ulink>. 
2084                     </para>
2085                 </listitem>
2086                 <listitem>
2087                     <para>
2088                         Dzięki metodzie <methodname>setTransactionIsolationLevel()</methodname>
2089                         można ustawić poziom izolacji transakcji dla bieżącego połączenia.
2090                         Rozpoznawane wartości
2091                         to <constant>SQLSRV_TXN_READ_UNCOMMITTED</constant>,
2092                         <constant>SQLSRV_TXN_READ_COMMITTED</constant>,
2093                         <constant>SQLSRV_TXN_REPEATABLE_READ</constant>,
2094                         <constant>SQLSRV_TXN_SNAPSHOT</constant> or
2095                         <constant>SQLSRV_TXN_SERIALIZABLE</constant>.
2096                     </para>
2097                 </listitem>
2098                 <listitem>
2099                     <para>
2100                         Począwszy od Zend Framework 1.9 minimalną wspieraną wersją rozszerzenia
2101                         <acronym>PHP</acronym> Microsoft <acronym>SQL</acronym> Server jest
2102                         1.0.1924.0. a dla <acronym>MSSQL</acronym> Server Native
2103                         Client - wersja 9.00.3042.00.
2104                     </para>
2105                 </listitem>
2106             </itemizedlist>
2107         </sect3>
2109         <sect3 id="zend.db.adapter.adapter-notes.pdo-ibm">
2110             <title>PDO dla IBM DB2 oraz Informix Dynamic Server (IDS)</title>
2111             <itemizedlist>
2112                 <listitem>
2113                     <para>
2114                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2115                         należy użyć nazwy '<classname>Pdo_Ibm</classname>'.
2116                     </para>
2117                 </listitem>
2118                 <listitem>
2119                     <para>
2120                         Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_ibm.
2121                     </para>
2122                 </listitem>
2123                 <listitem>
2124                     <para>
2125                         Należy używać wersji 1.2.2 lub wyższej rozszerzenia PDO_IBM. Zaleca się
2126                         uaktualnienie wcześniejszych wersji poprzez <acronym>PECL</acronym>.
2127                     </para>
2128                 </listitem>
2129             </itemizedlist>
2130         </sect3>
2132         <sect3 id="zend.db.adapter.adapter-notes.pdo-mssql">
2133             <title>PDO Microsoft SQL Server</title>
2134             <itemizedlist>
2135                 <listitem>
2136                     <para>
2137                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2138                         należy użyć nazwy '<classname>Pdo_Mssql</classname>'.
2139                     </para>
2140                 </listitem>
2141                 <listitem>
2142                     <para>
2143                         Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_dblib.
2144                     </para>
2145                 </listitem>
2146                 <listitem>
2147                     <para>
2148                         Microsoft <acronym>SQL</acronym> Server nie wspiera sekwencji więc
2149                         <methodname>lastInsertId()</methodname> ignoruje argument określający
2150                         klucz pierwotny i zwraca ostatnią wartość wygenerowaną przez automatyczny
2151                         klucz (jeśli jest podana nazwa tabeli) lub identyfikator zwrócony przez
2152                         ostatnie polecenie INSERT. Metoda <methodname>lastSequenceId()</methodname> 
2153                         zwraca <constant>NULL</constant>.
2154                     </para>
2155                 </listitem>
2156                 <listitem>
2157                     <para>
2158                         W przypadku pracy z łańcuchami znaków unicode zakodowanych w sposób inny
2159                         niż UCS-2 (czyli również w formie UTF-8), może zajść potrzeba dokonania 
2160                         konwersji w kodzie aplikacji lub przechowywania
2161                         danych w kolumnach binarnych.
2162                         Aby uzyskać więcej informacji można skorzystać z
2163                         <ulink url="http://support.microsoft.com/kb/232580">Microsoft's Knowledge
2164                         Base</ulink>.
2165                     </para>
2166                 </listitem>
2167                 <listitem>
2168                     <para>
2169                         <classname>Zend_Db_Adapter_Pdo_Mssql</classname> ustawia opcję
2170                         <constant>QUOTED_IDENTIFIER ON</constant> bezpośrednio po połączeniu się
2171                         z bazą danych <acronym>SQL</acronym> Server. To powoduje, że sterownik
2172                         zaczyna używać standardowego znaku cudzysłowu (<emphasis>"</emphasis>) jako
2173                         ograniczenia identyfikatorów zamiast - charakterystycznych dla produktu 
2174                         Microsoftu - nawiasów kwadratowych.
2175                     </para>
2176                 </listitem>
2177                 <listitem>
2178                     <para>
2179                         Adapter rozpoznaje klucz <property>pdoType</property> w tablicy opcji. Jego
2180                         wartość może wynosić "mssql" (domyślnie), "dblib", "freetds", lub "sybase".
2181                         To wpływa na prefiks <acronym>DSN</acronym> używany przez
2182                         adapter do utworzenia łańcucha połączenia.
2183                         Wartości "freetds" oraz "sybase" powodują utworzenie prefiksu
2184                         "sybase:" używanego przez biblioteki 
2185                         <ulink url="http://www.freetds.org/">FreeTDS</ulink>.
2186                         Należy zapoznać się z informacjami dotyczącymi prefiksów
2187                         <acronym>DSN</acronym>
2188                         używanymi przez ten sterownik pod adresem
2189                         <ulink url="http://www.php.net/manual/en/ref.pdo-dblib.connection.php">
2190                         http://www.php.net/manual/en/ref.pdo-dblib.connection.php</ulink>
2191                     </para>
2192                 </listitem>
2193             </itemizedlist>
2194         </sect3>
2196         <sect3 id="zend.db.adapter.adapter-notes.pdo-mysql">
2197             <title>PDO MySQL</title>
2198             <itemizedlist>
2199                 <listitem>
2200                     <para>
2201                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2202                         należy użyć nazwy '<classname>Pdo_Mysql</classname>'.
2203                     </para>
2204                 </listitem>
2205                 <listitem>
2206                     <para>
2207                         Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_mysql.
2208                     </para>
2209                 </listitem>
2210                 <listitem>
2211                     <para>
2212                         MySQL nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
2213                         ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
2214                         automatycznego. Metoda <methodname>lastSequenceId()</methodname>
2215                         zwraca <constant>NULL</constant>.
2216                     </para>
2217                 </listitem>
2218             </itemizedlist>
2219         </sect3>
2221         <sect3 id="zend.db.adapter.adapter-notes.pdo-oci">
2222             <title>PDO Oracle</title>
2223             <itemizedlist>
2224                 <listitem>
2225                     <para>
2226                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2227                         należy użyć nazwy '<classname>Pdo_Oci</classname>'.
2228                     </para>
2229                 </listitem>
2230                 <listitem>
2231                     <para>
2232                         Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_oci.
2233                     </para>
2234                 </listitem>
2235                 <listitem>
2236                     <para>
2237                         Oracle nie wspiera kluczy automatycznych więc należy podać nazwę
2238                         sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
2239                         <methodname>lastSequenceId()</methodname>.
2240                     </para>
2241                 </listitem>
2242             </itemizedlist>
2243         </sect3>
2245         <sect3 id="zend.db.adapter.adapter-notes.pdo-pgsql">
2246             <title>PDO PostgreSQL</title>
2247             <itemizedlist>
2248                 <listitem>
2249                     <para>
2250                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2251                         należy użyć nazwy '<classname>Pdo_Pgsql</classname>'.
2252                     </para>
2253                 </listitem>
2254                 <listitem>
2255                     <para>
2256                         Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_pgsql.
2257                     </para>
2258                 </listitem>
2259                 <listitem>
2260                     <para>
2261                         PostgreSQL wspiera sekwencje oraz klucze automatyczne. Przez to
2262                         podawanie argumentów w <methodname>lastInsertId()</methodname> jest
2263                         opcjonalne. Jeśli nie poda się argumentów adapter zwróci ostatnią
2264                         wartość wygenerowaną dla klucza automatycznego. Jeśli argumenty zostaną
2265                         podane to adapter zwróci ostatnią wartość wygenerowaną przez sekwencję
2266                         o nazwie zgodnej z konwencją 
2267                         '<emphasis>tabela</emphasis>_<emphasis>kolumna</emphasis>_seq'. 
2268                     </para>
2269                 </listitem>
2270             </itemizedlist>
2271         </sect3>
2273         <sect3 id="zend.db.adapter.adapter-notes.pdo-sqlite">
2274             <title>PDO SQLite</title>
2275             <itemizedlist>
2276                 <listitem>
2277                     <para>
2278                         Aby uzyskać ten adapter poprzez metodę <methodname>factory()</methodname> 
2279                         należy użyć nazwy '<classname>Pdo_Sqlite</classname>'.
2280                     </para>
2281                 </listitem>
2282                 <listitem>
2283                     <para>
2284                         Ten adapter używa rozszerzeń <acronym>PHP</acronym> pdo and pdo_sqlite.
2285                     </para>
2286                 </listitem>
2287                 <listitem>
2288                     <para>
2289                         SQLite nie wspiera sekwencji więc <methodname>lastInsertId()</methodname>
2290                         ignoruje argumenty i zwraca ostatnią wartość wygenerowaną dla klucza
2291                         automatycznego. Metoda <methodname>lastSequenceId()</methodname>
2292                         zwraca <constant>NULL</constant>.
2293                     </para>
2294                 </listitem>
2295                 <listitem>
2296                     <para>
2297                         Aby połączyć się z bazą danych SQLite2 należy podać 
2298                         <command>'sqlite2' => true</command> jako jeden z elementów
2299                         tablicy parametrów podczas tworzenia instancji adaptera
2300                         <classname>Pdo_Sqlite</classname>.
2301                     </para>
2302                 </listitem>
2303                 <listitem>
2304                     <para>
2305                         Aby połączyć się z bazą danych SQLite rezydującą w pamięci
2306                         należy podać <command>'dbname' => ':memory:'</command> jako
2307                         jeden z elementów tablicy parametrów podczas tworzenia instancji adaptera
2308                         <classname>Pdo_Sqlite</classname>.
2309                     </para>
2310                 </listitem>
2311                 <listitem>
2312                     <para>
2313                         Starsze wersje sterownika <acronym>PHP</acronym> SQLite nie wspierają
2314                         poleceń PRAGMA niezbędnych dla zachowania krótkich nazw kolumn w 
2315                         wynikach zapytania. W przypadku wystąpienia problemów z zapytaniami JOIN
2316                         polegających na zwracaniu wyników z nazwami kolumn w postaci 
2317                         "tabela.kolumna" zaleca się aktualizację <acronym>PHP</acronym> do 
2318                         najnowszej wersji.
2319                     </para>
2320                 </listitem>
2321             </itemizedlist>
2322         </sect3>
2324         <sect3 id="zend.db.adapter.adapter-notes.firebird">
2325             <title>Firebird/Interbase</title>
2326             <itemizedlist>
2327                 <listitem>
2328                     <para>
2329                         Ten adapter używa rozszerzenia <acronym>PHP</acronym> php_interbase.
2330                     </para>
2331                 </listitem>
2332                 <listitem>
2333                     <para>
2334                         Firebird/Interbase nie wspiera kluczy automatycznych więc należy podać nazwę
2335                         sekwencji w metodzie <methodname>lastInsertId()</methodname> lub
2336                         <methodname>lastSequenceId()</methodname>.
2337                     </para>
2338                 </listitem>
2339                 <listitem>
2340                     <para>
2341                         Obecnie, opcja <constant>Zend_Db::CASE_FOLDING</constant> nie jest
2342                         zaimplementowana w tym adapterze. Identyfikatory bez znaków ograniczających
2343                         są zwracane w postaci wielkich liter.
2344                     </para>
2345                 </listitem>
2347                 <listitem>
2348                     <para>
2349                         Nazwa adaptera to <classname>ZendX_Db_Adapter_Firebird</classname>.
2350                     </para>
2351                     <para>
2352                         Należy pamiętać o użyciu parametru adapterNamespace z wartością
2353                         <classname>ZendX_Db_Adapter</classname>.
2354                     </para>
2355                     <para>
2356                         Zaleca się aktualizację pliku <filename>gds32.dll</filename> (lub 
2357                         odpowiednika wersji linux) dostarczanym z <acronym>PHP</acronym> do wersji odpowiadającej
2358                         serwerowi bazy danych. Dla Firebird odpowiednikiem 
2359                         <filename>gds32.dll</filename> jest
2360                         <filename>fbclient.dll</filename>.
2361                     </para>
2362                     <para>
2363                         Domyślnie wszystkie identyfikatory (nazwy tabel, kolumn) są zwracane 
2364                         wielkimi literami.
2365                     </para>
2366                 </listitem>
2367             </itemizedlist>
2368         </sect3>
2370     </sect2>
2372 </sect1>
2373 <!--
2374 vim:se ts=4 sw=4 et: