rails_age 0.1.0 → 0.3.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 +51 -4
- data/README.md +177 -10
- data/db/migrate/{20240521062349_configure_apache_age.rb → 20240521062349_add_apache_age.rb} +1 -1
- data/lib/apache_age/entities/class_methods.rb +119 -0
- data/lib/apache_age/entities/common_methods.rb +118 -0
- data/lib/apache_age/entities/edge.rb +98 -0
- data/lib/apache_age/entities/entity.rb +69 -0
- data/lib/apache_age/entities/vertex.rb +53 -0
- data/lib/apache_age/types/age_type_generator.rb +46 -0
- data/lib/apache_age/validators/unique_edge_validator.rb +53 -0
- data/lib/apache_age/validators/unique_vertex_validator.rb +28 -0
- data/lib/apache_age/validators/vertex_type_validator.rb +14 -0
- data/lib/rails_age/version.rb +1 -1
- data/lib/rails_age.rb +10 -7
- data/lib/tasks/install.rake +210 -0
- metadata +31 -19
- data/lib/apache_age/class_methods.rb +0 -75
- data/lib/apache_age/common_methods.rb +0 -126
- data/lib/apache_age/edge.rb +0 -64
- data/lib/apache_age/entity.rb +0 -67
- data/lib/apache_age/vertex.rb +0 -52
@@ -0,0 +1,69 @@
|
|
1
|
+
module ApacheAge
|
2
|
+
module Entities
|
3
|
+
class Entity
|
4
|
+
class << self
|
5
|
+
def find_by(attributes)
|
6
|
+
where_clause = attributes.map { |k, v| "find.#{k} = '#{v}'" }.join(' AND ')
|
7
|
+
handle_find(where_clause)
|
8
|
+
end
|
9
|
+
|
10
|
+
def find(id)
|
11
|
+
where_clause = "id(find) = #{id}"
|
12
|
+
handle_find(where_clause)
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def age_graph = 'age_schema'
|
18
|
+
|
19
|
+
def handle_find(where_clause)
|
20
|
+
# try to find a vertex
|
21
|
+
match_node = '(find)'
|
22
|
+
cypher_sql = find_sql(match_node, where_clause)
|
23
|
+
age_response = execute_find(cypher_sql)
|
24
|
+
|
25
|
+
if age_response.nil?
|
26
|
+
# if not a vertex try to find an edge
|
27
|
+
match_edge = '()-[find]->()'
|
28
|
+
cypher_sql = find_sql(match_edge, where_clause)
|
29
|
+
age_response = execute_find(cypher_sql)
|
30
|
+
return nil if age_response.nil?
|
31
|
+
end
|
32
|
+
|
33
|
+
instantiate_result(age_response)
|
34
|
+
end
|
35
|
+
|
36
|
+
def execute_find(cypher_sql)
|
37
|
+
age_result = ActiveRecord::Base.connection.execute(cypher_sql)
|
38
|
+
return nil if age_result.values.first.nil?
|
39
|
+
|
40
|
+
age_result
|
41
|
+
end
|
42
|
+
|
43
|
+
def instantiate_result(age_response)
|
44
|
+
age_type = age_response.values.first.first.split('::').last
|
45
|
+
json_string = age_response.values.first.first.split('::').first
|
46
|
+
json_data = JSON.parse(json_string)
|
47
|
+
|
48
|
+
age_label = json_data['label']
|
49
|
+
attribs = json_data.except('label', 'properties')
|
50
|
+
.merge(json_data['properties'])
|
51
|
+
.symbolize_keys
|
52
|
+
|
53
|
+
"#{json_data['label'].gsub('__', '::')}".constantize.new(**attribs)
|
54
|
+
end
|
55
|
+
|
56
|
+
def find_sql(match_clause, where_clause)
|
57
|
+
<<-SQL
|
58
|
+
SELECT *
|
59
|
+
FROM cypher('#{age_graph}', $$
|
60
|
+
MATCH #{match_clause}
|
61
|
+
WHERE #{where_clause}
|
62
|
+
RETURN find
|
63
|
+
$$) as (found agtype);
|
64
|
+
SQL
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module ApacheAge
|
2
|
+
module Entities
|
3
|
+
module Vertex
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
include ActiveModel::Model
|
8
|
+
include ActiveModel::Dirty
|
9
|
+
include ActiveModel::Attributes
|
10
|
+
|
11
|
+
attribute :id, :integer
|
12
|
+
|
13
|
+
extend ApacheAge::Entities::ClassMethods
|
14
|
+
include ApacheAge::Entities::CommonMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
def age_type = 'vertex'
|
18
|
+
|
19
|
+
# AgeSchema::Nodes::Company.create(company_name: 'Bedrock Quarry')
|
20
|
+
# SELECT *
|
21
|
+
# FROM cypher('age_schema', $$
|
22
|
+
# CREATE (company:Company {company_name: 'Bedrock Quarry'})
|
23
|
+
# RETURN company
|
24
|
+
# $$) as (Company agtype);
|
25
|
+
def create_sql
|
26
|
+
alias_name = age_alias || age_label.downcase
|
27
|
+
<<-SQL
|
28
|
+
SELECT *
|
29
|
+
FROM cypher('#{age_graph}', $$
|
30
|
+
CREATE (#{alias_name}#{self})
|
31
|
+
RETURN #{alias_name}
|
32
|
+
$$) as (#{age_label} agtype);
|
33
|
+
SQL
|
34
|
+
end
|
35
|
+
|
36
|
+
# So far just properties of string type with '' around them
|
37
|
+
def update_sql
|
38
|
+
alias_name = age_alias || age_label.downcase
|
39
|
+
set_caluse =
|
40
|
+
age_properties.map { |k, v| v ? "#{alias_name}.#{k} = '#{v}'" : "#{alias_name}.#{k} = NULL" }.join(', ')
|
41
|
+
<<-SQL
|
42
|
+
SELECT *
|
43
|
+
FROM cypher('#{age_graph}', $$
|
44
|
+
MATCH (#{alias_name}:#{age_label})
|
45
|
+
WHERE id(#{alias_name}) = #{id}
|
46
|
+
SET #{set_caluse}
|
47
|
+
RETURN #{alias_name}
|
48
|
+
$$) as (#{age_label} agtype);
|
49
|
+
SQL
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# lib/apache_age/types/age_type_generator.rb
|
2
|
+
# Automatically generates ActiveModel::Type classes
|
3
|
+
# Dynamically builds this (as a concrete example):
|
4
|
+
# module ApacheAge
|
5
|
+
# module Types
|
6
|
+
# class CompanyType < ActiveModel::Type::Value
|
7
|
+
# def cast(value)
|
8
|
+
# case value
|
9
|
+
# when Nodes::Company
|
10
|
+
# value
|
11
|
+
# when Hash
|
12
|
+
# Nodes::Company.new(value)
|
13
|
+
# else
|
14
|
+
# nil
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
# def serialize(value)
|
18
|
+
# value.is_a?(Nodes::Company) ? value.attributes : nil
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
module ApacheAge
|
24
|
+
module Types
|
25
|
+
class AgeTypeGenerator
|
26
|
+
def self.create_type_for(klass)
|
27
|
+
Class.new(ActiveModel::Type::Value) do
|
28
|
+
define_method(:cast) do |value|
|
29
|
+
case value
|
30
|
+
when klass
|
31
|
+
value
|
32
|
+
when Hash
|
33
|
+
klass.new(value)
|
34
|
+
else
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
define_method(:serialize) do |value|
|
40
|
+
value.is_a?(klass) ? value.attributes : nil
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# Usage (within an Age Model)
|
2
|
+
# validates_with UniqueEdgeValidator, attributes: [:employee_role, :start_node, :end_node]
|
3
|
+
# validates_with UniqueEdgeValidator, attributes: [:start_id, :employee_role, :end_id]
|
4
|
+
#
|
5
|
+
module ApacheAge
|
6
|
+
module Validators
|
7
|
+
class UniqueEdgeValidator < ActiveModel::Validator
|
8
|
+
def validate(record)
|
9
|
+
allowed_keys = record.age_properties.keys
|
10
|
+
attributes = options[:attributes] || []
|
11
|
+
|
12
|
+
edge_attribs =
|
13
|
+
attributes
|
14
|
+
.map { |attr| [attr, record.send(attr)] }.to_h
|
15
|
+
.symbolize_keys
|
16
|
+
.slice(*allowed_keys)
|
17
|
+
|
18
|
+
possible_end_keys = [:end_id, 'end_id', :end_node, 'end_node']
|
19
|
+
end_query =
|
20
|
+
if possible_end_keys.any? { |key| attributes.include?(key) }
|
21
|
+
end_query = query_node(record.end_node)
|
22
|
+
edge_attribs[:end_id] = end_query&.id
|
23
|
+
end_query
|
24
|
+
end
|
25
|
+
|
26
|
+
possible_start_keys = [:start_id, 'start_id', :start_node, 'start_node']
|
27
|
+
start_query =
|
28
|
+
if possible_start_keys.any? { |key| attributes.include?(key) }
|
29
|
+
start_query = query_node(record.start_node)
|
30
|
+
edge_attribs[:start_id] = start_query&.id
|
31
|
+
start_query
|
32
|
+
end
|
33
|
+
return if attributes.blank? && (end_query.blank? || start_query.blank?)
|
34
|
+
|
35
|
+
query = record.class.find_by(edge_attribs.compact)
|
36
|
+
return if query.blank? || (query.id == record.id)
|
37
|
+
|
38
|
+
record.errors.add(:base, 'attribute combination not unique')
|
39
|
+
record.errors.add(:end_node, 'attribute combination not unique')
|
40
|
+
record.errors.add(:start_node, 'attribute combination not unique')
|
41
|
+
attributes.each { record.errors.add(_1, 'attribute combination not unique') }
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def query_node(node)
|
47
|
+
return nil if node.blank?
|
48
|
+
|
49
|
+
node.persisted? ? node.class.find(node.id) : node.class.find_by(node.age_properties)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# Usage (within an Age Model)
|
2
|
+
# validates_with UniqueVertexValidator, attributes: [:first_name, :last_name, :gender]
|
3
|
+
|
4
|
+
# lib/apache_age/validators/unique_vertex_validator.rb
|
5
|
+
module ApacheAge
|
6
|
+
module Validators
|
7
|
+
class UniqueVertexValidator < ActiveModel::Validator
|
8
|
+
def validate(record)
|
9
|
+
allowed_keys = record.age_properties.keys
|
10
|
+
attributes = options[:attributes]
|
11
|
+
return if attributes.blank?
|
12
|
+
|
13
|
+
record_attribs =
|
14
|
+
attributes
|
15
|
+
.map { |attr| [attr, record.send(attr)] }
|
16
|
+
.to_h.symbolize_keys
|
17
|
+
.slice(*allowed_keys)
|
18
|
+
query = record.class.find_by(record_attribs)
|
19
|
+
|
20
|
+
# if no match is found or if it finds itself, it's valid
|
21
|
+
return if query.blank? || (query.id == record.id)
|
22
|
+
|
23
|
+
record.errors.add(:base, 'attribute combination not unique')
|
24
|
+
attributes.each { record.errors.add(_1, 'attribute combination not unique') }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ApacheAge
|
2
|
+
module VertexTypeValidator
|
3
|
+
def vertex_attribute(attribute_name, type_symbol, klass)
|
4
|
+
attribute attribute_name, type_symbol
|
5
|
+
|
6
|
+
validate do
|
7
|
+
value = send(attribute_name)
|
8
|
+
unless value.is_a?(klass)
|
9
|
+
errors.add(attribute_name, "must be a #{klass.name}")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/rails_age/version.rb
CHANGED
data/lib/rails_age.rb
CHANGED
@@ -1,14 +1,17 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require 'rails_age/version'
|
2
|
+
require 'rails_age/engine'
|
3
3
|
|
4
4
|
module RailsAge
|
5
5
|
# Your code goes here...
|
6
6
|
end
|
7
7
|
|
8
8
|
module ApacheAge
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
9
|
+
require 'apache_age/entities/class_methods'
|
10
|
+
require 'apache_age/entities/common_methods'
|
11
|
+
require 'apache_age/entities/edge'
|
12
|
+
require 'apache_age/entities/entity'
|
13
|
+
require 'apache_age/entities/vertex'
|
14
|
+
require 'apache_age/types/age_type_generator'
|
15
|
+
require 'apache_age/validators/unique_edge_validator'
|
16
|
+
require 'apache_age/validators/unique_vertex_validator'
|
14
17
|
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
# lib/tasks/install.rake
|
2
|
+
# Usage: `rake apache_age:install`
|
3
|
+
#
|
4
|
+
namespace :apache_age do
|
5
|
+
desc "Copy migrations from rails_age to application and update schema"
|
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
|
+
|
38
|
+
source = File.expand_path('../../../db/migrate', __FILE__)
|
39
|
+
destination = File.expand_path("#{Rails.root}/db/migrate", __FILE__)
|
40
|
+
|
41
|
+
FileUtils.mkdir_p(destination) unless File.exist?(destination)
|
42
|
+
existing_migrations =
|
43
|
+
Dir.glob("#{destination}/*.rb").map { |file| File.basename(file).sub(/^\d+/, '') }
|
44
|
+
|
45
|
+
Dir.glob("#{source}/*.rb").each do |file|
|
46
|
+
filename = File.basename(file)
|
47
|
+
test_name = filename.sub(/^\d+/, '')
|
48
|
+
|
49
|
+
if existing_migrations.include?(test_name)
|
50
|
+
puts "Skipping #{filename}, it already exists"
|
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)
|
56
|
+
FileUtils.cp(file, destination_file)
|
57
|
+
puts "Copied #{filename} to #{destination} as #{new_filename}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
migration_version
|
61
|
+
end
|
62
|
+
|
63
|
+
def blank_schema?(destination_schema)
|
64
|
+
return false unless File.exist?(destination_schema)
|
65
|
+
|
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
|
71
|
+
|
72
|
+
def run_migrations
|
73
|
+
puts "Running migrations..."
|
74
|
+
Rake::Task["db:migrate"].invoke
|
75
|
+
end
|
76
|
+
|
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
|
88
|
+
|
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
|
111
|
+
|
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
|
+
)
|
121
|
+
|
122
|
+
destination_content = File.read(destination_schema)
|
123
|
+
|
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
|
+
)
|
161
|
+
end
|
162
|
+
|
163
|
+
File.write(destination_schema, destination_content)
|
164
|
+
puts "Updated #{destination_schema} with necessary extensions and configurations."
|
165
|
+
else
|
166
|
+
puts "local db/schema.rb file not found."
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
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.
|
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-
|
11
|
+
date: 2024-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -16,29 +16,36 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 7.
|
19
|
+
version: '7.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '9.0'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
27
|
- - ">="
|
25
28
|
- !ruby/object:Gem::Version
|
26
|
-
version: 7.
|
29
|
+
version: '7.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '9.0'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rspec-rails
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - "~>"
|
32
38
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
39
|
+
version: '6.0'
|
34
40
|
type: :development
|
35
41
|
prerelease: false
|
36
42
|
version_requirements: !ruby/object:Gem::Requirement
|
37
43
|
requirements:
|
38
|
-
- - "
|
44
|
+
- - "~>"
|
39
45
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
description: Apache AGE
|
46
|
+
version: '6.0'
|
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.
|
42
49
|
email:
|
43
50
|
- btihen@gmail.com
|
44
51
|
executables: []
|
@@ -58,23 +65,28 @@ files:
|
|
58
65
|
- app/models/rails_age/application_record.rb
|
59
66
|
- app/views/layouts/rails_age/application.html.erb
|
60
67
|
- config/routes.rb
|
61
|
-
- db/migrate/
|
68
|
+
- db/migrate/20240521062349_add_apache_age.rb
|
62
69
|
- db/schema.rb
|
63
|
-
- lib/apache_age/class_methods.rb
|
64
|
-
- lib/apache_age/common_methods.rb
|
65
|
-
- lib/apache_age/edge.rb
|
66
|
-
- lib/apache_age/entity.rb
|
67
|
-
- lib/apache_age/vertex.rb
|
70
|
+
- lib/apache_age/entities/class_methods.rb
|
71
|
+
- lib/apache_age/entities/common_methods.rb
|
72
|
+
- lib/apache_age/entities/edge.rb
|
73
|
+
- lib/apache_age/entities/entity.rb
|
74
|
+
- lib/apache_age/entities/vertex.rb
|
75
|
+
- lib/apache_age/types/age_type_generator.rb
|
76
|
+
- lib/apache_age/validators/unique_edge_validator.rb
|
77
|
+
- lib/apache_age/validators/unique_vertex_validator.rb
|
78
|
+
- lib/apache_age/validators/vertex_type_validator.rb
|
68
79
|
- lib/rails_age.rb
|
69
80
|
- lib/rails_age/engine.rb
|
70
81
|
- lib/rails_age/version.rb
|
82
|
+
- lib/tasks/install.rake
|
71
83
|
- lib/tasks/rails_age_tasks.rake
|
72
84
|
homepage: https://github.com/marpori/rails_age
|
73
85
|
licenses:
|
74
86
|
- MIT
|
75
87
|
metadata:
|
76
88
|
homepage_uri: https://github.com/marpori/rails_age
|
77
|
-
source_code_uri: https://github.com/marpori/rails_age
|
89
|
+
source_code_uri: https://github.com/marpori/rails_age/blob/main
|
78
90
|
changelog_uri: https://github.com/marpori/rails_age/blob/main/CHANGELOG.md
|
79
91
|
post_install_message:
|
80
92
|
rdoc_options: []
|
@@ -84,15 +96,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
84
96
|
requirements:
|
85
97
|
- - ">="
|
86
98
|
- !ruby/object:Gem::Version
|
87
|
-
version: '0'
|
99
|
+
version: '3.0'
|
88
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
101
|
requirements:
|
90
102
|
- - ">="
|
91
103
|
- !ruby/object:Gem::Version
|
92
104
|
version: '0'
|
93
105
|
requirements: []
|
94
|
-
rubygems_version: 3.5.
|
106
|
+
rubygems_version: 3.5.10
|
95
107
|
signing_key:
|
96
108
|
specification_version: 4
|
97
|
-
summary: Apache AGE plugin for Rails 7.
|
109
|
+
summary: Apache AGE plugin for Rails 7.x
|
98
110
|
test_files: []
|