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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +53 -6
- data/README.md +82 -341
- data/lib/apache_age/entities/edge.rb +3 -3
- data/lib/apache_age/validators/unique_edge_validator.rb +4 -4
- data/lib/apache_age/validators/unique_vertex_validator.rb +2 -2
- data/lib/generators/apache_age/edge/USAGE +54 -0
- data/lib/generators/apache_age/edge/edge_generator.rb +56 -0
- data/lib/generators/apache_age/edge/templates/edge.rb.tt +20 -0
- data/lib/generators/apache_age/node/USAGE +54 -0
- data/lib/generators/apache_age/node/node_generator.rb +94 -0
- data/lib/generators/apache_age/node/templates/node.rb.tt +17 -0
- data/lib/rails_age/version.rb +1 -1
- data/lib/tasks/{database_config.rake → config_database.rake} +1 -1
- data/lib/tasks/config_migrate.rake +35 -0
- data/lib/tasks/{schema_config.rake → config_schema.rake} +1 -2
- data/lib/tasks/config_types.rake +85 -0
- data/lib/tasks/install.rake +10 -3
- data/lib/tasks/migrate.rake +7 -0
- metadata +13 -5
- data/lib/tasks/install.original.rake +0 -257
@@ -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
|