7
* This source file is subject to the new BSD license that is bundled
8
* with this package in the file LICENSE.txt.
9
* It is also available through the world-wide-web at this URL:
10
* http://framework.zend.com/license/new-bsd
11
* If you did not receive a copy of the license and are unable to
12
* obtain it through the world-wide-web, please send an email
13
* to license@zend.com so we can send you a copy immediately.
18
* @copyright Copyright (c) 2005-2008 Zend Technologies USA Inc. (http://www.zend.com)
19
* @license http://framework.zend.com/license/new-bsd New BSD License
20
* @version $Id: Db2.php 9101 2008-03-30 19:54:38Z thomas $
24
/** @see Zend_Db_Adapter_Pdo_Ibm */
25
require_once 'Zend/Db/Adapter/Pdo/Ibm.php';
27
/** @see Zend_Db_Statement_Pdo_Ibm */
28
require_once 'Zend/Db/Statement/Pdo/Ibm.php';
35
* @copyright Copyright (c) 2005-2008 Zend Technologies Inc. (http://www.zend.com)
36
* @license http://framework.zend.com/license/new-bsd New BSD License
38
class Zend_Db_Adapter_Pdo_Ibm_Db2
41
* @var Zend_Db_Adapter_Abstract
43
protected $_adapter = null;
46
* Construct the data server class.
48
* It will be used to generate non-generic SQL
49
* for a particular data server
51
* @param Zend_Db_Adapter_Abstract $adapter
53
public function __construct($adapter)
55
$this->_adapter = $adapter;
59
* Returns a list of the tables in the database.
63
public function listTables()
65
$sql = "SELECT tabname "
66
. "FROM SYSCAT.TABLES ";
67
return $this->_adapter->fetchCol($sql);
71
* DB2 catalog lookup for describe table
73
* @param string $tableName
74
* @param string $schemaName OPTIONAL
77
public function describeTable($tableName, $schemaName = null)
79
$sql = "SELECT DISTINCT c.tabschema, c.tabname, c.colname, c.colno,
80
c.typename, c.default, c.nulls, c.length, c.scale,
81
c.identity, tc.type AS tabconsttype, k.colseq
83
LEFT JOIN (syscat.keycoluse k JOIN syscat.tabconst tc
84
ON (k.tabschema = tc.tabschema
85
AND k.tabname = tc.tabname
87
ON (c.tabschema = k.tabschema
88
AND c.tabname = k.tabname
89
AND c.colname = k.colname)
91
. $this->_adapter->quoteInto('UPPER(c.tabname) = UPPER(?)', $tableName);
93
$sql .= $this->_adapter->quoteInto(' AND UPPER(c.tabschema) = UPPER(?)', $schemaName);
95
$sql .= " ORDER BY c.colno";
98
$stmt = $this->_adapter->query($sql);
101
* To avoid case issues, fetch using FETCH_NUM
103
$result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
106
* The ordering of columns is defined by the query so we can map
107
* to variables to improve readability
122
foreach ($result as $key => $row) {
123
list ($primary, $primaryPosition, $identity) = array(false, null, false);
124
if ($row[$tabconstype] == 'P') {
126
$primaryPosition = $row[$colseq];
129
* In IBM DB2, an column can be IDENTITY
130
* even if it is not part of the PRIMARY KEY.
132
if ($row[$identityCol] == 'Y') {
136
$desc[$this->_adapter->foldCase($row[$colname])] = array(
137
'SCHEMA_NAME' => $this->_adapter->foldCase($row[$tabschema]),
138
'TABLE_NAME' => $this->_adapter->foldCase($row[$tabname]),
139
'COLUMN_NAME' => $this->_adapter->foldCase($row[$colname]),
140
'COLUMN_POSITION' => $row[$colno]+1,
141
'DATA_TYPE' => $row[$typename],
142
'DEFAULT' => $row[$default],
143
'NULLABLE' => (bool) ($row[$nulls] == 'Y'),
144
'LENGTH' => $row[$length],
145
'SCALE' => $row[$scale],
146
'PRECISION' => ($row[$typename] == 'DECIMAL' ? $row[$length] : 0),
148
'PRIMARY' => $primary,
149
'PRIMARY_POSITION' => $primaryPosition,
150
'IDENTITY' => $identity
158
* Adds a DB2-specific LIMIT clause to the SELECT statement.
161
* @param integer $count
162
* @param integer $offset OPTIONAL
163
* @throws Zend_Db_Adapter_Exception
166
public function limit($sql, $count, $offset = 0)
168
$count = intval($count);
170
/** @see Zend_Db_Adapter_Exception */
171
require_once 'Zend/Db/Adapter/Exception.php';
172
throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
174
$offset = intval($offset);
176
/** @see Zend_Db_Adapter_Exception */
177
require_once 'Zend/Db/Adapter/Exception.php';
178
throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
181
if ($offset == 0 && $count > 0) {
182
$limit_sql = $sql . " FETCH FIRST $count ROWS ONLY";
186
* DB2 does not implement the LIMIT clause as some RDBMS do.
187
* We have to simulate it with subqueries and ROWNUM.
188
* Unfortunately because we use the column wildcard "*",
189
* this puts an extra column into the query result set.
191
$limit_sql = "SELECT z2.*
193
SELECT ROW_NUMBER() OVER() AS \"ZEND_DB_ROWNUM\", z1.*
198
WHERE z2.zend_db_rownum BETWEEN " . ($offset+1) . " AND " . ($offset+$count);
204
* DB2-specific last sequence id
206
* @param string $sequenceName
209
public function lastSequenceId($sequenceName)
211
$sql = 'SELECT PREVVAL FOR '.$this->_adapter->quoteIdentifier($sequenceName).' AS VAL FROM SYSIBM.SYSDUMMY1';
212
$value = $this->_adapter->fetchOne($sql);
217
* DB2-specific sequence id value
219
* @param string $sequenceName
222
public function nextSequenceId($sequenceName)
224
$sql = 'SELECT NEXTVAL FOR '.$this->_adapter->quoteIdentifier($sequenceName).' AS VAL FROM SYSIBM.SYSDUMMY1';
225
$value = $this->_adapter->fetchOne($sql);