@@ -12,14 +12,11 @@ def self.up
1212
1313 return if Rails . env . test?
1414
15- unless connection . adapter_name =~ /postgres|mysql/i
15+ unless connection . adapter_name =~ /postgres/
1616 $stderr. puts "don't know how to migrate conversation data for #{ connection . adapter_name } !"
1717 return
1818 end
1919
20- mysql = %w{ MySQL Mysql2 } . include? ( connection . adapter_name )
21- table_opts = mysql ? 'engine=innodb' : 'AS'
22-
2320 # for grouping messages into conversations
2421 # private: list of participant ids <= 2
2522 # group: root_context_message_id + list of participant ids (if the list changes, it's a different conversation)
@@ -32,7 +29,7 @@ def self.up
3229 add_column :conversation_message_participants , :unread , :boolean
3330
3431 execute <<-SQL
35- CREATE TEMPORARY TABLE __migrated_messages #{ table_opts }
32+ CREATE TEMPORARY TABLE __migrated_messages AS
3633 SELECT
3734 id,
3835 user_id AS author_id,
@@ -41,15 +38,14 @@ def self.up
4138 COALESCE(root_context_message_id, id) AS root_context_message_id,
4239 media_comment_id,
4340 media_comment_type,
44- '' #{ mysql ? '' : ':: TEXT'} AS signature
41+ ':: TEXT' AS signature
4542 FROM
4643 #{ connection . quote_table_name ( 'context_messages' ) }
4744 SQL
48- change_column :__migrated_messages , :signature , :text if mysql
4945 execute "CREATE INDEX index__migrated_messages_on_id ON __migrated_messages (id)"
5046
5147 execute <<-SQL
52- CREATE TEMPORARY TABLE __migrated_message_participants #{ table_opts }
48+ CREATE TEMPORARY TABLE __migrated_message_participants AS
5349 SELECT DISTINCT
5450 context_message_id AS migrated_message_id,
5551 user_id
@@ -58,72 +54,47 @@ def self.up
5854 SQL
5955 execute "CREATE INDEX index_mmp_on_message_id ON __migrated_message_participants (migrated_message_id)"
6056
61- if mysql
62- execute <<-SQL
63- CREATE TEMPORARY TABLE __migrated_message_participant_strings #{ table_opts }
64- SELECT migrated_message_id, GROUP_CONCAT(DISTINCT user_id ORDER BY user_id) AS participants, COUNT(DISTINCT user_id) <= 2 AS private
57+ execute <<-SQL
58+ CREATE TEMPORARY TABLE __migrated_message_participant_strings AS
59+ SELECT migrated_message_id, STRING_AGG(user_id::TEXT, ',') AS participants, COUNT(DISTINCT user_id) <= 2 AS private
60+ FROM (
61+ SELECT DISTINCT migrated_message_id, user_id
6562 FROM __migrated_message_participants
66- GROUP BY migrated_message_id
67- SQL
68- else
69- execute <<-SQL
70- CREATE TEMPORARY TABLE __migrated_message_participant_strings #{ table_opts }
71- SELECT migrated_message_id, STRING_AGG(user_id::TEXT, ',') AS participants, COUNT(DISTINCT user_id) <= 2 AS private
72- FROM (
73- SELECT DISTINCT migrated_message_id, user_id
74- FROM __migrated_message_participants
75- ORDER BY migrated_message_id, user_id
76- ) p
77- GROUP BY migrated_message_id
78- SQL
79- end
63+ ORDER BY migrated_message_id, user_id
64+ ) p
65+ GROUP BY migrated_message_id
66+ SQL
8067 execute "CREATE INDEX index_mmps_on_migrated_message_id ON __migrated_message_participant_strings (migrated_message_id)"
8168
8269 execute <<-SQL
83- UPDATE __migrated_messages #{ mysql ? ", __migrated_message_participant_strings" : "" }
70+ UPDATE __migrated_messages
8471 SET signature = CASE WHEN private THEN '' ELSE root_context_message_id || ':' END || participants
85- #{ mysql ? "" : " FROM __migrated_message_participant_strings" }
72+ FROM __migrated_message_participant_strings
8673 WHERE migrated_message_id = __migrated_messages.id
8774 SQL
88- if mysql
89- execute "CREATE INDEX index___migrated_messages_on_signature ON __migrated_messages (signature(767))"
90- else
91- execute "CREATE INDEX index___migrated_messages_on_signature ON __migrated_messages (signature)"
92- end
75+ execute "CREATE INDEX index___migrated_messages_on_signature ON __migrated_messages (signature)"
9376
9477 execute <<-SQL
9578 INSERT INTO #{ Conversation . quoted_table_name } (migration_signature, has_attachments, has_media_objects)
9679 SELECT DISTINCT signature, FALSE, FALSE
9780 FROM __migrated_messages
9881 SQL
99- if mysql
100- execute "CREATE INDEX index_conversations_on_migration_signature ON conversations (migration_signature(767))"
101- else
102- add_index :conversations , :migration_signature
103- end
82+ add_index :conversations , :migration_signature
10483
105- if mysql
106- update <<-SQL
107- UPDATE #{ Conversation . quoted_table_name }
108- SET tmp_private_hash = SHA(migration_signature)
109- WHERE migration_signature REGEXP '^[0-9]+(,[0-9]+)?$'
110- SQL
111- else
112- Conversation . where ( "migration_signature ~ E'^[0-9]+(,[0-9]+)?$'" ) . find_each ( :batch_size => 10000 ) do |conversation |
113- conversation . update_attribute :tmp_private_hash , Digest ::SHA1 . hexdigest ( conversation . migration_signature )
114- end
84+ Conversation . where ( "migration_signature ~ E'^[0-9]+(,[0-9]+)?$'" ) . find_each ( :batch_size => 10000 ) do |conversation |
85+ conversation . update_attribute :tmp_private_hash , Digest ::SHA1 . hexdigest ( conversation . migration_signature )
11586 end
11687 add_index :conversations , :tmp_private_hash
11788
11889 # in case any private conversations already exist...
11990 update <<-SQL
120- UPDATE #{ Conversation . quoted_table_name } #{ mysql ? ", #{ Conversation . quoted_table_name } c2" : "" }
121- SET #{ mysql ? "conversations." : "" } migration_signature = c2.migration_signature
122- #{ mysql ? "" : " FROM #{ Conversation . quoted_table_name } c2" }
91+ UPDATE #{ Conversation . quoted_table_name }
92+ SET migration_signature = c2.migration_signature
93+ FROM #{ Conversation . quoted_table_name } c2
12394 WHERE conversations.private_hash = c2.tmp_private_hash
12495 SQL
12596 execute <<-SQL
126- CREATE TEMPORARY TABLE __existing_private_conversations #{ table_opts }
97+ CREATE TEMPORARY TABLE __existing_private_conversations AS
12798 SELECT private_hash FROM #{ Conversation . quoted_table_name } WHERE private_hash IS NOT NULL
12899 SQL
129100 delete <<-SQL
@@ -133,9 +104,7 @@ def self.up
133104 # create participants for any group conversations or *new* private conversations
134105 remove_index :conversation_participants , :column => [ :user_id , :last_message_at ]
135106 add_index :conversation_participants , :user_id # temporary for better insert speeds (and to prevent people hitting new messaging from killing the db)
136- subquery = mysql ?
137- "SELECT signature, id FROM __migrated_messages GROUP BY signature ORDER BY signature, id DESC" :
138- "SELECT DISTINCT ON (signature) signature, id FROM __migrated_messages ORDER BY signature, id DESC"
107+ subquery = "SELECT DISTINCT ON (signature) signature, id FROM __migrated_messages ORDER BY signature, id DESC"
139108 execute <<-SQL
140109 INSERT INTO #{ ConversationParticipant . quoted_table_name } (conversation_id, user_id, subscribed, workflow_state, has_attachments, has_media_objects)
141110 SELECT c.id, mp.user_id, TRUE, 'read', FALSE, FALSE
@@ -222,9 +191,9 @@ def self.up
222191
223192 # attachments
224193 update <<-SQL
225- UPDATE #{ Attachment . quoted_table_name } #{ mysql ? ', conversation_messages' : '' }
194+ UPDATE #{ Attachment . quoted_table_name }
226195 SET context_id = conversation_messages.id, context_type = 'ConversationMessage'
227- #{ mysql ? '' : " FROM #{ ConversationMessage . quoted_table_name } " }
196+ FROM #{ ConversationMessage . quoted_table_name }
228197 WHERE attachments.context_type = 'ContextMessage' AND conversation_messages.context_message_id = attachments.context_id
229198 SQL
230199
@@ -276,7 +245,7 @@ def self.up
276245
277246 # cached stats
278247 execute <<-SQL
279- CREATE TEMPORARY TABLE __migrated_conversation_stats #{ table_opts }
248+ CREATE TEMPORARY TABLE __migrated_conversation_stats AS
280249 SELECT
281250 conversation_participant_id,
282251 COUNT(*) AS message_count,
@@ -289,36 +258,20 @@ def self.up
289258 execute "CREATE INDEX index_mcs_on_cpi ON __migrated_conversation_stats (conversation_participant_id)"
290259
291260 update <<-SQL
292- UPDATE #{ ConversationParticipant . quoted_table_name } #{ mysql ? ', __migrated_conversation_stats' : '' }
293- SET #{ mysql ? 'conversation_participants.' : '' } message_count = __migrated_conversation_stats.message_count,
294- #{ mysql ? 'conversation_participants.' : '' } last_message_at = __migrated_conversation_stats.last_message_at,
295- #{ mysql ? 'conversation_participants.' : '' } last_authored_at = __migrated_conversation_stats.last_authored_at
296- #{ mysql ? '' : ' FROM __migrated_conversation_stats'}
261+ UPDATE #{ ConversationParticipant . quoted_table_name }
262+ SET message_count = __migrated_conversation_stats.message_count,
263+ last_message_at = __migrated_conversation_stats.last_message_at,
264+ last_authored_at = __migrated_conversation_stats.last_authored_at
265+ ' FROM __migrated_conversation_stats'
297266 WHERE conversation_participants.id = conversation_participant_id
298267 SQL
299- if mysql
300- execute <<-SQL
301- ALTER TABLE #{ ConversationParticipant . quoted_table_name }
302- ADD INDEX index_conversation_participants_on_user_id_and_last_message_at (user_id, last_message_at),
303- DROP INDEX index_conversation_participants_on_user_id
304- SQL
305- else
306- add_index :conversation_participants , [ :user_id , :last_message_at ]
307- remove_index :conversation_participants , :column => :user_id
308- end
268+ add_index :conversation_participants , [ :user_id , :last_message_at ]
269+ remove_index :conversation_participants , :column => :user_id
309270
310- if mysql
311- update <<-SQL
312- UPDATE #{ User . quoted_table_name } , (SELECT COUNT(*) AS unread_count, user_id FROM #{ ConversationParticipant . quoted_table_name } WHERE workflow_state = 'unread' GROUP BY user_id) AS counts
313- SET unread_conversations_count = unread_count
314- WHERE user_id = users.id
315- SQL
316- else
317- execute <<-SQL
318- UPDATE #{ User . quoted_table_name }
319- SET unread_conversations_count = (SELECT COUNT(*) FROM #{ ConversationParticipant . quoted_table_name } WHERE workflow_state = 'unread' AND user_id = users.id)
320- SQL
321- end
271+ execute <<-SQL
272+ UPDATE #{ User . quoted_table_name }
273+ SET unread_conversations_count = (SELECT COUNT(*) FROM #{ ConversationParticipant . quoted_table_name } WHERE workflow_state = 'unread' AND user_id = users.id)
274+ SQL
322275
323276 remove_column :conversations , :migration_signature
324277 remove_column :conversations , :tmp_private_hash
0 commit comments