OpenProject is the leading open source project management software.
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.
 
 
 
 
 
 
openproject/db/migrate/012_migrate_legacy.rb

167 lines
5.7 KiB

class MigrateLegacy < ActiveRecord::Migration
def self.normalize_value(v, t)
return nil if v.class == NilClass
case t
when :int
return Integer(v)
when :bool
if [TrueClass, FalseClass].include?(v.class)
return v
else
return ! (['', '0'].include?("#{v}"))
end
else
return v
end
end
def self.row(r, t)
return r.size.times.collect{|i| MigrateLegacy.normalize_value(r[i], t[i])}
end
def self.up
begin
execute "select count(*) from backlogs"
legacy = true
rescue
legacy = false
end
ActiveRecord::Base.connection.commit_db_transaction
if legacy
Story.reset_column_information
Issue.reset_column_information
Task.reset_column_information
if Story.trackers.nil? || Story.trackers.size == 0 || Task.tracker.nil?
raise "Please configure the Backlogs Story and Task trackers before migrating.
You do this by starting Redmine and going to \"Administration -> Plugins -> Redmine Scrum Plugin -> Configure\"
and setting up the Task tracker and one or more Story trackers.
You might have to go to \"Administration -> Trackers\" first
and create new trackers for this purpose. After doing this, stop
redmine and re-run this migration."
end
trackers = {}
# find story/task trackers per project
execute("
select projects.id as project_id, pt.tracker_id as tracker_id
from projects
left join projects_trackers pt on pt.project_id = projects.id").each { |row|
project_id, tracker_id = MigrateLegacy.row(row, [:int, :int])
trackers[project_id] ||= {}
trackers[project_id][:story] = tracker_id if Story.trackers.include?(tracker_id)
trackers[project_id][:task] = tracker_id if Task.tracker == tracker_id
}
# close existing transactions and turn on autocommit
ActiveRecord::Base.connection.commit_db_transaction
say_with_time "Migrating Backlogs data..." do
bottom = 0
execute("select coalesce(max(position), 0) from items").each { |row|
bottom = row[0].to_i
}
bottom += 1
connection = ActiveRecord::Base.connection
stories = execute "
select story.issue_id, story.points, versions.id, issues.project_id
from items story
join issues on issues.id = story.issue_id
left join items parent on parent.id = story.parent_id and story.parent_id <> 0
left join backlogs sprint on story.backlog_id = sprint.id and sprint.id <> 0
left join versions on versions.id = sprint.version_id and sprint.version_id <> 0
where parent.id is null
order by coalesce(story.position, #{bottom}) desc, story.created_at desc"
stories.each { |row|
id, points, sprint, project = MigrateLegacy.row(row, [:int, :int, :int, :int])
say "Updating story #{id}"
story = Story.find(id)
if ! Story.trackers.include?(story.tracker_id)
raise "Project #{project} does not have a story tracker configured" unless trackers[project][:story]
story.tracker_id = trackers[project][:story]
story.save!
end
story.fixed_version_id = sprint
story.story_points = points
story.save!
# because we're inserting the stories last-first, this
# position gets shifted down 1 spot each time, yielding a
# neatly compacted position list
story.insert_at 1
}
tasks = execute "
select task.issue_id, versions.id, parent.issue_id, task_issue.project_id
from items task
join issues task_issue on task_issue.id = task.issue_id
join items parent on parent.id = task.parent_id and task.parent_id <> 0
join issues parent_issue on parent_issue.id = parent.issue_id
left join backlogs sprint on task.backlog_id = sprint.id and sprint.id <> 0
left join versions on versions.id = sprint.version_id and sprint.version_id <> 0
order by coalesce(task.position, #{bottom}), task.created_at"
tasks.each { |row|
id, sprint, parent_id, project = MigrateLegacy.row(row, [:int, :int, :int, :int])
say "Updating task #{id}"
task = Task.find(id)
if ! Task.tracker == task.tracker_id
raise "Project #{project} does not have a task tracker configured" unless trackers[project][:task]
task.tracker_id = trackers[project][:task]
task.save!
end
# because we're inserting the tasks first-last, adding it to
# the story will yield the correct order
task.fixed_version_id = sprint
task.parent_issue_id = parent_id
task.save!
}
res = execute "select version_id, start_date, is_closed from backlogs"
res.each { |row|
version, start_date, is_closed = MigrateLegacy.row(row, [:int, :string, :bool])
status = connection.quote(is_closed ? 'closed' : 'open')
version = connection.quote(version == 0 ? nil : version)
start_date = connection.quote(start_date)
execute "update versions set status = #{status}, sprint_start_date = #{start_date} where id = #{version}"
}
end
execute %{
insert into burndown_days (version_id, points_committed, points_accepted, created_at)
select version_id, scope, done, backlog_chart_data.created_at
from backlogs
join backlog_chart_data on backlogs.id = backlog_id
}
ActiveRecord::Base.connection.commit_db_transaction
drop_table :backlogs
drop_table :items
end
end
def self.down
#pass
end
end