Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 /**
|
Chris@0
|
4 * @file
|
Chris@0
|
5 * Contains \Drupal\Tests\migrate\Kernel\SqlBaseTest.
|
Chris@0
|
6 */
|
Chris@0
|
7
|
Chris@0
|
8 namespace Drupal\Tests\migrate\Kernel;
|
Chris@0
|
9
|
Chris@0
|
10 use Drupal\Core\Database\Query\ConditionInterface;
|
Chris@0
|
11 use Drupal\Core\Database\Query\SelectInterface;
|
Chris@14
|
12 use Drupal\Core\Database\StatementInterface;
|
Chris@0
|
13 use Drupal\migrate\Exception\RequirementsException;
|
Chris@0
|
14 use Drupal\Core\Database\Database;
|
Chris@0
|
15 use Drupal\migrate\Plugin\migrate\source\SqlBase;
|
Chris@0
|
16 use Drupal\migrate\Plugin\MigrationInterface;
|
Chris@0
|
17
|
Chris@0
|
18 /**
|
Chris@0
|
19 * Tests the functionality of SqlBase.
|
Chris@0
|
20 *
|
Chris@0
|
21 * @group migrate
|
Chris@0
|
22 */
|
Chris@0
|
23 class SqlBaseTest extends MigrateTestBase {
|
Chris@0
|
24
|
Chris@0
|
25 /**
|
Chris@0
|
26 * The (probably mocked) migration under test.
|
Chris@0
|
27 *
|
Chris@0
|
28 * @var \Drupal\migrate\Plugin\MigrationInterface
|
Chris@0
|
29 */
|
Chris@0
|
30 protected $migration;
|
Chris@0
|
31
|
Chris@0
|
32 /**
|
Chris@0
|
33 * {@inheritdoc}
|
Chris@0
|
34 */
|
Chris@0
|
35 protected function setUp() {
|
Chris@0
|
36 parent::setUp();
|
Chris@0
|
37
|
Chris@0
|
38 $this->migration = $this->getMock(MigrationInterface::class);
|
Chris@0
|
39 $this->migration->method('id')->willReturn('fubar');
|
Chris@0
|
40 }
|
Chris@0
|
41
|
Chris@0
|
42 /**
|
Chris@0
|
43 * Tests different connection types.
|
Chris@0
|
44 */
|
Chris@0
|
45 public function testConnectionTypes() {
|
Chris@0
|
46 $sql_base = new TestSqlBase([], $this->migration);
|
Chris@0
|
47
|
Chris@0
|
48 // Verify that falling back to the default 'migrate' connection (defined in
|
Chris@0
|
49 // the base class) works.
|
Chris@14
|
50 $this->assertSame('default', $sql_base->getDatabase()->getTarget());
|
Chris@14
|
51 $this->assertSame('migrate', $sql_base->getDatabase()->getKey());
|
Chris@0
|
52
|
Chris@0
|
53 // Verify the fallback state key overrides the 'migrate' connection.
|
Chris@0
|
54 $target = 'test_fallback_target';
|
Chris@0
|
55 $key = 'test_fallback_key';
|
Chris@0
|
56 $config = ['target' => $target, 'key' => $key];
|
Chris@0
|
57 $database_state_key = 'test_fallback_state';
|
Chris@0
|
58 \Drupal::state()->set($database_state_key, $config);
|
Chris@0
|
59 \Drupal::state()->set('migrate.fallback_state_key', $database_state_key);
|
Chris@0
|
60 // Create a test connection using the default database configuration.
|
Chris@0
|
61 Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']);
|
Chris@0
|
62 $this->assertSame($sql_base->getDatabase()->getTarget(), $target);
|
Chris@0
|
63 $this->assertSame($sql_base->getDatabase()->getKey(), $key);
|
Chris@0
|
64
|
Chris@0
|
65 // Verify that setting explicit connection information overrides fallbacks.
|
Chris@0
|
66 $target = 'test_db_target';
|
Chris@0
|
67 $key = 'test_migrate_connection';
|
Chris@0
|
68 $config = ['target' => $target, 'key' => $key];
|
Chris@0
|
69 $sql_base->setConfiguration($config);
|
Chris@0
|
70 Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']);
|
Chris@0
|
71
|
Chris@0
|
72 // Validate we have injected our custom key and target.
|
Chris@0
|
73 $this->assertSame($sql_base->getDatabase()->getTarget(), $target);
|
Chris@0
|
74 $this->assertSame($sql_base->getDatabase()->getKey(), $key);
|
Chris@0
|
75
|
Chris@0
|
76 // Now test we can have SqlBase create the connection from an info array.
|
Chris@0
|
77 $sql_base = new TestSqlBase([], $this->migration);
|
Chris@0
|
78
|
Chris@0
|
79 $target = 'test_db_target2';
|
Chris@0
|
80 $key = 'test_migrate_connection2';
|
Chris@0
|
81 $database = Database::getConnectionInfo('default')['default'];
|
Chris@0
|
82 $config = ['target' => $target, 'key' => $key, 'database' => $database];
|
Chris@0
|
83 $sql_base->setConfiguration($config);
|
Chris@0
|
84
|
Chris@0
|
85 // Call getDatabase() to get the connection defined.
|
Chris@0
|
86 $sql_base->getDatabase();
|
Chris@0
|
87
|
Chris@0
|
88 // Validate the connection has been created with the right values.
|
Chris@0
|
89 $this->assertSame(Database::getConnectionInfo($key)[$target], $database);
|
Chris@0
|
90
|
Chris@0
|
91 // Now, test this all works when using state to store db info.
|
Chris@0
|
92 $target = 'test_state_db_target';
|
Chris@0
|
93 $key = 'test_state_migrate_connection';
|
Chris@0
|
94 $config = ['target' => $target, 'key' => $key];
|
Chris@0
|
95 $database_state_key = 'migrate_sql_base_test';
|
Chris@0
|
96 \Drupal::state()->set($database_state_key, $config);
|
Chris@0
|
97 $sql_base->setConfiguration(['database_state_key' => $database_state_key]);
|
Chris@0
|
98 Database::addConnectionInfo($key, $target, Database::getConnectionInfo('default')['default']);
|
Chris@0
|
99
|
Chris@0
|
100 // Validate we have injected our custom key and target.
|
Chris@0
|
101 $this->assertSame($sql_base->getDatabase()->getTarget(), $target);
|
Chris@0
|
102 $this->assertSame($sql_base->getDatabase()->getKey(), $key);
|
Chris@0
|
103
|
Chris@0
|
104 // Now test we can have SqlBase create the connection from an info array.
|
Chris@0
|
105 $sql_base = new TestSqlBase([], $this->migration);
|
Chris@0
|
106
|
Chris@0
|
107 $target = 'test_state_db_target2';
|
Chris@0
|
108 $key = 'test_state_migrate_connection2';
|
Chris@0
|
109 $database = Database::getConnectionInfo('default')['default'];
|
Chris@0
|
110 $config = ['target' => $target, 'key' => $key, 'database' => $database];
|
Chris@0
|
111 $database_state_key = 'migrate_sql_base_test2';
|
Chris@0
|
112 \Drupal::state()->set($database_state_key, $config);
|
Chris@0
|
113 $sql_base->setConfiguration(['database_state_key' => $database_state_key]);
|
Chris@0
|
114
|
Chris@0
|
115 // Call getDatabase() to get the connection defined.
|
Chris@0
|
116 $sql_base->getDatabase();
|
Chris@0
|
117
|
Chris@0
|
118 // Validate the connection has been created with the right values.
|
Chris@0
|
119 $this->assertSame(Database::getConnectionInfo($key)[$target], $database);
|
Chris@0
|
120
|
Chris@0
|
121 // Verify that falling back to 'migrate' when the connection is not defined
|
Chris@0
|
122 // throws a RequirementsException.
|
Chris@0
|
123 \Drupal::state()->delete('migrate.fallback_state_key');
|
Chris@0
|
124 $sql_base->setConfiguration([]);
|
Chris@0
|
125 Database::renameConnection('migrate', 'fallback_connection');
|
Chris@0
|
126 $this->setExpectedException(RequirementsException::class,
|
Chris@0
|
127 'No database connection configured for source plugin');
|
Chris@0
|
128 $sql_base->getDatabase();
|
Chris@0
|
129 }
|
Chris@0
|
130
|
Chris@0
|
131 /**
|
Chris@0
|
132 * Tests that SqlBase respects high-water values.
|
Chris@0
|
133 *
|
Chris@0
|
134 * @param mixed $high_water
|
Chris@0
|
135 * (optional) The high-water value to set.
|
Chris@0
|
136 * @param array $query_result
|
Chris@0
|
137 * (optional) The expected query results.
|
Chris@0
|
138 *
|
Chris@0
|
139 * @dataProvider highWaterDataProvider
|
Chris@0
|
140 */
|
Chris@0
|
141 public function testHighWater($high_water = NULL, array $query_result = []) {
|
Chris@0
|
142 $configuration = [
|
Chris@0
|
143 'high_water_property' => [
|
Chris@0
|
144 'name' => 'order',
|
Chris@0
|
145 ],
|
Chris@0
|
146 ];
|
Chris@0
|
147 $source = new TestSqlBase($configuration, $this->migration);
|
Chris@0
|
148
|
Chris@0
|
149 if ($high_water) {
|
Chris@0
|
150 $source->getHighWaterStorage()->set($this->migration->id(), $high_water);
|
Chris@0
|
151 }
|
Chris@0
|
152
|
Chris@14
|
153 $statement = $this->createMock(StatementInterface::class);
|
Chris@14
|
154 $statement->expects($this->atLeastOnce())->method('setFetchMode')->with(\PDO::FETCH_ASSOC);
|
Chris@14
|
155 $query = $this->createMock(SelectInterface::class);
|
Chris@14
|
156 $query->method('execute')->willReturn($statement);
|
Chris@0
|
157 $query->expects($this->atLeastOnce())->method('orderBy')->with('order', 'ASC');
|
Chris@0
|
158
|
Chris@0
|
159 $condition_group = $this->getMock(ConditionInterface::class);
|
Chris@0
|
160 $query->method('orConditionGroup')->willReturn($condition_group);
|
Chris@0
|
161
|
Chris@0
|
162 $source->setQuery($query);
|
Chris@0
|
163 $source->rewind();
|
Chris@0
|
164 }
|
Chris@0
|
165
|
Chris@0
|
166 /**
|
Chris@0
|
167 * Data provider for ::testHighWater().
|
Chris@0
|
168 *
|
Chris@0
|
169 * @return array
|
Chris@0
|
170 * The scenarios to test.
|
Chris@0
|
171 */
|
Chris@0
|
172 public function highWaterDataProvider() {
|
Chris@0
|
173 return [
|
Chris@0
|
174 'no high-water value set' => [],
|
Chris@0
|
175 'high-water value set' => [33],
|
Chris@0
|
176 ];
|
Chris@0
|
177 }
|
Chris@0
|
178
|
Chris@0
|
179 }
|
Chris@0
|
180
|
Chris@0
|
181 /**
|
Chris@0
|
182 * A dummy source to help with testing SqlBase.
|
Chris@0
|
183 *
|
Chris@0
|
184 * @package Drupal\migrate\Plugin\migrate\source
|
Chris@0
|
185 */
|
Chris@0
|
186 class TestSqlBase extends SqlBase {
|
Chris@0
|
187
|
Chris@0
|
188 /**
|
Chris@0
|
189 * The query to execute.
|
Chris@0
|
190 *
|
Chris@0
|
191 * @var \Drupal\Core\Database\Query\SelectInterface
|
Chris@0
|
192 */
|
Chris@0
|
193 protected $query;
|
Chris@0
|
194
|
Chris@0
|
195 /**
|
Chris@0
|
196 * Overrides the constructor so we can create one easily.
|
Chris@0
|
197 *
|
Chris@0
|
198 * @param array $configuration
|
Chris@0
|
199 * The plugin instance configuration.
|
Chris@0
|
200 * @param \Drupal\migrate\Plugin\MigrationInterface $migration
|
Chris@0
|
201 * (optional) The migration being run.
|
Chris@0
|
202 */
|
Chris@0
|
203 public function __construct(array $configuration = [], MigrationInterface $migration = NULL) {
|
Chris@0
|
204 parent::__construct($configuration, 'sql_base', [], $migration, \Drupal::state());
|
Chris@0
|
205 }
|
Chris@0
|
206
|
Chris@0
|
207 /**
|
Chris@0
|
208 * Gets the database without caching it.
|
Chris@0
|
209 */
|
Chris@0
|
210 public function getDatabase() {
|
Chris@0
|
211 $this->database = NULL;
|
Chris@0
|
212 return parent::getDatabase();
|
Chris@0
|
213 }
|
Chris@0
|
214
|
Chris@0
|
215 /**
|
Chris@0
|
216 * Allows us to set the configuration from a test.
|
Chris@0
|
217 *
|
Chris@0
|
218 * @param array $config
|
Chris@0
|
219 * The config array.
|
Chris@0
|
220 */
|
Chris@0
|
221 public function setConfiguration($config) {
|
Chris@0
|
222 $this->configuration = $config;
|
Chris@0
|
223 }
|
Chris@0
|
224
|
Chris@0
|
225 /**
|
Chris@0
|
226 * {@inheritdoc}
|
Chris@0
|
227 */
|
Chris@0
|
228 public function getIds() {}
|
Chris@0
|
229
|
Chris@0
|
230 /**
|
Chris@0
|
231 * {@inheritdoc}
|
Chris@0
|
232 */
|
Chris@0
|
233 public function fields() {}
|
Chris@0
|
234
|
Chris@0
|
235 /**
|
Chris@0
|
236 * {@inheritdoc}
|
Chris@0
|
237 */
|
Chris@0
|
238 public function query() {
|
Chris@0
|
239 return $this->query;
|
Chris@0
|
240 }
|
Chris@0
|
241
|
Chris@0
|
242 /**
|
Chris@0
|
243 * Sets the query to execute.
|
Chris@0
|
244 *
|
Chris@0
|
245 * @param \Drupal\Core\Database\Query\SelectInterface $query
|
Chris@0
|
246 * The query to execute.
|
Chris@0
|
247 */
|
Chris@0
|
248 public function setQuery(SelectInterface $query) {
|
Chris@0
|
249 $this->query = $query;
|
Chris@0
|
250 }
|
Chris@0
|
251
|
Chris@0
|
252 /**
|
Chris@0
|
253 * {@inheritdoc}
|
Chris@0
|
254 */
|
Chris@0
|
255 public function getHighWaterStorage() {
|
Chris@0
|
256 return parent::getHighWaterStorage();
|
Chris@0
|
257 }
|
Chris@0
|
258
|
Chris@0
|
259 }
|