=== modified file 'modules/system/system.install' --- modules/system/system.install 2010-02-18 04:36:38 +0000 +++ modules/system/system.install 2010-02-26 14:21:36 +0000 @@ -2224,28 +2224,121 @@ /** * Migrate upload module files to the new {file} table. */ -function system_update_7035() { +function system_update_7035(&$sandbox) { if (!db_table_exists('upload')) { return; } - // The old {files} tables still exists. We migrate core data from upload - // module, but any contrib module using it will need to do its own update. - $result = db_query('SELECT f.fid, uid, filename, filepath AS uri, filemime, filesize, status, timestamp FROM {files} f INNER JOIN {upload} u ON u.fid = f.fid', array(), array('fetch' => PDO::FETCH_ASSOC)); - - // We will convert filepaths to uri using the default schmeme - // and stripping off the existing file directory path. - $basename = variable_get('file_directory_path', conf_path() . '/files'); - $scheme = variable_get('file_default_scheme', 'public') . '://'; - $fids = array(); - // TODO: does this function need to run in batch mode, or should we use a multi-insert? - foreach ($result as $file) { - $file['uri'] = $scheme . str_replace($basename, '', $file['uri']); - $file['uri'] = file_stream_wrapper_uri_normalize($file['uri']); - db_insert('file')->fields($file)->execute(); - $fids[] = $file['fid']; - } - // TODO: delete the found fids from {files}? + $field = field_info_field('files'); + + if (!isset($sandbox['progress'])) { + if (empty($field)) { + $field = array( + 'field_name' => 'files', + 'type' => 'file', + 'object_types' => array('node'), + 'cardinality' => 0, + 'settings' => array( + 'display_field' => 1, + 'display_default' => variable_get('upload_list_default', 1), + 'uri_scheme' => variable_get('file_default_scheme', 'public'), + ), + ); + $field = field_create_field($field); + } + + $node_types = node_type_get_types(); + + foreach ($node_types as $type) { + $instance = field_info_instance('node', 'files', $type->type); + + if (variable_get('upload_' . $type->type, TRUE) && empty($instance)) { + $upload_extensions_default = variable_get('upload_extensions_default', 'jpg jpeg gif png txt doc xls pdf ppt pps odt ods odp'); + $upload_uploadsize_default = variable_get('upload_uploadsize_default', 1); + + $instance = array( + 'field_name' => 'files', + 'object_type' => 'node', + 'bundle' => $type->type, + 'label' => 'File attachments', + 'settings' => array( + 'file_extensions' => $upload_extensions_default, + 'max_filesize' => $upload_uploadsize_default, + 'description_field' => 1, + ), + ); + + field_create_instance($instance); + } + } + + $sandbox['progress'] = 0; + $sandbox['current_fid'] = 0; + $sandbox['current_vid'] = 0; + $sandbox['max'] = db_query("SELECT COUNT(DISTINCT fid) FROM {upload}")->fetchField(); + } + else { + $limit = 200; + + // The old {files} tables still exists. We migrate core data from upload + // module, but any contrib module using it will need to do its own update. + $result = db_query_range('SELECT u.nid, u.vid, n.type, u.fid, uid, filename, filepath AS uri, filemime, filesize, status, timestamp FROM {files} AS f INNER JOIN {upload} AS u ON u.fid = f.fid INNER JOIN {node} AS n ON u.nid = n.nid WHERE f.fid > :fid OR (f.fid = :current_fid AND u.vid > :vid) ORDER BY u.fid, u.vid', 0, $limit, array(':fid' => $sandbox['current_fid'], ':current_fid' => $sandbox['current_fid'], ':vid' => $sandbox['current_vid']), array('fetch' => PDO::FETCH_ASSOC)); + + // We will convert filepaths to uri using the default schmeme + // and stripping off the existing file directory path. + $basename = variable_get('file_directory_path', conf_path() . '/files'); + $scheme = variable_get('file_default_scheme', 'public') . '://'; + + // Keep track of how many files each node has across invocations. + $sandbox['deltas'] = array(); + // Don't need to keep the node data across invocations because we are only + // inserting data. + $nodes = array(); + + foreach ($result as $file) { + if (!isset($nodes[$file['vid']])) { + $node = (object) array( + 'nid' => $file['nid'], + 'vid' => $file['vid'], + 'type' => $file['type'], + 'uploads' => array(), + ); + $deltas[$node->vid] = 0; + } + else { + $node = $nodes[$file['vid']]; + } + + // Several node revisions may have the same file. Only copy file data once. + if ($sandbox['current_fid'] != $file['fid']) { + // Hide node fields from the insert query. + unset($file['nid']); + unset($file['vid']); + unset($file['type']); + + $file['uri'] = $scheme . str_replace($basename, '', $file['uri']); + $file['uri'] = file_stream_wrapper_uri_normalize($file['uri']); + $new_fid = db_insert('file')->fields($file)->execute(); + } + + $node->files[LANGUAGE_NONE][$sandbox['deltas'][$node->vid]++] = $file; + + $sandbox['progress']++; + $sandbox['current_fid'] = $file['fid']; + $sandbox['current_vid'] = $node->vid; + $sandbox['message'] = check_plain($file['filename']); + } + + foreach ($nodes as $node) { + // This is a core update and no contrib modules are enabled yet, so + // we can assume default field storage for a faster update. + field_sql_storage_field_storage_write('node', $node, FIELD_STORAGE_INSERT, array($field['id'])); + } + } + + if ($sandbox['progress'] < $sandbox['max']) { + $sandbox['#finished'] = $sandbox['progress'] / $sandbox['max']; + } } /**