Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

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  }