From 3295e62aec2fa59f8ac6209570c1777d5b784b0d Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Wed, 17 Sep 2014 23:00:57 +0100 Subject: [PATCH] Issue #2194885 by Berdir | sun: Remove drupal_write_record(). --- core/includes/schema.inc | 192 ------------------ .../src/Tests/Common/WriteRecordTest.php | 145 ------------- 2 files changed, 337 deletions(-) delete mode 100644 core/modules/system/src/Tests/Common/WriteRecordTest.php diff --git a/core/includes/schema.inc b/core/includes/schema.inc index f181c5467e30..4722cf825c42 100644 --- a/core/includes/schema.inc +++ b/core/includes/schema.inc @@ -306,198 +306,6 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU } } -/** - * Retrieves a list of fields from a table schema. - * - * The returned list is suitable for use in an SQL query. - * - * @param string $table - * The name of the table from which to retrieve fields. - * @param string $prefix - * An optional prefix to to all fields. - * - * @return array - * An array of fields. - */ -function drupal_schema_fields_sql($table, $prefix = NULL) { - if (!$schema = drupal_get_schema($table)) { - return array(); - } - $fields = array_keys($schema['fields']); - if ($prefix) { - $columns = array(); - foreach ($fields as $field) { - $columns[] = "$prefix.$field"; - } - return $columns; - } - else { - return $fields; - } -} - -/** - * Saves (inserts or updates) a record to the database based upon the schema. - * - * Do not use drupal_write_record() within hook_update_N() functions, since the - * database schema cannot be relied upon when a user is running a series of - * updates. Instead, use db_insert() or db_update() to save the record. - * - * @param string $table - * The name of the table; this must be defined by a hook_schema() - * implementation. - * @param object|array $record - * An object or array representing the record to write, passed in by - * reference. If inserting a new record, values not provided in $record will - * be populated in $record and in the database with the default values from - * the schema, as well as a single serial (auto-increment) field - * (if present). If updating an existing record, only provided values are - * updated in the database, and $record is not modified. - * @param array $primary_keys - * To indicate that this is a new record to be inserted, omit this argument. - * If this is an update, this argument specifies the primary keys' field - * names. If there is only 1 field in the key, you may pass in a string; if - * there are multiple fields in the key, pass in an array. - * - * @return bool|int - * If the record insert or update failed, returns FALSE. If it succeeded, - * returns SAVED_NEW or SAVED_UPDATED, depending on the operation performed. - */ -function drupal_write_record($table, &$record, $primary_keys = array()) { - // Standardize $primary_keys to an array. - if (is_string($primary_keys)) { - $primary_keys = array($primary_keys); - } - - $schema = drupal_get_schema($table); - if (empty($schema)) { - return FALSE; - } - - $object = (object) $record; - $fields = array(); - $default_fields = array(); - - // Go through the schema to determine fields to write. - foreach ($schema['fields'] as $field => $info) { - if ($info['type'] == 'serial') { - // Skip serial types if we are updating. - if (!empty($primary_keys)) { - continue; - } - // Track serial field so we can helpfully populate them after the query. - // NOTE: Each table should come with one serial field only. - $serial = $field; - } - - // Skip field if it is in $primary_keys as it is unnecessary to update a - // field to the value it is already set to. - if (in_array($field, $primary_keys)) { - continue; - } - - // Skip fields that are not provided, default values are already known - // by the database. property_exists() allows to explicitly set a value to - // NULL. - if (!property_exists($object, $field)) { - $default_fields[] = $field; - continue; - } - // However, if $object is an entity class instance, then class properties - // always exist, as they cannot be unset. Therefore, if $field is a serial - // type and the value is NULL, skip it. - // @see http://php.net/manual/en/function.property-exists.php - if ($info['type'] == 'serial' && !isset($object->$field)) { - $default_fields[] = $field; - continue; - } - - // Build array of fields to update or insert. - if (empty($info['serialize'])) { - $fields[$field] = $object->$field; - } - else { - $fields[$field] = serialize($object->$field); - } - - // Type cast to proper datatype, except when the value is NULL and the - // column allows this. - if (isset($object->$field) || !empty($info['not null'])) { - $fields[$field] = drupal_schema_get_field_value($info, $fields[$field]); - } - } - - // Build the SQL. - if (empty($primary_keys)) { - // We are doing an insert. - $options = array('return' => Database::RETURN_INSERT_ID); - if (isset($serial) && isset($fields[$serial])) { - // If the serial column has been explicitly set with an ID, then we don't - // require the database to return the last insert id. - if ($fields[$serial]) { - $options['return'] = Database::RETURN_AFFECTED; - } - // If a serial column does exist with no value (i.e. 0) then remove it as - // the database will insert the correct value for us. - else { - unset($fields[$serial]); - } - } - // Create an INSERT query. useDefaults() is necessary for the SQL to be - // valid when $fields is empty. - $query = db_insert($table, $options) - ->fields($fields) - ->useDefaults($default_fields); - - $return = SAVED_NEW; - } - else { - // Create an UPDATE query. - $query = db_update($table)->fields($fields); - foreach ($primary_keys as $key) { - $query->condition($key, $object->$key); - } - $return = SAVED_UPDATED; - } - - // Execute the SQL. - if ($query_return = $query->execute()) { - if (isset($serial)) { - // If the database was not told to return the last insert id, it will be - // because we already know it. - if (isset($options) && $options['return'] != Database::RETURN_INSERT_ID) { - $object->$serial = $fields[$serial]; - } - else { - $object->$serial = $query_return; - } - } - } - // If we have a single-field primary key but got no insert ID, the - // query failed. Note that we explicitly check for FALSE, because - // a valid update query which doesn't change any values will return - // zero (0) affected rows. - elseif ($query_return === FALSE && count($primary_keys) == 1) { - $return = FALSE; - } - - // If we are inserting, populate empty fields with default values. - if (empty($primary_keys)) { - foreach ($schema['fields'] as $field => $info) { - if (isset($info['default']) && !property_exists($object, $field)) { - $object->$field = $info['default']; - } - } - } - - // If we began with an array, convert back. - if (is_array($record)) { - $record = (array) $object; - } - - return $return; -} - /** * Typecasts values to proper datatypes. * diff --git a/core/modules/system/src/Tests/Common/WriteRecordTest.php b/core/modules/system/src/Tests/Common/WriteRecordTest.php deleted file mode 100644 index b0193281832b..000000000000 --- a/core/modules/system/src/Tests/Common/WriteRecordTest.php +++ /dev/null @@ -1,145 +0,0 @@ -<?php - -/** - * @file - * Definition of Drupal\system\Tests\Common\WriteRecordTest. - */ - -namespace Drupal\system\Tests\Common; - -use Drupal\simpletest\DrupalUnitTestBase; - -/** - * Tests writing of data records with drupal_write_record(). - * - * @group Common - */ -class WriteRecordTest extends DrupalUnitTestBase { - - /** - * Modules to enable. - * - * @var array - */ - public static $modules = array('database_test'); - - /** - * Tests the drupal_write_record() API function. - */ - function testDrupalWriteRecord() { - $this->installSchema('database_test', array('test', 'test_null', 'test_serialized', 'test_composite_primary')); - - // Insert a record with no columns populated. - $record = array(); - $insert_result = drupal_write_record('test', $record); - $this->assertTrue($insert_result == SAVED_NEW, 'Correct value returned when an empty record is inserted with drupal_write_record().'); - - // Insert a record - no columns allow NULL values. - $person = new \stdClass(); - $person->name = 'John'; - $person->unknown_column = 123; - $insert_result = drupal_write_record('test', $person); - $this->assertTrue($insert_result == SAVED_NEW, 'Correct value returned when a record is inserted with drupal_write_record() for a table with a single-field primary key.'); - $this->assertTrue(isset($person->id), 'Primary key is set on record created with drupal_write_record().'); - $this->assertIdentical($person->age, 0, 'Age field set to default value.'); - $this->assertIdentical($person->job, 'Undefined', 'Job field set to default value.'); - - // Verify that the record was inserted. - $result = db_query("SELECT * FROM {test} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical($result->name, 'John', 'Name field set.'); - $this->assertIdentical($result->age, '0', 'Age field set to default value.'); - $this->assertIdentical($result->job, 'Undefined', 'Job field set to default value.'); - $this->assertFalse(isset($result->unknown_column), 'Unknown column was ignored.'); - - // Update the newly created record. - $person->name = 'Peter'; - $person->age = 27; - $person->job = NULL; - $update_result = drupal_write_record('test', $person, array('id')); - $this->assertTrue($update_result == SAVED_UPDATED, 'Correct value returned when a record updated with drupal_write_record() for table with single-field primary key.'); - - // Verify that the record was updated. - $result = db_query("SELECT * FROM {test} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical($result->name, 'Peter', 'Name field set.'); - $this->assertIdentical($result->age, '27', 'Age field set.'); - $this->assertIdentical($result->job, '', 'Job field set and cast to string.'); - - // Try to insert NULL in columns that does not allow this. - $person = new \stdClass(); - $person->name = 'Ringo'; - $person->age = NULL; - $person->job = NULL; - drupal_write_record('test', $person); - $this->assertTrue(isset($person->id), 'Primary key is set on record created with drupal_write_record().'); - $result = db_query("SELECT * FROM {test} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical($result->name, 'Ringo', 'Name field set.'); - $this->assertIdentical($result->age, '0', 'Age field set.'); - $this->assertIdentical($result->job, '', 'Job field set.'); - - // Insert a record - the "age" column allows NULL. - $person = new \stdClass(); - $person->name = 'Paul'; - $person->age = NULL; - drupal_write_record('test_null', $person); - $this->assertTrue(isset($person->id), 'Primary key is set on record created with drupal_write_record().'); - $result = db_query("SELECT * FROM {test_null} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical($result->name, 'Paul', 'Name field set.'); - $this->assertIdentical($result->age, NULL, 'Age field set.'); - - // Insert a record - do not specify the value of a column that allows NULL. - $person = new \stdClass(); - $person->name = 'Meredith'; - drupal_write_record('test_null', $person); - $this->assertTrue(isset($person->id), 'Primary key is set on record created with drupal_write_record().'); - $this->assertIdentical($person->age, 0, 'Age field set to default value.'); - $result = db_query("SELECT * FROM {test_null} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical($result->name, 'Meredith', 'Name field set.'); - $this->assertIdentical($result->age, '0', 'Age field set to default value.'); - - // Update the newly created record. - $person->name = 'Mary'; - $person->age = NULL; - drupal_write_record('test_null', $person, array('id')); - $result = db_query("SELECT * FROM {test_null} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical($result->name, 'Mary', 'Name field set.'); - $this->assertIdentical($result->age, NULL, 'Age field set.'); - - // Insert a record - the "data" column should be serialized. - $person = new \stdClass(); - $person->name = 'Dave'; - drupal_write_record('test_serialized', $person); - $result = db_query("SELECT * FROM {test_serialized} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical($result->name, 'Dave', 'Name field set.'); - $this->assertIdentical($result->info, NULL, 'Info field set.'); - - $person->info = array(); - drupal_write_record('test_serialized', $person, array('id')); - $result = db_query("SELECT * FROM {test_serialized} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical(unserialize($result->info), array(), 'Info field updated.'); - - // Update the serialized record. - $data = array('foo' => 'bar', 1 => 2, 'empty' => '', 'null' => NULL); - $person->info = $data; - drupal_write_record('test_serialized', $person, array('id')); - $result = db_query("SELECT * FROM {test_serialized} WHERE id = :id", array(':id' => $person->id))->fetchObject(); - $this->assertIdentical(unserialize($result->info), $data, 'Info field updated.'); - - // Run an update query where no field values are changed. The database - // layer should return zero for number of affected rows, but - // db_write_record() should still return SAVED_UPDATED. - $update_result = drupal_write_record('test_null', $person, array('id')); - $this->assertTrue($update_result == SAVED_UPDATED, 'Correct value returned when a valid update is run without changing any values.'); - - // Insert an object record for a table with a multi-field primary key. - $composite_primary = new \stdClass(); - $composite_primary->name = $this->randomMachineName(); - $composite_primary->age = mt_rand(); - $insert_result = drupal_write_record('test_composite_primary', $composite_primary); - $this->assertTrue($insert_result == SAVED_NEW, 'Correct value returned when a record is inserted with drupal_write_record() for a table with a multi-field primary key.'); - - // Update the record. - $update_result = drupal_write_record('test_composite_primary', $composite_primary, array('name', 'job')); - $this->assertTrue($update_result == SAVED_UPDATED, 'Correct value returned when a record is updated with drupal_write_record() for a table with a multi-field primary key.'); - } - -} -- GitLab