TYPO3 CMS  TYPO3_6-2
adodb-xmlschema.inc.php
Go to the documentation of this file.
1 <?php
2 // Copyright (c) 2004 ars Cognita Inc., all rights reserved
3 /* ******************************************************************************
4  Released under both BSD license and Lesser GPL library license.
5  Whenever there is any discrepancy between the two licenses,
6  the BSD license will take precedence.
7 *******************************************************************************/
21 function _file_get_contents($file)
22 {
23  if (function_exists('file_get_contents')) return file_get_contents($file);
24 
25  $f = fopen($file,'r');
26  if (!$f) return '';
27  $t = '';
28 
29  while ($s = fread($f,100000)) $t .= $s;
30  fclose($f);
31  return $t;
32 }
33 
34 
38 if( !defined( 'XMLS_DEBUG' ) ) {
39  define( 'XMLS_DEBUG', FALSE );
40 }
41 
45 if( !defined( 'XMLS_PREFIX' ) ) {
46  define( 'XMLS_PREFIX', '%%P' );
47 }
48 
52 if( !defined( 'XMLS_PREFIX_MAXLEN' ) ) {
53  define( 'XMLS_PREFIX_MAXLEN', 10 );
54 }
55 
59 if( !defined( 'XMLS_EXECUTE_INLINE' ) ) {
60  define( 'XMLS_EXECUTE_INLINE', FALSE );
61 }
62 
66 if( !defined( 'XMLS_CONTINUE_ON_ERROR' ) ) {
67  define( 'XMLS_CONTINUE_ON_ERROR', FALSE );
68 }
69 
73 if( !defined( 'XMLS_SCHEMA_VERSION' ) ) {
74  define( 'XMLS_SCHEMA_VERSION', '0.2' );
75 }
76 
80 if( !defined( 'XMLS_DEFAULT_SCHEMA_VERSION' ) ) {
81  define( 'XMLS_DEFAULT_SCHEMA_VERSION', '0.1' );
82 }
83 
87 if( !defined( 'XMLS_DEFAULT_UPGRADE_METHOD' ) ) {
88  define( 'XMLS_DEFAULT_UPGRADE_METHOD', 'ALTER' );
89 }
90 
94 if( !defined( '_ADODB_LAYER' ) ) {
95  require( 'adodb.inc.php' );
96  require( 'adodb-datadict.inc.php' );
97 }
98 
106 class dbObject {
107 
111  var $parent;
112 
117 
121  function dbObject( &$parent, $attributes = NULL ) {
122  $this->parent = $parent;
123  }
124 
130  function _tag_open( &$parser, $tag, $attributes ) {
131 
132  }
133 
139  function _tag_cdata( &$parser, $cdata ) {
140 
141  }
142 
148  function _tag_close( &$parser, $tag ) {
149 
150  }
151 
152  function create(&$xmls) {
153  return array();
154  }
155 
159  function destroy() {
160  unset( $this );
161  }
162 
170  function supportedPlatform( $platform = NULL ) {
171  return is_object( $this->parent ) ? $this->parent->supportedPlatform( $platform ) : TRUE;
172  }
173 
180  function prefix( $name = '' ) {
181  return is_object( $this->parent ) ? $this->parent->prefix( $name ) : $name;
182  }
183 
190  function FieldID( $field ) {
191  return strtoupper( preg_replace( '/^`(.+)`$/', '$1', $field ) );
192  }
193 }
194 
206 class dbTable extends dbObject {
207 
211  var $name;
212 
216  var $fields = array();
217 
221  var $indexes = array();
222 
226  var $opts = array();
227 
232 
238 
243  var $drop_field = array();
244 
251  function dbTable( &$parent, $attributes = NULL ) {
252  $this->parent = $parent;
253  $this->name = $this->prefix($attributes['NAME']);
254  }
255 
262  function _tag_open( &$parser, $tag, $attributes ) {
263  $this->currentElement = strtoupper( $tag );
264 
265  switch( $this->currentElement ) {
266  case 'INDEX':
267  if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
268  xml_set_object( $parser, $this->addIndex( $attributes ) );
269  }
270  break;
271  case 'DATA':
272  if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
273  xml_set_object( $parser, $this->addData( $attributes ) );
274  }
275  break;
276  case 'DROP':
277  $this->drop();
278  break;
279  case 'FIELD':
280  // Add a field
281  $fieldName = $attributes['NAME'];
282  $fieldType = $attributes['TYPE'];
283  $fieldSize = isset( $attributes['SIZE'] ) ? $attributes['SIZE'] : NULL;
284  $fieldOpts = isset( $attributes['OPTS'] ) ? $attributes['OPTS'] : NULL;
285 
286  $this->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts );
287  break;
288  case 'KEY':
289  case 'NOTNULL':
290  case 'AUTOINCREMENT':
291  // Add a field option
292  $this->addFieldOpt( $this->current_field, $this->currentElement );
293  break;
294  case 'DEFAULT':
295  // Add a field option to the table object
296 
297  // Work around ADOdb datadict issue that misinterprets empty strings.
298  if( $attributes['VALUE'] == '' ) {
299  $attributes['VALUE'] = " '' ";
300  }
301 
302  $this->addFieldOpt( $this->current_field, $this->currentElement, $attributes['VALUE'] );
303  break;
304  case 'DEFDATE':
305  case 'DEFTIMESTAMP':
306  // Add a field option to the table object
307  $this->addFieldOpt( $this->current_field, $this->currentElement );
308  break;
309  default:
310  // print_r( array( $tag, $attributes ) );
311  }
312  }
313 
319  function _tag_cdata( &$parser, $cdata ) {
320  switch( $this->currentElement ) {
321  // Table constraint
322  case 'CONSTRAINT':
323  if( isset( $this->current_field ) ) {
324  $this->addFieldOpt( $this->current_field, $this->currentElement, $cdata );
325  } else {
326  $this->addTableOpt( $cdata );
327  }
328  break;
329  // Table option
330  case 'OPT':
331  $this->addTableOpt( $cdata );
332  break;
333  default:
334 
335  }
336  }
337 
343  function _tag_close( &$parser, $tag ) {
344  $this->currentElement = '';
345 
346  switch( strtoupper( $tag ) ) {
347  case 'TABLE':
348  $this->parent->addSQL( $this->create( $this->parent ) );
349  xml_set_object( $parser, $this->parent );
350  $this->destroy();
351  break;
352  case 'FIELD':
353  unset($this->current_field);
354  break;
355 
356  }
357  }
358 
365  function addIndex( $attributes ) {
366  $name = strtoupper( $attributes['NAME'] );
367  $this->indexes[$name] = new dbIndex( $this, $attributes );
368  return $this->indexes[$name];
369  }
370 
377  function addData( $attributes ) {
378  if( !isset( $this->data ) ) {
379  $this->data = new dbData( $this, $attributes );
380  }
381  return $this->data;
382  }
383 
413  function addField( $name, $type, $size = NULL, $opts = NULL ) {
414  $field_id = $this->FieldID( $name );
415 
416  // Set the field index so we know where we are
417  $this->current_field = $field_id;
418 
419  // Set the field name (required)
420  $this->fields[$field_id]['NAME'] = $name;
421 
422  // Set the field type (required)
423  $this->fields[$field_id]['TYPE'] = $type;
424 
425  // Set the field size (optional)
426  if( isset( $size ) ) {
427  $this->fields[$field_id]['SIZE'] = $size;
428  }
429 
430  // Set the field options
431  if( isset( $opts ) ) {
432  $this->fields[$field_id]['OPTS'][] = $opts;
433  }
434  }
435 
447  function addFieldOpt( $field, $opt, $value = NULL ) {
448  if( !isset( $value ) ) {
449  $this->fields[$this->FieldID( $field )]['OPTS'][] = $opt;
450  // Add the option and value
451  } else {
452  $this->fields[$this->FieldID( $field )]['OPTS'][] = array( $opt => $value );
453  }
454  }
455 
465  function addTableOpt( $opt ) {
466  if(isset($this->currentPlatform)) {
467  $this->opts[$this->parent->db->databaseType] = $opt;
468  }
469  return $this->opts;
470  }
471 
472 
479  function create( &$xmls ) {
480  $sql = array();
481 
482  // drop any existing indexes
483  if( is_array( $legacy_indexes = $xmls->dict->MetaIndexes( $this->name ) ) ) {
484  foreach( $legacy_indexes as $index => $index_details ) {
485  $sql[] = $xmls->dict->DropIndexSQL( $index, $this->name );
486  }
487  }
488 
489  // remove fields to be dropped from table object
490  foreach( $this->drop_field as $field ) {
491  unset( $this->fields[$field] );
492  }
493 
494  // if table exists
495  if( is_array( $legacy_fields = $xmls->dict->MetaColumns( $this->name ) ) ) {
496  // drop table
497  if( $this->drop_table ) {
498  $sql[] = $xmls->dict->DropTableSQL( $this->name );
499 
500  return $sql;
501  }
502 
503  // drop any existing fields not in schema
504  foreach( $legacy_fields as $field_id => $field ) {
505  if( !isset( $this->fields[$field_id] ) ) {
506  $sql[] = $xmls->dict->DropColumnSQL( $this->name, '`'.$field->name.'`' );
507  }
508  }
509  // if table doesn't exist
510  } else {
511  if( $this->drop_table ) {
512  return $sql;
513  }
514 
515  $legacy_fields = array();
516  }
517 
518  // Loop through the field specifier array, building the associative array for the field options
519  $fldarray = array();
520 
521  foreach( $this->fields as $field_id => $finfo ) {
522  // Set an empty size if it isn't supplied
523  if( !isset( $finfo['SIZE'] ) ) {
524  $finfo['SIZE'] = '';
525  }
526 
527  // Initialize the field array with the type and size
528  $fldarray[$field_id] = array(
529  'NAME' => $finfo['NAME'],
530  'TYPE' => $finfo['TYPE'],
531  'SIZE' => $finfo['SIZE']
532  );
533 
534  // Loop through the options array and add the field options.
535  if( isset( $finfo['OPTS'] ) ) {
536  foreach( $finfo['OPTS'] as $opt ) {
537  // Option has an argument.
538  if( is_array( $opt ) ) {
539  $key = key( $opt );
540  $value = $opt[key( $opt )];
541  @$fldarray[$field_id][$key] .= $value;
542  // Option doesn't have arguments
543  } else {
544  $fldarray[$field_id][$opt] = $opt;
545  }
546  }
547  }
548  }
549 
550  if( empty( $legacy_fields ) ) {
551  // Create the new table
552  $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
553  logMsg( end( $sql ), 'Generated CreateTableSQL' );
554  } else {
555  // Upgrade an existing table
556  logMsg( "Upgrading {$this->name} using '{$xmls->upgrade}'" );
557  switch( $xmls->upgrade ) {
558  // Use ChangeTableSQL
559  case 'ALTER':
560  logMsg( 'Generated ChangeTableSQL (ALTERing table)' );
561  $sql[] = $xmls->dict->ChangeTableSQL( $this->name, $fldarray, $this->opts );
562  break;
563  case 'REPLACE':
564  logMsg( 'Doing upgrade REPLACE (testing)' );
565  $sql[] = $xmls->dict->DropTableSQL( $this->name );
566  $sql[] = $xmls->dict->CreateTableSQL( $this->name, $fldarray, $this->opts );
567  break;
568  // ignore table
569  default:
570  return array();
571  }
572  }
573 
574  foreach( $this->indexes as $index ) {
575  $sql[] = $index->create( $xmls );
576  }
577 
578  if( isset( $this->data ) ) {
579  $sql[] = $this->data->create( $xmls );
580  }
581 
582  return $sql;
583  }
584 
588  function drop() {
589  if( isset( $this->current_field ) ) {
590  // Drop the current field
591  logMsg( "Dropping field '{$this->current_field}' from table '{$this->name}'" );
592  // $this->drop_field[$this->current_field] = $xmls->dict->DropColumnSQL( $this->name, $this->current_field );
593  $this->drop_field[$this->current_field] = $this->current_field;
594  } else {
595  // Drop the current table
596  logMsg( "Dropping table '{$this->name}'" );
597  // $this->drop_table = $xmls->dict->DropTableSQL( $this->name );
598  $this->drop_table = TRUE;
599  }
600  }
601 }
602 
614 class dbIndex extends dbObject {
615 
619  var $name;
620 
624  var $opts = array();
625 
629  var $columns = array();
630 
635  var $drop = FALSE;
636 
645  function dbIndex( &$parent, $attributes = NULL ) {
646  $this->parent = $parent;
647 
648  $this->name = $this->prefix ($attributes['NAME']);
649  }
650 
659  function _tag_open( &$parser, $tag, $attributes ) {
660  $this->currentElement = strtoupper( $tag );
661 
662  switch( $this->currentElement ) {
663  case 'DROP':
664  $this->drop();
665  break;
666  case 'CLUSTERED':
667  case 'BITMAP':
668  case 'UNIQUE':
669  case 'FULLTEXT':
670  case 'HASH':
671  // Add index Option
672  $this->addIndexOpt( $this->currentElement );
673  break;
674  default:
675  // print_r( array( $tag, $attributes ) );
676  }
677  }
678 
686  function _tag_cdata( &$parser, $cdata ) {
687  switch( $this->currentElement ) {
688  // Index field name
689  case 'COL':
690  $this->addField( $cdata );
691  break;
692  default:
693 
694  }
695  }
696 
702  function _tag_close( &$parser, $tag ) {
703  $this->currentElement = '';
704 
705  switch( strtoupper( $tag ) ) {
706  case 'INDEX':
707  xml_set_object( $parser, $this->parent );
708  break;
709  }
710  }
711 
718  function addField( $name ) {
719  $this->columns[$this->FieldID( $name )] = $name;
720 
721  // Return the field list
722  return $this->columns;
723  }
724 
731  function addIndexOpt( $opt ) {
732  $this->opts[] = $opt;
733 
734  // Return the options list
735  return $this->opts;
736  }
737 
744  function create( &$xmls ) {
745  if( $this->drop ) {
746  return NULL;
747  }
748 
749  // eliminate any columns that aren't in the table
750  foreach( $this->columns as $id => $col ) {
751  if( !isset( $this->parent->fields[$id] ) ) {
752  unset( $this->columns[$id] );
753  }
754  }
755 
756  return $xmls->dict->CreateIndexSQL( $this->name, $this->parent->name, $this->columns, $this->opts );
757  }
758 
762  function drop() {
763  $this->drop = TRUE;
764  }
765 }
766 
775 class dbData extends dbObject {
776 
777  var $data = array();
778 
779  var $row;
780 
789  function dbData( &$parent, $attributes = NULL ) {
790  $this->parent = $parent;
791  }
792 
801  function _tag_open( &$parser, $tag, $attributes ) {
802  $this->currentElement = strtoupper( $tag );
803 
804  switch( $this->currentElement ) {
805  case 'ROW':
806  $this->row = count( $this->data );
807  $this->data[$this->row] = array();
808  break;
809  case 'F':
810  $this->addField($attributes);
811  default:
812  // print_r( array( $tag, $attributes ) );
813  }
814  }
815 
823  function _tag_cdata( &$parser, $cdata ) {
824  switch( $this->currentElement ) {
825  // Index field name
826  case 'F':
827  $this->addData( $cdata );
828  break;
829  default:
830 
831  }
832  }
833 
839  function _tag_close( &$parser, $tag ) {
840  $this->currentElement = '';
841 
842  switch( strtoupper( $tag ) ) {
843  case 'DATA':
844  xml_set_object( $parser, $this->parent );
845  break;
846  }
847  }
848 
855  function addField( $attributes ) {
856  if( isset( $attributes['NAME'] ) ) {
857  $name = $attributes['NAME'];
858  } else {
859  $name = count($this->data[$this->row]);
860  }
861 
862  // Set the field index so we know where we are
863  $this->current_field = $this->FieldID( $name );
864  }
865 
872  function addData( $cdata ) {
873  if( !isset( $this->data[$this->row] ) ) {
874  $this->data[$this->row] = array();
875  }
876 
877  if( !isset( $this->data[$this->row][$this->current_field] ) ) {
878  $this->data[$this->row][$this->current_field] = '';
879  }
880 
881  $this->data[$this->row][$this->current_field] .= $cdata;
882  }
883 
890  function create( &$xmls ) {
891  $table = $xmls->dict->TableName($this->parent->name);
892  $table_field_count = count($this->parent->fields);
893  $sql = array();
894 
895  // eliminate any columns that aren't in the table
896  foreach( $this->data as $row ) {
897  $table_fields = $this->parent->fields;
898  $fields = array();
899 
900  foreach( $row as $field_id => $field_data ) {
901  if( !array_key_exists( $field_id, $table_fields ) ) {
902  if( is_numeric( $field_id ) ) {
903  $field_id = reset( array_keys( $table_fields ) );
904  } else {
905  continue;
906  }
907  }
908 
909  $name = $table_fields[$field_id]['NAME'];
910 
911  switch( $table_fields[$field_id]['TYPE'] ) {
912  case 'C':
913  case 'C2':
914  case 'X':
915  case 'X2':
916  $fields[$name] = $xmls->db->qstr( $field_data );
917  break;
918  case 'I':
919  case 'I1':
920  case 'I2':
921  case 'I4':
922  case 'I8':
923  $fields[$name] = intval($field_data);
924  break;
925  default:
926  $fields[$name] = $field_data;
927  }
928 
929  unset($table_fields[$field_id]);
930  }
931 
932  // check that at least 1 column is specified
933  if( empty( $fields ) ) {
934  continue;
935  }
936 
937  // check that no required columns are missing
938  if( count( $fields ) < $table_field_count ) {
939  foreach( $table_fields as $field ) {
940  if (isset( $field['OPTS'] ))
941  if( ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) {
942  continue(2);
943  }
944  }
945  }
946 
947  $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')';
948  }
949 
950  return $sql;
951  }
952 }
953 
960 class dbQuerySet extends dbObject {
961 
965  var $queries = array();
966 
970  var $query;
971 
975  var $prefixKey = '';
976 
980  var $prefixMethod = 'AUTO';
981 
988  function dbQuerySet( &$parent, $attributes = NULL ) {
989  $this->parent = $parent;
990 
991  // Overrides the manual prefix key
992  if( isset( $attributes['KEY'] ) ) {
993  $this->prefixKey = $attributes['KEY'];
994  }
995 
996  $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : '';
997 
998  // Enables or disables automatic prefix prepending
999  switch( $prefixMethod ) {
1000  case 'AUTO':
1001  $this->prefixMethod = 'AUTO';
1002  break;
1003  case 'MANUAL':
1004  $this->prefixMethod = 'MANUAL';
1005  break;
1006  case 'NONE':
1007  $this->prefixMethod = 'NONE';
1008  break;
1009  }
1010  }
1011 
1018  function _tag_open( &$parser, $tag, $attributes ) {
1019  $this->currentElement = strtoupper( $tag );
1020 
1021  switch( $this->currentElement ) {
1022  case 'QUERY':
1023  // Create a new query in a SQL queryset.
1024  // Ignore this query set if a platform is specified and it's different than the
1025  // current connection platform.
1026  if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
1027  $this->newQuery();
1028  } else {
1029  $this->discardQuery();
1030  }
1031  break;
1032  default:
1033  // print_r( array( $tag, $attributes ) );
1034  }
1035  }
1036 
1040  function _tag_cdata( &$parser, $cdata ) {
1041  switch( $this->currentElement ) {
1042  // Line of queryset SQL data
1043  case 'QUERY':
1044  $this->buildQuery( $cdata );
1045  break;
1046  default:
1047 
1048  }
1049  }
1050 
1056  function _tag_close( &$parser, $tag ) {
1057  $this->currentElement = '';
1058 
1059  switch( strtoupper( $tag ) ) {
1060  case 'QUERY':
1061  // Add the finished query to the open query set.
1062  $this->addQuery();
1063  break;
1064  case 'SQL':
1065  $this->parent->addSQL( $this->create( $this->parent ) );
1066  xml_set_object( $parser, $this->parent );
1067  $this->destroy();
1068  break;
1069  default:
1070 
1071  }
1072  }
1073 
1079  function newQuery() {
1080  $this->query = '';
1081 
1082  return TRUE;
1083  }
1084 
1090  function discardQuery() {
1091  unset( $this->query );
1092 
1093  return TRUE;
1094  }
1095 
1102  function buildQuery( $sql = NULL ) {
1103  if( !isset( $this->query ) OR empty( $sql ) ) {
1104  return FALSE;
1105  }
1106 
1107  $this->query .= $sql;
1108 
1109  return $this->query;
1110  }
1111 
1117  function addQuery() {
1118  if( !isset( $this->query ) ) {
1119  return FALSE;
1120  }
1121 
1122  $this->queries[] = $return = trim($this->query);
1123 
1124  unset( $this->query );
1125 
1126  return $return;
1127  }
1128 
1135  function create( &$xmls ) {
1136  foreach( $this->queries as $id => $query ) {
1137  switch( $this->prefixMethod ) {
1138  case 'AUTO':
1139  // Enable auto prefix replacement
1140 
1141  // Process object prefix.
1142  // Evaluate SQL statements to prepend prefix to objects
1143  $query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
1144  $query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
1145  $query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
1146 
1147  // SELECT statements aren't working yet
1148  #$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
1149 
1150  case 'MANUAL':
1151  // If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
1152  // If prefixKey is not set, we use the default constant XMLS_PREFIX
1153  if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
1154  // Enable prefix override
1155  $query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
1156  } else {
1157  // Use default replacement
1158  $query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
1159  }
1160  }
1161 
1162  $this->queries[$id] = trim( $query );
1163  }
1164 
1165  // Return the query set array
1166  return $this->queries;
1167  }
1168 
1177  function prefixQuery( $regex, $query, $prefix = NULL ) {
1178  if( !isset( $prefix ) ) {
1179  return $query;
1180  }
1181 
1182  if( preg_match( $regex, $query, $match ) ) {
1183  $preamble = $match[1];
1184  $postamble = $match[5];
1185  $objectList = explode( ',', $match[3] );
1186  // $prefix = $prefix . '_';
1187 
1188  $prefixedList = '';
1189 
1190  foreach( $objectList as $object ) {
1191  if( $prefixedList !== '' ) {
1192  $prefixedList .= ', ';
1193  }
1194 
1195  $prefixedList .= $prefix . trim( $object );
1196  }
1197 
1198  $query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
1199  }
1200 
1201  return $query;
1202  }
1203 }
1204 
1218 class adoSchema {
1219 
1225 
1230  var $db;
1231 
1236  var $dict;
1237 
1243 
1248  var $upgrade = '';
1249 
1254  var $objectPrefix = '';
1255 
1260  var $mgq;
1261 
1266  var $debug;
1267 
1272  var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
1273 
1279 
1284 
1289 
1294 
1304  function adoSchema( $db ) {
1305  // Initialize the environment
1306  $this->mgq = get_magic_quotes_runtime();
1307  ini_set("magic_quotes_runtime", 0);
1308  #set_magic_quotes_runtime(0);
1309 
1310  $this->db = $db;
1311  $this->debug = $this->db->debug;
1312  $this->dict = NewDataDictionary( $this->db );
1313  $this->sqlArray = array();
1314  $this->schemaVersion = XMLS_SCHEMA_VERSION;
1315  $this->executeInline( XMLS_EXECUTE_INLINE );
1316  $this->continueOnError( XMLS_CONTINUE_ON_ERROR );
1317  $this->setUpgradeMethod();
1318  }
1319 
1336  function SetUpgradeMethod( $method = '' ) {
1337  if( !is_string( $method ) ) {
1338  return FALSE;
1339  }
1340 
1341  $method = strtoupper( $method );
1342 
1343  // Handle the upgrade methods
1344  switch( $method ) {
1345  case 'ALTER':
1346  $this->upgrade = $method;
1347  break;
1348  case 'REPLACE':
1349  $this->upgrade = $method;
1350  break;
1351  case 'BEST':
1352  $this->upgrade = 'ALTER';
1353  break;
1354  case 'NONE':
1355  $this->upgrade = 'NONE';
1356  break;
1357  default:
1358  // Use default if no legitimate method is passed.
1359  $this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
1360  }
1361 
1362  return $this->upgrade;
1363  }
1364 
1378  function ExecuteInline( $mode = NULL ) {
1379  if( is_bool( $mode ) ) {
1380  $this->executeInline = $mode;
1381  }
1382 
1383  return $this->executeInline;
1384  }
1385 
1399  function ContinueOnError( $mode = NULL ) {
1400  if( is_bool( $mode ) ) {
1401  $this->continueOnError = $mode;
1402  }
1403 
1404  return $this->continueOnError;
1405  }
1406 
1418  function ParseSchema( $filename, $returnSchema = FALSE ) {
1419  return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
1420  }
1421 
1435  function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
1436  // Open the file
1437  if( !($fp = fopen( $filename, 'r' )) ) {
1438  // die( 'Unable to open file' );
1439  return FALSE;
1440  }
1441 
1442  // do version detection here
1443  if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
1444  return FALSE;
1445  }
1446 
1447  if ( $returnSchema )
1448  {
1449  $xmlstring = '';
1450  while( $data = fread( $fp, 100000 ) ) {
1451  $xmlstring .= $data;
1452  }
1453  return $xmlstring;
1454  }
1455 
1456  $this->success = 2;
1457 
1458  $xmlParser = $this->create_parser();
1459  // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
1460  $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
1461 
1462  // Process the file
1463  while( $data = fread( $fp, 4096 ) ) {
1464  if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
1465  die( sprintf(
1466  "XML error: %s at line %d",
1467  xml_error_string( xml_get_error_code( $xmlParser) ),
1468  xml_get_current_line_number( $xmlParser)
1469  ) );
1470  }
1471  }
1472 
1473  libxml_disable_entity_loader($previousValueOfEntityLoader);
1474  xml_parser_free( $xmlParser );
1475 
1476  return $this->sqlArray;
1477  }
1478 
1490  function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
1491  if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
1492  return FALSE;
1493  }
1494 
1495  // do version detection here
1496  if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
1497  return FALSE;
1498  }
1499 
1500  if ( $returnSchema )
1501  {
1502  return $xmlstring;
1503  }
1504 
1505  $this->success = 2;
1506 
1507  $xmlParser = $this->create_parser();
1508  // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
1509  $previousValueOfEntityLoader = libxml_disable_entity_loader(TRUE);
1510 
1511  if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
1512  die( sprintf(
1513  "XML error: %s at line %d",
1514  xml_error_string( xml_get_error_code( $xmlParser) ),
1515  xml_get_current_line_number( $xmlParser)
1516  ) );
1517  }
1518 
1519  libxml_disable_entity_loader($previousValueOfEntityLoader);
1520  xml_parser_free( $xmlParser );
1521 
1522  return $this->sqlArray;
1523  }
1524 
1536  function RemoveSchema( $filename, $returnSchema = FALSE ) {
1537  return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
1538  }
1539 
1551  function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
1552 
1553  // grab current version
1554  if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
1555  return FALSE;
1556  }
1557 
1558  return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
1559  }
1560 
1574  function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
1575  if( !is_bool( $continueOnErr ) ) {
1576  $continueOnErr = $this->ContinueOnError();
1577  }
1578 
1579  if( !isset( $sqlArray ) ) {
1580  $sqlArray = $this->sqlArray;
1581  }
1582 
1583  if( !is_array( $sqlArray ) ) {
1584  $this->success = 0;
1585  } else {
1586  $this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
1587  }
1588 
1589  return $this->success;
1590  }
1591 
1601  function PrintSQL( $format = 'NONE' ) {
1602  $sqlArray = null;
1603  return $this->getSQL( $format, $sqlArray );
1604  }
1605 
1615  function SaveSQL( $filename = './schema.sql' ) {
1616 
1617  if( !isset( $sqlArray ) ) {
1618  $sqlArray = $this->sqlArray;
1619  }
1620  if( !isset( $sqlArray ) ) {
1621  return FALSE;
1622  }
1623 
1624  $fp = fopen( $filename, "w" );
1625 
1626  foreach( $sqlArray as $key => $query ) {
1627  fwrite( $fp, $query . ";\n" );
1628  }
1629  fclose( $fp );
1630  }
1631 
1639  function create_parser() {
1640  // Create the parser
1641  $xmlParser = xml_parser_create();
1642  xml_set_object( $xmlParser, $this );
1643 
1644  // Initialize the XML callback functions
1645  xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
1646  xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
1647 
1648  return $xmlParser;
1649  }
1650 
1656  function _tag_open( &$parser, $tag, $attributes ) {
1657  switch( strtoupper( $tag ) ) {
1658  case 'TABLE':
1659  $this->obj = new dbTable( $this, $attributes );
1660  xml_set_object( $parser, $this->obj );
1661  break;
1662  case 'SQL':
1663  if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
1664  $this->obj = new dbQuerySet( $this, $attributes );
1665  xml_set_object( $parser, $this->obj );
1666  }
1667  break;
1668  default:
1669  // print_r( array( $tag, $attributes ) );
1670  }
1671 
1672  }
1673 
1679  function _tag_cdata( &$parser, $cdata ) {
1680  }
1681 
1688  function _tag_close( &$parser, $tag ) {
1689 
1690  }
1691 
1708  function ConvertSchemaString( $schema, $newVersion = NULL, $newFile = NULL ) {
1709 
1710  // grab current version
1711  if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
1712  return FALSE;
1713  }
1714 
1715  if( !isset ($newVersion) ) {
1716  $newVersion = $this->schemaVersion;
1717  }
1718 
1719  if( $version == $newVersion ) {
1720  $result = $schema;
1721  } else {
1722  $result = $this->TransformSchema( $schema, 'convert-' . $version . '-' . $newVersion);
1723  }
1724 
1725  if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
1726  fwrite( $fp, $result );
1727  fclose( $fp );
1728  }
1729 
1730  return $result;
1731  }
1732 
1733  // compat for pre-4.3 - jlim
1734  function _file_get_contents($path)
1735  {
1736  if (function_exists('file_get_contents')) return file_get_contents($path);
1737  return join('',file($path));
1738  }
1739 
1756  function ConvertSchemaFile( $filename, $newVersion = NULL, $newFile = NULL ) {
1757 
1758  // grab current version
1759  if( !( $version = $this->SchemaFileVersion( $filename ) ) ) {
1760  return FALSE;
1761  }
1762 
1763  if( !isset ($newVersion) ) {
1764  $newVersion = $this->schemaVersion;
1765  }
1766 
1767  if( $version == $newVersion ) {
1768  $result = _file_get_contents( $filename );
1769 
1770  // remove unicode BOM if present
1771  if( substr( $result, 0, 3 ) == sprintf( '%c%c%c', 239, 187, 191 ) ) {
1772  $result = substr( $result, 3 );
1773  }
1774  } else {
1775  $result = $this->TransformSchema( $filename, 'convert-' . $version . '-' . $newVersion, 'file' );
1776  }
1777 
1778  if( is_string( $result ) AND is_string( $newFile ) AND ( $fp = fopen( $newFile, 'w' ) ) ) {
1779  fwrite( $fp, $result );
1780  fclose( $fp );
1781  }
1782 
1783  return $result;
1784  }
1785 
1786  function TransformSchema( $schema, $xsl, $schematype='string' )
1787  {
1788  // Fail if XSLT extension is not available
1789  if( ! function_exists( 'xslt_create' ) ) {
1790  return FALSE;
1791  }
1792 
1793  $xsl_file = dirname( __FILE__ ) . '/xsl/' . $xsl . '.xsl';
1794 
1795  // look for xsl
1796  if( !is_readable( $xsl_file ) ) {
1797  return FALSE;
1798  }
1799 
1800  switch( $schematype )
1801  {
1802  case 'file':
1803  if( !is_readable( $schema ) ) {
1804  return FALSE;
1805  }
1806 
1807  $schema = _file_get_contents( $schema );
1808  break;
1809  case 'string':
1810  default:
1811  if( !is_string( $schema ) ) {
1812  return FALSE;
1813  }
1814  }
1815 
1816  $arguments = array (
1817  '/_xml' => $schema,
1818  '/_xsl' => _file_get_contents( $xsl_file )
1819  );
1820 
1821  // create an XSLT processor
1822  $xh = xslt_create ();
1823 
1824  // set error handler
1825  xslt_set_error_handler ($xh, array (&$this, 'xslt_error_handler'));
1826 
1827  // process the schema
1828  $result = xslt_process ($xh, 'arg:/_xml', 'arg:/_xsl', NULL, $arguments);
1829 
1830  xslt_free ($xh);
1831 
1832  return $result;
1833  }
1834 
1845  function xslt_error_handler( $parser, $errno, $level, $fields ) {
1846  if( is_array( $fields ) ) {
1847  $msg = array(
1848  'Message Type' => ucfirst( $fields['msgtype'] ),
1849  'Message Code' => $fields['code'],
1850  'Message' => $fields['msg'],
1851  'Error Number' => $errno,
1852  'Level' => $level
1853  );
1854 
1855  switch( $fields['URI'] ) {
1856  case 'arg:/_xml':
1857  $msg['Input'] = 'XML';
1858  break;
1859  case 'arg:/_xsl':
1860  $msg['Input'] = 'XSL';
1861  break;
1862  default:
1863  $msg['Input'] = $fields['URI'];
1864  }
1865 
1866  $msg['Line'] = $fields['line'];
1867  } else {
1868  $msg = array(
1869  'Message Type' => 'Error',
1870  'Error Number' => $errno,
1871  'Level' => $level,
1872  'Fields' => var_export( $fields, TRUE )
1873  );
1874  }
1875 
1876  $error_details = $msg['Message Type'] . ' in XSLT Transformation' . "\n"
1877  . '<table>' . "\n";
1878 
1879  foreach( $msg as $label => $details ) {
1880  $error_details .= '<tr><td><b>' . $label . ': </b></td><td>' . htmlentities( $details ) . '</td></tr>' . "\n";
1881  }
1882 
1883  $error_details .= '</table>';
1884 
1885  trigger_error( $error_details, E_USER_ERROR );
1886  }
1887 
1897  function SchemaFileVersion( $filename ) {
1898  // Open the file
1899  if( !($fp = fopen( $filename, 'r' )) ) {
1900  // die( 'Unable to open file' );
1901  return FALSE;
1902  }
1903 
1904  // Process the file
1905  while( $data = fread( $fp, 4096 ) ) {
1906  if( preg_match( $this->versionRegex, $data, $matches ) ) {
1907  return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
1908  }
1909  }
1910 
1911  return FALSE;
1912  }
1913 
1923  function SchemaStringVersion( $xmlstring ) {
1924  if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
1925  return FALSE;
1926  }
1927 
1928  if( preg_match( $this->versionRegex, $xmlstring, $matches ) ) {
1929  return !empty( $matches[2] ) ? $matches[2] : XMLS_DEFAULT_SCHEMA_VERSION;
1930  }
1931 
1932  return FALSE;
1933  }
1934 
1945  function ExtractSchema( $data = FALSE ) {
1946  $old_mode = $this->db->SetFetchMode( ADODB_FETCH_NUM );
1947 
1948  $schema = '<?xml version="1.0"?>' . "\n"
1949  . '<schema version="' . $this->schemaVersion . '">' . "\n";
1950 
1951  if( is_array( $tables = $this->db->MetaTables( 'TABLES' ) ) ) {
1952  foreach( $tables as $table ) {
1953  $schema .= ' <table name="' . $table . '">' . "\n";
1954 
1955  // grab details from database
1956  $rs = $this->db->Execute( 'SELECT * FROM ' . $table . ' WHERE 1=1' );
1957  $fields = $this->db->MetaColumns( $table );
1958  $indexes = $this->db->MetaIndexes( $table );
1959 
1960  if( is_array( $fields ) ) {
1961  foreach( $fields as $details ) {
1962  $extra = '';
1963  $content = array();
1964 
1965  if( $details->max_length > 0 ) {
1966  $extra .= ' size="' . $details->max_length . '"';
1967  }
1968 
1969  if( $details->primary_key ) {
1970  $content[] = '<KEY/>';
1971  } elseif( $details->not_null ) {
1972  $content[] = '<NOTNULL/>';
1973  }
1974 
1975  if( $details->has_default ) {
1976  $content[] = '<DEFAULT value="' . $details->default_value . '"/>';
1977  }
1978 
1979  if( $details->auto_increment ) {
1980  $content[] = '<AUTOINCREMENT/>';
1981  }
1982 
1983  // this stops the creation of 'R' columns,
1984  // AUTOINCREMENT is used to create auto columns
1985  $details->primary_key = 0;
1986  $type = $rs->MetaType( $details );
1987 
1988  $schema .= ' <field name="' . $details->name . '" type="' . $type . '"' . $extra . '>';
1989 
1990  if( !empty( $content ) ) {
1991  $schema .= "\n " . implode( "\n ", $content ) . "\n ";
1992  }
1993 
1994  $schema .= '</field>' . "\n";
1995  }
1996  }
1997 
1998  if( is_array( $indexes ) ) {
1999  foreach( $indexes as $index => $details ) {
2000  $schema .= ' <index name="' . $index . '">' . "\n";
2001 
2002  if( $details['unique'] ) {
2003  $schema .= ' <UNIQUE/>' . "\n";
2004  }
2005 
2006  foreach( $details['columns'] as $column ) {
2007  $schema .= ' <col>' . $column . '</col>' . "\n";
2008  }
2009 
2010  $schema .= ' </index>' . "\n";
2011  }
2012  }
2013 
2014  if( $data ) {
2015  $rs = $this->db->Execute( 'SELECT * FROM ' . $table );
2016 
2017  if( is_object( $rs ) ) {
2018  $schema .= ' <data>' . "\n";
2019 
2020  while( $row = $rs->FetchRow() ) {
2021  foreach( $row as $key => $val ) {
2022  $row[$key] = htmlentities($val);
2023  }
2024 
2025  $schema .= ' <row><f>' . implode( '</f><f>', $row ) . '</f></row>' . "\n";
2026  }
2027 
2028  $schema .= ' </data>' . "\n";
2029  }
2030  }
2031 
2032  $schema .= ' </table>' . "\n";
2033  }
2034  }
2035 
2036  $this->db->SetFetchMode( $old_mode );
2037 
2038  $schema .= '</schema>';
2039  return $schema;
2040  }
2041 
2052  function SetPrefix( $prefix = '', $underscore = TRUE ) {
2053  switch( TRUE ) {
2054  // clear prefix
2055  case empty( $prefix ):
2056  logMsg( 'Cleared prefix' );
2057  $this->objectPrefix = '';
2058  return TRUE;
2059  // prefix too long
2060  case strlen( $prefix ) > XMLS_PREFIX_MAXLEN:
2061  // prefix contains invalid characters
2062  case !preg_match( '/^[a-z][a-z0-9_]+$/i', $prefix ):
2063  logMsg( 'Invalid prefix: ' . $prefix );
2064  return FALSE;
2065  }
2066 
2067  if( $underscore AND substr( $prefix, -1 ) != '_' ) {
2068  $prefix .= '_';
2069  }
2070 
2071  // prefix valid
2072  logMsg( 'Set prefix: ' . $prefix );
2073  $this->objectPrefix = $prefix;
2074  return TRUE;
2075  }
2076 
2085  function prefix( $name = '' ) {
2086  // if prefix is set
2087  if( !empty( $this->objectPrefix ) ) {
2088  // Prepend the object prefix to the table name
2089  // prepend after quote if used
2090  return preg_replace( '/^(`?)(.+)$/', '$1' . $this->objectPrefix . '$2', $name );
2091  }
2092 
2093  // No prefix set. Use name provided.
2094  return $name;
2095  }
2096 
2105  function supportedPlatform( $platform = NULL ) {
2106  $regex = '/^(\w*\|)*' . $this->db->databaseType . '(\|\w*)*$/';
2107 
2108  if( !isset( $platform ) OR preg_match( $regex, $platform ) ) {
2109  logMsg( "Platform $platform is supported" );
2110  return TRUE;
2111  } else {
2112  logMsg( "Platform $platform is NOT supported" );
2113  return FALSE;
2114  }
2115  }
2116 
2122  function clearSQL() {
2123  $this->sqlArray = array();
2124  }
2125 
2134  function addSQL( $sql = NULL ) {
2135  if( is_array( $sql ) ) {
2136  foreach( $sql as $line ) {
2137  $this->addSQL( $line );
2138  }
2139 
2140  return TRUE;
2141  }
2142 
2143  if( is_string( $sql ) ) {
2144  $this->sqlArray[] = $sql;
2145 
2146  // if executeInline is enabled, and either no errors have occurred or continueOnError is enabled, execute SQL.
2147  if( $this->ExecuteInline() && ( $this->success == 2 || $this->ContinueOnError() ) ) {
2148  $saved = $this->db->debug;
2149  $this->db->debug = $this->debug;
2150  $ok = $this->db->Execute( $sql );
2151  $this->db->debug = $saved;
2152 
2153  if( !$ok ) {
2154  if( $this->debug ) {
2155  ADOConnection::outp( $this->db->ErrorMsg() );
2156  }
2157 
2158  $this->success = 1;
2159  }
2160  }
2161 
2162  return TRUE;
2163  }
2164 
2165  return FALSE;
2166  }
2167 
2176  function getSQL( $format = NULL, $sqlArray = NULL ) {
2177  if( !is_array( $sqlArray ) ) {
2178  $sqlArray = $this->sqlArray;
2179  }
2180 
2181  if( !is_array( $sqlArray ) ) {
2182  return FALSE;
2183  }
2184 
2185  switch( strtolower( $format ) ) {
2186  case 'string':
2187  case 'text':
2188  return !empty( $sqlArray ) ? implode( ";\n\n", $sqlArray ) . ';' : '';
2189  case'html':
2190  return !empty( $sqlArray ) ? nl2br( htmlentities( implode( ";\n\n", $sqlArray ) . ';' ) ) : '';
2191  }
2192 
2193  return $this->sqlArray;
2194  }
2195 
2202  function Destroy() {
2203  ini_set("magic_quotes_runtime", $this->mgq );
2204  #set_magic_quotes_runtime( $this->mgq );
2205  unset( $this );
2206  }
2207 }
2208 
2214 function logMsg( $msg, $title = NULL, $force = FALSE ) {
2215  if( XMLS_DEBUG or $force ) {
2216  echo '<pre>';
2217 
2218  if( isset( $title ) ) {
2219  echo '<h3>' . htmlentities( $title ) . '</h3>';
2220  }
2221 
2222  if( is_object( $this ) ) {
2223  echo '[' . get_class( $this ) . '] ';
2224  }
2225 
2226  print_r( $msg );
2227 
2228  echo '</pre>';
2229  }
2230 }
dbTable(&$parent, $attributes=NULL)
SchemaFileVersion( $filename)
_tag_open(&$parser, $tag, $attributes)
ExecuteSchema( $sqlArray=NULL, $continueOnErr=NULL)
_tag_close(&$parser, $tag)
RemoveSchemaString( $schema, $returnSchema=FALSE)
ConvertSchemaFile( $filename, $newVersion=NULL, $newFile=NULL)
$sql
Definition: server.php:82
ParseSchemaFile( $filename, $returnSchema=FALSE)
if(!defined('ADODB_ERROR_HANDLER_TYPE')) define('ADODB_ERROR_HANDLER_TYPE' E_USER_ERROR
_file_get_contents($file)
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:92
ContinueOnError( $mode=NULL)
_tag_close(&$parser, $tag)
RemoveSchema( $filename, $returnSchema=FALSE)
supportedPlatform( $platform=NULL)
_tag_open(&$parser, $tag, $attributes)
addSQL( $sql=NULL)
_tag_open(&$parser, $tag, $attributes)
_tag_cdata(&$parser, $cdata)
_tag_close(&$parser, $tag)
SaveSQL( $filename='./schema.sql')
supportedPlatform( $platform=NULL)
_tag_close(&$parser, $tag)
addIndex( $attributes)
prefixQuery( $regex, $query, $prefix=NULL)
_tag_cdata(&$parser, $cdata)
dbIndex(&$parent, $attributes=NULL)
ConvertSchemaString( $schema, $newVersion=NULL, $newFile=NULL)
prefix( $name='')
die
Definition: index.php:6
_tag_cdata(&$parser, $cdata)
getSQL( $format=NULL, $sqlArray=NULL)
addFieldOpt( $field, $opt, $value=NULL)
_tag_open(&$parser, $tag, $attributes)
xslt_error_handler( $parser, $errno, $level, $fields)
addField( $name, $type, $size=NULL, $opts=NULL)
_tag_cdata(&$parser, $cdata)
_tag_close(&$parser, $tag)
if($list_of_literals) if(!empty($literals)) if(!empty($literals)) $result
Analyse literals to prepend the N char to them if their contents aren&#39;t numeric.
SetPrefix( $prefix='', $underscore=TRUE)
addData( $attributes)
dbObject(&$parent, $attributes=NULL)
_tag_cdata(&$parser, $cdata)
SchemaStringVersion( $xmlstring)
TransformSchema( $schema, $xsl, $schematype='string')
dbData(&$parent, $attributes=NULL)
_tag_open(&$parser, $tag, $attributes)
ParseSchema( $filename, $returnSchema=FALSE)
_tag_open(&$parser, $tag, $attributes)
ParseSchemaString( $xmlstring, $returnSchema=FALSE)
addData( $cdata)
debug($variable='', $name=' *variable *', $line=' *line *', $file=' *file *', $recursiveDepth=3, $debugLevel=E_DEBUG)
ExecuteInline( $mode=NULL)
ExtractSchema( $data=FALSE)
addField( $attributes)
_tag_cdata(&$parser, $cdata)
dbQuerySet(&$parent, $attributes=NULL)
buildQuery( $sql=NULL)
logMsg( $msg, $title=NULL, $force=FALSE)
_tag_close(&$parser, $tag)
PrintSQL( $format='NONE')
SetUpgradeMethod( $method='')