diff options
author | Dries Buytaert <dries@buytaert.net> | 2007-10-02 16:15:56 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2007-10-02 16:15:56 +0000 |
commit | 4bb5080ebe210c5fc0e90549dcacfb088d4cbce3 (patch) | |
tree | b96ad761a3142351804d6108b23759deb1440451 /includes | |
parent | c389c90529d45b33c21f55fc7b7f4539fcea762c (diff) | |
download | brdo-4bb5080ebe210c5fc0e90549dcacfb088d4cbce3.tar.gz brdo-4bb5080ebe210c5fc0e90549dcacfb088d4cbce3.tar.bz2 |
- Patch #169982 by moshe, eaton, bjaspan, nedjo, yched, et al: missing feature from schema API: load/save records based upon schema.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/common.inc | 141 | ||||
-rw-r--r-- | includes/database.inc | 6 | ||||
-rw-r--r-- | includes/database.mysql-common.inc | 2 | ||||
-rw-r--r-- | includes/database.pgsql.inc | 2 | ||||
-rw-r--r-- | includes/file.inc | 6 |
5 files changed, 150 insertions, 7 deletions
diff --git a/includes/common.inc b/includes/common.inc index 080d95681..12051c7a9 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2995,6 +2995,147 @@ function _drupal_initialize_schema($module, &$schema) { } /** + * Retrieve a list of fields from a table schema. The list is suitable for use in a SQL query. + * + * @param $table + * The name of the table from which to retrieve fields. + * @param + * An optional prefix to to all fields. + * + * @return An array of fields. + **/ +function drupal_schema_fields_sql($table, $prefix = NULL) { + $schema = drupal_get_schema($table); + $fields = array_keys($schema['fields']); + if ($prefix) { + $columns = array(); + foreach ($fields as $field) { + $columns[] = "$prefix.$field"; + } + return $columns; + } + else { + return $fields; + } +} + +/** + * Save a record to the database based upon the schema. Default values are + * filled in for missing items, and 'serial' (auto increment) types are + * filled in with IDs. + * + * @param $table + * The name of the table; this must exist in schema API. + * @param $object + * The object to write. This is a reference, as defaults according to + * the schema may be filled in on the object, as well as ID on the serial + * type(s). Both array an object types may be passed. + * @param update + * If this is an update, specify the primary keys' field names. It is the + * caller's responsibility to know if a record for this object already + * exists in the database. If there is only 1 key, you may pass a simple string. + * @return (boolean) Failure to write a record will return FALSE. Otherwise, + * TRUE is returned. The $object parameter contains values for any serial + * fields defined by the $table. For example, $object->nid will be populated + * after inserting a new node. + */ +function drupal_write_record($table, &$object, $update = array()) { + // Standardize $update to an array. + if (is_string($update)) { + $update = array($update); + } + + // Convert to an object if needed. + if (is_array($object)) { + $object = (object) $object; + $array = TRUE; + } + else { + $array = FALSE; + } + + $schema = drupal_get_schema($table); + if (empty($schema)) { + return FALSE; + } + + $fields = $defs = $values = $serials = array(); + + // Go through our schema, build SQL, and when inserting, fill in defaults for + // fields that are not set. + foreach ($schema['fields'] as $field => $info) { + // Special case -- skip serial types if we are updating. + if ($info['type'] == 'serial' && count($update)) { + continue; + } + + // For inserts, populate defaults from Schema if not already provided + if (!isset($object->$field) && !count($update) && isset($info['default'])) { + $object->$field = $info['default']; + } + + // Track serial fields so we can helpfully populate them after the query. + if ($info['type'] == 'serial') { + $serials[] = $field; + // Ignore values for serials when inserting data. Unsupported. + $object->$field = 'NULL'; + } + + // Build arrays for the fields, placeholders, and values in our query. + if (isset($object->$field)) { + $fields[] = $field; + $placeholders[] = db_type_placeholder($info['type']); + + if (empty($info['serialize'])) { + $values[] = $object->$field; + } + else { + $values[] = serialize($object->$field); + } + } + } + + // Build the SQL. + $query = ''; + if (!count($update)) { + $query = "INSERT INTO {$table} (" . implode(', ', $fields) . ') VALUES (' . implode(', ', $placeholders) . ')'; + $return = SAVED_NEW; + } + else { + $query = ''; + foreach ($fields as $id => $field) { + if ($query) { + $query .= ', '; + } + $query .= $field . ' = ' . $placeholders[$id]; + } + + foreach ($update as $key){ + $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']); + $values[] = $object->$key; + } + + $query = "UPDATE {$table} SET $query WHERE ". implode(' AND ', $conditions); + $return = SAVED_UPDATED; + } + db_query($query, $values); + + if ($serials) { + // Get last insert ids and fill them in. + foreach ($serials as $field) { + $object->$field = db_last_insert_id($table, $field); + } + } + + // If we began with an array, convert back so we don't surprise the caller. + if ($array) { + $object = (array)$object; + } + + return $return; +} + +/** * @} End of "ingroup schemaapi". */ diff --git a/includes/database.inc b/includes/database.inc index d82f94d00..95e09feb5 100644 --- a/includes/database.inc +++ b/includes/database.inc @@ -199,7 +199,7 @@ function _db_query_callback($match, $init = FALSE) { * The Schema API type of a field (e.g. 'int', 'text', or 'varchar'). */ function db_placeholders($arguments, $type = 'int') { - $placeholder = _db_type_placeholder($type); + $placeholder = db_type_placeholder($type); return implode(',', array_fill(0, count($arguments), $placeholder)); } @@ -487,7 +487,7 @@ function db_field_names($fields) { * @return * The placeholder string to embed in a query for that type. */ -function _db_type_placeholder($type) { +function db_type_placeholder($type) { switch ($type) { case 'varchar': case 'text': @@ -516,7 +516,7 @@ function _db_type_placeholder($type) { // There is no safe value to return here, so return something that // will cause the query to fail. - return 'unsupported type '. $type .'for _db_type_placeholder'; + return 'unsupported type '. $type .'for db_type_placeholder'; } /** diff --git a/includes/database.mysql-common.inc b/includes/database.mysql-common.inc index 181039ec4..7632f4a12 100644 --- a/includes/database.mysql-common.inc +++ b/includes/database.mysql-common.inc @@ -297,7 +297,7 @@ function db_add_field(&$ret, $table, $field, $spec, $keys_new = array()) { $ret[] = update_sql($query); if (isset($spec['initial'])) { // All this because update_sql does not support %-placeholders. - $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. _db_type_placeholder($spec['type']); + $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. db_type_placeholder($spec['type']); $result = db_query($sql, $spec['initial']); $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql .' ('. $spec['initial'] .')')); } diff --git a/includes/database.pgsql.inc b/includes/database.pgsql.inc index 663934d72..6bf37f615 100644 --- a/includes/database.pgsql.inc +++ b/includes/database.pgsql.inc @@ -700,7 +700,7 @@ function db_add_field(&$ret, $table, $field, $spec, $new_keys = array()) { $ret[] = update_sql($query); if (isset($spec['initial'])) { // All this because update_sql does not support %-placeholders. - $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. _db_type_placeholder($spec['type']); + $sql = 'UPDATE {'. $table .'} SET '. $field .' = '. db_type_placeholder($spec['type']); $result = db_query($sql, $spec['initial']); $ret[] = array('success' => $result !== FALSE, 'query' => check_plain($sql .' ('. $spec['initial'] .')')); } diff --git a/includes/file.inc b/includes/file.inc index 5c8d28e04..a7ba5fb7c 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -574,8 +574,10 @@ function file_save_upload($source, $validators = array(), $dest = FALSE, $replac } // If we made it this far it's safe to record this file in the database. - db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", $user->uid, $file->filename, $file->filepath, $file->filemime, $file->filesize, FILE_STATUS_TEMPORARY, time()); - $file->fid = db_last_insert_id('files', 'fid'); + $file->uid = $user->uid; + $file->status = FILE_STATUS_TEMPORARY; + $file->timestamp = time(); + drupal_write_record('files', $file); // Add file to the cache. $upload_cache[$source] = $file; |