Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/ddl/mssql_sql_generator.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00018 
00029 defined('MOODLE_INTERNAL') || die();
00030 
00031 require_once($CFG->libdir.'/ddl/sql_generator.php');
00032 
00036 
00037 class mssql_sql_generator extends sql_generator {
00038 
00040 
00041     public $statement_end = "\ngo"; // String to be automatically added at the end of each statement
00042 
00043     public $number_type = 'DECIMAL';    // Proper type for NUMBER(x) in this DB
00044 
00045     public $unsigned_allowed = false;    // To define in the generator must handle unsigned information
00046     public $default_for_char = '';      // To define the default to set for NOT NULLs CHARs without default (null=do nothing)
00047 
00048     public $specify_nulls = true;  //To force the generator if NULL clauses must be specified. It shouldn't be necessary
00049                                      //but some mssql drivers require them or everything is created as NOT NULL :-(
00050 
00051     public $sequence_extra_code = false; //Does the generator need to add extra code to generate the sequence fields
00052     public $sequence_name = 'IDENTITY(1,1)'; //Particular name for inline sequences in this generator
00053     public $sequence_only = false; //To avoid to output the rest of the field specs, leaving only the name and the sequence_name variable
00054 
00055     public $enum_inline_code = false; //Does the generator need to add inline code in the column definition
00056 
00057     public $add_table_comments  = false;  // Does the generator need to add code for table comments
00058 
00059     public $concat_character = '+'; //Characters to be used as concatenation operator. If not defined
00060                                   //MySQL CONCAT function will be use
00061 
00062     public $rename_table_sql = "sp_rename 'OLDNAME', 'NEWNAME'"; //SQL sentence to rename one table, both
00063                                   //OLDNAME and NEWNAME are dynamically replaced
00064 
00065     public $rename_column_sql = "sp_rename 'TABLENAME.OLDFIELDNAME', 'NEWFIELDNAME', 'COLUMN'";
00067 
00068     public $drop_index_sql = 'DROP INDEX TABLENAME.INDEXNAME'; //SQL sentence to drop one index
00069                                                                //TABLENAME, INDEXNAME are dynamically replaced
00070 
00071     public $rename_index_sql = "sp_rename 'TABLENAME.OLDINDEXNAME', 'NEWINDEXNAME', 'INDEX'"; //SQL sentence to rename one index
00072                                       //TABLENAME, OLDINDEXNAME, NEWINDEXNAME are dynamically replaced
00073 
00074     public $rename_key_sql = null; //SQL sentence to rename one key
00075                                           //TABLENAME, OLDKEYNAME, NEWKEYNAME are dynamically replaced
00076 
00082     public function getResetSequenceSQL($table) {
00083 
00084         if (is_string($table)) {
00085             $table = new xmldb_table($table);
00086         }
00087 
00088         // From http://msdn.microsoft.com/en-us/library/ms176057.aspx
00089         $value = (int)$this->mdb->get_field_sql('SELECT MAX(id) FROM {'. $table->getName() . '}');
00090         if ($value == 0) {
00091             $value = 1;
00092         }
00093         return array("DBCC CHECKIDENT ('" . $this->getTableName($table) . "', RESEED, $value)");
00094     }
00095 
00104     public function getTableName(xmldb_table $xmldb_table, $quoted=true) {
00106         if ($this->temptables->is_temptable($xmldb_table->getName())) {
00107             $tablename = $this->temptables->get_correct_name($xmldb_table->getName());
00108         } else {
00109             $tablename = $this->prefix . $xmldb_table->getName();
00110         }
00111 
00113         if ($quoted) {
00114             $tablename = $this->getEncQuoted($tablename);
00115         }
00116 
00117         return $tablename;
00118     }
00119 
00120 
00125     public function getCreateTempTableSQL($xmldb_table) {
00126         $this->temptables->add_temptable($xmldb_table->getName());
00127         $sqlarr = $this->getCreateTableSQL($xmldb_table);
00128         return $sqlarr;
00129     }
00130 
00135     public function getDropTempTableSQL($xmldb_table) {
00136         $sqlarr = $this->getDropTableSQL($xmldb_table);
00137         $this->temptables->delete_temptable($xmldb_table->getName());
00138         return $sqlarr;
00139     }
00140 
00144     public function getTypeSQL($xmldb_type, $xmldb_length=null, $xmldb_decimals=null) {
00145 
00146         switch ($xmldb_type) {
00147             case XMLDB_TYPE_INTEGER:    // From http://msdn.microsoft.com/library/en-us/tsqlref/ts_da-db_7msw.asp?frame=true
00148                 if (empty($xmldb_length)) {
00149                     $xmldb_length = 10;
00150                 }
00151                 if ($xmldb_length > 9) {
00152                     $dbtype = 'BIGINT';
00153                 } else if ($xmldb_length > 4) {
00154                     $dbtype = 'INTEGER';
00155                 } else {
00156                     $dbtype = 'SMALLINT';
00157                 }
00158                 break;
00159             case XMLDB_TYPE_NUMBER:
00160                 $dbtype = $this->number_type;
00161                 if (!empty($xmldb_length)) {
00163                     if ($xmldb_length > 38) {
00164                         $xmldb_length = 38;
00165                     }
00166                     $dbtype .= '(' . $xmldb_length;
00167                     if (!empty($xmldb_decimals)) {
00168                         $dbtype .= ',' . $xmldb_decimals;
00169                     }
00170                     $dbtype .= ')';
00171                 }
00172                 break;
00173             case XMLDB_TYPE_FLOAT:
00174                 $dbtype = 'FLOAT';
00175                 if (!empty($xmldb_decimals)) {
00176                     if ($xmldb_decimals < 6) {
00177                         $dbtype = 'REAL';
00178                     }
00179                 }
00180                 break;
00181             case XMLDB_TYPE_CHAR:
00182                 $dbtype = 'NVARCHAR';
00183                 if (empty($xmldb_length)) {
00184                     $xmldb_length='255';
00185                 }
00186                 $dbtype .= '(' . $xmldb_length . ')';
00187                 break;
00188             case XMLDB_TYPE_TEXT:
00189                 $dbtype = 'NTEXT';
00190                 break;
00191             case XMLDB_TYPE_BINARY:
00192                 $dbtype = 'IMAGE';
00193                 break;
00194             case XMLDB_TYPE_DATETIME:
00195                 $dbtype = 'DATETIME';
00196                 break;
00197         }
00198         return $dbtype;
00199     }
00200 
00206     public function getDropFieldSQL($xmldb_table, $xmldb_field) {
00207         $results = array();
00208 
00210         $tablename = $this->getTableName($xmldb_table);
00211         $fieldname = $this->getEncQuoted($xmldb_field->getName());
00212 
00214         if ($defaultname = $this->getDefaultConstraintName($xmldb_table, $xmldb_field)) {
00215             $results[] = 'ALTER TABLE ' . $tablename . ' DROP CONSTRAINT ' . $defaultname;
00216         }
00217 
00219         if ($drop_check = $this->getDropEnumSQL($xmldb_table, $xmldb_field)) {
00220             $results = array_merge($results, $drop_check);
00221         }
00222 
00224         $results[] = 'ALTER TABLE ' . $tablename . ' DROP COLUMN ' . $fieldname;
00225 
00226         return $results;
00227     }
00228 
00235     public function getRenameFieldSQL($xmldb_table, $xmldb_field, $newname) {
00236 
00237         $results = array();  //Array where all the sentences will be stored
00238 
00246         if ($xmldb_field->getName() == 'id') {
00247             return array();
00248         }
00249 
00251         $results = array_merge($results, parent::getRenameFieldSQL($xmldb_table, $xmldb_field, $newname));
00252 
00253         return $results;
00254     }
00255 
00259     public function getRenameTableExtraSQL($xmldb_table, $newname) {
00260 
00261         $results = array();
00262 
00263         $newt = new xmldb_table($newname); //Temporal table for name calculations
00264 
00265         $oldtablename = $this->getTableName($xmldb_table);
00266         $newtablename = $this->getTableName($newt);
00267 
00269         $oldconstraintprefix = $this->getNameForObject($xmldb_table->getName(), '');
00270         $newconstraintprefix = $this->getNameForObject($newt->getName(), '', '');
00271 
00272         if ($constraints = $this->getCheckConstraintsFromDB($xmldb_table)) {
00273             foreach ($constraints as $constraint) {
00275                 $results[] = 'ALTER TABLE ' . $newtablename . ' DROP CONSTRAINT ' . $constraint->name;
00276             }
00277         }
00278 
00279         return $results;
00280     }
00281 
00285     public function getAlterFieldSQL($xmldb_table, $xmldb_field, $skip_type_clause = NULL, $skip_default_clause = NULL, $skip_notnull_clause = NULL) {
00286 
00287         $results = array(); 
00288 
00290         $tablename = $xmldb_table->getName();
00291         $fieldname = $xmldb_field->getName();
00292 
00294         $meta = $this->mdb->get_columns($tablename);
00295         $metac = $meta[$fieldname];
00296         $oldmetatype = $metac->meta_type;
00297 
00298         $oldlength = $metac->max_length;
00299         $olddecimals = empty($metac->scale) ? null : $metac->scale;
00300         $oldnotnull = empty($metac->not_null) ? false : $metac->not_null;
00301         //$olddefault = empty($metac->has_default) ? null : strtok($metac->default_value, ':');
00302 
00303         $typechanged = true;  //By default, assume that the column type has changed
00304         $lengthchanged = true;  //By default, assume that the column length has changed
00305 
00307         if (($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I') ||
00308             ($xmldb_field->getType() == XMLDB_TYPE_NUMBER  && $oldmetatype == 'N') ||
00309             ($xmldb_field->getType() == XMLDB_TYPE_FLOAT   && $oldmetatype == 'F') ||
00310             ($xmldb_field->getType() == XMLDB_TYPE_CHAR    && $oldmetatype == 'C') ||
00311             ($xmldb_field->getType() == XMLDB_TYPE_TEXT    && $oldmetatype == 'X') ||
00312             ($xmldb_field->getType() == XMLDB_TYPE_BINARY  && $oldmetatype == 'B')) {
00313             $typechanged = false;
00314         }
00315 
00318         if ($xmldb_field->getType() == XMLDB_TYPE_INTEGER && $oldmetatype == 'I') {
00319             if ($xmldb_field->getLength() > 9) { // Convert our new lenghts to detailed meta types
00320                 $newmssqlinttype = 'I8';
00321             } else if ($xmldb_field->getLength() > 4) {
00322                 $newmssqlinttype = 'I';
00323             } else {
00324                 $newmssqlinttype = 'I2';
00325             }
00326             if ($metac->type == 'bigint') { // Convert current DB type to detailed meta type (our metatype is not enough!)
00327                 $oldmssqlinttype = 'I8';
00328             } else if ($metac->type == 'smallint') {
00329                 $oldmssqlinttype = 'I2';
00330             } else {
00331                 $oldmssqlinttype = 'I';
00332             }
00333             if ($newmssqlinttype != $oldmssqlinttype) { // Compare new and old meta types
00334                 $typechanged = true; // Change in meta type means change in type at all effects
00335             }
00336         }
00337 
00340         if ($xmldb_field->getLength() == $oldlength) {
00341             $lengthchanged = false;
00342         }
00343 
00345         if ($typechanged || $lengthchanged) {
00346             $results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field);
00347         }
00348 
00352         $multiple_alter_stmt = array();
00353         $targettype = $xmldb_field->getType();
00354 
00355         if ($targettype == XMLDB_TYPE_TEXT && $oldmetatype == 'I') { // integer to text
00356             $multiple_alter_stmt[0] = new stdClass;                  // needs conversion to varchar
00357             $multiple_alter_stmt[0]->type = XMLDB_TYPE_CHAR;
00358             $multiple_alter_stmt[0]->length = 255;
00359 
00360         } else if ($targettype == XMLDB_TYPE_TEXT && $oldmetatype == 'N') { // decimal to text
00361             $multiple_alter_stmt[0] = new stdClass;                         // needs conversion to varchar
00362             $multiple_alter_stmt[0]->type = XMLDB_TYPE_CHAR;
00363             $multiple_alter_stmt[0]->length = 255;
00364 
00365         } else if ($targettype == XMLDB_TYPE_TEXT && $oldmetatype == 'F') { // float to text
00366             $multiple_alter_stmt[0] = new stdClass;                         // needs conversion to varchar
00367             $multiple_alter_stmt[0]->type = XMLDB_TYPE_CHAR;
00368             $multiple_alter_stmt[0]->length = 255;
00369 
00370         } else if ($targettype == XMLDB_TYPE_INTEGER && $oldmetatype == 'X') { // text to integer
00371             $multiple_alter_stmt[0] = new stdClass;                            // needs conversion to varchar
00372             $multiple_alter_stmt[0]->type = XMLDB_TYPE_CHAR;
00373             $multiple_alter_stmt[0]->length = 255;
00374             $multiple_alter_stmt[1] = new stdClass;                            // and also needs conversion to decimal
00375             $multiple_alter_stmt[1]->type = XMLDB_TYPE_NUMBER;                 // without decimal positions
00376             $multiple_alter_stmt[1]->length = 10;
00377 
00378         } else if ($targettype == XMLDB_TYPE_NUMBER && $oldmetatype == 'X') { // text to decimal
00379             $multiple_alter_stmt[0] = new stdClass;                           // needs conversion to varchar
00380             $multiple_alter_stmt[0]->type = XMLDB_TYPE_CHAR;
00381             $multiple_alter_stmt[0]->length = 255;
00382 
00383         } else if ($targettype ==  XMLDB_TYPE_FLOAT && $oldmetatype == 'X') { // text to float
00384             $multiple_alter_stmt[0] = new stdClass;                           // needs conversion to varchar
00385             $multiple_alter_stmt[0]->type = XMLDB_TYPE_CHAR;
00386             $multiple_alter_stmt[0]->length = 255;
00387         }
00388 
00390         if (empty($multiple_alter_stmt)) { // Direct implicit conversion allowed, launch it
00391             $results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, NULL, true, NULL));
00392 
00393         } else { // Direct implicit conversion forbidden, use the intermediate ones
00394             $final_type = $xmldb_field->getType(); // Save final type and length
00395             $final_length = $xmldb_field->getLength();
00396             foreach ($multiple_alter_stmt as $alter) {
00397                 $xmldb_field->setType($alter->type);  // Put our intermediate type and length and alter to it
00398                 $xmldb_field->setLength($alter->length);
00399                 $results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, NULL, true, NULL));
00400             }
00401             $xmldb_field->setType($final_type); // Set the final type and length and alter to it
00402             $xmldb_field->setLength($final_length);
00403             $results = array_merge($results, parent::getAlterFieldSQL($xmldb_table, $xmldb_field, NULL, true, NULL));
00404         }
00405 
00407         if ($typechanged || $lengthchanged) {
00408             $results = array_merge($results, $this->getCreateDefaultSQL($xmldb_table, $xmldb_field));
00409         }
00410 
00412         return $results;
00413     }
00414 
00418     public function getModifyDefaultSQL($xmldb_table, $xmldb_field) {
00421 
00422         $results = array();
00423 
00425         if ($xmldb_field->getDefault() === null) {
00426             $results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field); //Drop but, under some circumstances, re-enable
00427             $default_clause = $this->getDefaultClause($xmldb_field);
00428             if ($default_clause) { //If getDefaultClause() it must have one default, create it
00429                 $results = array_merge($results, $this->getCreateDefaultSQL($xmldb_table, $xmldb_field)); //Create/modify
00430             }
00431         } else {
00432             $results = $this->getDropDefaultSQL($xmldb_table, $xmldb_field); //Drop (only if exists)
00433             $results = array_merge($results, $this->getCreateDefaultSQL($xmldb_table, $xmldb_field)); //Create/modify
00434         }
00435 
00436         return $results;
00437     }
00438 
00445     public function getDropEnumSQL($xmldb_table, $xmldb_field) {
00447         if ($check_constraints = $this->getCheckConstraintsFromDB($xmldb_table, $xmldb_field)) {
00448             $check_constraint = array_shift($check_constraints); 
00449             $constraint_name = strtolower($check_constraint->name); 
00450 
00451             return array('ALTER TABLE ' . $this->getTableName($xmldb_table) .
00452                      ' DROP CONSTRAINT ' . $constraint_name);
00453         } else { 
00454             return array();
00455         }
00456     }
00457 
00462     public function getCreateDefaultSQL($xmldb_table, $xmldb_field) {
00464 
00465         $results = array();
00466 
00468         $tablename = $this->getTableName($xmldb_table);
00469         $fieldname = $this->getEncQuoted($xmldb_field->getName());
00470 
00472         $default_clause = $this->getDefaultClause($xmldb_field);
00473         if ($default_clause) {
00475             $sql = 'ALTER TABLE ' . $tablename . ' ADD' . $default_clause . ' FOR ' . $fieldname;
00476             $results[] = $sql;
00477         }
00478 
00479         return $results;
00480     }
00481 
00486     public function getDropDefaultSQL($xmldb_table, $xmldb_field) {
00488 
00489         $results = array();
00490 
00492         $tablename = $this->getTableName($xmldb_table);
00493         $fieldname = $this->getEncQuoted($xmldb_field->getName());
00494 
00496         if ($defaultname = $this->getDefaultConstraintName($xmldb_table, $xmldb_field)) {
00497             $results[] = 'ALTER TABLE ' . $tablename . ' DROP CONSTRAINT ' . $defaultname;
00498         }
00499 
00500         return $results;
00501     }
00502 
00508     public function getDefaultConstraintName($xmldb_table, $xmldb_field) {
00509 
00511         $tablename = $this->getTableName($xmldb_table);
00512         $fieldname = $xmldb_field->getName();
00513 
00515         if ($default = $this->mdb->get_record_sql("SELECT id, object_name(cdefault) AS defaultconstraint
00516                                                      FROM syscolumns
00517                                                     WHERE id = object_id(?)
00518                                                           AND name = ?", array($tablename, $fieldname))) {
00519             return $default->defaultconstraint;
00520         } else {
00521             return false;
00522         }
00523     }
00524 
00535     public function getCheckConstraintsFromDB($xmldb_table, $xmldb_field = null) {
00536 
00537 
00538         $results = array();
00539 
00540         $tablename = $this->getTableName($xmldb_table);
00541 
00542         if ($constraints = $this->mdb->get_records_sql("SELECT o.name, c.text AS description
00543                                                           FROM sysobjects o,
00544                                                                sysobjects p,
00545                                                                syscomments c
00546                                                          WHERE p.id = o.parent_obj
00547                                                                AND o.id = c.id
00548                                                                AND o.xtype = 'C'
00549                                                                AND p.name = ?", array($tablename))) {
00550             foreach ($constraints as $constraint) {
00551                 $results[$constraint->name] = $constraint;
00552             }
00553         }
00554 
00556         if ($xmldb_field) {
00557             $filtered_results = array();
00558             $filter = $xmldb_field->getName();
00560             foreach ($results as $key => $result) {
00561                 $description = trim(preg_replace('/[\(\)]/', '',  $result->description));   // Parenthesis out & trim
00563                 if (preg_match("/^\[{$filter}\]/i", $description)) {
00564                     $filtered_results[$key] = $result;
00565                 }
00566             }
00568             $results =  $filtered_results;
00569         }
00570 
00571         return $results;
00572     }
00573 
00589     public function getNameForObject($tablename, $fields, $suffix='') {
00590         if ($this->temptables->is_temptable($tablename)) { // Is temp table, inject random field names
00591             $random = strtolower(random_string(12)); // 12cc to be split in 4 parts
00592             $fields = $fields . ', ' . implode(', ', str_split($random, 3));
00593         }
00594         return parent::getNameForObject($tablename, $fields, $suffix); // Delegate to parent (common) algorithm
00595     }
00596 
00602     public function isNameInUse($object_name, $type, $table_name) {
00603         switch($type) {
00604             case 'seq':
00605             case 'trg':
00606             case 'pk':
00607             case 'uk':
00608             case 'fk':
00609             case 'ck':
00610                 if ($check = $this->mdb->get_records_sql("SELECT name
00611                                                             FROM sysobjects
00612                                                            WHERE lower(name) = ?", array(strtolower($object_name)))) {
00613                     return true;
00614                 }
00615                 break;
00616             case 'ix':
00617             case 'uix':
00618                 if ($check = $this->mdb->get_records_sql("SELECT name
00619                                                             FROM sysindexes
00620                                                            WHERE lower(name) = ?", array(strtolower($object_name)))) {
00621                     return true;
00622                 }
00623                 break;
00624         }
00625         return false; //No name in use found
00626     }
00627 
00631     public function getCommentSQL($xmldb_table) {
00632         return array();
00633     }
00634 
00635     public function addslashes($s) {
00636         // do not use php addslashes() because it depends on PHP quote settings!
00637         $s = str_replace("'",  "''", $s);
00638         return $s;
00639     }
00640 
00644     public static function getReservedWords() {
00647         $reserved_words = array (
00648             'add', 'all', 'alter', 'and', 'any', 'as', 'asc', 'authorization',
00649             'avg', 'backup', 'begin', 'between', 'break', 'browse', 'bulk',
00650             'by', 'cascade', 'case', 'check', 'checkpoint', 'close', 'clustered',
00651             'coalesce', 'collate', 'column', 'commit', 'committed', 'compute',
00652             'confirm', 'constraint', 'contains', 'containstable', 'continue',
00653             'controlrow', 'convert', 'count', 'create', 'cross', 'current',
00654             'current_date', 'current_time', 'current_timestamp', 'current_user',
00655             'cursor', 'database', 'dbcc', 'deallocate', 'declare', 'default', 'delete',
00656             'deny', 'desc', 'disk', 'distinct', 'distributed', 'double', 'drop', 'dummy',
00657             'dump', 'else', 'end', 'errlvl', 'errorexit', 'escape', 'except', 'exec',
00658             'execute', 'exists', 'exit', 'external', 'fetch', 'file', 'fillfactor', 'floppy',
00659             'for', 'foreign', 'freetext', 'freetexttable', 'from', 'full', 'function',
00660             'goto', 'grant', 'group', 'having', 'holdlock', 'identity', 'identitycol',
00661             'identity_insert', 'if', 'in', 'index', 'inner', 'insert', 'intersect', 'into',
00662             'is', 'isolation', 'join', 'key', 'kill', 'left', 'level', 'like', 'lineno',
00663             'load', 'max', 'min', 'mirrorexit', 'national', 'nocheck', 'nonclustered',
00664             'not', 'null', 'nullif', 'of', 'off', 'offsets', 'on', 'once', 'only', 'open',
00665             'opendatasource', 'openquery', 'openrowset', 'openxml', 'option', 'or', 'order',
00666             'outer', 'over', 'percent', 'perm', 'permanent', 'pipe', 'pivot', 'plan', 'precision',
00667             'prepare', 'primary', 'print', 'privileges', 'proc', 'procedure', 'processexit',
00668             'public', 'raiserror', 'read', 'readtext', 'reconfigure', 'references',
00669             'repeatable', 'replication', 'restore', 'restrict', 'return', 'revoke',
00670             'right', 'rollback', 'rowcount', 'rowguidcol', 'rule', 'save', 'schema',
00671             'select', 'serializable', 'session_user', 'set', 'setuser', 'shutdown', 'some',
00672             'statistics', 'sum', 'system_user', 'table', 'tape', 'temp', 'temporary',
00673             'textsize', 'then', 'to', 'top', 'tran', 'transaction', 'trigger', 'truncate',
00674             'tsequal', 'uncommitted', 'union', 'unique', 'update', 'updatetext', 'use',
00675             'user', 'values', 'varying', 'view', 'waitfor', 'when', 'where', 'while',
00676             'with', 'work', 'writetext'
00677         );
00678         return $reserved_words;
00679     }
00680 }
 All Data Structures Namespaces Files Functions Variables Enumerations