rails_age 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 349925c4b715d64987c69a6a20b23e67c9076d91152477a976ade763805fdbf7
4
- data.tar.gz: 4c7f1e430fe94ac3cb59eac8e6cb94bc03edab9532074c0df75be233b1210973
3
+ metadata.gz: aa956147280cd1ef2125eb39f3dd7867eadafde15806d95b90dab30d1290b135
4
+ data.tar.gz: a5b3a61d2fcf3026f9503b1bb4a9c6e60c6317f92266501f2890c2a02af1a01d
5
5
  SHA512:
6
- metadata.gz: af26f1a10253235703203804e508aa0d0dfbe7e44cc92097f70111587663c9af75e6cfd730fcb0986dc6093bb9bb16c847ab66ad7d3249057d3fe8adf443c78e
7
- data.tar.gz: f98980a1937efeef70c1e548b2f62f5b2a7e2f383f707a92e8392a8f45b1bc9ac882a1f478fff0f24f1fcb3cb145e0f037202356ea4a2e76737ee81f4c70b459
6
+ metadata.gz: a2dbb2a72e8f64056bf6531fab29da715bdc89d1748dce2fe92a44de11b5a8c74dbc354c18a903472c996c90e01f7947c921819d3cded09b4ffbfe1cbd0da33c
7
+ data.tar.gz: d5265daf4c4a1928bdd8f7f08a1efd884f8c4ce5da38d56321f58f6f507905a24d7587d2f92bacfe5a4141e500f7f81060726a2723368b443d8892bf2e66a9b3
data/CHANGELOG.md CHANGED
@@ -1,7 +1,9 @@
1
1
  # Change Log
2
2
 
3
- ## VERSION 0.3.0 - 2024-xx-xx
3
+ ## VERSION 0.4.0 - 2024-xx-xx
4
4
 
5
+ - **Edges**
6
+ * `find_edge` is deprecated - use `find_by` with :start_node, :end_node to find an edge with specific nodes
5
7
  - **cypher**
6
8
  * query support
7
9
  * paths support
@@ -9,10 +11,28 @@
9
11
  - **Paths**
10
12
  * ?
11
13
 
14
+ ## VERSION 0.3.1 - 2024-xx-xx
15
+
16
+ - **Genetator**
17
+ * add `rails generate apache_age:node` to create a node model (with its type in initializer)
18
+ * add `rails generate apache_age:edge` to create an edge model (with its type in initializer)
19
+ - **Installer**
20
+ * refactored into multiple independent tasks?
21
+
22
+ ## VERSION 0.3.0 - 2024-05-28
23
+
24
+ - **Installer** (`rails generate apache_age:install`)
25
+ * copy Age PG Extenstion migration to `db/migrate`
26
+ * run the AGE PG Migration
27
+ * repair `db/schema.rb` (rails mangles schema after running pg extension)
28
+ * update `database.yml` with schema search paths
29
+
30
+ NOTE: the `rails generate apache_age:install` can be run at any time to repair the schema (or other config) file if needed.
31
+
12
32
  ## VERSION 0.2.0 - 2024-05-26
13
33
 
14
34
  - **Edges**
15
- * add class methods to find_edge(with {properties, end_id, start_id})
35
+ * add class methods to `find_edge` (with {properties, end_id, start_id})
16
36
  * add missing methods to use in rails controllers
17
37
  * validate edge start- & end-nodes are valid
18
38
  * add unique edge validations
@@ -25,13 +45,13 @@
25
45
  Initial release has the following features:
26
46
 
27
47
  - **Nodes:**
28
- * Create, Read, Update, Delete & .find(by id), .find_by(age_property), .all
48
+ * `.create`, `.read`, `.update`, `.delete`, `.all`, `.find(by id)`, `.find_by(age_properties)`
29
49
  * verified with usage in a controller and views
30
50
  - **Edges:**
31
- * Create, Read, Update, Delete & .find(by id), .find_by(age_property), .all
51
+ *`.create`, `.read`, `.update`, `.delete`, `.all`, `.find(by id)`, `.find_by(age_properties)`
32
52
  * verified with usage in a controller and views
33
53
  - **Entities:**
34
- * find (by id), find_by(age_property), all; when class/label and/or edge/node is unknown)
54
+ * `.all`, `.find(id)`, `.find_by(age_property)` use these when class, label, edge, node
35
55
 
36
56
  These can be used within Rails applications using a Rails APIs including within controllers and views.
37
57
  See the [README](README.md) for more information.
data/README.md CHANGED
@@ -12,24 +12,26 @@ Add this line to your application's Gemfile:
12
12
  gem "rails_age"
13
13
  ```
14
14
 
15
- And then execute:
15
+ ### Quick Install
16
16
 
17
17
  ```bash
18
18
  $ bundle
19
+ $ bin/rails apache_age:install
20
+ $ git add .
21
+ $ git commit -m "Add Apache Age to Rails"
19
22
  ```
20
23
 
21
- Or install it yourself as:
24
+ NOTE: it is important to add the db/schema.rb to your git repository because `rails db:migrate` will inappropriately modify the schema file. However, you can run `bin/rails apache_age:install` at any time to repair the schema file if needed.
22
25
 
23
- ```bash
24
- $ gem install rails_age
25
- ```
26
-
27
- finally (tempoarily you need to copy and run the migration)
28
- https://github.com/marpori/rails_age/blob/main/db/migrate/20240521062349_configure_apache_age.rb
26
+ ### Manual Install
29
27
 
28
+ create a migration to add the Apache Age extension to your database
30
29
  ```bash
31
- # db/migrate/20240521062349_configure_apache_age.rb
32
- class ConfigureApacheAge < ActiveRecord::Migration[7.1]
30
+ $ bin/rails g migration AddApacheAge
31
+ ```
32
+ copy the contents of https://github.com/marpori/rails_age/blob/main/db/migrate/20240521062349_add_apache_age.rb
33
+ ```ruby
34
+ class AddApacheAge < ActiveRecord::Migration[7.1]
33
35
  def up
34
36
  # Allow age extension
35
37
  execute('CREATE EXTENSION IF NOT EXISTS age;')
@@ -65,13 +67,42 @@ class ConfigureApacheAge < ActiveRecord::Migration[7.1]
65
67
  end
66
68
  end
67
69
  ```
70
+ into your new migration file
71
+
72
+ then run the migration
73
+ ```bash
74
+ $ bin/rails db:migrate
75
+ ```
76
+
77
+ Rails migrate will mangle the schema `db/schema.rb` file. You need to remove the lines that look like:
78
+ ```ruby
79
+ create_schema "ag_catalog"
80
+ create_schema "age_schema"
81
+
82
+ # These are extensions that must be enabled in order to support this database
83
+ enable_extension "age"
84
+ enable_extension "plpgsql"
68
85
 
69
- and fix the TOP of `schema.rb` file to match the following (note: the version number should be the same as the LARGEST version number in your `db/migrations` folder)
70
- https://github.com/marpori/rails_age/blob/main/db/schema.rb
86
+ # Could not dump table "_ag_label_edge" because of following StandardError
87
+ # Unknown type 'graphid' for column 'id'
71
88
 
89
+ # Could not dump table "_ag_label_vertex" because of following StandardError
90
+ # Unknown type 'graphid' for column 'id'
91
+
92
+ # Could not dump table "ag_graph" because of following StandardError
93
+ # Unknown type 'regnamespace' for column 'namespace'
94
+
95
+ # Could not dump table "ag_label" because of following StandardError
96
+ # Unknown type 'regclass' for column 'relation'
97
+
98
+ add_foreign_key "ag_label", "ag_graph", column: "graph", primary_key: "graphid", name: "fk_graph_oid"
99
+
100
+ # other migrations
101
+ # ...
102
+ ```
103
+
104
+ and replace them with the following lines:
72
105
  ```ruby
73
- # db/schema.rb
74
- ActiveRecord::Schema[7.1].define(version: 2024_05_21_062349) do
75
106
  # These are extensions that must be enabled in order to support this database
76
107
  enable_extension "plpgsql"
77
108
 
@@ -89,9 +120,11 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_21_062349) do
89
120
 
90
121
  # other migrations
91
122
  # ...
92
- end
93
123
  ```
94
124
 
125
+ NOTE: I like to add the schema.rb to git so that it is easy to revert the unwanted changes and keep the desired changes.
126
+ ALSO note that running: `bin/rails apache_age:install` will check and non-destructively repair any config files at any time (however a git commit before hand as a backup is a good idea incase something goes wrong!)
127
+
95
128
  ## Contributing
96
129
 
97
130
  Create an MR and tests and I will review it.
@@ -115,7 +148,12 @@ module Nodes
115
148
  include ApacheAge::Entities::Vertex
116
149
 
117
150
  attribute :company_name, :string
151
+
118
152
  validates :company_name, presence: true
153
+ validates_with(
154
+ ApacheAge::Validators::UniqueVertexValidator,
155
+ attributes: [:company_name]
156
+ )
119
157
  end
120
158
  end
121
159
  ```
@@ -148,15 +186,30 @@ end
148
186
  ### Edges
149
187
 
150
188
  ```ruby
151
- # app/graphs/edges/works_at.rb
189
+ # app/graphs/edges/has_job.rb
152
190
  module Edges
153
191
  class HasJob
154
192
  include ApacheAge::Entities::Edge
155
193
 
156
194
  attribute :employee_role, :string
157
- attribute :start_node, :person # if using optional age types
158
- # attribute :end_node, :person # if using optional age types
195
+ attribute :start_node, :person
196
+ attribute :end_node, :company
197
+
159
198
  validates :employee_role, presence: true
199
+ validate :validate_unique
200
+ # or with a one-liner
201
+ # validates_with(
202
+ # ApacheAge::Validators::UniqueEdgeValidator,
203
+ # attributes: %i[employee_role start_node end_node]
204
+ # )
205
+
206
+ private
207
+
208
+ def validate_unique
209
+ ApacheAge::Validators::UniqueEdgeValidator
210
+ .new(attributes: %i[employee_role start_node end_node])
211
+ .validate(self)
212
+ end
160
213
  end
161
214
  end
162
215
  ```
@@ -1,4 +1,4 @@
1
- class ConfigureApacheAge < ActiveRecord::Migration[7.1]
1
+ class AddApacheAge < ActiveRecord::Migration[7.1]
2
2
  def up
3
3
  # Allow age extension
4
4
  execute('CREATE EXTENSION IF NOT EXISTS age;')
@@ -8,29 +8,15 @@ module ApacheAge
8
8
  instance
9
9
  end
10
10
 
11
- def find_edge(attributes)
12
- where_attribs =
13
- attributes
14
- .compact
15
- .except(:end_id, :start_id, :end_node, :start_node)
16
- .map { |k, v| "find.#{k} = '#{v}'" }.join(' AND ')
17
- where_attribs = where_attribs.empty? ? nil : where_attribs
18
-
19
- end_id = attributes[:end_id] || attributes[:end_node]&.id
20
- start_id = attributes[:start_id] || attributes[:start_node]&.id
21
- where_end_id = end_id ? "id(end_node) = #{end_id}" : nil
22
- where_start_id = start_id ? "id(start_node) = #{start_id}" : nil
23
-
24
- where_clause = [where_attribs, where_start_id, where_end_id].compact.join(' AND ')
25
- return nil if where_clause.empty?
11
+ def find_by(attributes)
12
+ return nil if attributes.reject{ |k,v| v.blank? }.empty?
26
13
 
27
- cypher_sql = find_edge_sql(where_clause)
28
- execute_find(cypher_sql)
29
- end
14
+ edge_keys = [:start_id, :start_node, :end_id, :end_node]
15
+ return find_edge(attributes) if edge_keys.any? { |key| attributes.include?(key) }
30
16
 
31
- def find_by(attributes)
32
17
  where_clause = attributes.map { |k, v| "find.#{k} = '#{v}'" }.join(' AND ')
33
18
  cypher_sql = find_sql(where_clause)
19
+
34
20
  execute_find(cypher_sql)
35
21
  end
36
22
 
@@ -55,6 +41,27 @@ module ApacheAge
55
41
 
56
42
  # Private stuff
57
43
 
44
+ def find_edge(attributes)
45
+ where_attribs =
46
+ attributes
47
+ .compact
48
+ .except(:end_id, :start_id, :end_node, :start_node)
49
+ .map { |k, v| "find.#{k} = '#{v}'" }.join(' AND ')
50
+ where_attribs = where_attribs.empty? ? nil : where_attribs
51
+
52
+ end_id = attributes[:end_id] || attributes[:end_node]&.id
53
+ start_id = attributes[:start_id] || attributes[:start_node]&.id
54
+ where_end_id = end_id ? "id(end_node) = #{end_id}" : nil
55
+ where_start_id = start_id ? "id(start_node) = #{start_id}" : nil
56
+
57
+ where_clause = [where_attribs, where_start_id, where_end_id].compact.join(' AND ')
58
+ return nil if where_clause.empty?
59
+
60
+ cypher_sql = find_edge_sql(where_clause)
61
+
62
+ execute_find(cypher_sql)
63
+ end
64
+
58
65
  def age_graph = 'age_schema'
59
66
  def age_label = name.gsub('::', '__')
60
67
  def age_type = name.constantize.new.age_type
@@ -32,7 +32,7 @@ module ApacheAge
32
32
  end
33
33
  return if attributes.blank? && (end_query.blank? || start_query.blank?)
34
34
 
35
- query = record.class.find_edge(edge_attribs.compact)
35
+ query = record.class.find_by(edge_attribs.compact)
36
36
  return if query.blank? || (query.id == record.id)
37
37
 
38
38
  record.errors.add(:base, 'attribute combination not unique')
@@ -1,3 +1,3 @@
1
1
  module RailsAge
2
- VERSION = "0.2.0"
2
+ VERSION = '0.3.0'
3
3
  end
@@ -1,91 +1,210 @@
1
1
  # lib/tasks/install.rake
2
- # Usage: `rake rails_age:install`
2
+ # Usage: `rake apache_age:install`
3
3
  #
4
- namespace :rails_age do
4
+ namespace :apache_age do
5
5
  desc "Copy migrations from rails_age to application and update schema"
6
6
  task :install => :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
+
10
+ # ensure we have a schema file
11
+ run_migrations
12
+
13
+ # copy our migrations to the application
14
+ last_migration_version = copy_migrations
15
+
16
+ # check if the schema is blank (NEW) before running migrations!
17
+ is_schema_blank = blank_schema?(destination_schema)
18
+ puts "Schema is blank: #{is_schema_blank}"
19
+
20
+ # run our new migrations
21
+ run_migrations
22
+
23
+ # adjust the schema file (unfortunately rails mangles the schema file)
24
+ if is_schema_blank
25
+ puts "creating new schema..."
26
+ create_new_schema(last_migration_version, destination_schema, source_schema)
27
+ else
28
+ puts "updating existing schema..."
29
+ update_existing_schema(last_migration_version, destination_schema, source_schema)
30
+ end
31
+
32
+ update_database_yml
33
+ end
34
+
35
+ def copy_migrations
36
+ migration_version = nil
37
+
7
38
  source = File.expand_path('../../../db/migrate', __FILE__)
8
- destination = File.expand_path('../../../../db/migrate', __FILE__)
39
+ destination = File.expand_path("#{Rails.root}/db/migrate", __FILE__)
9
40
 
10
- FileUtils.mkdir_p(destination) unless File.exists?(destination)
41
+ FileUtils.mkdir_p(destination) unless File.exist?(destination)
42
+ existing_migrations =
43
+ Dir.glob("#{destination}/*.rb").map { |file| File.basename(file).sub(/^\d+/, '') }
11
44
 
12
45
  Dir.glob("#{source}/*.rb").each do |file|
13
46
  filename = File.basename(file)
14
- destination_file = File.join(destination, filename)
47
+ test_name = filename.sub(/^\d+/, '')
15
48
 
16
- if File.exists?(destination_file)
49
+ if existing_migrations.include?(test_name)
17
50
  puts "Skipping #{filename}, it already exists"
18
51
  else
52
+ migration_version = Time.now.utc.strftime("%Y_%m_%d_%H%M%S")
53
+ file_version = migration_version.delete('_')
54
+ new_filename = filename.sub(/^\d+/, file_version)
55
+ destination_file = File.join(destination, new_filename)
19
56
  FileUtils.cp(file, destination_file)
20
- puts "Copied #{filename} to #{destination}"
57
+ puts "Copied #{filename} to #{destination} as #{new_filename}"
21
58
  end
22
59
  end
60
+ migration_version
61
+ end
23
62
 
24
- # Update the schema.rb file
25
- schema_file = File.expand_path('../../../../db/schema.rb', __FILE__)
26
- if File.exists?(schema_file)
27
- content = File.read(schema_file)
28
-
29
- # Add the necessary extensions and configurations at the top of the schema
30
- insert_statements = <<-RUBY
63
+ def blank_schema?(destination_schema)
64
+ return false unless File.exist?(destination_schema)
31
65
 
32
- # These are extensions that must be enabled in order to support this database
33
- enable_extension "plpgsql"
66
+ content = File.read(destination_schema)
67
+ content.include?('define(version: 0)') &&
68
+ content.include?('enable_extension "plpgsql"') &&
69
+ content.scan(/enable_extension/).size == 1
70
+ end
34
71
 
35
- # Allow age extension
36
- execute('CREATE EXTENSION IF NOT EXISTS age;')
72
+ def run_migrations
73
+ puts "Running migrations..."
74
+ Rake::Task["db:migrate"].invoke
75
+ end
37
76
 
38
- # Load the age code
39
- execute("LOAD 'age';")
77
+ def extract_rails_version(destination_schema)
78
+ if File.exist?(destination_schema)
79
+ content = File.read(destination_schema)
80
+ version_match = content.match(/ActiveRecord::Schema\[(.*?)\]/)
81
+ return version_match[1] if version_match
82
+ else
83
+ full_version = Rails.version
84
+ primary_secondary_version = full_version.split('.')[0..1].join('.')
85
+ primary_secondary_version
86
+ end
87
+ end
40
88
 
41
- # Load the ag_catalog into the search path
42
- execute('SET search_path = ag_catalog, "$user", public;')
89
+ def create_new_schema(last_migration_version, destination_schema, source_schema)
90
+ if File.exist?(source_schema) && File.exist?(destination_schema)
91
+ rails_version = extract_rails_version(destination_schema)
92
+ source_content = File.read(source_schema)
93
+
94
+ # ensure we use the Rails version from the destination schema
95
+ source_content.gsub!(
96
+ /ActiveRecord::Schema\[\d+\.\d+\]/,
97
+ "ActiveRecord::Schema[#{rails_version}]"
98
+ )
99
+ # ensure we use the last migration version (not the source schema version)
100
+ source_content.gsub!(
101
+ /define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do/,
102
+ "define(version: #{last_migration_version}) do"
103
+ )
104
+
105
+ File.write(destination_schema, source_content)
106
+ puts "Created new schema in #{destination_schema} with necessary extensions and configurations."
107
+ else
108
+ puts "local db/schema.rb file not found."
109
+ end
110
+ end
43
111
 
44
- # Create age_schema graph if it doesn't exist
45
- execute("SELECT create_graph('age_schema');")
112
+ def update_existing_schema(last_migration_version, destination_schema, source_schema)
113
+ if File.exist?(source_schema) && File.exist?(destination_schema)
114
+ rails_version = extract_rails_version(destination_schema)
115
+ source_content = File.read(source_schema)
116
+ new_content =
117
+ source_content.gsub(
118
+ /.*ActiveRecord::Schema\[\d+\.\d+\]\.define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do\n|\nend$/,
119
+ ''
120
+ )
46
121
 
47
- RUBY
122
+ destination_content = File.read(destination_schema)
48
123
 
49
- unless content.include?(insert_statements.strip)
50
- content.sub!(/^# These are extensions that must be enabled in order to support this database.*?\n\n/m, insert_statements)
124
+ # Remove unwanted schema statements
125
+ destination_content.gsub!(%r{^.*?# These are extensions that must be enabled in order to support this database.*?\n}, '')
126
+
127
+ destination_content.gsub!(%r{^.*?create_schema "ag_catalog".*?\n}, '')
128
+ destination_content.gsub!(%r{^.*?create_schema "age_schema".*?\n}, '')
129
+ destination_content.gsub!(%r{^.*?enable_extension "age".*?\n}, '')
130
+ destination_content.gsub!(%r{^.*?enable_extension "plpgsql".*?\n}, '')
131
+ destination_content.gsub!(%r{^.*?# Could not dump table "ag_graph" because of following StandardError.*?\n}, '')
132
+ destination_content.gsub!(%r{^.*?# Unknown type 'regnamespace' for column 'namespace'.*?\n}, '')
133
+ destination_content.gsub!(%r{^.*?# Could not dump table "ag_label" because of following StandardError.*?\n}, '')
134
+ destination_content.gsub!(%r{^.*?# Unknown type 'regclass' for column 'relation'.*?\n}, '')
135
+ destination_content.gsub!(%r{^.*?# Unknown type 'graphid' for column 'id'.*?\n}, '')
136
+ destination_content.gsub!(
137
+ %r{^.*?# Could not dump table "_ag_label_edge" because of following StandardError.*?\n}, ''
138
+ )
139
+ destination_content.gsub!(
140
+ %r{^.*?# Could not dump table "_ag_label_vertex" because of following StandardError.*?\n}, ''
141
+ )
142
+ destination_content.gsub!(%r{^.*?# Could not dump table "ag_graph" because of following StandardError.*?\n}, '')
143
+ destination_content.gsub!(%r{^.*?# Could not dump table "ag_label" because of following StandardError.*?\n}, '')
144
+ destination_content.gsub!(%r{^.*?add_foreign_key "ag_label", "ag_graph".*?\n}, '')
145
+
146
+ # add new wanted schema statements (at the top of the schema)
147
+ destination_content.sub!(
148
+ %r{(ActiveRecord::Schema\[\d+\.\d+\]\.define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do\n)},
149
+ "\\1#{new_content}\n"
150
+ )
151
+
152
+ existing_version = destination_content.match(/define\(version: (\d{4}(?:_\d{2}){2}(?:_\d{6})?)\)/)[1].gsub('_', '')
153
+ current_version = last_migration_version ? last_migration_version.gsub('_', '') : existing_version
154
+
155
+ # ensure we use the last migration version (not the source schema version)
156
+ if current_version.to_i > existing_version.to_i
157
+ destination_content.gsub!(
158
+ /define\(version: \d{4}(?:_\d{2}){2}(?:_\d{6})?\) do/,
159
+ "define(version: #{last_migration_version}) do"
160
+ )
51
161
  end
52
162
 
53
- # Remove unwanted schema statements
54
- content.gsub!(/^.*?create_schema "ag_catalog".*?\n\n/m, '')
55
- content.gsub!(/^.*?create_schema "age_schema".*?\n\n/m, '')
56
- content.gsub!(/^.*?enable_extension "age".*?\n\n/m, '')
57
- content.gsub!(/^.*?# Could not dump table "_ag_label_edge" because of following StandardError.*?\n\n/m, '')
58
- content.gsub!(/^.*?# Could not dump table "_ag_label_vertex" because of following StandardError.*?\n\n/m, '')
59
- content.gsub!(/^.*?# Could not dump table "ag_graph" because of following StandardError.*?\n\n/m, '')
60
- content.gsub!(/^.*?# Could not dump table "ag_label" because of following StandardError.*?\n\n/m, '')
61
- content.gsub!(/^.*?add_foreign_key "ag_label", "ag_graph".*?\n\n/m, '')
62
-
63
- File.write(schema_file, content)
64
- puts "Updated #{schema_file} with necessary extensions and configurations."
163
+ File.write(destination_schema, destination_content)
164
+ puts "Updated #{destination_schema} with necessary extensions and configurations."
65
165
  else
66
- puts "schema.rb file not found. Please ensure migrations have been run."
166
+ puts "local db/schema.rb file not found."
67
167
  end
68
168
  end
69
- end
70
169
 
71
- # namespace :rails_age do
72
- # desc "Copy migrations from rails_age to application"
73
- # task :install => :environment do
74
- # source = File.expand_path('../../../db/migrate', __FILE__)
75
- # destination = File.expand_path('../../../../db/migrate', __FILE__)
76
-
77
- # FileUtils.mkdir_p(destination) unless File.exists?(destination)
78
-
79
- # Dir.glob("#{source}/*.rb").each do |file|
80
- # filename = File.basename(file)
81
- # destination_file = File.join(destination, filename)
82
-
83
- # if File.exists?(destination_file)
84
- # puts "Skipping #{filename}, it already exists"
85
- # else
86
- # FileUtils.cp(file, destination_file)
87
- # puts "Copied #{filename} to #{destination}"
88
- # end
89
- # end
90
- # end
91
- # end
170
+ def update_database_yml
171
+ db_config_file = File.expand_path("#{Rails.root}/config/database.yml", __FILE__)
172
+
173
+ # Read the file
174
+ lines = File.readlines(db_config_file)
175
+
176
+ # any uncommented "schema_search_path:" lines?
177
+ path_index = lines.find_index { |line| !line.include?('#') && line.include?('schema_search_path:') }
178
+ default_start_index = lines.index { |line| line.strip.start_with?('default:') }
179
+
180
+ # when it finds an existing schema_search_path, it updates it
181
+ if path_index && lines[path_index].include?('ag_catalog,age_schema')
182
+ puts "schema_search_path already set to ag_catalog,age_schema nothing to do."
183
+ return
184
+ elsif path_index
185
+ key, val = lines[path_index].split(': ')
186
+ # remove any unwanted characters
187
+ val = val.gsub(/[ "\s\"\"'\n]/, '')
188
+ lines[path_index] = "#{key}: ag_catalog,age_schema,#{val}\n"
189
+ puts "add ag_catalog,age_schema to schema_search_path"
190
+ elsif default_start_index
191
+ puts "add ag_catalog,age_schema,public to schema_search_path in the default section of database.yml"
192
+ sections_index = lines.map.with_index { |line, index| index if !line.start_with?(' ') }.compact.sort
193
+
194
+ # find the start of the default section
195
+ next_section_in_list = sections_index.index(default_start_index) + 1
196
+
197
+ # find the end of the default section (before the next section starts)
198
+ path_insert_index = sections_index[next_section_in_list]
199
+
200
+ lines.insert(path_insert_index, " schema_search_path: ag_catalog,age_schema,public\n")
201
+ else
202
+ puts "didn't find a default section in database.yml, please add the following line:"
203
+ puts " schema_search_path: ag_catalog,age_schema,public"
204
+ puts "to the apprpriate section of your database.yml"
205
+ end
206
+
207
+ # Write the modified lines back to the file
208
+ File.open(db_config_file, 'w') { |file| file.write(lines.join) }
209
+ end
210
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_age
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bill Tihen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-26 00:00:00.000000000 Z
11
+ date: 2024-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -44,8 +44,8 @@ dependencies:
44
44
  - - "~>"
45
45
  - !ruby/object:Gem::Version
46
46
  version: '6.0'
47
- description: This plugin integrates Apache AGE with Rails 7.x, providing tools and
48
- helpers for working with graph databases within a Rails application.
47
+ description: This plugin integrates Apache AGE for PostgreSQL with Rails 7.x, providing
48
+ tools and helpers for working with graph databases within a Rails application.
49
49
  email:
50
50
  - btihen@gmail.com
51
51
  executables: []
@@ -65,7 +65,7 @@ files:
65
65
  - app/models/rails_age/application_record.rb
66
66
  - app/views/layouts/rails_age/application.html.erb
67
67
  - config/routes.rb
68
- - db/migrate/20240521062349_configure_apache_age.rb
68
+ - db/migrate/20240521062349_add_apache_age.rb
69
69
  - db/schema.rb
70
70
  - lib/apache_age/entities/class_methods.rb
71
71
  - lib/apache_age/entities/common_methods.rb