Ticket #986 (closed defect: fixed)

Opened 23 months ago

Last modified 23 months ago

exportClassesSql should be using array_reverse not rsort

Reported by: wizhippo Owned by: jwage
Priority: major Milestone: 0.11.0
Component: Import/Export Version: 0.11.0
Severity: Keywords:
Cc: Has Test:
Status: Has Patch:

Description (last modified by wizhippo) (diff)

Using rsort make indexes to be created first as CREATE UNIQUE INDEX is alphbeticaly after CREATE TABLE. This fails as you have to have the table first.

Also the results of $this->conn->export->createTableSql() needs to be array_reverse'd also to you get correct order of sql queries.

this may help get rid of the the hack in exportClasses mentioned in the comments

     * exportClasses
     * method for exporting Doctrine_Record classes to a schema
     *
     * FIXME: This function has ugly hacks in it to make sure sql is inserted in the correct order.

here is my fixed version for exportClassesSql

    public function exportClassesSql(array $classes)
    {
        $models = Doctrine::filterInvalidModels($classes);
        
        $sql = array();
        
        foreach ($models as $name) {
            $record = new $name();
            $table  = $record->getTable();

            $parents = $table->getOption('joinedParents');

            foreach ($parents as $parent) {
                $data  = $table->getConnection()->getTable($parent)->getExportableFormat();

                $query = $this->conn->export->createTableSql($data['tableName'], $data['columns'], $data['options']);
                $query = array_reverse($query);
                $sql = array_merge($sql, (array) $query);
            }

            $data = $table->getExportableFormat();

            $query = $this->conn->export->createTableSql($data['tableName'], $data['columns'], $data['options']);

            if (is_array($query)) {
				$query = array_reverse($query);
                $sql = array_merge($sql, $query);
            } else {
                $sql[] = $query;
            }
            
            if ($table->getAttribute(Doctrine::ATTR_EXPORT) & Doctrine::EXPORT_PLUGINS) {
                $query = $this->exportGeneratorsSql($table);                
                $query = array_reverse($query);
                $sql = array_merge($sql, $query);
            }
        }
        
        $sql = array_unique($sql);
        
        $sql = array_reverse($sql);

        return $sql;
    }

My results before my fix

CREATE UNIQUE INDEX profiletype_uidx ON profiletype (description);
CREATE TABLE profiletype (profiletypeid BIGINT NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY(profiletypeid));
CREATE TABLE profile (profileid BIGINT NOT NULL, profiletypeid BIGINT NOT NULL, status VARCHAR(1) NOT NULL, commonname VARCHAR(255) NOT NULL, firstname VARCHAR(80) NOT NULL, lastname VARCHAR(80) NOT NULL, middlename VARCHAR(80), birthdate DATE, PRIMARY KEY(profileid));
CREATE TABLE agent (profileid BIGINT NOT NULL, payeename VARCHAR(255), PRIMARY KEY(profileid));
CREATE TABLE addresstype (addresstypeid BIGINT NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY(addresstypeid));
CREATE TABLE address (addressid BIGINT NOT NULL, addresstypeid BIGINT NOT NULL, profileid BIGINT NOT NULL, address1 VARCHAR(255) NOT NULL, address2 VARCHAR(255) NOT NULL, city VARCHAR(255) NOT NULL, province VARCHAR(80) NOT NULL, postalcode VARCHAR(20) NOT NULL, country VARCHAR(80), apt VARCHAR(80), description VARCHAR(80), PRIMARY KEY(addressid));
ALTER TABLE profile ADD FOREIGN KEY (profileTypeId) REFERENCES profiletype(profileTypeId) NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE agent ADD FOREIGN KEY (profileTypeId) REFERENCES profiletype(profileTypeId) NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE address ADD FOREIGN KEY (profileId) REFERENCES profile(profileId) NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE address ADD FOREIGN KEY (addressTypeId) REFERENCES addresstype(addressTypeId) NOT DEFERRABLE INITIALLY IMMEDIATE;

My results after my fix

CREATE TABLE profiletype (profiletypeid BIGINT NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY(profiletypeid));
CREATE UNIQUE INDEX profiletype_uidx ON profiletype (description);
CREATE TABLE addresstype (addresstypeid BIGINT NOT NULL, description VARCHAR(255) NOT NULL, PRIMARY KEY(addresstypeid));
CREATE TABLE address (addressid BIGINT NOT NULL, addresstypeid BIGINT NOT NULL, profileid BIGINT NOT NULL, address1 VARCHAR(255) NOT NULL, address2 VARCHAR(255) NOT NULL, city VARCHAR(255) NOT NULL, province VARCHAR(80) NOT NULL, postalcode VARCHAR(20) NOT NULL, country VARCHAR(80), apt VARCHAR(80), description VARCHAR(80), PRIMARY KEY(addressid));
ALTER TABLE address ADD FOREIGN KEY (addressTypeId) REFERENCES addresstype(addressTypeId) NOT DEFERRABLE INITIALLY IMMEDIATE;
ALTER TABLE address ADD FOREIGN KEY (profileId) REFERENCES profile(profileId) NOT DEFERRABLE INITIALLY IMMEDIATE;
CREATE TABLE agent (profileid BIGINT NOT NULL, payeename VARCHAR(255), PRIMARY KEY(profileid));
ALTER TABLE agent ADD FOREIGN KEY (profileTypeId) REFERENCES profiletype(profileTypeId) NOT DEFERRABLE INITIALLY IMMEDIATE;
CREATE TABLE profile (profileid BIGINT NOT NULL, profiletypeid BIGINT NOT NULL, status VARCHAR(1) NOT NULL, commonname VARCHAR(255) NOT NULL, firstname VARCHAR(80) NOT NULL, lastname VARCHAR(80) NOT NULL, middlename VARCHAR(80), birthdate DATE, PRIMARY KEY(profileid));
ALTER TABLE profile ADD FOREIGN KEY (profileTypeId) REFERENCES profiletype(profileTypeId) NOT DEFERRABLE INITIALLY IMMEDIATE;

You may note ALTER TABLE agent ADD FOREIGN KEY (profileTypeId) REFERENCES profiletype(profileTypeId) NOT DEFERRABLE INITIALLY IMMEDIATE; should not exist as it inherits from profile. This is another bug I have yet to report.

Reviewing my fix i see

$query = array_reverse($query); $sql = array_merge($sql, (array) $query);

Tests will have to be added to ensure array_reverse is only done on arrays.

Change History

Changed 23 months ago by wizhippo

  • description modified (diff)

Changed 23 months ago by jwage

  • status changed from new to closed
  • resolution set to fixed

(In [4310]) fixes #986

Note: See TracTickets for help on using tickets.