SqlServerGrammar.php 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. <?php
  2. namespace Illuminate\Database\Schema\Grammars;
  3. use Illuminate\Database\Connection;
  4. use Illuminate\Database\Query\Expression;
  5. use Illuminate\Database\Schema\Blueprint;
  6. use Illuminate\Support\Fluent;
  7. class SqlServerGrammar extends Grammar
  8. {
  9. /**
  10. * If this Grammar supports schema changes wrapped in a transaction.
  11. *
  12. * @var bool
  13. */
  14. protected $transactions = true;
  15. /**
  16. * The possible column modifiers.
  17. *
  18. * @var string[]
  19. */
  20. protected $modifiers = ['Collate', 'Nullable', 'Default', 'Persisted', 'Increment'];
  21. /**
  22. * The columns available as serials.
  23. *
  24. * @var string[]
  25. */
  26. protected $serials = ['tinyInteger', 'smallInteger', 'mediumInteger', 'integer', 'bigInteger'];
  27. /**
  28. * The commands to be executed outside of create or alter command.
  29. *
  30. * @var string[]
  31. */
  32. protected $fluentCommands = ['Default'];
  33. /**
  34. * Compile a query to determine the name of the default schema.
  35. *
  36. * @return string
  37. */
  38. public function compileDefaultSchema()
  39. {
  40. return 'select schema_name()';
  41. }
  42. /**
  43. * Compile a create database command.
  44. *
  45. * @param string $name
  46. * @param \Illuminate\Database\Connection $connection
  47. * @return string
  48. */
  49. public function compileCreateDatabase($name, $connection)
  50. {
  51. return sprintf(
  52. 'create database %s',
  53. $this->wrapValue($name),
  54. );
  55. }
  56. /**
  57. * Compile a drop database if exists command.
  58. *
  59. * @param string $name
  60. * @return string
  61. */
  62. public function compileDropDatabaseIfExists($name)
  63. {
  64. return sprintf(
  65. 'drop database if exists %s',
  66. $this->wrapValue($name)
  67. );
  68. }
  69. /**
  70. * Compile the query to determine the tables.
  71. *
  72. * @return string
  73. */
  74. public function compileTables()
  75. {
  76. return 'select t.name as name, schema_name(t.schema_id) as [schema], sum(u.total_pages) * 8 * 1024 as size '
  77. .'from sys.tables as t '
  78. .'join sys.partitions as p on p.object_id = t.object_id '
  79. .'join sys.allocation_units as u on u.container_id = p.hobt_id '
  80. .'group by t.name, t.schema_id '
  81. .'order by t.name';
  82. }
  83. /**
  84. * Compile the query to determine the views.
  85. *
  86. * @return string
  87. */
  88. public function compileViews()
  89. {
  90. return 'select name, schema_name(v.schema_id) as [schema], definition from sys.views as v '
  91. .'inner join sys.sql_modules as m on v.object_id = m.object_id '
  92. .'order by name';
  93. }
  94. /**
  95. * Compile the query to determine the columns.
  96. *
  97. * @param string $schema
  98. * @param string $table
  99. * @return string
  100. */
  101. public function compileColumns($schema, $table)
  102. {
  103. return sprintf(
  104. 'select col.name, type.name as type_name, '
  105. .'col.max_length as length, col.precision as precision, col.scale as places, '
  106. .'col.is_nullable as nullable, def.definition as [default], '
  107. .'col.is_identity as autoincrement, col.collation_name as collation, '
  108. .'com.definition as [expression], is_persisted as [persisted], '
  109. .'cast(prop.value as nvarchar(max)) as comment '
  110. .'from sys.columns as col '
  111. .'join sys.types as type on col.user_type_id = type.user_type_id '
  112. .'join sys.objects as obj on col.object_id = obj.object_id '
  113. .'join sys.schemas as scm on obj.schema_id = scm.schema_id '
  114. .'left join sys.default_constraints def on col.default_object_id = def.object_id and col.object_id = def.parent_object_id '
  115. ."left join sys.extended_properties as prop on obj.object_id = prop.major_id and col.column_id = prop.minor_id and prop.name = 'MS_Description' "
  116. .'left join sys.computed_columns as com on col.column_id = com.column_id and col.object_id = com.object_id '
  117. ."where obj.type in ('U', 'V') and obj.name = %s and scm.name = %s "
  118. .'order by col.column_id',
  119. $this->quoteString($table),
  120. $schema ? $this->quoteString($schema) : 'schema_name()',
  121. );
  122. }
  123. /**
  124. * Compile the query to determine the indexes.
  125. *
  126. * @param string $schema
  127. * @param string $table
  128. * @return string
  129. */
  130. public function compileIndexes($schema, $table)
  131. {
  132. return sprintf(
  133. "select idx.name as name, string_agg(col.name, ',') within group (order by idxcol.key_ordinal) as columns, "
  134. .'idx.type_desc as [type], idx.is_unique as [unique], idx.is_primary_key as [primary] '
  135. .'from sys.indexes as idx '
  136. .'join sys.tables as tbl on idx.object_id = tbl.object_id '
  137. .'join sys.schemas as scm on tbl.schema_id = scm.schema_id '
  138. .'join sys.index_columns as idxcol on idx.object_id = idxcol.object_id and idx.index_id = idxcol.index_id '
  139. .'join sys.columns as col on idxcol.object_id = col.object_id and idxcol.column_id = col.column_id '
  140. .'where tbl.name = %s and scm.name = %s '
  141. .'group by idx.name, idx.type_desc, idx.is_unique, idx.is_primary_key',
  142. $this->quoteString($table),
  143. $schema ? $this->quoteString($schema) : 'schema_name()',
  144. );
  145. }
  146. /**
  147. * Compile the query to determine the foreign keys.
  148. *
  149. * @param string $schema
  150. * @param string $table
  151. * @return string
  152. */
  153. public function compileForeignKeys($schema, $table)
  154. {
  155. return sprintf(
  156. 'select fk.name as name, '
  157. ."string_agg(lc.name, ',') within group (order by fkc.constraint_column_id) as columns, "
  158. .'fs.name as foreign_schema, ft.name as foreign_table, '
  159. ."string_agg(fc.name, ',') within group (order by fkc.constraint_column_id) as foreign_columns, "
  160. .'fk.update_referential_action_desc as on_update, '
  161. .'fk.delete_referential_action_desc as on_delete '
  162. .'from sys.foreign_keys as fk '
  163. .'join sys.foreign_key_columns as fkc on fkc.constraint_object_id = fk.object_id '
  164. .'join sys.tables as lt on lt.object_id = fk.parent_object_id '
  165. .'join sys.schemas as ls on lt.schema_id = ls.schema_id '
  166. .'join sys.columns as lc on fkc.parent_object_id = lc.object_id and fkc.parent_column_id = lc.column_id '
  167. .'join sys.tables as ft on ft.object_id = fk.referenced_object_id '
  168. .'join sys.schemas as fs on ft.schema_id = fs.schema_id '
  169. .'join sys.columns as fc on fkc.referenced_object_id = fc.object_id and fkc.referenced_column_id = fc.column_id '
  170. .'where lt.name = %s and ls.name = %s '
  171. .'group by fk.name, fs.name, ft.name, fk.update_referential_action_desc, fk.delete_referential_action_desc',
  172. $this->quoteString($table),
  173. $schema ? $this->quoteString($schema) : 'schema_name()',
  174. );
  175. }
  176. /**
  177. * Compile a create table command.
  178. *
  179. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  180. * @param \Illuminate\Support\Fluent $command
  181. * @return string
  182. */
  183. public function compileCreate(Blueprint $blueprint, Fluent $command)
  184. {
  185. $columns = implode(', ', $this->getColumns($blueprint));
  186. return 'create table '.$this->wrapTable($blueprint)." ($columns)";
  187. }
  188. /**
  189. * Compile a column addition table command.
  190. *
  191. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  192. * @param \Illuminate\Support\Fluent $command
  193. * @return string
  194. */
  195. public function compileAdd(Blueprint $blueprint, Fluent $command)
  196. {
  197. return sprintf('alter table %s add %s',
  198. $this->wrapTable($blueprint),
  199. implode(', ', $this->getColumns($blueprint))
  200. );
  201. }
  202. /**
  203. * Compile a rename column command.
  204. *
  205. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  206. * @param \Illuminate\Support\Fluent $command
  207. * @param \Illuminate\Database\Connection $connection
  208. * @return array|string
  209. */
  210. public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Connection $connection)
  211. {
  212. return sprintf("sp_rename %s, %s, N'COLUMN'",
  213. $this->quoteString($this->wrapTable($blueprint).'.'.$this->wrap($command->from)),
  214. $this->wrap($command->to)
  215. );
  216. }
  217. /**
  218. * Compile a change column command into a series of SQL statements.
  219. *
  220. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  221. * @param \Illuminate\Support\Fluent $command
  222. * @param \Illuminate\Database\Connection $connection
  223. * @return array|string
  224. *
  225. * @throws \RuntimeException
  226. */
  227. public function compileChange(Blueprint $blueprint, Fluent $command, Connection $connection)
  228. {
  229. $changes = [$this->compileDropDefaultConstraint($blueprint, $command)];
  230. foreach ($blueprint->getChangedColumns() as $column) {
  231. $sql = sprintf('alter table %s alter column %s %s',
  232. $this->wrapTable($blueprint),
  233. $this->wrap($column),
  234. $this->getType($column)
  235. );
  236. foreach ($this->modifiers as $modifier) {
  237. if (method_exists($this, $method = "modify{$modifier}")) {
  238. $sql .= $this->{$method}($blueprint, $column);
  239. }
  240. }
  241. $changes[] = $sql;
  242. }
  243. return $changes;
  244. }
  245. /**
  246. * Compile a primary key command.
  247. *
  248. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  249. * @param \Illuminate\Support\Fluent $command
  250. * @return string
  251. */
  252. public function compilePrimary(Blueprint $blueprint, Fluent $command)
  253. {
  254. return sprintf('alter table %s add constraint %s primary key (%s)',
  255. $this->wrapTable($blueprint),
  256. $this->wrap($command->index),
  257. $this->columnize($command->columns)
  258. );
  259. }
  260. /**
  261. * Compile a unique key command.
  262. *
  263. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  264. * @param \Illuminate\Support\Fluent $command
  265. * @return string
  266. */
  267. public function compileUnique(Blueprint $blueprint, Fluent $command)
  268. {
  269. return sprintf('create unique index %s on %s (%s)',
  270. $this->wrap($command->index),
  271. $this->wrapTable($blueprint),
  272. $this->columnize($command->columns)
  273. );
  274. }
  275. /**
  276. * Compile a plain index key command.
  277. *
  278. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  279. * @param \Illuminate\Support\Fluent $command
  280. * @return string
  281. */
  282. public function compileIndex(Blueprint $blueprint, Fluent $command)
  283. {
  284. return sprintf('create index %s on %s (%s)',
  285. $this->wrap($command->index),
  286. $this->wrapTable($blueprint),
  287. $this->columnize($command->columns)
  288. );
  289. }
  290. /**
  291. * Compile a spatial index key command.
  292. *
  293. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  294. * @param \Illuminate\Support\Fluent $command
  295. * @return string
  296. */
  297. public function compileSpatialIndex(Blueprint $blueprint, Fluent $command)
  298. {
  299. return sprintf('create spatial index %s on %s (%s)',
  300. $this->wrap($command->index),
  301. $this->wrapTable($blueprint),
  302. $this->columnize($command->columns)
  303. );
  304. }
  305. /**
  306. * Compile a default command.
  307. *
  308. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  309. * @param \Illuminate\Support\Fluent $command
  310. * @return string|null
  311. */
  312. public function compileDefault(Blueprint $blueprint, Fluent $command)
  313. {
  314. if ($command->column->change && ! is_null($command->column->default)) {
  315. return sprintf('alter table %s add default %s for %s',
  316. $this->wrapTable($blueprint),
  317. $this->getDefaultValue($command->column->default),
  318. $this->wrap($command->column)
  319. );
  320. }
  321. }
  322. /**
  323. * Compile a drop table command.
  324. *
  325. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  326. * @param \Illuminate\Support\Fluent $command
  327. * @return string
  328. */
  329. public function compileDrop(Blueprint $blueprint, Fluent $command)
  330. {
  331. return 'drop table '.$this->wrapTable($blueprint);
  332. }
  333. /**
  334. * Compile a drop table (if exists) command.
  335. *
  336. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  337. * @param \Illuminate\Support\Fluent $command
  338. * @return string
  339. */
  340. public function compileDropIfExists(Blueprint $blueprint, Fluent $command)
  341. {
  342. return sprintf('if object_id(%s, \'U\') is not null drop table %s',
  343. $this->quoteString($this->wrapTable($blueprint)),
  344. $this->wrapTable($blueprint)
  345. );
  346. }
  347. /**
  348. * Compile the SQL needed to drop all tables.
  349. *
  350. * @return string
  351. */
  352. public function compileDropAllTables()
  353. {
  354. return "EXEC sp_msforeachtable 'DROP TABLE ?'";
  355. }
  356. /**
  357. * Compile a drop column command.
  358. *
  359. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  360. * @param \Illuminate\Support\Fluent $command
  361. * @return string
  362. */
  363. public function compileDropColumn(Blueprint $blueprint, Fluent $command)
  364. {
  365. $columns = $this->wrapArray($command->columns);
  366. $dropExistingConstraintsSql = $this->compileDropDefaultConstraint($blueprint, $command).';';
  367. return $dropExistingConstraintsSql.'alter table '.$this->wrapTable($blueprint).' drop column '.implode(', ', $columns);
  368. }
  369. /**
  370. * Compile a drop default constraint command.
  371. *
  372. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  373. * @param \Illuminate\Support\Fluent $command
  374. * @return string
  375. */
  376. public function compileDropDefaultConstraint(Blueprint $blueprint, Fluent $command)
  377. {
  378. $columns = $command->name === 'change'
  379. ? "'".collect($blueprint->getChangedColumns())->pluck('name')->implode("','")."'"
  380. : "'".implode("','", $command->columns)."'";
  381. $table = $this->wrapTable($blueprint);
  382. $tableName = $this->quoteString($this->wrapTable($blueprint));
  383. $sql = "DECLARE @sql NVARCHAR(MAX) = '';";
  384. $sql .= "SELECT @sql += 'ALTER TABLE $table DROP CONSTRAINT ' + OBJECT_NAME([default_object_id]) + ';' ";
  385. $sql .= 'FROM sys.columns ';
  386. $sql .= "WHERE [object_id] = OBJECT_ID($tableName) AND [name] in ($columns) AND [default_object_id] <> 0;";
  387. $sql .= 'EXEC(@sql)';
  388. return $sql;
  389. }
  390. /**
  391. * Compile a drop primary key command.
  392. *
  393. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  394. * @param \Illuminate\Support\Fluent $command
  395. * @return string
  396. */
  397. public function compileDropPrimary(Blueprint $blueprint, Fluent $command)
  398. {
  399. $index = $this->wrap($command->index);
  400. return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
  401. }
  402. /**
  403. * Compile a drop unique key command.
  404. *
  405. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  406. * @param \Illuminate\Support\Fluent $command
  407. * @return string
  408. */
  409. public function compileDropUnique(Blueprint $blueprint, Fluent $command)
  410. {
  411. $index = $this->wrap($command->index);
  412. return "drop index {$index} on {$this->wrapTable($blueprint)}";
  413. }
  414. /**
  415. * Compile a drop index command.
  416. *
  417. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  418. * @param \Illuminate\Support\Fluent $command
  419. * @return string
  420. */
  421. public function compileDropIndex(Blueprint $blueprint, Fluent $command)
  422. {
  423. $index = $this->wrap($command->index);
  424. return "drop index {$index} on {$this->wrapTable($blueprint)}";
  425. }
  426. /**
  427. * Compile a drop spatial index command.
  428. *
  429. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  430. * @param \Illuminate\Support\Fluent $command
  431. * @return string
  432. */
  433. public function compileDropSpatialIndex(Blueprint $blueprint, Fluent $command)
  434. {
  435. return $this->compileDropIndex($blueprint, $command);
  436. }
  437. /**
  438. * Compile a drop foreign key command.
  439. *
  440. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  441. * @param \Illuminate\Support\Fluent $command
  442. * @return string
  443. */
  444. public function compileDropForeign(Blueprint $blueprint, Fluent $command)
  445. {
  446. $index = $this->wrap($command->index);
  447. return "alter table {$this->wrapTable($blueprint)} drop constraint {$index}";
  448. }
  449. /**
  450. * Compile a rename table command.
  451. *
  452. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  453. * @param \Illuminate\Support\Fluent $command
  454. * @return string
  455. */
  456. public function compileRename(Blueprint $blueprint, Fluent $command)
  457. {
  458. return sprintf('sp_rename %s, %s',
  459. $this->quoteString($this->wrapTable($blueprint)),
  460. $this->wrapTable($command->to)
  461. );
  462. }
  463. /**
  464. * Compile a rename index command.
  465. *
  466. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  467. * @param \Illuminate\Support\Fluent $command
  468. * @return string
  469. */
  470. public function compileRenameIndex(Blueprint $blueprint, Fluent $command)
  471. {
  472. return sprintf("sp_rename %s, %s, N'INDEX'",
  473. $this->quoteString($this->wrapTable($blueprint).'.'.$this->wrap($command->from)),
  474. $this->wrap($command->to)
  475. );
  476. }
  477. /**
  478. * Compile the command to enable foreign key constraints.
  479. *
  480. * @return string
  481. */
  482. public function compileEnableForeignKeyConstraints()
  483. {
  484. return 'EXEC sp_msforeachtable @command1="print \'?\'", @command2="ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all";';
  485. }
  486. /**
  487. * Compile the command to disable foreign key constraints.
  488. *
  489. * @return string
  490. */
  491. public function compileDisableForeignKeyConstraints()
  492. {
  493. return 'EXEC sp_msforeachtable "ALTER TABLE ? NOCHECK CONSTRAINT all";';
  494. }
  495. /**
  496. * Compile the command to drop all foreign keys.
  497. *
  498. * @return string
  499. */
  500. public function compileDropAllForeignKeys()
  501. {
  502. return "DECLARE @sql NVARCHAR(MAX) = N'';
  503. SELECT @sql += 'ALTER TABLE '
  504. + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id)) + '.' + + QUOTENAME(OBJECT_NAME(parent_object_id))
  505. + ' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
  506. FROM sys.foreign_keys;
  507. EXEC sp_executesql @sql;";
  508. }
  509. /**
  510. * Compile the command to drop all views.
  511. *
  512. * @return string
  513. */
  514. public function compileDropAllViews()
  515. {
  516. return "DECLARE @sql NVARCHAR(MAX) = N'';
  517. SELECT @sql += 'DROP VIEW ' + QUOTENAME(OBJECT_SCHEMA_NAME(object_id)) + '.' + QUOTENAME(name) + ';'
  518. FROM sys.views;
  519. EXEC sp_executesql @sql;";
  520. }
  521. /**
  522. * Create the column definition for a char type.
  523. *
  524. * @param \Illuminate\Support\Fluent $column
  525. * @return string
  526. */
  527. protected function typeChar(Fluent $column)
  528. {
  529. return "nchar({$column->length})";
  530. }
  531. /**
  532. * Create the column definition for a string type.
  533. *
  534. * @param \Illuminate\Support\Fluent $column
  535. * @return string
  536. */
  537. protected function typeString(Fluent $column)
  538. {
  539. return "nvarchar({$column->length})";
  540. }
  541. /**
  542. * Create the column definition for a tiny text type.
  543. *
  544. * @param \Illuminate\Support\Fluent $column
  545. * @return string
  546. */
  547. protected function typeTinyText(Fluent $column)
  548. {
  549. return 'nvarchar(255)';
  550. }
  551. /**
  552. * Create the column definition for a text type.
  553. *
  554. * @param \Illuminate\Support\Fluent $column
  555. * @return string
  556. */
  557. protected function typeText(Fluent $column)
  558. {
  559. return 'nvarchar(max)';
  560. }
  561. /**
  562. * Create the column definition for a medium text type.
  563. *
  564. * @param \Illuminate\Support\Fluent $column
  565. * @return string
  566. */
  567. protected function typeMediumText(Fluent $column)
  568. {
  569. return 'nvarchar(max)';
  570. }
  571. /**
  572. * Create the column definition for a long text type.
  573. *
  574. * @param \Illuminate\Support\Fluent $column
  575. * @return string
  576. */
  577. protected function typeLongText(Fluent $column)
  578. {
  579. return 'nvarchar(max)';
  580. }
  581. /**
  582. * Create the column definition for an integer type.
  583. *
  584. * @param \Illuminate\Support\Fluent $column
  585. * @return string
  586. */
  587. protected function typeInteger(Fluent $column)
  588. {
  589. return 'int';
  590. }
  591. /**
  592. * Create the column definition for a big integer type.
  593. *
  594. * @param \Illuminate\Support\Fluent $column
  595. * @return string
  596. */
  597. protected function typeBigInteger(Fluent $column)
  598. {
  599. return 'bigint';
  600. }
  601. /**
  602. * Create the column definition for a medium integer type.
  603. *
  604. * @param \Illuminate\Support\Fluent $column
  605. * @return string
  606. */
  607. protected function typeMediumInteger(Fluent $column)
  608. {
  609. return 'int';
  610. }
  611. /**
  612. * Create the column definition for a tiny integer type.
  613. *
  614. * @param \Illuminate\Support\Fluent $column
  615. * @return string
  616. */
  617. protected function typeTinyInteger(Fluent $column)
  618. {
  619. return 'tinyint';
  620. }
  621. /**
  622. * Create the column definition for a small integer type.
  623. *
  624. * @param \Illuminate\Support\Fluent $column
  625. * @return string
  626. */
  627. protected function typeSmallInteger(Fluent $column)
  628. {
  629. return 'smallint';
  630. }
  631. /**
  632. * Create the column definition for a float type.
  633. *
  634. * @param \Illuminate\Support\Fluent $column
  635. * @return string
  636. */
  637. protected function typeFloat(Fluent $column)
  638. {
  639. if ($column->precision) {
  640. return "float({$column->precision})";
  641. }
  642. return 'float';
  643. }
  644. /**
  645. * Create the column definition for a double type.
  646. *
  647. * @param \Illuminate\Support\Fluent $column
  648. * @return string
  649. */
  650. protected function typeDouble(Fluent $column)
  651. {
  652. return 'double precision';
  653. }
  654. /**
  655. * Create the column definition for a decimal type.
  656. *
  657. * @param \Illuminate\Support\Fluent $column
  658. * @return string
  659. */
  660. protected function typeDecimal(Fluent $column)
  661. {
  662. return "decimal({$column->total}, {$column->places})";
  663. }
  664. /**
  665. * Create the column definition for a boolean type.
  666. *
  667. * @param \Illuminate\Support\Fluent $column
  668. * @return string
  669. */
  670. protected function typeBoolean(Fluent $column)
  671. {
  672. return 'bit';
  673. }
  674. /**
  675. * Create the column definition for an enumeration type.
  676. *
  677. * @param \Illuminate\Support\Fluent $column
  678. * @return string
  679. */
  680. protected function typeEnum(Fluent $column)
  681. {
  682. return sprintf(
  683. 'nvarchar(255) check ("%s" in (%s))',
  684. $column->name,
  685. $this->quoteString($column->allowed)
  686. );
  687. }
  688. /**
  689. * Create the column definition for a json type.
  690. *
  691. * @param \Illuminate\Support\Fluent $column
  692. * @return string
  693. */
  694. protected function typeJson(Fluent $column)
  695. {
  696. return 'nvarchar(max)';
  697. }
  698. /**
  699. * Create the column definition for a jsonb type.
  700. *
  701. * @param \Illuminate\Support\Fluent $column
  702. * @return string
  703. */
  704. protected function typeJsonb(Fluent $column)
  705. {
  706. return 'nvarchar(max)';
  707. }
  708. /**
  709. * Create the column definition for a date type.
  710. *
  711. * @param \Illuminate\Support\Fluent $column
  712. * @return string
  713. */
  714. protected function typeDate(Fluent $column)
  715. {
  716. return 'date';
  717. }
  718. /**
  719. * Create the column definition for a date-time type.
  720. *
  721. * @param \Illuminate\Support\Fluent $column
  722. * @return string
  723. */
  724. protected function typeDateTime(Fluent $column)
  725. {
  726. return $this->typeTimestamp($column);
  727. }
  728. /**
  729. * Create the column definition for a date-time (with time zone) type.
  730. *
  731. * @param \Illuminate\Support\Fluent $column
  732. * @return string
  733. */
  734. protected function typeDateTimeTz(Fluent $column)
  735. {
  736. return $this->typeTimestampTz($column);
  737. }
  738. /**
  739. * Create the column definition for a time type.
  740. *
  741. * @param \Illuminate\Support\Fluent $column
  742. * @return string
  743. */
  744. protected function typeTime(Fluent $column)
  745. {
  746. return $column->precision ? "time($column->precision)" : 'time';
  747. }
  748. /**
  749. * Create the column definition for a time (with time zone) type.
  750. *
  751. * @param \Illuminate\Support\Fluent $column
  752. * @return string
  753. */
  754. protected function typeTimeTz(Fluent $column)
  755. {
  756. return $this->typeTime($column);
  757. }
  758. /**
  759. * Create the column definition for a timestamp type.
  760. *
  761. * @param \Illuminate\Support\Fluent $column
  762. * @return string
  763. */
  764. protected function typeTimestamp(Fluent $column)
  765. {
  766. if ($column->useCurrent) {
  767. $column->default(new Expression('CURRENT_TIMESTAMP'));
  768. }
  769. return $column->precision ? "datetime2($column->precision)" : 'datetime';
  770. }
  771. /**
  772. * Create the column definition for a timestamp (with time zone) type.
  773. *
  774. * @link https://docs.microsoft.com/en-us/sql/t-sql/data-types/datetimeoffset-transact-sql?view=sql-server-ver15
  775. *
  776. * @param \Illuminate\Support\Fluent $column
  777. * @return string
  778. */
  779. protected function typeTimestampTz(Fluent $column)
  780. {
  781. if ($column->useCurrent) {
  782. $column->default(new Expression('CURRENT_TIMESTAMP'));
  783. }
  784. return $column->precision ? "datetimeoffset($column->precision)" : 'datetimeoffset';
  785. }
  786. /**
  787. * Create the column definition for a year type.
  788. *
  789. * @param \Illuminate\Support\Fluent $column
  790. * @return string
  791. */
  792. protected function typeYear(Fluent $column)
  793. {
  794. return $this->typeInteger($column);
  795. }
  796. /**
  797. * Create the column definition for a binary type.
  798. *
  799. * @param \Illuminate\Support\Fluent $column
  800. * @return string
  801. */
  802. protected function typeBinary(Fluent $column)
  803. {
  804. if ($column->length) {
  805. return $column->fixed ? "binary({$column->length})" : "varbinary({$column->length})";
  806. }
  807. return 'varbinary(max)';
  808. }
  809. /**
  810. * Create the column definition for a uuid type.
  811. *
  812. * @param \Illuminate\Support\Fluent $column
  813. * @return string
  814. */
  815. protected function typeUuid(Fluent $column)
  816. {
  817. return 'uniqueidentifier';
  818. }
  819. /**
  820. * Create the column definition for an IP address type.
  821. *
  822. * @param \Illuminate\Support\Fluent $column
  823. * @return string
  824. */
  825. protected function typeIpAddress(Fluent $column)
  826. {
  827. return 'nvarchar(45)';
  828. }
  829. /**
  830. * Create the column definition for a MAC address type.
  831. *
  832. * @param \Illuminate\Support\Fluent $column
  833. * @return string
  834. */
  835. protected function typeMacAddress(Fluent $column)
  836. {
  837. return 'nvarchar(17)';
  838. }
  839. /**
  840. * Create the column definition for a spatial Geometry type.
  841. *
  842. * @param \Illuminate\Support\Fluent $column
  843. * @return string
  844. */
  845. protected function typeGeometry(Fluent $column)
  846. {
  847. return 'geometry';
  848. }
  849. /**
  850. * Create the column definition for a spatial Geography type.
  851. *
  852. * @param \Illuminate\Support\Fluent $column
  853. * @return string
  854. */
  855. protected function typeGeography(Fluent $column)
  856. {
  857. return 'geography';
  858. }
  859. /**
  860. * Create the column definition for a generated, computed column type.
  861. *
  862. * @param \Illuminate\Support\Fluent $column
  863. * @return string|null
  864. */
  865. protected function typeComputed(Fluent $column)
  866. {
  867. return "as ({$this->getValue($column->expression)})";
  868. }
  869. /**
  870. * Get the SQL for a collation column modifier.
  871. *
  872. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  873. * @param \Illuminate\Support\Fluent $column
  874. * @return string|null
  875. */
  876. protected function modifyCollate(Blueprint $blueprint, Fluent $column)
  877. {
  878. if (! is_null($column->collation)) {
  879. return ' collate '.$column->collation;
  880. }
  881. }
  882. /**
  883. * Get the SQL for a nullable column modifier.
  884. *
  885. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  886. * @param \Illuminate\Support\Fluent $column
  887. * @return string|null
  888. */
  889. protected function modifyNullable(Blueprint $blueprint, Fluent $column)
  890. {
  891. if ($column->type !== 'computed') {
  892. return $column->nullable ? ' null' : ' not null';
  893. }
  894. }
  895. /**
  896. * Get the SQL for a default column modifier.
  897. *
  898. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  899. * @param \Illuminate\Support\Fluent $column
  900. * @return string|null
  901. */
  902. protected function modifyDefault(Blueprint $blueprint, Fluent $column)
  903. {
  904. if (! $column->change && ! is_null($column->default)) {
  905. return ' default '.$this->getDefaultValue($column->default);
  906. }
  907. }
  908. /**
  909. * Get the SQL for an auto-increment column modifier.
  910. *
  911. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  912. * @param \Illuminate\Support\Fluent $column
  913. * @return string|null
  914. */
  915. protected function modifyIncrement(Blueprint $blueprint, Fluent $column)
  916. {
  917. if (! $column->change && in_array($column->type, $this->serials) && $column->autoIncrement) {
  918. return $this->hasCommand($blueprint, 'primary') ? ' identity' : ' identity primary key';
  919. }
  920. }
  921. /**
  922. * Get the SQL for a generated stored column modifier.
  923. *
  924. * @param \Illuminate\Database\Schema\Blueprint $blueprint
  925. * @param \Illuminate\Support\Fluent $column
  926. * @return string|null
  927. */
  928. protected function modifyPersisted(Blueprint $blueprint, Fluent $column)
  929. {
  930. if ($column->change) {
  931. if ($column->type === 'computed') {
  932. return $column->persisted ? ' add persisted' : ' drop persisted';
  933. }
  934. return null;
  935. }
  936. if ($column->persisted) {
  937. return ' persisted';
  938. }
  939. }
  940. /**
  941. * Wrap a table in keyword identifiers.
  942. *
  943. * @param \Illuminate\Database\Schema\Blueprint|\Illuminate\Contracts\Database\Query\Expression|string $table
  944. * @return string
  945. */
  946. public function wrapTable($table)
  947. {
  948. if ($table instanceof Blueprint && $table->temporary) {
  949. $this->setTablePrefix('#');
  950. }
  951. return parent::wrapTable($table);
  952. }
  953. /**
  954. * Quote the given string literal.
  955. *
  956. * @param string|array $value
  957. * @return string
  958. */
  959. public function quoteString($value)
  960. {
  961. if (is_array($value)) {
  962. return implode(', ', array_map([$this, __FUNCTION__], $value));
  963. }
  964. return "N'$value'";
  965. }
  966. }