/** * This function IS NOT IMPLEMENTED. ONCE WE'LL BE USING RELATIONAL * INTEGRITY IT WILL BECOME MORE USEFUL. FOR NOW, JUST CALCULATE "OFFICIAL" * KEY NAMES WITHOUT ACCESSING TO DB AT ALL. * Given one xmldb_key, the function returns the name of the key in DB (if exists) * of false if it doesn't exist * * @param xmldb_table $xmldb_table The table to be searched. * @param xmldb_key $xmldb_key The key to be searched. * @return string key name if found */ public function find_key_name(xmldb_table $xmldb_table, xmldb_key $xmldb_key) { $keycolumns = $xmldb_key->getFields(); // Get list of keys in table // first primaries (we aren't going to use this now, because the MetaPrimaryKeys is awful) //TODO: To implement when we advance in relational integrity // then uniques (note that Moodle, for now, shouldn't have any UNIQUE KEY for now, but unique indexes) //TODO: To implement when we advance in relational integrity (note that AdoDB hasn't any MetaXXX for this. // then foreign (note that Moodle, for now, shouldn't have any FOREIGN KEY for now, but indexes) //TODO: To implement when we advance in relational integrity (note that AdoDB has one MetaForeignKeys() //but it's far from perfect. // TODO: To create the proper functions inside each generator to retrieve all the needed KEY info (name // columns, reftable and refcolumns // So all we do is to return the official name of the requested key without any confirmation!) // One exception, hardcoded primary constraint names if ($this->generator->primary_key_name && $xmldb_key->getType() == XMLDB_KEY_PRIMARY) { return $this->generator->primary_key_name; } else { // Calculate the name suffix switch ($xmldb_key->getType()) { case XMLDB_KEY_PRIMARY: $suffix = 'pk'; break; case XMLDB_KEY_UNIQUE: $suffix = 'uk'; break; case XMLDB_KEY_FOREIGN_UNIQUE: case XMLDB_KEY_FOREIGN: $suffix = 'fk'; break; } // And simply, return the official name return $this->generator->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), $suffix); } }
/** * Given one correct xmldb_key, returns its specs. * * @param xmldb_table $xmldb_table The table related to $xmldb_key. * @param xmldb_key $xmldb_key The xmldb_key's specifications requested. * @return string SQL statement about the xmldb_key. */ public function getKeySQL($xmldb_table, $xmldb_key) { $key = ''; switch ($xmldb_key->getType()) { case XMLDB_KEY_PRIMARY: if ($this->primary_keys) { if ($this->primary_key_name !== null) { $key = $this->getEncQuoted($this->primary_key_name); } else { $key = $this->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), 'pk'); } $key .= ' PRIMARY KEY (' . implode(', ', $this->getEncQuoted($xmldb_key->getFields())) . ')'; } break; case XMLDB_KEY_UNIQUE: if ($this->unique_keys) { $key = $this->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), 'uk'); $key .= ' UNIQUE (' . implode(', ', $this->getEncQuoted($xmldb_key->getFields())) . ')'; } break; case XMLDB_KEY_FOREIGN: case XMLDB_KEY_FOREIGN_UNIQUE: if ($this->foreign_keys) { $key = $this->getNameForObject($xmldb_table->getName(), implode(', ', $xmldb_key->getFields()), 'fk'); $key .= ' FOREIGN KEY (' . implode(', ', $this->getEncQuoted($xmldb_key->getFields())) . ')'; $key .= ' REFERENCES ' . $this->getEncQuoted($this->prefix . $xmldb_key->getRefTable()); $key .= ' (' . implode(', ', $this->getEncQuoted($xmldb_key->getRefFields())) . ')'; } break; } return $key; }
/** * Add one key to the table, allowing to specify the desired order * If it's not specified, then the key is added at the end * @param xmldb_key $key * @param xmldb_object $after */ public function addKey($key, $after = null) { // Detect duplicates first if ($this->getKey($key->getName())) { throw new coding_exception('Duplicate key ' . $key->getName() . ' specified in table ' . $this->getName()); } // Make sure there are no indexes with the key column specs because they would collide. $newfields = $key->getFields(); $allindexes = $this->getIndexes(); foreach ($allindexes as $index) { $fields = $index->getFields(); if ($fields === $newfields) { throw new coding_exception('Index ' . $index->getName() . ' collides with key' . $key->getName() . ' specified in table ' . $this->getName()); } } // Calculate the previous and next keys $prevkey = null; $nextkey = null; if (!$after) { $allkeys = $this->getKeys(); if (!empty($allkeys)) { end($allkeys); $prevkey = $allkeys[key($allkeys)]; } } else { $prevkey = $this->getKey($after); } if ($prevkey && $prevkey->getNext()) { $nextkey = $this->getKey($prevkey->getNext()); } // Set current key previous and next attributes if ($prevkey) { $key->setPrevious($prevkey->getName()); $prevkey->setNext($key->getName()); } if ($nextkey) { $key->setNext($nextkey->getName()); $nextkey->setPrevious($key->getName()); } // Some more attributes $key->setLoaded(true); $key->setChanged(true); // Add the new key $this->keys[] = $key; // Reorder the keys $this->orderKeys($this->keys); // Recalculate the hash $this->calculateHash(true); // We have one new field, so the table has changed $this->setChanged(true); }