<?php
/*
 * This file is part of the sfPropel13Plugin package.
 * (c) 2007 Joshua May <notjosh@gmail.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

/**
 * This class is the Propel 1.2 implementation of sfPropelData.  It interacts with the data source
 * and loads data.
 *
 * @package    symfony
 * @subpackage addon
 * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
 * @version    SVN: $Id: sfPropelData.class.php 4940 2007-08-30 14:11:28Z fabien $
 */
class sfPropel13Data extends sfPropelData
{

  /**
   * @see sfPropelData::loadData()
   */
  public function loadData($directory_or_file = null, $connectionName = 'propel')
  {
    $fixture_files = $this->getFiles($directory_or_file);

    // wrap all database operations in a single transaction
    $this->con = Propel::getConnection($connectionName);
    try
    {
      $this->con->beginTransaction();

      $this->doDeleteCurrentData($fixture_files);

      $this->doLoadData($fixture_files);

      $this->con->commit();
    }
    catch (Exception $e)
    {
      $this->con->rollback();
      throw $e;
    }
  }

  /**
   * @see sfPropelData::dumpData()
   */
  public function dumpData($directory_or_file = null, $tables = 'all', $connectionName = 'propel')
  {
    $sameFile = true;
    if (is_dir($directory_or_file))
    {
      // multi files
      $sameFile = false;
    }
    else
    {
      // same file
      // delete file
    }

    $this->con = Propel::getConnection($connectionName);

    // get tables
    if ('all' === $tables || is_null($tables))
    {
      // load all map builder classes
      $files = sfFinder::type('file')->name('*MapBuilder.php')->in(sfLoader::getModelDirs());
      foreach ($files as $file)
      {
        $mapBuilderClass = basename($file, '.php');
        $map = new $mapBuilderClass();
        $map->doBuild();
      }

      $dbMap = Propel::getDatabaseMap($connectionName);
      $tables = array();
      foreach ($dbMap->getTables() as $table)
      {
        $tables[] = $table->getPhpName();
      }
    }
    else if (!is_array($tables))
    {
      $tables = array($tables);
    }

    $dumpData = array();

    // load map classes

    array_walk($tables, array($this, 'loadMapBuilder'));

    $tables = $this->fixOrderingOfForeignKeyData($tables);

    foreach ($tables as $tableName)
    {
      $tableMap = $this->maps[$tableName]->getDatabaseMap()->getTable(constant($tableName.'Peer::TABLE_NAME'));

      // get db info
      $stmt = $this->con->prepare('SELECT * FROM '.constant($tableName.'Peer::TABLE_NAME'));
      $stmt->execute();

      while ($row = $stmt->fetch())
      {
        $pk = $tableName;
        $values = array();
        foreach ($tableMap->getColumns() as $column)
        {
          $col = strtolower($column->getColumnName());
          if ($column->isPrimaryKey())
          {
            $pk .= '_'.$row[$col];
          }
          else if ($column->isForeignKey())
          {
            $relatedTable = $this->maps[$tableName]->getDatabaseMap()->getTable($column->getRelatedTableName());

            $values[$col] = $relatedTable->getPhpName().'_'.$row[$col];
          }
          else
          {
            $values[$col] = $row[$col];
          }
        }

        if (!isset($dumpData[$tableName]))
        {
          $dumpData[$tableName] = array();
        }

        $dumpData[$tableName][$pk] = $values;
      }
    }

    // save to file(s)
    if ($sameFile)
    {
      file_put_contents($directory_or_file, Spyc::YAMLDump($dumpData));
    }
    else
    {
      $i = 0;
      foreach ($tables as $tableName)
      {
        if (!isset($dumpData[$tableName]))
        {
          continue;
        }

        file_put_contents(sprintf("%s/%03d-%s.yml", $directory_or_file, ++$i, $tableName), Spyc::YAMLDump(array($tableName => $dumpData[$tableName])));
      }
    }
  }
}
