ExportCodegen.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Set of functions used to build NHibernate dumps of tables
  5. *
  6. * @package PhpMyAdmin-Export
  7. * @subpackage CodeGen
  8. */
  9. namespace PhpMyAdmin\Plugins\Export;
  10. use PhpMyAdmin\Export;
  11. use PhpMyAdmin\Plugins\ExportPlugin;
  12. use PhpMyAdmin\Plugins\Export\Helpers\TableProperty;
  13. use PhpMyAdmin\Properties\Plugins\ExportPluginProperties;
  14. use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
  15. use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
  16. use PhpMyAdmin\Properties\Options\Items\HiddenPropertyItem;
  17. use PhpMyAdmin\Properties\Options\Items\SelectPropertyItem;
  18. use PhpMyAdmin\Util;
  19. /**
  20. * Handles the export for the CodeGen class
  21. *
  22. * @package PhpMyAdmin-Export
  23. * @subpackage CodeGen
  24. */
  25. class ExportCodegen extends ExportPlugin
  26. {
  27. /**
  28. * CodeGen Formats
  29. *
  30. * @var array
  31. */
  32. private $_cgFormats;
  33. /**
  34. * CodeGen Handlers
  35. *
  36. * @var array
  37. */
  38. private $_cgHandlers;
  39. /**
  40. * Constructor
  41. */
  42. public function __construct()
  43. {
  44. // initialize the specific export CodeGen variables
  45. $this->initSpecificVariables();
  46. $this->setProperties();
  47. }
  48. /**
  49. * Initialize the local variables that are used for export CodeGen
  50. *
  51. * @return void
  52. */
  53. protected function initSpecificVariables()
  54. {
  55. $this->_setCgFormats(
  56. array(
  57. "NHibernate C# DO",
  58. "NHibernate XML",
  59. )
  60. );
  61. $this->_setCgHandlers(
  62. array(
  63. "_handleNHibernateCSBody",
  64. "_handleNHibernateXMLBody",
  65. )
  66. );
  67. }
  68. /**
  69. * Sets the export CodeGen properties
  70. *
  71. * @return void
  72. */
  73. protected function setProperties()
  74. {
  75. $exportPluginProperties = new ExportPluginProperties();
  76. $exportPluginProperties->setText('CodeGen');
  77. $exportPluginProperties->setExtension('cs');
  78. $exportPluginProperties->setMimeType('text/cs');
  79. $exportPluginProperties->setOptionsText(__('Options'));
  80. // create the root group that will be the options field for
  81. // $exportPluginProperties
  82. // this will be shown as "Format specific options"
  83. $exportSpecificOptions = new OptionsPropertyRootGroup(
  84. "Format Specific Options"
  85. );
  86. // general options main group
  87. $generalOptions = new OptionsPropertyMainGroup("general_opts");
  88. // create primary items and add them to the group
  89. $leaf = new HiddenPropertyItem("structure_or_data");
  90. $generalOptions->addProperty($leaf);
  91. $leaf = new SelectPropertyItem(
  92. "format",
  93. __('Format:')
  94. );
  95. $leaf->setValues($this->_getCgFormats());
  96. $generalOptions->addProperty($leaf);
  97. // add the main group to the root group
  98. $exportSpecificOptions->addProperty($generalOptions);
  99. // set the options for the export plugin property item
  100. $exportPluginProperties->setOptions($exportSpecificOptions);
  101. $this->properties = $exportPluginProperties;
  102. }
  103. /**
  104. * Outputs export header
  105. *
  106. * @return bool Whether it succeeded
  107. */
  108. public function exportHeader()
  109. {
  110. return true;
  111. }
  112. /**
  113. * Outputs export footer
  114. *
  115. * @return bool Whether it succeeded
  116. */
  117. public function exportFooter()
  118. {
  119. return true;
  120. }
  121. /**
  122. * Outputs database header
  123. *
  124. * @param string $db Database name
  125. * @param string $db_alias Aliases of db
  126. *
  127. * @return bool Whether it succeeded
  128. */
  129. public function exportDBHeader($db, $db_alias = '')
  130. {
  131. return true;
  132. }
  133. /**
  134. * Outputs database footer
  135. *
  136. * @param string $db Database name
  137. *
  138. * @return bool Whether it succeeded
  139. */
  140. public function exportDBFooter($db)
  141. {
  142. return true;
  143. }
  144. /**
  145. * Outputs CREATE DATABASE statement
  146. *
  147. * @param string $db Database name
  148. * @param string $export_type 'server', 'database', 'table'
  149. * @param string $db_alias Aliases of db
  150. *
  151. * @return bool Whether it succeeded
  152. */
  153. public function exportDBCreate($db, $export_type, $db_alias = '')
  154. {
  155. return true;
  156. }
  157. /**
  158. * Outputs the content of a table in NHibernate format
  159. *
  160. * @param string $db database name
  161. * @param string $table table name
  162. * @param string $crlf the end of line sequence
  163. * @param string $error_url the url to go back in case of error
  164. * @param string $sql_query SQL query for obtaining data
  165. * @param array $aliases Aliases of db/table/columns
  166. *
  167. * @return bool Whether it succeeded
  168. */
  169. public function exportData(
  170. $db,
  171. $table,
  172. $crlf,
  173. $error_url,
  174. $sql_query,
  175. array $aliases = array()
  176. ) {
  177. $CG_FORMATS = $this->_getCgFormats();
  178. $CG_HANDLERS = $this->_getCgHandlers();
  179. $format = $GLOBALS['codegen_format'];
  180. if (isset($CG_FORMATS[$format])) {
  181. $method = $CG_HANDLERS[$format];
  182. return Export::outputHandler(
  183. $this->$method($db, $table, $crlf, $aliases)
  184. );
  185. }
  186. return Export::outputHandler(sprintf("%s is not supported.", $format));
  187. }
  188. /**
  189. * Used to make identifiers (from table or database names)
  190. *
  191. * @param string $str name to be converted
  192. * @param bool $ucfirst whether to make the first character uppercase
  193. *
  194. * @return string identifier
  195. */
  196. public static function cgMakeIdentifier($str, $ucfirst = true)
  197. {
  198. // remove unsafe characters
  199. $str = preg_replace('/[^\p{L}\p{Nl}_]/u', '', $str);
  200. // make sure first character is a letter or _
  201. if (!preg_match('/^\pL/u', $str)) {
  202. $str = '_' . $str;
  203. }
  204. if ($ucfirst) {
  205. $str = ucfirst($str);
  206. }
  207. return $str;
  208. }
  209. /**
  210. * C# Handler
  211. *
  212. * @param string $db database name
  213. * @param string $table table name
  214. * @param string $crlf line separator
  215. * @param array $aliases Aliases of db/table/columns
  216. *
  217. * @return string containing C# code lines, separated by "\n"
  218. */
  219. private function _handleNHibernateCSBody($db, $table, $crlf, array $aliases = array())
  220. {
  221. $db_alias = $db;
  222. $table_alias = $table;
  223. $this->initAlias($aliases, $db_alias, $table_alias);
  224. $lines = array();
  225. $result = $GLOBALS['dbi']->query(
  226. sprintf(
  227. 'DESC %s.%s',
  228. Util::backquote($db),
  229. Util::backquote($table)
  230. )
  231. );
  232. if ($result) {
  233. /** @var TableProperty[] $tableProperties */
  234. $tableProperties = array();
  235. while ($row = $GLOBALS['dbi']->fetchRow($result)) {
  236. $col_as = $this->getAlias($aliases, $row[0], 'col', $db, $table);
  237. if (!empty($col_as)) {
  238. $row[0] = $col_as;
  239. }
  240. $tableProperties[] = new TableProperty($row);
  241. }
  242. $GLOBALS['dbi']->freeResult($result);
  243. $lines[] = 'using System;';
  244. $lines[] = 'using System.Collections;';
  245. $lines[] = 'using System.Collections.Generic;';
  246. $lines[] = 'using System.Text;';
  247. $lines[] = 'namespace ' . ExportCodegen::cgMakeIdentifier($db_alias);
  248. $lines[] = '{';
  249. $lines[] = ' #region '
  250. . ExportCodegen::cgMakeIdentifier($table_alias);
  251. $lines[] = ' public class '
  252. . ExportCodegen::cgMakeIdentifier($table_alias);
  253. $lines[] = ' {';
  254. $lines[] = ' #region Member Variables';
  255. foreach ($tableProperties as $tableProperty) {
  256. $lines[] = $tableProperty->formatCs(
  257. ' protected #dotNetPrimitiveType# _#name#;'
  258. );
  259. }
  260. $lines[] = ' #endregion';
  261. $lines[] = ' #region Constructors';
  262. $lines[] = ' public '
  263. . ExportCodegen::cgMakeIdentifier($table_alias) . '() { }';
  264. $temp = array();
  265. foreach ($tableProperties as $tableProperty) {
  266. if (!$tableProperty->isPK()) {
  267. $temp[] = $tableProperty->formatCs(
  268. '#dotNetPrimitiveType# #name#'
  269. );
  270. }
  271. }
  272. $lines[] = ' public '
  273. . ExportCodegen::cgMakeIdentifier($table_alias)
  274. . '('
  275. . implode(', ', $temp)
  276. . ')';
  277. $lines[] = ' {';
  278. foreach ($tableProperties as $tableProperty) {
  279. if (!$tableProperty->isPK()) {
  280. $lines[] = $tableProperty->formatCs(
  281. ' this._#name#=#name#;'
  282. );
  283. }
  284. }
  285. $lines[] = ' }';
  286. $lines[] = ' #endregion';
  287. $lines[] = ' #region Public Properties';
  288. foreach ($tableProperties as $tableProperty) {
  289. $lines[] = $tableProperty->formatCs(
  290. ' public virtual #dotNetPrimitiveType# #ucfirstName#'
  291. . "\n"
  292. . ' {' . "\n"
  293. . ' get {return _#name#;}' . "\n"
  294. . ' set {_#name#=value;}' . "\n"
  295. . ' }'
  296. );
  297. }
  298. $lines[] = ' #endregion';
  299. $lines[] = ' }';
  300. $lines[] = ' #endregion';
  301. $lines[] = '}';
  302. }
  303. return implode($crlf, $lines);
  304. }
  305. /**
  306. * XML Handler
  307. *
  308. * @param string $db database name
  309. * @param string $table table name
  310. * @param string $crlf line separator
  311. * @param array $aliases Aliases of db/table/columns
  312. *
  313. * @return string containing XML code lines, separated by "\n"
  314. */
  315. private function _handleNHibernateXMLBody(
  316. $db,
  317. $table,
  318. $crlf,
  319. array $aliases = array()
  320. ) {
  321. $db_alias = $db;
  322. $table_alias = $table;
  323. $this->initAlias($aliases, $db_alias, $table_alias);
  324. $lines = array();
  325. $lines[] = '<?xml version="1.0" encoding="utf-8" ?' . '>';
  326. $lines[] = '<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" '
  327. . 'namespace="' . ExportCodegen::cgMakeIdentifier($db_alias) . '" '
  328. . 'assembly="' . ExportCodegen::cgMakeIdentifier($db_alias) . '">';
  329. $lines[] = ' <class '
  330. . 'name="' . ExportCodegen::cgMakeIdentifier($table_alias) . '" '
  331. . 'table="' . ExportCodegen::cgMakeIdentifier($table_alias) . '">';
  332. $result = $GLOBALS['dbi']->query(
  333. sprintf(
  334. "DESC %s.%s",
  335. Util::backquote($db),
  336. Util::backquote($table)
  337. )
  338. );
  339. if ($result) {
  340. while ($row = $GLOBALS['dbi']->fetchRow($result)) {
  341. $col_as = $this->getAlias($aliases, $row[0], 'col', $db, $table);
  342. if (!empty($col_as)) {
  343. $row[0] = $col_as;
  344. }
  345. $tableProperty = new TableProperty($row);
  346. if ($tableProperty->isPK()) {
  347. $lines[] = $tableProperty->formatXml(
  348. ' <id name="#ucfirstName#" type="#dotNetObjectType#"'
  349. . ' unsaved-value="0">' . "\n"
  350. . ' <column name="#name#" sql-type="#type#"'
  351. . ' not-null="#notNull#" unique="#unique#"'
  352. . ' index="PRIMARY"/>' . "\n"
  353. . ' <generator class="native" />' . "\n"
  354. . ' </id>'
  355. );
  356. } else {
  357. $lines[] = $tableProperty->formatXml(
  358. ' <property name="#ucfirstName#"'
  359. . ' type="#dotNetObjectType#">' . "\n"
  360. . ' <column name="#name#" sql-type="#type#"'
  361. . ' not-null="#notNull#" #indexName#/>' . "\n"
  362. . ' </property>'
  363. );
  364. }
  365. }
  366. $GLOBALS['dbi']->freeResult($result);
  367. }
  368. $lines[] = ' </class>';
  369. $lines[] = '</hibernate-mapping>';
  370. return implode($crlf, $lines);
  371. }
  372. /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
  373. /**
  374. * Getter for CodeGen formats
  375. *
  376. * @return array
  377. */
  378. private function _getCgFormats()
  379. {
  380. return $this->_cgFormats;
  381. }
  382. /**
  383. * Setter for CodeGen formats
  384. *
  385. * @param array $CG_FORMATS contains CodeGen Formats
  386. *
  387. * @return void
  388. */
  389. private function _setCgFormats(array $CG_FORMATS)
  390. {
  391. $this->_cgFormats = $CG_FORMATS;
  392. }
  393. /**
  394. * Getter for CodeGen handlers
  395. *
  396. * @return array
  397. */
  398. private function _getCgHandlers()
  399. {
  400. return $this->_cgHandlers;
  401. }
  402. /**
  403. * Setter for CodeGen handlers
  404. *
  405. * @param array $CG_HANDLERS contains CodeGen handler methods
  406. *
  407. * @return void
  408. */
  409. private function _setCgHandlers(array $CG_HANDLERS)
  410. {
  411. $this->_cgHandlers = $CG_HANDLERS;
  412. }
  413. }