diff --git a/database/updates.inc b/database/updates.inc index bc09a0b1009caf3270008233cdef03e678ac2e17..ed3a59ae580844beaa3a8cb59762906217241959 100644 --- a/database/updates.inc +++ b/database/updates.inc @@ -1588,6 +1588,22 @@ function system_update_172() { function system_update_173() { $ret = array(); + // State tracker to determine whether we keep a backup of the files table or not. + $safe = TRUE; + + // PostgreSQL needs CREATE TABLE foobar _AS_ SELECT ... + $AS = ($GLOBALS['db_type'] == 'pgsql') ? 'AS' : ''; + + // Backup the files table. + $ret[] = update_sql("CREATE TABLE {files_backup} $AS SELECT * FROM {files}"); + + // Do some files table sanity checking and cleanup. + $ret[] = update_sql('DELETE FROM {files} WHERE fid = 0'); + $ret[] = update_sql('UPDATE {files} SET vid = nid WHERE vid = 0'); + + // Create a temporary table to build the new file_revisions and files tables from. + $ret[] = update_sql("CREATE TABLE {files_tmp} $AS SELECT * FROM {files}"); + $ret[] = update_sql('DROP TABLE {files}'); switch ($GLOBALS['db_type']) { case 'pgsql': @@ -1598,11 +1614,13 @@ function system_update_173() { description varchar(255) NOT NULL default '', list smallint NOT NULL default 0, PRIMARY KEY (fid, vid))"); - $ret[] = update_sql("INSERT INTO {file_revisions} SELECT fid, vid, description, list FROM {files}"); + $result = update_sql("INSERT INTO {file_revisions} SELECT DISTINCT ON (fid,vid) fid, vid, description, list FROM {files_tmp}"); + $ret[] = $result; + if ($result['success'] === FALSE) { + $safe = FALSE; + } - // alter files table - $ret[] = update_sql("CREATE TABLE {files_copy} AS SELECT * FROM {files}"); - $ret[] = update_sql("DROP TABLE {files}"); + // Create normalized files table $ret[] = update_sql("CREATE TABLE {files} ( fid SERIAL, nid integer NOT NULL default 0, @@ -1611,10 +1629,16 @@ function system_update_173() { filemime varchar(255) NOT NULL default '', filesize integer NOT NULL default 0, PRIMARY KEY (fid))"); - $ret[] = update_sql("INSERT INTO {files} SELECT DISTINCT ON (fid) fid, nid, filename, filepath, filemime, filesize FROM {files_copy}"); + $result = update_sql("INSERT INTO {files} SELECT DISTINCT ON (fid) fid, nid, filename, filepath, filemime, filesize FROM {files_tmp}"); + $ret[] = $result; + if ($result['success'] === FALSE) { + $safe = FALSE; + } + $ret[] = update_sql("SELECT setval('{files}_fid_seq', max(fid)) FROM {files}"); - $ret[] = update_sql("DROP TABLE {files_copy}"); + break; + case 'mysqli': case 'mysql': // create file_revisions table @@ -1625,11 +1649,14 @@ function system_update_173() { list tinyint(1) unsigned NOT NULL default 0, PRIMARY KEY (fid, vid) ) /*!40100 DEFAULT CHARACTER SET utf8 */"); - $ret[] = update_sql('INSERT INTO {file_revisions} SELECT fid, vid, description, list FROM {files}'); - // alter files table - $ret[] = update_sql("CREATE TABLE {files_copy} AS SELECT * FROM {files}"); - $ret[] = update_sql("DROP TABLE {files}"); + // Try as you might mysql only does distinct row if you are selecting more than 1 column. + $result = update_sql('INSERT INTO {file_revisions} SELECT DISTINCT fid , vid, description, list FROM {files_tmp}'); + $ret[] = $result; + if ($result['success'] === FALSE) { + $safe = FALSE; + } + $ret[] = update_sql("CREATE TABLE {files} ( fid int(10) unsigned NOT NULL default 0, nid int(10) unsigned NOT NULL default 0, @@ -1639,11 +1666,25 @@ function system_update_173() { filesize int(10) unsigned NOT NULL default 0, PRIMARY KEY (fid) ) /*!40100 DEFAULT CHARACTER SET utf8 */"); - $ret[] = update_sql("INSERT IGNORE INTO {files} SELECT fid, nid, filename, filepath, filemime, filesize FROM {files_copy}"); - $ret[] = update_sql("DROP TABLE {files_copy}"); + $result = update_sql("INSERT INTO {files} SELECT DISTINCT fid, nid, filename, filepath, filemime, filesize FROM {files_tmp}"); + $ret[] = $result; + if ($result['success'] === FALSE) { + $safe = FALSE; + } + break; } + $ret[] = update_sql("DROP TABLE {files_tmp}"); + + // Remove original files table if all went well. Otherwise preserve it and notify user. + if ($safe) { + $ret[] = update_sql("DROP TABLE {files_backup}"); + } + else { + drupal_set_message(t('Normalizing files table failed. A backup of the original table called {files_backup} remains in your database.')); + } + return $ret; }