PluginProbe
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler / 1.6.5
FluentCart A New Era of eCommerce – Faster, Lighter, and Simpler v1.6.5
1.6.5 1.6.4 1.6.3 1.6.2 1.6.1 1.6.0 1.5.4 1.5.5 1.5.3 1.5.2 1.5.1 1.5.0 1.4.2 1.4.1 1.4.0 1.3.28 1.3.27 1.3.26 1.3.25 1.3.23 1.3.22 1.3.21 1.3.20 1.3.19 trunk All 48 releases
← All changes | vendor/wpfluent/framework/src/WPFluent/Database/Schema.php +144 -18 1.3.26 → 1.6.5 View file →
@@ -33,8 +33,23 @@
33 33 public static function getInfo($key = null)
34 34 {
35 35 $db = static::db();
36 36
37 + if (static::isSqlite()) {
38 + $info = [
39 + 'dbname' => 'sqlite',
40 + 'prefix' => $db->prefix,
41 + 'dbhost' => '',
42 + 'username' => '',
43 + 'password' => '',
44 + 'charset' => 'utf8',
45 + 'collation' => '',
46 + 'tables' => static::getTableList(),
47 + ];
48 +
49 + return $key ? ($info[$key] ?? null) : $info;
50 + }
51 +
37 52 $info = [
38 53 // @phpstan-ignore-next-line
39 54 'dbname' => $db->dbname,
40 55 'prefix' => $db->prefix,
@@ -135,9 +150,9 @@
135 150 // error and then turn off the error from being shown, so
136 151 // error will be not shown if there is no temporary
137 152 // table, then restore the error state.
138 153 $isErrorSuppressed = $wpdb->suppress_errors;
139 -
154 +
140 155 $wpdb->suppress_errors = true;
141 156
142 157 static::query("SELECT 1 FROM %{$table}% WHERE 0");
143 158
@@ -379,17 +394,13 @@
379 394 // SQLite cannot drop PRIMARY KEY columns or columns referenced by indexes
380 395 // via native ALTER TABLE DROP COLUMN.
381 396 //
382 397 // Workarounds:
383 - // - Indexed columns: drop the index first with ALTER TABLE DROP INDEX,
398 + // - Indexed columns: drop the index first with DROP INDEX,
384 399 // then drop the column.
385 400 // - PRIMARY KEY columns: use CHANGE COLUMN to rebuild the table without
386 401 // the PK attribute (renaming the column to a temp name), then drop
387 402 // the renamed column.
388 - //
389 - // Note: ALTER TABLE … RENAME TO and standalone DROP INDEX are NOT
390 - // supported by this version of the WP SQLite integration, so we cannot
391 - // use a full-table-rebuild via rename.
392 403 if (static::isSqlite()) {
393 404 // Collect PRIMARY KEY columns and per-column index key names.
394 405 $indexRows = (array) static::db()->get_results("SHOW INDEX FROM {$tbl}");
395 406 $pkColumns = [];
@@ -544,12 +555,65 @@
544 555 * @see https://developer.wordpress.org/reference/functions/drop_index
545 556 */
546 557 public static function dropIndex($table, $index)
547 558 {
559 + if (static::isSqlite()) {
560 + $tbl = static::table($table);
561 + return static::db()->query("ALTER TABLE {$tbl} DROP INDEX {$index}");
562 + }
563 +
548 564 return drop_index(static::table($table), $index);
549 565 }
550 566
551 567 /**
568 + * Add a FULLTEXT index to the given columns, required by the query
569 + * builder's relevance ranking (selectRelevance/orderByRelevance and the
570 + * Searchable relevanceSearch scope). No-ops on SQLite, which has no
571 + * native FULLTEXT support and degrades to LIKE-based matching.
572 + *
573 + * @param string $table Table name without prefix
574 + * @param string|array $columns
575 + * @param string|null $name Optional index name
576 + * @return mixed
577 + */
578 + public static function fullText($table, $columns, $name = null)
579 + {
580 + if (static::isSqlite()) {
581 + return false;
582 + }
583 +
584 + $columns = is_array($columns)
585 + ? $columns
586 + : array_map('trim', explode(',', $columns));
587 +
588 + $tbl = static::table($table);
589 + $name = $name ?: ('ft_' . implode('_', $columns));
590 + $list = implode(', ', $columns);
591 +
592 + return static::db()->query(
593 + "ALTER TABLE {$tbl} ADD FULLTEXT {$name} ({$list})"
594 + );
595 + }
596 +
597 + /**
598 + * Drop a FULLTEXT index by name.
599 + *
600 + * @param string $table Table name without prefix
601 + * @param string $name Index name
602 + * @return mixed
603 + */
604 + public static function dropFullText($table, $name)
605 + {
606 + if (static::isSqlite()) {
607 + return false;
608 + }
609 +
610 + $tbl = static::table($table);
611 +
612 + return static::db()->query("ALTER TABLE {$tbl} DROP INDEX {$name}");
613 + }
614 +
615 + /**
552 616 * Makes raw query and can resolve the table name from the query
553 617 * and can form a full table name including the table prefix if
554 618 * the table name is wrapped like: %table_name% in the query.
555 619 *
@@ -581,9 +645,9 @@
581 645 return null;
582 646 }
583 647
584 648 return static::db()->get_col(
585 - 'SHOW COLUMNS FROM ' . static::table($table), 0
649 + 'DESCRIBE ' . static::table($table), 0
586 650 );
587 651 }
588 652
589 653 /**
@@ -595,12 +659,47 @@
595 659 protected static function protectedGetColumnsWithTypes($table)
596 660 {
597 661 if (!static::hasTable($table)) return;
598 662
599 - // @phpstan-ignore-next-line
663 + $table = static::table($table);
664 +
665 + if (static::isSqlite()) {
666 + // INFORMATION_SCHEMA is not available in SQLite.
667 + // Use DESCRIBE which the WP SQLite plugin translates with
668 + // proper MySQL type mapping from its data type cache.
669 + $columns = (array) static::db()->get_results("DESCRIBE {$table}");
670 + return array_map(function ($col, $pos) {
671 + $extra = $col->Extra ?? '';
672 + // SQLite INTEGER PRIMARY KEY is auto_increment but DESCRIBE
673 + // doesn't report it in Extra — detect from Key + Type.
674 + if (empty($extra) && ($col->Key ?? '') === 'PRI') {
675 + $type = strtoupper($col->Type ?? '');
676 + if (in_array($type, ['INTEGER', 'BIGINT', 'BIGINT(20)', 'BIGINT(20) UNSIGNED', 'INT'])) {
677 + $extra = 'auto_increment';
678 + }
679 + }
680 +
681 + return [
682 + 'column_name' => $col->Field,
683 + 'ordinal_position' => $pos + 1,
684 + 'column_default' => $col->Default,
685 + 'is_nullable' => ($col->Null === 'YES' ? 'YES' : 'NO'),
686 + 'data_type' => strtolower(
687 + preg_replace('/\(.*/', '', $col->Type)
688 + ),
689 + 'character_maximum_length' => preg_match(
690 + '/\((\d+)\)/', $col->Type, $matches
691 + ) ? (int)$matches[1] : null,
692 + 'numeric_precision' => null,
693 + 'numeric_scale' => null,
694 + 'column_key' => $col->Key ?? '',
695 + 'extra' => $extra,
696 + ];
697 + }, $columns, array_keys($columns));
698 + }
699 +
700 + // @phpstan-ignore-next-line
600 701 $db = static::db()->dbname;
601 -
602 - $table = static::table($table);
603 702
604 703 $fields = [
605 704 'COLUMN_NAME',
606 705 'ORDINAL_POSITION',
@@ -612,9 +711,9 @@
612 711 'NUMERIC_SCALE',
613 712 'COLUMN_KEY',
614 713 'EXTRA',
615 714 ];
616 -
715 +
617 716 $sql = "SELECT " . implode(',', $fields) . " FROM INFORMATION_SCHEMA.COLUMNS";
618 717 $sql .= " WHERE TABLE_NAME = '".$table."' AND TABLE_SCHEMA = '".$db."'";
619 718
620 719 return array_map(function($i) {
@@ -633,8 +732,12 @@
633 732 if (!empty($columns)) {
634 733 return $columns;
635 734 }
636 735
736 + if (static::isSqlite()) {
737 + return [];
738 + }
739 +
637 740 $columns = static::db()->get_results(
638 741 'SHOW COLUMNS FROM `'.static::table($table).'`'
639 742 );
640 743
@@ -679,15 +782,30 @@
679 782 {
680 783 $table = static::table($table);
681 784
682 785 if (static::isSqlite()) {
683 - return array_map(function ($i) {
684 - return [
685 - 'column_name' => $i->from,
686 - 'referenced_table' => $i->table,
687 - 'referenced_column' => $i->to,
688 - ];
689 - }, (array) static::db()->get_results("PRAGMA foreign_key_list({$table})"));
786 + // Parse foreign keys from the CREATE TABLE statement in sqlite_master
787 + // since PRAGMA queries cannot go through $wpdb.
788 + $row = static::db()->get_row(
789 + "SELECT sql FROM sqlite_master WHERE type='table' AND name='{$table}'"
790 + );
791 + if (!$row || empty($row->sql)) {
792 + return [];
793 + }
794 + $fks = [];
795 + if (preg_match_all(
796 + '/FOREIGN\s+KEY\s*\(\s*[`"]?(\w+)[`"]?\s*\)\s*REFERENCES\s+[`"]?(\w+)[`"]?\s*\(\s*[`"]?(\w+)[`"]?\s*\)/i',
797 + $row->sql, $matches, PREG_SET_ORDER
798 + )) {
799 + foreach ($matches as $m) {
800 + $fks[] = [
801 + 'column_name' => $m[1],
802 + 'referenced_table' => $m[2],
803 + 'referenced_column' => $m[3],
804 + ];
805 + }
806 + }
807 + return $fks;
690 808 }
691 809
692 810 // @phpstan-ignore-next-line
693 811 $db = static::db()->dbname;
@@ -830,8 +948,12 @@
830 948 * @return bool
831 949 */
832 950 public static function isMaria()
833 951 {
952 + if (static::isSqlite()) {
953 + return false;
954 + }
955 +
834 956 return str_contains(
835 957 static::db()->get_var('SELECT VERSION()'), 'MariaDB'
836 958 );
837 959 }
@@ -843,8 +965,12 @@
843 965 * @return string
844 966 */
845 967 public static function getEngine($table)
846 968 {
969 + if (static::isSqlite()) {
970 + return 'sqlite';
971 + }
972 +
847 973 return static::db()->get_var(
848 974 'SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = "' . static::table($table) . '"'
849 975 );
850 976 }