Code snippets for symfony 1.x

Navigation

Refine Tags

Snippets tagged "fixtures"

Dump fixtures using Criteria

In case you have a populated database and you need to generate a fixtures for it, you can use symfony propel:data-dump tasks or manually call methods of sfPropelData.

But If your database contains too much data to be fetched, this methods will not work for you.

For such cases I have extended sfPropelData to use Propel Criteria objects to filter dumped data. For example, you can set limit 30 records for every model to prevent dumping all records from database.

Usage:

You can create special tasks to generate fixtures and use there class listed below

$data = new fxPropelData();
 
// Defining criterias
$c1 = new Criteria();
$c1->setLimit(30);
$c2 = clone($c1);
$c2->add('IS_DELETED',0);
 
// array with models and criterias for them
    $models = array(
      'Fruit'=> $c1,
      'Vegetable' => $c2,
    );
 
$data->dumpDataWithCriteria(sfConfig::get('sf_data_dir').'/fixtures/food.yml',$models, $options['connection']);
 

class fxPropelData

class fxPropelData extends sfPropelData {
 
  public function dumpDataWithCriteria($directoryOrFile, $models = array(), $connectionName = null) {
 
    $dumpData = $this->getDataWithCriteria($models, $connectionName);
 
    // save to file(s)
    if (!is_dir($directoryOrFile)) {
      file_put_contents($directoryOrFile, sfYaml::dump($dumpData, 3));
    }
    else {
      $i = 0;
      foreach ($models as $tableName => $criteria) {
        if (!isset($dumpData[$tableName])) {
          continue;
        }
 
        file_put_contents(sprintf("%s/%03d-%s.yml", $directoryOrFile, ++$i, $tableName), sfYaml::dump(array($tableName => $dumpData[$tableName]), 3));
      }
    }
  }
 
  protected function getDataWithCriteria($models, $connectionName = 'propel') {
    $this->loadMapBuilders();
    $this->con = Propel::getConnection($connectionName);
    $this->dbMap = Propel::getDatabaseMap($connectionName);
 
 
    $dumpData = array();
 
    foreach ($models as $model => $criteria) {
      $tableName = $model;
 
      $tableMap = $this->dbMap->getTable(constant(constant($tableName.'::PEER').'::TABLE_NAME'));
      $hasParent = false;
      $haveParents = false;
      $fixColumn = null;
      foreach ($tableMap->getColumns() as $column) {
        $col = strtolower($column->getName());
        if ($column->isForeignKey()) {
          $relatedTable = $this->dbMap->getTable($column->getRelatedTableName());
          if ($tableName === $relatedTable->getPhpName()) {
            if ($hasParent) {
              $haveParents = true;
            }
            else {
              $fixColumn = $column;
              $hasParent = true;
            }
          }
        }
      }
 
      if ($haveParents) {
        // unable to dump tables having multi-recursive references
        continue;
      }
 
      // get db info
      $resultsSets = array();
      if ($hasParent) {
        $resultsSets[] = $this->fixOrderingOfForeignKeyDataInSameTableWithCriteria($resultsSets, $criteria, $tableName, $fixColumn);
      }
      else {
        $stmt = call_user_func(array($tableName.'Peer', 'doSelectStmt'),$criteria,$this->con);
        $resultsSets[] = array_merge($stmt->fetchAll(PDO::FETCH_ASSOC),$resultsSets);
        $stmt->closeCursor();
        unset($stmt);
      }
 
 
      foreach ($resultsSets as $rows) {
        if(count($rows) > 0) {
          if (!isset($dumpData[$tableName])) $dumpData[$tableName] = array();
 
          foreach ($rows as $row) {
            $pk = $tableName;
            $values = array();
            $primaryKeys = array();
            $foreignKeys = array();
 
            foreach ($tableMap->getColumns() as $column) {
              $col = $column->getName();
              $isPrimaryKey = $column->isPrimaryKey();
 
              if (is_null($row[$col])) {
                continue;
              }
 
              if ($isPrimaryKey) {
                $value = $row[$col];
                $pk .= '_'.$value;
                $primaryKeys[$col] = $value;
              }
 
              if ($column->isForeignKey()) {
                $relatedTable = $this->dbMap->getTable($column->getRelatedTableName());
                if ($isPrimaryKey) {
                  $foreignKeys[$col] = $row[$col];
                  $primaryKeys[$col] = $relatedTable->getPhpName().'_'.$row[$col];
                }
                else {
                  $values[$col] = $relatedTable->getPhpName().'_'.$row[$col];
 
                  $values[$col] = strlen($row[$col]) ? $relatedTable->getPhpName().'_'.$row[$col] : '';
                }
              }
              elseif (!$isPrimaryKey || ($isPrimaryKey && !$tableMap->isUseIdGenerator())) {
                // We did not want auto incremented primary keys
                $values[$col] = $row[$col];
              }
            }
 
            if (count($primaryKeys) > 1 || (count($primaryKeys) > 0 && count($foreignKeys) > 0)) {
              $values = array_merge($primaryKeys, $values);
            }
 
            $dumpData[$tableName][$pk] = $values;
          }
        }
      }
    }
 
    return $dumpData;
  }
 
  protected function fixOrderingOfForeignKeyDataInSameTableWithCriteria($resultsSets, $criteria, $tableName, $column, $in = null)
  {
    is_null($in) ? $criteria->add($column->getName(),NULL) : $criteria->add($column->getName(),$in,Criteria::IN);
 
    $stmt = call_user_func(array($tableName.'Peer', 'doSelectStmt'),$criteria,$this->con);
 
    $in = array();
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
    {
      $in[] = "'".$row[strtolower($column->getRelatedColumnName())]."'";
      $resultsSets[] = $row;
    }
 
    if ($in = implode(', ', $in))
    {
      $resultsSets = $this->fixOrderingOfForeignKeyDataInSameTableWithCriteria($resultsSets, $tableName, $column, $in);
    }
 
    return $resultsSets;
  }
 
 
}
 
by Davert on 2009-12-11, tagged creiteria  fixtures  functional  propel  test  unit