See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 /** 3 * Data Dictionary for Firebird. 4 * 5 * This file is part of ADOdb, a Database Abstraction Layer library for PHP. 6 * 7 * @package ADOdb 8 * @link https://adodb.org Project's web site and documentation 9 * @link https://github.com/ADOdb/ADOdb Source code and issue tracker 10 * 11 * The ADOdb Library is dual-licensed, released under both the BSD 3-Clause 12 * and the GNU Lesser General Public Licence (LGPL) v2.1 or, at your option, 13 * any later version. This means you can use it in proprietary products. 14 * See the LICENSE.md file distributed with this source code for details. 15 * @license BSD-3-Clause 16 * @license LGPL-2.1-or-later 17 * 18 * @copyright 2000-2013 John Lim 19 * @copyright 2014 Damien Regad, Mark Newnham and the ADOdb community 20 */ 21 22 // security - hide paths 23 if (!defined('ADODB_DIR')) die(); 24 25 class ADODB2_firebird extends ADODB_DataDict 26 { 27 var $databaseType = 'firebird'; 28 var $seqField = false; 29 var $seqPrefix = 's_'; 30 var $blobSize = 40000; 31 var $renameColumn = 'ALTER TABLE %s ALTER %s TO %s'; 32 var $alterCol = ' ALTER'; 33 var $dropCol = ' DROP'; 34 35 function actualType($meta) 36 { 37 38 $meta = strtoupper($meta); 39 40 // Add support for custom meta types. 41 // We do this first, that allows us to override existing types 42 if (isset($this->connection->customMetaTypes[$meta])) { 43 return $this->connection->customMetaTypes[$meta]['actual']; 44 } 45 46 switch($meta) { 47 case 'C': 48 return 'VARCHAR'; 49 case 'XL': 50 return 'BLOB SUB_TYPE BINARY'; 51 case 'X': 52 return 'BLOB SUB_TYPE TEXT'; 53 54 case 'C2': 55 return 'VARCHAR(32765)'; // up to 32K 56 case 'X2': 57 return 'VARCHAR(4096)'; 58 59 case 'V': 60 return 'CHAR'; 61 case 'C1': 62 return 'CHAR(1)'; 63 64 case 'B': 65 return 'BLOB'; 66 67 case 'D': 68 return 'DATE'; 69 case 'TS': 70 case 'T': 71 return 'TIMESTAMP'; 72 73 case 'L': 74 case 'I1': 75 case 'I2': 76 return 'SMALLINT'; 77 case 'I': 78 case 'I4': 79 return 'INTEGER'; 80 case 'I8': 81 return 'BIGINT'; 82 83 case 'F': 84 return 'DOUBLE PRECISION'; 85 case 'N': 86 return 'DECIMAL'; 87 default: 88 return $meta; 89 } 90 } 91 92 function nameQuote($name = null, $allowBrackets = false) 93 { 94 if (!is_string($name)) { 95 return false; 96 } 97 98 $name = trim($name); 99 100 if (!is_object($this->connection)) { 101 return $name; 102 } 103 104 $quote = $this->connection->nameQuote; 105 106 // if name is of the form `name`, quote it 107 if (preg_match('/^`(.+)`$/', $name, $matches)) { 108 return $quote . $matches[1] . $quote; 109 } 110 111 // if name contains special characters, quote it 112 if (!preg_match('/^[' . $this->nameRegex . ']+$/', $name)) { 113 return $quote . $name . $quote; 114 } 115 116 return $quote . $name . $quote; 117 } 118 119 function createDatabase($dbname, $options = false) 120 { 121 $sql = array(); 122 123 $sql[] = "DECLARE EXTERNAL FUNCTION LOWER CSTRING(80) RETURNS CSTRING(80) FREE_IT ENTRY_POINT 'IB_UDF_lower' MODULE_NAME 'ib_udf'"; 124 125 return $sql; 126 } 127 128 function _dropAutoIncrement($tabname) 129 { 130 if (strpos($tabname, '.') !== false) { 131 $tarr = explode('.', $tabname); 132 return 'DROP SEQUENCE ' . $tarr[0] . '."s_' . $tarr[1] . '"'; 133 } 134 return 'DROP SEQUENCE s_' . $tabname; 135 } 136 137 138 function _createSuffix($fname, &$ftype, $fnotnull, $fdefault, $fautoinc, $fconstraint, $funsigned) 139 { 140 $suffix = ''; 141 142 if (strlen($fdefault)) { 143 $suffix .= " DEFAULT $fdefault"; 144 } 145 if ($fnotnull) { 146 $suffix .= ' NOT NULL'; 147 } 148 if ($fautoinc) { 149 $this->seqField = $fname; 150 } 151 $fconstraint = preg_replace("/``/", "\"", $fconstraint); 152 if ($fconstraint) { 153 $suffix .= ' ' . $fconstraint; 154 } 155 156 return $suffix; 157 } 158 159 /** 160 * Generate the SQL to create table. Returns an array of sql strings. 161 */ 162 function createTableSQL($tabname, $flds, $tableoptions = array()) 163 { 164 list($lines, $pkey, $idxs) = $this->_GenFields($flds, true); 165 // genfields can return FALSE at times 166 if ($lines == null) { 167 $lines = array(); 168 } 169 170 $taboptions = $this->_Options($tableoptions); 171 $tabname = $this->TableName($tabname); 172 $sql = $this->_TableSQL($tabname, $lines, $pkey, $taboptions); 173 174 if ($this->autoIncrement && !isset($taboptions['DROP'])) { 175 $tsql = $this->_Triggers($tabname, $taboptions); 176 foreach ($tsql as $s) { 177 $sql[] = $s; 178 } 179 } 180 181 if (is_array($idxs)) { 182 foreach ($idxs as $idx => $idxdef) { 183 $sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']); 184 $sql = array_merge($sql, $sql_idxs); 185 } 186 } 187 188 return $sql; 189 } 190 191 192 /* 193 CREATE or replace TRIGGER jaddress_insert 194 before insert on jaddress 195 for each row 196 begin 197 IF ( NEW."seqField" IS NULL OR NEW."seqField" = 0 ) THEN 198 NEW."seqField" = GEN_ID("GEN_tabname", 1); 199 end; 200 */ 201 function _triggers($tabname, $taboptions) 202 { 203 if (!$this->seqField) { 204 return array(); 205 } 206 207 $tab1 = preg_replace('/"/', '', $tabname); 208 if ($this->schema) { 209 $t = strpos($tab1, '.'); 210 if ($t !== false) { 211 $tab = substr($tab1, $t + 1); 212 } else { 213 $tab = $tab1; 214 } 215 $seqField = $this->seqField; 216 $seqname = $this->schema . '.' . $this->seqPrefix . $tab; 217 $trigname = $this->schema . '.t_' . $this->seqPrefix . $tab; 218 } else { 219 $seqField = $this->seqField; 220 $seqname = $this->seqPrefix . $tab1; 221 $trigname = 't_' . $seqname; 222 } 223 224 if (isset($taboptions['DROP'])) { 225 $sql[] = "DROP SEQUENCE $seqname"; 226 } elseif (isset($taboptions['REPLACE'])) { 227 $sql[] = "DROP SEQUENCE \"$seqname\""; 228 $sql[] = "CREATE SEQUENCE \"$seqname\""; 229 $sql[] = "ALTER TRIGGER \"$trigname\" BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID(\"$seqname\", 1); END"; 230 } else { 231 $sql[] = "CREATE SEQUENCE $seqname"; 232 $sql[] = "CREATE TRIGGER $trigname FOR $tabname BEFORE INSERT OR UPDATE AS BEGIN IF ( NEW.$seqField IS NULL OR NEW.$seqField = 0 ) THEN NEW.$seqField = GEN_ID($seqname, 1); END"; 233 } 234 235 $this->seqField = false; 236 return $sql; 237 } 238 239 /** 240 * Change the definition of one column 241 * 242 * @param string $tabname table-name 243 * @param string $flds column-name and type for the changed column 244 * @param string $tableflds Unused 245 * @param array|string $tableoptions Unused 246 * 247 * @return array with SQL strings 248 */ 249 public function alterColumnSQL($tabname, $flds, $tableflds = '', $tableoptions = '') 250 { 251 $tabname = $this->TableName($tabname); 252 $sql = array(); 253 list($lines, , $idxs) = $this->_GenFields($flds); 254 // genfields can return FALSE at times 255 256 if ($lines == null) { 257 $lines = array(); 258 } 259 260 $alter = 'ALTER TABLE ' . $tabname . $this->alterCol . ' '; 261 262 foreach ($lines as $v) { 263 /* 264 * The type must be preceded by the keyword 'TYPE' 265 */ 266 $vExplode = explode(' ', $v); 267 $vExplode = array_filter($vExplode); 268 array_splice($vExplode, 1, 0, array('TYPE')); 269 $v = implode(' ', $vExplode); 270 $sql[] = $alter . $v; 271 } 272 273 if (is_array($idxs)) { 274 foreach ($idxs as $idx => $idxdef) { 275 $sql_idxs = $this->CreateIndexSql($idx, $tabname, $idxdef['cols'], $idxdef['opts']); 276 $sql = array_merge($sql, $sql_idxs); 277 } 278 279 } 280 return $sql; 281 } 282 283 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body