rails_age 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,257 +0,0 @@
1
- # lib/tasks/install.rake
2
- # Usage: `rake apache_age:install`
3
- #
4
- namespace :apache_age do
5
- desc "Install & configure Apache Age within Rails (updates migrations, schema & database.yml)"
6
- task :install_old => :environment do
7
- source_schema = File.expand_path('../../../db/schema.rb', __FILE__)
8
- destination_schema = File.expand_path("#{Rails.root}/db/schema.rb", __FILE__)
9
- source_migrations = File.expand_path('../../../db/migrate', __FILE__)
10
- destination_migrations = File.expand_path("#{Rails.root}/db/migrate", __FILE__)
11
- # create the migrations folder if needed
12
- FileUtils.mkdir_p(destination_migrations) unless File.exist?(destination_migrations)
13
- original_migrations =
14
- Dir.glob("#{destination_migrations}/*.rb").map { |file| File.basename(file).sub(/^\d+/, '') }
15
-
16
- # # check if the schema is non-existent or blank (NEW) we need to know how to handle schema
17
- # is_schema_blank = !File.exist?(destination_schema) || blank_schema?(destination_schema)
18
- # puts "Schema is blank: #{is_schema_blank}"
19
-
20
- # ensure we have a schema file
21
- unless File.exist?(destination_schema)
22
- run_db_create
23
- run_db_migrate
24
- end
25
-
26
- # copy our migrations to the application (last_migration_version is nil if no migration necessary)
27
- # last_migration_version = copy_migrations
28
- Rake::Task["apache_age:copy_migrations"].invoke
29
-
30
- updated_migrations =
31
- Dir.glob("#{destination_migrations}/*.rb").map { |file| File.basename(file).sub(/^\d+/, '') }
32
-
33
- # # run our new migrations (unless we have not added any new migrations)
34
- # if original_migrations == updated_migrations
35
- # puts "no new migrations were copied, skipping migrations"
36
- # else
37
- # puts "added Apache Age migrations, running migrations"
38
- # run_db_migrate
39
- # end
40
- run_db_migrate
41
-
42
- # adjust the schema file (unfortunately rails mangles the schema file)
43
- # if is_schema_blank
44
- # puts "creating new schema..."
45
- # create_new_schema(last_migration_version, destination_schema, source_schema)
46
- # else
47
- # puts "updating existing schema..."
48
- # update_existing_schema(last_migration_version, destination_schema, source_schema)
49
- # end
50
- Rake::Task["apache_age:schema_config"].invoke
51
-
52
- # ensure the config/database.yml file has the proper configurations
53
- # update_database_yml
54
- Rake::Task["apache_age:database_config"].invoke
55
- end
56
-
57
- def run_db_create
58
- puts "Running db:create..."
59
- Rake::Task["db:create"].invoke
60
- end
61
-
62
- def run_db_migrate
63
- puts "Running db:migrate..."
64
- Rake::Task["db:migrate"].invoke
65
- end
66
-
67
- def copy_migrations
68
- migration_version = nil
69
-
70
- source = File.expand_path('../../../db/migrate', __FILE__)
71
- destination = File.expand_path("#{Rails.root}/db/migrate", __FILE__)
72
-
73
- FileUtils.mkdir_p(destination) unless File.exist?(destination)
74
- existing_migrations =
75
- Dir.glob("#{destination}/*.rb").map { |file| File.basename(file).sub(/^\d+/, '') }
76
-
77
- Dir.glob("#{source}/*.rb").each do |file|
78
- filename = File.basename(file)
79
- test_name = filename.sub(/^\d+/, '')
80
-
81
- if existing_migrations.include?(test_name)
82
- puts "Skipping #{filename}, it already exists"
83
- else
84
- migration_version = Time.now.utc.strftime("%Y_%m_%d_%H%M%S")
85
- file_version = migration_version.delete('_')
86
- new_filename = filename.sub(/^\d+/, file_version)
87
- destination_file = File.join(destination, new_filename)
88
- FileUtils.cp(file, destination_file)
89
- puts "Copied #{filename} to #{destination} as #{new_filename}"
90
- end
91
- end
92
- migration_version
93
- end
94
-
95
- def blank_schema?(destination_schema)
96
- return false unless File.exist?(destination_schema)
97
-
98
- content = File.read(destination_schema)
99
- content.include?('define(version: 0)') &&
100
- (content.include?("enable_extension 'plpgsql'") || content.include?('enable_extension "plpgsql"')) &&
101
- content.scan(/enable_extension/).size == 1
102
- end
103
-
104
- def schema_rails_version(destination_schema)
105
- if File.exist?(destination_schema)
106
- content = File.read(destination_schema)
107
- version_match = content.match(/ActiveRecord::Schema\[(.*?)\]/)
108
- return version_match[1] if version_match
109
- else
110
- full_version = Rails.version
111
- primary_secondary_version = full_version.split('.')[0..1].join('.')
112
- primary_secondary_version
113
- end
114
- end
115
-
116
- def create_new_schema(last_migration_version, destination_schema, source_schema)
117
- if File.exist?(source_schema) && File.exist?(destination_schema)
118
- rails_version = schema_rails_version(destination_schema)
119
- source_content = File.read(source_schema)
120
-
121
- # ensure we use the Rails version from the destination schema
122
- source_content.gsub!(
123
- /ActiveRecord::Schema\[\d+\.\d+\]/,
124
- "ActiveRecord::Schema[#{rails_version}]"
125
- )
126
- # ensure we use the last migration version (not the source schema version)
127
- source_content.gsub!(
128
- /define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do/,
129
- "define(version: #{last_migration_version}) do"
130
- )
131
-
132
- File.write(destination_schema, source_content)
133
- puts "Created new schema in #{destination_schema} with necessary extensions and configurations."
134
- else
135
- puts "local db/schema.rb file not found."
136
- end
137
- end
138
-
139
- def update_existing_schema(last_migration_version, destination_schema, source_schema)
140
- if File.exist?(source_schema) && File.exist?(destination_schema)
141
- rails_version = schema_rails_version(destination_schema)
142
- source_content = File.read(source_schema)
143
- new_content =
144
- source_content.gsub(
145
- /.*ActiveRecord::Schema\[\d+\.\d+\]\.define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do\n|\nend$/,
146
- ''
147
- )
148
-
149
- destination_content = File.read(destination_schema)
150
-
151
- # Remove unwanted schema statements
152
- destination_content.gsub!(%r{^.*?create_schema "ag_catalog".*?\n}, '')
153
- destination_content.gsub!(%r{^.*?create_schema "age_schema".*?\n}, '')
154
- destination_content.gsub!(%r{^.*?enable_extension "age".*?\n}, '')
155
- destination_content.gsub!(%r{^.*?enable_extension "plpgsql".*?\n}, '')
156
- destination_content.gsub!(%r{^.*?# Could not dump table "ag_graph" because of following StandardError.*?\n}, '')
157
- destination_content.gsub!(%r{^.*?# Unknown type 'regnamespace' for column 'namespace'.*?\n}, '')
158
- destination_content.gsub!(%r{^.*?# Could not dump table "ag_label" because of following StandardError.*?\n}, '')
159
- destination_content.gsub!(%r{^.*?# Unknown type 'regclass' for column 'relation'.*?\n}, '')
160
- destination_content.gsub!(%r{^.*?# Unknown type 'graphid' for column 'id'.*?\n}, '')
161
- destination_content.gsub!(
162
- %r{^.*?# Could not dump table "_ag_label_edge" because of following StandardError.*?\n}, ''
163
- )
164
- destination_content.gsub!(
165
- %r{^.*?# Could not dump table "_ag_label_vertex" because of following StandardError.*?\n}, ''
166
- )
167
- destination_content.gsub!(%r{^.*?# Could not dump table "ag_graph" because of following StandardError.*?\n}, '')
168
- destination_content.gsub!(%r{^.*?# Could not dump table "ag_label" because of following StandardError.*?\n}, '')
169
- destination_content.gsub!(%r{^.*?add_foreign_key "ag_label", "ag_graph".*?\n}, '')
170
-
171
- # add new wanted schema statements (at the top of the schema)
172
- unless destination_content.include?(%{execute("LOAD 'age';")}) &&
173
- destination_content.include?(%{enable_extension 'plpgsql'}) &&
174
- destination_content.include?(%{execute("SELECT create_graph('age_schema');")}) &&
175
- destination_content.include?(%{execute('CREATE EXTENSION IF NOT EXISTS age;')}) &&
176
- destination_content.include?(%{execute('SET search_path = ag_catalog, "$user", public;')})
177
- # if not all are found then remove any found
178
- destination_content.gsub!(%r{^.*?execute("LOAD 'age';")*?\n}, '')
179
- destination_content.gsub!(%r{^.*?enable_extension 'plpgsql'*?\n}, '')
180
- destination_content.gsub!(%r{^.*?execute("SELECT create_graph('age_schema');")*?\n}, '')
181
- destination_content.gsub!(%r{^.*?execute('CREATE EXTENSION IF NOT EXISTS age;')*?\n}, '')
182
- destination_content.gsub!(%r{^.*?execute('SET search_path = ag_catalog, "$user", public;')*?\n}, '')
183
- destination_content.gsub!(%r{^.*?# Allow age extension*?\n}, '')
184
- destination_content.gsub!(%r{^.*?# Load the ag_catalog into the search path*?\n}, '')
185
- destination_content.gsub!(%r{^.*?# Create age_schema graph if it doesn't exist*?\n}, '')
186
- destination_content.gsub!(%r{^.*?# These are extensions that must be enabled in order to support this database*?\n}, '')
187
-
188
- # add all of the correct settings back in
189
- destination_content.sub!(
190
- %r{(ActiveRecord::Schema\[\d+\.\d+\]\.define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do\n)},
191
- "\\1#{new_content}\n"
192
- )
193
- puts 'db/schema.rb has been updated with the necessary configuration.'
194
- else
195
- puts 'db/schema.rb has the necessary configuration, no adjustments necessary'
196
- end
197
-
198
- existing_version = destination_content.match(/define\(version: (\d{4}(?:_\d{2}){2}(?:_\d{6})?)\)/)[1].gsub('_', '')
199
- current_version = last_migration_version ? last_migration_version.gsub('_', '') : existing_version
200
-
201
- # ensure we use the last migration version (not the source schema version)
202
- if current_version.to_i > existing_version.to_i
203
- destination_content.gsub!(
204
- /define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do/,
205
- "define(version: #{last_migration_version}) do"
206
- )
207
- puts "Updated schema version to the migration version #{last_migration_version}"
208
- end
209
-
210
- File.write(destination_schema, destination_content)
211
- puts "Updated #{destination_schema} with necessary extensions and configurations."
212
- else
213
- puts "local db/schema.rb file not found."
214
- end
215
- end
216
-
217
- def update_database_yml
218
- db_config_file = File.expand_path("#{Rails.root}/config/database.yml", __FILE__)
219
-
220
- # Read the file
221
- lines = File.readlines(db_config_file)
222
-
223
- # any uncommented "schema_search_path:" lines?
224
- path_index = lines.find_index { |line| !line.include?('#') && line.include?('schema_search_path:') }
225
- default_start_index = lines.index { |line| line.strip.start_with?('default:') }
226
-
227
- # when it finds an existing schema_search_path, it updates it
228
- if path_index && lines[path_index].include?('ag_catalog,age_schema')
229
- puts "schema_search_path already set to ag_catalog,age_schema nothing to do."
230
- return
231
- elsif path_index
232
- key, val = lines[path_index].split(': ')
233
- # remove any unwanted characters
234
- val = val.gsub(/[ "\s\"\"'\n]/, '')
235
- lines[path_index] = "#{key}: ag_catalog,age_schema,#{val}\n"
236
- puts "add ag_catalog,age_schema to schema_search_path"
237
- elsif default_start_index
238
- puts "add ag_catalog,age_schema,public to schema_search_path in the default section of database.yml"
239
- sections_index = lines.map.with_index { |line, index| index if !line.start_with?(' ') }.compact.sort
240
-
241
- # find the start of the default section
242
- next_section_in_list = sections_index.index(default_start_index) + 1
243
-
244
- # find the end of the default section (before the next section starts)
245
- path_insert_index = sections_index[next_section_in_list]
246
-
247
- lines.insert(path_insert_index, " schema_search_path: ag_catalog,age_schema,public\n")
248
- else
249
- puts "didn't find a default section in database.yml, please add the following line:"
250
- puts " schema_search_path: ag_catalog,age_schema,public"
251
- puts "to the apprpriate section of your database.yml"
252
- end
253
-
254
- # Write the modified lines back to the file
255
- File.open(db_config_file, 'w') { |file| file.write(lines.join) }
256
- end
257
- end