Skip to content

Commit

Permalink
More work on data migration from 0.x to 1.0 (tested).
Browse files Browse the repository at this point in the history
  • Loading branch information
gaspard committed Mar 15, 2011
1 parent dd53d1a commit 0e023e8
Showing 1 changed file with 120 additions and 63 deletions.
183 changes: 120 additions & 63 deletions bricks/zena/zena/migrate/03_zerox1_data.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

require 'fileutils'
# ============================================ contact_contents
# migrate content to properties
class ContactContent < ActiveRecord::Base
Expand Down Expand Up @@ -53,7 +53,7 @@ def migrate_attachment(version)
fname = name.gsub(/[^a-zA-Z\-_0-9]/,'')

if File.exist?("#{SITES_ROOT}#{$site.data_path}/full") && !File.exist?("#{SITES_ROOT}#{$site.data_path}/full_old")
File.mv("#{SITES_ROOT}#{$site.data_path}/full","#{SITES_ROOT}#{$site.data_path}/full_old")
FileUtils.mv("#{SITES_ROOT}#{$site.data_path}/full","#{SITES_ROOT}#{$site.data_path}/full_old")
end
old_path = "#{SITES_ROOT}#{$site.data_path}/full_old/#{digest[0..0]}/#{digest[1..1]}/#{digest[2..2]}/#{fname}"

Expand Down Expand Up @@ -99,6 +99,15 @@ def migrate(version)
end
end

# ============================================ site_attributes
class SiteAttribute < ActiveRecord::Base
set_table_name :site_attributes

def migrate(site)
site.prop[key] = value
end
end

# ============================================ template_contents
# migrate content to properties
# rebuild index ==> should recreate idx_templates content
Expand All @@ -121,14 +130,24 @@ def migrate(version)
class VersionMig < ActiveRecord::Base
set_table_name :versions
belongs_to :node, :class_name => 'NodeMig', :foreign_key => 'node_id'
has_one :contact_content, :foreign_key => 'version_id'
has_one :document_content, :foreign_key => 'version_id'
has_one :template_content, :foreign_key => 'node_id', :primary_key => 'node_id'

include Property
# Should be the same serialization as in Version and Site
include Property::Serialization::JSON

def contact_content
@contact_content ||= ContactContent.find(:first,
:conditions => ['version_id = ?', content_id || id]
)
end

def document_content
@document_content ||= DocumentContent.find(:first,
:conditions => ['version_id = ?', content_id || id]
)
end

def migrate!
migrate_base
migrate_contact
Expand Down Expand Up @@ -196,20 +215,112 @@ def self.inheritance_column
# === dyn_attributes

class SiteMig < ActiveRecord::Base
CHUNK_SIZE = 200
has_many :site_attributes, :class_name => 'SiteAttribute', :foreign_key => 'owner_id'

include Property

set_table_name :sites

def data_path
"/#{self[:host]}/data"
end

def migrate!
# needed by DocumentContent
$site = self

# Allow any property
class << self.prop
def validate
# do nothing
true
end
end

migrate_nodes
migrate_site
if !save
puts "Could not save site #{id} (#{host}):"
errors.each_error do |er,msg|
puts " [#{er}] #{msg}"
end
end
end

def migrate_nodes
node_count = NodeMig.count(:conditions =>['site_id = ?', id])
puts "========================================== Start data migration to 1.0 for #{host} (#{node_count} nodes)"
puts "========== creating virtual classes (Contact, Reference)"
# Create Contact + Reference virtual classes
ref_class = VClassMig.create(
:name => 'Reference',
:kpath => 'NR',
:real_class => 'Node',
:create_group_id => public_group_id,
:site_id => id
)
contact_class = VClassMig.create(
:name => 'Contact',
:kpath => 'NRC',
:real_class => 'Node',
:create_group_id => public_group_id,
:site_id => id
)
# Update nodes depending on Contact + Reference classes
execute "UPDATE nodes SET vclass_id = #{ref_class.id} WHERE type = 'Reference' AND vclass_id IS NULL AND site_id = #{id}"
execute "UPDATE nodes SET vclass_id = #{contact_class.id} WHERE type = 'Contact' AND vclass_id IS NULL AND site_id = #{id}"
execute "UPDATE nodes SET type = 'Node' WHERE (type = 'Reference' or type = 'Contact') AND site_id = #{id}"

page = 0
while true do
nodes = NodeMig.find(:all,
:conditions => ['site_id = ?', id],
:limit => CHUNK_SIZE,
:offset => page * CHUNK_SIZE,
:order => 'id ASC'
)
break if nodes == []
puts "========== migrating nodes #{(page * CHUNK_SIZE) + 1} to #{[((page+1) * CHUNK_SIZE), node_count].min}"
nodes.each do |n|
n.versions.each do |v|
v.migrate!
end
end
page += 1
end

# ============================================ nodes
# 1. Set skin_id from skin name
NodeMig.find(:all,
:conditions => ['site_id = ? AND type = ?', id, 'Skin']
).each do |skin|
execute "UPDATE nodes SET skin_id = #{skin.id} WHERE skin = '#{skin.name}'"
end

# 2. Set _id from name
execute "UPDATE nodes SET _id = name WHERE site_id = #{id}"
end

def migrate_site
# ============================================ site_attributes
# migrate to properties
site_attributes.each do |attribute|
attribute.migrate(self)
end
end

private
def execute(*args)
self.class.connection.execute(*args)
end
end


# This migration should be run in the 1.0 branch *AFTER* the migration
# to Zerox1Schema.
class Zerox1Data < ActiveRecord::Migration
extend Zena::Acts::Secure

CHUNK_SIZE = 200
def self.up
if connection.tables.include?('contact_contents')
# Need to migrate data
Expand All @@ -229,70 +340,16 @@ def self.up

execute "UPDATE roles SET real_class = 'Node' WHERE real_class = 'Reference' OR real_class = 'Contact'"

# sites = SiteMig.all
sites = [SiteMig.find(:first, :conditions => ['host = ?', 'lubyk.org'])]
sites = SiteMig.all
sites.each do |site|
node_count = NodeMig.count(:conditions =>['site_id = ?', site.id])
puts "========================================== Start data migration to 1.0 for #{site.host} (#{node_count} nodes)"
puts "========== creating virtual classes (Contact, Reference)"
# Create Contact + Reference virtual classes
ref_class = VClassMig.create(
:name => 'Reference',
:kpath => 'NR',
:real_class => 'Node',
:create_group_id => site.public_group_id,
:site_id => site.id
)
contact_class = VClassMig.create(
:name => 'Contact',
:kpath => 'NRC',
:real_class => 'Node',
:create_group_id => site.public_group_id,
:site_id => site.id
)
# Update nodes depending on Contact + Reference classes
execute "UPDATE nodes SET vclass_id = #{ref_class.id} WHERE type = 'Reference' AND vclass_id IS NULL AND site_id = #{site.id}"
execute "UPDATE nodes SET vclass_id = #{contact_class.id} WHERE type = 'Contact' AND vclass_id IS NULL AND site_id = #{site.id}"
execute "UPDATE nodes SET type = 'Node' WHERE (type = 'Reference' or type = 'Contact') AND site_id = #{site.id}"

$site = site
page = 0
while true do
nodes = NodeMig.find(:all,
:conditions => ['site_id = ?', site.id],
:limit => CHUNK_SIZE,
:offset => page * CHUNK_SIZE,
:order => 'id ASC'
)
break if nodes == []
puts "========== migrating nodes #{(page * CHUNK_SIZE) + 1} to #{[((page+1) * CHUNK_SIZE), node_count].min}"
nodes.each do |n|
n.versions.each do |v|
v.migrate!
end
end
page += 1
end

# ============================================ nodes
# 1. Set skin_id from skin name
NodeMig.find(:all,
:conditions => ['site_id = ? AND type = ?', site.id, 'Skin']
).each do |skin|
execute "UPDATE nodes SET skin_id = #{skin.id} WHERE skin = '#{skin.name}'"
end

# 2. Set _id from name
execute "UPDATE nodes SET _id = name WHERE site_id = #{site.id}"
end # sites.each
site.migrate!
end

# ============================================ roles
# make properties from dyn_keys list ?

execute "UPDATE roles SET type = 'VirtualClass'"

# ============================================ site_attributes
# migrate to properties

puts "\n\n======== Migration succeded.\n****************** You need to rebuild vhash, fullpath and index now! *************\n=> rake zena:rebuild_vhash && rake zena:rebuild_fullpath && rake zena:rebuild_index\n\n"
end
Expand Down

0 comments on commit 0e023e8

Please sign in to comment.