/** * Add the content of a Criteria to the current Criteria * In case of conflict, the current Criteria keeps its properties * * @param Criteria $criteria The criteria to read properties from * @param string $operator The logical operator used to combine conditions * Defaults to Criteria::LOGICAL_AND, also accapts Criteria::LOGICAL_OR * This parameter is deprecated, use _or() instead * * @return Criteria The current criteria object */ public function mergeWith(Criteria $criteria, $operator = null) { // merge limit $limit = $criteria->getLimit(); if ($limit != 0 && $this->getLimit() == 0) { $this->limit = $limit; } // merge offset $offset = $criteria->getOffset(); if ($offset != 0 && $this->getOffset() == 0) { $this->offset = $offset; } // merge select modifiers $selectModifiers = $criteria->getSelectModifiers(); if ($selectModifiers && !$this->selectModifiers) { $this->selectModifiers = $selectModifiers; } // merge select columns $this->selectColumns = array_merge($this->getSelectColumns(), $criteria->getSelectColumns()); // merge as columns $commonAsColumns = array_intersect_key($this->getAsColumns(), $criteria->getAsColumns()); if (!empty($commonAsColumns)) { throw new PropelException('The given criteria contains an AsColumn with an alias already existing in the current object'); } $this->asColumns = array_merge($this->getAsColumns(), $criteria->getAsColumns()); // merge orderByColumns $orderByColumns = array_merge($this->getOrderByColumns(), $criteria->getOrderByColumns()); $this->orderByColumns = array_unique($orderByColumns); // merge groupByColumns $groupByColumns = array_merge($this->getGroupByColumns(), $criteria->getGroupByColumns()); $this->groupByColumns = array_unique($groupByColumns); // merge where conditions if ($operator == Criteria::LOGICAL_OR) { $this->_or(); } $isFirstCondition = true; foreach ($criteria->getMap() as $key => $criterion) { if ($isFirstCondition && $this->defaultCombineOperator == Criteria::LOGICAL_OR) { $this->addOr($criterion, null, null, false); $this->defaultCombineOperator == Criteria::LOGICAL_AND; } elseif ($this->containsKey($key)) { $this->addAnd($criterion); } else { $this->add($criterion); } $isFirstCondition = false; } // merge having if ($having = $criteria->getHaving()) { if ($this->getHaving()) { $this->addHaving($this->getHaving()->addAnd($having)); } else { $this->addHaving($having); } } // merge alias $commonAliases = array_intersect_key($this->getAliases(), $criteria->getAliases()); if (!empty($commonAliases)) { throw new PropelException('The given criteria contains an alias already existing in the current object'); } $this->aliases = array_merge($this->getAliases(), $criteria->getAliases()); // merge join $this->joins = array_merge($this->getJoins(), $criteria->getJoins()); return $this; }
/** * Tests adding duplicate joins. * @link http://propel.phpdb.org/trac/ticket/613 */ public function testAddJoin_Duplicate() { $c = new Criteria(); $c->addJoin("tbl.COL1", "tbl.COL2", Criteria::LEFT_JOIN); $c->addJoin("tbl.COL1", "tbl.COL2", Criteria::LEFT_JOIN); $this->assertEquals(1, count($c->getJoins()), "Expected not to have duplciate LJOIN added."); $c->addJoin("tbl.COL1", "tbl.COL2", Criteria::RIGHT_JOIN); $c->addJoin("tbl.COL1", "tbl.COL2", Criteria::RIGHT_JOIN); $this->assertEquals(2, count($c->getJoins()), "Expected 1 new right join to be added."); $c->addJoin("tbl.COL1", "tbl.COL2"); $c->addJoin("tbl.COL1", "tbl.COL2"); $this->assertEquals(3, count($c->getJoins()), "Expected 1 new implicit join to be added."); $c->addJoin("tbl.COL3", "tbl.COL4"); $this->assertEquals(4, count($c->getJoins()), "Expected new col join to be added."); }
/** * Method to perform deletes based on values and keys in a * Criteria. * * @param Criteria $criteria The criteria to use. * @param ConnectionInterface $con A ConnectionInterface connection object. * @return int The number of rows affected by last statement execution. For most * uses there is only one delete statement executed, so this number * will correspond to the number of rows affected by the call to this * method. Note that the return value does require that this information * is returned (supported) by the PDO driver. * @throws \Propel\Runtime\Exception\RuntimeException */ public static function doDelete(Criteria $criteria, ConnectionInterface $con) { $db = Propel::getServiceContainer()->getAdapter($criteria->getDbName()); $dbMap = Propel::getServiceContainer()->getDatabaseMap($criteria->getDbName()); //join are not supported with DELETE statement if (count($criteria->getJoins())) { throw new RuntimeException('Delete does not support join'); } // Set up a list of required tables (one DELETE statement will // be executed per table) $tables = $criteria->getTablesColumns(); if (empty($tables)) { throw new RuntimeException("Cannot delete from an empty Criteria"); } $affectedRows = 0; // initialize this in case the next loop has no iterations. foreach ($tables as $tableName => $columns) { $whereClause = array(); $params = array(); $stmt = null; try { $sql = $db->getDeleteFromClause($criteria, $tableName); foreach ($columns as $colName) { $sb = ""; $criteria->getCriterion($colName)->appendPsTo($sb, $params); $whereClause[] = $sb; } $sql .= " WHERE " . implode(" AND ", $whereClause); $stmt = $con->prepare($sql); $db->bindValues($stmt, $params, $dbMap); $stmt->execute(); $affectedRows = $stmt->rowCount(); } catch (Exception $e) { Propel::log($e->getMessage(), Propel::LOG_ERR); throw new RuntimeException(sprintf('Unable to execute DELETE statement [%s]', $sql), 0, $e); } } // for each table return $affectedRows; }
public function testMergeWithJoins() { $c1 = new Criteria(); $c1->addJoin(BookPeer::AUTHOR_ID, AuthorPeer::ID, Criteria::LEFT_JOIN); $c2 = new Criteria(); $c1->mergeWith($c2); $joins = $c1->getJoins(); $this->assertEquals(1, count($joins), 'mergeWith() does not remove an existing join'); $this->assertEquals('LEFT JOIN author ON (book.AUTHOR_ID=author.ID)', $joins[0]->toString(), 'mergeWith() does not remove an existing join'); $c1 = new Criteria(); $c2 = new Criteria(); $c2->addJoin(BookPeer::AUTHOR_ID, AuthorPeer::ID, Criteria::LEFT_JOIN); $c1->mergeWith($c2); $joins = $c1->getJoins(); $this->assertEquals(1, count($joins), 'mergeWith() merge joins to an empty join'); $this->assertEquals('LEFT JOIN author ON (book.AUTHOR_ID=author.ID)', $joins[0]->toString(), 'mergeWith() merge joins to an empty join'); $c1 = new Criteria(); $c1->addJoin(BookPeer::AUTHOR_ID, AuthorPeer::ID, Criteria::LEFT_JOIN); $c2 = new Criteria(); $c2->addJoin(BookPeer::PUBLISHER_ID, PublisherPeer::ID, Criteria::INNER_JOIN); $c1->mergeWith($c2); $joins = $c1->getJoins(); $this->assertEquals(2, count($joins), 'mergeWith() merge joins to an existing join'); $this->assertEquals('LEFT JOIN author ON (book.AUTHOR_ID=author.ID)', $joins[0]->toString(), 'mergeWith() merge joins to an empty join'); $this->assertEquals('INNER JOIN publisher ON (book.PUBLISHER_ID=publisher.ID)', $joins[1]->toString(), 'mergeWith() merge joins to an empty join'); }