forked from padrino/padrino-framework
/
mongoid.rb
115 lines (96 loc) · 3.62 KB
/
mongoid.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
if defined?(Mongoid)
namespace :mi do
desc 'Drops all the collections for the database for the current Padrino.env'
task :drop => :environment do
Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
end
# Helper to retrieve a list of models.
def get_mongoid_models
documents = []
Dir['{app,.}/models/*.rb'].sort.each do |file|
model_path = file[0..-4].split('/')[2..-1]
begin
klass = model_path.map(&:classify).join('::').constantize
if klass.ancestors.include?(Mongoid::Document) && !klass.embedded
documents << klass
end
rescue => e
# Just for non-mongoid objects that dont have the embedded
# attribute at the class level.
end
end
documents
end
desc 'Create the indexes defined on your mongoid models'
task :create_indexes => :environment do
get_mongoid_models.each { |model| model.create_indexes }
end
def convert_ids(obj)
if obj.is_a?(String) && obj =~ /^[a-f0-9]{24}$/
BSON::ObjectId(obj)
elsif obj.is_a?(Array)
obj.map do |v|
convert_ids(v)
end
elsif obj.is_a?(Hash)
obj.each do |k, v|
obj[k] = convert_ids(v)
end
else
obj
end
end
def collection_names
@collection_names ||= get_mongoid_models.map{ |d| d.collection.name }.uniq
end
desc "Convert string objectids in mongo database to ObjectID type"
task :objectid_convert => :environment do
collection_names.each do |collection_name|
puts "Converting #{collection_name} to use ObjectIDs"
# get old collection
collection = Mongoid.master.collection(collection_name)
# get new collection (a clean one)
collection.db["#{collection_name}_new"].drop
new_collection = collection.db["#{collection_name}_new"]
# convert collection documents
collection.find({}, :timeout => false, :sort => "_id") do |cursor|
cursor.each do |doc|
new_doc = convert_ids(doc)
new_collection.insert(new_doc, :safe => true)
end
end
puts "Done! Converted collection is in #{new_collection.name}\n\n"
end
# no errors. great! now rename _new to collection_name
collection_names.each do |collection_name|
collection = Mongoid.master.collection(collection_name)
new_collection = collection.db["#{collection_name}_new"]
# swap collection to _old
puts "Moving #{collection.name} to #{collection_name}_old"
collection.db["#{collection_name}_old"].drop
begin
collection.rename("#{collection_name}_old")
rescue StandardError => e
puts "Unable to rename database #{collection_name} to #{collection_name}_old"
puts "reason: #{e.message}\n\n"
end
# swap _new to collection
puts "Moving #{new_collection.name} to #{collection_name}\n\n"
begin
new_collection.rename(collection_name)
rescue StandardError => e
puts "Unable to rename database #{new_collection.name} to #{collection_name}"
puts "reason: #{e.message}\n\n"
end
end
puts "DONE! Run `padrino rake mi:cleanup_old_collections` to remove old collections"
end
desc "Clean up old collections backed up by objectid_convert"
task :cleanup_old_collections => :environment do
collection_names.each do |collection_name|
collection = Mongoid.master.collection(collection_name)
collection.db["#{collection.name}_old"].drop
end
end
end
end