📄 adodb-xmlschema03.inc.php
字号:
$name = $table_fields[$field_id]['NAME']; switch( $table_fields[$field_id]['TYPE'] ) { case 'I': case 'I1': case 'I2': case 'I4': case 'I8': $fields[$name] = intval($field_data); break; case 'C': case 'C2': case 'X': case 'X2': default: $fields[$name] = $xmls->db->qstr( $field_data ); $rawfields[$name] = $field_data; } unset($table_fields[$field_id]); } // check that at least 1 column is specified if( empty( $fields ) ) { continue; } // check that no required columns are missing if( count( $fields ) < $table_field_count ) { foreach( $table_fields as $field ) { if( isset( $field['OPTS'] ) and ( in_array( 'NOTNULL', $field['OPTS'] ) || in_array( 'KEY', $field['OPTS'] ) ) && !in_array( 'AUTOINCREMENT', $field['OPTS'] ) ) { continue(2); } } } // The rest of this method deals with updating existing data records. if( !in_array( $table, $tables ) or ( $mode = $xmls->existingData() ) == XMLS_MODE_INSERT ) { // Table doesn't yet exist, so it's safe to insert. logMsg( "$table doesn't exist, inserting or mode is INSERT" ); $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')'; continue; } // Prepare to test for potential violations. Get primary keys and unique indexes $mfields = array_merge( $fields, $rawfields ); $keyFields = array_intersect( $ukeys, array_keys( $mfields ) ); if( empty( $ukeys ) or count( $keyFields ) == 0 ) { // No unique keys in schema, so safe to insert logMsg( "Either schema or data has no unique keys, so safe to insert" ); $sql[] = 'INSERT INTO '. $table .' ('. implode( ',', array_keys( $fields ) ) .') VALUES ('. implode( ',', $fields ) .')'; continue; } // Select record containing matching unique keys. $where = ''; foreach( $ukeys as $key ) { if( isset( $mfields[$key] ) and $mfields[$key] ) { if( $where ) $where .= ' AND '; $where .= $key . ' = ' . $xmls->db->qstr( $mfields[$key] ); } } $records = $xmls->db->Execute( 'SELECT * FROM ' . $table . ' WHERE ' . $where ); switch( $records->RecordCount() ) { case 0: // No matching record, so safe to insert. logMsg( "No matching records. Inserting new row with unique data" ); $sql[] = $xmls->db->GetInsertSQL( $records, $mfields ); break; case 1: // Exactly one matching record, so we can update if the mode permits. logMsg( "One matching record..." ); if( $mode == XMLS_MODE_UPDATE ) { logMsg( "...Updating existing row from unique data" ); $sql[] = $xmls->db->GetUpdateSQL( $records, $mfields ); } break; default: // More than one matching record; the result is ambiguous, so we must ignore the row. logMsg( "More than one matching record. Ignoring row." ); } } return $sql; }}/*** Creates the SQL to execute a list of provided SQL queries** @package axmls* @access private*/class dbQuerySet extends dbObject { /** * @var array List of SQL queries */ var $queries = array(); /** * @var string String used to build of a query line by line */ var $query; /** * @var string Query prefix key */ var $prefixKey = ''; /** * @var boolean Auto prefix enable (TRUE) */ var $prefixMethod = 'AUTO'; /** * Initializes the query set. * * @param object $parent Parent object * @param array $attributes Attributes */ function dbQuerySet( &$parent, $attributes = NULL ) { $this->parent =& $parent; // Overrides the manual prefix key if( isset( $attributes['KEY'] ) ) { $this->prefixKey = $attributes['KEY']; } $prefixMethod = isset( $attributes['PREFIXMETHOD'] ) ? strtoupper( trim( $attributes['PREFIXMETHOD'] ) ) : ''; // Enables or disables automatic prefix prepending switch( $prefixMethod ) { case 'AUTO': $this->prefixMethod = 'AUTO'; break; case 'MANUAL': $this->prefixMethod = 'MANUAL'; break; case 'NONE': $this->prefixMethod = 'NONE'; break; } } /** * XML Callback to process start elements. Elements currently * processed are: QUERY. * * @access private */ function _tag_open( &$parser, $tag, $attributes ) { $this->currentElement = strtoupper( $tag ); switch( $this->currentElement ) { case 'QUERY': // Create a new query in a SQL queryset. // Ignore this query set if a platform is specified and it's different than the // current connection platform. if( !isset( $attributes['PLATFORM'] ) OR $this->supportedPlatform( $attributes['PLATFORM'] ) ) { $this->newQuery(); } else { $this->discardQuery(); } break; default: // print_r( array( $tag, $attributes ) ); } } /** * XML Callback to process CDATA elements */ function _tag_cdata( &$parser, $cdata ) { switch( $this->currentElement ) { // Line of queryset SQL data case 'QUERY': $this->buildQuery( $cdata ); break; default: } } /** * XML Callback to process end elements * * @access private */ function _tag_close( &$parser, $tag ) { $this->currentElement = ''; switch( strtoupper( $tag ) ) { case 'QUERY': // Add the finished query to the open query set. $this->addQuery(); break; case 'SQL': $this->parent->addSQL( $this->create( $this->parent ) ); xml_set_object( $parser, $this->parent ); $this->destroy(); break; default: } } /** * Re-initializes the query. * * @return boolean TRUE */ function newQuery() { $this->query = ''; return TRUE; } /** * Discards the existing query. * * @return boolean TRUE */ function discardQuery() { unset( $this->query ); return TRUE; } /** * 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 * @return string SQL query string. */ function buildQuery( $sql = NULL ) { if( !isset( $this->query ) OR empty( $sql ) ) { return FALSE; } $this->query .= $sql; return $this->query; } /** * Adds a completed query to the query list * * @return string SQL of added query */ 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.62 $** @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; /** * @var int How to handle existing data rows (insert, update, or ignore) */ var $existingData; /** * 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->existingData( XMLS_EXISTING_DATA ); $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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -