10 defined(
'JPATH_PLATFORM') or die;
29 public function check()
34 throw new Exception(
'JPLATFORM_ERROR_DATABASE_CONNECTOR_WRONG_TYPE');
38 if (empty($this->from))
40 throw new Exception(
'JPLATFORM_ERROR_NO_TABLES_SPECIFIED');
56 protected function getAddColumnSQL($table, SimpleXMLElement $field)
58 return 'ALTER TABLE ' . $this->db->quoteName($table) .
' ADD COLUMN ' . $this->getColumnSQL($field);
70 protected function getAddIndexSQL(SimpleXMLElement $field)
72 return (
string) $field[
'Query'];
84 protected function getAlterTableSQL(SimpleXMLElement $structure)
86 $table = $this->getRealTableName($structure[
'name']);
87 $oldFields = $this->db->getTableColumns($table);
88 $oldKeys = $this->db->getTableKeys($table);
89 $oldSequence = $this->db->getTableSequences($table);
93 $newFields = $structure->xpath(
'field');
94 $newKeys = $structure->xpath(
'key');
95 $newSequence = $structure->xpath(
'sequence');
98 $oldSeq = $this->getSeqLookup($oldSequence);
99 $newSequenceLook = $this->getSeqLookup($newSequence);
101 foreach ($newSequenceLook as $kSeqName => $vSeq)
103 if (isset($oldSeq[$kSeqName]))
106 $column = $oldSeq[$kSeqName][0];
109 if (version_compare($this->db->getVersion(),
'9.1.0') < 0)
111 $column->Min_Value =
'1';
112 $column->Max_Value =
'9223372036854775807';
113 $column->Increment =
'1';
114 $column->Cycle_option =
'NO';
115 $column->Start_Value =
'1';
119 $change = ((string) $vSeq[0][
'Type'] != $column->Type) || ((string) $vSeq[0][
'Start_Value'] != $column->Start_Value)
120 || ((string) $vSeq[0][
'Min_Value'] != $column->Min_Value) || ((string) $vSeq[0][
'Max_Value'] != $column->Max_Value)
121 || ((string) $vSeq[0][
'Increment'] != $column->Increment) || ((string) $vSeq[0][
'Cycle_option'] != $column->Cycle_option)
122 || ((string) $vSeq[0][
'Table'] != $column->Table) || ((string) $vSeq[0][
'Column'] != $column->Column)
123 || ((string) $vSeq[0][
'Schema'] != $column->Schema) || ((string) $vSeq[0][
'Name'] != $column->Name);
127 $alters[] = $this->getChangeSequenceSQL($kSeqName, $vSeq);
131 unset($oldSeq[$kSeqName]);
136 $alters[] = $this->getAddSequenceSQL($newSequenceLook[$kSeqName][0]);
141 foreach ($oldSeq as $name => $column)
144 $alters[] = $this->getDropSequenceSQL($name);
149 foreach ($newFields as $field)
151 $fName = (string) $field[
'Field'];
153 if (isset($oldFields[$fName]))
156 $column = $oldFields[$fName];
159 $change = ((string) $field[
'Type'] != $column->Type) || ((string) $field[
'Null'] != $column->Null)
160 || ((string) $field[
'Default'] != $column->Default);
164 $alters[] = $this->getChangeColumnSQL($table, $field);
168 unset($oldFields[$fName]);
173 $alters[] = $this->getAddColumnSQL($table, $field);
178 foreach ($oldFields as $name => $column)
181 $alters[] = $this->getDropColumnSQL($table, $name);
186 $oldLookup = $this->getIdxLookup($oldKeys);
187 $newLookup = $this->getIdxLookup($newKeys);
190 foreach ($newLookup as $name => $keys)
193 if (isset($oldLookup[$name]))
196 $newCount = count($newLookup[$name]);
197 $oldCount = count($oldLookup[$name]);
200 if ($newCount == $oldCount)
202 for ($i = 0; $i < $newCount; $i++)
205 $same = ((string) $newLookup[$name][$i][
'Query'] == $oldLookup[$name][$i]->Query);
222 $alters[] = $this->getDropIndexSQL($name);
223 $alters[] = (string) $newLookup[$name][0][
'Query'];
227 unset($oldLookup[$name]);
232 $alters[] = (string) $newLookup[$name][0][
'Query'];
237 foreach ($oldLookup as $name => $keys)
239 if ($oldLookup[$name][0]->is_primary ==
'TRUE')
241 $alters[] = $this->getDropPrimaryKeySQL($table, $oldLookup[$name][0]->Index);
245 $alters[] = $this->getDropIndexSQL($name);
261 protected function getDropSequenceSQL($name)
263 return 'DROP SEQUENCE ' . $this->db->quoteName($name);
275 protected function getAddSequenceSQL($field)
278 if (version_compare($this->db->getVersion(),
'9.1.0') < 0)
280 $field[
'Min_Value'] =
'1';
281 $field[
'Max_Value'] =
'9223372036854775807';
282 $field[
'Increment'] =
'1';
283 $field[
'Cycle_option'] =
'NO';
284 $field[
'Start_Value'] =
'1';
287 return 'CREATE SEQUENCE ' . (string) $field[
'Name'] .
288 ' INCREMENT BY ' . (
string) $field[
'Increment'] .
' MINVALUE ' . $field[
'Min_Value'] .
289 ' MAXVALUE ' . (string) $field[
'Max_Value'] .
' START ' . (
string) $field[
'Start_Value'] .
290 (((string) $field[
'Cycle_option'] ==
'NO') ?
' NO' :
'') .
' CYCLE' .
291 ' OWNED BY ' . $this->db->quoteName((
string) $field[
'Schema'] .
'.' . (
string) $field[
'Table'] .
'.' . (
string) $field[
'Column']);
303 protected function getChangeSequenceSQL($field)
306 if (version_compare($this->db->getVersion(),
'9.1.0') < 0)
308 $field[
'Min_Value'] =
'1';
309 $field[
'Max_Value'] =
'9223372036854775807';
310 $field[
'Increment'] =
'1';
311 $field[
'Cycle_option'] =
'NO';
312 $field[
'Start_Value'] =
'1';
315 return 'ALTER SEQUENCE ' . (string) $field[
'Name'] .
316 ' INCREMENT BY ' . (
string) $field[
'Increment'] .
' MINVALUE ' . (string) $field[
'Min_Value'] .
317 ' MAXVALUE ' . (
string) $field[
'Max_Value'] .
' START ' . (string) $field[
'Start_Value'] .
318 ' OWNED BY ' . $this->db->quoteName((
string) $field[
'Schema'] .
'.' . (
string) $field[
'Table'] .
'.' . (
string) $field[
'Column']);
331 protected function getChangeColumnSQL($table, SimpleXMLElement $field)
333 return 'ALTER TABLE ' . $this->db->quoteName($table) .
' ALTER COLUMN ' . $this->db->quoteName((
string) $field[
'Field']) .
' '
334 . $this->getAlterColumnSQL($table, $field);
347 protected function getAlterColumnSQL($table, $field)
350 $blobs = array(
'text',
'smalltext',
'mediumtext',
'largetext');
352 $fName = (string) $field[
'Field'];
353 $fType = (string) $field[
'Type'];
354 $fNull = (string) $field[
'Null'];
355 $fDefault = (isset($field[
'Default']) && $field[
'Default'] !=
'NULL' ) ?
356 preg_match(
'/^[0-9]$/', $field[
'Default']) ? $field[
'Default'] : $this->db->quote((
string) $field[
'Default'])
359 $query =
' TYPE ' . $fType;
363 if (in_array($fType, $blobs) || $fDefault === null)
365 $query .=
",\nALTER COLUMN " . $this->db->quoteName($fName) .
' SET NOT NULL' .
366 ",\nALTER COLUMN " . $this->db->quoteName($fName) .
' DROP DEFAULT';
370 $query .=
",\nALTER COLUMN " . $this->db->quoteName($fName) .
' SET NOT NULL' .
371 ",\nALTER COLUMN " . $this->db->quoteName($fName) .
' SET DEFAULT ' . $fDefault;
376 if ($fDefault !== null)
378 $query .=
",\nALTER COLUMN " . $this->db->quoteName($fName) .
' DROP NOT NULL' .
379 ",\nALTER COLUMN " . $this->db->quoteName($fName) .
' SET DEFAULT ' . $fDefault;
384 if (strpos($fDefault,
'nextval') !==
false)
386 $query .=
";\nALTER SEQUENCE " . $this->db->quoteName($table .
'_' . $fName .
'_seq') .
' OWNED BY ' . $this->db->quoteName($table .
'.' . $fName);
401 protected function getColumnSQL(SimpleXMLElement $field)
404 $blobs = array(
'text',
'smalltext',
'mediumtext',
'largetext');
406 $fName = (string) $field[
'Field'];
407 $fType = (string) $field[
'Type'];
408 $fNull = (string) $field[
'Null'];
409 $fDefault = (isset($field[
'Default']) && $field[
'Default'] !=
'NULL' ) ?
410 preg_match(
'/^[0-9]$/', $field[
'Default']) ? $field[
'Default'] : $this->db->quote((
string) $field[
'Default'])
414 if (strpos($fDefault,
'nextval') !==
false)
416 $query = $this->db->quoteName($fName) .
' SERIAL';
420 $query = $this->db->quoteName($fName) .
' ' . $fType;
424 if (in_array($fType, $blobs) || $fDefault === null)
426 $query .=
' NOT NULL';
430 $query .=
' NOT NULL DEFAULT ' . $fDefault;
435 if ($fDefault !== null)
437 $query .=
' DEFAULT ' . $fDefault;
454 protected function getDropIndexSQL($name)
456 return 'DROP INDEX ' . $this->db->quoteName($name);
469 protected function getDropPrimaryKeySQL($table, $name)
471 return 'ALTER TABLE ONLY ' . $this->db->quoteName($table) .
' DROP CONSTRAINT ' . $this->db->quoteName($name);
484 protected function getIdxLookup($keys)
489 foreach ($keys as $key)
491 if ($key instanceof SimpleXMLElement)
493 $kName = (string) $key[
'Index'];
497 $kName = $key->Index;
500 if (empty($lookup[$kName]))
502 $lookup[$kName] = array();
505 $lookup[$kName][] = $key;
521 protected function getSeqLookup($sequences)
526 foreach ($sequences as $seq)
528 if ($seq instanceof SimpleXMLElement)
530 $sName = (string) $seq[
'Name'];
537 if (empty($lookup[$sName]))
539 $lookup[$sName] = array();
542 $lookup[$sName][] = $seq;