private function getCompositeKey($record) { $composite = array(); foreach ((array) $this->_table->getIdentifier() as $keyPart) { if (!isset($record[$keyPart])) { return false; } $composite[] = $record[$keyPart]; } return join('-', $composite); }
/** * Populate the relationship $name for all records in the passed collection * * @param string $name * @param Doctrine_Collection $coll * @return void */ public function populateRelated($name, Doctrine_Collection $coll) { $rel = $this->_table->getRelation($name); $table = $rel->getTable(); $foreign = $rel->getForeign(); $local = $rel->getLocal(); if ($rel instanceof Doctrine_Relation_LocalKey) { foreach ($this->data as $key => $record) { foreach ($coll as $k => $related) { if ($related[$foreign] == $record[$local]) { $this->data[$key]->setRelated($name, $related); } } } } elseif ($rel instanceof Doctrine_Relation_ForeignKey) { foreach ($this->data as $key => $record) { if ( ! $record->exists()) { continue; } $sub = Doctrine_Collection::create($table); foreach ($coll as $k => $related) { if ($related[$foreign] == $record[$local]) { $sub->add($related); $coll->remove($k); } } $this->data[$key]->setRelated($name, $sub); } } elseif ($rel instanceof Doctrine_Relation_Association) { $identifier = $this->_table->getIdentifier(); $asf = $rel->getAssociationFactory(); $name = $table->getComponentName(); foreach ($this->data as $key => $record) { if ( ! $record->exists()) { continue; } $sub = Doctrine_Collection::create($table); foreach ($coll as $k => $related) { if ($related->get($local) == $record[$identifier]) { $sub->add($related->get($name)); } } $this->data[$key]->setRelated($name, $sub); } } }
/** * isIdentifiable * returns whether or not a given data row is identifiable (it contains * all primary key fields specified in the second argument) * * @param array $row * @param Doctrine_Table $table * @return boolean */ public function isIdentifiable(array $row, Doctrine_Table $table) { $primaryKeys = $table->getIdentifier(); if (is_array($primaryKeys)) { foreach ($primaryKeys as $id) { if (!isset($row[$id])) { return false; } } } else { if (!isset($row[$primaryKeys])) { return false; } } return true; }
/** * Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT * query, except that if there is already a row in the table with the same * key field values, the REPLACE query just updates its values instead of * inserting a new row. * * The REPLACE type of query does not make part of the SQL standards. Since * practically only MySQL and SQLIte implement it natively, this type of * query isemulated through this method for other DBMS using standard types * of queries inside a transaction to assure the atomicity of the operation. * * @param string name of the table on which the REPLACE query will * be executed. * * @param array an associative array that describes the fields and the * values that will be inserted or updated in the specified table. The * indexes of the array are the names of all the fields of the table. * * The values of the array are values to be assigned to the specified field. * * @param array $keys an array containing all key fields (primary key fields * or unique index fields) for this table * * the uniqueness of a row will be determined according to * the provided key fields * * this method will fail if no key fields are specified * * @throws Doctrine_Connection_Exception if this driver doesn't support replace * @throws Doctrine_Connection_Exception if some of the key values was null * @throws Doctrine_Connection_Exception if there were no key fields * @throws PDOException if something fails at PDO level * @ return integer number of rows affected */ public function replace(Doctrine_Table $table, array $fields, array $keys) { if (empty($keys)) { throw new Doctrine_Connection_Exception('Not specified which fields are keys'); } $identifier = (array) $table->getIdentifier(); $condition = array(); foreach ($fields as $fieldName => $value) { if (in_array($fieldName, $keys)) { if ($value !== null) { $condition[] = $table->getColumnName($fieldName) . ' = ?'; $conditionValues[] = $value; } } } $affectedRows = 0; if (!empty($condition) && !empty($conditionValues)) { $query = 'DELETE FROM ' . $this->quoteIdentifier($table->getTableName()) . ' WHERE ' . implode(' AND ', $condition); $affectedRows = $this->exec($query, $conditionValues); } $this->insert($table, $fields); $affectedRows++; return $affectedRows; }
/** * Generates foreign keys for the plugin table based on the owner table. * These columns are automatically added to the generated model so we can * create foreign keys back to the table object that owns the plugin. * * @param Doctrine_Table $table the table object that owns the plugin * @return array an array of foreign key definitions */ public function buildForeignKeys(Doctrine_Table $table) { $fk = array(); foreach ((array) $table->getIdentifier() as $column) { $def = $table->getDefinitionOf($column); unset($def['autoincrement']); unset($def['sequence']); unset($def['primary']); $col = $column; $def['primary'] = true; $fk[$col] = $def; } return $fk; }
/** * getIdentifiers * gives a list of identifiers from given table * * the identifiers are in format: * [componentName].[identifier] * * @param Doctrine_Table $table table object to retrieve identifiers from */ public function getIdentifiers(Doctrine_Table $table) { $componentNameToLower = strtolower($table->getComponentName()); if (is_array($table->getIdentifier())) { $columns = array(); foreach ((array) $table->getIdentifierColumnNames() as $identColName) { $columns[] = $componentNameToLower . '_' . $identColName; } } else { $columns = $componentNameToLower . '_' . $table->getColumnName($table->getIdentifier()); } return $columns; }
/** * Completes the given definition * * @param array $def definition array to be completed * @return array completed definition array */ public function completeDefinition($def) { $conn = $this->_table->getConnection(); $def['table'] = $conn->getTable($def['class']); $foreignClasses = array_merge($def['table']->getOption('parents'), array($def['class'])); $localClasses = array_merge($this->_table->getOption('parents'), array($this->_table->getComponentName())); if (isset($def['local'])) { if (!isset($def['foreign'])) { // local key is set, but foreign key is not // try to guess the foreign key if ($def['local'] === $this->_table->getIdentifier()) { $def['foreign'] = $this->guessColumns($localClasses, $def['table']); } else { // the foreign field is likely to be the // identifier of the foreign class $def['foreign'] = $def['table']->getIdentifier(); $def['localKey'] = true; } } else { if ($def['local'] !== $this->_table->getIdentifier()) { $def['localKey'] = true; } } } else { if (isset($def['foreign'])) { // local key not set, but foreign key is set // try to guess the local key if ($def['foreign'] === $def['table']->getIdentifier()) { $def['localKey'] = true; try { $def['local'] = $this->guessColumns($foreignClasses, $this->_table); } catch (Doctrine_Relation_Exception $e) { $def['local'] = $this->_table->getIdentifier(); } } else { $def['local'] = $this->_table->getIdentifier(); } } else { // neither local or foreign key is being set // try to guess both keys $conn = $this->_table->getConnection(); // the following loops are needed for covering inheritance foreach ($localClasses as $class) { $table = $conn->getTable($class); $column = strtolower($table->getComponentName()) . '_' . $table->getIdentifier(); foreach ($foreignClasses as $class2) { $table2 = $conn->getTable($class2); if ($table2->hasColumn($column)) { $def['foreign'] = $column; $def['local'] = $table->getIdentifier(); return $def; } } } foreach ($foreignClasses as $class) { $table = $conn->getTable($class); $column = strtolower($table->getComponentName()) . '_' . $table->getIdentifier(); foreach ($localClasses as $class2) { $table2 = $conn->getTable($class2); if ($table2->hasColumn($column)) { $def['foreign'] = $table->getIdentifier(); $def['local'] = $column; $def['localKey'] = true; return $def; } } } // auto-add columns and auto-build relation $columns = array(); foreach ((array) $this->_table->getIdentifier() as $id) { $column = strtolower($table->getComponentName()) . '_' . $id; $col = $this->_table->getDefinitionOf($id); $type = $col['type']; $length = $col['length']; unset($col['type']); unset($col['length']); unset($col['autoincrement']); unset($col['sequence']); unset($col['primary']); $def['table']->setColumn($column, $type, $length, $col); $columns[] = $column; } if (count($columns) > 1) { $def['foreign'] = $columns; } else { $def['foreign'] = $columns[0]; } $def['local'] = $this->_table->getIdentifier(); } } return $def; }