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
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;
}
Logged In: YES
user_id=1046780
function _tag_close:
case 'OPT':
case 'CONSTRAINT':
$this->currentPlatform = true;
$this->tableOptPlatforms = array();
break;
The modified adodb-xmlschema
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().
axmls dtd with the sequence element and comments