Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
}