Index: trunk/kernel/include/adodb/adodb-xmlschema.inc.php =================================================================== diff -u -N --- trunk/kernel/include/adodb/adodb-xmlschema.inc.php (revision 13) +++ trunk/kernel/include/adodb/adodb-xmlschema.inc.php (revision 0) @@ -1,722 +0,0 @@ -tableName = $name; - } - - /** - * Adds a field to a table object - * - * $name is the name of the table to which the field should be added. - * $type is an ADODB datadict field type. The following field types - * are supported as of ADODB 3.40: - * - C: varchar - * - X: CLOB (character large object) or largest varchar size - * if CLOB is not supported - * - C2: Multibyte varchar - * - X2: Multibyte CLOB - * - B: BLOB (binary large object) - * - D: Date (some databases do not support this, and we return a datetime type) - * - T: Datetime or Timestamp - * - L: Integer field suitable for storing booleans (0 or 1) - * - I: Integer (mapped to I4) - * - I1: 1-byte integer - * - I2: 2-byte integer - * - I4: 4-byte integer - * - I8: 8-byte integer - * - F: Floating point number - * - N: Numeric or decimal number - * - * @param string $name Name of the table to which the field will be added. - * @param string $type ADODB datadict field type. - * @param string $size Field size - * @param array $opts Field options array - * @return array Field specifier array - */ - function addField( $name, $type, $size = NULL, $opts = NULL ) { - - // Set the field index so we know where we are - $this->currentField = $name; - - // Set the field type (required) - $this->fieldSpec[$name]['TYPE'] = $type; - - // Set the field size (optional) - if( isset( $size ) ) { - $this->fieldSpec[$name]['SIZE'] = $size; - } - - // Set the field options - if( isset( $opts ) ) $this->fieldSpec[$name]['OPTS'] = $opts; - - // Return array containing field specifier - return $this->fieldSpec; - } - - /** - * Adds a field option to the current field specifier - * - * This method adds a field option allowed by the ADOdb datadict - * and appends it to the given field. - * - * @param string $field Field name - * @param string $opt ADOdb field option - * @param mixed $value Field option value - * @return array Field specifier array - */ - function addFieldOpt( $field, $opt, $value = NULL ) { - - // Add the option to the field specifier - if( $value === NULL ) { // No value, so add only the option - $this->fieldSpec[$field]['OPTS'][] = $opt; - } else { // Add the option and value - $this->fieldSpec[$field]['OPTS'][] = array( "$opt" => "$value" ); - } - - // Return array containing field specifier - return $this->fieldSpec; - } - - /** - * Adds an option to the table - * - *This method takes a comma-separated list of table-level options - * and appends them to the table object. - * - * @param string $opt Table option - * @return string Option list - */ - function addTableOpt( $opt ) { - - $optlist = &$this->tableOpts; - $optlist ? $optlist .= ", $opt" : $optlist = $opt; - - // Return the options list - return $optlist; - } - - /** - * Generates the SQL that will create the table in the database - * - * Returns SQL that will create the table represented by the object. - * - * @param object $dict ADOdb data dictionary - * @return array Array containing table creation SQL - */ - function create( $dict ) { - - // Loop through the field specifier array, building the associative array for the field options - $fldarray = array(); - $i = 0; - - foreach( $this->fieldSpec as $field => $finfo ) { - $i++; - - // Set an empty size if it isn't supplied - if( !isset( $finfo['SIZE'] ) ) $finfo['SIZE'] = ''; - - // Initialize the field array with the type and size - $fldarray[$i] = array( $field, $finfo['TYPE'], $finfo['SIZE'] ); - - // Loop through the options array and add the field options. - $opts = $finfo['OPTS']; - if( $opts ) { - foreach( $finfo['OPTS'] as $opt ) { - - if( is_array( $opt ) ) { // Option has an argument. - $key = key( $opt ); - $value = $opt[key( $opt ) ]; - $fldarray[$i][$key] = $value; - } else { // Option doesn't have arguments - array_push( $fldarray[$i], $opt ); - } - } - } - } - - // Build table array - $sqlArray = $dict->CreateTableSQL( $this->tableName, $fldarray, $this->tableOpts ); - - // Return the array containing the SQL to create the table - return $sqlArray; - } - - /** - * Destructor - */ - function destroy() { - unset( $this ); - } -} - -/** -* Creates an index object in ADOdb's datadict format -* -* This class stores information about a database index. As charactaristics -* of the index are loaded from the external source, methods and properties -* of this class are used to build up the index description in ADOdb's -* datadict format. -* -* @package xmlschema -* @access private -*/ -class dbIndex { - - /** - * @var string Index name - */ - var $indexName; - - /** - * @var string Name of the table this index is attached to - */ - var $tableName; - - /** - * @var array Indexed fields: Table columns included in this index - */ - var $fields; - - /** - * Constructor. Initialize the index and table names. - * - * @param string $name Index name - * @param string $table Name of indexed table - */ - function dbIndex( $name, $table ) { - $this->indexName = $name; - $this->tableName = $table; - } - - /** - * Adds a field to the index - * - * This method adds the specified column to an index. - * - * @param string $name Field name - * @return string Field list - */ - function addField( $name ) { - $fieldlist = &$this->fields; - $fieldlist ? $fieldlist .=" , $name" : $fieldlist = $name; - - // Return the field list - return $fieldlist; - } - - /** - * Generates the SQL that will create the index in the database - * - * Returns SQL that will create the index represented by the object. - * - * @param object $dict ADOdb data dictionary object - * @return array Array containing index creation SQL - */ - function create( $dict ) { - - // Build table array - $sqlArray = $dict->CreateIndexSQL( $this->indexName, $this->tableName, $this->fields ); - - // Return the array containing the SQL to create the table - return $sqlArray; - } - - /** - * Destructor - */ - function destroy() { - unset( $this ); - } -} - -/** -* Creates the SQL to execute a list of provided SQL queries -* -* This class compiles a list of SQL queries specified in the external file. -* -* @package xmlschema -* @access private -*/ -class dbQuerySet { - - /** - * @var array List of SQL queries - */ - var $querySet; - - /** - * @var string String used to build of a query line by line - */ - var $query; - - /** - * Constructor. Initializes the queries array - */ - function dbQuerySet() { - $this->querySet = array(); - $this->query = ''; - } - - /** - * Appends a line to a query that is being built line by line - * - * $param string $data Line of SQL data or NULL to initialize a new query - */ - function buildQuery( $data = NULL ) { - isset( $data ) ? $this->query .= " " . trim( $data ) : $this->query = ''; - } - - /** - * Adds a completed query to the query list - * - * @return string SQL of added query - */ - function addQuery() { - - // Push the query onto the query set array - $finishedQuery = $this->query; - array_push( $this->querySet, $finishedQuery ); - - // Return the query set array - return $finishedQuery; - } - - /** - * Creates and returns the current query set - * - * @return array Query set - */ - function create() { - return $this->querySet; - } - - /** - * Destructor - */ - function destroy() { - unset( $this ); - } -} - - -/** -* Loads and parses an XML file, creating an array of "ready-to-run" SQL statements -* -* This class is used to load and parse the XML file, to create an array of SQL statements -* that can be used to build a database, and to build the database using the SQL array. -* -* @package xmlschema -*/ -class adoSchema { - - /** - * @var array Array containing SQL queries to generate all objects - */ - var $sqlArray; - - /** - * @var object XML Parser object - */ - var $xmlParser; - - /** - * @var object ADOdb connection object - */ - var $dbconn; - - /** - * @var string Database type (platform) - */ - var $dbType; - - /** - * @var object ADOdb Data Dictionary - */ - var $dict; - - /** - * @var object Temporary dbTable object - * @access private - */ - var $table; - - /** - * @var object Temporary dbIndex object - * @access private - */ - var $index; - - /** - * @var object Temporary dbQuerySet object - * @access private - */ - var $querySet; - - /** - * @var string Current XML element - * @access private - */ - var $currentElement; - - /** - * @var long Original Magic Quotes Runtime value - * @access private - */ - var $mgq; - - /** - * Constructor. Initializes the xmlschema object - * - * @param object $dbconn ADOdb connection object - */ - function adoSchema( $dbconn ) { - - // Initialize the environment - $this->mgq = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - - $this->dbconn = &$dbconn; - $this->dbType = $dbconn->databaseType; - $this->sqlArray = array(); - - // Create an ADOdb dictionary object - $this->dict = NewDataDictionary( $dbconn ); - } - - /** - * Loads and parses an XML file - * - * This method accepts a path to an xmlschema-compliant XML file, - * loads it, parses it, and uses it to create the SQL to generate the objects - * described by the XML file. - * - * @param string $file XML file - * @return array Array of SQL queries, ready to execute - */ - function ParseSchema( $file ) { - - // Create the parser - $this->xmlParser = &$xmlParser; - $xmlParser = xml_parser_create(); - xml_set_object( $xmlParser, &$this ); - - // Initialize the XML callback functions - xml_set_element_handler( $xmlParser, "_xmlcb_startElement", "_xmlcb_endElement" ); - xml_set_character_data_handler( $xmlParser, "_xmlcb_cData" ); - - // Open the file - if( !( $fp = fopen( $file, "r" ) ) ) { - die( "Unable to open file" ); - } - - // Process the file - while( $data = fread( $fp, 4096 ) ) { - if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) { - die( sprint( "XML error: %s at line %d", - xml_error_string( xml_get_error_code( $xmlParser ) ), - xml_get_current_line_number( $xmlParser ) ) ); - } - } - - // Return the array of queries - return $this->sqlArray; - } - - /** - * Loads a schema into the database - * - * Accepts an array of SQL queries generated by the parser - * and executes them. - * - * @param array $sqlArray Array of SQL statements - * @param boolean $continueOnErr Don't fail out if an error is encountered - * @return integer 0 if failed, 1 if errors, 2 if successful - */ - function ExecuteSchema( $sqlArray, $continueOnErr = TRUE ) { - $err = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr ); - - // Return the success code - return $err; - } - - /** - * XML Callback to process start elements - * - * @access private - */ - function _xmlcb_startElement( $parser, $name, $attrs ) { - - $dbType = $this->dbType; - if( isset( $this->table ) ) $table = &$this->table; - if( isset( $this->index ) ) $index = &$this->index; - if( isset( $this->querySet ) ) $querySet = &$this->querySet; - $this->currentElement = $name; - - // Process the element. Ignore unimportant elements. - if( in_array( trim( $name ), array( "SCHEMA", "DESCR", "COL", "CONSTRAINT" ) ) ) { - return FALSE; - } - - switch( $name ) { - - case "TABLE": // Table element - if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) { - $this->table = new dbTable( $attrs['NAME'] ); - } else { - unset( $this->table ); - } - break; - - case "FIELD": // Table field - if( isset( $this->table ) ) { - $fieldName = $attrs['NAME']; - $fieldType = $attrs['TYPE']; - isset( $attrs['SIZE'] ) ? $fieldSize = $attrs['SIZE'] : $fieldSize = NULL; - isset( $attrs['OPTS'] ) ? $fieldOpts = $attrs['OPTS'] : $fieldOpts = NULL; - $this->table->addField( $fieldName, $fieldType, $fieldSize, $fieldOpts ); - } - break; - - case "KEY": // Table field option - if( isset( $this->table ) ) { - $this->table->addFieldOpt( $this->table->currentField, 'KEY' ); - } - break; - - case "NOTNULL": // Table field option - if( isset( $this->table ) ) { - $this->table->addFieldOpt( $this->table->currentField, 'NOTNULL' ); - } - break; - - case "AUTOINCREMENT": // Table field option - if( isset( $this->table ) ) { - $this->table->addFieldOpt( $this->table->currentField, 'AUTOINCREMENT' ); - } - break; - - case "DEFAULT": // Table field option - if( isset( $this->table ) ) { - $this->table->addFieldOpt( $this->table->currentField, 'DEFAULT', $attrs['VALUE'] ); - } - break; - - case "INDEX": // Table index - if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) { - $this->index = new dbIndex( $attrs['NAME'], $attrs['TABLE'] ); - } else { - if( isset( $this->index ) ) unset( $this->index ); - } - break; - - case "SQL": // Freeform SQL queryset - if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) { - $this->querySet = new dbQuerySet( $attrs ); - } else { - if( isset( $this->querySet ) ) unset( $this->querySet ); - } - break; - - case "QUERY": // Queryset SQL query - if( isset( $this->querySet ) ) { - // Ignore this query set if a platform is specified and it's different than the - // current connection platform. - if( $this->supportedPlatform( $attrs['PLATFORM'] ) ) { - $this->querySet->buildQuery(); - } else { - if( isset( $this->querySet->query ) ) unset( $this->querySet->query ); - } - } - break; - - default: - print "OPENING ELEMENT '$name'
\n"; - } - } - - /** - * XML Callback to process cDATA elements - * - * @access private - */ - function _xmlcb_cData( $parser, $data ) { - - $element = &$this->currentElement; - - if( trim( $data ) == "" ) return; - - // Process the data depending on the element - switch( $element ) { - - case "COL": // Index column - if( isset( $this->index ) ) $this->index->addField( $data ); - break; - - case "DESCR": // Description element - // Display the description information - if( isset( $this->table ) ) { - $name = "({$this->table->tableName}): "; - } elseif( isset( $this->index ) ) { - $name = "({$this->index->indexName}): "; - } else { - $name = ""; - } - print "
  • $name $data\n"; - break; - - case "QUERY": // Query SQL data - if( isset( $this->querySet ) and isset( $this->querySet->query ) ) $this->querySet->buildQuery( $data ); - break; - - case "CONSTRAINT": // Table constraint - if( isset( $this->table ) ) $this->table->addTableOpt( $data ); - break; - - default: - print "\n"; - } - } - - /** - * XML Callback to process end elements - * - * @access private - */ - function _xmlcb_endElement( $parser, $name ) { - - // Process the element. Ignore unimportant elements. - if( in_array( trim( $name ), - array( "SCHEMA", "DESCR", "KEY", "AUTOINCREMENT", "FIELD", - "DEFAULT", "NOTNULL", "CONSTRAINT", "COL" ) ) ) { - return FALSE; - } - - switch( trim( $name ) ) { - - case "TABLE": // Table element - if( isset( $this->table ) ) { - $tableSQL = $this->table->create( $this->dict ); - array_push( $this->sqlArray, $tableSQL[0] ); - $this->table->destroy(); - } - break; - - case "INDEX": // Index element - if( isset( $this->index ) ) { - $indexSQL = $this->index->create( $this->dict ); - array_push( $this->sqlArray, $indexSQL[0] ); - $this->index->destroy(); - } - break; - - case "QUERY": // Queryset element - if( isset( $this->querySet ) and isset( $this->querySet->query ) ) $this->querySet->addQuery(); - break; - - case "SQL": // Query SQL element - if( isset( $this->querySet ) ) { - $querySQL = $this->querySet->create(); - $this->sqlArray = array_merge( $this->sqlArray, $querySQL );; - $this->querySet->destroy(); - } - break; - - default: - print "
  • CLOSING $name\n"; - } - } - - /** - * Checks if element references a specific platform - * - * Returns TRUE is no platform is specified or if we are currently - * using the specified platform. - * - * @param string $platform Requested platform - * @return boolean TRUE if platform check succeeds - * - * @access private - */ - function supportedPlatform( $platform = NULL ) { - - $dbType = $this->dbType; - $regex = "/^(\w*\|)*" . $dbType . "(\|\w*)*$/"; - - if( !isset( $platform ) or - preg_match( $regex, $platform ) ) { - return TRUE; - } else { - return FALSE; - } - } - - /** - * Destructor - */ - function Destroy() { - xml_parser_free( $this->xmlParser ); - set_magic_quotes_runtime( $this->mgq ); - unset( $this ); - } -} -?>