PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.0.5
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.0.5
5.12.1 5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Db / Schema / Mysql.php
matomo / app / core / Db / Schema Last commit date
Mysql.php 6 years ago
Mysql.php
591 lines
1 <?php
2 /**
3 * Piwik - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 *
8 */
9 namespace Piwik\Db\Schema;
10
11 use Exception;
12 use Piwik\Common;
13 use Piwik\Concurrency\Lock;
14 use Piwik\Date;
15 use Piwik\Db\SchemaInterface;
16 use Piwik\Db;
17 use Piwik\DbHelper;
18 use Piwik\Option;
19 use Piwik\Plugins\Installation\Installation;
20 use Piwik\Version;
21
22 /**
23 * MySQL schema
24 */
25 class Mysql implements SchemaInterface
26 {
27 const OPTION_NAME_MATOMO_INSTALL_VERSION = 'install_version';
28 const MAX_TABLE_NAME_LENGTH = 64;
29
30 private $tablesInstalled = null;
31
32 /**
33 * Get the SQL to create Piwik tables
34 *
35 * @return array array of strings containing SQL
36 */
37 public function getTablesCreateSql()
38 {
39 $engine = $this->getTableEngine();
40 $prefixTables = $this->getTablePrefix();
41
42 $tables = array(
43 'user' => "CREATE TABLE {$prefixTables}user (
44 login VARCHAR(100) NOT NULL,
45 password VARCHAR(255) NOT NULL,
46 alias VARCHAR(45) NOT NULL,
47 email VARCHAR(100) NOT NULL,
48 twofactor_secret VARCHAR(40) NOT NULL DEFAULT '',
49 token_auth CHAR(32) NOT NULL,
50 superuser_access TINYINT(2) unsigned NOT NULL DEFAULT '0',
51 date_registered TIMESTAMP NULL,
52 ts_password_modified TIMESTAMP NULL,
53 PRIMARY KEY(login),
54 UNIQUE KEY uniq_keytoken(token_auth)
55 ) ENGINE=$engine DEFAULT CHARSET=utf8
56 ",
57
58 'twofactor_recovery_code' => "CREATE TABLE {$prefixTables}twofactor_recovery_code (
59 idrecoverycode BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
60 login VARCHAR(100) NOT NULL,
61 recovery_code VARCHAR(40) NOT NULL,
62 PRIMARY KEY(idrecoverycode)
63 ) ENGINE=$engine DEFAULT CHARSET=utf8
64 ",
65
66 'access' => "CREATE TABLE {$prefixTables}access (
67 idaccess INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
68 login VARCHAR(100) NOT NULL,
69 idsite INTEGER UNSIGNED NOT NULL,
70 access VARCHAR(50) NULL,
71 PRIMARY KEY(idaccess),
72 INDEX index_loginidsite (login, idsite)
73 ) ENGINE=$engine DEFAULT CHARSET=utf8
74 ",
75
76 'site' => "CREATE TABLE {$prefixTables}site (
77 idsite INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
78 name VARCHAR(90) NOT NULL,
79 main_url VARCHAR(255) NOT NULL,
80 ts_created TIMESTAMP NULL,
81 ecommerce TINYINT DEFAULT 0,
82 sitesearch TINYINT DEFAULT 1,
83 sitesearch_keyword_parameters TEXT NOT NULL,
84 sitesearch_category_parameters TEXT NOT NULL,
85 timezone VARCHAR( 50 ) NOT NULL,
86 currency CHAR( 3 ) NOT NULL,
87 exclude_unknown_urls TINYINT(1) DEFAULT 0,
88 excluded_ips TEXT NOT NULL,
89 excluded_parameters TEXT NOT NULL,
90 excluded_user_agents TEXT NOT NULL,
91 `group` VARCHAR(250) NOT NULL,
92 `type` VARCHAR(255) NOT NULL,
93 keep_url_fragment TINYINT NOT NULL DEFAULT 0,
94 creator_login VARCHAR(100) NULL,
95 PRIMARY KEY(idsite)
96 ) ENGINE=$engine DEFAULT CHARSET=utf8
97 ",
98
99 'plugin_setting' => "CREATE TABLE {$prefixTables}plugin_setting (
100 `plugin_name` VARCHAR(60) NOT NULL,
101 `setting_name` VARCHAR(255) NOT NULL,
102 `setting_value` LONGTEXT NOT NULL,
103 `json_encoded` TINYINT UNSIGNED NOT NULL DEFAULT 0,
104 `user_login` VARCHAR(100) NOT NULL DEFAULT '',
105 `idplugin_setting` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
106 PRIMARY KEY (idplugin_setting),
107 INDEX(plugin_name, user_login)
108 ) ENGINE=$engine DEFAULT CHARSET=utf8
109 ",
110
111 'site_setting' => "CREATE TABLE {$prefixTables}site_setting (
112 idsite INTEGER(10) UNSIGNED NOT NULL,
113 `plugin_name` VARCHAR(60) NOT NULL,
114 `setting_name` VARCHAR(255) NOT NULL,
115 `setting_value` LONGTEXT NOT NULL,
116 `json_encoded` TINYINT UNSIGNED NOT NULL DEFAULT 0,
117 `idsite_setting` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
118 PRIMARY KEY (idsite_setting),
119 INDEX(idsite, plugin_name)
120 ) ENGINE=$engine DEFAULT CHARSET=utf8
121 ",
122
123 'site_url' => "CREATE TABLE {$prefixTables}site_url (
124 idsite INTEGER(10) UNSIGNED NOT NULL,
125 url VARCHAR(255) NOT NULL,
126 PRIMARY KEY(idsite, url)
127 ) ENGINE=$engine DEFAULT CHARSET=utf8
128 ",
129
130 'goal' => "CREATE TABLE `{$prefixTables}goal` (
131 `idsite` int(11) NOT NULL,
132 `idgoal` int(11) NOT NULL,
133 `name` varchar(50) NOT NULL,
134 `description` varchar(255) NOT NULL DEFAULT '',
135 `match_attribute` varchar(20) NOT NULL,
136 `pattern` varchar(255) NOT NULL,
137 `pattern_type` varchar(25) NOT NULL,
138 `case_sensitive` tinyint(4) NOT NULL,
139 `allow_multiple` tinyint(4) NOT NULL,
140 `revenue` float NOT NULL,
141 `deleted` tinyint(4) NOT NULL default '0',
142 `event_value_as_revenue` tinyint(4) NOT NULL default '0',
143 PRIMARY KEY (`idsite`,`idgoal`)
144 ) ENGINE=$engine DEFAULT CHARSET=utf8
145 ",
146
147 'logger_message' => "CREATE TABLE {$prefixTables}logger_message (
148 idlogger_message INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
149 tag VARCHAR(50) NULL,
150 timestamp TIMESTAMP NULL,
151 level VARCHAR(16) NULL,
152 message TEXT NULL,
153 PRIMARY KEY(idlogger_message)
154 ) ENGINE=$engine DEFAULT CHARSET=utf8
155 ",
156
157 'log_action' => "CREATE TABLE {$prefixTables}log_action (
158 idaction INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
159 name VARCHAR(4096),
160 hash INTEGER(10) UNSIGNED NOT NULL,
161 type TINYINT UNSIGNED NULL,
162 url_prefix TINYINT(2) NULL,
163 PRIMARY KEY(idaction),
164 INDEX index_type_hash (type, hash)
165 ) ENGINE=$engine DEFAULT CHARSET=utf8
166 ",
167
168 'log_visit' => "CREATE TABLE {$prefixTables}log_visit (
169 idvisit BIGINT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
170 idsite INTEGER(10) UNSIGNED NOT NULL,
171 idvisitor BINARY(8) NOT NULL,
172 visit_last_action_time DATETIME NOT NULL,
173 config_id BINARY(8) NOT NULL,
174 location_ip VARBINARY(16) NOT NULL,
175 PRIMARY KEY(idvisit),
176 INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time),
177 INDEX index_idsite_datetime (idsite, visit_last_action_time),
178 INDEX index_idsite_idvisitor (idsite, idvisitor)
179 ) ENGINE=$engine DEFAULT CHARSET=utf8
180 ",
181
182 'log_conversion_item' => "CREATE TABLE `{$prefixTables}log_conversion_item` (
183 idsite int(10) UNSIGNED NOT NULL,
184 idvisitor BINARY(8) NOT NULL,
185 server_time DATETIME NOT NULL,
186 idvisit BIGINT(10) UNSIGNED NOT NULL,
187 idorder varchar(100) NOT NULL,
188 idaction_sku INTEGER(10) UNSIGNED NOT NULL,
189 idaction_name INTEGER(10) UNSIGNED NOT NULL,
190 idaction_category INTEGER(10) UNSIGNED NOT NULL,
191 idaction_category2 INTEGER(10) UNSIGNED NOT NULL,
192 idaction_category3 INTEGER(10) UNSIGNED NOT NULL,
193 idaction_category4 INTEGER(10) UNSIGNED NOT NULL,
194 idaction_category5 INTEGER(10) UNSIGNED NOT NULL,
195 price FLOAT NOT NULL,
196 quantity INTEGER(10) UNSIGNED NOT NULL,
197 deleted TINYINT(1) UNSIGNED NOT NULL,
198 PRIMARY KEY(idvisit, idorder, idaction_sku),
199 INDEX index_idsite_servertime ( idsite, server_time )
200 ) ENGINE=$engine DEFAULT CHARSET=utf8
201 ",
202
203 'log_conversion' => "CREATE TABLE `{$prefixTables}log_conversion` (
204 idvisit BIGINT(10) unsigned NOT NULL,
205 idsite int(10) unsigned NOT NULL,
206 idvisitor BINARY(8) NOT NULL,
207 server_time datetime NOT NULL,
208 idaction_url INTEGER(10) UNSIGNED default NULL,
209 idlink_va BIGINT(10) UNSIGNED default NULL,
210 idgoal int(10) NOT NULL,
211 buster int unsigned NOT NULL,
212 idorder varchar(100) default NULL,
213 items SMALLINT UNSIGNED DEFAULT NULL,
214 url VARCHAR(4096) NOT NULL,
215 PRIMARY KEY (idvisit, idgoal, buster),
216 UNIQUE KEY unique_idsite_idorder (idsite, idorder),
217 INDEX index_idsite_datetime ( idsite, server_time )
218 ) ENGINE=$engine DEFAULT CHARSET=utf8
219 ",
220
221 'log_link_visit_action' => "CREATE TABLE {$prefixTables}log_link_visit_action (
222 idlink_va BIGINT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
223 idsite int(10) UNSIGNED NOT NULL,
224 idvisitor BINARY(8) NOT NULL,
225 idvisit BIGINT(10) UNSIGNED NOT NULL,
226 idaction_url_ref INTEGER(10) UNSIGNED NULL DEFAULT 0,
227 idaction_name_ref INTEGER(10) UNSIGNED NULL,
228 custom_float DOUBLE NULL DEFAULT NULL,
229 PRIMARY KEY(idlink_va),
230 INDEX index_idvisit(idvisit)
231 ) ENGINE=$engine DEFAULT CHARSET=utf8
232 ",
233
234 'log_profiling' => "CREATE TABLE {$prefixTables}log_profiling (
235 query TEXT NOT NULL,
236 count INTEGER UNSIGNED NULL,
237 sum_time_ms FLOAT NULL,
238 idprofiling BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
239 PRIMARY KEY (idprofiling),
240 UNIQUE KEY query(query(100))
241 ) ENGINE=$engine DEFAULT CHARSET=utf8
242 ",
243
244 'option' => "CREATE TABLE `{$prefixTables}option` (
245 option_name VARCHAR( 255 ) NOT NULL,
246 option_value LONGTEXT NOT NULL,
247 autoload TINYINT NOT NULL DEFAULT '1',
248 PRIMARY KEY ( option_name ),
249 INDEX autoload( autoload )
250 ) ENGINE=$engine DEFAULT CHARSET=utf8
251 ",
252
253 'session' => "CREATE TABLE {$prefixTables}session (
254 id VARCHAR( 255 ) NOT NULL,
255 modified INTEGER,
256 lifetime INTEGER,
257 data TEXT,
258 PRIMARY KEY ( id )
259 ) ENGINE=$engine DEFAULT CHARSET=utf8
260 ",
261
262 'archive_numeric' => "CREATE TABLE {$prefixTables}archive_numeric (
263 idarchive INTEGER UNSIGNED NOT NULL,
264 name VARCHAR(255) NOT NULL,
265 idsite INTEGER UNSIGNED NULL,
266 date1 DATE NULL,
267 date2 DATE NULL,
268 period TINYINT UNSIGNED NULL,
269 ts_archived DATETIME NULL,
270 value DOUBLE NULL,
271 PRIMARY KEY(idarchive, name),
272 INDEX index_idsite_dates_period(idsite, date1, date2, period, ts_archived),
273 INDEX index_period_archived(period, ts_archived)
274 ) ENGINE=$engine DEFAULT CHARSET=utf8
275 ",
276
277 'archive_blob' => "CREATE TABLE {$prefixTables}archive_blob (
278 idarchive INTEGER UNSIGNED NOT NULL,
279 name VARCHAR(255) NOT NULL,
280 idsite INTEGER UNSIGNED NULL,
281 date1 DATE NULL,
282 date2 DATE NULL,
283 period TINYINT UNSIGNED NULL,
284 ts_archived DATETIME NULL,
285 value MEDIUMBLOB NULL,
286 PRIMARY KEY(idarchive, name),
287 INDEX index_period_archived(period, ts_archived)
288 ) ENGINE=$engine DEFAULT CHARSET=utf8
289 ",
290
291 'sequence' => "CREATE TABLE {$prefixTables}sequence (
292 `name` VARCHAR(120) NOT NULL,
293 `value` BIGINT(20) UNSIGNED NOT NULL ,
294 PRIMARY KEY(`name`)
295 ) ENGINE=$engine DEFAULT CHARSET=utf8
296 ",
297
298 'brute_force_log' => "CREATE TABLE {$prefixTables}brute_force_log (
299 `id_brute_force_log` bigint(11) NOT NULL AUTO_INCREMENT,
300 `ip_address` VARCHAR(60) DEFAULT NULL,
301 `attempted_at` datetime NOT NULL,
302 INDEX index_ip_address(ip_address),
303 PRIMARY KEY(`id_brute_force_log`)
304 ) ENGINE=$engine DEFAULT CHARSET=utf8
305 ",
306
307 'tracking_failure' => "CREATE TABLE {$prefixTables}tracking_failure (
308 `idsite` BIGINT(20) UNSIGNED NOT NULL ,
309 `idfailure` SMALLINT UNSIGNED NOT NULL ,
310 `date_first_occurred` DATETIME NOT NULL ,
311 `request_url` MEDIUMTEXT NOT NULL ,
312 PRIMARY KEY(`idsite`, `idfailure`)
313 ) ENGINE=$engine DEFAULT CHARSET=utf8
314 ",
315 'locks' => "CREATE TABLE `{$prefixTables}locks` (
316 `key` VARCHAR(".Lock::MAX_KEY_LEN.") NOT NULL,
317 `value` VARCHAR(255) NULL DEFAULT NULL,
318 `expiry_time` BIGINT UNSIGNED DEFAULT 9999999999,
319 PRIMARY KEY (`key`)
320 ) ENGINE=$engine DEFAULT CHARSET=utf8
321 ",
322 );
323
324 return $tables;
325 }
326
327 /**
328 * Get the SQL to create a specific Piwik table
329 *
330 * @param string $tableName
331 * @throws Exception
332 * @return string SQL
333 */
334 public function getTableCreateSql($tableName)
335 {
336 $tables = DbHelper::getTablesCreateSql();
337
338 if (!isset($tables[$tableName])) {
339 throw new Exception("The table '$tableName' SQL creation code couldn't be found.");
340 }
341
342 return $tables[$tableName];
343 }
344
345 /**
346 * Names of all the prefixed tables in piwik
347 * Doesn't use the DB
348 *
349 * @return array Table names
350 */
351 public function getTablesNames()
352 {
353 $aTables = array_keys($this->getTablesCreateSql());
354 $prefixTables = $this->getTablePrefix();
355
356 $return = array();
357 foreach ($aTables as $table) {
358 $return[] = $prefixTables . $table;
359 }
360
361 return $return;
362 }
363
364 /**
365 * Get list of installed columns in a table
366 *
367 * @param string $tableName The name of a table.
368 *
369 * @return array Installed columns indexed by the column name.
370 */
371 public function getTableColumns($tableName)
372 {
373 $db = $this->getDb();
374
375 $allColumns = $db->fetchAll("SHOW COLUMNS FROM " . $tableName);
376
377 $fields = array();
378 foreach ($allColumns as $column) {
379 $fields[trim($column['Field'])] = $column;
380 }
381
382 return $fields;
383 }
384
385 /**
386 * Get list of tables installed
387 *
388 * @param bool $forceReload Invalidate cache
389 * @return array installed Tables
390 */
391 public function getTablesInstalled($forceReload = true)
392 {
393 if (is_null($this->tablesInstalled)
394 || $forceReload === true
395 ) {
396 $db = $this->getDb();
397 $prefixTables = $this->getTablePrefixEscaped();
398
399 $allTables = $this->getAllExistingTables($prefixTables);
400
401 // all the tables to be installed
402 $allMyTables = $this->getTablesNames();
403
404 // we get the intersection between all the tables in the DB and the tables to be installed
405 $tablesInstalled = array_intersect($allMyTables, $allTables);
406
407 // at this point we have the static list of core tables, but let's add the monthly archive tables
408 $allArchiveNumeric = $db->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "archive_numeric%'");
409 $allArchiveBlob = $db->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "archive_blob%'");
410
411 $allTablesReallyInstalled = array_merge($tablesInstalled, $allArchiveNumeric, $allArchiveBlob);
412
413 $this->tablesInstalled = $allTablesReallyInstalled;
414 }
415
416 return $this->tablesInstalled;
417 }
418
419 /**
420 * Checks whether any table exists
421 *
422 * @return bool True if tables exist; false otherwise
423 */
424 public function hasTables()
425 {
426 return count($this->getTablesInstalled()) != 0;
427 }
428
429 /**
430 * Create database
431 *
432 * @param string $dbName Name of the database to create
433 */
434 public function createDatabase($dbName = null)
435 {
436 if (is_null($dbName)) {
437 $dbName = $this->getDbName();
438 }
439
440 $dbName = str_replace('`', '', $dbName);
441
442 Db::exec("CREATE DATABASE IF NOT EXISTS `" . $dbName . "` DEFAULT CHARACTER SET utf8");
443 }
444
445 /**
446 * Creates a new table in the database.
447 *
448 * @param string $nameWithoutPrefix The name of the table without any piwik prefix.
449 * @param string $createDefinition The table create definition, see the "MySQL CREATE TABLE" specification for
450 * more information.
451 * @throws \Exception
452 */
453 public function createTable($nameWithoutPrefix, $createDefinition)
454 {
455 $statement = sprintf("CREATE TABLE IF NOT EXISTS `%s` ( %s ) ENGINE=%s DEFAULT CHARSET=utf8 ;",
456 Common::prefixTable($nameWithoutPrefix),
457 $createDefinition,
458 $this->getTableEngine());
459
460 try {
461 Db::exec($statement);
462 } catch (Exception $e) {
463 // mysql code error 1050:table already exists
464 // see bug #153 https://github.com/piwik/piwik/issues/153
465 if (!$this->getDb()->isErrNo($e, '1050')) {
466 throw $e;
467 }
468 }
469 }
470
471 /**
472 * Drop database
473 */
474 public function dropDatabase($dbName = null)
475 {
476 $dbName = $dbName ?: $this->getDbName();
477 $dbName = str_replace('`', '', $dbName);
478 Db::exec("DROP DATABASE IF EXISTS `" . $dbName . "`");
479 }
480
481 /**
482 * Create all tables
483 */
484 public function createTables()
485 {
486 $db = $this->getDb();
487 $prefixTables = $this->getTablePrefix();
488
489 $tablesAlreadyInstalled = $this->getTablesInstalled();
490 $tablesToCreate = $this->getTablesCreateSql();
491 unset($tablesToCreate['archive_blob']);
492 unset($tablesToCreate['archive_numeric']);
493
494 foreach ($tablesToCreate as $tableName => $tableSql) {
495 $tableName = $prefixTables . $tableName;
496 if (!in_array($tableName, $tablesAlreadyInstalled)) {
497 $db->query($tableSql);
498 }
499 }
500 }
501
502 /**
503 * Creates an entry in the User table for the "anonymous" user.
504 */
505 public function createAnonymousUser()
506 {
507 $now = Date::factory('now')->getDatetime();
508
509 // The anonymous user is the user that is assigned by default
510 // note that the token_auth value is anonymous, which is assigned by default as well in the Login plugin
511 $db = $this->getDb();
512 $db->query("INSERT IGNORE INTO " . Common::prefixTable("user") . "
513 VALUES ( 'anonymous', '', 'anonymous', 'anonymous@example.org', '', 'anonymous', 0, '$now', '$now' );");
514 }
515
516 /**
517 * Records the Matomo version a user used when installing this Matomo for the first time
518 */
519 public function recordInstallVersion()
520 {
521 if (!self::getInstallVersion()) {
522 Option::set(self::OPTION_NAME_MATOMO_INSTALL_VERSION, Version::VERSION);
523 }
524 }
525
526 /**
527 * Returns which Matomo version was used to install this Matomo for the first time.
528 */
529 public function getInstallVersion()
530 {
531 Option::clearCachedOption(self::OPTION_NAME_MATOMO_INSTALL_VERSION);
532 $version = Option::get(self::OPTION_NAME_MATOMO_INSTALL_VERSION);
533 if (!empty($version)) {
534 return $version;
535 }
536 }
537
538 /**
539 * Truncate all tables
540 */
541 public function truncateAllTables()
542 {
543 $tables = $this->getAllExistingTables();
544 foreach ($tables as $table) {
545 Db::query("TRUNCATE `$table`");
546 }
547 }
548
549 private function getTablePrefix()
550 {
551 return $this->getDbSettings()->getTablePrefix();
552 }
553
554 private function getTableEngine()
555 {
556 return $this->getDbSettings()->getEngine();
557 }
558
559 private function getDb()
560 {
561 return Db::get();
562 }
563
564 private function getDbSettings()
565 {
566 return new Db\Settings();
567 }
568
569 private function getDbName()
570 {
571 return $this->getDbSettings()->getDbName();
572 }
573
574 private function getAllExistingTables($prefixTables = false)
575 {
576 if (empty($prefixTables)) {
577 $prefixTables = $this->getTablePrefixEscaped();
578 }
579
580 return Db::get()->fetchCol("SHOW TABLES LIKE '" . $prefixTables . "%'");
581 }
582
583 private function getTablePrefixEscaped()
584 {
585 $prefixTables = $this->getTablePrefix();
586 // '_' matches any character; force it to be literal
587 $prefixTables = str_replace('_', '\_', $prefixTables);
588 return $prefixTables;
589 }
590 }
591