Menu

#19 Correction of parsing of opt/constraint

CVS
open
core (13)
5
2005-11-30
2005-11-30
Jakub Holý
No

adodb-xmlschema.inc.php revision 1.62

PROBLEM:
Adding <opt platform="mysql">type=ISAM</opt> to a
<table> does nothing - "type=ISAM" won't be in the
final sql.

SOLUTION:
Modify dbTable->addTableOpt to include the platform info:
function addTableOpt( $opt ) {
if( $this->currentPlatform ) {
// ADDED:
$platform = $this->parent->db->databaseType;
// - databaseType is unset in this->db
$this->opts[$platform] .= $opt;
// WAS:
// $this->opts[] = $opt;
}
return $this->opts;
}

EXPLANATION:
As far as I can understand it, it's necessary to
include the platform as a key, otherwise
ADODB_DataDict->CreateTableSQL (more exactly _TableSQL)
ignores it.
1. The original code adds $opt as another element into
$this->opts[] with a numerical index.
2. The array $this->opts is then, in dbTable->create,
passed to ADODB_DataDict->CreateTableSQL().
3. CreateTableSQL calls _Options to modify the array by
replacing a numerical index by the value stored under
it. In our case we get: [TYPE=ISAM] => "TYPE=ISAM"
4. It's then passed to ADODB_DataDict->_TableSQL that
appends it to the sql only if the key is one of:
REPLACE, DROP, CONSTRAINTS or if it matches the current
databaseType (mysql, postgres7 etc). An element with a
numerical key is ignored.
Thus we have to use the databaseType (platform) as a
key - which I did above.

Regards, malymelky

Discussion

  • Jakub Holý

    Jakub Holý - 2005-11-30

    Logged In: YES
    user_id=1046780

    MODIFICATION:
    The code above doesn't work with PostgreSQL because the
    driver used (databaseType) is usually "postgres7" but ADOdb
    Data dictionnray knows only "postgres" (see
    datadict-postgres.inc.php). The best solutions seems to be
    to remember the list of platforms and use all of them as a
    key; let adodb dictionnary itself to filter out those that
    are not applicable.
    So:
    var $tableOptPlatforms = array();
    function _tag_open(...) {
    ...
    case 'OPT':

    case 'CONSTRAINT':

    if(isset( $attributes['PLATFORM']) ) {

    $this->tableOptPlatforms =
    explode('|',$attributes['PLATFORM']);

    }

    $this->currentPlatform = ( !isset(
    $attributes['PLATFORM'] ) OR
    $this->supportedPlatform( $attributes['PLATFORM'] ) );

    break;
    ...
    }

    function addTableOpt( $opt ) {
    foreach( $this->tableOptPlatforms as $platform ) {

    if(! empty($platform)) $this->opts[$platform] .= $opt;

    }

    return $this->opts;

    }

     
  • Jakub Holý

    Jakub Holý - 2005-11-30

    Logged In: YES
    user_id=1046780

    function _tag_close:
    case 'OPT':
    case 'CONSTRAINT':
    $this->currentPlatform = true;
    $this->tableOptPlatforms = array();
    break;

     
  • Jakub Holý

    Jakub Holý - 2005-12-01

    The modified adodb-xmlschema

     
  • Jakub Holý

    Jakub Holý - 2005-12-01

    Logged In: YES
    user_id=1046780

    The previous approach as not ideal as it prevents the usage
    of platform="- posgres".
    Finally I decided to revert to the first solution (if the
    opt's platform matches the current one, store it with the
    platform as a key) but now I use ADODB_DataDict->upperName
    (this is used in the decision whether or not include an
    option) instead of ADOConnection->databaseType.
    So I added the function getCurrentPlatform that returns
    dict->upperName (which is set in NewDataDictionary in
    adodb.inc.php) and modify the regular expression in
    supportedPlatform(...) to accept both
    ADOConnection->databaseType and the one returned by
    getCurrentPlatform().

     
  • Jakub Holý

    Jakub Holý - 2005-12-06

    axmls dtd with the sequence element and comments

     

Log in to post a comment.