MODX Revolution PHP Cross Reference Content Management Systems

Source: /core/xpdo/om/mysql/xpdogenerator.class.php - 222 lines - 11022 bytes - Summary - Text - Print

Description: MySQL classes for generating xPDOObject classes and maps from an xPDO schema.

   1  <?php
   2  /*
   3   * Copyright 2010-2013 by MODX, LLC.
   4   *
   5   * This file is part of xPDO.
   6   *
   7   * xPDO is free software; you can redistribute it and/or modify it under the
   8   * terms of the GNU General Public License as published by the Free Software
   9   * Foundation; either version 2 of the License, or (at your option) any later
  10   * version.
  11   *
  12   * xPDO is distributed in the hope that it will be useful, but WITHOUT ANY
  13   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  14   * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  15   *
  16   * You should have received a copy of the GNU General Public License along with
  17   * xPDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
  18   * Suite 330, Boston, MA 02111-1307 USA
  19   */
  20  
  21  /**
  22   * MySQL classes for generating xPDOObject classes and maps from an xPDO schema.
  23   *
  24   * @package xpdo
  25   * @subpackage om.mysql
  26   */
  27  
  28  /**
  29   * Include the parent {@link xPDOGenerator} class.
  30   */
  31  include_once (dirname(dirname(__FILE__)) . '/xpdogenerator.class.php');
  32  
  33  /**
  34   * An extension for generating {@link xPDOObject} class and map files for MySQL.
  35   *
  36   * A MySQL-specific extension to an {@link xPDOManager} instance that can
  37   * generate class stub and meta-data map files from a provided XML schema of a
  38   * database structure.
  39   *
  40   * @package xpdo
  41   * @subpackage om.mysql
  42   */
  43  class xPDOGenerator_mysql extends xPDOGenerator {
  44      public function compile($path = '') {
  45          return false;
  46      }
  47  
  48      public function getIndex($index) {
  49          switch ($index) {
  50              case 'PRI':
  51                  $index= 'pk';
  52                  break;
  53  
  54              case 'UNI':
  55                  $index= 'unique';
  56                  break;
  57  
  58              case 'MUL':
  59                  $index= 'index';
  60                  break;
  61  
  62              default:
  63                  break;
  64          }
  65          if (!empty ($index)) {
  66              $index= ' index="' . $index . '"';
  67          }
  68          return $index;
  69      }
  70  
  71      /**
  72       * Write an xPDO XML Schema from your database.
  73       *
  74       * @param string $schemaFile The name (including path) of the schemaFile you
  75       * want to write.
  76       * @param string $package Name of the package to generate the classes in.
  77       * @param string $baseClass The class which all classes in the package will
  78       * extend; by default this is set to {@link xPDOObject} and any
  79       * auto_increment fields with the column name 'id' will extend {@link
  80       * xPDOSimpleObject} automatically.
  81       * @param string $tablePrefix The table prefix for the current connection,
  82       * which will be removed from all of the generated class and table names.
  83       * Specify a prefix when creating a new {@link xPDO} instance to recreate
  84       * the tables with the same prefix, but still use the generic class names.
  85       * @param boolean $restrictPrefix Only reverse-engineer tables that have the
  86       * specified tablePrefix; if tablePrefix is empty, this is ignored.
  87       * @return boolean True on success, false on failure.
  88       */
  89      public function writeSchema($schemaFile, $package= '', $baseClass= '', $tablePrefix= '', $restrictPrefix= false) {
  90          if (empty ($package))
  91              $package= $this->manager->xpdo->package;
  92          if (empty ($baseClass))
  93              $baseClass= 'xPDOObject';
  94          if (empty ($tablePrefix))
  95              $tablePrefix= $this->manager->xpdo->config[xPDO::OPT_TABLE_PREFIX];
  96          $schemaVersion = xPDO::SCHEMA_VERSION;
  97          $xmlContent = array();
  98          $xmlContent[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  99          $xmlContent[] = "<model package=\"{$package}\" baseClass=\"{$baseClass}\" platform=\"mysql\" defaultEngine=\"MyISAM\" version=\"{$schemaVersion}\">";
 100          //read list of tables
 101          $dbname= $this->manager->xpdo->escape($this->manager->xpdo->config['dbname']);
 102          $tableLike= ($tablePrefix && $restrictPrefix) ? " LIKE '{$tablePrefix}%'" : '';
 103          $tablesStmt= $this->manager->xpdo->prepare("SHOW TABLES FROM {$dbname}{$tableLike}");
 104          $tstart = microtime(true);
 105          $tablesStmt->execute();
 106          $this->manager->xpdo->queryTime += microtime(true) - $tstart;
 107          $this->manager->xpdo->executedQueries++;
 108          $tables= $tablesStmt->fetchAll(PDO::FETCH_NUM);
 109          if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, print_r($tables, true));
 110          foreach ($tables as $table) {
 111              $xmlObject= array();
 112              $xmlFields= array();
 113              $xmlIndices= array();
 114              if (!$tableName= $this->getTableName($table[0], $tablePrefix, $restrictPrefix)) {
 115                  continue;
 116              }
 117              $class= $this->getClassName($tableName);
 118              $extends= $baseClass;
 119              $fieldsStmt= $this->manager->xpdo->query('SHOW COLUMNS FROM ' . $this->manager->xpdo->escape($table[0]));
 120              if ($fieldsStmt) {
 121                  $fields= $fieldsStmt->fetchAll(PDO::FETCH_ASSOC);
 122                  if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, print_r($fields, true));
 123                  if (!empty($fields)) {
 124                      foreach ($fields as $field) {
 125                          $Field= '';
 126                          $Type= '';
 127                          $Null= '';
 128                          $Key= '';
 129                          $Default= '';
 130                          $Extra= '';
 131                          extract($field, EXTR_OVERWRITE);
 132                          $Type= xPDO :: escSplit(' ', $Type, "'", 2);
 133                          $precisionPos= strpos($Type[0], '(');
 134                          $dbType= $precisionPos? substr($Type[0], 0, $precisionPos): $Type[0];
 135                          $dbType= strtolower($dbType);
 136                          $Precision= $precisionPos? substr($Type[0], $precisionPos + 1, strrpos($Type[0], ')') - ($precisionPos + 1)): '';
 137                          if (!empty ($Precision)) {
 138                              $Precision= ' precision="' . trim($Precision) . '"';
 139                          }
 140                          $attributes= '';
 141                          if (isset ($Type[1]) && !empty ($Type[1])) {
 142                              $attributes= ' attributes="' . trim($Type[1]) . '"';
 143                          }
 144                          $PhpType= $this->manager->xpdo->driver->getPhpType($dbType);
 145                          $Null= ' null="' . (($Null === 'NO') ? 'false' : 'true') . '"';
 146                          $Key= $this->getIndex($Key);
 147                          $Default= $this->getDefault($Default);
 148                          if (!empty ($Extra)) {
 149                              if ($Extra === 'auto_increment') {
 150                                  if ($baseClass === 'xPDOObject' && $Field === 'id') {
 151                                      $extends= 'xPDOSimpleObject';
 152                                      continue;
 153                                  } else {
 154                                      $Extra= ' generated="native"';
 155                                  }
 156                              } else {
 157                                  $Extra= ' extra="' . strtolower($Extra) . '"';
 158                              }
 159                              $Extra= ' ' . $Extra;
 160                          }
 161                          $xmlFields[] = "\t\t<field key=\"{$Field}\" dbtype=\"{$dbType}\"{$Precision}{$attributes} phptype=\"{$PhpType}\"{$Null}{$Default}{$Key}{$Extra} />";
 162                      }
 163                  } else {
 164                      $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'No columns were found in table ' .  $table[0]);
 165                  }
 166              } else {
 167                  $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Error retrieving columns for table ' .  $table[0]);
 168              }
 169              $whereClause= ($extends === 'xPDOSimpleObject' ? " WHERE `Key_name` != 'PRIMARY'" : '');
 170              $indexesStmt= $this->manager->xpdo->query('SHOW INDEXES FROM ' . $this->manager->xpdo->escape($table[0]) . $whereClause);
 171              if ($indexesStmt) {
 172                  $indexes= $indexesStmt->fetchAll(PDO::FETCH_ASSOC);
 173                  if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Indices for table {$table[0]}: " . print_r($indexes, true));
 174                  if (!empty($indexes)) {
 175                      $indices = array();
 176                      foreach ($indexes as $index) {
 177                          if (!array_key_exists($index['Key_name'], $indices)) $indices[$index['Key_name']] = array();
 178                          $indices[$index['Key_name']][$index['Seq_in_index']] = $index;
 179                      }
 180                      foreach ($indices as $index) {
 181                          $xmlIndexCols = array();
 182                          if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Details of index: " . print_r($index, true));
 183                          foreach ($index as $columnSeq => $column) {
 184                              if ($columnSeq == 1) {
 185                                  $keyName = $column['Key_name'];
 186                                  $primary = $keyName == 'PRIMARY' ? 'true' : 'false';
 187                                  $unique = empty($column['Non_unique']) ? 'true' : 'false';
 188                                  $packed = empty($column['Packed']) ? 'false' : 'true';
 189                                  $type = $column['Index_type'];
 190                              }
 191                              $null = $column['Null'] == 'YES' ? 'true' : 'false';
 192                              $xmlIndexCols[]= "\t\t\t<column key=\"{$column['Column_name']}\" length=\"{$column['Sub_part']}\" collation=\"{$column['Collation']}\" null=\"{$null}\" />";
 193                          }
 194                          $xmlIndices[]= "\t\t<index alias=\"{$keyName}\" name=\"{$keyName}\" primary=\"{$primary}\" unique=\"{$unique}\" type=\"{$type}\" >";
 195                          $xmlIndices[]= implode("\n", $xmlIndexCols);
 196                          $xmlIndices[]= "\t\t</index>";
 197                      }
 198                  } else {
 199                      $this->manager->xpdo->log(xPDO::LOG_LEVEL_WARN, 'No indexes were found in table ' .  $table[0]);
 200                  }
 201              } else {
 202                  $this->manager->xpdo->log(xPDO::LOG_LEVEL_ERROR, 'Error getting indexes for table ' .  $table[0]);
 203              }
 204              $xmlObject[] = "\t<object class=\"{$class}\" table=\"{$tableName}\" extends=\"{$extends}\">";
 205              $xmlObject[] = implode("\n", $xmlFields);
 206              if (!empty($xmlIndices)) {
 207                  $xmlObject[] = '';
 208                  $xmlObject[] = implode("\n", $xmlIndices);
 209              }
 210              $xmlObject[] = "\t</object>";
 211              $xmlContent[] = implode("\n", $xmlObject);
 212          }
 213          $xmlContent[] = "</model>";
 214          if ($this->manager->xpdo->getDebug() === true) {
 215             $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, implode("\n", $xmlContent));
 216          }
 217          $file= fopen($schemaFile, 'wb');
 218          $written= fwrite($file, implode("\n", $xmlContent));
 219          fclose($file);
 220          return true;
 221      }
 222  }

title

Description

title

Description

title

Description

title

title

Body