/** * Clears and repopulates the DatabaseMap with new TableMap classes * * @param type $name * @param type $tableMapClassNames */ protected function resetDatabaseMap($name, array $tableMapClassNames) { $dbMap = new DatabaseMap($name); foreach ($tableMapClassNames as $tableMapClassName) { $dbMap->addTableFromMapClass($tableMapClassName); } Propel::setDatabaseMap($name, $dbMap); }
/** * Load Map builders. * * @param string $connectionName A connection name. */ protected function loadMapBuilders($connectionName = null) { if (null !== $this->dbMap) { return; } $this->dbMap = Propel::getDatabaseMap($connectionName); $finder = new Finder(); $files = $finder->files()->name('*TableMap.php')->in($this->getRootDir() . '/../'); foreach ($files as $file) { $class = $this->guessFullClassName($file->getRelativePath(), basename($file, '.php')); if (null !== $class) { $this->dbMap->addTableFromMapClass($class); } } }
/** * Adds a RelationMap to the table * * @param string $name The relation name * @param string $tablePhpName The related table name * @param integer $type The relation type (either RelationMap::MANY_TO_ONE, RelationMap::ONE_TO_MANY, or RelationMAp::ONE_TO_ONE) * @param array $columnMapping An associative array mapping column names (local => foreign) * @param string $onDelete SQL behavior upon deletion ('SET NULL', 'CASCADE', ...) * @param string $onUpdate SQL behavior upon update ('SET NULL', 'CASCADE', ...) * @param string $pluralName Optional plural name for *_TO_MANY relationships * * @return RelationMap the built RelationMap object */ public function addRelation($name, $tablePhpName, $type, $columnMapping = array(), $onDelete = null, $onUpdate = null, $pluralName = null) { // note: using phpName for the second table allows the use of DatabaseMap::getTableByPhpName() // and this method autoloads the TableMap if the table isn't loaded yet $relation = new RelationMap($name); $relation->setType($type); $relation->setOnUpdate($onUpdate); $relation->setOnDelete($onDelete); if (null !== $pluralName) { $relation->setPluralName($pluralName); } // set tables if ($type == RelationMap::MANY_TO_ONE) { $relation->setLocalTable($this); $relation->setForeignTable($this->dbMap->getTableByPhpName($tablePhpName)); } else { $relation->setLocalTable($this->dbMap->getTableByPhpName($tablePhpName)); $relation->setForeignTable($this); $columnMapping = array_flip($columnMapping); } // set columns foreach ($columnMapping as $local => $foreign) { $relation->addColumnMapping($relation->getLocalTable()->getColumn($local), $relation->getForeignTable()->getColumn($foreign)); } $this->relations[$name] = $relation; return $relation; }
/** * Load Map builders. * * @param string $connectionName A connection name. */ protected function loadMapBuilders($connectionName = null) { if (null !== $this->dbMap) { return; } $this->dbMap = Propel::getDatabaseMap($connectionName); if (0 === count($this->dbMap->getTables())) { $finder = new Finder(); $files = $finder->files()->name('*TableMap.php')->in($this->getModelSearchPaths($connectionName))->exclude('PropelBundle')->exclude('Tests'); foreach ($files as $file) { $class = $this->guessFullClassName($file->getRelativePath(), basename($file, '.php')); if (null !== $class && $this->isInDatabase($class, $connectionName)) { $this->dbMap->addTableFromMapClass($class); } } } }
/** * @see parent::cleanupSQL() * * @param string $sql * @param array $params * @param Criteria $values * @param DatabaseMap $dbMap */ public function cleanupSQL(&$sql, array &$params, Criteria $values, DatabaseMap $dbMap) { $i = 1; foreach ($params as $param) { $tableName = $param['table']; $columnName = $param['column']; $value = $param['value']; // this is to workaround for a bug with pdo_sqlsrv inserting or updating blobs with null values // http://social.msdn.microsoft.com/Forums/en-US/sqldriverforphp/thread/5a755bdd-41e9-45cb-9166-c9da4475bb94 if (null !== $tableName) { $cMap = $dbMap->getTable($tableName)->getColumn($columnName); if ($value === null && $cMap->isLob()) { $sql = str_replace(":p{$i}", "CONVERT(VARBINARY(MAX), :p{$i})", $sql); } } $i++; } }
/** * Sets the alias for the model in this query * * @param string $modelAlias The model alias * @param boolean $useAliasInSQL Whether to use the alias in the SQL code (false by default) * * @return ModelCriteria The current object, for fluid interface */ public function setModelAlias($modelAlias, $useAliasInSQL = false) { if ($useAliasInSQL) { $this->addAlias($modelAlias, $this->tableMap->getName()); $this->useAliasInSQL = true; } $this->modelAlias = $modelAlias; return $this; }
public function testWipesExistingData() { $author = new \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\BookAuthor(); $author->setName('Some famous author'); $book = new \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\Book(); $book->setName('Armageddon is near')->setBookAuthor($author)->save($this->con); $savedBook = \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\BookPeer::doSelectOne(new \Criteria(), $this->con); $this->assertInstanceOf('Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\Book', $savedBook, 'The fixture has been saved correctly.'); $builder = $this->getMockBuilder('Propel\\PropelBundle\\DataFixtures\\Loader\\DataWiper'); $wipeout = $builder->setMethods(array('loadMapBuilders'))->disableOriginalConstructor()->getMock(); $dbMap = new \DatabaseMap('default'); $dbMap->addTableFromMapClass('Propel\\PropelBundle\\Tests\\Fixtures\\DataFixtures\\Loader\\map\\BookTableMap'); $reflection = new \ReflectionObject($wipeout); $property = $reflection->getProperty('dbMap'); $property->setAccessible(true); $property->setValue($wipeout, $dbMap); $wipeout->expects($this->once())->method('loadMapBuilders'); $wipeout->load(array(), 'default'); $this->assertCount(0, \Propel\PropelBundle\Tests\Fixtures\DataFixtures\Loader\BookPeer::doSelect(new \Criteria(), $this->con)); }
/** * Binds values in a prepared statement. * * This method is designed to work with the BasePeer::createSelectSql() method, which creates * both the SELECT SQL statement and populates a passed-in array of parameter * values that should be substituted. * * <code> * $db = Propel::getDB($criteria->getDbName()); * $sql = BasePeer::createSelectSql($criteria, $params); * $stmt = $con->prepare($sql); * $params = array(); * $db->populateStmtValues($stmt, $params, Propel::getDatabaseMap($critera->getDbName())); * $stmt->execute(); * </code> * * @param PDOStatement $stmt * @param array $params array('column' => ..., 'table' => ..., 'value' => ...) * @param DatabaseMap $dbMap */ public function bindValues(PDOStatement $stmt, array $params, DatabaseMap $dbMap) { $position = 0; foreach ($params as $param) { $position++; $parameter = ':p' . $position; $value = $param['value']; if (null === $value) { $stmt->bindValue($parameter, null, PDO::PARAM_NULL); continue; } $tableName = $param['table']; if (null === $tableName) { $type = isset($param['type']) ? $param['type'] : PDO::PARAM_STR; $stmt->bindValue($parameter, $value, $type); continue; } $cMap = $dbMap->getTable($tableName)->getColumn($param['column']); $this->bindValue($stmt, $parameter, $value, $cMap, $position); } }
/** * Populates values in a prepared statement. * * This method is designed to work with the createSelectSql() method, which creates * both the SELECT SQL statement and populates a passed-in array of parameter * values that should be substituted. * * <code> * $params = array(); * $sql = BasePeer::createSelectSql($criteria, $params); * BasePeer::populateStmtValues($stmt, $params, Propel::getDatabaseMap($critera->getDbName()), Propel::getDB($criteria->getDbName())); * </code> * * @param PDOStatement $stmt * @param array $params array('column' => ..., 'table' => ..., 'value' => ...) * @param DatabaseMap $dbMap * @return int The number of params replaced. * @see createSelectSql() * @see doSelect() */ public static function populateStmtValues(PDOStatement $stmt, array $params, DatabaseMap $dbMap, DBAdapter $db) { $i = 1; foreach ($params as $param) { $tableName = $param['table']; $columnName = $param['column']; $value = $param['value']; if (null === $value) { $stmt->bindValue(':p' . $i++, null, PDO::PARAM_NULL); } elseif (null !== $tableName) { $cMap = $dbMap->getTable($tableName)->getColumn($columnName); $type = $cMap->getType(); $pdoType = $cMap->getPdoType(); // FIXME - This is a temporary hack to get around apparent bugs w/ PDO+MYSQL // See http://pecl.php.net/bugs/bug.php?id=9919 if ($pdoType == PDO::PARAM_BOOL && $db instanceof DBMySQL) { $value = (int) $value; $pdoType = PDO::PARAM_INT; } elseif (is_numeric($value) && $cMap->isEpochTemporal()) { // it's a timestamp that needs to be formatted if ($type == PropelColumnTypes::TIMESTAMP) { $value = date($db->getTimestampFormatter(), $value); } else { if ($type == PropelColumnTypes::DATE) { $value = date($db->getDateFormatter(), $value); } else { if ($type == PropelColumnTypes::TIME) { $value = date($db->getTimeFormatter(), $value); } } } } elseif ($value instanceof DateTime && $cMap->isTemporal()) { // it's a timestamp that needs to be formatted if ($type == PropelColumnTypes::TIMESTAMP || $type == PropelColumnTypes::BU_TIMESTAMP) { $value = $value->format($db->getTimestampFormatter()); } else { if ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::BU_DATE) { $value = $value->format($db->getDateFormatter()); } else { if ($type == PropelColumnTypes::TIME) { $value = $value->format($db->getTimeFormatter()); } } } } elseif (is_resource($value) && $cMap->isLob()) { // we always need to make sure that the stream is rewound, otherwise nothing will // get written to database. rewind($value); } $stmt->bindValue(':p' . $i++, $value, $pdoType); } else { $stmt->bindValue(':p' . $i++, $value); } } // foreach }
/** * Populates values in a prepared statement. * * @param PreparedStatement $stmt * @param array $params array('column' => ..., 'table' => ..., 'value' => ...) * @param DatabaseMap $dbMap * @return int The number of params replaced. */ private static function populateStmtValues($stmt, $params, DatabaseMap $dbMap) { $i = 1; foreach ($params as $param) { $tableName = $param['table']; $columnName = $param['column']; $value = $param['value']; if ($value === null) { $stmt->setNull($i++); } else { $cMap = $dbMap->getTable($tableName)->getColumn($columnName); $setter = 'set' . CreoleTypes::getAffix($cMap->getCreoleType()); $stmt->{$setter}($i++, $value); } } // foreach }
/** * @see parent::cleanupSQL() * * @param string $sql * @param array $params * @param Criteria $values * @param DatabaseMap $dbMap */ public function cleanupSQL(&$sql, array &$params, Criteria $values, DatabaseMap $dbMap) { $i = 1; $paramCols = array(); foreach ($params as $param) { if (null !== $param['table']) { $column = $dbMap->getTable($param['table'])->getColumn($param['column']); /* MSSQL pdo_dblib and pdo_mssql blob values must be converted to hex and then the hex added * to the query string directly. If it goes through PDOStatement::bindValue quotes will cause * an error with the insert or update. */ if (is_resource($param['value']) && $column->isLob()) { // we always need to make sure that the stream is rewound, otherwise nothing will // get written to database. rewind($param['value']); $hexArr = unpack('H*hex', stream_get_contents($param['value'])); $sql = str_replace(":p{$i}", '0x' . $hexArr['hex'], $sql); unset($hexArr); fclose($param['value']); } else { $paramCols[] = $param; } } $i++; } //if we made changes re-number the params if ($params != $paramCols) { $params = $paramCols; unset($paramCols); preg_match_all('/:p\\d/', $sql, $matches); foreach ($matches[0] as $key => $match) { $sql = str_replace($match, ':p' . ($key + 1), $sql); } } }
/** * Populates values in a prepared statement. * * This method is designed to work with the createSelectSql() method, which creates * both the SELECT SQL statement and populates a passed-in array of parameter * values that should be substituted. * * <code> * $params = array(); * $sql = BasePeer::createSelectSql($criteria, $params); * BasePeer::populateStmtValues($stmt, $params, Propel::getDatabaseMap($critera->getDbName()), Propel::getDB($criteria->getDbName())); * </code> * * @param PDOStatement $stmt * @param array $params array('column' => ..., 'table' => ..., 'value' => ...) * @param DatabaseMap $dbMap * @return int The number of params replaced. * @see createSelectSql() * @see doSelect() */ public static function populateStmtValues(PDOStatement $stmt, array $params, DatabaseMap $dbMap, DBAdapter $db) { $i = 1; foreach ($params as $param) { $tableName = $param['table']; $columnName = $param['column']; $value = $param['value']; if (null === $value) { $stmt->bindValue(':p' . $i++, null, PDO::PARAM_NULL); } elseif (null !== $tableName) { $cMap = $dbMap->getTable($tableName)->getColumn($columnName); $type = $cMap->getType(); $pdoType = $cMap->getPdoType(); // FIXME - This is a temporary hack to get around apparent bugs w/ PDO+MYSQL // See http://pecl.php.net/bugs/bug.php?id=9919 if ($pdoType == PDO::PARAM_BOOL && $db instanceof DBMySQL) { $value = (int) $value; $pdoType = PDO::PARAM_INT; } elseif (is_numeric($value) && $cMap->isEpochTemporal()) { // it's a timestamp that needs to be formatted if ($type == PropelColumnTypes::TIMESTAMP) { $value = date($db->getTimestampFormatter(), $value); } else { if ($type == PropelColumnTypes::DATE) { $value = date($db->getDateFormatter(), $value); } else { if ($type == PropelColumnTypes::TIME) { $value = date($db->getTimeFormatter(), $value); } } } } elseif ($value instanceof DateTime && $cMap->isTemporal()) { // it's a timestamp that needs to be formatted if ($type == PropelColumnTypes::TIMESTAMP || $type == PropelColumnTypes::BU_TIMESTAMP) { $value = $value->format($db->getTimestampFormatter()); } else { if ($type == PropelColumnTypes::DATE || $type == PropelColumnTypes::BU_DATE) { $value = $value->format($db->getDateFormatter()); } else { if ($type == PropelColumnTypes::TIME) { $value = $value->format($db->getTimeFormatter()); } } } } elseif (is_resource($value) && $cMap->isLob()) { // we always need to make sure that the stream is rewound, otherwise nothing will // get written to database. rewind($value); } // pdo_sqlsrv must have bind binaries using bindParam so that the PDO::SQLSRV_ENCODING_BINARY // driver option can be utilized. This requires a unique blob parameter because the bindParam // value is passed by reference and if we didn't do this then the referenced parameter value // would change on the next loop if ($db instanceof DBSQLSRV && is_resource($value) && $cMap->isLob()) { $blob = "blob" . $i; ${$blob} = $value; $stmt->bindParam(':p' . $i++, ${$blob}, PDO::PARAM_LOB, 0, PDO::SQLSRV_ENCODING_BINARY); } else { $stmt->bindValue(':p' . $i++, $value, $pdoType); } } else { $stmt->bindValue(':p' . $i++, $value); } } // foreach }
public function translatableFieldNamesProvider() { $dbMap = new \DatabaseMap('default'); $authorTableMap = new \TableMap(); $authorTableMap->setName('author'); $authorTableMap->setPhpName('Author'); $authorTableMap->setClassname('Acme\\DemoBundle\\Model\\Author'); $authorTableMap->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $dbMap->addTableObject($authorTableMap); $bookTableMap = new \TableMap(); $bookTableMap->setName('book'); $bookTableMap->setPhpName('Book'); $bookTableMap->setClassname('Acme\\DemoBundle\\Model\\Book'); $bookTableMap->addPrimaryKey('ID', 'Id', 'INTEGER', true, null, null); $bookTableMap->addColumn('NAME', 'Name', 'VARCHAR', false, 255, null); $bookTableMap->addColumn('SLUG', 'Slug', 'VARCHAR', false, 255, null); $bookTableMap->addForeignKey('AUTHOR_ID', 'AuthorId', 'INTEGER', 'author', 'id', true, null, null); $dbMap->addTableObject($bookTableMap); $bookTableMap->addRelation('Author', 'Acme\\DemoBundle\\Model\\Author', \RelationMap::MANY_TO_ONE, array('AUTHOR_ID' => 'ID'), 'CASCADE', null); $manager = new TestableModelManager(); $manager->addTable('Acme\\DemoBundle\\Model\\Author', $authorTableMap); $manager->addTable('Acme\\DemoBundle\\Model\\Book', $bookTableMap); return array(array($manager, 'Acme\\DemoBundle\\Model\\Author', 'ID', 'Id'), array($manager, 'Acme\\DemoBundle\\Model\\Author', 'Id', 'Id'), array($manager, 'Acme\\DemoBundle\\Model\\Author', 'id', 'Id'), array($manager, 'Acme\\DemoBundle\\Model\\Book', 'name', 'Name'), array($manager, 'Acme\\DemoBundle\\Model\\Book', 'author', 'AuthorId'), array($manager, 'Acme\\DemoBundle\\Model\\Book', 'Author', 'AuthorId')); }