DB_Delta_Engine   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 50
dl 0
loc 180
rs 10
c 5
b 0
f 0
wmc 16

8 Methods

Rating   Name   Duplication   Size   Complexity  
A set_query_for_create() 0 7 2
A set_query_for_drop() 0 5 2
A __construct() 0 6 1
A compile_create_sql_query() 0 16 1
A create_table() 0 23 4
A create_table_query() 0 3 1
A drop_table() 0 19 4
A drop_table_query() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * WPDB DB_Delta table builder.
7
 *
8
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
9
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
10
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
11
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
12
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
13
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
14
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
15
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
16
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
17
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
18
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
 *
20
 * @since 0.3.0
21
 * @author Glynn Quelch <[email protected]>
22
 * @license http://www.opensource.org/licenses/mit-license.html  MIT License
23
 * @package PinkCrab\Table_Builder
24
 */
25
26
namespace PinkCrab\Table_Builder\Engines\WPDB_DB_Delta;
27
28
use PinkCrab\Table_Builder\Schema;
29
use PinkCrab\Table_Builder\Engines\Engine;
30
use PinkCrab\Table_Builder\Exception\Engine_Exception;
31
use PinkCrab\Table_Builder\Engines\WPDB_DB_Delta\DB_Delta_Validator;
32
use PinkCrab\Table_Builder\Engines\WPDB_DB_Delta\DB_Delta_Translator;
33
use PinkCrab\Table_Builder\Exception\WPDB_DB_Delta\WPDB_Validator_Exception;
34
35
class DB_Delta_Engine implements Engine {
36
37
	/**
38
	 * The engines validator class name.
39
	 *
40
	 * @var DB_Delta_Validator
41
	 */
42
	protected $validator;
43
44
	/**
45
	 * The WPDB Translator for SQL
46
	 *
47
	 * @var DB_Delta_Translator
48
	 */
49
	protected $translator;
50
51
	/**
52
	 * Access to wpdb
53
	 *
54
	 * @var \wpdb
55
	 */
56
	protected $wpdb;
57
58
59
	/**
60
	 * Holds access to the Schema definition
61
	 *
62
	 * @var Schema
63
	 */
64
	protected $schema;
65
66
	public function __construct( \wpdb $wpdb ) {
67
		$this->wpdb = $wpdb;
68
69
		// Set the translator and valiator
70
		$this->translator = new DB_Delta_Translator();
71
		$this->validator  = new DB_Delta_Validator();
72
	}
73
74
	/**
75
	 * Validate and set the schema
76
	 *
77
	 * @param \PinkCrab\Table_Builder\Schema $schema
78
	 * @return void
79
	 * @throws WPDB_Validator_Exception if fails validation (code 201)
80
	 */
81
	private function set_query_for_create( Schema $schema ): void {
82
		$this->schema = $schema;
83
84
		if ( ! $this->validator->validate( $schema ) ) {
85
			throw WPDB_Validator_Exception::failed_validation(
86
				$schema,
87
				$this->validator->get_errors()
88
			);
89
		}
90
91
	}
92
93
	/**
94
	 * Create the table based on the schema passed.
95
	 *
96
	 * @param \PinkCrab\Table_Builder\Schema $schema
97
	 * @return bool
98
	 * @throws WPDB_Validator_Exception if fails validation (code 201)
99
	 * @throws Engine_Exception If errors thrown creating table (code 101)
100
	 */
101
	public function create_table( Schema $schema ): bool {
102
103
		// Generate the query from the passed schema.
104
		$query = $this->create_table_query( $schema );
105
106
		// Include WP dbDelta.
107
		require_once ABSPATH . 'wp-admin/includes/upgrade.php';
108
109
		\ob_start();
110
		dbDelta( $query );
111
		$output = \ob_get_clean();
112
113
		// If output captured, throw.
114
		if ( '' !== $output ) {
115
			throw Engine_Exception::create_table( $schema, $output ?: '' );
116
		}
117
118
		// Throw if WPDB has errors.
119
		if ( '' !== $this->wpdb->last_error ) {
120
			throw Engine_Exception::create_table( $schema, $this->wpdb->last_error );
121
		}
122
123
		return true;
124
	}
125
126
	/**
127
	 * Returns the table query generated for creating a table
128
	 *
129
	 * @param \PinkCrab\Table_Builder\Schema $schema
130
	 * @return string
131
	 * @throws WPDB_Validator_Exception if fails validation (code 201)
132
	 */
133
	public function create_table_query( Schema $schema ): string {
134
		$this->set_query_for_create( $schema );
135
		return $this->compile_create_sql_query();
136
	}
137
138
	/**
139
	 * Validate and set the schema
140
	 *
141
	 * @param \PinkCrab\Table_Builder\Schema $schema
142
	 * @return void
143
	 * @throws WPDB_Validator_Exception If fails schema validation (code 201)
144
	 */
145
	private function set_query_for_drop( Schema $schema ): void {
146
		$this->schema = $schema;
147
148
		if ( ! $this->validator->validate( $schema ) ) {
149
			throw WPDB_Validator_Exception::failed_validation( $schema, $this->validator->get_errors() );
150
		}
151
	}
152
153
	/**
154
	 * Drops the table
155
	 *
156
	 * @param \PinkCrab\Table_Builder\Schema $schema
157
	 * @return bool
158
	 * @throws WPDB_Validator_Exception If fails schema validation (code 201)
159
	 * @throws Engine_Exception If error thrown dropping table. (code 102)
160
	 */
161
	public function drop_table( Schema $schema ): bool {
162
163
		$query = $this->drop_table_query( $schema );
164
165
		\ob_start();
166
		$this->wpdb->get_results( $query ); // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
167
		$output = \ob_get_clean();
168
169
		// If output captured, throw.
170
		if ( '' !== $output ) {
171
			throw Engine_Exception::drop_table( $schema, $output ?: '' );
172
		}
173
174
		// Throw if WPDB has errors.
175
		if ( '' !== $this->wpdb->last_error ) {
176
			throw Engine_Exception::drop_table( $schema, $this->wpdb->last_error );
177
		}
178
179
		return true;
180
	}
181
182
	/**
183
	 * Returns the query for dropping the curren table.
184
	 *
185
	 * @param \PinkCrab\Table_Builder\Schema $schema
186
	 * @return string
187
	 * @throws WPDB_Validator_Exception If fails schema validation (code 201)
188
	 */
189
	public function drop_table_query( Schema $schema ): string {
190
		$this->set_query_for_drop( $schema );
191
		return "DROP TABLE IF EXISTS {$this->schema->get_table_name()};";
192
	}
193
194
	/**
195
	 * Compiles the SQL query used to create a table.
196
	 *
197
	 * @return string
198
	 */
199
	protected function compile_create_sql_query(): string {
200
201
		// Compile query partials.
202
		$table   = $this->schema->get_table_name();
203
		$body    = join(
204
			',' . PHP_EOL,
205
			array_merge(
206
				$this->translator->translate_columns( $this->schema ),
207
				$this->translator->translate_indexes( $this->schema )
208
			)
209
		);
210
		$collate = $this->wpdb->collate;
211
212
		return <<<SQL
213
CREATE TABLE $table (
214
$body ) COLLATE $collate 
215
SQL;
216
	}
217
}
218