Skip to:
Content

bbPress.org


Ignore:
Timestamp:
06/04/2010 09:12:16 PM (16 years ago)
Author:
chrishajer
Message:

Performance improvements for tag recount functions. Fixes #1146. Props sambauers, _ck_

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/bb-admin/includes/functions.bb-recount.php

    r2391 r2441  
    1010        $sql = "INSERT INTO `$bbdb->topics` (`topic_id`, `topic_posts`) (SELECT `topic_id`, COUNT(`post_status`) as `topic_posts` FROM `$bbdb->posts` WHERE `post_status` = '0' GROUP BY `topic_id`) ON DUPLICATE KEY UPDATE `topic_posts` = VALUES(`topic_posts`);";
    1111        if ( is_wp_error( $bbdb->query( $sql ) ) ) {
    12                 return sprintf( $statement, $result );
    13         }
    14 
    15         $result = __( 'Complete!' );
    16         return sprintf( $statement, $result );
     12                return array( 1, sprintf( $statement, $result ) );
     13        }
     14
     15        $result = __( 'Complete!' );
     16        return array( 0, sprintf( $statement, $result ) );
    1717}
    1818
     
    2626        $sql_delete = "DELETE FROM `$bbdb->meta` WHERE `object_type` = 'bb_topic' AND `meta_key` = 'voices_count';";
    2727        if ( is_wp_error( $bbdb->query( $sql_delete ) ) ) {
    28                 return sprintf( $statement, $result );
     28                return array( 1, sprintf( $statement, $result ) );
    2929        }
    3030
    3131        $sql = "INSERT INTO `$bbdb->meta` (`object_type`, `object_id`, `meta_key`, `meta_value`) (SELECT 'bb_topic', `topic_id`, 'voices_count', COUNT(DISTINCT `poster_id`) as `meta_value` FROM `$bbdb->posts` WHERE `post_status` = '0' GROUP BY `topic_id`);";
    3232        if ( is_wp_error( $bbdb->query( $sql ) ) ) {
    33                 return sprintf( $statement, $result );
    34         }
    35 
    36         $result = __( 'Complete!' );
    37         return sprintf( $statement, $result );
     33                return array( 2, sprintf( $statement, $result ) );
     34        }
     35
     36        $result = __( 'Complete!' );
     37        return array( 0, sprintf( $statement, $result ) );
    3838}
    3939
     
    4747        $sql_delete = "DELETE FROM `$bbdb->meta` WHERE `object_type` = 'bb_topic' AND `meta_key` = 'deleted_posts';";
    4848        if ( is_wp_error( $bbdb->query( $sql_delete ) ) ) {
    49                 return sprintf( $statement, $result );
     49                return array( 1, sprintf( $statement, $result ) );
    5050        }
    5151
    5252        $sql = "INSERT INTO `$bbdb->meta` (`object_type`, `object_id`, `meta_key`, `meta_value`) (SELECT 'bb_topic', `topic_id`, 'deleted_posts', COUNT(`post_status`) as `meta_value` FROM `$bbdb->posts` WHERE `post_status` != '0' GROUP BY `topic_id`);";
    5353        if ( is_wp_error( $bbdb->query( $sql ) ) ) {
    54                 return sprintf( $statement, $result );
    55         }
    56 
    57         $result = __( 'Complete!' );
    58         return sprintf( $statement, $result );
     54                return array( 2, sprintf( $statement, $result ) );
     55        }
     56
     57        $result = __( 'Complete!' );
     58        return array( 0, sprintf( $statement, $result ) );
    5959}
    6060
     
    6868        $sql = "INSERT INTO `$bbdb->forums` (`forum_id`, `topics`) (SELECT `forum_id`, COUNT(`topic_status`) as `topics` FROM `$bbdb->topics` WHERE `topic_status` = '0' GROUP BY `forum_id`) ON DUPLICATE KEY UPDATE `topics` = VALUES(`topics`);";
    6969        if ( is_wp_error( $bbdb->query( $sql ) ) ) {
    70                 return sprintf( $statement, $result );
    71         }
    72 
    73         $result = __( 'Complete!' );
    74         return sprintf( $statement, $result );
     70                return array( 1, sprintf( $statement, $result ) );
     71        }
     72
     73        $result = __( 'Complete!' );
     74        return array( 0, sprintf( $statement, $result ) );
    7575}
    7676
     
    8484        $sql = "INSERT INTO `$bbdb->forums` (`forum_id`, `posts`) (SELECT `forum_id`, COUNT(`post_status`) as `posts` FROM `$bbdb->posts` WHERE `post_status` = '0' GROUP BY `forum_id`) ON DUPLICATE KEY UPDATE `posts` = VALUES(`posts`);";
    8585        if ( is_wp_error( $bbdb->query( $sql ) ) ) {
    86                 return sprintf( $statement, $result );
    87         }
    88 
    89         $result = __( 'Complete!' );
    90         return sprintf( $statement, $result );
     86                return array( 1, sprintf( $statement, $result ) );
     87        }
     88
     89        $result = __( 'Complete!' );
     90        return array( 0, sprintf( $statement, $result ) );
    9191}
    9292
     
    102102
    103103        if ( is_wp_error( $insert_rows ) ) {
    104                 return sprintf( $statement, $result );
     104                return array( 1, sprintf( $statement, $result ) );
    105105        }
    106106
     
    113113
    114114        if ( !count( $insert_values ) ) {
    115                 return sprintf( $statement, $result );
     115                return array( 2, sprintf( $statement, $result ) );
    116116        }
    117117
    118118        $sql_delete = "DELETE FROM `$bbdb->usermeta` WHERE `meta_key` = '$meta_key';";
    119119        if ( is_wp_error( $bbdb->query( $sql_delete ) ) ) {
    120                 return sprintf( $statement, $result );
     120                return array( 3, sprintf( $statement, $result ) );
    121121        }
    122122
     
    127127
    128128                if ( is_wp_error( $bbdb->query( $sql_insert ) ) ) {
    129                         return sprintf( $statement, $result );
    130                 }
    131         }
    132 
    133         $result = __( 'Complete!' );
    134         return sprintf( $statement, $result );
    135 }
    136 
    137 // TODO - make fast - see #1146
     129                        return array( 4, sprintf( $statement, $result ) );
     130                }
     131        }
     132
     133        $result = __( 'Complete!' );
     134        return array( 0, sprintf( $statement, $result ) );
     135}
     136
     137// This function bypasses the taxonomy API
    138138function bb_recount_topic_tags()
    139139{
    140         global $bbdb, $wp_taxonomy_object;
    141 
    142         // Reset tag count to zero
    143         $bbdb->query( "UPDATE $bbdb->topics SET tag_count = 0" );
     140        global $bbdb;
     141
     142        $statement = __( 'Counting the number of topic tags in each topic… %s' );
     143        $result = __( 'Failed!' );
     144
     145        // Delete empty tags
     146        $delete = bb_recount_tag_delete_empty();
     147        if ( $delete[0] > 0 ) {
     148                $result = __( 'Could not delete empty tags.' );
     149                return array( 1, sprintf( $statement, $result ) );
     150        }
    144151
    145152        // Get all tags
    146         $terms = $wp_taxonomy_object->get_terms( 'bb_topic_tag' );
    147 
    148         if ( !is_wp_error( $terms ) && is_array( $terms ) ) {
    149                 $message = __('Counted topic tags');
    150                 foreach ( $terms as $term ) {
    151                         $topic_ids = bb_get_tagged_topic_ids( $term->term_id );
    152                         if ( !is_wp_error( $topic_ids ) && is_array( $topic_ids ) ) {
    153                                 $bbdb->query(
    154                                         "UPDATE $bbdb->topics SET tag_count = tag_count + 1 WHERE topic_id IN (" . join( ',', $topic_ids ) . ")"
    155                                 );
     153        $sql_terms = "SELECT
     154                `$bbdb->term_relationships`.`object_id`,
     155                `$bbdb->term_taxonomy`.`term_id`
     156        FROM `$bbdb->term_relationships`
     157        JOIN `$bbdb->term_taxonomy`
     158                ON `$bbdb->term_taxonomy`.`term_taxonomy_id` = `$bbdb->term_relationships`.`term_taxonomy_id`
     159        WHERE
     160                `$bbdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag'
     161        ORDER BY
     162                `$bbdb->term_relationships`.`object_id`,
     163                `$bbdb->term_taxonomy`.`term_id`;";
     164
     165        $terms = $bbdb->get_results( $sql_terms );
     166        if ( is_wp_error( $terms ) || !is_array( $terms ) ) {
     167                return array( 2, sprintf( $statement, $result ) );
     168        }
     169        if ( empty( $terms ) ) {
     170                $result = __( 'No topic tags found.' );
     171                return array( 3, sprintf( $statement, $result ) );
     172        }
     173
     174        // Count the tags in each topic
     175        $topics = array();
     176        foreach ( $terms as $term ) {
     177                if ( !isset( $topics[$term->object_id] ) ) {
     178                        $topics[$term->object_id] = 1;
     179                } else {
     180                        $topics[$term->object_id]++;
     181                }
     182        }
     183        if ( empty( $topics ) ) {
     184                return array( 4, sprintf( $statement, $result ) );
     185        }
     186
     187        // Build the values to insert into the SQL statement
     188        $values = array();
     189        foreach ($topics as $topic_id => $tag_count) {
     190                $values[] = '(' . $topic_id . ', ' . $tag_count . ')';
     191        }
     192        if ( empty( $values ) ) {
     193                return array( 5, sprintf( $statement, $result ) );
     194        }
     195
     196        // Update the topics with the new tag counts
     197        $values = array_chunk( $values, 10000 );
     198        foreach ($values as $chunk) {
     199                $sql = "INSERT INTO `$bbdb->topics` (`topic_id`, `tag_count`) VALUES " . implode(", ", $chunk) . " ON DUPLICATE KEY UPDATE `tag_count` = VALUES(`tag_count`);";
     200                if ( is_wp_error( $bbdb->query( $sql ) ) ) {
     201                        return array( 6, sprintf( $statement, $result ) );
     202                }
     203        }
     204
     205        $result = __( 'Complete!' );
     206        return array( 0, sprintf( $statement, $result ) );
     207}
     208
     209// This function bypasses the taxonomy API
     210function bb_recount_tag_topics()
     211{
     212        global $bbdb;
     213
     214        $statement = __( 'Counting the number of topics in each topic tag… %s' );
     215        $result = __( 'Failed!' );
     216
     217        // Delete empty tags
     218        $delete = bb_recount_tag_delete_empty();
     219        if ( $delete[0] > 0 ) {
     220                $result = __( 'Could not delete empty tags.' );
     221                return array( 1, sprintf( $statement, $result ) );
     222        }
     223
     224        // Get all tags
     225        $sql_terms = "SELECT
     226                `$bbdb->term_taxonomy`.`term_taxonomy_id`,
     227                `$bbdb->term_relationships`.`object_id`
     228        FROM `$bbdb->term_relationships`
     229        JOIN `$bbdb->term_taxonomy`
     230                ON `$bbdb->term_taxonomy`.`term_taxonomy_id` = `$bbdb->term_relationships`.`term_taxonomy_id`
     231        WHERE
     232                `$bbdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag'
     233        ORDER BY
     234                `$bbdb->term_taxonomy`.`term_taxonomy_id`,
     235                `$bbdb->term_relationships`.`object_id`;";
     236
     237        $terms = $bbdb->get_results( $sql_terms );
     238        if ( is_wp_error( $terms ) || !is_array( $terms ) ) {
     239                return array( 2, sprintf( $statement, $result ) );
     240        }
     241        if ( empty( $terms ) ) {
     242                $result = __( 'No topic tags found.' );
     243                return array( 3, sprintf( $statement, $result ) );
     244        }
     245       
     246        // Count the topics in each tag
     247        $tags = array();
     248        foreach ( $terms as $term ) {
     249                if ( !isset( $tags[$term->term_taxonomy_id] ) ) {
     250                        $tags[$term->term_taxonomy_id] = 1;
     251                } else {
     252                        $tags[$term->term_taxonomy_id]++;
     253                }
     254        }
     255        if ( empty( $tags ) ) {
     256                return array( 4, sprintf( $statement, $result ) );
     257        }
     258       
     259        // Build the values to insert into the SQL statement
     260        $values = array();
     261        foreach ($tags as $term_taxonomy_id => $count) {
     262                $values[] = '(' . $term_taxonomy_id . ', ' . $count . ')';
     263        }
     264        if ( empty( $values ) ) {
     265                return array( 5, sprintf( $statement, $result ) );
     266        }
     267       
     268        // Update the terms with the new tag counts
     269        $values = array_chunk( $values, 10000 );
     270        foreach ($values as $chunk) {
     271                $sql = "INSERT INTO `$bbdb->term_taxonomy` (`term_taxonomy_id`, `count`) VALUES " . implode(", ", $chunk) . " ON DUPLICATE KEY UPDATE `count` = VALUES(`count`);";
     272                if ( is_wp_error( $bbdb->query( $sql ) ) ) {
     273                        return array( 6, sprintf( $statement, $result ) );
     274                }
     275        }
     276
     277        if ($return_boolean) {
     278                return true;
     279        }
     280        $result = __( 'Complete!' );
     281        return array( 0, sprintf( $statement, $result ) );
     282}
     283
     284// This function bypasses the taxonomy API
     285function bb_recount_tag_delete_empty()
     286{
     287        global $bbdb;
     288
     289        $statement = __( 'Deleting topic tags with no topics… %s' );
     290        $result = __( 'Failed!' );
     291
     292        static $run_once;
     293        if ( isset( $run_once ) ) {
     294                if ($run_once > 0) {
     295                        $exit = sprintf( __( 'failure (returned code %s)' ), $run_once );
     296                } else {
     297                        $exit = __( 'success' );
     298                }
     299                $result = sprintf( __( 'Already run with %s.' ), $exit );
     300                return array( $run_once, sprintf( $statement, $result ) );
     301        }
     302
     303        // Get all topic ids
     304        $sql_topics = "SELECT `topic_id` FROM $bbdb->topics ORDER BY `topic_id`;";
     305        $topics = $bbdb->get_results( $sql_topics );
     306        if ( is_wp_error( $topics ) ) {
     307                $result = __('No topics found.');
     308                $run_once = 1;
     309                return array( 1, sprintf( $statement, $result ) );
     310        }
     311        $topic_ids = array();
     312        foreach ($topics as $topic) {
     313                $topic_ids[] = $topic->topic_id;
     314        }
     315
     316        // Get all topic tag term relationships without a valid topic id
     317        $in_topic_ids = implode(', ', $topic_ids);
     318        $sql_bad_term_relationships = "SELECT
     319                `$bbdb->term_taxonomy`.`term_taxonomy_id`,
     320                `$bbdb->term_taxonomy`.`term_id`,
     321                `$bbdb->term_relationships`.`object_id`
     322        FROM `$bbdb->term_relationships`
     323        JOIN `$bbdb->term_taxonomy`
     324                ON `$bbdb->term_taxonomy`.`term_taxonomy_id` = `$bbdb->term_relationships`.`term_taxonomy_id`
     325        WHERE
     326                `$bbdb->term_taxonomy`.`taxonomy` = 'bb_topic_tag' AND
     327                `$bbdb->term_relationships`.`object_id` NOT IN ($in_topic_ids)
     328        ORDER BY
     329                `$bbdb->term_relationships`.`object_id`,
     330                `$bbdb->term_taxonomy`.`term_id`,
     331                `$bbdb->term_taxonomy`.`term_taxonomy_id`;";
     332
     333        $bad_term_relationships = $bbdb->get_results( $sql_bad_term_relationships );
     334        if ( is_wp_error( $bad_term_relationships ) || !is_array( $bad_term_relationships ) ) {
     335                $run_once = 2;
     336                return array( 2, sprintf( $statement, $result ) );
     337        }
     338
     339        // Delete those bad term relationships
     340        if ( !empty( $bad_term_relationships ) ) {
     341                $values = array();
     342                foreach ( $bad_term_relationships as $bad_term_relationship ) {
     343                        $values[] = '(`object_id` = ' . $bad_term_relationship->object_id . ' AND `term_taxonomy_id` = ' . $bad_term_relationship->term_taxonomy_id . ')';
     344                }
     345                if ( !empty( $values ) ) {
     346                        $values = join(' OR ', $values);
     347                        $sql_bad_term_relationships_delete = "DELETE
     348                        FROM `$bbdb->term_relationships`
     349                        WHERE $values;";
     350                        if ( is_wp_error( $bbdb->query( $sql_bad_term_relationships_delete ) ) ) {
     351                                $run_once = 3;
     352                                return array( 3, sprintf( $statement, $result ) );
    156353                        }
    157                         unset( $topic_ids );
    158                 }
    159         }
    160         unset( $terms, $term );
    161 
    162         return $message;
    163 }
    164 
    165 // TODO - make fast - see #1146
    166 function bb_recount_tag_topics()
    167 {
    168         global $wp_taxonomy_object;
    169 
    170         // Get all tags
    171         $terms = $wp_taxonomy_object->get_terms( 'bb_topic_tag', array( 'hide_empty' => false ) );
    172 
    173         if ( !is_wp_error( $terms ) && is_array( $terms ) ) {
    174                 $message = __('Counted tagged topics');
    175                 $_terms = array();
    176                 foreach ( $terms as $term ) {
    177                         $_terms[] = $term->term_id;
    178                 }
    179                 if ( count( $_terms ) ) {
    180                         $wp_taxonomy_object->update_term_count( $_terms, 'bb_topic_tag' );
    181                 }
    182         }
    183         unset( $term, $_terms );
    184 
    185         return $message;
    186 }
    187 
    188 // TODO - make fast - see #1146
    189 function bb_recount_tag_delete_empty()
    190 {
    191         global $wp_taxonomy_object;
    192 
    193         // Get all tags
    194         if ( !isset( $terms ) ) {
    195                 $terms = $wp_taxonomy_object->get_terms( 'bb_topic_tag', array( 'hide_empty' => false ) );
    196         }
    197 
    198         if ( !is_wp_error( $terms ) && is_array( $terms ) ) {
    199                 $message = __('Deleted tags with no topics');
    200                 foreach ( $terms as $term ) {
    201                         $topic_ids = bb_get_tagged_topic_ids( $term->term_id );
    202                         if ( !is_wp_error( $topic_ids ) && is_array( $topic_ids ) ) {
    203                                 if ( false === $topic_ids || ( is_array( $topic_ids ) && !count( $topic_ids ) ) ) {
    204                                         bb_destroy_tag( $term->term_taxonomy_id );
    205                                 }
    206                         }
    207                         unset( $topic_ids );
    208                 }
    209         }
    210         unset( $terms, $term );
    211 
    212         return $message;
     354                }
     355        }
     356
     357        // Now get all term taxonomy ids with term relationships
     358        $sql_term_relationships = "SELECT `term_taxonomy_id` FROM $bbdb->term_relationships ORDER BY `term_taxonomy_id`;";
     359        $term_taxonomy_ids = $bbdb->get_col($sql_term_relationships);
     360        if ( is_wp_error( $term_taxonomy_ids ) ) {
     361                $run_once = 4;
     362                return array( 4, sprintf( $statement, $result ) );
     363        }
     364        $term_taxonomy_ids = array_unique( $term_taxonomy_ids );
     365
     366        // Delete topic tags that don't have any term relationships
     367        if ( !empty( $term_taxonomy_ids ) ) {
     368                $in_term_taxonomy_ids = implode(', ', $term_taxonomy_ids);
     369                $sql_delete_term_relationships = "DELETE
     370                FROM $bbdb->term_taxonomy
     371                WHERE
     372                        `taxonomy` = 'bb_topic_tag' AND
     373                        `term_taxonomy_id` NOT IN ($in_term_taxonomy_ids);";
     374                if ( is_wp_error( $bbdb->query( $sql_delete_term_relationships ) ) ) {
     375                        $run_once = 5;
     376                        return array( 5, sprintf( $statement, $result ) );
     377                }
     378        }
     379
     380        // Get all valid term ids
     381        $sql_terms = "SELECT `term_id` FROM $bbdb->term_taxonomy ORDER BY `term_id`;";
     382        $term_ids = $bbdb->get_col($sql_terms);
     383        if ( is_wp_error( $term_ids ) ) {
     384                $run_once = 6;
     385                return array( 6, sprintf( $statement, $result ) );
     386        }
     387        $term_ids = array_unique( $term_ids );
     388
     389        // Delete terms that don't have any associated term taxonomies
     390        if ( !empty( $term_ids ) ) {
     391                $in_term_ids = implode(', ', $term_ids);
     392                $sql_delete_terms = "DELETE
     393                FROM $bbdb->terms
     394                WHERE
     395                        `term_id` NOT IN ($in_term_ids);";
     396                if ( is_wp_error( $bbdb->query( $sql_delete_terms ) ) ) {
     397                        $run_once = 7;
     398                        return array( 7, sprintf( $statement, $result ) );
     399                }
     400        }
     401
     402        $result = __( 'Complete!' );
     403        $run_once = 0;
     404        return array( 0, sprintf( $statement, $result ) );
    213405}
    214406
     
    224416        $users = $bbdb->get_results( "SELECT `user_id`, `meta_value` AS `favorites` FROM `$bbdb->usermeta` WHERE `meta_key` = '$meta_key';" );
    225417        if ( is_wp_error( $users ) ) {
    226                 return sprintf( $statement, $result );
     418                return array( 1, sprintf( $statement, $result ) );
    227419        }
    228420
     
    230422
    231423        if ( is_wp_error( $topics ) ) {
    232                 return sprintf( $statement, $result );
     424                return array( 2, sprintf( $statement, $result ) );
    233425        }
    234426
     
    247439
    248440        if ( !count( $values ) ) {
    249                 return sprintf( $statement, $result );
     441                $result = __( 'Nothing to remove!' );
     442                return array( 0, sprintf( $statement, $result ) );
    250443        }
    251444
    252445        $sql_delete = "DELETE FROM `$bbdb->usermeta` WHERE `meta_key` = '$meta_key';";
    253446        if ( is_wp_error( $bbdb->query( $sql_delete ) ) ) {
    254                 return sprintf( $statement, $result );
     447                return array( 4, sprintf( $statement, $result ) );
    255448        }
    256449
     
    260453                $sql_insert = "INSERT INTO `$bbdb->usermeta` (`user_id`, `meta_key`, `meta_value`) VALUES $chunk;";
    261454                if ( is_wp_error( $bbdb->query( $sql_insert ) ) ) {
    262                         return sprintf( $statement, $result );
    263                 }
    264         }
    265 
    266         $result = __( 'Complete!' );
    267         return sprintf( $statement, $result );
    268 }
     455                        return array( 5, sprintf( $statement, $result ) );
     456                }
     457        }
     458
     459        $result = __( 'Complete!' );
     460        return array( 0, sprintf( $statement, $result ) );
     461}
Note: See TracChangeset for help on using the changeset viewer.