00001 <?php
00025 require_once 'Zend/Db/Adapter/Pdo/Ibm.php';
00026
00028 require_once 'Zend/Db/Statement/Pdo/Ibm.php';
00029
00030
00038 class Zend_Db_Adapter_Pdo_Ibm_Ids
00039 {
00043 protected $_adapter = null;
00044
00053 public function __construct($adapter)
00054 {
00055 $this->_adapter = $adapter;
00056 }
00057
00063 public function listTables()
00064 {
00065 $sql = "SELECT tabname "
00066 . "FROM systables ";
00067
00068 return $this->_adapter->fetchCol($sql);
00069 }
00070
00078 public function describeTable($tableName, $schemaName = null)
00079 {
00080
00081
00082 $sql= "SELECT DISTINCT t.owner, t.tabname, c.colname, c.colno, c.coltype,
00083 d.default, c.collength, t.tabid
00084 FROM syscolumns c
00085 JOIN systables t ON c.tabid = t.tabid
00086 LEFT JOIN sysdefaults d ON c.tabid = d.tabid AND c.colno = d.colno
00087 WHERE "
00088 . $this->_adapter->quoteInto('UPPER(t.tabname) = UPPER(?)', $tableName);
00089 if ($schemaName) {
00090 $sql .= $this->_adapter->quoteInto(' AND UPPER(t.owner) = UPPER(?)', $schemaName);
00091 }
00092 $sql .= " ORDER BY c.colno";
00093
00094 $desc = array();
00095 $stmt = $this->_adapter->query($sql);
00096
00097 $result = $stmt->fetchAll(Zend_Db::FETCH_NUM);
00098
00103 $tabschema = 0;
00104 $tabname = 1;
00105 $colname = 2;
00106 $colno = 3;
00107 $typename = 4;
00108 $default = 5;
00109 $length = 6;
00110 $tabid = 7;
00111
00112 $primaryCols = null;
00113
00114 foreach ($result as $key => $row) {
00115 $primary = false;
00116 $primaryPosition = null;
00117
00118 if (!$primaryCols) {
00119 $primaryCols = $this->_getPrimaryInfo($row[$tabid]);
00120 }
00121
00122 if (array_key_exists($row[$colno], $primaryCols)) {
00123 $primary = true;
00124 $primaryPosition = $primaryCols[$row[$colno]];
00125 }
00126
00127 $identity = false;
00128 if ($row[$typename] == 6 + 256 ||
00129 $row[$typename] == 18 + 256) {
00130 $identity = true;
00131 }
00132
00133 $desc[$this->_adapter->foldCase($row[$colname])] = array (
00134 'SCHEMA_NAME' => $this->_adapter->foldCase($row[$tabschema]),
00135 'TABLE_NAME' => $this->_adapter->foldCase($row[$tabname]),
00136 'COLUMN_NAME' => $this->_adapter->foldCase($row[$colname]),
00137 'COLUMN_POSITION' => $row[$colno],
00138 'DATA_TYPE' => $this->_getDataType($row[$typename]),
00139 'DEFAULT' => $row[$default],
00140 'NULLABLE' => (bool) !($row[$typename] - 256 >= 0),
00141 'LENGTH' => $row[$length],
00142 'SCALE' => ($row[$typename] == 5 ? $row[$length]&255 : 0),
00143 'PRECISION' => ($row[$typename] == 5 ? (int)($row[$length]/256) : 0),
00144 'UNSIGNED' => false,
00145 'PRIMARY' => $primary,
00146 'PRIMARY_POSITION' => $primaryPosition,
00147 'IDENTITY' => $identity
00148 );
00149 }
00150
00151 return $desc;
00152 }
00153
00161 protected function _getDataType($typeNo)
00162 {
00163 $typemap = array(
00164 0 => "CHAR",
00165 1 => "SMALLINT",
00166 2 => "INTEGER",
00167 3 => "FLOAT",
00168 4 => "SMALLFLOAT",
00169 5 => "DECIMAL",
00170 6 => "SERIAL",
00171 7 => "DATE",
00172 8 => "MONEY",
00173 9 => "NULL",
00174 10 => "DATETIME",
00175 11 => "BYTE",
00176 12 => "TEXT",
00177 13 => "VARCHAR",
00178 14 => "INTERVAL",
00179 15 => "NCHAR",
00180 16 => "NVARCHAR",
00181 17 => "INT8",
00182 18 => "SERIAL8",
00183 19 => "SET",
00184 20 => "MULTISET",
00185 21 => "LIST",
00186 22 => "Unnamed ROW",
00187 40 => "Variable-length opaque type",
00188 4118 => "Named ROW"
00189 );
00190
00191 if ($typeNo - 256 >= 0) {
00192 $typeNo = $typeNo - 256;
00193 }
00194
00195 return $typemap[$typeNo];
00196 }
00197
00205 protected function _getPrimaryInfo($tabid)
00206 {
00207 $sql = "SELECT i.part1, i.part2, i.part3, i.part4, i.part5, i.part6,
00208 i.part7, i.part8, i.part9, i.part10, i.part11, i.part12,
00209 i.part13, i.part14, i.part15, i.part16
00210 FROM sysindexes i
00211 JOIN sysconstraints c ON c.idxname = i.idxname
00212 WHERE i.tabid = " . $tabid . " AND c.constrtype = 'P'";
00213
00214 $stmt = $this->_adapter->query($sql);
00215 $results = $stmt->fetchAll();
00216
00217 $cols = array();
00218
00219
00220
00221
00222 if ($results) {
00223 $row = $results[0];
00224 } else {
00225 return $cols;
00226 }
00227
00228 $position = 0;
00229 foreach ($row as $key => $colno) {
00230 $position++;
00231 if ($colno == 0) {
00232 return $cols;
00233 } else {
00234 $cols[$colno] = $position;
00235 }
00236 }
00237 }
00238
00248 public function limit($sql, $count, $offset = 0)
00249 {
00250 $count = intval($count);
00251 if ($count < 0) {
00253 require_once 'Zend/Db/Adapter/Exception.php';
00254 throw new Zend_Db_Adapter_Exception("LIMIT argument count=$count is not valid");
00255 } else if ($count == 0) {
00256 $limit_sql = str_ireplace("SELECT", "SELECT * FROM (SELECT", $sql);
00257 $limit_sql .= ") WHERE 0 = 1";
00258 } else {
00259 $offset = intval($offset);
00260 if ($offset < 0) {
00262 require_once 'Zend/Db/Adapter/Exception.php';
00263 throw new Zend_Db_Adapter_Exception("LIMIT argument offset=$offset is not valid");
00264 }
00265 if ($offset == 0) {
00266 $limit_sql = str_ireplace("SELECT", "SELECT FIRST $count", $sql);
00267 } else {
00268 $limit_sql = str_ireplace("SELECT", "SELECT SKIP $offset LIMIT $count", $sql);
00269 }
00270 }
00271 return $limit_sql;
00272 }
00273
00280 public function lastSequenceId($sequenceName)
00281 {
00282 $sql = 'SELECT '.$this->_adapter->quoteIdentifier($sequenceName).'.CURRVAL FROM '
00283 .'systables WHERE tabid = 1';
00284 $value = $this->_adapter->fetchOne($sql);
00285 return $value;
00286 }
00287
00294 public function nextSequenceId($sequenceName)
00295 {
00296 $sql = 'SELECT '.$this->_adapter->quoteIdentifier($sequenceName).'.NEXTVAL FROM '
00297 .'systables WHERE tabid = 1';
00298 $value = $this->_adapter->fetchOne($sql);
00299 return $value;
00300 }
00301 }