schema.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <?php namespace Laravel\Database;
  2. use Closure;
  3. use Laravel\Fluent;
  4. use Laravel\Database as DB;
  5. class Schema {
  6. /**
  7. * Begin a fluent schema operation on a database table.
  8. *
  9. * @param string $table
  10. * @param Closure $callback
  11. * @return void
  12. */
  13. public static function table($table, $callback)
  14. {
  15. call_user_func($callback, $table = new Schema\Table($table));
  16. return static::execute($table);
  17. }
  18. /**
  19. * Create a new database table schema.
  20. *
  21. * @param string $table
  22. * @param Closure $callback
  23. * @return void
  24. */
  25. public static function create($table, $callback)
  26. {
  27. $table = new Schema\Table($table);
  28. // To indicate that the table is new and needs to be created, we'll run
  29. // the "create" command on the table instance. This tells schema it is
  30. // not simply a column modification operation.
  31. $table->create();
  32. call_user_func($callback, $table);
  33. return static::execute($table);
  34. }
  35. /**
  36. * Rename a database table in the schema.
  37. *
  38. * @param string $table
  39. * @param string $new_name
  40. * @return void
  41. */
  42. public static function rename($table, $new_name)
  43. {
  44. $table = new Schema\Table($table);
  45. // To indicate that the table needs to be renamed, we will run the
  46. // "rename" command on the table instance and pass the instance to
  47. // the execute method as calling a Closure isn't needed.
  48. $table->rename($new_name);
  49. return static::execute($table);
  50. }
  51. /**
  52. * Drop a database table from the schema.
  53. *
  54. * @param string $table
  55. * @param string $connection
  56. * @return void
  57. */
  58. public static function drop($table, $connection = null)
  59. {
  60. $table = new Schema\Table($table);
  61. $table->on($connection);
  62. // To indicate that the table needs to be dropped, we will run the
  63. // "drop" command on the table instance and pass the instance to
  64. // the execute method as calling a Closure isn't needed.
  65. $table->drop();
  66. return static::execute($table);
  67. }
  68. /**
  69. * Execute the given schema operation against the database.
  70. *
  71. * @param Schema\Table $table
  72. * @return void
  73. */
  74. public static function execute($table)
  75. {
  76. // The implications method is responsible for finding any fluently
  77. // defined indexes on the schema table and adding the explicit
  78. // commands that are needed for the schema instance.
  79. static::implications($table);
  80. foreach ($table->commands as $command)
  81. {
  82. $connection = DB::connection($table->connection);
  83. $grammar = static::grammar($connection);
  84. // Each grammar has a function that corresponds to the command type and
  85. // is for building that command's SQL. This lets the SQL syntax builds
  86. // stay granular across various database systems.
  87. if (method_exists($grammar, $method = $command->type))
  88. {
  89. $statements = $grammar->$method($table, $command);
  90. // Once we have the statements, we will cast them to an array even
  91. // though not all of the commands return an array just in case it
  92. // needs multiple queries to complete.
  93. foreach ((array) $statements as $statement)
  94. {
  95. $connection->query($statement);
  96. }
  97. }
  98. }
  99. }
  100. /**
  101. * Add any implicit commands to the schema table operation.
  102. *
  103. * @param Schema\Table $table
  104. * @return void
  105. */
  106. protected static function implications($table)
  107. {
  108. // If the developer has specified columns for the table and the table is
  109. // not being created, we'll assume they simply want to add the columns
  110. // to the table and generate the add command.
  111. if (count($table->columns) > 0 and ! $table->creating())
  112. {
  113. $command = new Fluent(array('type' => 'add'));
  114. array_unshift($table->commands, $command);
  115. }
  116. // For some extra syntax sugar, we'll check for any implicit indexes
  117. // on the table since the developer may specify the index type on
  118. // the fluent column declaration for convenience.
  119. foreach ($table->columns as $column)
  120. {
  121. foreach (array('primary', 'unique', 'fulltext', 'index') as $key)
  122. {
  123. if (isset($column->$key))
  124. {
  125. if ($column->$key === true)
  126. {
  127. $table->$key($column->name);
  128. }
  129. else
  130. {
  131. $table->$key($column->name, $column->$key);
  132. }
  133. }
  134. }
  135. }
  136. }
  137. /**
  138. * Create the appropriate schema grammar for the driver.
  139. *
  140. * @param Connection $connection
  141. * @return Grammar
  142. */
  143. public static function grammar(Connection $connection)
  144. {
  145. $driver = $connection->driver();
  146. if (isset(\Laravel\Database::$registrar[$driver]))
  147. {
  148. return \Laravel\Database::$registrar[$driver]['schema']();
  149. }
  150. switch ($driver)
  151. {
  152. case 'mysql':
  153. return new Schema\Grammars\MySQL($connection);
  154. case 'pgsql':
  155. return new Schema\Grammars\Postgres($connection);
  156. case 'sqlsrv':
  157. return new Schema\Grammars\SQLServer($connection);
  158. case 'sqlite':
  159. return new Schema\Grammars\SQLite($connection);
  160. }
  161. throw new \Exception("Schema operations not supported for [$driver].");
  162. }
  163. }