Passed
Push — master ( b7b77b...565dd3 )
by Glynn
05:12 queued 03:02
created
static-loader-creator.php 2 patches
Indentation   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -25,161 +25,161 @@  discard block
 block discarded – undo
25 25
 
26 26
 class StaticLoaderCreator
27 27
 {
28
-    /** @var string[] Array of file names */
29
-    protected array $files = [];
30
-
31
-    /** @var array<int, array{class:string|null, ns:string|null, interface:string|null, trait:string|null, file:string}> Classes */
32
-    protected array $classes = [];
33
-
34
-    /** @var string Path to the SRC directory. */
35
-    protected $routePath;
36
-
37
-    public function __construct()
38
-    {
39
-        $this->routePath = __DIR__ . DIRECTORY_SEPARATOR . 'src';
40
-    }
41
-
42
-    /**
43
-     * Static initialiser
44
-     *
45
-     * @return void
46
-     */
47
-    public static function run(): void
48
-    {
49
-        $instance = new self();
50
-        $instance->getFiles();
51
-        $instance->getClassNames();
52
-        $instance->writeLoader();
53
-    }
54
-
55
-    /**
56
-     * Get all filenames excluding the loader.
57
-     *
58
-     * @return void
59
-     */
60
-    public function getFiles(): void
61
-    {
62
-        $rii = new RecursiveIteratorIterator(
63
-            new RecursiveDirectoryIterator($this->routePath)
64
-        );
65
-
66
-        foreach ($rii as $file) {
67
-            if ($file->isDir() || $file->getPathname() === $this->routePath . DIRECTORY_SEPARATOR . 'loader.php') {
68
-                continue;
69
-            }
70
-
71
-            $this->files[] = $file->getPathname();
72
-        }
73
-    }
74
-
75
-    /**
76
-     * Compiles the list of classnames with file paths.
77
-     *
78
-     * @return void
79
-     */
80
-    public function getClassNames(): void
81
-    {
82
-        foreach ($this->files as $file) {
83
-            $classData['class'] = $this->getObjectTypeFromFile($file, T_CLASS);
84
-            $classData['trait'] = $this->getObjectTypeFromFile($file, T_TRAIT);
85
-            $classData['interface'] = $this->getObjectTypeFromFile($file, T_INTERFACE);
86
-            $classData['ns'] = $this->getNamespace($file);
87
-            $classData['file'] = str_replace($this->routePath, '', $file);
88
-            $this->classes[] = $classData;
89
-        }
90
-
91
-        // Set all classes to be required last, allow traits to load first.
92
-        uasort($this->classes, function ($file1, $file2) {
93
-            return is_null($file1['class']) ? -1 : 1;
94
-        });
95
-    }
96
-
97
-    /**
98
-     * Gets the namespace from a file.
99
-     *
100
-     * @see https://stackoverflow.com/questions/7153000/get-class-name-from-file/44654073
101
-     * @param string $file
102
-     * @return string|null
103
-     * @throws \Exception If file not found or empty.
104
-     */
105
-    public function getNamespace(string $file): ?string
106
-    {
107
-        $src = file_get_contents($file);
108
-
109
-        if (false === $src) {
110
-            throw new \Exception("Could not read contents of {$file}", 1);
111
-        }
112
-
113
-        $tokens = token_get_all($src);
114
-        $count = count($tokens);
115
-        $i = 0;
116
-        $namespace = '';
117
-        $namespace_ok = false;
118
-        while ($i < $count) {
119
-            $token = $tokens[$i];
120
-            if (is_array($token) && $token[0] === T_NAMESPACE) {
121
-                // Found namespace declaration
122
-                while (++$i < $count) {
123
-                    if ($tokens[$i] === ';') {
124
-                        $namespace_ok = true;
125
-                        $namespace = trim($namespace);
126
-                        break;
127
-                    }
128
-                    $namespace .= is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i];
129
-                }
130
-                break;
131
-            }
132
-            $i++;
133
-        }
134
-        if (!$namespace_ok) {
135
-            return null;
136
-        } else {
137
-            return $namespace;
138
-        }
139
-    }
140
-
141
-    /**
142
-     * get the class name form file path using token
143
-     *
144
-     * @see https://stackoverflow.com/questions/7153000/get-class-name-from-file/44654073
145
-     * @param string $file
146
-     * @param int $type
147
-     * @return string|null
148
-     */
149
-    protected function getObjectTypeFromFile(string $file, int $type = T_CLASS): ?string
150
-    {
151
-        $src = file_get_contents($file);
152
-
153
-        if (false === $src) {
154
-            throw new \Exception("Could not read contents of {$file}", 1);
155
-        }
156
-
157
-        $classes = array();
158
-        $tokens = token_get_all($src);
159
-        $count = count($tokens);
160
-        for ($i = 2; $i < $count; $i++) {
161
-            if (
162
-                $tokens[$i - 2][0] == $type
163
-                && $tokens[$i - 1][0] == T_WHITESPACE
164
-                && $tokens[$i][0] == T_STRING
165
-            ) {
166
-                $class_name = $tokens[$i][1];
167
-                $classes[] = $class_name;
168
-            }
169
-        }
170
-
171
-        return array_key_exists(0, $classes) ? $classes[0] : null;
172
-    }
173
-
174
-    /**
175
-     * Writes the loader.php file.
176
-     *
177
-     * @return void
178
-     */
179
-    public function writeLoader(): void
180
-    {
181
-        $newLine = PHP_EOL;
182
-        $header = "<?php{$newLine}{$newLine}{$newLine}
28
+	/** @var string[] Array of file names */
29
+	protected array $files = [];
30
+
31
+	/** @var array<int, array{class:string|null, ns:string|null, interface:string|null, trait:string|null, file:string}> Classes */
32
+	protected array $classes = [];
33
+
34
+	/** @var string Path to the SRC directory. */
35
+	protected $routePath;
36
+
37
+	public function __construct()
38
+	{
39
+		$this->routePath = __DIR__ . DIRECTORY_SEPARATOR . 'src';
40
+	}
41
+
42
+	/**
43
+	 * Static initialiser
44
+	 *
45
+	 * @return void
46
+	 */
47
+	public static function run(): void
48
+	{
49
+		$instance = new self();
50
+		$instance->getFiles();
51
+		$instance->getClassNames();
52
+		$instance->writeLoader();
53
+	}
54
+
55
+	/**
56
+	 * Get all filenames excluding the loader.
57
+	 *
58
+	 * @return void
59
+	 */
60
+	public function getFiles(): void
61
+	{
62
+		$rii = new RecursiveIteratorIterator(
63
+			new RecursiveDirectoryIterator($this->routePath)
64
+		);
65
+
66
+		foreach ($rii as $file) {
67
+			if ($file->isDir() || $file->getPathname() === $this->routePath . DIRECTORY_SEPARATOR . 'loader.php') {
68
+				continue;
69
+			}
70
+
71
+			$this->files[] = $file->getPathname();
72
+		}
73
+	}
74
+
75
+	/**
76
+	 * Compiles the list of classnames with file paths.
77
+	 *
78
+	 * @return void
79
+	 */
80
+	public function getClassNames(): void
81
+	{
82
+		foreach ($this->files as $file) {
83
+			$classData['class'] = $this->getObjectTypeFromFile($file, T_CLASS);
84
+			$classData['trait'] = $this->getObjectTypeFromFile($file, T_TRAIT);
85
+			$classData['interface'] = $this->getObjectTypeFromFile($file, T_INTERFACE);
86
+			$classData['ns'] = $this->getNamespace($file);
87
+			$classData['file'] = str_replace($this->routePath, '', $file);
88
+			$this->classes[] = $classData;
89
+		}
90
+
91
+		// Set all classes to be required last, allow traits to load first.
92
+		uasort($this->classes, function ($file1, $file2) {
93
+			return is_null($file1['class']) ? -1 : 1;
94
+		});
95
+	}
96
+
97
+	/**
98
+	 * Gets the namespace from a file.
99
+	 *
100
+	 * @see https://stackoverflow.com/questions/7153000/get-class-name-from-file/44654073
101
+	 * @param string $file
102
+	 * @return string|null
103
+	 * @throws \Exception If file not found or empty.
104
+	 */
105
+	public function getNamespace(string $file): ?string
106
+	{
107
+		$src = file_get_contents($file);
108
+
109
+		if (false === $src) {
110
+			throw new \Exception("Could not read contents of {$file}", 1);
111
+		}
112
+
113
+		$tokens = token_get_all($src);
114
+		$count = count($tokens);
115
+		$i = 0;
116
+		$namespace = '';
117
+		$namespace_ok = false;
118
+		while ($i < $count) {
119
+			$token = $tokens[$i];
120
+			if (is_array($token) && $token[0] === T_NAMESPACE) {
121
+				// Found namespace declaration
122
+				while (++$i < $count) {
123
+					if ($tokens[$i] === ';') {
124
+						$namespace_ok = true;
125
+						$namespace = trim($namespace);
126
+						break;
127
+					}
128
+					$namespace .= is_array($tokens[$i]) ? $tokens[$i][1] : $tokens[$i];
129
+				}
130
+				break;
131
+			}
132
+			$i++;
133
+		}
134
+		if (!$namespace_ok) {
135
+			return null;
136
+		} else {
137
+			return $namespace;
138
+		}
139
+	}
140
+
141
+	/**
142
+	 * get the class name form file path using token
143
+	 *
144
+	 * @see https://stackoverflow.com/questions/7153000/get-class-name-from-file/44654073
145
+	 * @param string $file
146
+	 * @param int $type
147
+	 * @return string|null
148
+	 */
149
+	protected function getObjectTypeFromFile(string $file, int $type = T_CLASS): ?string
150
+	{
151
+		$src = file_get_contents($file);
152
+
153
+		if (false === $src) {
154
+			throw new \Exception("Could not read contents of {$file}", 1);
155
+		}
156
+
157
+		$classes = array();
158
+		$tokens = token_get_all($src);
159
+		$count = count($tokens);
160
+		for ($i = 2; $i < $count; $i++) {
161
+			if (
162
+				$tokens[$i - 2][0] == $type
163
+				&& $tokens[$i - 1][0] == T_WHITESPACE
164
+				&& $tokens[$i][0] == T_STRING
165
+			) {
166
+				$class_name = $tokens[$i][1];
167
+				$classes[] = $class_name;
168
+			}
169
+		}
170
+
171
+		return array_key_exists(0, $classes) ? $classes[0] : null;
172
+	}
173
+
174
+	/**
175
+	 * Writes the loader.php file.
176
+	 *
177
+	 * @return void
178
+	 */
179
+	public function writeLoader(): void
180
+	{
181
+		$newLine = PHP_EOL;
182
+		$header = "<?php{$newLine}{$newLine}{$newLine}
183 183
 /**
184 184
  * Pixie WPDB Static Loader
185 185
  *
@@ -205,77 +205,77 @@  discard block
 block discarded – undo
205 205
 
206 206
 // Generated code start...";
207 207
 
208
-        $contents = array_map(function ($file, $class) {
209
-             return sprintf(
210
-                 "if (!%s(%s::class)) {
208
+		$contents = array_map(function ($file, $class) {
209
+			 return sprintf(
210
+				 "if (!%s(%s::class)) {
211 211
     require_once __DIR__ . '%s';
212 212
 }",
213
-                 $this->getMethodFromToken($class),
214
-                 $this->getFullTokenName($class),
215
-                 $class['file']
216
-             );
217
-        }, array_keys($this->classes), $this->classes);
218
-
219
-        $footer = sprintf("// CREATED ON %s", date('D jS F Y', time()));
220
-
221
-        $file = __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'loader.php';
222
-        touch($file);
223
-
224
-        file_put_contents(
225
-            $file,
226
-            join(PHP_EOL, [
227
-                $header,
228
-                join(PHP_EOL, $contents),
229
-                $footer, ''
230
-            ])
231
-        );
232
-    }
233
-
234
-    /**
235
-     * Gets the *_exists() method based on the token type.
236
-     *
237
-     * @param array{class:string|null, ns:string|null, interface:string|null, trait:string|null, file:string} $token
238
-     * @return string
239
-     */
240
-    public function getMethodFromToken(array $token): string
241
-    {
242
-        switch (true) {
243
-            case ! is_null($token['trait']):
244
-                return 'trait_exists';
245
-
246
-            case ! is_null($token['interface']):
247
-                return 'interface_exists';
248
-
249
-            default:
250
-                return 'class_exists';
251
-        }
252
-    }
253
-
254
-    /**
255
-     * Returns the full (namespaced) token name
256
-     *
257
-     * @param array{class:string|null, ns:string|null, interface:string|null, trait:string|null, file:string} $token
258
-     * @return string
259
-     */
260
-    public function getFullTokenName(array $token): string
261
-    {
262
-        switch (true) {
263
-            case ! array_key_exists('ns', $token):
264
-                return '';
265
-
266
-            case ! is_null($token['trait']):
267
-                return $token['ns'] . '\\' . $token['trait'];
268
-
269
-            case ! is_null($token['interface']):
270
-                return $token['ns'] . '\\' . $token['interface'];
271
-
272
-            case ! is_null($token['class']):
273
-                return $token['ns'] . '\\' . $token['class'];
274
-
275
-            default:
276
-                return '';
277
-        }
278
-    }
213
+				 $this->getMethodFromToken($class),
214
+				 $this->getFullTokenName($class),
215
+				 $class['file']
216
+			 );
217
+		}, array_keys($this->classes), $this->classes);
218
+
219
+		$footer = sprintf("// CREATED ON %s", date('D jS F Y', time()));
220
+
221
+		$file = __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'loader.php';
222
+		touch($file);
223
+
224
+		file_put_contents(
225
+			$file,
226
+			join(PHP_EOL, [
227
+				$header,
228
+				join(PHP_EOL, $contents),
229
+				$footer, ''
230
+			])
231
+		);
232
+	}
233
+
234
+	/**
235
+	 * Gets the *_exists() method based on the token type.
236
+	 *
237
+	 * @param array{class:string|null, ns:string|null, interface:string|null, trait:string|null, file:string} $token
238
+	 * @return string
239
+	 */
240
+	public function getMethodFromToken(array $token): string
241
+	{
242
+		switch (true) {
243
+			case ! is_null($token['trait']):
244
+				return 'trait_exists';
245
+
246
+			case ! is_null($token['interface']):
247
+				return 'interface_exists';
248
+
249
+			default:
250
+				return 'class_exists';
251
+		}
252
+	}
253
+
254
+	/**
255
+	 * Returns the full (namespaced) token name
256
+	 *
257
+	 * @param array{class:string|null, ns:string|null, interface:string|null, trait:string|null, file:string} $token
258
+	 * @return string
259
+	 */
260
+	public function getFullTokenName(array $token): string
261
+	{
262
+		switch (true) {
263
+			case ! array_key_exists('ns', $token):
264
+				return '';
265
+
266
+			case ! is_null($token['trait']):
267
+				return $token['ns'] . '\\' . $token['trait'];
268
+
269
+			case ! is_null($token['interface']):
270
+				return $token['ns'] . '\\' . $token['interface'];
271
+
272
+			case ! is_null($token['class']):
273
+				return $token['ns'] . '\\' . $token['class'];
274
+
275
+			default:
276
+				return '';
277
+		}
278
+	}
279 279
 }
280 280
 
281 281
 StaticLoaderCreator::run();
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -36,7 +36,7 @@  discard block
 block discarded – undo
36 36
 
37 37
     public function __construct()
38 38
     {
39
-        $this->routePath = __DIR__ . DIRECTORY_SEPARATOR . 'src';
39
+        $this->routePath = __DIR__.DIRECTORY_SEPARATOR.'src';
40 40
     }
41 41
 
42 42
     /**
@@ -64,7 +64,7 @@  discard block
 block discarded – undo
64 64
         );
65 65
 
66 66
         foreach ($rii as $file) {
67
-            if ($file->isDir() || $file->getPathname() === $this->routePath . DIRECTORY_SEPARATOR . 'loader.php') {
67
+            if ($file->isDir() || $file->getPathname() === $this->routePath.DIRECTORY_SEPARATOR.'loader.php') {
68 68
                 continue;
69 69
             }
70 70
 
@@ -89,7 +89,7 @@  discard block
 block discarded – undo
89 89
         }
90 90
 
91 91
         // Set all classes to be required last, allow traits to load first.
92
-        uasort($this->classes, function ($file1, $file2) {
92
+        uasort($this->classes, function($file1, $file2) {
93 93
             return is_null($file1['class']) ? -1 : 1;
94 94
         });
95 95
     }
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
             }
132 132
             $i++;
133 133
         }
134
-        if (!$namespace_ok) {
134
+        if ( ! $namespace_ok) {
135 135
             return null;
136 136
         } else {
137 137
             return $namespace;
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
 
206 206
 // Generated code start...";
207 207
 
208
-        $contents = array_map(function ($file, $class) {
208
+        $contents = array_map(function($file, $class) {
209 209
              return sprintf(
210 210
                  "if (!%s(%s::class)) {
211 211
     require_once __DIR__ . '%s';
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
 
219 219
         $footer = sprintf("// CREATED ON %s", date('D jS F Y', time()));
220 220
 
221
-        $file = __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'loader.php';
221
+        $file = __DIR__.DIRECTORY_SEPARATOR.'src'.DIRECTORY_SEPARATOR.'loader.php';
222 222
         touch($file);
223 223
 
224 224
         file_put_contents(
@@ -264,13 +264,13 @@  discard block
 block discarded – undo
264 264
                 return '';
265 265
 
266 266
             case ! is_null($token['trait']):
267
-                return $token['ns'] . '\\' . $token['trait'];
267
+                return $token['ns'].'\\'.$token['trait'];
268 268
 
269 269
             case ! is_null($token['interface']):
270
-                return $token['ns'] . '\\' . $token['interface'];
270
+                return $token['ns'].'\\'.$token['interface'];
271 271
 
272 272
             case ! is_null($token['class']):
273
-                return $token['ns'] . '\\' . $token['class'];
273
+                return $token['ns'].'\\'.$token['class'];
274 274
 
275 275
             default:
276 276
                 return '';
Please login to merge, or discard this patch.
src/QueryBuilder/JsonQueryBuilder.php 1 patch
Indentation   +444 added lines, -444 removed lines patch added patch discarded remove patch
@@ -4,448 +4,448 @@
 block discarded – undo
4 4
 
5 5
 class JsonQueryBuilder extends QueryBuilderHandler
6 6
 {
7
-    /**
8
-    * @param string|Raw $column The database column which holds the JSON value
9
-    * @param string|Raw|string[] $nodes The json key/index to search
10
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
11
-    * @param mixed|null $value
12
-    * @return static
13
-    */
14
-    public function whereJson($column, $nodes, $operator = null, $value = null): self
15
-    {
16
-        // If two params are given then assume operator is =
17
-        if (3 === func_num_args()) {
18
-            $value    = $operator;
19
-            $operator = '=';
20
-        }
21
-
22
-        return $this->whereJsonHandler($column, $nodes, $operator, $value, 'AND');
23
-    }
24
-
25
-    /**
26
-     * @param string|Raw $column The database column which holds the JSON value
27
-     * @param string|Raw|string[] $nodes The json key/index to search
28
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
29
-     * @param mixed|null $value
30
-     * @return static
31
-     */
32
-    public function whereNotJson($column, $nodes, $operator = null, $value = null): self
33
-    {
34
-        // If two params are given then assume operator is =
35
-        if (3 === func_num_args()) {
36
-            $value    = $operator;
37
-            $operator = '=';
38
-        }
39
-
40
-        return $this->whereJsonHandler($column, $nodes, $operator, $value, 'AND NOT');
41
-    }
42
-
43
-    /**
44
-    * @param string|Raw $column The database column which holds the JSON value
45
-    * @param string|Raw|string[] $nodes The json key/index to search
46
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
47
-    * @param mixed|null $value
48
-    * @return static
49
-    */
50
-    public function orWhereJson($column, $nodes, $operator = null, $value = null): self
51
-    {
52
-        // If two params are given then assume operator is =
53
-        if (3 === func_num_args()) {
54
-            $value    = $operator;
55
-            $operator = '=';
56
-        }
57
-
58
-        return $this->whereJsonHandler($column, $nodes, $operator, $value, 'OR');
59
-    }
60
-
61
-    /**
62
-    * @param string|Raw $column The database column which holds the JSON value
63
-    * @param string|Raw|string[] $nodes The json key/index to search
64
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
65
-    * @param mixed|null $value
66
-    * @return static
67
-    */
68
-    public function orWhereNotJson($column, $nodes, $operator = null, $value = null): self
69
-    {
70
-        // If two params are given then assume operator is =
71
-        if (3 === func_num_args()) {
72
-            $value    = $operator;
73
-            $operator = '=';
74
-        }
75
-
76
-        return $this->whereJsonHandler($column, $nodes, $operator, $value, 'OR NOT');
77
-    }
78
-
79
-    /**
80
-    * @param string|Raw $column The database column which holds the JSON value
81
-    * @param string|Raw|string[] $nodes The json key/index to search
82
-    * @param mixed[] $values
83
-    * @return static
84
-    */
85
-    public function whereInJson($column, $nodes, $values): self
86
-    {
87
-        return $this->whereJsonHandler($column, $nodes, 'IN', $values, 'AND');
88
-    }
89
-
90
-    /**
91
-    * @param string|Raw $column The database column which holds the JSON value
92
-    * @param string|Raw|string[] $nodes The json key/index to search
93
-    * @param mixed[] $values
94
-    * @return static
95
-    */
96
-    public function whereNotInJson($column, $nodes, $values): self
97
-    {
98
-        return $this->whereJsonHandler($column, $nodes, 'NOT IN', $values, 'AND');
99
-    }
100
-
101
-    /**
102
-    * @param string|Raw $column The database column which holds the JSON value
103
-    * @param string|Raw|string[] $nodes The json key/index to search
104
-    * @param mixed[] $values
105
-    * @return static
106
-    */
107
-    public function orWhereInJson($column, $nodes, $values): self
108
-    {
109
-        return $this->whereJsonHandler($column, $nodes, 'IN', $values, 'OR');
110
-    }
111
-
112
-    /**
113
-    * @param string|Raw $column The database column which holds the JSON value
114
-    * @param string|Raw|string[] $nodes The json key/index to search
115
-    * @param mixed[] $values
116
-    * @return static
117
-    */
118
-    public function orWhereNotInJson($column, $nodes, $values): self
119
-    {
120
-        return $this->whereJsonHandler($column, $nodes, 'NOT IN', $values, 'OR');
121
-    }
122
-
123
-    /**
124
-     * @param string|Raw $column
125
-    * @param string|Raw|string[] $nodes The json key/index to search
126
-     * @param mixed $valueFrom
127
-     * @param mixed $valueTo
128
-     *
129
-     * @return static
130
-     */
131
-    public function whereBetweenJson($column, $nodes, $valueFrom, $valueTo): self
132
-    {
133
-        return $this->whereJsonHandler($column, $nodes, 'BETWEEN', [$valueFrom, $valueTo], 'AND');
134
-    }
135
-
136
-    /**
137
-     * @param string|Raw $column
138
-    * @param string|Raw|string[] $nodes The json key/index to search
139
-     * @param mixed $valueFrom
140
-     * @param mixed $valueTo
141
-     *
142
-     * @return static
143
-     */
144
-    public function orWhereBetweenJson($column, $nodes, $valueFrom, $valueTo): self
145
-    {
146
-        return $this->whereJsonHandler($column, $nodes, 'BETWEEN', [$valueFrom, $valueTo], 'OR');
147
-    }
148
-
149
-    /**
150
-    * @param string|Raw $column The database column which holds the JSON value
151
-    * @param string|Raw|string[] $nodes The json key/index to search
152
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
153
-    * @param mixed|null $value
154
-    * @return static
155
-    */
156
-    public function whereDayJson($column, $nodes, $operator = null, $value = null): self
157
-    {
158
-        // If two params are given then assume operator is =
159
-        if (3 === func_num_args()) {
160
-            $value    = $operator;
161
-            $operator = '=';
162
-        }
163
-        return $this->whereFunctionCallJsonHandler($column, $nodes, 'DAY', $operator, $value);
164
-    }
165
-
166
-    /**
167
-    * @param string|Raw $column The database column which holds the JSON value
168
-    * @param string|Raw|string[] $nodes The json key/index to search
169
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
170
-    * @param mixed|null $value
171
-    * @return static
172
-    */
173
-    public function whereMonthJson($column, $nodes, $operator = null, $value = null): self
174
-    {
175
-        // If two params are given then assume operator is =
176
-        if (3 === func_num_args()) {
177
-            $value    = $operator;
178
-            $operator = '=';
179
-        }
180
-        return $this->whereFunctionCallJsonHandler($column, $nodes, 'MONTH', $operator, $value);
181
-    }
182
-
183
-    /**
184
-    * @param string|Raw $column The database column which holds the JSON value
185
-    * @param string|Raw|string[] $nodes The json key/index to search
186
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
187
-    * @param mixed|null $value
188
-    * @return static
189
-    */
190
-    public function whereYearJson($column, $nodes, $operator = null, $value = null): self
191
-    {
192
-        // If two params are given then assume operator is =
193
-        if (3 === func_num_args()) {
194
-            $value    = $operator;
195
-            $operator = '=';
196
-        }
197
-        return $this->whereFunctionCallJsonHandler($column, $nodes, 'YEAR', $operator, $value);
198
-    }
199
-
200
-    /**
201
-    * @param string|Raw $column The database column which holds the JSON value
202
-    * @param string|Raw|string[] $nodes The json key/index to search
203
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
204
-    * @param mixed|null $value
205
-    * @return static
206
-    */
207
-    public function whereDateJson($column, $nodes, $operator = null, $value = null): self
208
-    {
209
-        // If two params are given then assume operator is =
210
-        if (3 === func_num_args()) {
211
-            $value    = $operator;
212
-            $operator = '=';
213
-        }
214
-        return $this->whereFunctionCallJsonHandler($column, $nodes, 'DATE', $operator, $value);
215
-    }
216
-
217
-    /**
218
-     * Maps a function call for a JSON where condition
219
-     *
220
-     * @param string|Raw $column
221
-     * @param string|Raw|string[] $nodes
222
-     * @param string $function
223
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
224
-     * @param mixed|null $value
225
-     * @return static
226
-     */
227
-    protected function whereFunctionCallJsonHandler($column, $nodes, $function, $operator, $value): self
228
-    {
229
-        // Handle potential raw values.
230
-        if ($column instanceof Raw) {
231
-            $column = $this->adapterInstance->parseRaw($column);
232
-        }
233
-        if ($nodes instanceof Raw) {
234
-            $nodes = $this->adapterInstance->parseRaw($nodes);
235
-        }
236
-
237
-        return $this->whereFunctionCallHandler(
238
-            $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($column, $nodes),
239
-            $function,
240
-            $operator,
241
-            $value
242
-        );
243
-    }
244
-
245
-    /**
246
-    * @param string|Raw $column The database column which holds the JSON value
247
-    * @param string|Raw|string[] $nodes The json key/index to search
248
-    * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
249
-    * @param mixed|null $value
250
-    * @param string $joiner
251
-    * @return static
252
-    */
253
-    protected function whereJsonHandler($column, $nodes, $operator = null, $value = null, string $joiner = 'AND'): self
254
-    {
255
-        // Handle potential raw values.
256
-        if ($column instanceof Raw) {
257
-            $column = $this->adapterInstance->parseRaw($column);
258
-        }
259
-        if ($nodes instanceof Raw) {
260
-            $nodes = $this->adapterInstance->parseRaw($nodes);
261
-        }
262
-
263
-        return $this->whereHandler(
264
-            $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($column, $nodes),
265
-            $operator,
266
-            $value,
267
-            $joiner
268
-        );
269
-    }
270
-
271
-    /**
272
-     * @param string|Raw $table
273
-     * @param string|Raw $leftColumn
274
-     * @param string|Raw|string[]|null $leftNodes The json key/index to search
275
-     * @param string $operator
276
-     * @param string|Raw $rightColumn
277
-     * @param string|Raw|string[]|null $rightNodes
278
-     * @param string $type
279
-     *
280
-     * @return static
281
-     */
282
-    public function joinJson(
283
-        $table,
284
-        $leftColumn,
285
-        $leftNodes,
286
-        string $operator,
287
-        $rightColumn,
288
-        $rightNodes,
289
-        $type = 'inner'
290
-    ): self {
291
-        // Convert key if json
292
-        if (null !== $rightNodes) {
293
-            $rightColumn = $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($rightColumn, $rightNodes);
294
-        }
295
-
296
-        // Convert key if json
297
-        if (null !== $leftNodes) {
298
-            $leftColumn = $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($leftColumn, $leftNodes);
299
-        }
300
-
301
-        return $this->join($table, $leftColumn, $operator, $rightColumn, $type);
302
-    }
303
-
304
-    /**
305
-     * @param string|Raw $table
306
-     * @param string|Raw $leftColumn
307
-     * @param string|Raw|string[]|null $leftNodes The json key/index to search
308
-     * @param string $operator
309
-     * @param string|Raw $rightColumn
310
-     * @param string|Raw|string[]|null $rightNodes
311
-     *
312
-     * @return static
313
-     */
314
-    public function leftJoinJson(
315
-        $table,
316
-        $leftColumn,
317
-        $leftNodes,
318
-        string $operator,
319
-        $rightColumn,
320
-        $rightNodes
321
-    ): self {
322
-        return $this->joinJson(
323
-            $table,
324
-            $leftColumn,
325
-            $leftNodes,
326
-            $operator,
327
-            $rightColumn,
328
-            $rightNodes,
329
-            'left'
330
-        );
331
-    }
332
-
333
-    /**
334
-     * @param string|Raw $table
335
-     * @param string|Raw $leftColumn
336
-     * @param string|Raw|string[]|null $leftNodes The json key/index to search
337
-     * @param string $operator
338
-     * @param string|Raw $rightColumn
339
-     * @param string|Raw|string[]|null $rightNodes
340
-     *
341
-     * @return static
342
-     */
343
-    public function rightJoinJson(
344
-        $table,
345
-        $leftColumn,
346
-        $leftNodes,
347
-        string $operator,
348
-        $rightColumn,
349
-        $rightNodes
350
-    ): self {
351
-        return $this->joinJson(
352
-            $table,
353
-            $leftColumn,
354
-            $leftNodes,
355
-            $operator,
356
-            $rightColumn,
357
-            $rightNodes,
358
-            'right'
359
-        );
360
-    }
361
-
362
-    /**
363
-     * @param string|Raw $table
364
-     * @param string|Raw $leftColumn
365
-     * @param string|Raw|string[]|null $leftNodes The json key/index to search
366
-     * @param string $operator
367
-     * @param string|Raw $rightColumn
368
-     * @param string|Raw|string[]|null $rightNodes
369
-     *
370
-     * @return static
371
-     */
372
-    public function outerJoinJson(
373
-        $table,
374
-        $leftColumn,
375
-        $leftNodes,
376
-        string $operator,
377
-        $rightColumn,
378
-        $rightNodes
379
-    ): self {
380
-        return $this->joinJson(
381
-            $table,
382
-            $leftColumn,
383
-            $leftNodes,
384
-            $operator,
385
-            $rightColumn,
386
-            $rightNodes,
387
-            'FULL OUTER'
388
-        );
389
-    }
390
-
391
-    /**
392
-     * @param string|Raw $table
393
-     * @param string|Raw $leftColumn
394
-     * @param string|Raw|string[]|null $leftNodes The json key/index to search
395
-     * @param string $operator
396
-     * @param string|Raw $rightColumn
397
-     * @param string|Raw|string[]|null $rightNodes
398
-     *
399
-     * @return static
400
-     */
401
-    public function crossJoinJson(
402
-        $table,
403
-        $leftColumn,
404
-        $leftNodes,
405
-        string $operator,
406
-        $rightColumn,
407
-        $rightNodes
408
-    ): self {
409
-        return $this->joinJson(
410
-            $table,
411
-            $leftColumn,
412
-            $leftNodes,
413
-            $operator,
414
-            $rightColumn,
415
-            $rightNodes,
416
-            'cross'
417
-        );
418
-    }
419
-
420
-
421
-
422
-    // JSON
423
-
424
-    /**
425
-     * @param string|Raw $column The database column which holds the JSON value
426
-     * @param string|Raw|string[] $nodes The json key/index to search
427
-     * @param string|null $alias The alias used to define the value in results, if not defined will use json_{$nodes}
428
-     * @return static
429
-     */
430
-    public function selectJson($column, $nodes, ?string $alias = null): self
431
-    {
432
-        // Handle potential raw values.
433
-        if ($column instanceof Raw) {
434
-            $column = $this->adapterInstance->parseRaw($column);
435
-        }
436
-        if ($nodes instanceof Raw) {
437
-            $nodes = $this->adapterInstance->parseRaw($nodes);
438
-        }
439
-
440
-        // If deeply nested jsonKey.
441
-        if (is_array($nodes)) {
442
-            $nodes = \implode('.', $nodes);
443
-        }
444
-
445
-        // Add any possible prefixes to the key
446
-        $column = $this->addTablePrefix($column, true);
447
-
448
-        $alias = null === $alias ? "json_{$nodes}" : $alias;
449
-        return  $this->select(new Raw("JSON_UNQUOTE(JSON_EXTRACT({$column}, \"$.{$nodes}\")) as {$alias}"));
450
-    }
7
+	/**
8
+	 * @param string|Raw $column The database column which holds the JSON value
9
+	 * @param string|Raw|string[] $nodes The json key/index to search
10
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
11
+	 * @param mixed|null $value
12
+	 * @return static
13
+	 */
14
+	public function whereJson($column, $nodes, $operator = null, $value = null): self
15
+	{
16
+		// If two params are given then assume operator is =
17
+		if (3 === func_num_args()) {
18
+			$value    = $operator;
19
+			$operator = '=';
20
+		}
21
+
22
+		return $this->whereJsonHandler($column, $nodes, $operator, $value, 'AND');
23
+	}
24
+
25
+	/**
26
+	 * @param string|Raw $column The database column which holds the JSON value
27
+	 * @param string|Raw|string[] $nodes The json key/index to search
28
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
29
+	 * @param mixed|null $value
30
+	 * @return static
31
+	 */
32
+	public function whereNotJson($column, $nodes, $operator = null, $value = null): self
33
+	{
34
+		// If two params are given then assume operator is =
35
+		if (3 === func_num_args()) {
36
+			$value    = $operator;
37
+			$operator = '=';
38
+		}
39
+
40
+		return $this->whereJsonHandler($column, $nodes, $operator, $value, 'AND NOT');
41
+	}
42
+
43
+	/**
44
+	 * @param string|Raw $column The database column which holds the JSON value
45
+	 * @param string|Raw|string[] $nodes The json key/index to search
46
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
47
+	 * @param mixed|null $value
48
+	 * @return static
49
+	 */
50
+	public function orWhereJson($column, $nodes, $operator = null, $value = null): self
51
+	{
52
+		// If two params are given then assume operator is =
53
+		if (3 === func_num_args()) {
54
+			$value    = $operator;
55
+			$operator = '=';
56
+		}
57
+
58
+		return $this->whereJsonHandler($column, $nodes, $operator, $value, 'OR');
59
+	}
60
+
61
+	/**
62
+	 * @param string|Raw $column The database column which holds the JSON value
63
+	 * @param string|Raw|string[] $nodes The json key/index to search
64
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
65
+	 * @param mixed|null $value
66
+	 * @return static
67
+	 */
68
+	public function orWhereNotJson($column, $nodes, $operator = null, $value = null): self
69
+	{
70
+		// If two params are given then assume operator is =
71
+		if (3 === func_num_args()) {
72
+			$value    = $operator;
73
+			$operator = '=';
74
+		}
75
+
76
+		return $this->whereJsonHandler($column, $nodes, $operator, $value, 'OR NOT');
77
+	}
78
+
79
+	/**
80
+	 * @param string|Raw $column The database column which holds the JSON value
81
+	 * @param string|Raw|string[] $nodes The json key/index to search
82
+	 * @param mixed[] $values
83
+	 * @return static
84
+	 */
85
+	public function whereInJson($column, $nodes, $values): self
86
+	{
87
+		return $this->whereJsonHandler($column, $nodes, 'IN', $values, 'AND');
88
+	}
89
+
90
+	/**
91
+	 * @param string|Raw $column The database column which holds the JSON value
92
+	 * @param string|Raw|string[] $nodes The json key/index to search
93
+	 * @param mixed[] $values
94
+	 * @return static
95
+	 */
96
+	public function whereNotInJson($column, $nodes, $values): self
97
+	{
98
+		return $this->whereJsonHandler($column, $nodes, 'NOT IN', $values, 'AND');
99
+	}
100
+
101
+	/**
102
+	 * @param string|Raw $column The database column which holds the JSON value
103
+	 * @param string|Raw|string[] $nodes The json key/index to search
104
+	 * @param mixed[] $values
105
+	 * @return static
106
+	 */
107
+	public function orWhereInJson($column, $nodes, $values): self
108
+	{
109
+		return $this->whereJsonHandler($column, $nodes, 'IN', $values, 'OR');
110
+	}
111
+
112
+	/**
113
+	 * @param string|Raw $column The database column which holds the JSON value
114
+	 * @param string|Raw|string[] $nodes The json key/index to search
115
+	 * @param mixed[] $values
116
+	 * @return static
117
+	 */
118
+	public function orWhereNotInJson($column, $nodes, $values): self
119
+	{
120
+		return $this->whereJsonHandler($column, $nodes, 'NOT IN', $values, 'OR');
121
+	}
122
+
123
+	/**
124
+	 * @param string|Raw $column
125
+	 * @param string|Raw|string[] $nodes The json key/index to search
126
+	 * @param mixed $valueFrom
127
+	 * @param mixed $valueTo
128
+	 *
129
+	 * @return static
130
+	 */
131
+	public function whereBetweenJson($column, $nodes, $valueFrom, $valueTo): self
132
+	{
133
+		return $this->whereJsonHandler($column, $nodes, 'BETWEEN', [$valueFrom, $valueTo], 'AND');
134
+	}
135
+
136
+	/**
137
+	 * @param string|Raw $column
138
+	 * @param string|Raw|string[] $nodes The json key/index to search
139
+	 * @param mixed $valueFrom
140
+	 * @param mixed $valueTo
141
+	 *
142
+	 * @return static
143
+	 */
144
+	public function orWhereBetweenJson($column, $nodes, $valueFrom, $valueTo): self
145
+	{
146
+		return $this->whereJsonHandler($column, $nodes, 'BETWEEN', [$valueFrom, $valueTo], 'OR');
147
+	}
148
+
149
+	/**
150
+	 * @param string|Raw $column The database column which holds the JSON value
151
+	 * @param string|Raw|string[] $nodes The json key/index to search
152
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
153
+	 * @param mixed|null $value
154
+	 * @return static
155
+	 */
156
+	public function whereDayJson($column, $nodes, $operator = null, $value = null): self
157
+	{
158
+		// If two params are given then assume operator is =
159
+		if (3 === func_num_args()) {
160
+			$value    = $operator;
161
+			$operator = '=';
162
+		}
163
+		return $this->whereFunctionCallJsonHandler($column, $nodes, 'DAY', $operator, $value);
164
+	}
165
+
166
+	/**
167
+	 * @param string|Raw $column The database column which holds the JSON value
168
+	 * @param string|Raw|string[] $nodes The json key/index to search
169
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
170
+	 * @param mixed|null $value
171
+	 * @return static
172
+	 */
173
+	public function whereMonthJson($column, $nodes, $operator = null, $value = null): self
174
+	{
175
+		// If two params are given then assume operator is =
176
+		if (3 === func_num_args()) {
177
+			$value    = $operator;
178
+			$operator = '=';
179
+		}
180
+		return $this->whereFunctionCallJsonHandler($column, $nodes, 'MONTH', $operator, $value);
181
+	}
182
+
183
+	/**
184
+	 * @param string|Raw $column The database column which holds the JSON value
185
+	 * @param string|Raw|string[] $nodes The json key/index to search
186
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
187
+	 * @param mixed|null $value
188
+	 * @return static
189
+	 */
190
+	public function whereYearJson($column, $nodes, $operator = null, $value = null): self
191
+	{
192
+		// If two params are given then assume operator is =
193
+		if (3 === func_num_args()) {
194
+			$value    = $operator;
195
+			$operator = '=';
196
+		}
197
+		return $this->whereFunctionCallJsonHandler($column, $nodes, 'YEAR', $operator, $value);
198
+	}
199
+
200
+	/**
201
+	 * @param string|Raw $column The database column which holds the JSON value
202
+	 * @param string|Raw|string[] $nodes The json key/index to search
203
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
204
+	 * @param mixed|null $value
205
+	 * @return static
206
+	 */
207
+	public function whereDateJson($column, $nodes, $operator = null, $value = null): self
208
+	{
209
+		// If two params are given then assume operator is =
210
+		if (3 === func_num_args()) {
211
+			$value    = $operator;
212
+			$operator = '=';
213
+		}
214
+		return $this->whereFunctionCallJsonHandler($column, $nodes, 'DATE', $operator, $value);
215
+	}
216
+
217
+	/**
218
+	 * Maps a function call for a JSON where condition
219
+	 *
220
+	 * @param string|Raw $column
221
+	 * @param string|Raw|string[] $nodes
222
+	 * @param string $function
223
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
224
+	 * @param mixed|null $value
225
+	 * @return static
226
+	 */
227
+	protected function whereFunctionCallJsonHandler($column, $nodes, $function, $operator, $value): self
228
+	{
229
+		// Handle potential raw values.
230
+		if ($column instanceof Raw) {
231
+			$column = $this->adapterInstance->parseRaw($column);
232
+		}
233
+		if ($nodes instanceof Raw) {
234
+			$nodes = $this->adapterInstance->parseRaw($nodes);
235
+		}
236
+
237
+		return $this->whereFunctionCallHandler(
238
+			$this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($column, $nodes),
239
+			$function,
240
+			$operator,
241
+			$value
242
+		);
243
+	}
244
+
245
+	/**
246
+	 * @param string|Raw $column The database column which holds the JSON value
247
+	 * @param string|Raw|string[] $nodes The json key/index to search
248
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
249
+	 * @param mixed|null $value
250
+	 * @param string $joiner
251
+	 * @return static
252
+	 */
253
+	protected function whereJsonHandler($column, $nodes, $operator = null, $value = null, string $joiner = 'AND'): self
254
+	{
255
+		// Handle potential raw values.
256
+		if ($column instanceof Raw) {
257
+			$column = $this->adapterInstance->parseRaw($column);
258
+		}
259
+		if ($nodes instanceof Raw) {
260
+			$nodes = $this->adapterInstance->parseRaw($nodes);
261
+		}
262
+
263
+		return $this->whereHandler(
264
+			$this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($column, $nodes),
265
+			$operator,
266
+			$value,
267
+			$joiner
268
+		);
269
+	}
270
+
271
+	/**
272
+	 * @param string|Raw $table
273
+	 * @param string|Raw $leftColumn
274
+	 * @param string|Raw|string[]|null $leftNodes The json key/index to search
275
+	 * @param string $operator
276
+	 * @param string|Raw $rightColumn
277
+	 * @param string|Raw|string[]|null $rightNodes
278
+	 * @param string $type
279
+	 *
280
+	 * @return static
281
+	 */
282
+	public function joinJson(
283
+		$table,
284
+		$leftColumn,
285
+		$leftNodes,
286
+		string $operator,
287
+		$rightColumn,
288
+		$rightNodes,
289
+		$type = 'inner'
290
+	): self {
291
+		// Convert key if json
292
+		if (null !== $rightNodes) {
293
+			$rightColumn = $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($rightColumn, $rightNodes);
294
+		}
295
+
296
+		// Convert key if json
297
+		if (null !== $leftNodes) {
298
+			$leftColumn = $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($leftColumn, $leftNodes);
299
+		}
300
+
301
+		return $this->join($table, $leftColumn, $operator, $rightColumn, $type);
302
+	}
303
+
304
+	/**
305
+	 * @param string|Raw $table
306
+	 * @param string|Raw $leftColumn
307
+	 * @param string|Raw|string[]|null $leftNodes The json key/index to search
308
+	 * @param string $operator
309
+	 * @param string|Raw $rightColumn
310
+	 * @param string|Raw|string[]|null $rightNodes
311
+	 *
312
+	 * @return static
313
+	 */
314
+	public function leftJoinJson(
315
+		$table,
316
+		$leftColumn,
317
+		$leftNodes,
318
+		string $operator,
319
+		$rightColumn,
320
+		$rightNodes
321
+	): self {
322
+		return $this->joinJson(
323
+			$table,
324
+			$leftColumn,
325
+			$leftNodes,
326
+			$operator,
327
+			$rightColumn,
328
+			$rightNodes,
329
+			'left'
330
+		);
331
+	}
332
+
333
+	/**
334
+	 * @param string|Raw $table
335
+	 * @param string|Raw $leftColumn
336
+	 * @param string|Raw|string[]|null $leftNodes The json key/index to search
337
+	 * @param string $operator
338
+	 * @param string|Raw $rightColumn
339
+	 * @param string|Raw|string[]|null $rightNodes
340
+	 *
341
+	 * @return static
342
+	 */
343
+	public function rightJoinJson(
344
+		$table,
345
+		$leftColumn,
346
+		$leftNodes,
347
+		string $operator,
348
+		$rightColumn,
349
+		$rightNodes
350
+	): self {
351
+		return $this->joinJson(
352
+			$table,
353
+			$leftColumn,
354
+			$leftNodes,
355
+			$operator,
356
+			$rightColumn,
357
+			$rightNodes,
358
+			'right'
359
+		);
360
+	}
361
+
362
+	/**
363
+	 * @param string|Raw $table
364
+	 * @param string|Raw $leftColumn
365
+	 * @param string|Raw|string[]|null $leftNodes The json key/index to search
366
+	 * @param string $operator
367
+	 * @param string|Raw $rightColumn
368
+	 * @param string|Raw|string[]|null $rightNodes
369
+	 *
370
+	 * @return static
371
+	 */
372
+	public function outerJoinJson(
373
+		$table,
374
+		$leftColumn,
375
+		$leftNodes,
376
+		string $operator,
377
+		$rightColumn,
378
+		$rightNodes
379
+	): self {
380
+		return $this->joinJson(
381
+			$table,
382
+			$leftColumn,
383
+			$leftNodes,
384
+			$operator,
385
+			$rightColumn,
386
+			$rightNodes,
387
+			'FULL OUTER'
388
+		);
389
+	}
390
+
391
+	/**
392
+	 * @param string|Raw $table
393
+	 * @param string|Raw $leftColumn
394
+	 * @param string|Raw|string[]|null $leftNodes The json key/index to search
395
+	 * @param string $operator
396
+	 * @param string|Raw $rightColumn
397
+	 * @param string|Raw|string[]|null $rightNodes
398
+	 *
399
+	 * @return static
400
+	 */
401
+	public function crossJoinJson(
402
+		$table,
403
+		$leftColumn,
404
+		$leftNodes,
405
+		string $operator,
406
+		$rightColumn,
407
+		$rightNodes
408
+	): self {
409
+		return $this->joinJson(
410
+			$table,
411
+			$leftColumn,
412
+			$leftNodes,
413
+			$operator,
414
+			$rightColumn,
415
+			$rightNodes,
416
+			'cross'
417
+		);
418
+	}
419
+
420
+
421
+
422
+	// JSON
423
+
424
+	/**
425
+	 * @param string|Raw $column The database column which holds the JSON value
426
+	 * @param string|Raw|string[] $nodes The json key/index to search
427
+	 * @param string|null $alias The alias used to define the value in results, if not defined will use json_{$nodes}
428
+	 * @return static
429
+	 */
430
+	public function selectJson($column, $nodes, ?string $alias = null): self
431
+	{
432
+		// Handle potential raw values.
433
+		if ($column instanceof Raw) {
434
+			$column = $this->adapterInstance->parseRaw($column);
435
+		}
436
+		if ($nodes instanceof Raw) {
437
+			$nodes = $this->adapterInstance->parseRaw($nodes);
438
+		}
439
+
440
+		// If deeply nested jsonKey.
441
+		if (is_array($nodes)) {
442
+			$nodes = \implode('.', $nodes);
443
+		}
444
+
445
+		// Add any possible prefixes to the key
446
+		$column = $this->addTablePrefix($column, true);
447
+
448
+		$alias = null === $alias ? "json_{$nodes}" : $alias;
449
+		return  $this->select(new Raw("JSON_UNQUOTE(JSON_EXTRACT({$column}, \"$.{$nodes}\")) as {$alias}"));
450
+	}
451 451
 }
Please login to merge, or discard this patch.
src/QueryBuilder/QueryBuilderHandler.php 2 patches
Indentation   +1494 added lines, -1494 removed lines patch added patch discarded remove patch
@@ -24,1498 +24,1498 @@
 block discarded – undo
24 24
 
25 25
 class QueryBuilderHandler implements HasConnection
26 26
 {
27
-    /**
28
-     * @method add
29
-     */
30
-    use TablePrefixer;
31
-
32
-    /**
33
-     * @var \Viocon\Container
34
-     */
35
-    protected $container;
36
-
37
-    /**
38
-     * @var Connection
39
-     */
40
-    protected $connection;
41
-
42
-    /**
43
-     * @var array<string, mixed[]|mixed>
44
-     */
45
-    protected $statements = [];
46
-
47
-    /**
48
-     * @var wpdb
49
-     */
50
-    protected $dbInstance;
51
-
52
-    /**
53
-     * @var string|string[]|null
54
-     */
55
-    protected $sqlStatement = null;
56
-
57
-    /**
58
-     * @var string|null
59
-     */
60
-    protected $tablePrefix = null;
61
-
62
-    /**
63
-     * @var WPDBAdapter
64
-     */
65
-    protected $adapterInstance;
66
-
67
-    /**
68
-     * The mode to return results as.
69
-     * Accepts WPDB constants or class names.
70
-     *
71
-     * @var string
72
-     */
73
-    protected $fetchMode;
74
-
75
-    /**
76
-     * Custom args used to construct models for hydrator
77
-     *
78
-     * @var array<int, mixed>|null
79
-     */
80
-    protected $hydratorConstructorArgs;
81
-
82
-    /**
83
-     * Handler for Json Selectors
84
-     *
85
-     * @var JsonHandler
86
-     */
87
-    protected $jsonHandler;
88
-
89
-    /**
90
-     * @param \Pixie\Connection|null $connection
91
-     * @param string $fetchMode
92
-     * @param mixed[] $hydratorConstructorArgs
93
-     *
94
-     * @throws Exception if no connection passed and not previously established
95
-     */
96
-    final public function __construct(
97
-        Connection $connection = null,
98
-        string $fetchMode = \OBJECT,
99
-        ?array $hydratorConstructorArgs = null
100
-    ) {
101
-        if (is_null($connection)) {
102
-            // throws if connection not already established.
103
-            $connection = Connection::getStoredConnection();
104
-        }
105
-
106
-        // Set all dependencies from connection.
107
-        $this->connection = $connection;
108
-        $this->container  = $this->connection->getContainer();
109
-        $this->dbInstance = $this->connection->getDbInstance();
110
-        $this->setAdapterConfig($this->connection->getAdapterConfig());
111
-
112
-        // Set up optional hydration details.
113
-        $this->setFetchMode($fetchMode);
114
-        $this->hydratorConstructorArgs = $hydratorConstructorArgs;
115
-
116
-        // Query builder adapter instance
117
-        $this->adapterInstance = $this->container->build(
118
-            WPDBAdapter::class,
119
-            [$this->connection]
120
-        );
121
-
122
-        // Setup JSON Selector handler.
123
-        $this->jsonHandler = new JsonHandler($connection);
124
-    }
125
-
126
-    /**
127
-     * Sets the config for WPDB
128
-     *
129
-     * @param array<string, mixed> $adapterConfig
130
-     *
131
-     * @return void
132
-     */
133
-    protected function setAdapterConfig(array $adapterConfig): void
134
-    {
135
-        if (isset($adapterConfig[Connection::PREFIX])) {
136
-            $this->tablePrefix = $adapterConfig[Connection::PREFIX];
137
-        }
138
-    }
139
-
140
-    /**
141
-     * Fetch query results as object of specified type
142
-     *
143
-     * @param string $className
144
-     * @param array<int, mixed> $constructorArgs
145
-     * @return static
146
-     */
147
-    public function asObject($className, $constructorArgs = array()): self
148
-    {
149
-        return $this->setFetchMode($className, $constructorArgs);
150
-    }
151
-
152
-    /**
153
-     * Set the fetch mode
154
-     *
155
-     * @param string $mode
156
-     * @param array<int, mixed>|null $constructorArgs
157
-     *
158
-     * @return static
159
-     */
160
-    public function setFetchMode(string $mode, ?array $constructorArgs = null): self
161
-    {
162
-        $this->fetchMode               = $mode;
163
-        $this->hydratorConstructorArgs = $constructorArgs;
164
-
165
-        return $this;
166
-    }
167
-
168
-    /**
169
-     * @param Connection|null $connection
170
-     *
171
-     * @return static
172
-     *
173
-     * @throws Exception
174
-     */
175
-    public function newQuery(Connection $connection = null): self
176
-    {
177
-        if (is_null($connection)) {
178
-            $connection = $this->connection;
179
-        }
180
-
181
-        $newQuery = $this->constructCurrentBuilderClass($connection);
182
-        $newQuery->setFetchMode($this->getFetchMode(), $this->hydratorConstructorArgs);
183
-
184
-        return $newQuery;
185
-    }
186
-
187
-    /**
188
-     * Returns a new instance of the current, with the passed connection.
189
-     *
190
-     * @param \Pixie\Connection $connection
191
-     *
192
-     * @return static
193
-     */
194
-    protected function constructCurrentBuilderClass(Connection $connection): self
195
-    {
196
-        return new static($connection);
197
-    }
198
-
199
-    /**
200
-     * Interpolates a query
201
-     *
202
-     * @param string $query
203
-     * @param array<mixed> $bindings
204
-     * @return string
205
-     */
206
-    public function interpolateQuery(string $query, array $bindings = []): string
207
-    {
208
-        return $this->adapterInstance->interpolateQuery($query, $bindings);
209
-    }
210
-
211
-    /**
212
-     * @param string           $sql
213
-     * @param array<int,mixed> $bindings
214
-     *
215
-     * @return static
216
-     */
217
-    public function query($sql, $bindings = []): self
218
-    {
219
-        list($this->sqlStatement) = $this->statement($sql, $bindings);
220
-
221
-        return $this;
222
-    }
223
-
224
-    /**
225
-     * @param string           $sql
226
-     * @param array<int,mixed> $bindings
227
-     *
228
-     * @return array{0:string, 1:float}
229
-     */
230
-    public function statement(string $sql, $bindings = []): array
231
-    {
232
-        $start        = microtime(true);
233
-        $sqlStatement = empty($bindings) ? $sql : $this->interpolateQuery($sql, $bindings);
234
-
235
-        if (!is_string($sqlStatement)) {
236
-            throw new Exception('Could not interpolate query', 1);
237
-        }
238
-
239
-        return [$sqlStatement, microtime(true) - $start];
240
-    }
241
-
242
-    /**
243
-     * Get all rows
244
-     *
245
-     * @return array<mixed,mixed>|null
246
-     *
247
-     * @throws Exception
248
-     */
249
-    public function get()
250
-    {
251
-        $eventResult = $this->fireEvents('before-select');
252
-        if (!is_null($eventResult)) {
253
-            return $eventResult;
254
-        }
255
-        $executionTime = 0;
256
-        if (is_null($this->sqlStatement)) {
257
-            $queryObject = $this->getQuery('select');
258
-            $statement   = $this->statement(
259
-                $queryObject->getSql(),
260
-                $queryObject->getBindings()
261
-            );
262
-
263
-            $this->sqlStatement = $statement[0];
264
-            $executionTime      = $statement[1];
265
-        }
266
-
267
-        $start  = microtime(true);
268
-        $result = $this->dbInstance()->get_results(
269
-            is_array($this->sqlStatement) ? (end($this->sqlStatement) ?: '') : $this->sqlStatement,
270
-            // If we are using the hydrator, return as OBJECT and let the hydrator map the correct model.
271
-            $this->useHydrator() ? OBJECT : $this->getFetchMode()
272
-        );
273
-        $executionTime += microtime(true) - $start;
274
-        $this->sqlStatement = null;
275
-
276
-        // Ensure we have an array of results.
277
-        if (!is_array($result) && null !== $result) {
278
-            $result = [$result];
279
-        }
280
-
281
-        // Maybe hydrate the results.
282
-        if (null !== $result && $this->useHydrator()) {
283
-            $result = $this->getHydrator()->fromMany($result);
284
-        }
285
-
286
-        $this->fireEvents('after-select', $result, $executionTime);
287
-
288
-        return $result;
289
-    }
290
-
291
-    /**
292
-     * Returns a populated instance of the Hydrator.
293
-     *
294
-     * @return Hydrator
295
-     */
296
-    protected function getHydrator(): Hydrator /* @phpstan-ignore-line */
297
-    {
298
-        $hydrator = new Hydrator($this->getFetchMode(), $this->hydratorConstructorArgs ?? []); /* @phpstan-ignore-line */
299
-
300
-        return $hydrator;
301
-    }
302
-
303
-    /**
304
-     * Checks if the results should be mapped via the hydrator
305
-     *
306
-     * @return bool
307
-     */
308
-    protected function useHydrator(): bool
309
-    {
310
-        return !in_array($this->getFetchMode(), [\ARRAY_A, \ARRAY_N, \OBJECT, \OBJECT_K]);
311
-    }
312
-
313
-    /**
314
-     * Find all matching a simple where condition.
315
-     *
316
-     * Shortcut of ->where('key','=','value')->limit(1)->get();
317
-     *
318
-     * @return \stdClass\array<mixed,mixed>|object|null Can return any object using hydrator
319
-     */
320
-    public function first()
321
-    {
322
-        $this->limit(1);
323
-        $result = $this->get();
324
-
325
-        return empty($result) ? null : $result[0];
326
-    }
327
-
328
-    /**
329
-     * Find all matching a simple where condition.
330
-     *
331
-     * Shortcut of ->where('key','=','value')->get();
332
-     *
333
-     * @param string $fieldName
334
-     * @param mixed $value
335
-     *
336
-     * @return array<mixed,mixed>|null Can return any object using hydrator
337
-     */
338
-    public function findAll($fieldName, $value)
339
-    {
340
-        $this->where($fieldName, '=', $value);
341
-
342
-        return $this->get();
343
-    }
344
-
345
-    /**
346
-     * @param string $fieldName
347
-     * @param mixed $value
348
-     *
349
-     * @return \stdClass\array<mixed,mixed>|object|null Can return any object using hydrator
350
-     */
351
-    public function find($value, $fieldName = 'id')
352
-    {
353
-        $this->where($fieldName, '=', $value);
354
-
355
-        return $this->first();
356
-    }
357
-
358
-    /**
359
-     * @param string $fieldName
360
-     * @param mixed $value
361
-     *
362
-     * @return \stdClass\array<mixed,mixed>|object Can return any object using hydrator
363
-     * @throws Exception If fails to find
364
-     */
365
-    public function findOrFail($value, $fieldName = 'id')
366
-    {
367
-        $result = $this->find($value, $fieldName);
368
-        if (null === $result) {
369
-            throw new Exception("Failed to find {$fieldName}={$value}", 1);
370
-        }
371
-        return $result;
372
-    }
373
-
374
-    /**
375
-     * Used to handle all aggregation method.
376
-     *
377
-     * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
378
-     *
379
-     * @param string $type
380
-     * @param string|Raw $field
381
-     *
382
-     * @return float
383
-     */
384
-    protected function aggregate(string $type, $field = '*'): float
385
-    {
386
-        // Parse a raw expression.
387
-        if ($field instanceof Raw) {
388
-            $field = $this->adapterInstance->parseRaw($field);
389
-        }
390
-
391
-        // Potentialy cast field from JSON
392
-        if ($this->jsonHandler->isJsonSelector($field)) {
393
-            $field = $this->jsonHandler->extractAndUnquoteFromJsonSelector($field);
394
-        }
395
-
396
-        // Verify that field exists
397
-        if ('*' !== $field && true === isset($this->statements['selects']) && false === \in_array($field, $this->statements['selects'], true)) {
398
-            throw new \Exception(sprintf('Failed %s query - the column %s hasn\'t been selected in the query.', $type, $field));
399
-        }
400
-
401
-
402
-        if (false === isset($this->statements['tables'])) {
403
-            throw new Exception('No table selected');
404
-        }
405
-
406
-        $count = $this
407
-            ->table($this->subQuery($this, 'count'))
408
-            ->select([$this->raw(sprintf('%s(%s) AS field', strtoupper($type), $field))])
409
-            ->first();
410
-
411
-        return true === isset($count->field) ? (float)$count->field : 0;
412
-    }
413
-
414
-    /**
415
-     * Get count of all the rows for the current query
416
-     *
417
-     * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
418
-     *
419
-     * @param string|Raw $field
420
-     *
421
-     * @return int
422
-     *
423
-     * @throws Exception
424
-     */
425
-    public function count($field = '*'): int
426
-    {
427
-        return (int)$this->aggregate('count', $field);
428
-    }
429
-
430
-    /**
431
-     * Get the sum for a field in the current query
432
-     *
433
-     * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
434
-     *
435
-     * @param string|Raw $field
436
-     *
437
-     * @return float
438
-     *
439
-     * @throws Exception
440
-     */
441
-    public function sum($field): float
442
-    {
443
-        return $this->aggregate('sum', $field);
444
-    }
445
-
446
-    /**
447
-     * Get the average for a field in the current query
448
-     *
449
-     * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
450
-     *
451
-     * @param string|Raw $field
452
-     *
453
-     * @return float
454
-     *
455
-     * @throws Exception
456
-     */
457
-    public function average($field): float
458
-    {
459
-        return $this->aggregate('avg', $field);
460
-    }
461
-
462
-    /**
463
-     * Get the minimum for a field in the current query
464
-     *
465
-     * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
466
-     *
467
-     * @param string|Raw $field
468
-     *
469
-     * @return float
470
-     *
471
-     * @throws Exception
472
-     */
473
-    public function min($field): float
474
-    {
475
-        return $this->aggregate('min', $field);
476
-    }
477
-
478
-    /**
479
-     * Get the maximum for a field in the current query
480
-     *
481
-     * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
482
-     *
483
-     * @param string|Raw $field
484
-     *
485
-     * @return float
486
-     *
487
-     * @throws Exception
488
-     */
489
-    public function max($field): float
490
-    {
491
-        return $this->aggregate('max', $field);
492
-    }
493
-
494
-    /**
495
-     * @param string $type
496
-     * @param bool|array<mixed, mixed> $dataToBePassed
497
-     *
498
-     * @return mixed
499
-     *
500
-     * @throws Exception
501
-     */
502
-    public function getQuery(string $type = 'select', $dataToBePassed = [])
503
-    {
504
-        $allowedTypes = ['select', 'insert', 'insertignore', 'replace', 'delete', 'update', 'criteriaonly'];
505
-        if (!in_array(strtolower($type), $allowedTypes)) {
506
-            throw new Exception($type . ' is not a known type.', 2);
507
-        }
508
-
509
-        $queryArr = $this->adapterInstance->$type($this->statements, $dataToBePassed);
510
-
511
-        return $this->container->build(
512
-            QueryObject::class,
513
-            [$queryArr['sql'], $queryArr['bindings'], $this->dbInstance]
514
-        );
515
-    }
516
-
517
-    /**
518
-     * @param QueryBuilderHandler $queryBuilder
519
-     * @param string|null $alias
520
-     *
521
-     * @return Raw
522
-     */
523
-    public function subQuery(QueryBuilderHandler $queryBuilder, ?string $alias = null)
524
-    {
525
-        $sql = '(' . $queryBuilder->getQuery()->getRawSql() . ')';
526
-        if (is_string($alias) && 0 !== mb_strlen($alias)) {
527
-            $sql = $sql . ' as ' . $alias;
528
-        }
529
-
530
-        return $queryBuilder->raw($sql);
531
-    }
532
-
533
-    /**
534
-     * Handles the various insert operations based on the type.
535
-     *
536
-     * @param array<int|string, mixed|mixed[]> $data
537
-     * @param string $type
538
-     *
539
-     * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
540
-     */
541
-    private function doInsert(array $data, string $type)
542
-    {
543
-        $eventResult = $this->fireEvents('before-insert');
544
-        if (!is_null($eventResult)) {
545
-            return $eventResult;
546
-        }
547
-
548
-        // If first value is not an array () not a batch insert)
549
-        if (!is_array(current($data))) {
550
-            $queryObject = $this->getQuery($type, $data);
551
-
552
-            list($preparedQuery, $executionTime) = $this->statement($queryObject->getSql(), $queryObject->getBindings());
553
-            $this->dbInstance->get_results($preparedQuery);
554
-
555
-            // Check we have a result.
556
-            $return = 1 === $this->dbInstance->rows_affected ? $this->dbInstance->insert_id : null;
557
-        } else {
558
-            // Its a batch insert
559
-            $return        = [];
560
-            $executionTime = 0;
561
-            foreach ($data as $subData) {
562
-                $queryObject = $this->getQuery($type, $subData);
563
-
564
-                list($preparedQuery, $time) = $this->statement($queryObject->getSql(), $queryObject->getBindings());
565
-                $this->dbInstance->get_results($preparedQuery);
566
-                $executionTime += $time;
567
-
568
-                if (1 === $this->dbInstance->rows_affected) {
569
-                    $return[] = $this->dbInstance->insert_id;
570
-                }
571
-            }
572
-        }
573
-
574
-        $this->fireEvents('after-insert', $return, $executionTime);
575
-
576
-        return $return;
577
-    }
578
-
579
-    /**
580
-     * @param array<int|string, mixed|mixed[]> $data either key=>value array for single or array of arrays for bulk
581
-     *
582
-     * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
583
-     */
584
-    public function insert($data)
585
-    {
586
-        return $this->doInsert($data, 'insert');
587
-    }
588
-
589
-    /**
590
-     *
591
-     * @param array<int|string, mixed|mixed[]> $data either key=>value array for single or array of arrays for bulk
592
-     *
593
-     * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
594
-     */
595
-    public function insertIgnore($data)
596
-    {
597
-        return $this->doInsert($data, 'insertignore');
598
-    }
599
-
600
-    /**
601
-     *
602
-     * @param array<int|string, mixed|mixed[]> $data either key=>value array for single or array of arrays for bulk
603
-     *
604
-     * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
605
-     */
606
-    public function replace($data)
607
-    {
608
-        return $this->doInsert($data, 'replace');
609
-    }
610
-
611
-    /**
612
-     * @param array<string, mixed> $data
613
-     *
614
-     * @return int|null
615
-     */
616
-    public function update($data)
617
-    {
618
-        $eventResult = $this->fireEvents('before-update');
619
-        if (!is_null($eventResult)) {
620
-            return $eventResult;
621
-        }
622
-        $queryObject                         = $this->getQuery('update', $data);
623
-        $r = $this->statement($queryObject->getSql(), $queryObject->getBindings());
624
-        list($preparedQuery, $executionTime) = $r;
625
-        $this->dbInstance()->get_results($preparedQuery);
626
-        $this->fireEvents('after-update', $queryObject, $executionTime);
627
-
628
-        return 0 !== $this->dbInstance()->rows_affected
629
-            ? $this->dbInstance()->rows_affected
630
-            : null;
631
-    }
632
-
633
-    /**
634
-     * @param array<string, mixed> $data
635
-     *
636
-     * @return int|null will return row id for insert and bool for success/fail on update
637
-     */
638
-    public function updateOrInsert($data)
639
-    {
640
-        if ($this->first()) {
641
-            return $this->update($data);
642
-        }
643
-
644
-        return $this->insert($data);
645
-    }
646
-
647
-    /**
648
-     * @param array<string, mixed> $data
649
-     *
650
-     * @return static
651
-     */
652
-    public function onDuplicateKeyUpdate($data)
653
-    {
654
-        $this->addStatement('onduplicate', $data);
655
-
656
-        return $this;
657
-    }
658
-
659
-    /**
660
-     * @return mixed number of rows effected or shortcircuited response
661
-     */
662
-    public function delete()
663
-    {
664
-        $eventResult = $this->fireEvents('before-delete');
665
-        if (!is_null($eventResult)) {
666
-            return $eventResult;
667
-        }
668
-
669
-        $queryObject = $this->getQuery('delete');
670
-
671
-        list($preparedQuery, $executionTime) = $this->statement($queryObject->getSql(), $queryObject->getBindings());
672
-        $this->dbInstance()->get_results($preparedQuery);
673
-        $this->fireEvents('after-delete', $queryObject, $executionTime);
674
-
675
-        return $this->dbInstance()->rows_affected;
676
-    }
677
-
678
-    /**
679
-     * @param string|Raw ...$tables Single table or array of tables
680
-     *
681
-     * @return static
682
-     *
683
-     * @throws Exception
684
-     */
685
-    public function table(...$tables)
686
-    {
687
-        $instance =  $this->constructCurrentBuilderClass($this->connection);
688
-        $this->setFetchMode($this->getFetchMode(), $this->hydratorConstructorArgs);
689
-        $tables = $this->addTablePrefix($tables, false);
690
-        $instance->addStatement('tables', $tables);
691
-
692
-        return $instance;
693
-    }
694
-
695
-    /**
696
-     * @param string|Raw ...$tables Single table or array of tables
697
-     *
698
-     * @return static
699
-     */
700
-    public function from(...$tables): self
701
-    {
702
-        $tables = $this->addTablePrefix($tables, false);
703
-        $this->addStatement('tables', $tables);
704
-
705
-        return $this;
706
-    }
707
-
708
-    /**
709
-     * @param string|string[]|Raw[]|array<string, string> $fields
710
-     *
711
-     * @return static
712
-     */
713
-    public function select($fields): self
714
-    {
715
-        if (!is_array($fields)) {
716
-            $fields = func_get_args();
717
-        }
718
-
719
-        foreach ($fields as $field => $alias) {
720
-            // If we have a JSON expression
721
-            if ($this->jsonHandler->isJsonSelector($field)) {
722
-                $field = $this->jsonHandler->extractAndUnquoteFromJsonSelector($field);
723
-            }
724
-
725
-            // If no alias passed, but field is for JSON. thrown an exception.
726
-            if (is_numeric($field) && is_string($alias) && $this->jsonHandler->isJsonSelector($alias)) {
727
-                throw new Exception("An alias must be used if you wish to select from JSON Object", 1);
728
-            }
729
-
730
-            // Treat each array as a single table, to retain order added
731
-            $field = is_numeric($field)
732
-                ? $field = $alias // If single colum
733
-                : $field = [$field => $alias]; // Has alias
734
-
735
-            $field = $this->addTablePrefix($field);
736
-            $this->addStatement('selects', $field);
737
-        }
738
-
739
-        return $this;
740
-    }
741
-
742
-    /**
743
-     * @param string|string[]|Raw[]|array<string, string> $fields
744
-     *
745
-     * @return static
746
-     */
747
-    public function selectDistinct($fields)
748
-    {
749
-        $this->select($fields);
750
-        $this->addStatement('distinct', true);
751
-
752
-        return $this;
753
-    }
754
-
755
-    /**
756
-     * @param string|string[] $field either the single field or an array of fields
757
-     *
758
-     * @return static
759
-     */
760
-    public function groupBy($field): self
761
-    {
762
-        $field = $this->addTablePrefix($field);
763
-        $this->addStatement('groupBys', $field);
764
-
765
-        return $this;
766
-    }
767
-
768
-    /**
769
-     * @param string|array<string|int, mixed> $fields
770
-     * @param string          $defaultDirection
771
-     *
772
-     * @return static
773
-     */
774
-    public function orderBy($fields, string $defaultDirection = 'ASC'): self
775
-    {
776
-        if (!is_array($fields)) {
777
-            $fields = [$fields];
778
-        }
779
-
780
-        foreach ($fields as $key => $value) {
781
-            $field = $key;
782
-            $type  = $value;
783
-            if (is_int($key)) {
784
-                $field = $value;
785
-                $type  = $defaultDirection;
786
-            }
787
-
788
-            if ($this->jsonHandler->isJsonSelector($field)) {
789
-                $field = $this->jsonHandler->extractAndUnquoteFromJsonSelector($field);
790
-            }
791
-
792
-            if (!$field instanceof Raw) {
793
-                $field = $this->addTablePrefix($field);
794
-            }
795
-            $this->statements['orderBys'][] = compact('field', 'type');
796
-        }
797
-
798
-        return $this;
799
-    }
800
-
801
-    /**
802
-     * @param string|Raw $key The database column which holds the JSON value
803
-     * @param string|Raw|string[] $jsonKey The json key/index to search
804
-     * @param string $defaultDirection
805
-     * @return static
806
-     */
807
-    public function orderByJson($key, $jsonKey, string $defaultDirection = 'ASC'): self
808
-    {
809
-        $key = $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($key, $jsonKey);
810
-        return $this->orderBy($key, $defaultDirection);
811
-    }
812
-
813
-    /**
814
-     * @param int $limit
815
-     *
816
-     * @return static
817
-     */
818
-    public function limit(int $limit): self
819
-    {
820
-        $this->statements['limit'] = $limit;
821
-
822
-        return $this;
823
-    }
824
-
825
-    /**
826
-     * @param int $offset
827
-     *
828
-     * @return static
829
-     */
830
-    public function offset(int $offset): self
831
-    {
832
-        $this->statements['offset'] = $offset;
833
-
834
-        return $this;
835
-    }
836
-
837
-    /**
838
-     * @param string|string[]|Raw|Raw[]       $key
839
-     * @param string $operator
840
-     * @param mixed $value
841
-     * @param string $joiner
842
-     *
843
-     * @return static
844
-     */
845
-    public function having($key, string $operator, $value, string $joiner = 'AND')
846
-    {
847
-        $key                           = $this->addTablePrefix($key);
848
-        $this->statements['havings'][] = compact('key', 'operator', 'value', 'joiner');
849
-
850
-        return $this;
851
-    }
852
-
853
-    /**
854
-     * @param string|string[]|Raw|Raw[]       $key
855
-     * @param string $operator
856
-     * @param mixed $value
857
-     *
858
-     * @return static
859
-     */
860
-    public function orHaving($key, $operator, $value)
861
-    {
862
-        return $this->having($key, $operator, $value, 'OR');
863
-    }
864
-
865
-    /**
866
-     * @param string|Raw $key
867
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
868
-     * @param mixed|null $value
869
-     *
870
-     * @return static
871
-     */
872
-    public function where($key, $operator = null, $value = null): self
873
-    {
874
-        // If two params are given then assume operator is =
875
-        if (2 === func_num_args()) {
876
-            $value    = $operator;
877
-            $operator = '=';
878
-        }
879
-
880
-        return $this->whereHandler($key, $operator, $value);
881
-    }
882
-
883
-    /**
884
-     * @param string|Raw|\Closure(QueryBuilderHandler):void $key
885
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
886
-     * @param mixed|null $value
887
-     *
888
-     * @return static
889
-     */
890
-    public function orWhere($key, $operator = null, $value = null): self
891
-    {
892
-        // If two params are given then assume operator is =
893
-        if (2 === func_num_args()) {
894
-            $value    = $operator;
895
-            $operator = '=';
896
-        }
897
-
898
-        return $this->whereHandler($key, $operator, $value, 'OR');
899
-    }
900
-
901
-    /**
902
-     * @param string|Raw $key
903
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
904
-     * @param mixed|null $value
905
-     *
906
-     * @return static
907
-     */
908
-    public function whereNot($key, $operator = null, $value = null): self
909
-    {
910
-        // If two params are given then assume operator is =
911
-        if (2 === func_num_args()) {
912
-            $value    = $operator;
913
-            $operator = '=';
914
-        }
915
-
916
-        return $this->whereHandler($key, $operator, $value, 'AND NOT');
917
-    }
918
-
919
-    /**
920
-     * @param string|Raw $key
921
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
922
-     * @param mixed|null $value
923
-     *
924
-     * @return static
925
-     */
926
-    public function orWhereNot($key, $operator = null, $value = null)
927
-    {
928
-        // If two params are given then assume operator is =
929
-        if (2 === func_num_args()) {
930
-            $value    = $operator;
931
-            $operator = '=';
932
-        }
933
-
934
-        return $this->whereHandler($key, $operator, $value, 'OR NOT');
935
-    }
936
-
937
-    /**
938
-     * @param string|Raw $key
939
-     * @param mixed[]|string|Raw $values
940
-     *
941
-     * @return static
942
-     */
943
-    public function whereIn($key, $values): self
944
-    {
945
-        return $this->whereHandler($key, 'IN', $values, 'AND');
946
-    }
947
-
948
-    /**
949
-     * @param string|Raw $key
950
-     * @param mixed[]|string|Raw $values
951
-     *
952
-     * @return static
953
-     */
954
-    public function whereNotIn($key, $values): self
955
-    {
956
-        return $this->whereHandler($key, 'NOT IN', $values, 'AND');
957
-    }
958
-
959
-    /**
960
-     * @param string|Raw $key
961
-     * @param mixed[]|string|Raw $values
962
-     *
963
-     * @return static
964
-     */
965
-    public function orWhereIn($key, $values): self
966
-    {
967
-        return $this->whereHandler($key, 'IN', $values, 'OR');
968
-    }
969
-
970
-    /**
971
-     * @param string|Raw $key
972
-     * @param mixed[]|string|Raw $values
973
-     *
974
-     * @return static
975
-     */
976
-    public function orWhereNotIn($key, $values): self
977
-    {
978
-        return $this->whereHandler($key, 'NOT IN', $values, 'OR');
979
-    }
980
-
981
-    /**
982
-     * @param string|Raw $key
983
-     * @param mixed $valueFrom
984
-     * @param mixed $valueTo
985
-     *
986
-     * @return static
987
-     */
988
-    public function whereBetween($key, $valueFrom, $valueTo): self
989
-    {
990
-        return $this->whereHandler($key, 'BETWEEN', [$valueFrom, $valueTo], 'AND');
991
-    }
992
-
993
-    /**
994
-     * @param string|Raw $key
995
-     * @param mixed $valueFrom
996
-     * @param mixed $valueTo
997
-     *
998
-     * @return static
999
-     */
1000
-    public function orWhereBetween($key, $valueFrom, $valueTo): self
1001
-    {
1002
-        return $this->whereHandler($key, 'BETWEEN', [$valueFrom, $valueTo], 'OR');
1003
-    }
1004
-
1005
-    /**
1006
-     * Handles all function call based where conditions
1007
-     *
1008
-     * @param string|Raw $key
1009
-     * @param string $function
1010
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1011
-     * @param mixed|null $value
1012
-     * @return static
1013
-     */
1014
-    protected function whereFunctionCallHandler($key, $function, $operator, $value): self
1015
-    {
1016
-        $key = \sprintf('%s(%s)', $function, $this->addTablePrefix($key));
1017
-        return $this->where($key, $operator, $value);
1018
-    }
1019
-
1020
-    /**
1021
-     * @param string|Raw $key
1022
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1023
-     * @param mixed|null $value
1024
-     * @return self
1025
-     */
1026
-    public function whereMonth($key, $operator = null, $value = null): self
1027
-    {
1028
-        // If two params are given then assume operator is =
1029
-        if (2 === func_num_args()) {
1030
-            $value    = $operator;
1031
-            $operator = '=';
1032
-        }
1033
-        return $this->whereFunctionCallHandler($key, 'MONTH', $operator, $value);
1034
-    }
1035
-
1036
-    /**
1037
-     * @param string|Raw $key
1038
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1039
-     * @param mixed|null $value
1040
-     * @return self
1041
-     */
1042
-    public function whereDay($key, $operator = null, $value = null): self
1043
-    {
1044
-        // If two params are given then assume operator is =
1045
-        if (2 === func_num_args()) {
1046
-            $value    = $operator;
1047
-            $operator = '=';
1048
-        }
1049
-        return $this->whereFunctionCallHandler($key, 'DAY', $operator, $value);
1050
-    }
1051
-
1052
-    /**
1053
-     * @param string|Raw $key
1054
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1055
-     * @param mixed|null $value
1056
-     * @return self
1057
-     */
1058
-    public function whereYear($key, $operator = null, $value = null): self
1059
-    {
1060
-        // If two params are given then assume operator is =
1061
-        if (2 === func_num_args()) {
1062
-            $value    = $operator;
1063
-            $operator = '=';
1064
-        }
1065
-        return $this->whereFunctionCallHandler($key, 'YEAR', $operator, $value);
1066
-    }
1067
-
1068
-    /**
1069
-     * @param string|Raw $key
1070
-     * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1071
-     * @param mixed|null $value
1072
-     * @return self
1073
-     */
1074
-    public function whereDate($key, $operator = null, $value = null): self
1075
-    {
1076
-        // If two params are given then assume operator is =
1077
-        if (2 === func_num_args()) {
1078
-            $value    = $operator;
1079
-            $operator = '=';
1080
-        }
1081
-        return $this->whereFunctionCallHandler($key, 'DATE', $operator, $value);
1082
-    }
1083
-
1084
-    /**
1085
-     * @param string|Raw $key
1086
-     *
1087
-     * @return static
1088
-     */
1089
-    public function whereNull($key): self
1090
-    {
1091
-        return $this->whereNullHandler($key);
1092
-    }
1093
-
1094
-    /**
1095
-     * @param string|Raw $key
1096
-     *
1097
-     * @return static
1098
-     */
1099
-    public function whereNotNull($key): self
1100
-    {
1101
-        return $this->whereNullHandler($key, 'NOT');
1102
-    }
1103
-
1104
-    /**
1105
-     * @param string|Raw $key
1106
-     *
1107
-     * @return static
1108
-     */
1109
-    public function orWhereNull($key): self
1110
-    {
1111
-        return $this->whereNullHandler($key, '', 'or');
1112
-    }
1113
-
1114
-    /**
1115
-     * @param string|Raw $key
1116
-     *
1117
-     * @return static
1118
-     */
1119
-    public function orWhereNotNull($key): self
1120
-    {
1121
-        return $this->whereNullHandler($key, 'NOT', 'or');
1122
-    }
1123
-
1124
-    /**
1125
-     * @param string|Raw $key
1126
-     * @param string $prefix
1127
-     * @param string $operator
1128
-     *
1129
-     * @return static
1130
-     */
1131
-    protected function whereNullHandler($key, string $prefix = '', $operator = ''): self
1132
-    {
1133
-        $prefix = 0 === mb_strlen($prefix) ? '' : " {$prefix}";
1134
-
1135
-        if ($key instanceof Raw) {
1136
-            $key = $this->adapterInstance->parseRaw($key);
1137
-        }
1138
-
1139
-        $key = $this->addTablePrefix($key);
1140
-        if ($key instanceof Closure) {
1141
-            throw new Exception('Key used for whereNull condition must be a string or raw exrpession.', 1);
1142
-        }
1143
-
1144
-        return $this->{$operator . 'Where'}($this->raw("{$key} IS{$prefix} NULL"));
1145
-    }
1146
-
1147
-
1148
-    /**
1149
-     * Runs a transaction
1150
-     *
1151
-     * @param \Closure(Transaction):void $callback
1152
-     *
1153
-     * @return static
1154
-     */
1155
-    public function transaction(Closure $callback): self
1156
-    {
1157
-        try {
1158
-            // Begin the transaction
1159
-            $this->dbInstance->query('START TRANSACTION');
1160
-
1161
-            // Get the Transaction class
1162
-            $transaction = $this->container->build(Transaction::class, [$this->connection]);
1163
-
1164
-            $this->handleTransactionCall($callback, $transaction);
1165
-
1166
-            // If no errors have been thrown or the transaction wasn't completed within
1167
-            $this->dbInstance->query('COMMIT');
1168
-
1169
-            return $this;
1170
-        } catch (TransactionHaltException $e) {
1171
-            // Commit or rollback behavior has been handled in the closure, so exit
1172
-            return $this;
1173
-        } catch (\Exception $e) {
1174
-            // something happened, rollback changes
1175
-            $this->dbInstance->query('ROLLBACK');
1176
-
1177
-            return $this;
1178
-        }
1179
-    }
1180
-
1181
-    /**
1182
-     * Handles the transaction call.
1183
-     * Catches any WPDB Errors (printed)
1184
-     *
1185
-     * @param Closure    $callback
1186
-     * @param Transaction $transaction
1187
-     *
1188
-     * @return void
1189
-     * @throws Exception
1190
-     */
1191
-    protected function handleTransactionCall(Closure $callback, Transaction $transaction): void
1192
-    {
1193
-        try {
1194
-            ob_start();
1195
-            $callback($transaction);
1196
-            $output = ob_get_clean() ?: '';
1197
-        } catch (Throwable $th) {
1198
-            ob_end_clean();
1199
-            throw $th;
1200
-        }
1201
-
1202
-        // If we caught an error, throw an exception.
1203
-        if (0 !== mb_strlen($output)) {
1204
-            throw new Exception($output);
1205
-        }
1206
-    }
1207
-
1208
-    /*************************************************************************/
1209
-    /*************************************************************************/
1210
-    /*************************************************************************/
1211
-    /**                              JOIN JOIN                              **/
1212
-    /**                                 JOIN                                **/
1213
-    /**                              JOIN JOIN                              **/
1214
-    /*************************************************************************/
1215
-    /*************************************************************************/
1216
-    /*************************************************************************/
1217
-
1218
-    /**
1219
-     * @param string|Raw $table
1220
-     * @param string|Raw|Closure $key
1221
-     * @param string|null $operator
1222
-     * @param mixed $value
1223
-     * @param string $type
1224
-     *
1225
-     * @return static
1226
-     */
1227
-    public function join($table, $key, ?string $operator = null, $value = null, $type = 'inner')
1228
-    {
1229
-        // Potentially cast key from JSON
1230
-        if ($this->jsonHandler->isJsonSelector($key)) {
1231
-            /** @var string $key */
1232
-            $key = $this->jsonHandler->extractAndUnquoteFromJsonSelector($key); /** @phpstan-ignore-line */
1233
-        }
1234
-
1235
-        // Potentially cast value from json
1236
-        if ($this->jsonHandler->isJsonSelector($value)) {
1237
-            /** @var string $value */
1238
-            $value = $this->jsonHandler->extractAndUnquoteFromJsonSelector($value);
1239
-        }
1240
-
1241
-        if (!$key instanceof Closure) {
1242
-            $key = function ($joinBuilder) use ($key, $operator, $value) {
1243
-                $joinBuilder->on($key, $operator, $value);
1244
-            };
1245
-        }
1246
-
1247
-        // Build a new JoinBuilder class, keep it by reference so any changes made
1248
-        // in the closure should reflect here
1249
-        $joinBuilder = $this->container->build(JoinBuilder::class, [$this->connection]);
1250
-        $joinBuilder = &$joinBuilder;
1251
-        // Call the closure with our new joinBuilder object
1252
-        $key($joinBuilder);
1253
-        $table = $this->addTablePrefix($table, false);
1254
-        // Get the criteria only query from the joinBuilder object
1255
-        $this->statements['joins'][] = compact('type', 'table', 'joinBuilder');
1256
-        return $this;
1257
-    }
1258
-
1259
-    /**
1260
-     * @param string|Raw $table
1261
-     * @param string|Raw|Closure $key
1262
-     * @param string|null $operator
1263
-     * @param mixed $value
1264
-     *
1265
-     * @return static
1266
-     */
1267
-    public function leftJoin($table, $key, $operator = null, $value = null)
1268
-    {
1269
-        return $this->join($table, $key, $operator, $value, 'left');
1270
-    }
1271
-
1272
-    /**
1273
-     * @param string|Raw $table
1274
-     * @param string|Raw|Closure $key
1275
-     * @param string|null $operator
1276
-     * @param mixed $value
1277
-     *
1278
-     * @return static
1279
-     */
1280
-    public function rightJoin($table, $key, $operator = null, $value = null)
1281
-    {
1282
-        return $this->join($table, $key, $operator, $value, 'right');
1283
-    }
1284
-
1285
-    /**
1286
-     * @param string|Raw $table
1287
-     * @param string|Raw|Closure $key
1288
-     * @param string|null $operator
1289
-     * @param mixed $value
1290
-     *
1291
-     * @return static
1292
-     */
1293
-    public function innerJoin($table, $key, $operator = null, $value = null)
1294
-    {
1295
-        return $this->join($table, $key, $operator, $value, 'inner');
1296
-    }
1297
-
1298
-    /**
1299
-     * @param string|Raw $table
1300
-     * @param string|Raw|Closure $key
1301
-     * @param string|null $operator
1302
-     * @param mixed $value
1303
-     *
1304
-     * @return static
1305
-     */
1306
-    public function crossJoin($table, $key, $operator = null, $value = null)
1307
-    {
1308
-        return $this->join($table, $key, $operator, $value, 'cross');
1309
-    }
1310
-
1311
-    /**
1312
-     * @param string|Raw $table
1313
-     * @param string|Raw|Closure $key
1314
-     * @param string|null $operator
1315
-     * @param mixed $value
1316
-     *
1317
-     * @return static
1318
-     */
1319
-    public function outerJoin($table, $key, $operator = null, $value = null)
1320
-    {
1321
-        return $this->join($table, $key, $operator, $value, 'full outer');
1322
-    }
1323
-
1324
-    /**
1325
-     * Shortcut to join 2 tables on the same key name with equals
1326
-     *
1327
-     * @param string $table
1328
-     * @param string $key
1329
-     * @param string $type
1330
-     * @return self
1331
-     * @throws Exception If base table is set as more than 1 or 0
1332
-     */
1333
-    public function joinUsing(string $table, string $key, string $type = 'INNER'): self
1334
-    {
1335
-        if (!array_key_exists('tables', $this->statements) || count($this->statements['tables']) !== 1) {
1336
-            throw new Exception("JoinUsing can only be used with a single table set as the base of the query", 1);
1337
-        }
1338
-        $baseTable = end($this->statements['tables']);
1339
-
1340
-        // Potentialy cast key from JSON
1341
-        if ($this->jsonHandler->isJsonSelector($key)) {
1342
-            $key = $this->jsonHandler->extractAndUnquoteFromJsonSelector($key);
1343
-        }
1344
-
1345
-        $remoteKey = $table = $this->addTablePrefix("{$table}.{$key}", true);
1346
-        $localKey = $table = $this->addTablePrefix("{$baseTable}.{$key}", true);
1347
-        return $this->join($table, $remoteKey, '=', $localKey, $type);
1348
-    }
1349
-
1350
-    /**
1351
-     * Add a raw query
1352
-     *
1353
-     * @param string|Raw $value
1354
-     * @param mixed|mixed[] $bindings
1355
-     *
1356
-     * @return Raw
1357
-     */
1358
-    public function raw($value, $bindings = []): Raw
1359
-    {
1360
-        return new Raw($value, $bindings);
1361
-    }
1362
-
1363
-    /**
1364
-     * Return wpdb instance
1365
-     *
1366
-     * @return wpdb
1367
-     */
1368
-    public function dbInstance(): wpdb
1369
-    {
1370
-        return $this->dbInstance;
1371
-    }
1372
-
1373
-    /**
1374
-     * @param Connection $connection
1375
-     *
1376
-     * @return static
1377
-     */
1378
-    public function setConnection(Connection $connection): self
1379
-    {
1380
-        $this->connection = $connection;
1381
-
1382
-        return $this;
1383
-    }
1384
-
1385
-    /**
1386
-     * @return Connection
1387
-     */
1388
-    public function getConnection(): Connection
1389
-    {
1390
-        return $this->connection;
1391
-    }
1392
-
1393
-    /**
1394
-     * @param string|Raw|Closure $key
1395
-     * @param string|null      $operator
1396
-     * @param mixed|null       $value
1397
-     * @param string $joiner
1398
-     *
1399
-     * @return static
1400
-     */
1401
-    protected function whereHandler($key, $operator = null, $value = null, $joiner = 'AND')
1402
-    {
1403
-        $key = $this->addTablePrefix($key);
1404
-        if ($key instanceof Raw) {
1405
-            $key = $this->adapterInstance->parseRaw($key);
1406
-        }
1407
-
1408
-        if ($this->jsonHandler->isJsonSelector($key)) {
1409
-            $key = $this->jsonHandler->extractAndUnquoteFromJsonSelector($key);
1410
-        }
1411
-
1412
-        $this->statements['wheres'][] = compact('key', 'operator', 'value', 'joiner');
1413
-        return $this;
1414
-    }
1415
-
1416
-
1417
-
1418
-    /**
1419
-     * @param string $key
1420
-     * @param mixed|mixed[]|bool $value
1421
-     *
1422
-     * @return void
1423
-     */
1424
-    protected function addStatement($key, $value)
1425
-    {
1426
-        if (!is_array($value)) {
1427
-            $value = [$value];
1428
-        }
1429
-
1430
-        if (!array_key_exists($key, $this->statements)) {
1431
-            $this->statements[$key] = $value;
1432
-        } else {
1433
-            $this->statements[$key] = array_merge($this->statements[$key], $value);
1434
-        }
1435
-    }
1436
-
1437
-    /**
1438
-     * @param string $event
1439
-     * @param string|Raw $table
1440
-     *
1441
-     * @return callable|null
1442
-     */
1443
-    public function getEvent(string $event, $table = ':any'): ?callable
1444
-    {
1445
-        return $this->connection->getEventHandler()->getEvent($event, $table);
1446
-    }
1447
-
1448
-    /**
1449
-     * @param string $event
1450
-     * @param string|Raw $table
1451
-     * @param Closure $action
1452
-     *
1453
-     * @return void
1454
-     */
1455
-    public function registerEvent($event, $table, Closure $action): void
1456
-    {
1457
-        $table = $table ?: ':any';
1458
-
1459
-        if (':any' != $table) {
1460
-            $table = $this->addTablePrefix($table, false);
1461
-        }
1462
-
1463
-        $this->connection->getEventHandler()->registerEvent($event, $table, $action);
1464
-    }
1465
-
1466
-    /**
1467
-     * @param string $event
1468
-     * @param string|Raw $table
1469
-     *
1470
-     * @return void
1471
-     */
1472
-    public function removeEvent(string $event, $table = ':any')
1473
-    {
1474
-        if (':any' != $table) {
1475
-            $table = $this->addTablePrefix($table, false);
1476
-        }
1477
-
1478
-        $this->connection->getEventHandler()->removeEvent($event, $table);
1479
-    }
1480
-
1481
-    /**
1482
-     * @param string $event
1483
-     *
1484
-     * @return mixed
1485
-     */
1486
-    public function fireEvents(string $event)
1487
-    {
1488
-        $params = func_get_args(); // @todo Replace this with an easier to read alteratnive
1489
-        array_unshift($params, $this);
1490
-
1491
-        return call_user_func_array([$this->connection->getEventHandler(), 'fireEvents'], $params);
1492
-    }
1493
-
1494
-    /**
1495
-     * @return array<string, mixed[]>
1496
-     */
1497
-    public function getStatements()
1498
-    {
1499
-        return $this->statements;
1500
-    }
1501
-
1502
-    /**
1503
-     * @return string will return WPDB Fetch mode
1504
-     */
1505
-    public function getFetchMode()
1506
-    {
1507
-        return null !== $this->fetchMode
1508
-            ? $this->fetchMode
1509
-            : \OBJECT;
1510
-    }
1511
-
1512
-    /**
1513
-     * Returns an NEW instance of the JSON builder populated with the same connection and hydrator details.
1514
-     *
1515
-     * @return JsonQueryBuilder
1516
-     */
1517
-    public function jsonBuilder(): JsonQueryBuilder
1518
-    {
1519
-        return new JsonQueryBuilder($this->getConnection(), $this->getFetchMode(), $this->hydratorConstructorArgs);
1520
-    }
27
+	/**
28
+	 * @method add
29
+	 */
30
+	use TablePrefixer;
31
+
32
+	/**
33
+	 * @var \Viocon\Container
34
+	 */
35
+	protected $container;
36
+
37
+	/**
38
+	 * @var Connection
39
+	 */
40
+	protected $connection;
41
+
42
+	/**
43
+	 * @var array<string, mixed[]|mixed>
44
+	 */
45
+	protected $statements = [];
46
+
47
+	/**
48
+	 * @var wpdb
49
+	 */
50
+	protected $dbInstance;
51
+
52
+	/**
53
+	 * @var string|string[]|null
54
+	 */
55
+	protected $sqlStatement = null;
56
+
57
+	/**
58
+	 * @var string|null
59
+	 */
60
+	protected $tablePrefix = null;
61
+
62
+	/**
63
+	 * @var WPDBAdapter
64
+	 */
65
+	protected $adapterInstance;
66
+
67
+	/**
68
+	 * The mode to return results as.
69
+	 * Accepts WPDB constants or class names.
70
+	 *
71
+	 * @var string
72
+	 */
73
+	protected $fetchMode;
74
+
75
+	/**
76
+	 * Custom args used to construct models for hydrator
77
+	 *
78
+	 * @var array<int, mixed>|null
79
+	 */
80
+	protected $hydratorConstructorArgs;
81
+
82
+	/**
83
+	 * Handler for Json Selectors
84
+	 *
85
+	 * @var JsonHandler
86
+	 */
87
+	protected $jsonHandler;
88
+
89
+	/**
90
+	 * @param \Pixie\Connection|null $connection
91
+	 * @param string $fetchMode
92
+	 * @param mixed[] $hydratorConstructorArgs
93
+	 *
94
+	 * @throws Exception if no connection passed and not previously established
95
+	 */
96
+	final public function __construct(
97
+		Connection $connection = null,
98
+		string $fetchMode = \OBJECT,
99
+		?array $hydratorConstructorArgs = null
100
+	) {
101
+		if (is_null($connection)) {
102
+			// throws if connection not already established.
103
+			$connection = Connection::getStoredConnection();
104
+		}
105
+
106
+		// Set all dependencies from connection.
107
+		$this->connection = $connection;
108
+		$this->container  = $this->connection->getContainer();
109
+		$this->dbInstance = $this->connection->getDbInstance();
110
+		$this->setAdapterConfig($this->connection->getAdapterConfig());
111
+
112
+		// Set up optional hydration details.
113
+		$this->setFetchMode($fetchMode);
114
+		$this->hydratorConstructorArgs = $hydratorConstructorArgs;
115
+
116
+		// Query builder adapter instance
117
+		$this->adapterInstance = $this->container->build(
118
+			WPDBAdapter::class,
119
+			[$this->connection]
120
+		);
121
+
122
+		// Setup JSON Selector handler.
123
+		$this->jsonHandler = new JsonHandler($connection);
124
+	}
125
+
126
+	/**
127
+	 * Sets the config for WPDB
128
+	 *
129
+	 * @param array<string, mixed> $adapterConfig
130
+	 *
131
+	 * @return void
132
+	 */
133
+	protected function setAdapterConfig(array $adapterConfig): void
134
+	{
135
+		if (isset($adapterConfig[Connection::PREFIX])) {
136
+			$this->tablePrefix = $adapterConfig[Connection::PREFIX];
137
+		}
138
+	}
139
+
140
+	/**
141
+	 * Fetch query results as object of specified type
142
+	 *
143
+	 * @param string $className
144
+	 * @param array<int, mixed> $constructorArgs
145
+	 * @return static
146
+	 */
147
+	public function asObject($className, $constructorArgs = array()): self
148
+	{
149
+		return $this->setFetchMode($className, $constructorArgs);
150
+	}
151
+
152
+	/**
153
+	 * Set the fetch mode
154
+	 *
155
+	 * @param string $mode
156
+	 * @param array<int, mixed>|null $constructorArgs
157
+	 *
158
+	 * @return static
159
+	 */
160
+	public function setFetchMode(string $mode, ?array $constructorArgs = null): self
161
+	{
162
+		$this->fetchMode               = $mode;
163
+		$this->hydratorConstructorArgs = $constructorArgs;
164
+
165
+		return $this;
166
+	}
167
+
168
+	/**
169
+	 * @param Connection|null $connection
170
+	 *
171
+	 * @return static
172
+	 *
173
+	 * @throws Exception
174
+	 */
175
+	public function newQuery(Connection $connection = null): self
176
+	{
177
+		if (is_null($connection)) {
178
+			$connection = $this->connection;
179
+		}
180
+
181
+		$newQuery = $this->constructCurrentBuilderClass($connection);
182
+		$newQuery->setFetchMode($this->getFetchMode(), $this->hydratorConstructorArgs);
183
+
184
+		return $newQuery;
185
+	}
186
+
187
+	/**
188
+	 * Returns a new instance of the current, with the passed connection.
189
+	 *
190
+	 * @param \Pixie\Connection $connection
191
+	 *
192
+	 * @return static
193
+	 */
194
+	protected function constructCurrentBuilderClass(Connection $connection): self
195
+	{
196
+		return new static($connection);
197
+	}
198
+
199
+	/**
200
+	 * Interpolates a query
201
+	 *
202
+	 * @param string $query
203
+	 * @param array<mixed> $bindings
204
+	 * @return string
205
+	 */
206
+	public function interpolateQuery(string $query, array $bindings = []): string
207
+	{
208
+		return $this->adapterInstance->interpolateQuery($query, $bindings);
209
+	}
210
+
211
+	/**
212
+	 * @param string           $sql
213
+	 * @param array<int,mixed> $bindings
214
+	 *
215
+	 * @return static
216
+	 */
217
+	public function query($sql, $bindings = []): self
218
+	{
219
+		list($this->sqlStatement) = $this->statement($sql, $bindings);
220
+
221
+		return $this;
222
+	}
223
+
224
+	/**
225
+	 * @param string           $sql
226
+	 * @param array<int,mixed> $bindings
227
+	 *
228
+	 * @return array{0:string, 1:float}
229
+	 */
230
+	public function statement(string $sql, $bindings = []): array
231
+	{
232
+		$start        = microtime(true);
233
+		$sqlStatement = empty($bindings) ? $sql : $this->interpolateQuery($sql, $bindings);
234
+
235
+		if (!is_string($sqlStatement)) {
236
+			throw new Exception('Could not interpolate query', 1);
237
+		}
238
+
239
+		return [$sqlStatement, microtime(true) - $start];
240
+	}
241
+
242
+	/**
243
+	 * Get all rows
244
+	 *
245
+	 * @return array<mixed,mixed>|null
246
+	 *
247
+	 * @throws Exception
248
+	 */
249
+	public function get()
250
+	{
251
+		$eventResult = $this->fireEvents('before-select');
252
+		if (!is_null($eventResult)) {
253
+			return $eventResult;
254
+		}
255
+		$executionTime = 0;
256
+		if (is_null($this->sqlStatement)) {
257
+			$queryObject = $this->getQuery('select');
258
+			$statement   = $this->statement(
259
+				$queryObject->getSql(),
260
+				$queryObject->getBindings()
261
+			);
262
+
263
+			$this->sqlStatement = $statement[0];
264
+			$executionTime      = $statement[1];
265
+		}
266
+
267
+		$start  = microtime(true);
268
+		$result = $this->dbInstance()->get_results(
269
+			is_array($this->sqlStatement) ? (end($this->sqlStatement) ?: '') : $this->sqlStatement,
270
+			// If we are using the hydrator, return as OBJECT and let the hydrator map the correct model.
271
+			$this->useHydrator() ? OBJECT : $this->getFetchMode()
272
+		);
273
+		$executionTime += microtime(true) - $start;
274
+		$this->sqlStatement = null;
275
+
276
+		// Ensure we have an array of results.
277
+		if (!is_array($result) && null !== $result) {
278
+			$result = [$result];
279
+		}
280
+
281
+		// Maybe hydrate the results.
282
+		if (null !== $result && $this->useHydrator()) {
283
+			$result = $this->getHydrator()->fromMany($result);
284
+		}
285
+
286
+		$this->fireEvents('after-select', $result, $executionTime);
287
+
288
+		return $result;
289
+	}
290
+
291
+	/**
292
+	 * Returns a populated instance of the Hydrator.
293
+	 *
294
+	 * @return Hydrator
295
+	 */
296
+	protected function getHydrator(): Hydrator /* @phpstan-ignore-line */
297
+	{
298
+		$hydrator = new Hydrator($this->getFetchMode(), $this->hydratorConstructorArgs ?? []); /* @phpstan-ignore-line */
299
+
300
+		return $hydrator;
301
+	}
302
+
303
+	/**
304
+	 * Checks if the results should be mapped via the hydrator
305
+	 *
306
+	 * @return bool
307
+	 */
308
+	protected function useHydrator(): bool
309
+	{
310
+		return !in_array($this->getFetchMode(), [\ARRAY_A, \ARRAY_N, \OBJECT, \OBJECT_K]);
311
+	}
312
+
313
+	/**
314
+	 * Find all matching a simple where condition.
315
+	 *
316
+	 * Shortcut of ->where('key','=','value')->limit(1)->get();
317
+	 *
318
+	 * @return \stdClass\array<mixed,mixed>|object|null Can return any object using hydrator
319
+	 */
320
+	public function first()
321
+	{
322
+		$this->limit(1);
323
+		$result = $this->get();
324
+
325
+		return empty($result) ? null : $result[0];
326
+	}
327
+
328
+	/**
329
+	 * Find all matching a simple where condition.
330
+	 *
331
+	 * Shortcut of ->where('key','=','value')->get();
332
+	 *
333
+	 * @param string $fieldName
334
+	 * @param mixed $value
335
+	 *
336
+	 * @return array<mixed,mixed>|null Can return any object using hydrator
337
+	 */
338
+	public function findAll($fieldName, $value)
339
+	{
340
+		$this->where($fieldName, '=', $value);
341
+
342
+		return $this->get();
343
+	}
344
+
345
+	/**
346
+	 * @param string $fieldName
347
+	 * @param mixed $value
348
+	 *
349
+	 * @return \stdClass\array<mixed,mixed>|object|null Can return any object using hydrator
350
+	 */
351
+	public function find($value, $fieldName = 'id')
352
+	{
353
+		$this->where($fieldName, '=', $value);
354
+
355
+		return $this->first();
356
+	}
357
+
358
+	/**
359
+	 * @param string $fieldName
360
+	 * @param mixed $value
361
+	 *
362
+	 * @return \stdClass\array<mixed,mixed>|object Can return any object using hydrator
363
+	 * @throws Exception If fails to find
364
+	 */
365
+	public function findOrFail($value, $fieldName = 'id')
366
+	{
367
+		$result = $this->find($value, $fieldName);
368
+		if (null === $result) {
369
+			throw new Exception("Failed to find {$fieldName}={$value}", 1);
370
+		}
371
+		return $result;
372
+	}
373
+
374
+	/**
375
+	 * Used to handle all aggregation method.
376
+	 *
377
+	 * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
378
+	 *
379
+	 * @param string $type
380
+	 * @param string|Raw $field
381
+	 *
382
+	 * @return float
383
+	 */
384
+	protected function aggregate(string $type, $field = '*'): float
385
+	{
386
+		// Parse a raw expression.
387
+		if ($field instanceof Raw) {
388
+			$field = $this->adapterInstance->parseRaw($field);
389
+		}
390
+
391
+		// Potentialy cast field from JSON
392
+		if ($this->jsonHandler->isJsonSelector($field)) {
393
+			$field = $this->jsonHandler->extractAndUnquoteFromJsonSelector($field);
394
+		}
395
+
396
+		// Verify that field exists
397
+		if ('*' !== $field && true === isset($this->statements['selects']) && false === \in_array($field, $this->statements['selects'], true)) {
398
+			throw new \Exception(sprintf('Failed %s query - the column %s hasn\'t been selected in the query.', $type, $field));
399
+		}
400
+
401
+
402
+		if (false === isset($this->statements['tables'])) {
403
+			throw new Exception('No table selected');
404
+		}
405
+
406
+		$count = $this
407
+			->table($this->subQuery($this, 'count'))
408
+			->select([$this->raw(sprintf('%s(%s) AS field', strtoupper($type), $field))])
409
+			->first();
410
+
411
+		return true === isset($count->field) ? (float)$count->field : 0;
412
+	}
413
+
414
+	/**
415
+	 * Get count of all the rows for the current query
416
+	 *
417
+	 * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
418
+	 *
419
+	 * @param string|Raw $field
420
+	 *
421
+	 * @return int
422
+	 *
423
+	 * @throws Exception
424
+	 */
425
+	public function count($field = '*'): int
426
+	{
427
+		return (int)$this->aggregate('count', $field);
428
+	}
429
+
430
+	/**
431
+	 * Get the sum for a field in the current query
432
+	 *
433
+	 * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
434
+	 *
435
+	 * @param string|Raw $field
436
+	 *
437
+	 * @return float
438
+	 *
439
+	 * @throws Exception
440
+	 */
441
+	public function sum($field): float
442
+	{
443
+		return $this->aggregate('sum', $field);
444
+	}
445
+
446
+	/**
447
+	 * Get the average for a field in the current query
448
+	 *
449
+	 * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
450
+	 *
451
+	 * @param string|Raw $field
452
+	 *
453
+	 * @return float
454
+	 *
455
+	 * @throws Exception
456
+	 */
457
+	public function average($field): float
458
+	{
459
+		return $this->aggregate('avg', $field);
460
+	}
461
+
462
+	/**
463
+	 * Get the minimum for a field in the current query
464
+	 *
465
+	 * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
466
+	 *
467
+	 * @param string|Raw $field
468
+	 *
469
+	 * @return float
470
+	 *
471
+	 * @throws Exception
472
+	 */
473
+	public function min($field): float
474
+	{
475
+		return $this->aggregate('min', $field);
476
+	}
477
+
478
+	/**
479
+	 * Get the maximum for a field in the current query
480
+	 *
481
+	 * @see Taken from the pecee-pixie library - https://github.com/skipperbent/pecee-pixie/
482
+	 *
483
+	 * @param string|Raw $field
484
+	 *
485
+	 * @return float
486
+	 *
487
+	 * @throws Exception
488
+	 */
489
+	public function max($field): float
490
+	{
491
+		return $this->aggregate('max', $field);
492
+	}
493
+
494
+	/**
495
+	 * @param string $type
496
+	 * @param bool|array<mixed, mixed> $dataToBePassed
497
+	 *
498
+	 * @return mixed
499
+	 *
500
+	 * @throws Exception
501
+	 */
502
+	public function getQuery(string $type = 'select', $dataToBePassed = [])
503
+	{
504
+		$allowedTypes = ['select', 'insert', 'insertignore', 'replace', 'delete', 'update', 'criteriaonly'];
505
+		if (!in_array(strtolower($type), $allowedTypes)) {
506
+			throw new Exception($type . ' is not a known type.', 2);
507
+		}
508
+
509
+		$queryArr = $this->adapterInstance->$type($this->statements, $dataToBePassed);
510
+
511
+		return $this->container->build(
512
+			QueryObject::class,
513
+			[$queryArr['sql'], $queryArr['bindings'], $this->dbInstance]
514
+		);
515
+	}
516
+
517
+	/**
518
+	 * @param QueryBuilderHandler $queryBuilder
519
+	 * @param string|null $alias
520
+	 *
521
+	 * @return Raw
522
+	 */
523
+	public function subQuery(QueryBuilderHandler $queryBuilder, ?string $alias = null)
524
+	{
525
+		$sql = '(' . $queryBuilder->getQuery()->getRawSql() . ')';
526
+		if (is_string($alias) && 0 !== mb_strlen($alias)) {
527
+			$sql = $sql . ' as ' . $alias;
528
+		}
529
+
530
+		return $queryBuilder->raw($sql);
531
+	}
532
+
533
+	/**
534
+	 * Handles the various insert operations based on the type.
535
+	 *
536
+	 * @param array<int|string, mixed|mixed[]> $data
537
+	 * @param string $type
538
+	 *
539
+	 * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
540
+	 */
541
+	private function doInsert(array $data, string $type)
542
+	{
543
+		$eventResult = $this->fireEvents('before-insert');
544
+		if (!is_null($eventResult)) {
545
+			return $eventResult;
546
+		}
547
+
548
+		// If first value is not an array () not a batch insert)
549
+		if (!is_array(current($data))) {
550
+			$queryObject = $this->getQuery($type, $data);
551
+
552
+			list($preparedQuery, $executionTime) = $this->statement($queryObject->getSql(), $queryObject->getBindings());
553
+			$this->dbInstance->get_results($preparedQuery);
554
+
555
+			// Check we have a result.
556
+			$return = 1 === $this->dbInstance->rows_affected ? $this->dbInstance->insert_id : null;
557
+		} else {
558
+			// Its a batch insert
559
+			$return        = [];
560
+			$executionTime = 0;
561
+			foreach ($data as $subData) {
562
+				$queryObject = $this->getQuery($type, $subData);
563
+
564
+				list($preparedQuery, $time) = $this->statement($queryObject->getSql(), $queryObject->getBindings());
565
+				$this->dbInstance->get_results($preparedQuery);
566
+				$executionTime += $time;
567
+
568
+				if (1 === $this->dbInstance->rows_affected) {
569
+					$return[] = $this->dbInstance->insert_id;
570
+				}
571
+			}
572
+		}
573
+
574
+		$this->fireEvents('after-insert', $return, $executionTime);
575
+
576
+		return $return;
577
+	}
578
+
579
+	/**
580
+	 * @param array<int|string, mixed|mixed[]> $data either key=>value array for single or array of arrays for bulk
581
+	 *
582
+	 * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
583
+	 */
584
+	public function insert($data)
585
+	{
586
+		return $this->doInsert($data, 'insert');
587
+	}
588
+
589
+	/**
590
+	 *
591
+	 * @param array<int|string, mixed|mixed[]> $data either key=>value array for single or array of arrays for bulk
592
+	 *
593
+	 * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
594
+	 */
595
+	public function insertIgnore($data)
596
+	{
597
+		return $this->doInsert($data, 'insertignore');
598
+	}
599
+
600
+	/**
601
+	 *
602
+	 * @param array<int|string, mixed|mixed[]> $data either key=>value array for single or array of arrays for bulk
603
+	 *
604
+	 * @return int|int[]|mixed|null can return a single row id, array of row ids, null (for failed) or any other value short circuited from event
605
+	 */
606
+	public function replace($data)
607
+	{
608
+		return $this->doInsert($data, 'replace');
609
+	}
610
+
611
+	/**
612
+	 * @param array<string, mixed> $data
613
+	 *
614
+	 * @return int|null
615
+	 */
616
+	public function update($data)
617
+	{
618
+		$eventResult = $this->fireEvents('before-update');
619
+		if (!is_null($eventResult)) {
620
+			return $eventResult;
621
+		}
622
+		$queryObject                         = $this->getQuery('update', $data);
623
+		$r = $this->statement($queryObject->getSql(), $queryObject->getBindings());
624
+		list($preparedQuery, $executionTime) = $r;
625
+		$this->dbInstance()->get_results($preparedQuery);
626
+		$this->fireEvents('after-update', $queryObject, $executionTime);
627
+
628
+		return 0 !== $this->dbInstance()->rows_affected
629
+			? $this->dbInstance()->rows_affected
630
+			: null;
631
+	}
632
+
633
+	/**
634
+	 * @param array<string, mixed> $data
635
+	 *
636
+	 * @return int|null will return row id for insert and bool for success/fail on update
637
+	 */
638
+	public function updateOrInsert($data)
639
+	{
640
+		if ($this->first()) {
641
+			return $this->update($data);
642
+		}
643
+
644
+		return $this->insert($data);
645
+	}
646
+
647
+	/**
648
+	 * @param array<string, mixed> $data
649
+	 *
650
+	 * @return static
651
+	 */
652
+	public function onDuplicateKeyUpdate($data)
653
+	{
654
+		$this->addStatement('onduplicate', $data);
655
+
656
+		return $this;
657
+	}
658
+
659
+	/**
660
+	 * @return mixed number of rows effected or shortcircuited response
661
+	 */
662
+	public function delete()
663
+	{
664
+		$eventResult = $this->fireEvents('before-delete');
665
+		if (!is_null($eventResult)) {
666
+			return $eventResult;
667
+		}
668
+
669
+		$queryObject = $this->getQuery('delete');
670
+
671
+		list($preparedQuery, $executionTime) = $this->statement($queryObject->getSql(), $queryObject->getBindings());
672
+		$this->dbInstance()->get_results($preparedQuery);
673
+		$this->fireEvents('after-delete', $queryObject, $executionTime);
674
+
675
+		return $this->dbInstance()->rows_affected;
676
+	}
677
+
678
+	/**
679
+	 * @param string|Raw ...$tables Single table or array of tables
680
+	 *
681
+	 * @return static
682
+	 *
683
+	 * @throws Exception
684
+	 */
685
+	public function table(...$tables)
686
+	{
687
+		$instance =  $this->constructCurrentBuilderClass($this->connection);
688
+		$this->setFetchMode($this->getFetchMode(), $this->hydratorConstructorArgs);
689
+		$tables = $this->addTablePrefix($tables, false);
690
+		$instance->addStatement('tables', $tables);
691
+
692
+		return $instance;
693
+	}
694
+
695
+	/**
696
+	 * @param string|Raw ...$tables Single table or array of tables
697
+	 *
698
+	 * @return static
699
+	 */
700
+	public function from(...$tables): self
701
+	{
702
+		$tables = $this->addTablePrefix($tables, false);
703
+		$this->addStatement('tables', $tables);
704
+
705
+		return $this;
706
+	}
707
+
708
+	/**
709
+	 * @param string|string[]|Raw[]|array<string, string> $fields
710
+	 *
711
+	 * @return static
712
+	 */
713
+	public function select($fields): self
714
+	{
715
+		if (!is_array($fields)) {
716
+			$fields = func_get_args();
717
+		}
718
+
719
+		foreach ($fields as $field => $alias) {
720
+			// If we have a JSON expression
721
+			if ($this->jsonHandler->isJsonSelector($field)) {
722
+				$field = $this->jsonHandler->extractAndUnquoteFromJsonSelector($field);
723
+			}
724
+
725
+			// If no alias passed, but field is for JSON. thrown an exception.
726
+			if (is_numeric($field) && is_string($alias) && $this->jsonHandler->isJsonSelector($alias)) {
727
+				throw new Exception("An alias must be used if you wish to select from JSON Object", 1);
728
+			}
729
+
730
+			// Treat each array as a single table, to retain order added
731
+			$field = is_numeric($field)
732
+				? $field = $alias // If single colum
733
+				: $field = [$field => $alias]; // Has alias
734
+
735
+			$field = $this->addTablePrefix($field);
736
+			$this->addStatement('selects', $field);
737
+		}
738
+
739
+		return $this;
740
+	}
741
+
742
+	/**
743
+	 * @param string|string[]|Raw[]|array<string, string> $fields
744
+	 *
745
+	 * @return static
746
+	 */
747
+	public function selectDistinct($fields)
748
+	{
749
+		$this->select($fields);
750
+		$this->addStatement('distinct', true);
751
+
752
+		return $this;
753
+	}
754
+
755
+	/**
756
+	 * @param string|string[] $field either the single field or an array of fields
757
+	 *
758
+	 * @return static
759
+	 */
760
+	public function groupBy($field): self
761
+	{
762
+		$field = $this->addTablePrefix($field);
763
+		$this->addStatement('groupBys', $field);
764
+
765
+		return $this;
766
+	}
767
+
768
+	/**
769
+	 * @param string|array<string|int, mixed> $fields
770
+	 * @param string          $defaultDirection
771
+	 *
772
+	 * @return static
773
+	 */
774
+	public function orderBy($fields, string $defaultDirection = 'ASC'): self
775
+	{
776
+		if (!is_array($fields)) {
777
+			$fields = [$fields];
778
+		}
779
+
780
+		foreach ($fields as $key => $value) {
781
+			$field = $key;
782
+			$type  = $value;
783
+			if (is_int($key)) {
784
+				$field = $value;
785
+				$type  = $defaultDirection;
786
+			}
787
+
788
+			if ($this->jsonHandler->isJsonSelector($field)) {
789
+				$field = $this->jsonHandler->extractAndUnquoteFromJsonSelector($field);
790
+			}
791
+
792
+			if (!$field instanceof Raw) {
793
+				$field = $this->addTablePrefix($field);
794
+			}
795
+			$this->statements['orderBys'][] = compact('field', 'type');
796
+		}
797
+
798
+		return $this;
799
+	}
800
+
801
+	/**
802
+	 * @param string|Raw $key The database column which holds the JSON value
803
+	 * @param string|Raw|string[] $jsonKey The json key/index to search
804
+	 * @param string $defaultDirection
805
+	 * @return static
806
+	 */
807
+	public function orderByJson($key, $jsonKey, string $defaultDirection = 'ASC'): self
808
+	{
809
+		$key = $this->jsonHandler->jsonExpressionFactory()->extractAndUnquote($key, $jsonKey);
810
+		return $this->orderBy($key, $defaultDirection);
811
+	}
812
+
813
+	/**
814
+	 * @param int $limit
815
+	 *
816
+	 * @return static
817
+	 */
818
+	public function limit(int $limit): self
819
+	{
820
+		$this->statements['limit'] = $limit;
821
+
822
+		return $this;
823
+	}
824
+
825
+	/**
826
+	 * @param int $offset
827
+	 *
828
+	 * @return static
829
+	 */
830
+	public function offset(int $offset): self
831
+	{
832
+		$this->statements['offset'] = $offset;
833
+
834
+		return $this;
835
+	}
836
+
837
+	/**
838
+	 * @param string|string[]|Raw|Raw[]       $key
839
+	 * @param string $operator
840
+	 * @param mixed $value
841
+	 * @param string $joiner
842
+	 *
843
+	 * @return static
844
+	 */
845
+	public function having($key, string $operator, $value, string $joiner = 'AND')
846
+	{
847
+		$key                           = $this->addTablePrefix($key);
848
+		$this->statements['havings'][] = compact('key', 'operator', 'value', 'joiner');
849
+
850
+		return $this;
851
+	}
852
+
853
+	/**
854
+	 * @param string|string[]|Raw|Raw[]       $key
855
+	 * @param string $operator
856
+	 * @param mixed $value
857
+	 *
858
+	 * @return static
859
+	 */
860
+	public function orHaving($key, $operator, $value)
861
+	{
862
+		return $this->having($key, $operator, $value, 'OR');
863
+	}
864
+
865
+	/**
866
+	 * @param string|Raw $key
867
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
868
+	 * @param mixed|null $value
869
+	 *
870
+	 * @return static
871
+	 */
872
+	public function where($key, $operator = null, $value = null): self
873
+	{
874
+		// If two params are given then assume operator is =
875
+		if (2 === func_num_args()) {
876
+			$value    = $operator;
877
+			$operator = '=';
878
+		}
879
+
880
+		return $this->whereHandler($key, $operator, $value);
881
+	}
882
+
883
+	/**
884
+	 * @param string|Raw|\Closure(QueryBuilderHandler):void $key
885
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
886
+	 * @param mixed|null $value
887
+	 *
888
+	 * @return static
889
+	 */
890
+	public function orWhere($key, $operator = null, $value = null): self
891
+	{
892
+		// If two params are given then assume operator is =
893
+		if (2 === func_num_args()) {
894
+			$value    = $operator;
895
+			$operator = '=';
896
+		}
897
+
898
+		return $this->whereHandler($key, $operator, $value, 'OR');
899
+	}
900
+
901
+	/**
902
+	 * @param string|Raw $key
903
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
904
+	 * @param mixed|null $value
905
+	 *
906
+	 * @return static
907
+	 */
908
+	public function whereNot($key, $operator = null, $value = null): self
909
+	{
910
+		// If two params are given then assume operator is =
911
+		if (2 === func_num_args()) {
912
+			$value    = $operator;
913
+			$operator = '=';
914
+		}
915
+
916
+		return $this->whereHandler($key, $operator, $value, 'AND NOT');
917
+	}
918
+
919
+	/**
920
+	 * @param string|Raw $key
921
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
922
+	 * @param mixed|null $value
923
+	 *
924
+	 * @return static
925
+	 */
926
+	public function orWhereNot($key, $operator = null, $value = null)
927
+	{
928
+		// If two params are given then assume operator is =
929
+		if (2 === func_num_args()) {
930
+			$value    = $operator;
931
+			$operator = '=';
932
+		}
933
+
934
+		return $this->whereHandler($key, $operator, $value, 'OR NOT');
935
+	}
936
+
937
+	/**
938
+	 * @param string|Raw $key
939
+	 * @param mixed[]|string|Raw $values
940
+	 *
941
+	 * @return static
942
+	 */
943
+	public function whereIn($key, $values): self
944
+	{
945
+		return $this->whereHandler($key, 'IN', $values, 'AND');
946
+	}
947
+
948
+	/**
949
+	 * @param string|Raw $key
950
+	 * @param mixed[]|string|Raw $values
951
+	 *
952
+	 * @return static
953
+	 */
954
+	public function whereNotIn($key, $values): self
955
+	{
956
+		return $this->whereHandler($key, 'NOT IN', $values, 'AND');
957
+	}
958
+
959
+	/**
960
+	 * @param string|Raw $key
961
+	 * @param mixed[]|string|Raw $values
962
+	 *
963
+	 * @return static
964
+	 */
965
+	public function orWhereIn($key, $values): self
966
+	{
967
+		return $this->whereHandler($key, 'IN', $values, 'OR');
968
+	}
969
+
970
+	/**
971
+	 * @param string|Raw $key
972
+	 * @param mixed[]|string|Raw $values
973
+	 *
974
+	 * @return static
975
+	 */
976
+	public function orWhereNotIn($key, $values): self
977
+	{
978
+		return $this->whereHandler($key, 'NOT IN', $values, 'OR');
979
+	}
980
+
981
+	/**
982
+	 * @param string|Raw $key
983
+	 * @param mixed $valueFrom
984
+	 * @param mixed $valueTo
985
+	 *
986
+	 * @return static
987
+	 */
988
+	public function whereBetween($key, $valueFrom, $valueTo): self
989
+	{
990
+		return $this->whereHandler($key, 'BETWEEN', [$valueFrom, $valueTo], 'AND');
991
+	}
992
+
993
+	/**
994
+	 * @param string|Raw $key
995
+	 * @param mixed $valueFrom
996
+	 * @param mixed $valueTo
997
+	 *
998
+	 * @return static
999
+	 */
1000
+	public function orWhereBetween($key, $valueFrom, $valueTo): self
1001
+	{
1002
+		return $this->whereHandler($key, 'BETWEEN', [$valueFrom, $valueTo], 'OR');
1003
+	}
1004
+
1005
+	/**
1006
+	 * Handles all function call based where conditions
1007
+	 *
1008
+	 * @param string|Raw $key
1009
+	 * @param string $function
1010
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1011
+	 * @param mixed|null $value
1012
+	 * @return static
1013
+	 */
1014
+	protected function whereFunctionCallHandler($key, $function, $operator, $value): self
1015
+	{
1016
+		$key = \sprintf('%s(%s)', $function, $this->addTablePrefix($key));
1017
+		return $this->where($key, $operator, $value);
1018
+	}
1019
+
1020
+	/**
1021
+	 * @param string|Raw $key
1022
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1023
+	 * @param mixed|null $value
1024
+	 * @return self
1025
+	 */
1026
+	public function whereMonth($key, $operator = null, $value = null): self
1027
+	{
1028
+		// If two params are given then assume operator is =
1029
+		if (2 === func_num_args()) {
1030
+			$value    = $operator;
1031
+			$operator = '=';
1032
+		}
1033
+		return $this->whereFunctionCallHandler($key, 'MONTH', $operator, $value);
1034
+	}
1035
+
1036
+	/**
1037
+	 * @param string|Raw $key
1038
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1039
+	 * @param mixed|null $value
1040
+	 * @return self
1041
+	 */
1042
+	public function whereDay($key, $operator = null, $value = null): self
1043
+	{
1044
+		// If two params are given then assume operator is =
1045
+		if (2 === func_num_args()) {
1046
+			$value    = $operator;
1047
+			$operator = '=';
1048
+		}
1049
+		return $this->whereFunctionCallHandler($key, 'DAY', $operator, $value);
1050
+	}
1051
+
1052
+	/**
1053
+	 * @param string|Raw $key
1054
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1055
+	 * @param mixed|null $value
1056
+	 * @return self
1057
+	 */
1058
+	public function whereYear($key, $operator = null, $value = null): self
1059
+	{
1060
+		// If two params are given then assume operator is =
1061
+		if (2 === func_num_args()) {
1062
+			$value    = $operator;
1063
+			$operator = '=';
1064
+		}
1065
+		return $this->whereFunctionCallHandler($key, 'YEAR', $operator, $value);
1066
+	}
1067
+
1068
+	/**
1069
+	 * @param string|Raw $key
1070
+	 * @param string|mixed|null $operator Can be used as value, if 3rd arg not passed
1071
+	 * @param mixed|null $value
1072
+	 * @return self
1073
+	 */
1074
+	public function whereDate($key, $operator = null, $value = null): self
1075
+	{
1076
+		// If two params are given then assume operator is =
1077
+		if (2 === func_num_args()) {
1078
+			$value    = $operator;
1079
+			$operator = '=';
1080
+		}
1081
+		return $this->whereFunctionCallHandler($key, 'DATE', $operator, $value);
1082
+	}
1083
+
1084
+	/**
1085
+	 * @param string|Raw $key
1086
+	 *
1087
+	 * @return static
1088
+	 */
1089
+	public function whereNull($key): self
1090
+	{
1091
+		return $this->whereNullHandler($key);
1092
+	}
1093
+
1094
+	/**
1095
+	 * @param string|Raw $key
1096
+	 *
1097
+	 * @return static
1098
+	 */
1099
+	public function whereNotNull($key): self
1100
+	{
1101
+		return $this->whereNullHandler($key, 'NOT');
1102
+	}
1103
+
1104
+	/**
1105
+	 * @param string|Raw $key
1106
+	 *
1107
+	 * @return static
1108
+	 */
1109
+	public function orWhereNull($key): self
1110
+	{
1111
+		return $this->whereNullHandler($key, '', 'or');
1112
+	}
1113
+
1114
+	/**
1115
+	 * @param string|Raw $key
1116
+	 *
1117
+	 * @return static
1118
+	 */
1119
+	public function orWhereNotNull($key): self
1120
+	{
1121
+		return $this->whereNullHandler($key, 'NOT', 'or');
1122
+	}
1123
+
1124
+	/**
1125
+	 * @param string|Raw $key
1126
+	 * @param string $prefix
1127
+	 * @param string $operator
1128
+	 *
1129
+	 * @return static
1130
+	 */
1131
+	protected function whereNullHandler($key, string $prefix = '', $operator = ''): self
1132
+	{
1133
+		$prefix = 0 === mb_strlen($prefix) ? '' : " {$prefix}";
1134
+
1135
+		if ($key instanceof Raw) {
1136
+			$key = $this->adapterInstance->parseRaw($key);
1137
+		}
1138
+
1139
+		$key = $this->addTablePrefix($key);
1140
+		if ($key instanceof Closure) {
1141
+			throw new Exception('Key used for whereNull condition must be a string or raw exrpession.', 1);
1142
+		}
1143
+
1144
+		return $this->{$operator . 'Where'}($this->raw("{$key} IS{$prefix} NULL"));
1145
+	}
1146
+
1147
+
1148
+	/**
1149
+	 * Runs a transaction
1150
+	 *
1151
+	 * @param \Closure(Transaction):void $callback
1152
+	 *
1153
+	 * @return static
1154
+	 */
1155
+	public function transaction(Closure $callback): self
1156
+	{
1157
+		try {
1158
+			// Begin the transaction
1159
+			$this->dbInstance->query('START TRANSACTION');
1160
+
1161
+			// Get the Transaction class
1162
+			$transaction = $this->container->build(Transaction::class, [$this->connection]);
1163
+
1164
+			$this->handleTransactionCall($callback, $transaction);
1165
+
1166
+			// If no errors have been thrown or the transaction wasn't completed within
1167
+			$this->dbInstance->query('COMMIT');
1168
+
1169
+			return $this;
1170
+		} catch (TransactionHaltException $e) {
1171
+			// Commit or rollback behavior has been handled in the closure, so exit
1172
+			return $this;
1173
+		} catch (\Exception $e) {
1174
+			// something happened, rollback changes
1175
+			$this->dbInstance->query('ROLLBACK');
1176
+
1177
+			return $this;
1178
+		}
1179
+	}
1180
+
1181
+	/**
1182
+	 * Handles the transaction call.
1183
+	 * Catches any WPDB Errors (printed)
1184
+	 *
1185
+	 * @param Closure    $callback
1186
+	 * @param Transaction $transaction
1187
+	 *
1188
+	 * @return void
1189
+	 * @throws Exception
1190
+	 */
1191
+	protected function handleTransactionCall(Closure $callback, Transaction $transaction): void
1192
+	{
1193
+		try {
1194
+			ob_start();
1195
+			$callback($transaction);
1196
+			$output = ob_get_clean() ?: '';
1197
+		} catch (Throwable $th) {
1198
+			ob_end_clean();
1199
+			throw $th;
1200
+		}
1201
+
1202
+		// If we caught an error, throw an exception.
1203
+		if (0 !== mb_strlen($output)) {
1204
+			throw new Exception($output);
1205
+		}
1206
+	}
1207
+
1208
+	/*************************************************************************/
1209
+	/*************************************************************************/
1210
+	/*************************************************************************/
1211
+	/**                              JOIN JOIN                              **/
1212
+	/**                                 JOIN                                **/
1213
+	/**                              JOIN JOIN                              **/
1214
+	/*************************************************************************/
1215
+	/*************************************************************************/
1216
+	/*************************************************************************/
1217
+
1218
+	/**
1219
+	 * @param string|Raw $table
1220
+	 * @param string|Raw|Closure $key
1221
+	 * @param string|null $operator
1222
+	 * @param mixed $value
1223
+	 * @param string $type
1224
+	 *
1225
+	 * @return static
1226
+	 */
1227
+	public function join($table, $key, ?string $operator = null, $value = null, $type = 'inner')
1228
+	{
1229
+		// Potentially cast key from JSON
1230
+		if ($this->jsonHandler->isJsonSelector($key)) {
1231
+			/** @var string $key */
1232
+			$key = $this->jsonHandler->extractAndUnquoteFromJsonSelector($key); /** @phpstan-ignore-line */
1233
+		}
1234
+
1235
+		// Potentially cast value from json
1236
+		if ($this->jsonHandler->isJsonSelector($value)) {
1237
+			/** @var string $value */
1238
+			$value = $this->jsonHandler->extractAndUnquoteFromJsonSelector($value);
1239
+		}
1240
+
1241
+		if (!$key instanceof Closure) {
1242
+			$key = function ($joinBuilder) use ($key, $operator, $value) {
1243
+				$joinBuilder->on($key, $operator, $value);
1244
+			};
1245
+		}
1246
+
1247
+		// Build a new JoinBuilder class, keep it by reference so any changes made
1248
+		// in the closure should reflect here
1249
+		$joinBuilder = $this->container->build(JoinBuilder::class, [$this->connection]);
1250
+		$joinBuilder = &$joinBuilder;
1251
+		// Call the closure with our new joinBuilder object
1252
+		$key($joinBuilder);
1253
+		$table = $this->addTablePrefix($table, false);
1254
+		// Get the criteria only query from the joinBuilder object
1255
+		$this->statements['joins'][] = compact('type', 'table', 'joinBuilder');
1256
+		return $this;
1257
+	}
1258
+
1259
+	/**
1260
+	 * @param string|Raw $table
1261
+	 * @param string|Raw|Closure $key
1262
+	 * @param string|null $operator
1263
+	 * @param mixed $value
1264
+	 *
1265
+	 * @return static
1266
+	 */
1267
+	public function leftJoin($table, $key, $operator = null, $value = null)
1268
+	{
1269
+		return $this->join($table, $key, $operator, $value, 'left');
1270
+	}
1271
+
1272
+	/**
1273
+	 * @param string|Raw $table
1274
+	 * @param string|Raw|Closure $key
1275
+	 * @param string|null $operator
1276
+	 * @param mixed $value
1277
+	 *
1278
+	 * @return static
1279
+	 */
1280
+	public function rightJoin($table, $key, $operator = null, $value = null)
1281
+	{
1282
+		return $this->join($table, $key, $operator, $value, 'right');
1283
+	}
1284
+
1285
+	/**
1286
+	 * @param string|Raw $table
1287
+	 * @param string|Raw|Closure $key
1288
+	 * @param string|null $operator
1289
+	 * @param mixed $value
1290
+	 *
1291
+	 * @return static
1292
+	 */
1293
+	public function innerJoin($table, $key, $operator = null, $value = null)
1294
+	{
1295
+		return $this->join($table, $key, $operator, $value, 'inner');
1296
+	}
1297
+
1298
+	/**
1299
+	 * @param string|Raw $table
1300
+	 * @param string|Raw|Closure $key
1301
+	 * @param string|null $operator
1302
+	 * @param mixed $value
1303
+	 *
1304
+	 * @return static
1305
+	 */
1306
+	public function crossJoin($table, $key, $operator = null, $value = null)
1307
+	{
1308
+		return $this->join($table, $key, $operator, $value, 'cross');
1309
+	}
1310
+
1311
+	/**
1312
+	 * @param string|Raw $table
1313
+	 * @param string|Raw|Closure $key
1314
+	 * @param string|null $operator
1315
+	 * @param mixed $value
1316
+	 *
1317
+	 * @return static
1318
+	 */
1319
+	public function outerJoin($table, $key, $operator = null, $value = null)
1320
+	{
1321
+		return $this->join($table, $key, $operator, $value, 'full outer');
1322
+	}
1323
+
1324
+	/**
1325
+	 * Shortcut to join 2 tables on the same key name with equals
1326
+	 *
1327
+	 * @param string $table
1328
+	 * @param string $key
1329
+	 * @param string $type
1330
+	 * @return self
1331
+	 * @throws Exception If base table is set as more than 1 or 0
1332
+	 */
1333
+	public function joinUsing(string $table, string $key, string $type = 'INNER'): self
1334
+	{
1335
+		if (!array_key_exists('tables', $this->statements) || count($this->statements['tables']) !== 1) {
1336
+			throw new Exception("JoinUsing can only be used with a single table set as the base of the query", 1);
1337
+		}
1338
+		$baseTable = end($this->statements['tables']);
1339
+
1340
+		// Potentialy cast key from JSON
1341
+		if ($this->jsonHandler->isJsonSelector($key)) {
1342
+			$key = $this->jsonHandler->extractAndUnquoteFromJsonSelector($key);
1343
+		}
1344
+
1345
+		$remoteKey = $table = $this->addTablePrefix("{$table}.{$key}", true);
1346
+		$localKey = $table = $this->addTablePrefix("{$baseTable}.{$key}", true);
1347
+		return $this->join($table, $remoteKey, '=', $localKey, $type);
1348
+	}
1349
+
1350
+	/**
1351
+	 * Add a raw query
1352
+	 *
1353
+	 * @param string|Raw $value
1354
+	 * @param mixed|mixed[] $bindings
1355
+	 *
1356
+	 * @return Raw
1357
+	 */
1358
+	public function raw($value, $bindings = []): Raw
1359
+	{
1360
+		return new Raw($value, $bindings);
1361
+	}
1362
+
1363
+	/**
1364
+	 * Return wpdb instance
1365
+	 *
1366
+	 * @return wpdb
1367
+	 */
1368
+	public function dbInstance(): wpdb
1369
+	{
1370
+		return $this->dbInstance;
1371
+	}
1372
+
1373
+	/**
1374
+	 * @param Connection $connection
1375
+	 *
1376
+	 * @return static
1377
+	 */
1378
+	public function setConnection(Connection $connection): self
1379
+	{
1380
+		$this->connection = $connection;
1381
+
1382
+		return $this;
1383
+	}
1384
+
1385
+	/**
1386
+	 * @return Connection
1387
+	 */
1388
+	public function getConnection(): Connection
1389
+	{
1390
+		return $this->connection;
1391
+	}
1392
+
1393
+	/**
1394
+	 * @param string|Raw|Closure $key
1395
+	 * @param string|null      $operator
1396
+	 * @param mixed|null       $value
1397
+	 * @param string $joiner
1398
+	 *
1399
+	 * @return static
1400
+	 */
1401
+	protected function whereHandler($key, $operator = null, $value = null, $joiner = 'AND')
1402
+	{
1403
+		$key = $this->addTablePrefix($key);
1404
+		if ($key instanceof Raw) {
1405
+			$key = $this->adapterInstance->parseRaw($key);
1406
+		}
1407
+
1408
+		if ($this->jsonHandler->isJsonSelector($key)) {
1409
+			$key = $this->jsonHandler->extractAndUnquoteFromJsonSelector($key);
1410
+		}
1411
+
1412
+		$this->statements['wheres'][] = compact('key', 'operator', 'value', 'joiner');
1413
+		return $this;
1414
+	}
1415
+
1416
+
1417
+
1418
+	/**
1419
+	 * @param string $key
1420
+	 * @param mixed|mixed[]|bool $value
1421
+	 *
1422
+	 * @return void
1423
+	 */
1424
+	protected function addStatement($key, $value)
1425
+	{
1426
+		if (!is_array($value)) {
1427
+			$value = [$value];
1428
+		}
1429
+
1430
+		if (!array_key_exists($key, $this->statements)) {
1431
+			$this->statements[$key] = $value;
1432
+		} else {
1433
+			$this->statements[$key] = array_merge($this->statements[$key], $value);
1434
+		}
1435
+	}
1436
+
1437
+	/**
1438
+	 * @param string $event
1439
+	 * @param string|Raw $table
1440
+	 *
1441
+	 * @return callable|null
1442
+	 */
1443
+	public function getEvent(string $event, $table = ':any'): ?callable
1444
+	{
1445
+		return $this->connection->getEventHandler()->getEvent($event, $table);
1446
+	}
1447
+
1448
+	/**
1449
+	 * @param string $event
1450
+	 * @param string|Raw $table
1451
+	 * @param Closure $action
1452
+	 *
1453
+	 * @return void
1454
+	 */
1455
+	public function registerEvent($event, $table, Closure $action): void
1456
+	{
1457
+		$table = $table ?: ':any';
1458
+
1459
+		if (':any' != $table) {
1460
+			$table = $this->addTablePrefix($table, false);
1461
+		}
1462
+
1463
+		$this->connection->getEventHandler()->registerEvent($event, $table, $action);
1464
+	}
1465
+
1466
+	/**
1467
+	 * @param string $event
1468
+	 * @param string|Raw $table
1469
+	 *
1470
+	 * @return void
1471
+	 */
1472
+	public function removeEvent(string $event, $table = ':any')
1473
+	{
1474
+		if (':any' != $table) {
1475
+			$table = $this->addTablePrefix($table, false);
1476
+		}
1477
+
1478
+		$this->connection->getEventHandler()->removeEvent($event, $table);
1479
+	}
1480
+
1481
+	/**
1482
+	 * @param string $event
1483
+	 *
1484
+	 * @return mixed
1485
+	 */
1486
+	public function fireEvents(string $event)
1487
+	{
1488
+		$params = func_get_args(); // @todo Replace this with an easier to read alteratnive
1489
+		array_unshift($params, $this);
1490
+
1491
+		return call_user_func_array([$this->connection->getEventHandler(), 'fireEvents'], $params);
1492
+	}
1493
+
1494
+	/**
1495
+	 * @return array<string, mixed[]>
1496
+	 */
1497
+	public function getStatements()
1498
+	{
1499
+		return $this->statements;
1500
+	}
1501
+
1502
+	/**
1503
+	 * @return string will return WPDB Fetch mode
1504
+	 */
1505
+	public function getFetchMode()
1506
+	{
1507
+		return null !== $this->fetchMode
1508
+			? $this->fetchMode
1509
+			: \OBJECT;
1510
+	}
1511
+
1512
+	/**
1513
+	 * Returns an NEW instance of the JSON builder populated with the same connection and hydrator details.
1514
+	 *
1515
+	 * @return JsonQueryBuilder
1516
+	 */
1517
+	public function jsonBuilder(): JsonQueryBuilder
1518
+	{
1519
+		return new JsonQueryBuilder($this->getConnection(), $this->getFetchMode(), $this->hydratorConstructorArgs);
1520
+	}
1521 1521
 }
Please login to merge, or discard this patch.
Spacing   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -232,7 +232,7 @@  discard block
 block discarded – undo
232 232
         $start        = microtime(true);
233 233
         $sqlStatement = empty($bindings) ? $sql : $this->interpolateQuery($sql, $bindings);
234 234
 
235
-        if (!is_string($sqlStatement)) {
235
+        if ( ! is_string($sqlStatement)) {
236 236
             throw new Exception('Could not interpolate query', 1);
237 237
         }
238 238
 
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
     public function get()
250 250
     {
251 251
         $eventResult = $this->fireEvents('before-select');
252
-        if (!is_null($eventResult)) {
252
+        if ( ! is_null($eventResult)) {
253 253
             return $eventResult;
254 254
         }
255 255
         $executionTime = 0;
@@ -274,7 +274,7 @@  discard block
 block discarded – undo
274 274
         $this->sqlStatement = null;
275 275
 
276 276
         // Ensure we have an array of results.
277
-        if (!is_array($result) && null !== $result) {
277
+        if ( ! is_array($result) && null !== $result) {
278 278
             $result = [$result];
279 279
         }
280 280
 
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
      */
308 308
     protected function useHydrator(): bool
309 309
     {
310
-        return !in_array($this->getFetchMode(), [\ARRAY_A, \ARRAY_N, \OBJECT, \OBJECT_K]);
310
+        return ! in_array($this->getFetchMode(), [\ARRAY_A, \ARRAY_N, \OBJECT, \OBJECT_K]);
311 311
     }
312 312
 
313 313
     /**
@@ -408,7 +408,7 @@  discard block
 block discarded – undo
408 408
             ->select([$this->raw(sprintf('%s(%s) AS field', strtoupper($type), $field))])
409 409
             ->first();
410 410
 
411
-        return true === isset($count->field) ? (float)$count->field : 0;
411
+        return true === isset($count->field) ? (float) $count->field : 0;
412 412
     }
413 413
 
414 414
     /**
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
      */
425 425
     public function count($field = '*'): int
426 426
     {
427
-        return (int)$this->aggregate('count', $field);
427
+        return (int) $this->aggregate('count', $field);
428 428
     }
429 429
 
430 430
     /**
@@ -502,8 +502,8 @@  discard block
 block discarded – undo
502 502
     public function getQuery(string $type = 'select', $dataToBePassed = [])
503 503
     {
504 504
         $allowedTypes = ['select', 'insert', 'insertignore', 'replace', 'delete', 'update', 'criteriaonly'];
505
-        if (!in_array(strtolower($type), $allowedTypes)) {
506
-            throw new Exception($type . ' is not a known type.', 2);
505
+        if ( ! in_array(strtolower($type), $allowedTypes)) {
506
+            throw new Exception($type.' is not a known type.', 2);
507 507
         }
508 508
 
509 509
         $queryArr = $this->adapterInstance->$type($this->statements, $dataToBePassed);
@@ -522,9 +522,9 @@  discard block
 block discarded – undo
522 522
      */
523 523
     public function subQuery(QueryBuilderHandler $queryBuilder, ?string $alias = null)
524 524
     {
525
-        $sql = '(' . $queryBuilder->getQuery()->getRawSql() . ')';
525
+        $sql = '('.$queryBuilder->getQuery()->getRawSql().')';
526 526
         if (is_string($alias) && 0 !== mb_strlen($alias)) {
527
-            $sql = $sql . ' as ' . $alias;
527
+            $sql = $sql.' as '.$alias;
528 528
         }
529 529
 
530 530
         return $queryBuilder->raw($sql);
@@ -541,12 +541,12 @@  discard block
 block discarded – undo
541 541
     private function doInsert(array $data, string $type)
542 542
     {
543 543
         $eventResult = $this->fireEvents('before-insert');
544
-        if (!is_null($eventResult)) {
544
+        if ( ! is_null($eventResult)) {
545 545
             return $eventResult;
546 546
         }
547 547
 
548 548
         // If first value is not an array () not a batch insert)
549
-        if (!is_array(current($data))) {
549
+        if ( ! is_array(current($data))) {
550 550
             $queryObject = $this->getQuery($type, $data);
551 551
 
552 552
             list($preparedQuery, $executionTime) = $this->statement($queryObject->getSql(), $queryObject->getBindings());
@@ -616,7 +616,7 @@  discard block
 block discarded – undo
616 616
     public function update($data)
617 617
     {
618 618
         $eventResult = $this->fireEvents('before-update');
619
-        if (!is_null($eventResult)) {
619
+        if ( ! is_null($eventResult)) {
620 620
             return $eventResult;
621 621
         }
622 622
         $queryObject                         = $this->getQuery('update', $data);
@@ -662,7 +662,7 @@  discard block
 block discarded – undo
662 662
     public function delete()
663 663
     {
664 664
         $eventResult = $this->fireEvents('before-delete');
665
-        if (!is_null($eventResult)) {
665
+        if ( ! is_null($eventResult)) {
666 666
             return $eventResult;
667 667
         }
668 668
 
@@ -684,7 +684,7 @@  discard block
 block discarded – undo
684 684
      */
685 685
     public function table(...$tables)
686 686
     {
687
-        $instance =  $this->constructCurrentBuilderClass($this->connection);
687
+        $instance = $this->constructCurrentBuilderClass($this->connection);
688 688
         $this->setFetchMode($this->getFetchMode(), $this->hydratorConstructorArgs);
689 689
         $tables = $this->addTablePrefix($tables, false);
690 690
         $instance->addStatement('tables', $tables);
@@ -712,7 +712,7 @@  discard block
 block discarded – undo
712 712
      */
713 713
     public function select($fields): self
714 714
     {
715
-        if (!is_array($fields)) {
715
+        if ( ! is_array($fields)) {
716 716
             $fields = func_get_args();
717 717
         }
718 718
 
@@ -773,7 +773,7 @@  discard block
 block discarded – undo
773 773
      */
774 774
     public function orderBy($fields, string $defaultDirection = 'ASC'): self
775 775
     {
776
-        if (!is_array($fields)) {
776
+        if ( ! is_array($fields)) {
777 777
             $fields = [$fields];
778 778
         }
779 779
 
@@ -789,7 +789,7 @@  discard block
 block discarded – undo
789 789
                 $field = $this->jsonHandler->extractAndUnquoteFromJsonSelector($field);
790 790
             }
791 791
 
792
-            if (!$field instanceof Raw) {
792
+            if ( ! $field instanceof Raw) {
793 793
                 $field = $this->addTablePrefix($field);
794 794
             }
795 795
             $this->statements['orderBys'][] = compact('field', 'type');
@@ -1141,7 +1141,7 @@  discard block
 block discarded – undo
1141 1141
             throw new Exception('Key used for whereNull condition must be a string or raw exrpession.', 1);
1142 1142
         }
1143 1143
 
1144
-        return $this->{$operator . 'Where'}($this->raw("{$key} IS{$prefix} NULL"));
1144
+        return $this->{$operator.'Where'}($this->raw("{$key} IS{$prefix} NULL"));
1145 1145
     }
1146 1146
 
1147 1147
 
@@ -1238,8 +1238,8 @@  discard block
 block discarded – undo
1238 1238
             $value = $this->jsonHandler->extractAndUnquoteFromJsonSelector($value);
1239 1239
         }
1240 1240
 
1241
-        if (!$key instanceof Closure) {
1242
-            $key = function ($joinBuilder) use ($key, $operator, $value) {
1241
+        if ( ! $key instanceof Closure) {
1242
+            $key = function($joinBuilder) use ($key, $operator, $value) {
1243 1243
                 $joinBuilder->on($key, $operator, $value);
1244 1244
             };
1245 1245
         }
@@ -1332,7 +1332,7 @@  discard block
 block discarded – undo
1332 1332
      */
1333 1333
     public function joinUsing(string $table, string $key, string $type = 'INNER'): self
1334 1334
     {
1335
-        if (!array_key_exists('tables', $this->statements) || count($this->statements['tables']) !== 1) {
1335
+        if ( ! array_key_exists('tables', $this->statements) || count($this->statements['tables']) !== 1) {
1336 1336
             throw new Exception("JoinUsing can only be used with a single table set as the base of the query", 1);
1337 1337
         }
1338 1338
         $baseTable = end($this->statements['tables']);
@@ -1423,11 +1423,11 @@  discard block
 block discarded – undo
1423 1423
      */
1424 1424
     protected function addStatement($key, $value)
1425 1425
     {
1426
-        if (!is_array($value)) {
1426
+        if ( ! is_array($value)) {
1427 1427
             $value = [$value];
1428 1428
         }
1429 1429
 
1430
-        if (!array_key_exists($key, $this->statements)) {
1430
+        if ( ! array_key_exists($key, $this->statements)) {
1431 1431
             $this->statements[$key] = $value;
1432 1432
         } else {
1433 1433
             $this->statements[$key] = array_merge($this->statements[$key], $value);
Please login to merge, or discard this patch.
src/JSON/JsonSelectorHandler.php 2 patches
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -9,84 +9,84 @@
 block discarded – undo
9 9
 
10 10
 class JsonSelectorHandler implements HasConnection
11 11
 {
12
-    use TablePrefixer;
12
+	use TablePrefixer;
13 13
 
14
-    /** @var Connection */
15
-    protected $connection;
14
+	/** @var Connection */
15
+	protected $connection;
16 16
 
17
-    public function __construct(Connection $connection)
18
-    {
19
-        $this->connection = $connection;
20
-    }
17
+	public function __construct(Connection $connection)
18
+	{
19
+		$this->connection = $connection;
20
+	}
21 21
 
22
-    /**
23
-     * Returns the current connection instance.
24
-     *
25
-     * @return connection
26
-     */
27
-    public function getConnection(): Connection
28
-    {
29
-        return $this->connection;
30
-    }
22
+	/**
23
+	 * Returns the current connection instance.
24
+	 *
25
+	 * @return connection
26
+	 */
27
+	public function getConnection(): Connection
28
+	{
29
+		return $this->connection;
30
+	}
31 31
 
32
-    /**
33
-     * Checks if the passed expression is for JSON
34
-     * this->denotes->json
35
-     *
36
-     * @param string $expression
37
-     * @return bool
38
-     */
39
-    public function isJsonSelector($expression): bool
40
-    {
41
-        return is_string($expression)
42
-        && 2 <= count(array_diff(explode('->', $expression), array("")));
43
-    }
32
+	/**
33
+	 * Checks if the passed expression is for JSON
34
+	 * this->denotes->json
35
+	 *
36
+	 * @param string $expression
37
+	 * @return bool
38
+	 */
39
+	public function isJsonSelector($expression): bool
40
+	{
41
+		return is_string($expression)
42
+		&& 2 <= count(array_diff(explode('->', $expression), array("")));
43
+	}
44 44
 
45
-    /**
46
-    * Gets the column name form a potential array
47
-    *
48
-    * @param string $expression
49
-    * @return string
50
-    * @throws Exception If invalid JSON Selector string passed.
51
-    */
52
-    public function getColumn(string $expression): string
53
-    {
54
-        return $this->toJsonSelector($expression)->getColumn();
55
-    }
45
+	/**
46
+	 * Gets the column name form a potential array
47
+	 *
48
+	 * @param string $expression
49
+	 * @return string
50
+	 * @throws Exception If invalid JSON Selector string passed.
51
+	 */
52
+	public function getColumn(string $expression): string
53
+	{
54
+		return $this->toJsonSelector($expression)->getColumn();
55
+	}
56 56
 
57
-    /**
58
-     * Gets all JSON object keys while removing the column name.
59
-     *
60
-     * @param string $expression
61
-     * @return string[]
62
-     * @throws Exception If invalid JSON Selector string passed.
63
-     */
64
-    public function getNodes(string $expression): array
65
-    {
66
-        return $this->toJsonSelector($expression)->getNodes();
67
-    }
57
+	/**
58
+	 * Gets all JSON object keys while removing the column name.
59
+	 *
60
+	 * @param string $expression
61
+	 * @return string[]
62
+	 * @throws Exception If invalid JSON Selector string passed.
63
+	 */
64
+	public function getNodes(string $expression): array
65
+	{
66
+		return $this->toJsonSelector($expression)->getNodes();
67
+	}
68 68
 
69
-    /**
70
-     * Casts a valid JSON selector to a JsonSelector object.
71
-     *
72
-     * @param string $expression
73
-     * @return JsonSelector
74
-     * @throws Exception If invalid JSON Selector string passed.
75
-     */
76
-    public function toJsonSelector(string $expression): JsonSelector
77
-    {
78
-        if (! $this->isJsonSelector($expression)) {
79
-            throw new Exception('JSON expression must contain at least 2 values, the table column and at least 1 node.', 1);
80
-        }
69
+	/**
70
+	 * Casts a valid JSON selector to a JsonSelector object.
71
+	 *
72
+	 * @param string $expression
73
+	 * @return JsonSelector
74
+	 * @throws Exception If invalid JSON Selector string passed.
75
+	 */
76
+	public function toJsonSelector(string $expression): JsonSelector
77
+	{
78
+		if (! $this->isJsonSelector($expression)) {
79
+			throw new Exception('JSON expression must contain at least 2 values, the table column and at least 1 node.', 1);
80
+		}
81 81
 
82
-        /** @var string[] Check done above. */
83
-        $parts = array_diff(explode('->', $expression), array(""));
82
+		/** @var string[] Check done above. */
83
+		$parts = array_diff(explode('->', $expression), array(""));
84 84
 
85
-        /** @var string */
86
-        $column = array_shift($parts);
87
-        /** @var string[] */
88
-        $nodes = $parts;
85
+		/** @var string */
86
+		$column = array_shift($parts);
87
+		/** @var string[] */
88
+		$nodes = $parts;
89 89
 
90
-        return new JsonSelector($column, $nodes);
91
-    }
90
+		return new JsonSelector($column, $nodes);
91
+	}
92 92
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -75,7 +75,7 @@
 block discarded – undo
75 75
      */
76 76
     public function toJsonSelector(string $expression): JsonSelector
77 77
     {
78
-        if (! $this->isJsonSelector($expression)) {
78
+        if ( ! $this->isJsonSelector($expression)) {
79 79
             throw new Exception('JSON expression must contain at least 2 values, the table column and at least 1 node.', 1);
80 80
         }
81 81
 
Please login to merge, or discard this patch.
src/JSON/JsonExpressionFactory.php 2 patches
Indentation   +51 added lines, -51 removed lines patch added patch discarded remove patch
@@ -9,65 +9,65 @@
 block discarded – undo
9 9
 
10 10
 class JsonExpressionFactory
11 11
 {
12
-    use TablePrefixer;
12
+	use TablePrefixer;
13 13
 
14
-    /** @var Connection */
15
-    protected $connection;
14
+	/** @var Connection */
15
+	protected $connection;
16 16
 
17
-    public function __construct(Connection $connection)
18
-    {
19
-        $this->connection = $connection;
20
-    }
17
+	public function __construct(Connection $connection)
18
+	{
19
+		$this->connection = $connection;
20
+	}
21 21
 
22
-    /**
23
-     * Returns the current connection instance.
24
-     *
25
-     * @return connection
26
-     */
27
-    public function getConnection(): Connection
28
-    {
29
-        return $this->connection;
30
-    }
22
+	/**
23
+	 * Returns the current connection instance.
24
+	 *
25
+	 * @return connection
26
+	 */
27
+	public function getConnection(): Connection
28
+	{
29
+		return $this->connection;
30
+	}
31 31
 
32
-    /**
33
-     * Normalises the values passed as nodes
34
-     *
35
-     * @param mixed $nodes
36
-     * @return string
37
-     */
38
-    protected function normaliseNodes($nodes): string
39
-    {
40
-        // If its not an array, cast.
41
-        if (!is_array($nodes)) {
42
-            $nodes = [$nodes];
43
-        }
32
+	/**
33
+	 * Normalises the values passed as nodes
34
+	 *
35
+	 * @param mixed $nodes
36
+	 * @return string
37
+	 */
38
+	protected function normaliseNodes($nodes): string
39
+	{
40
+		// If its not an array, cast.
41
+		if (!is_array($nodes)) {
42
+			$nodes = [$nodes];
43
+		}
44 44
 
45
-        // Remove all none string.
46
-        $nodes = array_filter($nodes, function ($node): bool {
47
-            return is_string($node);
48
-        });
45
+		// Remove all none string.
46
+		$nodes = array_filter($nodes, function ($node): bool {
47
+			return is_string($node);
48
+		});
49 49
 
50
-        // If we have no nodes, throw.
51
-        if (count($nodes) === 0) {
52
-            throw new Exception("Only strings values may be passed as nodes.");
53
-        }
50
+		// If we have no nodes, throw.
51
+		if (count($nodes) === 0) {
52
+			throw new Exception("Only strings values may be passed as nodes.");
53
+		}
54 54
 
55
-        return \implode('.', $nodes);
56
-    }
55
+		return \implode('.', $nodes);
56
+	}
57 57
 
58
-    /**
59
-     * @param string          $column  The database column which holds the JSON value
60
-     * @param string|string[] $nodes   The json key/index to search
61
-     * @return \Pixie\QueryBuilder\Raw
62
-     */
63
-    public function extractAndUnquote(string $column, $nodes): Raw
64
-    {
65
-        // Normalise nodes.
66
-        $nodes = $this->normaliseNodes($nodes);
58
+	/**
59
+	 * @param string          $column  The database column which holds the JSON value
60
+	 * @param string|string[] $nodes   The json key/index to search
61
+	 * @return \Pixie\QueryBuilder\Raw
62
+	 */
63
+	public function extractAndUnquote(string $column, $nodes): Raw
64
+	{
65
+		// Normalise nodes.
66
+		$nodes = $this->normaliseNodes($nodes);
67 67
 
68
-        // Add any possible prefixes to the key
69
-        $column = $this->addTablePrefix($column, true);
68
+		// Add any possible prefixes to the key
69
+		$column = $this->addTablePrefix($column, true);
70 70
 
71
-        return new Raw("JSON_UNQUOTE(JSON_EXTRACT({$column}, \"$.{$nodes}\"))");
72
-    }
71
+		return new Raw("JSON_UNQUOTE(JSON_EXTRACT({$column}, \"$.{$nodes}\"))");
72
+	}
73 73
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -38,12 +38,12 @@
 block discarded – undo
38 38
     protected function normaliseNodes($nodes): string
39 39
     {
40 40
         // If its not an array, cast.
41
-        if (!is_array($nodes)) {
41
+        if ( ! is_array($nodes)) {
42 42
             $nodes = [$nodes];
43 43
         }
44 44
 
45 45
         // Remove all none string.
46
-        $nodes = array_filter($nodes, function ($node): bool {
46
+        $nodes = array_filter($nodes, function($node): bool {
47 47
             return is_string($node);
48 48
         });
49 49
 
Please login to merge, or discard this patch.
src/loader.php 2 patches
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -27,66 +27,66 @@
 block discarded – undo
27 27
 
28 28
 // Generated code start...
29 29
 if (!trait_exists(Pixie\QueryBuilder\TablePrefixer::class)) {
30
-    require_once __DIR__ . '/QueryBuilder/TablePrefixer.php';
30
+	require_once __DIR__ . '/QueryBuilder/TablePrefixer.php';
31 31
 }
32 32
 if (!interface_exists(Pixie\HasConnection::class)) {
33
-    require_once __DIR__ . '/HasConnection.php';
33
+	require_once __DIR__ . '/HasConnection.php';
34 34
 }
35 35
 if (!class_exists(Pixie\Binding::class)) {
36
-    require_once __DIR__ . '/Binding.php';
36
+	require_once __DIR__ . '/Binding.php';
37 37
 }
38 38
 if (!class_exists(Pixie\QueryBuilder\QueryBuilderHandler::class)) {
39
-    require_once __DIR__ . '/QueryBuilder/QueryBuilderHandler.php';
39
+	require_once __DIR__ . '/QueryBuilder/QueryBuilderHandler.php';
40 40
 }
41 41
 if (!class_exists(Pixie\QueryBuilder\Transaction::class)) {
42
-    require_once __DIR__ . '/QueryBuilder/Transaction.php';
42
+	require_once __DIR__ . '/QueryBuilder/Transaction.php';
43 43
 }
44 44
 if (!class_exists(Pixie\QueryBuilder\Raw::class)) {
45
-    require_once __DIR__ . '/QueryBuilder/Raw.php';
45
+	require_once __DIR__ . '/QueryBuilder/Raw.php';
46 46
 }
47 47
 if (!class_exists(Pixie\JSON\JsonHandler::class)) {
48
-    require_once __DIR__ . '/JSON/JsonHandler.php';
48
+	require_once __DIR__ . '/JSON/JsonHandler.php';
49 49
 }
50 50
 if (!class_exists(Pixie\EventHandler::class)) {
51
-    require_once __DIR__ . '/EventHandler.php';
51
+	require_once __DIR__ . '/EventHandler.php';
52 52
 }
53 53
 if (!class_exists(Pixie\QueryBuilder\QueryObject::class)) {
54
-    require_once __DIR__ . '/QueryBuilder/QueryObject.php';
54
+	require_once __DIR__ . '/QueryBuilder/QueryObject.php';
55 55
 }
56 56
 if (!class_exists(Pixie\QueryBuilder\JoinBuilder::class)) {
57
-    require_once __DIR__ . '/QueryBuilder/JoinBuilder.php';
57
+	require_once __DIR__ . '/QueryBuilder/JoinBuilder.php';
58 58
 }
59 59
 if (!class_exists(Pixie\QueryBuilder\NestedCriteria::class)) {
60
-    require_once __DIR__ . '/QueryBuilder/NestedCriteria.php';
60
+	require_once __DIR__ . '/QueryBuilder/NestedCriteria.php';
61 61
 }
62 62
 if (!class_exists(Pixie\JSON\JsonSelectorHandler::class)) {
63
-    require_once __DIR__ . '/JSON/JsonSelectorHandler.php';
63
+	require_once __DIR__ . '/JSON/JsonSelectorHandler.php';
64 64
 }
65 65
 if (!class_exists(Pixie\JSON\JsonSelector::class)) {
66
-    require_once __DIR__ . '/JSON/JsonSelector.php';
66
+	require_once __DIR__ . '/JSON/JsonSelector.php';
67 67
 }
68 68
 if (!class_exists(Pixie\Connection::class)) {
69
-    require_once __DIR__ . '/Connection.php';
69
+	require_once __DIR__ . '/Connection.php';
70 70
 }
71 71
 if (!class_exists(Pixie\QueryBuilder\JsonQueryBuilder::class)) {
72
-    require_once __DIR__ . '/QueryBuilder/JsonQueryBuilder.php';
72
+	require_once __DIR__ . '/QueryBuilder/JsonQueryBuilder.php';
73 73
 }
74 74
 if (!class_exists(Pixie\Hydration\Hydrator::class)) {
75
-    require_once __DIR__ . '/Hydration/Hydrator.php';
75
+	require_once __DIR__ . '/Hydration/Hydrator.php';
76 76
 }
77 77
 if (!class_exists(Pixie\QueryBuilder\WPDBAdapter::class)) {
78
-    require_once __DIR__ . '/QueryBuilder/WPDBAdapter.php';
78
+	require_once __DIR__ . '/QueryBuilder/WPDBAdapter.php';
79 79
 }
80 80
 if (!class_exists(Pixie\Exception::class)) {
81
-    require_once __DIR__ . '/Exception.php';
81
+	require_once __DIR__ . '/Exception.php';
82 82
 }
83 83
 if (!class_exists(Pixie\QueryBuilder\TransactionHaltException::class)) {
84
-    require_once __DIR__ . '/QueryBuilder/TransactionHaltException.php';
84
+	require_once __DIR__ . '/QueryBuilder/TransactionHaltException.php';
85 85
 }
86 86
 if (!class_exists(Pixie\AliasFacade::class)) {
87
-    require_once __DIR__ . '/AliasFacade.php';
87
+	require_once __DIR__ . '/AliasFacade.php';
88 88
 }
89 89
 if (!class_exists(Pixie\JSON\JsonExpressionFactory::class)) {
90
-    require_once __DIR__ . '/JSON/JsonExpressionFactory.php';
90
+	require_once __DIR__ . '/JSON/JsonExpressionFactory.php';
91 91
 }
92 92
 // CREATED ON Fri 4th February 2022
Please login to merge, or discard this patch.
Spacing   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -26,67 +26,67 @@
 block discarded – undo
26 26
  */
27 27
 
28 28
 // Generated code start...
29
-if (!trait_exists(Pixie\QueryBuilder\TablePrefixer::class)) {
30
-    require_once __DIR__ . '/QueryBuilder/TablePrefixer.php';
29
+if ( ! trait_exists(Pixie\QueryBuilder\TablePrefixer::class)) {
30
+    require_once __DIR__.'/QueryBuilder/TablePrefixer.php';
31 31
 }
32
-if (!interface_exists(Pixie\HasConnection::class)) {
33
-    require_once __DIR__ . '/HasConnection.php';
32
+if ( ! interface_exists(Pixie\HasConnection::class)) {
33
+    require_once __DIR__.'/HasConnection.php';
34 34
 }
35
-if (!class_exists(Pixie\Binding::class)) {
36
-    require_once __DIR__ . '/Binding.php';
35
+if ( ! class_exists(Pixie\Binding::class)) {
36
+    require_once __DIR__.'/Binding.php';
37 37
 }
38
-if (!class_exists(Pixie\QueryBuilder\QueryBuilderHandler::class)) {
39
-    require_once __DIR__ . '/QueryBuilder/QueryBuilderHandler.php';
38
+if ( ! class_exists(Pixie\QueryBuilder\QueryBuilderHandler::class)) {
39
+    require_once __DIR__.'/QueryBuilder/QueryBuilderHandler.php';
40 40
 }
41
-if (!class_exists(Pixie\QueryBuilder\Transaction::class)) {
42
-    require_once __DIR__ . '/QueryBuilder/Transaction.php';
41
+if ( ! class_exists(Pixie\QueryBuilder\Transaction::class)) {
42
+    require_once __DIR__.'/QueryBuilder/Transaction.php';
43 43
 }
44
-if (!class_exists(Pixie\QueryBuilder\Raw::class)) {
45
-    require_once __DIR__ . '/QueryBuilder/Raw.php';
44
+if ( ! class_exists(Pixie\QueryBuilder\Raw::class)) {
45
+    require_once __DIR__.'/QueryBuilder/Raw.php';
46 46
 }
47
-if (!class_exists(Pixie\JSON\JsonHandler::class)) {
48
-    require_once __DIR__ . '/JSON/JsonHandler.php';
47
+if ( ! class_exists(Pixie\JSON\JsonHandler::class)) {
48
+    require_once __DIR__.'/JSON/JsonHandler.php';
49 49
 }
50
-if (!class_exists(Pixie\EventHandler::class)) {
51
-    require_once __DIR__ . '/EventHandler.php';
50
+if ( ! class_exists(Pixie\EventHandler::class)) {
51
+    require_once __DIR__.'/EventHandler.php';
52 52
 }
53
-if (!class_exists(Pixie\QueryBuilder\QueryObject::class)) {
54
-    require_once __DIR__ . '/QueryBuilder/QueryObject.php';
53
+if ( ! class_exists(Pixie\QueryBuilder\QueryObject::class)) {
54
+    require_once __DIR__.'/QueryBuilder/QueryObject.php';
55 55
 }
56
-if (!class_exists(Pixie\QueryBuilder\JoinBuilder::class)) {
57
-    require_once __DIR__ . '/QueryBuilder/JoinBuilder.php';
56
+if ( ! class_exists(Pixie\QueryBuilder\JoinBuilder::class)) {
57
+    require_once __DIR__.'/QueryBuilder/JoinBuilder.php';
58 58
 }
59
-if (!class_exists(Pixie\QueryBuilder\NestedCriteria::class)) {
60
-    require_once __DIR__ . '/QueryBuilder/NestedCriteria.php';
59
+if ( ! class_exists(Pixie\QueryBuilder\NestedCriteria::class)) {
60
+    require_once __DIR__.'/QueryBuilder/NestedCriteria.php';
61 61
 }
62
-if (!class_exists(Pixie\JSON\JsonSelectorHandler::class)) {
63
-    require_once __DIR__ . '/JSON/JsonSelectorHandler.php';
62
+if ( ! class_exists(Pixie\JSON\JsonSelectorHandler::class)) {
63
+    require_once __DIR__.'/JSON/JsonSelectorHandler.php';
64 64
 }
65
-if (!class_exists(Pixie\JSON\JsonSelector::class)) {
66
-    require_once __DIR__ . '/JSON/JsonSelector.php';
65
+if ( ! class_exists(Pixie\JSON\JsonSelector::class)) {
66
+    require_once __DIR__.'/JSON/JsonSelector.php';
67 67
 }
68
-if (!class_exists(Pixie\Connection::class)) {
69
-    require_once __DIR__ . '/Connection.php';
68
+if ( ! class_exists(Pixie\Connection::class)) {
69
+    require_once __DIR__.'/Connection.php';
70 70
 }
71
-if (!class_exists(Pixie\QueryBuilder\JsonQueryBuilder::class)) {
72
-    require_once __DIR__ . '/QueryBuilder/JsonQueryBuilder.php';
71
+if ( ! class_exists(Pixie\QueryBuilder\JsonQueryBuilder::class)) {
72
+    require_once __DIR__.'/QueryBuilder/JsonQueryBuilder.php';
73 73
 }
74
-if (!class_exists(Pixie\Hydration\Hydrator::class)) {
75
-    require_once __DIR__ . '/Hydration/Hydrator.php';
74
+if ( ! class_exists(Pixie\Hydration\Hydrator::class)) {
75
+    require_once __DIR__.'/Hydration/Hydrator.php';
76 76
 }
77
-if (!class_exists(Pixie\QueryBuilder\WPDBAdapter::class)) {
78
-    require_once __DIR__ . '/QueryBuilder/WPDBAdapter.php';
77
+if ( ! class_exists(Pixie\QueryBuilder\WPDBAdapter::class)) {
78
+    require_once __DIR__.'/QueryBuilder/WPDBAdapter.php';
79 79
 }
80
-if (!class_exists(Pixie\Exception::class)) {
81
-    require_once __DIR__ . '/Exception.php';
80
+if ( ! class_exists(Pixie\Exception::class)) {
81
+    require_once __DIR__.'/Exception.php';
82 82
 }
83
-if (!class_exists(Pixie\QueryBuilder\TransactionHaltException::class)) {
84
-    require_once __DIR__ . '/QueryBuilder/TransactionHaltException.php';
83
+if ( ! class_exists(Pixie\QueryBuilder\TransactionHaltException::class)) {
84
+    require_once __DIR__.'/QueryBuilder/TransactionHaltException.php';
85 85
 }
86
-if (!class_exists(Pixie\AliasFacade::class)) {
87
-    require_once __DIR__ . '/AliasFacade.php';
86
+if ( ! class_exists(Pixie\AliasFacade::class)) {
87
+    require_once __DIR__.'/AliasFacade.php';
88 88
 }
89
-if (!class_exists(Pixie\JSON\JsonExpressionFactory::class)) {
90
-    require_once __DIR__ . '/JSON/JsonExpressionFactory.php';
89
+if ( ! class_exists(Pixie\JSON\JsonExpressionFactory::class)) {
90
+    require_once __DIR__.'/JSON/JsonExpressionFactory.php';
91 91
 }
92 92
 // CREATED ON Fri 4th February 2022
Please login to merge, or discard this patch.
src/Event.php 1 patch
Indentation   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -27,13 +27,13 @@
 block discarded – undo
27 27
 
28 28
 class Event
29 29
 {
30
-    /** Events */
31
-    public const BEFORE_SELECT = 'before-select';
32
-    public const AFTER_SELECT = 'after-select';
33
-    public const BEFORE_INSERT = 'before-insert';
34
-    public const AFTER_INSERT = 'after-insert';
35
-    public const BEFORE_UPDATE = 'before-update';
36
-    public const AFTER_UPDATE = 'after-update';
37
-    public const BEFORE_DELETE = 'before-delete';
38
-    public const AFTER_DELETE = 'after-delete';
30
+	/** Events */
31
+	public const BEFORE_SELECT = 'before-select';
32
+	public const AFTER_SELECT = 'after-select';
33
+	public const BEFORE_INSERT = 'before-insert';
34
+	public const AFTER_INSERT = 'after-insert';
35
+	public const BEFORE_UPDATE = 'before-update';
36
+	public const AFTER_UPDATE = 'after-update';
37
+	public const BEFORE_DELETE = 'before-delete';
38
+	public const AFTER_DELETE = 'after-delete';
39 39
 }
Please login to merge, or discard this patch.