예제 #1
0
 /**
  * Builds the XML structure to export.
  *
  * @return  array  An array of XML lines (strings).
  *
  * @since   12.1
  * @throws  Exception if an error occurs.
  */
 protected function buildXmlStructure()
 {
     $buffer = array();
     foreach ($this->from as $table) {
         // Replace the magic prefix if found.
         $table = $this->getGenericTableName($table);
         // Get the details columns information.
         $fields = $this->db->getTableColumns($table, false);
         $keys = $this->db->getTableKeys($table);
         $sequences = $this->db->getTableSequences($table);
         $buffer[] = '  <table_structure name="' . $table . '">';
         foreach ($sequences as $sequence) {
             if (version_compare($this->db->getVersion(), '9.1.0') < 0) {
                 $sequence->start_value = null;
             }
             $buffer[] = '   <sequence Name="' . $sequence->sequence . '"' . ' Schema="' . $sequence->schema . '"' . ' Table="' . $sequence->table . '"' . ' Column="' . $sequence->column . '"' . ' Type="' . $sequence->data_type . '"' . ' Start_Value="' . $sequence->start_value . '"' . ' Min_Value="' . $sequence->minimum_value . '"' . ' Max_Value="' . $sequence->maximum_value . '"' . ' Increment="' . $sequence->increment . '"' . ' Cycle_option="' . $sequence->cycle_option . '"' . ' />';
         }
         foreach ($fields as $field) {
             $buffer[] = '   <field Field="' . $field->column_name . '"' . ' Type="' . $field->type . '"' . ' Null="' . $field->null . '"' . (isset($field->default) ? ' Default="' . $field->default . '"' : '') . ' Comments="' . $field->comments . '"' . ' />';
         }
         foreach ($keys as $key) {
             $buffer[] = '   <key Index="' . $key->idxName . '"' . ' is_primary="' . $key->isPrimary . '"' . ' is_unique="' . $key->isUnique . '"' . ' Query="' . $key->Query . '" />';
         }
         $buffer[] = '  </table_structure>';
     }
     return $buffer;
 }
예제 #2
0
 /**
  * Get alters for table if there is a difference.
  *
  * @param   SimpleXMLElement  $structure  The XML structure of the table.
  *
  * @return  array
  *
  * @since   12.1
  */
 protected function getAlterTableSQL(SimpleXMLElement $structure)
 {
     // Initialise variables.
     $table = $this->getRealTableName($structure['name']);
     $oldFields = $this->db->getTableColumns($table);
     $oldKeys = $this->db->getTableKeys($table);
     $oldSequence = $this->db->getTableSequences($table);
     $alters = array();
     // Get the fields and keys from the XML that we are aiming for.
     $newFields = $structure->xpath('field');
     $newKeys = $structure->xpath('key');
     $newSequence = $structure->xpath('sequence');
     /* Sequence section */
     $oldSeq = $this->getSeqLookup($oldSequence);
     $newSequenceLook = $this->getSeqLookup($newSequence);
     foreach ($newSequenceLook as $kSeqName => $vSeq) {
         if (isset($oldSeq[$kSeqName])) {
             // The field exists, check it's the same.
             $column = $oldSeq[$kSeqName][0];
             /* For older database version that doesn't support these fields use default values */
             if (version_compare($this->db->getVersion(), '9.1.0') < 0) {
                 $column->Min_Value = '1';
                 $column->Max_Value = '9223372036854775807';
                 $column->Increment = '1';
                 $column->Cycle_option = 'NO';
                 $column->Start_Value = '1';
             }
             // Test whether there is a change.
             $change = (string) $vSeq[0]['Type'] != $column->Type || (string) $vSeq[0]['Start_Value'] != $column->Start_Value || (string) $vSeq[0]['Min_Value'] != $column->Min_Value || (string) $vSeq[0]['Max_Value'] != $column->Max_Value || (string) $vSeq[0]['Increment'] != $column->Increment || (string) $vSeq[0]['Cycle_option'] != $column->Cycle_option || (string) $vSeq[0]['Table'] != $column->Table || (string) $vSeq[0]['Column'] != $column->Column || (string) $vSeq[0]['Schema'] != $column->Schema || (string) $vSeq[0]['Name'] != $column->Name;
             if ($change) {
                 $alters[] = $this->getChangeSequenceSQL($kSeqName, $vSeq);
             }
             // Unset this field so that what we have left are fields that need to be removed.
             unset($oldSeq[$kSeqName]);
         } else {
             // The sequence is new
             $alters[] = $this->getAddSequenceSQL($newSequenceLook[$kSeqName][0]);
         }
     }
     // Any sequences left are orphans
     foreach ($oldSeq as $name => $column) {
         // Delete the sequence.
         $alters[] = $this->getDropSequenceSQL($name);
     }
     /* Field section */
     // Loop through each field in the new structure.
     foreach ($newFields as $field) {
         $fName = (string) $field['Field'];
         if (isset($oldFields[$fName])) {
             // The field exists, check it's the same.
             $column = $oldFields[$fName];
             // Test whether there is a change.
             $change = (string) $field['Type'] != $column->Type || (string) $field['Null'] != $column->Null || (string) $field['Default'] != $column->Default;
             if ($change) {
                 $alters[] = $this->getChangeColumnSQL($table, $field);
             }
             // Unset this field so that what we have left are fields that need to be removed.
             unset($oldFields[$fName]);
         } else {
             // The field is new.
             $alters[] = $this->getAddColumnSQL($table, $field);
         }
     }
     // Any columns left are orphans
     foreach ($oldFields as $name => $column) {
         // Delete the column.
         $alters[] = $this->getDropColumnSQL($table, $name);
     }
     /* Index section */
     // Get the lookups for the old and new keys
     $oldLookup = $this->getIdxLookup($oldKeys);
     $newLookup = $this->getIdxLookup($newKeys);
     // Loop through each key in the new structure.
     foreach ($newLookup as $name => $keys) {
         // Check if there are keys on this field in the existing table.
         if (isset($oldLookup[$name])) {
             $same = true;
             $newCount = count($newLookup[$name]);
             $oldCount = count($oldLookup[$name]);
             // There is a key on this field in the old and new tables. Are they the same?
             if ($newCount == $oldCount) {
                 for ($i = 0; $i < $newCount; $i++) {
                     // Check only query field -> different query means different index
                     $same = (string) $newLookup[$name][$i]['Query'] == $oldLookup[$name][$i]->Query;
                     if (!$same) {
                         // Break out of the loop. No need to check further.
                         break;
                     }
                 }
             } else {
                 // Count is different, just drop and add.
                 $same = false;
             }
             if (!$same) {
                 $alters[] = $this->getDropIndexSQL($name);
                 $alters[] = (string) $newLookup[$name][0]['Query'];
             }
             // Unset this field so that what we have left are fields that need to be removed.
             unset($oldLookup[$name]);
         } else {
             // This is a new key.
             $alters[] = (string) $newLookup[$name][0]['Query'];
         }
     }
     // Any keys left are orphans.
     foreach ($oldLookup as $name => $keys) {
         if ($oldLookup[$name][0]->is_primary == 'TRUE') {
             $alters[] = $this->getDropPrimaryKeySQL($table, $oldLookup[$name][0]->Index);
         } else {
             $alters[] = $this->getDropIndexSQL($name);
         }
     }
     return $alters;
 }