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 Microsoft SQL Server (mssql)
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
/*
23
In ADOdb, named quotes for MS SQL Server use ". From the MSSQL Docs:
24
 
25
	Note Delimiters are for identifiers only. Delimiters cannot be used for keywords,
26
	whether or not they are marked as reserved in SQL Server.
27
 
28
	Quoted identifiers are delimited by double quotation marks ("):
29
	SELECT * FROM "Blanks in Table Name"
30
 
31
	Bracketed identifiers are delimited by brackets ([ ]):
32
	SELECT * FROM [Blanks In Table Name]
33
 
34
	Quoted identifiers are valid only when the QUOTED_IDENTIFIER option is set to ON. By default,
35
	the Microsoft OLE DB Provider for SQL Server and SQL Server ODBC driver set QUOTED_IDENTIFIER ON
36
	when they connect.
37
 
38
	In Transact-SQL, the option can be set at various levels using SET QUOTED_IDENTIFIER,
39
	the quoted identifier option of sp_dboption, or the user options option of sp_configure.
40
 
41
	When SET ANSI_DEFAULTS is ON, SET QUOTED_IDENTIFIER is enabled.
42
 
43
	Syntax
44
 
45
		SET QUOTED_IDENTIFIER { ON | OFF }
46
 
47
 
48
*/
49
 
50
// security - hide paths
51
if (!defined('ADODB_DIR')) die();
52
 
53
class ADODB2_mssql extends ADODB_DataDict {
54
	var $databaseType = 'mssql';
55
	var $dropIndex = 'DROP INDEX %2$s.%1$s';
56
	var $renameTable = "EXEC sp_rename '%s','%s'";
57
	var $renameColumn = "EXEC sp_rename '%s.%s','%s'";
58
 
59
	var $typeX = 'TEXT';  ## Alternatively, set it to VARCHAR(4000)
60
	var $typeXL = 'TEXT';
61
 
62
	//var $alterCol = ' ALTER COLUMN ';
63
 
64
	function MetaType($t,$len=-1,$fieldobj=false)
65
	{
66
		if (is_object($t)) {
67
			$fieldobj = $t;
68
			$t = $fieldobj->type;
69
			$len = $fieldobj->max_length;
70
		}
71
 
72
		$t = strtoupper($t);
73
 
74
		if (array_key_exists($t,$this->connection->customActualTypes))
75
			return  $this->connection->customActualTypes[$t];
76
 
77
		$len = -1; // mysql max_length is not accurate
78
		switch ($t) {
79
		case 'R':
80
		case 'INT':
81
		case 'INTEGER': return  'I';
82
		case 'BIT':
83
		case 'TINYINT': return  'I1';
84
		case 'SMALLINT': return 'I2';
85
		case 'BIGINT':  return  'I8';
86
		case 'SMALLDATETIME': return 'T';
87
		case 'REAL':
88
		case 'FLOAT': return 'F';
89
		default: return parent::MetaType($t,$len,$fieldobj);
90
		}
91
	}
92
 
93
	function ActualType($meta)
94
	{
95
 
96
		$meta = strtoupper($meta);
97
 
98
		/*
99
		* Add support for custom meta types. We do this
100
		* first, that allows us to override existing types
101
		*/
102
		if (isset($this->connection->customMetaTypes[$meta]))
103
			return $this->connection->customMetaTypes[$meta]['actual'];
104
 
105
		switch(strtoupper($meta)) {
106
 
107
		case 'C': return 'VARCHAR';
108
		case 'XL': return (isset($this)) ? $this->typeXL : 'TEXT';
109
		case 'X': return (isset($this)) ? $this->typeX : 'TEXT'; ## could be varchar(8000), but we want compat with oracle
110
		case 'C2': return 'NVARCHAR';
111
		case 'X2': return 'NTEXT';
112
 
113
		case 'B': return 'IMAGE';
114
 
115
		case 'D': return 'DATETIME';
116
 
117
		case 'TS':
118
		case 'T': return 'DATETIME';
119
		case 'L': return 'BIT';
120
 
121
		case 'R':
122
		case 'I': return 'INT';
123
		case 'I1': return 'TINYINT';
124
		case 'I2': return 'SMALLINT';
125
		case 'I4': return 'INT';
126
		case 'I8': return 'BIGINT';
127
 
128
		case 'F': return 'REAL';
129
		case 'N': return 'NUMERIC';
130
		default:
131
			return $meta;
132
		}
133
	}
134
 
135
 
136
	function AddColumnSQL($tabname, $flds)
137
	{
138
		$tabname = $this->TableName ($tabname);
139
		$f = array();
140
		list($lines,$pkey) = $this->_GenFields($flds);
141
		$s = "ALTER TABLE $tabname $this->addCol";
142
		foreach($lines as $v) {
143
			$f[] = "\n $v";
144
		}
145
		$s .= implode(', ',$f);
146
		$sql[] = $s;
147
		return $sql;
148
	}
149
 
150
	/*
151
	function AlterColumnSQL($tabname, $flds, $tableflds='', $tableoptions='')
152
	{
153
		$tabname = $this->TableName ($tabname);
154
		$sql = array();
155
		list($lines,$pkey) = $this->_GenFields($flds);
156
		foreach($lines as $v) {
157
			$sql[] = "ALTER TABLE $tabname $this->alterCol $v";
158
		}
159
 
160
		return $sql;
161
	}
162
	*/
163
 
164
	function DropColumnSQL($tabname, $flds, $tableflds='',$tableoptions='')
165
	{
166
		$tabname = $this->TableName ($tabname);
167
		if (!is_array($flds))
168
			$flds = explode(',',$flds);
169
		$f = array();
170
		$s = 'ALTER TABLE ' . $tabname;
171
		foreach($flds as $v) {
172
			$f[] = "\n$this->dropCol ".$this->NameQuote($v);
173
		}
174
		$s .= implode(', ',$f);
175
		$sql[] = $s;
176
		return $sql;
177
	}
178
 
179
	// return string must begin with space
180
	function _CreateSuffix($fname,&$ftype,$fnotnull,$fdefault,$fautoinc,$fconstraint,$funsigned)
181
	{
182
		$suffix = '';
183
		if (strlen($fdefault)) $suffix .= " DEFAULT $fdefault";
184
		if ($fautoinc) $suffix .= ' IDENTITY(1,1)';
185
		if ($fnotnull) $suffix .= ' NOT NULL';
186
		else if ($suffix == '') $suffix .= ' NULL';
187
		if ($fconstraint) $suffix .= ' '.$fconstraint;
188
		return $suffix;
189
	}
190
 
191
	/*
192
CREATE TABLE
193
    [ database_name.[ owner ] . | owner. ] table_name
194
    ( { < column_definition >
195
        | column_name AS computed_column_expression
196
        | < table_constraint > ::= [ CONSTRAINT constraint_name ] }
197
 
198
            | [ { PRIMARY KEY | UNIQUE } [ ,...n ]
199
    )
200
 
201
[ ON { filegroup | DEFAULT } ]
202
[ TEXTIMAGE_ON { filegroup | DEFAULT } ]
203
 
204
< column_definition > ::= { column_name data_type }
205
    [ COLLATE < collation_name > ]
206
    [ [ DEFAULT constant_expression ]
207
        | [ IDENTITY [ ( seed , increment ) [ NOT FOR REPLICATION ] ] ]
208
    ]
209
    [ ROWGUIDCOL]
210
    [ < column_constraint > ] [ ...n ]
211
 
212
< column_constraint > ::= [ CONSTRAINT constraint_name ]
213
    { [ NULL | NOT NULL ]
214
        | [ { PRIMARY KEY | UNIQUE }
215
            [ CLUSTERED | NONCLUSTERED ]
216
            [ WITH FILLFACTOR = fillfactor ]
217
            [ON {filegroup | DEFAULT} ] ]
218
        ]
219
        | [ [ FOREIGN KEY ]
220
            REFERENCES ref_table [ ( ref_column ) ]
221
            [ ON DELETE { CASCADE | NO ACTION } ]
222
            [ ON UPDATE { CASCADE | NO ACTION } ]
223
            [ NOT FOR REPLICATION ]
224
        ]
225
        | CHECK [ NOT FOR REPLICATION ]
226
        ( logical_expression )
227
    }
228
 
229
< table_constraint > ::= [ CONSTRAINT constraint_name ]
230
    { [ { PRIMARY KEY | UNIQUE }
231
        [ CLUSTERED | NONCLUSTERED ]
232
        { ( column [ ASC | DESC ] [ ,...n ] ) }
233
        [ WITH FILLFACTOR = fillfactor ]
234
        [ ON { filegroup | DEFAULT } ]
235
    ]
236
    | FOREIGN KEY
237
        [ ( column [ ,...n ] ) ]
238
        REFERENCES ref_table [ ( ref_column [ ,...n ] ) ]
239
        [ ON DELETE { CASCADE | NO ACTION } ]
240
        [ ON UPDATE { CASCADE | NO ACTION } ]
241
        [ NOT FOR REPLICATION ]
242
    | CHECK [ NOT FOR REPLICATION ]
243
        ( search_conditions )
244
    }
245
 
246
 
247
	*/
248
 
249
	/*
250
	CREATE [ UNIQUE ] [ CLUSTERED | NONCLUSTERED ] INDEX index_name
251
    ON { table | view } ( column [ ASC | DESC ] [ ,...n ] )
252
		[ WITH < index_option > [ ,...n] ]
253
		[ ON filegroup ]
254
		< index_option > :: =
255
		    { PAD_INDEX |
256
		        FILLFACTOR = fillfactor |
257
		        IGNORE_DUP_KEY |
258
		        DROP_EXISTING |
259
		    STATISTICS_NORECOMPUTE |
260
		    SORT_IN_TEMPDB
261
		}
262
*/
263
	function _IndexSQL($idxname, $tabname, $flds, $idxoptions)
264
	{
265
		$sql = array();
266
 
267
		if ( isset($idxoptions['REPLACE']) || isset($idxoptions['DROP']) ) {
268
			$sql[] = sprintf ($this->dropIndex, $idxname, $tabname);
269
			if ( isset($idxoptions['DROP']) )
270
				return $sql;
271
		}
272
 
273
		if ( empty ($flds) ) {
274
			return $sql;
275
		}
276
 
277
		$unique = isset($idxoptions['UNIQUE']) ? ' UNIQUE' : '';
278
		$clustered = isset($idxoptions['CLUSTERED']) ? ' CLUSTERED' : '';
279
 
280
		if ( is_array($flds) )
281
			$flds = implode(', ',$flds);
282
		$s = 'CREATE' . $unique . $clustered . ' INDEX ' . $idxname . ' ON ' . $tabname . ' (' . $flds . ')';
283
 
284
		if ( isset($idxoptions[$this->upperName]) )
285
			$s .= $idxoptions[$this->upperName];
286
 
287
 
288
		$sql[] = $s;
289
 
290
		return $sql;
291
	}
292
 
293
 
294
	function _GetSize($ftype, $ty, $fsize, $fprec, $options=false)
295
	{
296
		switch ($ftype) {
297
		case 'INT':
298
		case 'SMALLINT':
299
		case 'TINYINT':
300
		case 'BIGINT':
301
			return $ftype;
302
		}
303
    	if ($ty == 'T') return $ftype;
304
    	return parent::_GetSize($ftype, $ty, $fsize, $fprec, $options);
305
 
306
	}
307
}