# Source for file Db2.php

Documentation is available at Db2.php

1. <?php
2. /*
3. * $Id: Mock.php 1080 2007-02-10 18:17:08Z romanb $
4. *
5. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
6. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
7. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
8. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
9. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
10. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
11. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
12. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
13. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
14. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
15. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
16. *
17. * This software consists of voluntary contributions made by many individuals
18. * and is licensed under the LGPL. For more information, see
19. * <http://www.phpdoctrine.com>.
20. */
21. Doctrine::autoload('Doctrine_Adapter');
22. /**
23. * Doctrine_Adapter_Db2
24. * IBM DB2 Adapter [BORROWED FROM ZEND FRAMEWORK]
25. *
26. * @package Doctrine
27. * @subpackage Doctrine_Adapter
28. * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
29. * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
30. * @category Object Relational Mapping
31. * @link www.phpdoctrine.com
32. * @since 1.0
33. * @version $Revision: 1080 $
34. */
35. class Doctrine_Adapter_Db2 extends Doctrine_Adapter
36. {
37. /**
38. * User-provided configuration.
39. *
40. * Basic keys are:
41. *
42. * username => (string) Connect to the database as this username.
43. * password => (string) Password associated with the username.
44. * host => (string) What host to connect to (default 127.0.0.1)
45. * dbname => (string) The name of the database to user
46. * protocol => (string) Protocol to use, defaults to "TCPIP"
47. * port => (integer) Port number to use for TCP/IP if protocol is "TCPIP"
48. * persistent => (boolean) Set TRUE to use a persistent connection (db2_pconnect)
49. *
50. * @var array
51. */
52. protected $_config = array(
53. 'dbname' => null,
54. 'username' => null,
55. 'password' => null,
56. 'host' => 'localhost',
57. 'port' => '50000',
58. 'protocol' => 'TCPIP',
59. 'persistent' => false
60. );
62. /**
63. * Execution mode
64. *
65. * @var int execution flag (DB2_AUTOCOMMIT_ON or DB2_AUTOCOMMIT_OFF)
66. * @access protected
67. */
68. protected $_execute_mode = DB2_AUTOCOMMIT_ON;
70. /**
71. * Table name of the last accessed table for an insert operation
72. * This is a DB2-Adapter-specific member variable with the utmost
73. * probability you might not find it in other adapters...
74. *
75. * @var string
76. * @access protected
77. */
78. protected $_lastInsertTable = null;
80. /**
81. * Constructor.
82. *
83. * $config is an array of key/value pairs containing configuration
84. * options. These options are common to most adapters:
85. *
86. * dbname => (string) The name of the database to user
87. * username => (string) Connect to the database as this username.
88. * password => (string) Password associated with the username.
89. * host => (string) What host to connect to, defaults to localhost
90. * port => (string) The port of the database, defaults to 50000
91. * persistent => (boolean) Whether to use a persistent connection or not, defaults to false
92. * protocol => (string) The network protocol, defaults to TCPIP
93. * options => (array) Other database options such as autocommit, case, and cursor options
94. *
95. * @param array $config An array of configuration keys.
96. */
97. public function __construct(array $config)
98. {
99. if ( ! isset($config['password'])) {
100. throw new Doctrine_Adapter_Db2_Exception("Configuration array must have a key for 'password' for login credentials.");
101. }
103. if ( ! isset($config['username'])) {
104. throw new Doctrine_Adapter_Db2_Exception("Configuration array must have a key for 'username' for login credentials.");
105. }
107. if ( ! isset($config['dbname'])) {
108. throw new Doctrine_Adapter_Db2_Exception("Configuration array must have a key for 'dbname' that names the database instance.");
109. }
111. // keep the config
112. $this->_config = array_merge($this->_config, (array) $config);
114. // create a profiler object
115. $enabled = false;
116. if (array_key_exists('profiler', $this->_config)) {
117. $enabled = (bool) $this->_config['profiler'];
118. unset($this->_config['profiler']);
119. }
121. $this->_profiler = new Doctrine_Profiler($enabled);
122. }
124. /**
125. * Creates a connection resource.
126. *
127. * @return void
128. */
129. protected function _connect()
130. {
131. if (is_resource($this->_connection)) {
132. // connection already exists
133. return;
134. }
136. if ( ! extension_loaded('ibm_db2')) {
137. throw new Doctrine_Adapter_Db2_Exception('The IBM DB2 extension is required for this adapter but not loaded');
138. }
140. if ($this->_config['persistent']) {
141. // use persistent connection
142. $conn_func_name = 'db2_pconnect';
143. } else {
144. // use "normal" connection
145. $conn_func_name = 'db2_connect';
146. }
148. if (!isset($this->_config['options'])) {
149. // config options were not set, so set it to an empty array
150. $this->_config['options'] = array();
151. }
153. if (!isset($this->_config['options']['autocommit'])) {
154. // set execution mode
155. $this->_config['options']['autocommit'] = &$this->_execute_mode;
156. }
158. if ($this->_config['host'] !== 'localhost') {
159. // if the host isn't localhost, use extended connection params
160. $dbname = 'DRIVER={IBM DB2 ODBC DRIVER}' .
161. ';DATABASE=' . $this->_config['dbname'] .
162. ';HOSTNAME=' . $this->_config['host'] .
163. ';PORT=' . $this->_config['port'] .
164. ';PROTOCOL=' . $this->_config['protocol'] .
165. ';UID=' . $this->_config['username'] .
166. ';PWD=' . $this->_config['password'] .';';
167. $this->_connection = $conn_func_name(
168. $dbname,
169. null,
170. null,
171. $this->_config['options']
172. );
173. } else {
174. // host is localhost, so use standard connection params
175. $this->_connection = $conn_func_name(
176. $this->_config['dbname'],
177. $this->_config['username'],
178. $this->_config['password'],
179. $this->_config['options']
180. );
181. }
183. // check the connection
184. if (!$this->_connection) {
185. throw new Doctrine_Adapter_Db2_Exception(db2_conn_errormsg(), db2_conn_error());
186. }
187. }
189. /**
190. * Force the connection to close.
191. *
192. * @return void
193. */
194. public function closeConnection()
195. {
196. db2_close($this->_connection);
197. $this->_connection = null;
198. }
200. /**
201. * Returns an SQL statement for preparation.
202. *
203. * @param string $sql The SQL statement with placeholders.
204. * @return Doctrine_Statement_Db2
205. */
206. public function prepare($sql)
207. {
208. $this->_connect();
209. $stmt = new Doctrine_Statement_Db2($this, $sql);
210. $stmt->setFetchMode($this->_fetchMode);
211. return $stmt;
212. }
214. /**
215. * Gets the execution mode
216. *
217. * @return int the execution mode (DB2_AUTOCOMMIT_ON or DB2_AUTOCOMMIT_OFF)
218. */
219. public function _getExecuteMode()
220. {
221. return $this->_execute_mode;
222. }
224. /**
225. * @param integer $mode
226. * @return void
227. */
228. public function _setExecuteMode($mode)
229. {
230. switch ($mode) {
231. case DB2_AUTOCOMMIT_OFF:
232. case DB2_AUTOCOMMIT_ON:
233. $this->_execute_mode = $mode;
234. db2_autocommit($this->_connection, $mode);
235. break;
236. default:
237. throw new Doctrine_Adapter_Db2_Exception("execution mode not supported");
238. break;
239. }
240. }
242. /**
243. * Quote a raw string.
244. *
245. * @param string $value Raw string
246. * @return string Quoted string
247. */
248. protected function _quote($value)
249. {
250. /**
251. * Some releases of the IBM DB2 extension appear
252. * to be missing the db2_escape_string() method.
253. * The method was added in ibm_db2.c revision 1.53
254. * according to cvs.php.net. But the function is
255. * not present in my build of PHP 5.2.1.
256. */
257. if (function_exists('db2_escape_string')) {
258. return db2_escape_string($value);
259. }
260. return parent::_quote($value);
261. }
263. /**
264. * @return string
265. */
266. public function getQuoteIdentifierSymbol()
267. {
268. $info = db2_server_info($this->_connection);
269. $identQuote = $info->IDENTIFIER_QUOTE_CHAR;
270. return $identQuote;
271. }
272. /**
273. * Begin a transaction.
274. *
275. * @return void
276. */
277. protected function _beginTransaction()
278. {
279. $this->_setExecuteMode(DB2_AUTOCOMMIT_OFF);
280. }
282. /**
283. * Commit a transaction.
284. *
285. * @return void
286. */
287. protected function _commit()
288. {
289. if (!db2_commit($this->_connection)) {
290. throw new Doctrine_Adapter_Db2_Exception(
291. db2_conn_errormsg($this->_connection),
292. db2_conn_error($this->_connection));
293. }
295. $this->_setExecuteMode(DB2_AUTOCOMMIT_ON);
296. }
298. /**
299. * Rollback a transaction.
300. *
301. * @return void
302. */
303. protected function _rollBack()
304. {
305. if (!db2_rollback($this->_connection)) {
306. throw new Doctrine_Adapter_Db2_Exception(
307. db2_conn_errormsg($this->_connection),
308. db2_conn_error($this->_connection));
309. }
310. $this->_setExecuteMode(DB2_AUTOCOMMIT_ON);
311. }
313. /**
314. * Set the fetch mode.
315. *
316. * @param integer $mode
317. * @return void
318. */
319. public function setFetchMode($mode)
320. {
321. switch ($mode) {
322. case Doctrine::FETCH_NUM: // seq array
323. case Doctrine::FETCH_ASSOC: // assoc array
324. case Doctrine::FETCH_BOTH: // seq+assoc array
325. case Doctrine::FETCH_OBJ: // object
326. $this->_fetchMode = $mode;
327. break;
328. default:
329. throw new Doctrine_Adapter_Db2_Exception('Invalid fetch mode specified');
330. break;
331. }
332. }
333. }