Last active
July 6, 2017 03:00
-
-
Save pento/714bfd58c423ff06a37d8268a5af5cd3 to your computer and use it in GitHub Desktop.
πdb, the next evolution of wpdb.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| class πdb extends wpdb { | |
| public $tablesπ = array( | |
| // Tables | |
| 'posts' => 'β', | |
| 'postmeta' => 'ββ‘οΈ', | |
| 'comments' => 'β»', | |
| 'commentmeta' => 'β»β‘οΈ', | |
| 'terms' => 'βοΈ', | |
| 'termmeta' => 'βοΈβ‘οΈ', | |
| 'term_taxonomy' => 'βοΈβ°', | |
| 'term_relationships' => 'βοΈβΏ', | |
| 'options' => 'βΉ', | |
| 'links' => 'β', | |
| // Global tables | |
| 'users' => 'β', | |
| 'usermeta' => 'ββ‘οΈ', | |
| // Multisite global tables | |
| 'blogs' => 'β΄', | |
| 'signups' => 'βΌ', | |
| 'site' => 'β', | |
| 'sitemeta' => 'ββ‘οΈ', | |
| 'sitecategories' => 'ββοΈ', | |
| 'registration_log' => 'β_γ½', | |
| 'blog_versions' => 'β΄_γ°', | |
| ); | |
| public function tables( $scope = 'all', $prefix = true, $blog_id = 0 ) { | |
| $tables = parent::tables( $scope, $prefix, $blog_id ); | |
| foreach ( $this->tablesπ as $name => $replacement ) { | |
| if ( $prefix && ! empty( $tables[ $name ] ) ) { | |
| $tables[ $name ] = str_replace( $name, $replacement, $tables[ $name ] ); | |
| } | |
| if ( ! $prefix && in_array( $name, $tables, true ) ) { | |
| $tables = str_replace( $name, $replacement, $tables ); | |
| } | |
| } | |
| return $tables; | |
| } | |
| protected function get_table_from_query( $query ) { | |
| // Remove characters that can legally trail the table name. | |
| $query = rtrim( $query, ';/-#' ); | |
| // Allow (select...) union [...] style queries. Use the first query's table name. | |
| $query = ltrim( $query, "\r\n\t (" ); | |
| // Strip everything between parentheses except nested selects. | |
| $query = preg_replace( '/\((?!\s*select)[^(]*?\)/is', '()', $query ); | |
| // Quickly match most common queries. | |
| if ( preg_match( '/^\s*(?:' | |
| . 'SELECT.*?\s+FROM' | |
| . '|INSERT(?:\s+LOW_PRIORITY|\s+DELAYED|\s+HIGH_PRIORITY)?(?:\s+IGNORE)?(?:\s+INTO)?' | |
| . '|REPLACE(?:\s+LOW_PRIORITY|\s+DELAYED)?(?:\s+INTO)?' | |
| . '|UPDATE(?:\s+LOW_PRIORITY)?(?:\s+IGNORE)?' | |
| . '|DELETE(?:\s+LOW_PRIORITY|\s+QUICK|\s+IGNORE)*(?:.+?FROM)?' | |
| . ')\s+((?:[^\s,])+)/is', $query, $maybe ) ) { | |
| return str_replace( '`', '', $maybe[1] ); | |
| } | |
| // SHOW TABLE STATUS and SHOW TABLES WHERE Name = 'wp_posts' | |
| if ( preg_match( '/^\s*SHOW\s+(?:TABLE\s+STATUS|(?:FULL\s+)?TABLES).+WHERE\s+Name\s*=\s*("|\')((?:[^\s,])+)\\1/is', $query, $maybe ) ) { | |
| return $maybe[2]; | |
| } | |
| // SHOW TABLE STATUS LIKE and SHOW TABLES LIKE 'wp\_123\_%' | |
| // This quoted LIKE operand seldom holds a full table name. | |
| // It is usually a pattern for matching a prefix so we just | |
| // strip the trailing % and unescape the _ to get 'wp_123_' | |
| // which drop-ins can use for routing these SQL statements. | |
| if ( preg_match( '/^\s*SHOW\s+(?:TABLE\s+STATUS|(?:FULL\s+)?TABLES)\s+(?:WHERE\s+Name\s+)?LIKE\s*("|\')((?:[^\s,])+)%?\\1/is', $query, $maybe ) ) { | |
| return str_replace( '\\_', '_', $maybe[2] ); | |
| } | |
| // Big pattern for the rest of the table-related queries. | |
| if ( preg_match( '/^\s*(?:' | |
| . '(?:EXPLAIN\s+(?:EXTENDED\s+)?)?SELECT.*?\s+FROM' | |
| . '|DESCRIBE|DESC|EXPLAIN|HANDLER' | |
| . '|(?:LOCK|UNLOCK)\s+TABLE(?:S)?' | |
| . '|(?:RENAME|OPTIMIZE|BACKUP|RESTORE|CHECK|CHECKSUM|ANALYZE|REPAIR).*\s+TABLE' | |
| . '|TRUNCATE(?:\s+TABLE)?' | |
| . '|CREATE(?:\s+TEMPORARY)?\s+TABLE(?:\s+IF\s+NOT\s+EXISTS)?' | |
| . '|ALTER(?:\s+IGNORE)?\s+TABLE' | |
| . '|DROP\s+TABLE(?:\s+IF\s+EXISTS)?' | |
| . '|CREATE(?:\s+\w+)?\s+INDEX.*\s+ON' | |
| . '|DROP\s+INDEX.*\s+ON' | |
| . '|LOAD\s+DATA.*INFILE.*INTO\s+TABLE' | |
| . '|(?:GRANT|REVOKE).*ON\s+TABLE' | |
| . '|SHOW\s+(?:.*FROM|.*TABLE)' | |
| . ')\s+\(*\s*((?:[^\s,])+)\s*\)*/is', $query, $maybe ) ) { | |
| return str_replace( '`', '', $maybe[1] ); | |
| } | |
| return false; | |
| } | |
| public function query( $query ) { | |
| // WP_Date_Query::validate_column() strips non-ASCII table names, which makes πdb sad. | |
| $known_columns = array( | |
| $this->posts => array( | |
| 'post_date', | |
| 'post_date_gmt', | |
| 'post_modified', | |
| 'post_modified_gmt', | |
| ), | |
| $this->comments => array( | |
| 'comment_date', | |
| 'comment_date_gmt', | |
| ), | |
| $this->users => array( | |
| 'user_registered', | |
| ), | |
| $this->blogs => array( | |
| 'registered', | |
| 'last_updated', | |
| ), | |
| ); | |
| foreach ( $known_columns as $table => $columns ) { | |
| foreach ( $columns as $column ) { | |
| $query = str_replace( "$this->prefix.$column", "$table.$column", $query ); | |
| } | |
| } | |
| // Tests_List_Pages::setUp() assumes the posts table name. | |
| $query = str_replace( "TRUNCATE {$this->prefix}posts", "TRUNCATE $this->posts", $query ); | |
| // WP_User_Query::prepare_query() assumes the posts table name. | |
| $wrong_name = $this->prefix . 'posts'; | |
| $right_name = $this->tables()['posts']; | |
| $query = str_replace( "FROM $wrong_name WHERE", "FROM $right_name WHERE", $query ); | |
| $query = str_replace( " $wrong_name.", " $right_name.", $query ); | |
| $matches = array(); | |
| if ( is_multisite() && preg_match( "/{$this->prefix}(\d+)_posts/", $query, $matches ) ) { | |
| $wrong_name = $this->prefix . $matches[1] . '_posts'; | |
| $right_name = $this->tables( 'all', true, $matches[1] )['posts']; | |
| $query = str_replace( "FROM $wrong_name WHERE", "FROM $right_name WHERE", $query ); | |
| $query = str_replace( " $wrong_name.", " $right_name.", $query ); | |
| } | |
| // No need to check DROP TABLE queries | |
| if ( strpos( $query, 'DROP TABLE' ) === 0 ) { | |
| $this->check_current_query = false; | |
| } | |
| return parent::query( $query ); | |
| } | |
| } | |
| $wpdb = new πdb( DB_USER, DB_PASSWORD, DB_NAME, DB_HOST ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment