WordPress.org

Make WordPress Core

Ticket #22196: upsert.diff

File upsert.diff, 3.9 KB (added by donpark, 4 years ago)

UPSERT Patch

  • wp-includes/wp-db.php

     
    20502050        }
    20512051
    20522052        /**
     2053         * Insert or update (UPSERT) a row into a table.
     2054         *
     2055         *     wpdb::upsert( 'table', array( 'column' => 'foo', 'field' => 'bar' ) )
     2056         *     wpdb::upsert( 'table', array( 'column' => 'foo', 'field' => 1337 ), array( '%s', '%d' ), [ 'id' ] )
     2057         *
     2058         * @since 3.0.0
     2059         * @see wpdb::prepare()
     2060         * @see wpdb::$field_types
     2061         * @see wp_set_wpdb_vars()
     2062         *
     2063         * @param string       $table  Table name
     2064         * @param array        $data   Data to insert (in column => value pairs).
     2065         *                             Both $data columns and $data values should be "raw" (neither should be SQL escaped).
     2066         *                             Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case.
     2067         * @param array|string $format Optional. An array of formats to be mapped to each of the value in $data.
     2068         *                             If string, that format will be used for all of the values in $data.
     2069         *                             A format is one of '%d', '%f', '%s' (integer, float, string).
     2070         *                             If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
     2071         * @param array|string $keys   Optional, An array of primary or unique key column names to filter out when updating.
     2072         *                             If string, that will be assumed to be a primary or unique key column name.
     2073         * @return int|false The number of rows affected, or false on error.
     2074         */
     2075        public function upsert( $table, $data, $format = null, $keys = null ) {
     2076                return $this->_insert_replace_helper( $table, $data, $format, 'UPSERT', $keys );
     2077        }
     2078
     2079        /**
    20532080         * Helper function for insert and replace.
    20542081         *
    20552082         * Runs an insert or replace query based on $type argument.
     
    20692096         *                             A format is one of '%d', '%f', '%s' (integer, float, string).
    20702097         *                             If omitted, all values in $data will be treated as strings unless otherwise specified in wpdb::$field_types.
    20712098         * @param string $type         Optional. What type of operation is this? INSERT or REPLACE. Defaults to INSERT.
     2099         * @param array|string $keys   Optional, An array of primary or unique key column names to filter out when updating.
     2100         *                             If string, that will be assumed to be a primary or unique key column name.
    20722101         * @return int|false The number of rows affected, or false on error.
    20732102         */
    2074         function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT' ) {
     2103        function _insert_replace_helper( $table, $data, $format = null, $type = 'INSERT', $keys = null ) {
    20752104                $this->insert_id = 0;
    20762105
    2077                 if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT' ) ) ) {
     2106                if ( ! in_array( strtoupper( $type ), array( 'REPLACE', 'INSERT', 'UPSERT' ) ) ) {
    20782107                        return false;
    20792108                }
    20802109
     
    20972126                $fields  = '`' . implode( '`, `', array_keys( $data ) ) . '`';
    20982127                $formats = implode( ', ', $formats );
    20992128
    2100                 $sql = "$type INTO `$table` ($fields) VALUES ($formats)";
     2129                if ($type !== 'UPSERT') {
     2130                        $sql = "$type INTO `$table` ($fields) VALUES ($formats)";
     2131                } else {
     2132                        if (is_string($keys)) {
     2133                                $keys = array($keys);
     2134                        }
     2135                        $updates = array();
     2136                        foreach ( $data as $field => $value ) {
     2137                                if (is_array($keys) && in_array($field, $keys)) {
     2138                                        continue;
     2139                                }
     2140                                if ( is_null( $value['value'] ) ) {
     2141                                        $updates[] = "$field=NULL";
     2142                                        continue;
     2143                                }
     2144                                $format = $value['format'];
     2145                                $updates[] = "$field=$format";
     2146                                $values[]  = $value['value'];
     2147                        }
     2148                        $updates = implode( ', ', $updates );
     2149                        $sql = "INSERT INTO `$table` ($fields) VALUES ($formats) ON DUPLICATE KEY UPDATE $updates";
     2150                }
    21012151
    21022152                $this->check_current_query = false;
    21032153                return $this->query( $this->prepare( $sql, $values ) );