SqlserverSchemaTest.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. * @link http://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license http://www.opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Test\TestCase\Database\Schema;
  16. use Cake\Core\Configure;
  17. use Cake\Database\Schema\Collection as SchemaCollection;
  18. use Cake\Database\Schema\SqlserverSchema;
  19. use Cake\Database\Schema\Table;
  20. use Cake\Datasource\ConnectionManager;
  21. use Cake\TestSuite\TestCase;
  22. /**
  23. * SQL Server schema test case.
  24. */
  25. class SqlserverSchemaTest extends TestCase
  26. {
  27. /**
  28. * Set up
  29. *
  30. * @return void
  31. */
  32. public function setUp()
  33. {
  34. parent::setUp();
  35. $this->skipUnless(defined('PDO::SQLSRV_ENCODING_UTF8'), 'SQL Server extension not present');
  36. }
  37. /**
  38. * Helper method for skipping tests that need a real connection.
  39. *
  40. * @return void
  41. */
  42. protected function _needsConnection()
  43. {
  44. $config = ConnectionManager::config('test');
  45. $this->skipIf(strpos($config['driver'], 'Sqlserver') === false, 'Not using Sqlserver for test config');
  46. }
  47. /**
  48. * Helper method for testing methods.
  49. *
  50. * @return void
  51. */
  52. protected function _createTables($connection)
  53. {
  54. $this->_needsConnection();
  55. $connection->execute("IF OBJECT_ID('schema_articles', 'U') IS NOT NULL DROP TABLE schema_articles");
  56. $connection->execute("IF OBJECT_ID('schema_authors', 'U') IS NOT NULL DROP TABLE schema_authors");
  57. $table = <<<SQL
  58. CREATE TABLE schema_authors (
  59. id int IDENTITY(1,1) PRIMARY KEY,
  60. name VARCHAR(50),
  61. bio DATE,
  62. created DATETIME
  63. )
  64. SQL;
  65. $connection->execute($table);
  66. $table = <<<SQL
  67. CREATE TABLE schema_articles (
  68. id BIGINT PRIMARY KEY,
  69. title VARCHAR(20),
  70. body VARCHAR(1000),
  71. author_id INTEGER NOT NULL,
  72. published BIT DEFAULT 0,
  73. views SMALLINT DEFAULT 0,
  74. created DATETIME,
  75. CONSTRAINT [content_idx] UNIQUE ([title], [body]),
  76. CONSTRAINT [author_idx] FOREIGN KEY ([author_id]) REFERENCES [schema_authors] ([id]) ON DELETE CASCADE ON UPDATE CASCADE
  77. )
  78. SQL;
  79. $connection->execute($table);
  80. $connection->execute('CREATE INDEX [author_idx] ON [schema_articles] ([author_id])');
  81. }
  82. /**
  83. * Data provider for convert column testing
  84. *
  85. * @return array
  86. */
  87. public static function convertColumnProvider()
  88. {
  89. return [
  90. [
  91. 'DATETIME',
  92. null,
  93. null,
  94. null,
  95. ['type' => 'timestamp', 'length' => null]
  96. ],
  97. [
  98. 'DATE',
  99. null,
  100. null,
  101. null,
  102. ['type' => 'date', 'length' => null]
  103. ],
  104. [
  105. 'TIME',
  106. null,
  107. null,
  108. null,
  109. ['type' => 'time', 'length' => null]
  110. ],
  111. [
  112. 'SMALLINT',
  113. null,
  114. 4,
  115. null,
  116. ['type' => 'integer', 'length' => 4]
  117. ],
  118. [
  119. 'INTEGER',
  120. null,
  121. null,
  122. null,
  123. ['type' => 'integer', 'length' => 10]
  124. ],
  125. [
  126. 'INTEGER',
  127. null,
  128. 8,
  129. null,
  130. ['type' => 'integer', 'length' => 8]
  131. ],
  132. [
  133. 'BIGINT',
  134. null,
  135. null,
  136. null,
  137. ['type' => 'biginteger', 'length' => 20]
  138. ],
  139. [
  140. 'NUMERIC',
  141. null,
  142. 15,
  143. 5,
  144. ['type' => 'decimal', 'length' => 15, 'precision' => 5]
  145. ],
  146. [
  147. 'DECIMAL',
  148. null,
  149. 11,
  150. 3,
  151. ['type' => 'decimal', 'length' => 11, 'precision' => 3]
  152. ],
  153. [
  154. 'MONEY',
  155. null,
  156. null,
  157. null,
  158. ['type' => 'decimal', 'length' => null, 'precision' => null]
  159. ],
  160. [
  161. 'VARCHAR',
  162. null,
  163. null,
  164. null,
  165. ['type' => 'string', 'length' => 255]
  166. ],
  167. [
  168. 'VARCHAR',
  169. 10,
  170. null,
  171. null,
  172. ['type' => 'string', 'length' => 10]
  173. ],
  174. [
  175. 'NVARCHAR',
  176. 50,
  177. null,
  178. null,
  179. ['type' => 'string', 'length' => 50]
  180. ],
  181. [
  182. 'CHAR',
  183. 10,
  184. null,
  185. null,
  186. ['type' => 'string', 'fixed' => true, 'length' => 10]
  187. ],
  188. [
  189. 'NCHAR',
  190. 10,
  191. null,
  192. null,
  193. ['type' => 'string', 'fixed' => true, 'length' => 10]
  194. ],
  195. [
  196. 'UNIQUEIDENTIFIER',
  197. null,
  198. null,
  199. null,
  200. ['type' => 'uuid']
  201. ],
  202. [
  203. 'TEXT',
  204. null,
  205. null,
  206. null,
  207. ['type' => 'text', 'length' => null]
  208. ],
  209. [
  210. 'REAL',
  211. null,
  212. null,
  213. null,
  214. ['type' => 'float', 'length' => null]
  215. ],
  216. [
  217. 'VARCHAR',
  218. -1,
  219. null,
  220. null,
  221. ['type' => 'text', 'length' => null]
  222. ],
  223. ];
  224. }
  225. /**
  226. * Test parsing Sqlserver column types from field description.
  227. *
  228. * @dataProvider convertColumnProvider
  229. * @return void
  230. */
  231. public function testConvertColumn($type, $length, $precision, $scale, $expected)
  232. {
  233. $field = [
  234. 'name' => 'field',
  235. 'type' => $type,
  236. 'null' => 'YES',
  237. 'default' => 'Default value',
  238. 'char_length' => $length,
  239. 'precision' => $precision,
  240. 'scale' => $scale
  241. ];
  242. $expected += [
  243. 'null' => true,
  244. 'default' => 'Default value',
  245. ];
  246. $driver = $this->getMock('Cake\Database\Driver\Sqlserver');
  247. $dialect = new SqlserverSchema($driver);
  248. $table = $this->getMock('Cake\Database\Schema\Table', [], ['table']);
  249. $table->expects($this->at(0))->method('addColumn')->with('field', $expected);
  250. $dialect->convertColumnDescription($table, $field);
  251. }
  252. /**
  253. * Test listing tables with Sqlserver
  254. *
  255. * @return void
  256. */
  257. public function testListTables()
  258. {
  259. $connection = ConnectionManager::get('test');
  260. $this->_createTables($connection);
  261. $schema = new SchemaCollection($connection);
  262. $result = $schema->listTables();
  263. $this->assertInternalType('array', $result);
  264. $this->assertContains('schema_articles', $result);
  265. $this->assertContains('schema_authors', $result);
  266. }
  267. /**
  268. * Test describing a table with Sqlserver
  269. *
  270. * @return void
  271. */
  272. public function testDescribeTable()
  273. {
  274. $connection = ConnectionManager::get('test');
  275. $this->_createTables($connection);
  276. $schema = new SchemaCollection($connection);
  277. $result = $schema->describe('schema_articles');
  278. $expected = [
  279. 'id' => [
  280. 'type' => 'biginteger',
  281. 'null' => false,
  282. 'default' => null,
  283. 'length' => 19,
  284. 'precision' => null,
  285. 'unsigned' => null,
  286. 'autoIncrement' => null,
  287. 'comment' => null,
  288. ],
  289. 'title' => [
  290. 'type' => 'string',
  291. 'null' => true,
  292. 'default' => null,
  293. 'length' => 20,
  294. 'precision' => null,
  295. 'comment' => null,
  296. 'fixed' => null,
  297. ],
  298. 'body' => [
  299. 'type' => 'string',
  300. 'null' => true,
  301. 'default' => null,
  302. 'length' => 1000,
  303. 'precision' => null,
  304. 'fixed' => null,
  305. 'comment' => null,
  306. ],
  307. 'author_id' => [
  308. 'type' => 'integer',
  309. 'null' => false,
  310. 'default' => null,
  311. 'length' => 10,
  312. 'precision' => null,
  313. 'unsigned' => null,
  314. 'autoIncrement' => null,
  315. 'comment' => null,
  316. ],
  317. 'published' => [
  318. 'type' => 'boolean',
  319. 'null' => true,
  320. 'default' => 0,
  321. 'length' => null,
  322. 'precision' => null,
  323. 'comment' => null,
  324. ],
  325. 'views' => [
  326. 'type' => 'integer',
  327. 'null' => true,
  328. 'default' => 0,
  329. 'length' => 5,
  330. 'precision' => null,
  331. 'unsigned' => null,
  332. 'autoIncrement' => null,
  333. 'comment' => null,
  334. ],
  335. 'created' => [
  336. 'type' => 'timestamp',
  337. 'null' => true,
  338. 'default' => null,
  339. 'length' => null,
  340. 'precision' => null,
  341. 'comment' => null,
  342. ],
  343. ];
  344. $this->assertEquals(['id'], $result->primaryKey());
  345. foreach ($expected as $field => $definition) {
  346. $this->assertEquals($definition, $result->column($field), 'Failed to match field ' . $field);
  347. }
  348. }
  349. /**
  350. * Test that describe accepts tablenames containing `schema.table`.
  351. *
  352. * @return void
  353. */
  354. public function testDescribeWithSchemaName()
  355. {
  356. $connection = ConnectionManager::get('test');
  357. $this->_createTables($connection);
  358. $schema = new SchemaCollection($connection);
  359. $result = $schema->describe('dbo.schema_articles');
  360. $this->assertEquals(['id'], $result->primaryKey());
  361. $this->assertEquals('schema_articles', $result->name());
  362. }
  363. /**
  364. * Test describing a table with indexes
  365. *
  366. * @return void
  367. */
  368. public function testDescribeTableIndexes()
  369. {
  370. $connection = ConnectionManager::get('test');
  371. $this->_createTables($connection);
  372. $schema = new SchemaCollection($connection);
  373. $result = $schema->describe('schema_articles');
  374. $this->assertInstanceOf('Cake\Database\Schema\Table', $result);
  375. $this->assertCount(3, $result->constraints());
  376. $expected = [
  377. 'primary' => [
  378. 'type' => 'primary',
  379. 'columns' => ['id'],
  380. 'length' => []
  381. ],
  382. 'content_idx' => [
  383. 'type' => 'unique',
  384. 'columns' => ['title', 'body'],
  385. 'length' => []
  386. ],
  387. 'author_idx' => [
  388. 'type' => 'foreign',
  389. 'columns' => ['author_id'],
  390. 'references' => ['schema_authors', 'id'],
  391. 'length' => [],
  392. 'update' => 'cascade',
  393. 'delete' => 'cascade',
  394. ]
  395. ];
  396. $this->assertEquals($expected['primary'], $result->constraint('primary'));
  397. $this->assertEquals($expected['content_idx'], $result->constraint('content_idx'));
  398. $this->assertEquals($expected['author_idx'], $result->constraint('author_idx'));
  399. $this->assertCount(1, $result->indexes());
  400. $expected = [
  401. 'type' => 'index',
  402. 'columns' => ['author_id'],
  403. 'length' => []
  404. ];
  405. $this->assertEquals($expected, $result->index('author_idx'));
  406. }
  407. /**
  408. * Column provider for creating column sql
  409. *
  410. * @return array
  411. */
  412. public static function columnSqlProvider()
  413. {
  414. return [
  415. // strings
  416. [
  417. 'title',
  418. ['type' => 'string', 'length' => 25, 'null' => false],
  419. '[title] NVARCHAR(25) NOT NULL'
  420. ],
  421. [
  422. 'title',
  423. ['type' => 'string', 'length' => 25, 'null' => true, 'default' => 'ignored'],
  424. '[title] NVARCHAR(25) DEFAULT NULL'
  425. ],
  426. [
  427. 'id',
  428. ['type' => 'string', 'length' => 32, 'fixed' => true, 'null' => false],
  429. '[id] NCHAR(32) NOT NULL'
  430. ],
  431. [
  432. 'id',
  433. ['type' => 'uuid', 'null' => false],
  434. '[id] UNIQUEIDENTIFIER NOT NULL'
  435. ],
  436. [
  437. 'role',
  438. ['type' => 'string', 'length' => 10, 'null' => false, 'default' => 'admin'],
  439. "[role] NVARCHAR(10) NOT NULL DEFAULT [admin]"
  440. ],
  441. [
  442. 'title',
  443. ['type' => 'string'],
  444. '[title] NVARCHAR(255)'
  445. ],
  446. // Text
  447. [
  448. 'body',
  449. ['type' => 'text', 'null' => false],
  450. '[body] NVARCHAR(MAX) NOT NULL'
  451. ],
  452. // Integers
  453. [
  454. 'post_id',
  455. ['type' => 'integer', 'length' => 11],
  456. '[post_id] INTEGER'
  457. ],
  458. [
  459. 'post_id',
  460. ['type' => 'biginteger', 'length' => 20],
  461. '[post_id] BIGINT'
  462. ],
  463. // Decimal
  464. [
  465. 'value',
  466. ['type' => 'decimal'],
  467. '[value] DECIMAL'
  468. ],
  469. [
  470. 'value',
  471. ['type' => 'decimal', 'length' => 11],
  472. '[value] DECIMAL(11,0)'
  473. ],
  474. [
  475. 'value',
  476. ['type' => 'decimal', 'length' => 12, 'precision' => 5],
  477. '[value] DECIMAL(12,5)'
  478. ],
  479. // Float
  480. [
  481. 'value',
  482. ['type' => 'float'],
  483. '[value] FLOAT'
  484. ],
  485. [
  486. 'value',
  487. ['type' => 'float', 'length' => 11, 'precision' => 3],
  488. '[value] FLOAT(3)'
  489. ],
  490. // Binary
  491. [
  492. 'img',
  493. ['type' => 'binary'],
  494. '[img] VARBINARY(MAX)'
  495. ],
  496. // Boolean
  497. [
  498. 'checked',
  499. ['type' => 'boolean', 'default' => false],
  500. '[checked] BIT DEFAULT 0'
  501. ],
  502. [
  503. 'checked',
  504. ['type' => 'boolean', 'default' => true, 'null' => false],
  505. '[checked] BIT NOT NULL DEFAULT 1'
  506. ],
  507. // datetimes
  508. [
  509. 'created',
  510. ['type' => 'datetime'],
  511. '[created] DATETIME'
  512. ],
  513. // Date & Time
  514. [
  515. 'start_date',
  516. ['type' => 'date'],
  517. '[start_date] DATE'
  518. ],
  519. [
  520. 'start_time',
  521. ['type' => 'time'],
  522. '[start_time] TIME'
  523. ],
  524. // timestamps
  525. [
  526. 'created',
  527. ['type' => 'timestamp', 'null' => true],
  528. '[created] DATETIME DEFAULT NULL'
  529. ],
  530. ];
  531. }
  532. /**
  533. * Test generating column definitions
  534. *
  535. * @dataProvider columnSqlProvider
  536. * @return void
  537. */
  538. public function testColumnSql($name, $data, $expected)
  539. {
  540. $driver = $this->_getMockedDriver();
  541. $schema = new SqlserverSchema($driver);
  542. $table = (new Table('schema_articles'))->addColumn($name, $data);
  543. $this->assertEquals($expected, $schema->columnSql($table, $name));
  544. }
  545. /**
  546. * Provide data for testing constraintSql
  547. *
  548. * @return array
  549. */
  550. public static function constraintSqlProvider()
  551. {
  552. return [
  553. [
  554. 'primary',
  555. ['type' => 'primary', 'columns' => ['title']],
  556. 'PRIMARY KEY ([title])'
  557. ],
  558. [
  559. 'unique_idx',
  560. ['type' => 'unique', 'columns' => ['title', 'author_id']],
  561. 'CONSTRAINT [unique_idx] UNIQUE ([title], [author_id])'
  562. ],
  563. [
  564. 'author_id_idx',
  565. ['type' => 'foreign', 'columns' => ['author_id'], 'references' => ['authors', 'id']],
  566. 'CONSTRAINT [author_id_idx] FOREIGN KEY ([author_id]) ' .
  567. 'REFERENCES [authors] ([id]) ON UPDATE SET NULL ON DELETE SET NULL'
  568. ],
  569. [
  570. 'author_id_idx',
  571. ['type' => 'foreign', 'columns' => ['author_id'], 'references' => ['authors', 'id'], 'update' => 'cascade'],
  572. 'CONSTRAINT [author_id_idx] FOREIGN KEY ([author_id]) ' .
  573. 'REFERENCES [authors] ([id]) ON UPDATE CASCADE ON DELETE SET NULL'
  574. ],
  575. [
  576. 'author_id_idx',
  577. ['type' => 'foreign', 'columns' => ['author_id'], 'references' => ['authors', 'id'], 'update' => 'setDefault'],
  578. 'CONSTRAINT [author_id_idx] FOREIGN KEY ([author_id]) ' .
  579. 'REFERENCES [authors] ([id]) ON UPDATE SET DEFAULT ON DELETE SET NULL'
  580. ],
  581. [
  582. 'author_id_idx',
  583. ['type' => 'foreign', 'columns' => ['author_id'], 'references' => ['authors', 'id'], 'update' => 'setNull'],
  584. 'CONSTRAINT [author_id_idx] FOREIGN KEY ([author_id]) ' .
  585. 'REFERENCES [authors] ([id]) ON UPDATE SET NULL ON DELETE SET NULL'
  586. ],
  587. [
  588. 'author_id_idx',
  589. ['type' => 'foreign', 'columns' => ['author_id'], 'references' => ['authors', 'id'], 'update' => 'noAction'],
  590. 'CONSTRAINT [author_id_idx] FOREIGN KEY ([author_id]) ' .
  591. 'REFERENCES [authors] ([id]) ON UPDATE NO ACTION ON DELETE SET NULL'
  592. ],
  593. ];
  594. }
  595. /**
  596. * Test the constraintSql method.
  597. *
  598. * @dataProvider constraintSqlProvider
  599. */
  600. public function testConstraintSql($name, $data, $expected)
  601. {
  602. $driver = $this->_getMockedDriver();
  603. $schema = new SqlserverSchema($driver);
  604. $table = (new Table('schema_articles'))->addColumn('title', [
  605. 'type' => 'string',
  606. 'length' => 255
  607. ])->addColumn('author_id', [
  608. 'type' => 'integer',
  609. ])->addConstraint($name, $data);
  610. $this->assertEquals($expected, $schema->constraintSql($table, $name));
  611. }
  612. /**
  613. * Integration test for converting a Schema\Table into MySQL table creates.
  614. *
  615. * @return void
  616. */
  617. public function testCreateSql()
  618. {
  619. $driver = $this->_getMockedDriver();
  620. $connection = $this->getMock('Cake\Database\Connection', [], [], '', false);
  621. $connection->expects($this->any())->method('driver')
  622. ->will($this->returnValue($driver));
  623. $table = (new Table('schema_articles'))->addColumn('id', [
  624. 'type' => 'integer',
  625. 'null' => false
  626. ])
  627. ->addColumn('title', [
  628. 'type' => 'string',
  629. 'null' => false,
  630. ])
  631. ->addColumn('body', ['type' => 'text'])
  632. ->addColumn('created', 'datetime')
  633. ->addConstraint('primary', [
  634. 'type' => 'primary',
  635. 'columns' => ['id'],
  636. ])
  637. ->addIndex('title_idx', [
  638. 'type' => 'index',
  639. 'columns' => ['title'],
  640. ]);
  641. $expected = <<<SQL
  642. CREATE TABLE [schema_articles] (
  643. [id] INTEGER IDENTITY(1, 1),
  644. [title] NVARCHAR(255) NOT NULL,
  645. [body] NVARCHAR(MAX),
  646. [created] DATETIME,
  647. PRIMARY KEY ([id])
  648. )
  649. SQL;
  650. $result = $table->createSql($connection);
  651. $this->assertCount(2, $result);
  652. $this->assertEquals(str_replace("\r\n", "\n", $expected), str_replace("\r\n", "\n", $result[0]));
  653. $this->assertEquals(
  654. 'CREATE INDEX [title_idx] ON [schema_articles] ([title])',
  655. $result[1]
  656. );
  657. }
  658. /**
  659. * test dropSql
  660. *
  661. * @return void
  662. */
  663. public function testDropSql()
  664. {
  665. $driver = $this->_getMockedDriver();
  666. $connection = $this->getMock('Cake\Database\Connection', [], [], '', false);
  667. $connection->expects($this->any())->method('driver')
  668. ->will($this->returnValue($driver));
  669. $table = new Table('schema_articles');
  670. $result = $table->dropSql($connection);
  671. $this->assertCount(1, $result);
  672. $this->assertEquals('DROP TABLE [schema_articles]', $result[0]);
  673. }
  674. /**
  675. * Test truncateSql()
  676. *
  677. * @return void
  678. */
  679. public function testTruncateSql()
  680. {
  681. $driver = $this->_getMockedDriver();
  682. $connection = $this->getMock('Cake\Database\Connection', [], [], '', false);
  683. $connection->expects($this->any())->method('driver')
  684. ->will($this->returnValue($driver));
  685. $table = new Table('schema_articles');
  686. $table->addColumn('id', 'integer')
  687. ->addConstraint('primary', [
  688. 'type' => 'primary',
  689. 'columns' => ['id']
  690. ]);
  691. $result = $table->truncateSql($connection);
  692. $this->assertCount(2, $result);
  693. $this->assertEquals('DELETE FROM [schema_articles]', $result[0]);
  694. $this->assertEquals('DBCC CHECKIDENT([schema_articles], RESEED, 0)', $result[1]);
  695. }
  696. /**
  697. * Get a schema instance with a mocked driver/pdo instances
  698. *
  699. * @return Driver
  700. */
  701. protected function _getMockedDriver()
  702. {
  703. $driver = new \Cake\Database\Driver\Sqlserver();
  704. $mock = $this->getMock('FakePdo', ['quote', 'quoteIdentifier']);
  705. $mock->expects($this->any())
  706. ->method('quote')
  707. ->will($this->returnCallback(function ($value) {
  708. return '[' . $value . ']';
  709. }));
  710. $mock->expects($this->any())
  711. ->method('quoteIdentifier')
  712. ->will($this->returnCallback(function ($value) {
  713. return '[' . $value . ']';
  714. }));
  715. $driver->connection($mock);
  716. return $driver;
  717. }
  718. }