📄 adodb-xmlschema.inc.php
字号:
*/
function addQuery() {
if( !isset( $this->query ) ) {
return FALSE;
}
$this->queries[] = $return = trim($this->query);
unset( $this->query );
return $return;
}
/**
* Creates and returns the current query set
*
* @param object $xmls adoSchema object
* @return array Query set
*/
function create( &$xmls ) {
foreach( $this->queries as $id => $query ) {
switch( $this->prefixMethod ) {
case 'AUTO':
// Enable auto prefix replacement
// Process object prefix.
// Evaluate SQL statements to prepend prefix to objects
$query = $this->prefixQuery( '/^\s*((?is)INSERT\s+(INTO\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
$query = $this->prefixQuery( '/^\s*((?is)UPDATE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
$query = $this->prefixQuery( '/^\s*((?is)DELETE\s+(FROM\s+)?)((\w+\s*,?\s*)+)(\s.*$)/', $query, $xmls->objectPrefix );
// SELECT statements aren't working yet
#$data = preg_replace( '/(?ias)(^\s*SELECT\s+.*\s+FROM)\s+(\W\s*,?\s*)+((?i)\s+WHERE.*$)/', "\1 $prefix\2 \3", $data );
case 'MANUAL':
// If prefixKey is set and has a value then we use it to override the default constant XMLS_PREFIX.
// If prefixKey is not set, we use the default constant XMLS_PREFIX
if( isset( $this->prefixKey ) AND( $this->prefixKey !== '' ) ) {
// Enable prefix override
$query = str_replace( $this->prefixKey, $xmls->objectPrefix, $query );
} else {
// Use default replacement
$query = str_replace( XMLS_PREFIX , $xmls->objectPrefix, $query );
}
}
$this->queries[$id] = trim( $query );
}
// Return the query set array
return $this->queries;
}
/**
* Rebuilds the query with the prefix attached to any objects
*
* @param string $regex Regex used to add prefix
* @param string $query SQL query string
* @param string $prefix Prefix to be appended to tables, indices, etc.
* @return string Prefixed SQL query string.
*/
function prefixQuery( $regex, $query, $prefix = NULL ) {
if( !isset( $prefix ) ) {
return $query;
}
if( preg_match( $regex, $query, $match ) ) {
$preamble = $match[1];
$postamble = $match[5];
$objectList = explode( ',', $match[3] );
// $prefix = $prefix . '_';
$prefixedList = '';
foreach( $objectList as $object ) {
if( $prefixedList !== '' ) {
$prefixedList .= ', ';
}
$prefixedList .= $prefix . trim( $object );
}
$query = $preamble . ' ' . $prefixedList . ' ' . $postamble;
}
return $query;
}
}
/**
* 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.
*
* @tutorial getting_started.pkg
*
* @author Richard Tango-Lowy & Dan Cech
* @version $Revision: 1.4.2.1 $
*
* @package axmls
*/
class adoSchema {
/**
* @var array Array containing SQL queries to generate all objects
* @access private
*/
var $sqlArray;
/**
* @var object ADOdb connection object
* @access private
*/
var $db;
/**
* @var object ADOdb Data Dictionary
* @access private
*/
var $dict;
/**
* @var string Current XML element
* @access private
*/
var $currentElement = '';
/**
* @var string If set (to 'ALTER' or 'REPLACE'), upgrade an existing database
* @access private
*/
var $upgrade = '';
/**
* @var string Optional object prefix
* @access private
*/
var $objectPrefix = '';
/**
* @var long Original Magic Quotes Runtime value
* @access private
*/
var $mgq;
/**
* @var long System debug
* @access private
*/
var $debug;
/**
* @var string Regular expression to find schema version
* @access private
*/
var $versionRegex = '/<schema.*?( version="([^"]*)")?.*?>/';
/**
* @var string Current schema version
* @access private
*/
var $schemaVersion;
/**
* @var int Success of last Schema execution
*/
var $success;
/**
* @var bool Execute SQL inline as it is generated
*/
var $executeInline;
/**
* @var bool Continue SQL execution if errors occur
*/
var $continueOnError;
/**
* Creates an adoSchema object
*
* Creating an adoSchema object is the first step in processing an XML schema.
* The only parameter is an ADOdb database connection object, which must already
* have been created.
*
* @param object $db ADOdb database connection object.
*/
function adoSchema( &$db ) {
// Initialize the environment
$this->mgq = get_magic_quotes_runtime();
set_magic_quotes_runtime(0);
$this->db =& $db;
$this->debug = $this->db->debug;
$this->dict = NewDataDictionary( $this->db );
$this->sqlArray = array();
$this->schemaVersion = XMLS_SCHEMA_VERSION;
$this->executeInline( XMLS_EXECUTE_INLINE );
$this->continueOnError( XMLS_CONTINUE_ON_ERROR );
$this->setUpgradeMethod();
}
/**
* Sets the method to be used for upgrading an existing database
*
* Use this method to specify how existing database objects should be upgraded.
* The method option can be set to ALTER, REPLACE, BEST, or NONE. ALTER attempts to
* alter each database object directly, REPLACE attempts to rebuild each object
* from scratch, BEST attempts to determine the best upgrade method for each
* object, and NONE disables upgrading.
*
* This method is not yet used by AXMLS, but exists for backward compatibility.
* The ALTER method is automatically assumed when the adoSchema object is
* instantiated; other upgrade methods are not currently supported.
*
* @param string $method Upgrade method (ALTER|REPLACE|BEST|NONE)
* @returns string Upgrade method used
*/
function SetUpgradeMethod( $method = '' ) {
if( !is_string( $method ) ) {
return FALSE;
}
$method = strtoupper( $method );
// Handle the upgrade methods
switch( $method ) {
case 'ALTER':
$this->upgrade = $method;
break;
case 'REPLACE':
$this->upgrade = $method;
break;
case 'BEST':
$this->upgrade = 'ALTER';
break;
case 'NONE':
$this->upgrade = 'NONE';
break;
default:
// Use default if no legitimate method is passed.
$this->upgrade = XMLS_DEFAULT_UPGRADE_METHOD;
}
return $this->upgrade;
}
/**
* Enables/disables inline SQL execution.
*
* Call this method to enable or disable inline execution of the schema. If the mode is set to TRUE (inline execution),
* AXMLS applies the SQL to the database immediately as each schema entity is parsed. If the mode
* is set to FALSE (post execution), AXMLS parses the entire schema and you will need to call adoSchema::ExecuteSchema()
* to apply the schema to the database.
*
* @param bool $mode execute
* @return bool current execution mode
*
* @see ParseSchema(), ExecuteSchema()
*/
function ExecuteInline( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->executeInline = $mode;
}
return $this->executeInline;
}
/**
* Enables/disables SQL continue on error.
*
* Call this method to enable or disable continuation of SQL execution if an error occurs.
* If the mode is set to TRUE (continue), AXMLS will continue to apply SQL to the database, even if an error occurs.
* If the mode is set to FALSE (halt), AXMLS will halt execution of generated sql if an error occurs, though parsing
* of the schema will continue.
*
* @param bool $mode execute
* @return bool current continueOnError mode
*
* @see addSQL(), ExecuteSchema()
*/
function ContinueOnError( $mode = NULL ) {
if( is_bool( $mode ) ) {
$this->continueOnError = $mode;
}
return $this->continueOnError;
}
/**
* Loads an XML schema from a file and converts it to SQL.
*
* Call this method to load the specified schema (see the DTD for the proper format) from
* the filesystem and generate the SQL necessary to create the database described.
* @see ParseSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function ParseSchema( $filename, $returnSchema = FALSE ) {
return $this->ParseSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
* Loads an XML schema from a file and converts it to SQL.
*
* Call this method to load the specified schema from a file (see the DTD for the proper format)
* and generate the SQL necessary to create the database described by the schema.
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*
* @deprecated Replaced by adoSchema::ParseSchema() and adoSchema::ParseSchemaString()
* @see ParseSchema(), ParseSchemaString()
*/
function ParseSchemaFile( $filename, $returnSchema = FALSE ) {
// Open the file
if( !($fp = fopen( $filename, 'r' )) ) {
// die( 'Unable to open file' );
return FALSE;
}
// do version detection here
if( $this->SchemaFileVersion( $filename ) != $this->schemaVersion ) {
return FALSE;
}
if ( $returnSchema )
{
return $xmlstring;
}
$this->success = 2;
$xmlParser = $this->create_parser();
// Process the file
while( $data = fread( $fp, 4096 ) ) {
if( !xml_parse( $xmlParser, $data, feof( $fp ) ) ) {
die( sprintf(
"XML error: %s at line %d",
xml_error_string( xml_get_error_code( $xmlParser) ),
xml_get_current_line_number( $xmlParser)
) );
}
}
xml_parser_free( $xmlParser );
return $this->sqlArray;
}
/**
* Converts an XML schema string to SQL.
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to create the database described by the schema.
* @see ParseSchema()
*
* @param string $xmlstring XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function ParseSchemaString( $xmlstring, $returnSchema = FALSE ) {
if( !is_string( $xmlstring ) OR empty( $xmlstring ) ) {
return FALSE;
}
// do version detection here
if( $this->SchemaStringVersion( $xmlstring ) != $this->schemaVersion ) {
return FALSE;
}
if ( $returnSchema )
{
return $xmlstring;
}
$this->success = 2;
$xmlParser = $this->create_parser();
if( !xml_parse( $xmlParser, $xmlstring, TRUE ) ) {
die( sprintf(
"XML error: %s at line %d",
xml_error_string( xml_get_error_code( $xmlParser) ),
xml_get_current_line_number( $xmlParser)
) );
}
xml_parser_free( $xmlParser );
return $this->sqlArray;
}
/**
* Loads an XML schema from a file and converts it to uninstallation SQL.
*
* Call this method to load the specified schema (see the DTD for the proper format) from
* the filesystem and generate the SQL necessary to remove the database described.
* @see RemoveSchemaString()
*
* @param string $file Name of XML schema file.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute
*/
function RemoveSchema( $filename, $returnSchema = FALSE ) {
return $this->RemoveSchemaString( $this->ConvertSchemaFile( $filename ), $returnSchema );
}
/**
* Converts an XML schema string to uninstallation SQL.
*
* Call this method to parse a string containing an XML schema (see the DTD for the proper format)
* and generate the SQL necessary to uninstall the database described by the schema.
* @see RemoveSchema()
*
* @param string $schema XML schema string.
* @param bool $returnSchema Return schema rather than parsing.
* @return array Array of SQL queries, ready to execute.
*/
function RemoveSchemaString( $schema, $returnSchema = FALSE ) {
// grab current version
if( !( $version = $this->SchemaStringVersion( $schema ) ) ) {
return FALSE;
}
return $this->ParseSchemaString( $this->TransformSchema( $schema, 'remove-' . $version), $returnSchema );
}
/**
* Applies the current XML schema to the database (post execution).
*
* Call this method to apply the current schema (generally created by calling
* ParseSchema() or ParseSchemaString() ) to the database (creating the tables, indexes,
* and executing other SQL specified in the schema) after parsing.
* @see ParseSchema(), ParseSchemaString(), ExecuteInline()
*
* @param array $sqlArray Array of SQL statements that will be applied rather than
* the current schema.
* @param boolean $continueOnErr Continue to apply the schema even if an error occurs.
* @returns integer 0 if failure, 1 if errors, 2 if successful.
*/
function ExecuteSchema( $sqlArray = NULL, $continueOnErr = NULL ) {
if( !is_bool( $continueOnErr ) ) {
$continueOnErr = $this->ContinueOnError();
}
if( !isset( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !is_array( $sqlArray ) ) {
$this->success = 0;
} else {
$this->success = $this->dict->ExecuteSQLArray( $sqlArray, $continueOnErr );
}
return $this->success;
}
/**
* Returns the current SQL array.
*
* Call this method to fetch the array of SQL queries resulting from
* ParseSchema() or ParseSchemaString().
*
* @param string $format Format: HTML, TEXT, or NONE (PHP array)
* @return array Array of SQL statements or FALSE if an error occurs
*/
function PrintSQL( $format = 'NONE' ) {
return $this->getSQL( $format, $sqlArray );
}
/**
* Saves the current SQL array to the local filesystem as a list of SQL queries.
*
* Call this method to save the array of SQL queries (generally resulting from a
* parsed XML schema) to the filesystem.
*
* @param string $filename Path and name where the file should be saved.
* @return boolean TRUE if save is successful, else FALSE.
*/
function SaveSQL( $filename = './schema.sql' ) {
if( !isset( $sqlArray ) ) {
$sqlArray = $this->sqlArray;
}
if( !isset( $sqlArray ) ) {
return FALSE;
}
$fp = fopen( $filename, "w" );
foreach( $sqlArray as $key => $query ) {
fwrite( $fp, $query . ";\n" );
}
fclose( $fp );
}
/**
* Create an xml parser
*
* @return object PHP XML parser object
*
* @access private
*/
function &create_parser() {
// Create the parser
$xmlParser = xml_parser_create();
xml_set_object( $xmlParser, $this );
// Initialize the XML callback functions
xml_set_element_handler( $xmlParser, '_tag_open', '_tag_close' );
xml_set_character_data_handler( $xmlParser, '_tag_cdata' );
return $xmlParser;
}
/**
* XML Callback to process start elements
*
* @access private
*/
function _tag_open( &$parser, $tag, $attributes ) {
switch( strtoupper( $tag ) ) {
case 'TABLE':
$this->obj = new dbTable( $this, $attributes );
xml_set_object( $parser, $this->obj );
break;
case 'SQL':
if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) {
$this->obj = new dbQuerySet( $this, $attributes );
xml_set_object( $parser, $this->obj );
}
break;
default:
// print_r( array( $tag, $attributes ) );
}
}
/**
* XML Callback to process CDATA elements
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -