WPDB: Allow null values in the CRUD functions.

Specifically, `::insert()`, `::replace()`, `::update()`, and `::delete()` can now set a column to `NULL`, or add the `IS NULL` condition to the `WHERE` clause.

This is based on [backpress 279].

Props pento, nbachiyski, sorich87.

Fixes #15158.



git-svn-id: https://develop.svn.wordpress.org/trunk@34737 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Gary Pendergast 2015-10-01 05:36:15 +00:00
parent 3ffcb9548d
commit f9f56fb942
2 changed files with 161 additions and 1 deletions

View File

@ -1779,6 +1779,7 @@ class wpdb {
* @param string $table Table name
* @param array $data Data to insert (in column => value pairs).
* Both $data columns and $data values should be "raw" (neither should be SQL escaped).
* Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case.
* @param array|string $format Optional. An array of formats to be mapped to each of the value in $data.
* If string, that format will be used for all of the values in $data.
* A format is one of '%d', '%f', '%s' (integer, float, string).
@ -1803,6 +1804,7 @@ class wpdb {
* @param string $table Table name
* @param array $data Data to insert (in column => value pairs).
* Both $data columns and $data values should be "raw" (neither should be SQL escaped).
* Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case.
* @param array|string $format Optional. An array of formats to be mapped to each of the value in $data.
* If string, that format will be used for all of the values in $data.
* A format is one of '%d', '%f', '%s' (integer, float, string).
@ -1827,6 +1829,7 @@ class wpdb {
* @param string $table Table name
* @param array $data Data to insert (in column => value pairs).
* Both $data columns and $data values should be "raw" (neither should be SQL escaped).
* Sending a null value will cause the column to be set to NULL - the corresponding format is ignored in this case.
* @param array|string $format Optional. An array of formats to be mapped to each of the value in $data.
* If string, that format will be used for all of the values in $data.
* A format is one of '%d', '%f', '%s' (integer, float, string).
@ -1848,6 +1851,11 @@ class wpdb {
$formats = $values = array();
foreach ( $data as $value ) {
if ( is_null( $value['value'] ) ) {
$formats[] = 'NULL';
continue;
}
$formats[] = $value['format'];
$values[] = $value['value'];
}
@ -1875,9 +1883,12 @@ class wpdb {
* @param string $table Table name
* @param array $data Data to update (in column => value pairs).
* Both $data columns and $data values should be "raw" (neither should be SQL escaped).
* Sending a null value will cause the column to be set to NULL - the corresponding
* format is ignored in this case.
* @param array $where A named array of WHERE clauses (in column => value pairs).
* Multiple clauses will be joined with ANDs.
* Both $where columns and $where values should be "raw".
* Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case.
* @param array|string $format Optional. An array of formats to be mapped to each of the values in $data.
* If string, that format will be used for all of the values in $data.
* A format is one of '%d', '%f', '%s' (integer, float, string).
@ -1904,10 +1915,20 @@ class wpdb {
$fields = $conditions = $values = array();
foreach ( $data as $field => $value ) {
if ( is_null( $value['value'] ) ) {
$fields[] = "`$field` = NULL";
continue;
}
$fields[] = "`$field` = " . $value['format'];
$values[] = $value['value'];
}
foreach ( $where as $field => $value ) {
if ( is_null( $value['value'] ) ) {
$conditions[] = "`$field` IS NULL";
continue;
}
$conditions[] = "`$field` = " . $value['format'];
$values[] = $value['value'];
}
@ -1936,6 +1957,7 @@ class wpdb {
* @param array $where A named array of WHERE clauses (in column => value pairs).
* Multiple clauses will be joined with ANDs.
* Both $where columns and $where values should be "raw".
* Sending a null value will create an IS NULL comparison - the corresponding format will be ignored in this case.
* @param array|string $where_format Optional. An array of formats to be mapped to each of the values in $where.
* If string, that format will be used for all of the items in $where.
* A format is one of '%d', '%f', '%s' (integer, float, string).
@ -1954,6 +1976,11 @@ class wpdb {
$conditions = $values = array();
foreach ( $where as $field => $value ) {
if ( is_null( $value['value'] ) ) {
$conditions[] = "`$field` IS NULL";
continue;
}
$conditions[] = "`$field` = " . $value['format'];
$values[] = $value['value'];
}

View File

@ -807,5 +807,138 @@ class Tests_DB extends WP_UnitTestCase {
function filter_pre_get_col_charset( $charset, $table, $column ) {
return 'fake_col_charset';
}
}
/**
* @ticket 15158
*/
function test_null_insert() {
global $wpdb;
$key = 'null_insert_key';
$wpdb->insert(
$wpdb->postmeta,
array(
'meta_key' => $key,
'meta_value' => NULL
),
array( '%s', '%s' )
);
$row = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_key='$key'" );
$this->assertNull( $row->meta_value );
}
/**
* @ticket 15158
*/
function test_null_update_value() {
global $wpdb;
$key = 'null_update_value_key';
$value = 'null_update_value_key';
$wpdb->insert(
$wpdb->postmeta,
array(
'meta_key' => $key,
'meta_value' => $value
),
array( '%s', '%s' )
);
$row = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_key='$key'" );
$this->assertSame( $value, $row->meta_value );
$wpdb->update(
$wpdb->postmeta,
array( 'meta_value' => NULL ),
array(
'meta_key' => $key,
'meta_value' => $value
),
array( '%s' ),
array( '%s', '%s' )
);
$row = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_key='$key'" );
$this->assertNull( $row->meta_value );
}
/**
* @ticket 15158
*/
function test_null_update_where() {
global $wpdb;
$key = 'null_update_where_key';
$value = 'null_update_where_key';
$wpdb->insert(
$wpdb->postmeta,
array(
'meta_key' => $key,
'meta_value' => NULL
),
array( '%s', '%s' )
);
$row = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_key='$key'" );
$this->assertNull( $row->meta_value );
$wpdb->update(
$wpdb->postmeta,
array( 'meta_value' => $value ),
array(
'meta_key' => $key,
'meta_value' => NULL
),
array( '%s' ),
array( '%s', '%s' )
);
$row = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_key='$key'" );
$this->assertSame( $value, $row->meta_value );
}
/**
* @ticket 15158
*/
function test_null_delete() {
global $wpdb;
$key = 'null_update_where_key';
$value = 'null_update_where_key';
$wpdb->insert(
$wpdb->postmeta,
array(
'meta_key' => $key,
'meta_value' => NULL
),
array( '%s', '%s' )
);
$row = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_key='$key'" );
$this->assertNull( $row->meta_value );
$wpdb->delete(
$wpdb->postmeta,
array(
'meta_key' => $key,
'meta_value' => NULL
),
array( '%s', '%s' )
);
$row = $wpdb->get_row( "SELECT * FROM $wpdb->postmeta WHERE meta_key='$key'" );
$this->assertNull( $row );
}
}