xpdogenerator.class.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. <?php
  2. /*
  3. * Copyright 2010-2015 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. * sqlsrv classes for generating xPDOObject classes and maps from an xPDO schema.
  22. *
  23. * @package xpdo
  24. * @subpackage om.sqlsrv
  25. */
  26. /**
  27. * Include the parent {@link xPDOGenerator} class.
  28. */
  29. include_once (dirname(__DIR__) . '/xpdogenerator.class.php');
  30. /**
  31. * An extension for generating {@link xPDOObject} class and map files for sqlsrv.
  32. *
  33. * A sqlsrv-specific extension to an {@link xPDOManager} instance that can
  34. * generate class stub and meta-data map files from a provided XML schema of a
  35. * database structure.
  36. *
  37. * @package xpdo
  38. * @subpackage om.sqlsrv
  39. */
  40. class xPDOGenerator_sqlsrv extends xPDOGenerator {
  41. public function compile($path = '') {
  42. return false;
  43. }
  44. public function getIndex($index) {
  45. return '';
  46. }
  47. /**
  48. * Write an xPDO XML Schema from your database.
  49. *
  50. * @param string $schemaFile The name (including path) of the schemaFile you
  51. * want to write.
  52. * @param string $package Name of the package to generate the classes in.
  53. * @param string $baseClass The class which all classes in the package will
  54. * extend; by default this is set to {@link xPDOObject} and any
  55. * auto_increment fields with the column name 'id' will extend {@link
  56. * xPDOSimpleObject} automatically.
  57. * @param string $tablePrefix The table prefix for the current connection,
  58. * which will be removed from all of the generated class and table names.
  59. * Specify a prefix when creating a new {@link xPDO} instance to recreate
  60. * the tables with the same prefix, but still use the generic class names.
  61. * @param boolean $restrictPrefix Only reverse-engineer tables that have the
  62. * specified tablePrefix; if tablePrefix is empty, this is ignored.
  63. * @return boolean True on success, false on failure.
  64. */
  65. public function writeSchema($schemaFile, $package= '', $baseClass= '', $tablePrefix= '', $restrictPrefix= false) {
  66. if (empty ($package))
  67. $package= $this->manager->xpdo->package;
  68. if (empty ($baseClass))
  69. $baseClass= 'xPDOObject';
  70. if (empty ($tablePrefix))
  71. $tablePrefix= $this->manager->xpdo->config[xPDO::OPT_TABLE_PREFIX];
  72. $xmlContent = array();
  73. $xmlContent[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
  74. $xmlContent[] = "<model package=\"{$package}\" baseClass=\"{$baseClass}\" platform=\"sqlsrv\">";
  75. //read list of tables
  76. $tableLike= ($tablePrefix && $restrictPrefix);
  77. if ($tableLike) {
  78. $tablesStmt= $this->manager->xpdo->query("SELECT * FROM sys.Tables WHERE name LIKE '{$tablePrefix}%' ORDER BY name");
  79. } else {
  80. $tablesStmt= $this->manager->xpdo->query("SELECT * FROM sys.Tables ORDER BY name");
  81. }
  82. $tables= $tablesStmt->fetchAll(PDO::FETCH_NUM);
  83. if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, print_r($tables, true));
  84. foreach ($tables as $table) {
  85. $xmlObject= array();
  86. $xmlFields= array();
  87. $xmlIndices= array();
  88. if (!$tableName= $this->getTableName($table[0], $tablePrefix, $restrictPrefix)) {
  89. continue;
  90. }
  91. $class= $this->getClassName($tableName);
  92. $extends= $baseClass;
  93. $fieldsStmt= $this->manager->xpdo->query("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '{$tableName}'");
  94. $fields= $fieldsStmt->fetchAll(PDO::FETCH_ASSOC);
  95. if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Fields for table {$table[0]}: " . print_r($fields, true));
  96. $cid = 0;
  97. foreach ($fields as $field) {
  98. $name = '';
  99. $type = '';
  100. $notnull = 0;
  101. $dflt_value = null;
  102. $pk = 0;
  103. extract($field, EXTR_OVERWRITE);
  104. $Field= $name;
  105. $PhpType= $this->manager->getPhpType($type);
  106. $Null= ' null="' . ($notnull ? 'false' : 'true') . '"';
  107. $Default= $this->getDefault($dflt_value);
  108. $Extra= '';
  109. if (!empty($pk)) {
  110. if (preg_match('/INT/i', $type)) {
  111. if ($baseClass === 'xPDOObject' && $Field === 'id') {
  112. $extends= 'xPDOSimpleObject';
  113. continue;
  114. } elseif ($cid == 0) {
  115. $Extra= ' generated="native"';
  116. }
  117. }
  118. $Key = ' index="pk"';
  119. } else {
  120. $Key = $this->getIndex($field);
  121. }
  122. $xmlFields[]= "\t\t<field key=\"{$Field}\" dbtype=\"{$type}\" phptype=\"{$PhpType}\"{$Null}{$Default}{$Key}{$Extra} />";
  123. $cid++;
  124. }
  125. $indicesStmt= $this->manager->xpdo->query("PRAGMA index_list({$table[0]})");
  126. $indices= $indicesStmt->fetchAll(PDO::FETCH_ASSOC);
  127. if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Indices for table {$table[0]}: " . print_r($indices, true));
  128. foreach ($indices as $index) {
  129. $primary = preg_match('/^sqlite_autoindex/', $index['name']) ? 'true' : 'false';
  130. $unique = !empty($index['unique']) ? 'true' : 'false';
  131. $xmlIndices[]= "\t\t<index alias=\"{$index['name']}\" name=\"{$index['name']}\" primary=\"{$primary}\" unique=\"{$unique}\">";
  132. $columnsStmt = $this->manager->xpdo->query("PRAGMA index_info({$index['name']})");
  133. $columns = $columnsStmt->fetchAll(PDO::FETCH_ASSOC);
  134. if ($this->manager->xpdo->getDebug() === true) $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, "Columns of index {$index['name']}: " . print_r($columns, true));
  135. foreach ($columns as $column) {
  136. $xmlIndices[]= "\t\t\t<column key=\"{$column['name']}\" />";
  137. }
  138. $xmlIndices[]= "\t\t</index>";
  139. }
  140. $xmlObject[] = "\t<object class=\"{$class}\" table=\"{$tableName}\" extends=\"{$extends}\">";
  141. $xmlObject[] = implode("\n", $xmlFields);
  142. if (!empty($xmlIndices)) {
  143. $xmlObject[] = '';
  144. $xmlObject[] = implode("\n", $xmlIndices);
  145. }
  146. $xmlObject[] = "\t</object>";
  147. $xmlContent[] = implode("\n", $xmlObject);
  148. }
  149. $xmlContent[] = "</model>";
  150. if ($this->manager->xpdo->getDebug() === true) {
  151. $this->manager->xpdo->log(xPDO::LOG_LEVEL_DEBUG, implode("\n", $xmlContent));
  152. }
  153. $file= fopen($schemaFile, 'wb');
  154. $written= fwrite($file, implode("\n", $xmlContent));
  155. fclose($file);
  156. return true;
  157. }
  158. }