fromdb.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP5 framework.
  4. *
  5. * @package Fuel
  6. * @version 1.5
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2013 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Fuel\Tasks;
  13. /**
  14. * Run scaffolding or model generation based an an existing database tables.
  15. *
  16. * Based on https://github.com/mp-php/fuel-myapp/blob/master/tasks/scafdb.php
  17. *
  18. * @author Mamoru Otsuka http://madroom-project.blogspot.jp/
  19. * @copyright 2012 Mamoru Otsuka
  20. * @license WTFPL http://sam.zoy.org/wtfpl/COPYING
  21. */
  22. class Fromdb
  23. {
  24. /**
  25. * Class initialization
  26. */
  27. public function __construct()
  28. {
  29. // load the migrations config
  30. \Config::load('migrations', true);
  31. }
  32. /**
  33. * Show help.
  34. *
  35. * Usage (from command line):
  36. *
  37. * php oil refine fromdb
  38. */
  39. public static function run()
  40. {
  41. static::help();
  42. }
  43. /**
  44. * Show help.
  45. *
  46. * Usage (from command line):
  47. *
  48. * php oil refine fromdb:help
  49. */
  50. public static function help()
  51. {
  52. $output = <<<HELP
  53. Description:
  54. Run scaffolding or generate a model from existing database table(s).
  55. Database settings must be configured correctly for this to work.
  56. Runtime options:
  57. -f, [--force] # Overwrite files that already exist
  58. -s, [--skip] # Skip generating files that already exist
  59. -a, [--admin] # Generate admin scaffolding code
  60. --all # Generate code for all tables found in the database
  61. --db=<database> # Name of the database to use
  62. Commands:
  63. php oil refine fromdb:scaffold <table_name,table_name...>
  64. php oil refine fromdb:scaffold --all
  65. php oil refine fromdb:model <table_name,table_name...>
  66. php oil refine fromdb:model --all
  67. php oil refine fromdb:help
  68. HELP;
  69. \Cli::write($output);
  70. }
  71. /**
  72. * Generate scaffold for a database table.
  73. *
  74. * Usage (from command line):
  75. *
  76. * php oil refine fromdb:scaffold <table_name,table_name...>
  77. */
  78. public static function scaffold($tables = null)
  79. {
  80. // do we have any tables defined?
  81. if (empty($tables))
  82. {
  83. // do we want to generate for all tables?
  84. if ( ! \Cli::option('all', false))
  85. {
  86. \Cli::write('No table names specified to run scaffolding on.', 'red');
  87. exit();
  88. }
  89. // get the list of all available tables
  90. try
  91. {
  92. $list = \DB::list_tables(null, \Cli::option('db', null));
  93. }
  94. catch (\FuelException $e)
  95. {
  96. \Cli::write('The database driver configured does not support listing tables. Please specify them manually.', 'red');
  97. exit();
  98. }
  99. $prefix = \DB::table_prefix();
  100. $migration = \Config::get('migrations.table', 'migration');
  101. $tables = array();
  102. // create the table list
  103. foreach ($list as $table)
  104. {
  105. // strip any defined table prefix from the table name
  106. if ( ! empty($prefix) and strpos($table, $prefix) === 0)
  107. {
  108. $table = substr($table, strlen($prefix));
  109. }
  110. // skip the migration table
  111. $table == $migration or $tables[] = $table;
  112. }
  113. }
  114. // make sure we have an array to work with
  115. is_array($tables) or $tables = explode(',', $tables);
  116. // check what kind of models we need to generate
  117. $subfolder = \Cli::option('crud') ? 'crud' : 'orm';
  118. // generate for each table defined
  119. foreach ($tables as $table)
  120. {
  121. // start with an empty list
  122. \Oil\Generate::$create_files = array();
  123. // and generate
  124. if (\Cli::option('admin', \Cli::option('a', false)))
  125. {
  126. call_user_func('\\Oil\\Generate_Admin::forge', static::arguments($table), $subfolder);
  127. }
  128. else
  129. {
  130. call_user_func('\\Oil\\Generate_Scaffold::forge', static::arguments($table), $subfolder);
  131. }
  132. }
  133. }
  134. /**
  135. * Generate model for a database table.
  136. *
  137. * Usage (from command line):
  138. *
  139. * php oil refine fromdb:model <table_name,table_name...>
  140. */
  141. public static function model($tables = '')
  142. {
  143. // do we have any tables defined?
  144. if (empty($tables))
  145. {
  146. // do we want to generate for all tables?
  147. if ( ! \Cli::option('all', false))
  148. {
  149. \Cli::write('No table names specified to generate a model on.', 'red');
  150. exit();
  151. }
  152. // get the list of all available tables
  153. try
  154. {
  155. $list = \DB::list_tables(null, \Cli::option('db', null));
  156. }
  157. catch (\FuelException $e)
  158. {
  159. \Cli::write('The database driver configured does not support listing tables. Please specify them manually.', 'red');
  160. exit();
  161. }
  162. $prefix = \DB::table_prefix();
  163. $migration = \Config::get('migrations.table', 'migration');
  164. $tables = array();
  165. // create the table list
  166. foreach ($list as $table)
  167. {
  168. // strip any defined table prefix from the table name
  169. if ( ! empty($prefix) and strpos($table, $prefix) === 0)
  170. {
  171. $table = substr($table, strlen($prefix));
  172. }
  173. // skip the migration table
  174. $table == $migration or $tables[] = $table;
  175. }
  176. }
  177. // make sure we have an array to work with
  178. is_array($tables) or $tables = explode(',', $tables);
  179. // generate for each table defined
  180. foreach ($tables as $table)
  181. {
  182. // start with an empty list
  183. \Oil\Generate::$create_files = array();
  184. // and generate
  185. call_user_func('Oil\Generate::model', static::arguments($table));
  186. }
  187. }
  188. /**
  189. * Construct the argument list
  190. *
  191. * @param string $table name of the database table we need to create the list for
  192. * @return array
  193. */
  194. protected static function arguments($table)
  195. {
  196. // get the list of columns from the table
  197. try
  198. {
  199. $columns = \DB::list_columns(trim($table), null, \Cli::option('db', null));
  200. }
  201. catch (\Exception $e)
  202. {
  203. \Cli::write($e->getMessage(), 'red');
  204. exit();
  205. }
  206. // construct the arguments list, starting with the table name
  207. $arguments = array($table);
  208. // set some switches
  209. $include_timestamps = false;
  210. $timestamp_is_int = true;
  211. // process the columns found
  212. foreach ($columns as $column)
  213. {
  214. // do we have a data_type defined? If not, use the generic type
  215. isset($column['data_type']) or $column['data_type'] = $column['type'];
  216. // skip the 'id' column, it will be added automatically
  217. if ($column['name'] == 'id')
  218. {
  219. continue;
  220. }
  221. // detect timestamp columns
  222. if (in_array($column['name'], array('created_at', 'updated_at')))
  223. {
  224. $include_timestamps = true;
  225. $timestamp_is_int = $column['data_type'] == 'int';
  226. continue;
  227. }
  228. // do we need to add constraints?
  229. $constraint = '';
  230. foreach (array('length', 'character_maximum_length', 'display') as $idx)
  231. {
  232. // check if we have such a column, and filter out some default values
  233. if (isset($column[$idx]) and ! in_array($column[$idx], array('65535', '4294967295')))
  234. {
  235. $constraint = '['.$column[$idx].']';
  236. break;
  237. }
  238. }
  239. // if it's an enum column, list the available options
  240. if (in_array($column['data_type'], array('set', 'enum')))
  241. {
  242. $constraint = '['.implode(',', $column['options']).']';
  243. }
  244. // store the column in the argument list
  245. $arguments[] = $column['name'].':'.$column['data_type'].$constraint;
  246. }
  247. // set the switches for the code generation
  248. \Cli::set_option('no-timestamp', $include_timestamps === false);
  249. \Cli::set_option('mysql-timestamp', $timestamp_is_int === false);
  250. // return the generated argument list
  251. return $arguments;
  252. }
  253. }