kanbanworkflowstimelinescrumrubyroadmapproject-planningproject-managementopenprojectangularissue-trackerifcgantt-chartganttbug-trackerboardsbcf
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
124 lines
3.7 KiB
124 lines
3.7 KiB
#-- copyright
|
|
# OpenProject is a project management system.
|
|
#
|
|
# Copyright (C) 2012-2013 the OpenProject Team
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License version 3.
|
|
#
|
|
# See doc/COPYRIGHT.rdoc for more details.
|
|
#++
|
|
|
|
module Migration
|
|
module Utils
|
|
UpdateResult = Struct.new(:row, :updated)
|
|
|
|
def say_with_time_silently message
|
|
say_with_time message do
|
|
suppress_messages do
|
|
yield
|
|
end
|
|
end
|
|
end
|
|
|
|
def filter(columns, terms)
|
|
column_filters = []
|
|
|
|
columns.each do |column|
|
|
filters = terms.map {|term| "#{column} LIKE '%#{term}%'"}
|
|
|
|
column_filters << "(#{filters.join(' OR ')})"
|
|
end
|
|
|
|
column_filters.join(' OR ')
|
|
end
|
|
|
|
def update_column_values(table, column_list, updater, conditions)
|
|
update_column_values_and_journals(table, column_list, updater, false, conditions)
|
|
end
|
|
|
|
def update_column_values_and_journals(table, column_list, updater, update_journal, conditions)
|
|
processed_rows = []
|
|
|
|
select_rows_from_database(table, column_list, conditions).each do |row|
|
|
processed_rows << updater.call(row)
|
|
end
|
|
|
|
updated_rows = processed_rows.select(&:updated)
|
|
|
|
update_rows_in_database(table, column_list, updated_rows.collect(&:row))
|
|
|
|
update_journals(table, updated_rows) if update_journal
|
|
end
|
|
|
|
def reset_public_key_sequence_in_postgres(table)
|
|
return unless ActiveRecord::Base.connection.instance_values["config"][:adapter] == "postgresql"
|
|
ActiveRecord::Base.connection.reset_pk_sequence!(table)
|
|
end
|
|
|
|
private
|
|
|
|
def select_rows_from_database(table, column_list, conditions)
|
|
columns = (column_list.nil?) ? '' : ', ' + column_list.join(', ')
|
|
from_clause = table
|
|
where_clause = conditions.nil? ? '1 = 1' : conditions
|
|
|
|
select_all <<-SQL
|
|
SELECT id#{columns}
|
|
FROM #{from_clause}
|
|
WHERE #{where_clause}
|
|
SQL
|
|
end
|
|
|
|
def update_rows_in_database(table, column_list, updated_rows)
|
|
columns = (column_list.nil?) ? '' : column_list.join(', ')
|
|
|
|
updated_rows.each do |row|
|
|
values = column_list.map {|c| "#{c}=#{quote(row[c])}"}
|
|
.join(', ')
|
|
|
|
update <<-SQL
|
|
UPDATE #{table}
|
|
SET #{values}
|
|
WHERE id = #{row['id']}
|
|
SQL
|
|
end
|
|
end
|
|
|
|
def update_journals(table, updated_rows)
|
|
created_journals = {}
|
|
|
|
updated_ids = updated_rows.collect {|r| r.row['id']}
|
|
journal_table = "#{table.singularize}_journals"
|
|
journable_type = table.classify
|
|
|
|
updated_ids.each do |id|
|
|
created_journals[id] = insert <<-SQL
|
|
INSERT INTO journals (journable_id, journable_type, user_id, created_at, version, activity_type)
|
|
SELECT journable_id, journable_type, #{system_user_id}, NOW(), MAX(version) + 1, activity_type
|
|
FROM journals
|
|
WHERE journable_type = '#{journable_type}' AND journable_id = #{id}
|
|
GROUP BY journable_id, journable_type, activity_type;
|
|
SQL
|
|
end
|
|
|
|
journal_table_columns = journal_table_columns(journal_table)
|
|
|
|
insert <<-SQL
|
|
INSERT INTO #{journal_table} (journal_id, #{journal_table_columns.join(", ")})
|
|
SELECT j.id AS journal_id, #{journal_table_columns.collect{|c| "w.#{c}"}.join(", ")}
|
|
FROM journals AS j JOIN #{table} AS w ON (j.journable_id = w.id)
|
|
WHERE journable_type = '#{journable_type}'
|
|
AND j.id NOT IN (SELECT journal_id FROM work_package_journals)
|
|
SQL
|
|
end
|
|
|
|
def system_user_id
|
|
@system_user_id ||= User.system.id
|
|
end
|
|
|
|
def journal_table_columns(table)
|
|
"Journal::#{table.classify}".constantize.column_names - ['id', 'journal_id']
|
|
end
|
|
end
|
|
end
|
|
|