activegraph 11.0.0.beta.1-java
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 +7 -0
- data/CHANGELOG.md +2016 -0
- data/CONTRIBUTORS +12 -0
- data/Gemfile +24 -0
- data/README.md +111 -0
- data/activegraph.gemspec +52 -0
- data/bin/rake +17 -0
- data/config/locales/en.yml +5 -0
- data/config/neo4j/add_classnames.yml +1 -0
- data/config/neo4j/config.yml +35 -0
- data/lib/active_graph.rb +123 -0
- data/lib/active_graph/ansi.rb +14 -0
- data/lib/active_graph/attribute_set.rb +32 -0
- data/lib/active_graph/base.rb +77 -0
- data/lib/active_graph/class_arguments.rb +39 -0
- data/lib/active_graph/config.rb +135 -0
- data/lib/active_graph/core.rb +14 -0
- data/lib/active_graph/core/connection_failed_error.rb +6 -0
- data/lib/active_graph/core/cypher_error.rb +37 -0
- data/lib/active_graph/core/entity.rb +11 -0
- data/lib/active_graph/core/instrumentable.rb +37 -0
- data/lib/active_graph/core/label.rb +135 -0
- data/lib/active_graph/core/logging.rb +44 -0
- data/lib/active_graph/core/node.rb +15 -0
- data/lib/active_graph/core/querable.rb +41 -0
- data/lib/active_graph/core/query.rb +485 -0
- data/lib/active_graph/core/query_builder.rb +18 -0
- data/lib/active_graph/core/query_clauses.rb +727 -0
- data/lib/active_graph/core/query_ext.rb +24 -0
- data/lib/active_graph/core/query_find_in_batches.rb +46 -0
- data/lib/active_graph/core/record.rb +51 -0
- data/lib/active_graph/core/result.rb +31 -0
- data/lib/active_graph/core/schema.rb +65 -0
- data/lib/active_graph/core/schema_errors.rb +12 -0
- data/lib/active_graph/core/wrappable.rb +30 -0
- data/lib/active_graph/errors.rb +59 -0
- data/lib/active_graph/lazy_attribute_hash.rb +38 -0
- data/lib/active_graph/migration.rb +148 -0
- data/lib/active_graph/migrations.rb +27 -0
- data/lib/active_graph/migrations/base.rb +77 -0
- data/lib/active_graph/migrations/check_pending.rb +20 -0
- data/lib/active_graph/migrations/helpers.rb +105 -0
- data/lib/active_graph/migrations/helpers/id_property.rb +72 -0
- data/lib/active_graph/migrations/helpers/relationships.rb +66 -0
- data/lib/active_graph/migrations/helpers/schema.rb +63 -0
- data/lib/active_graph/migrations/migration_file.rb +24 -0
- data/lib/active_graph/migrations/runner.rb +195 -0
- data/lib/active_graph/migrations/schema.rb +64 -0
- data/lib/active_graph/migrations/schema_migration.rb +14 -0
- data/lib/active_graph/model_schema.rb +139 -0
- data/lib/active_graph/node.rb +110 -0
- data/lib/active_graph/node/callbacks.rb +8 -0
- data/lib/active_graph/node/dependent.rb +11 -0
- data/lib/active_graph/node/dependent/association_methods.rb +49 -0
- data/lib/active_graph/node/dependent/query_proxy_methods.rb +52 -0
- data/lib/active_graph/node/dependent_callbacks.rb +31 -0
- data/lib/active_graph/node/enum.rb +26 -0
- data/lib/active_graph/node/has_n.rb +602 -0
- data/lib/active_graph/node/has_n/association.rb +278 -0
- data/lib/active_graph/node/has_n/association/rel_factory.rb +61 -0
- data/lib/active_graph/node/has_n/association/rel_wrapper.rb +23 -0
- data/lib/active_graph/node/has_n/association_cypher_methods.rb +108 -0
- data/lib/active_graph/node/id_property.rb +224 -0
- data/lib/active_graph/node/id_property/accessor.rb +62 -0
- data/lib/active_graph/node/initialize.rb +21 -0
- data/lib/active_graph/node/labels.rb +207 -0
- data/lib/active_graph/node/labels/index.rb +37 -0
- data/lib/active_graph/node/labels/reloading.rb +21 -0
- data/lib/active_graph/node/node_list_formatter.rb +13 -0
- data/lib/active_graph/node/node_wrapper.rb +54 -0
- data/lib/active_graph/node/orm_adapter.rb +82 -0
- data/lib/active_graph/node/persistence.rb +186 -0
- data/lib/active_graph/node/property.rb +60 -0
- data/lib/active_graph/node/query.rb +76 -0
- data/lib/active_graph/node/query/query_proxy.rb +367 -0
- data/lib/active_graph/node/query/query_proxy_eager_loading.rb +177 -0
- data/lib/active_graph/node/query/query_proxy_eager_loading/association_tree.rb +75 -0
- data/lib/active_graph/node/query/query_proxy_enumerable.rb +110 -0
- data/lib/active_graph/node/query/query_proxy_find_in_batches.rb +19 -0
- data/lib/active_graph/node/query/query_proxy_link.rb +139 -0
- data/lib/active_graph/node/query/query_proxy_methods.rb +303 -0
- data/lib/active_graph/node/query/query_proxy_methods_of_mass_updating.rb +99 -0
- data/lib/active_graph/node/query_methods.rb +68 -0
- data/lib/active_graph/node/reflection.rb +86 -0
- data/lib/active_graph/node/rels.rb +11 -0
- data/lib/active_graph/node/scope.rb +166 -0
- data/lib/active_graph/node/unpersisted.rb +48 -0
- data/lib/active_graph/node/validations.rb +59 -0
- data/lib/active_graph/paginated.rb +27 -0
- data/lib/active_graph/railtie.rb +108 -0
- data/lib/active_graph/relationship.rb +68 -0
- data/lib/active_graph/relationship/callbacks.rb +21 -0
- data/lib/active_graph/relationship/initialize.rb +28 -0
- data/lib/active_graph/relationship/persistence.rb +133 -0
- data/lib/active_graph/relationship/persistence/query_factory.rb +95 -0
- data/lib/active_graph/relationship/property.rb +92 -0
- data/lib/active_graph/relationship/query.rb +99 -0
- data/lib/active_graph/relationship/rel_wrapper.rb +31 -0
- data/lib/active_graph/relationship/related_node.rb +87 -0
- data/lib/active_graph/relationship/types.rb +80 -0
- data/lib/active_graph/relationship/validations.rb +8 -0
- data/lib/active_graph/schema/operation.rb +102 -0
- data/lib/active_graph/shared.rb +48 -0
- data/lib/active_graph/shared/attributes.rb +217 -0
- data/lib/active_graph/shared/callbacks.rb +66 -0
- data/lib/active_graph/shared/cypher.rb +37 -0
- data/lib/active_graph/shared/declared_properties.rb +204 -0
- data/lib/active_graph/shared/declared_property.rb +109 -0
- data/lib/active_graph/shared/declared_property/index.rb +37 -0
- data/lib/active_graph/shared/enum.rb +167 -0
- data/lib/active_graph/shared/filtered_hash.rb +79 -0
- data/lib/active_graph/shared/identity.rb +34 -0
- data/lib/active_graph/shared/initialize.rb +65 -0
- data/lib/active_graph/shared/marshal.rb +23 -0
- data/lib/active_graph/shared/mass_assignment.rb +63 -0
- data/lib/active_graph/shared/permitted_attributes.rb +28 -0
- data/lib/active_graph/shared/persistence.rb +272 -0
- data/lib/active_graph/shared/property.rb +249 -0
- data/lib/active_graph/shared/query_factory.rb +122 -0
- data/lib/active_graph/shared/rel_type_converters.rb +43 -0
- data/lib/active_graph/shared/serialized_properties.rb +30 -0
- data/lib/active_graph/shared/type_converters.rb +439 -0
- data/lib/active_graph/shared/typecasted_attributes.rb +99 -0
- data/lib/active_graph/shared/typecaster.rb +53 -0
- data/lib/active_graph/shared/validations.rb +44 -0
- data/lib/active_graph/tasks/migration.rake +204 -0
- data/lib/active_graph/timestamps.rb +11 -0
- data/lib/active_graph/timestamps/created.rb +9 -0
- data/lib/active_graph/timestamps/updated.rb +9 -0
- data/lib/active_graph/transaction.rb +22 -0
- data/lib/active_graph/transactions.rb +57 -0
- data/lib/active_graph/type_converters.rb +7 -0
- data/lib/active_graph/undeclared_properties.rb +53 -0
- data/lib/active_graph/version.rb +3 -0
- data/lib/active_graph/wrapper.rb +4 -0
- data/lib/rails/generators/active_graph/migration/migration_generator.rb +16 -0
- data/lib/rails/generators/active_graph/migration/templates/migration.erb +9 -0
- data/lib/rails/generators/active_graph/model/model_generator.rb +89 -0
- data/lib/rails/generators/active_graph/model/templates/migration.erb +11 -0
- data/lib/rails/generators/active_graph/model/templates/model.erb +15 -0
- data/lib/rails/generators/active_graph/upgrade_v8/templates/migration.erb +17 -0
- data/lib/rails/generators/active_graph/upgrade_v8/upgrade_v8_generator.rb +34 -0
- data/lib/rails/generators/active_graph_generator.rb +121 -0
- metadata +423 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
module ActiveGraph::Shared
|
|
2
|
+
# TypecastedAttributes allows types to be declared for your attributes
|
|
3
|
+
#
|
|
4
|
+
# Types are declared by passing the :type option to the attribute class
|
|
5
|
+
# method. After a type is declared, attribute readers will convert any
|
|
6
|
+
# assigned attribute value to the declared type. If the assigned value
|
|
7
|
+
# cannot be cast, nil will be returned instead. You can access the original
|
|
8
|
+
# assigned value using the before_type_cast methods.
|
|
9
|
+
#
|
|
10
|
+
# See {Typecasting} for the currently supported types.
|
|
11
|
+
#
|
|
12
|
+
# @example Usage
|
|
13
|
+
# class Person
|
|
14
|
+
# include ActiveGraph::Shared::TypecastedAttributes
|
|
15
|
+
# attribute :age, :type => Integer
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# person = Person.new
|
|
19
|
+
# person.age = "29"
|
|
20
|
+
# person.age #=> 29
|
|
21
|
+
# person.age_before_type_cast #=> "29"
|
|
22
|
+
#
|
|
23
|
+
# Originally part of ActiveAttr, https://github.com/cgriego/active_attr
|
|
24
|
+
module TypecastedAttributes
|
|
25
|
+
extend ActiveSupport::Concern
|
|
26
|
+
include ActiveGraph::Shared::Attributes
|
|
27
|
+
|
|
28
|
+
included do
|
|
29
|
+
attribute_method_suffix '_before_type_cast'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Read the raw attribute value
|
|
33
|
+
#
|
|
34
|
+
# @example Reading a raw age value
|
|
35
|
+
# person.age = "29"
|
|
36
|
+
# person.attribute_before_type_cast(:age) #=> "29"
|
|
37
|
+
#
|
|
38
|
+
# @param [String, Symbol, #to_s] name Attribute name
|
|
39
|
+
#
|
|
40
|
+
# @return [Object, nil] The attribute value before typecasting
|
|
41
|
+
def attribute_before_type_cast(name)
|
|
42
|
+
@attributes ||= ActiveGraph::AttributeSet.new({}, self.class.attributes.keys)
|
|
43
|
+
@attributes.fetch_value(name.to_s)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
# Reads the attribute and typecasts the result
|
|
49
|
+
def attribute(name)
|
|
50
|
+
Property::NEO4J_DRIVER_DATA_TYPES.include?(_attribute_type(name)) ? super : typecast_attribute(_attribute_typecaster(name), super)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def typecast_attribute(typecaster, value)
|
|
54
|
+
self.class.typecast_attribute(typecaster, value)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Calculates an attribute type
|
|
58
|
+
#
|
|
59
|
+
# @private
|
|
60
|
+
def _attribute_type(attribute_name)
|
|
61
|
+
self.class._attribute_type(attribute_name)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Resolve an attribute typecaster
|
|
65
|
+
#
|
|
66
|
+
# @private
|
|
67
|
+
def _attribute_typecaster(attribute_name)
|
|
68
|
+
type = _attribute_type(attribute_name)
|
|
69
|
+
default_typecaster = self.class.attributes[attribute_name].typecaster
|
|
70
|
+
caster = default_typecaster || ActiveGraph::Shared::TypeConverters.typecaster_for(type)
|
|
71
|
+
caster || fail(ActiveGraph::UnknownTypeConverterError, "Unable to cast to type #{type}")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
module ClassMethods
|
|
75
|
+
# Returns the class name plus its attribute names and types
|
|
76
|
+
#
|
|
77
|
+
# @example Inspect the model's definition.
|
|
78
|
+
# Person.inspect
|
|
79
|
+
#
|
|
80
|
+
# @return [String] Human-readable presentation of the attributes
|
|
81
|
+
def inspect
|
|
82
|
+
inspected_attributes = attribute_names.sort.map { |name| "#{name}: #{_attribute_type(name)}" }
|
|
83
|
+
attributes_list = "(#{inspected_attributes.join(', ')})" unless inspected_attributes.empty?
|
|
84
|
+
"#{name}#{attributes_list}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Calculates an attribute type
|
|
88
|
+
#
|
|
89
|
+
# @private
|
|
90
|
+
def _attribute_type(attribute_name)
|
|
91
|
+
attributes[attribute_name].type || Object
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def typecast_attribute(typecaster, value)
|
|
95
|
+
ActiveGraph::Shared::TypeConverters.typecast_attribute(typecaster, value)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
module ActiveGraph
|
|
2
|
+
module Shared
|
|
3
|
+
# This module provides a convenient way of registering a custom Typecasting class. Custom Typecasters all follow a simple pattern.
|
|
4
|
+
#
|
|
5
|
+
# EXAMPLE:
|
|
6
|
+
#
|
|
7
|
+
# .. code-block:: ruby
|
|
8
|
+
#
|
|
9
|
+
# class RangeConverter
|
|
10
|
+
# class << self
|
|
11
|
+
# def primitive_type
|
|
12
|
+
# String
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# def convert_type
|
|
16
|
+
# Range
|
|
17
|
+
# end
|
|
18
|
+
#
|
|
19
|
+
# def to_db(value)
|
|
20
|
+
# value.to_s
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# def to_ruby(value)
|
|
24
|
+
# ends = value.to_s.split('..').map { |d| Integer(d) }
|
|
25
|
+
# ends[0]..ends[1]
|
|
26
|
+
# end
|
|
27
|
+
# alias_method :call, :to_ruby
|
|
28
|
+
# end
|
|
29
|
+
#
|
|
30
|
+
# include ActiveGraph::Shared::Typecaster
|
|
31
|
+
# end
|
|
32
|
+
#
|
|
33
|
+
# This would allow you to use `property :my_prop, type: Range` in a model.
|
|
34
|
+
# Each method and the `alias_method` call is required. Make sure the module inclusion happens at the end of the file.
|
|
35
|
+
#
|
|
36
|
+
# `primitive_type` is used to fool ActiveAttr's type converters, which only recognize a few basic Ruby classes.
|
|
37
|
+
#
|
|
38
|
+
# `convert_type` must match the constant given to the `type` option.
|
|
39
|
+
#
|
|
40
|
+
# `to_db` provides logic required to transform your value into the class defined by `primitive_type`
|
|
41
|
+
#
|
|
42
|
+
# `to_ruby` provides logic to transform the DB-provided value back into the class expected by code using the property.
|
|
43
|
+
# In other words, it should match the `convert_type`.
|
|
44
|
+
#
|
|
45
|
+
# Note that `alias_method` is used to make `to_ruby` respond to `call`. This is to provide compatibility with ActiveAttr.
|
|
46
|
+
|
|
47
|
+
module Typecaster
|
|
48
|
+
def self.included(other)
|
|
49
|
+
ActiveGraph::Shared::TypeConverters.register_converter(other)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module ActiveGraph
|
|
2
|
+
module Shared
|
|
3
|
+
module Validations
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
include ActiveModel::Validations
|
|
6
|
+
# Implements the ActiveModel::Validation hook method.
|
|
7
|
+
# @see http://rubydoc.info/docs/rails/ActiveModel/Validations:read_attribute_for_validation
|
|
8
|
+
def read_attribute_for_validation(key)
|
|
9
|
+
respond_to?(key) ? send(key) : self[key]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# The validation process on save can be skipped by passing false. The regular Model#save method is
|
|
13
|
+
# replaced with this when the validations module is mixed in, which it is by default.
|
|
14
|
+
# @param [Hash] options the options to create a message with.
|
|
15
|
+
# @option options [true, false] :validate if false no validation will take place
|
|
16
|
+
# @return [Boolean] true if it saved it successfully
|
|
17
|
+
def save(options = {})
|
|
18
|
+
perform_validations(options) ? super : false
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @return [Boolean] true if valid
|
|
22
|
+
def valid?(context = nil)
|
|
23
|
+
context ||= (new_record? ? :create : :update)
|
|
24
|
+
super(context)
|
|
25
|
+
errors.empty?
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def perform_validations(options = {})
|
|
31
|
+
perform_validation = case options
|
|
32
|
+
when Hash
|
|
33
|
+
options[:validate] != false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
if perform_validation
|
|
37
|
+
valid?(options.is_a?(Hash) ? options[:context] : nil)
|
|
38
|
+
else
|
|
39
|
+
true
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
require 'rake'
|
|
2
|
+
require 'active_support/concern'
|
|
3
|
+
require 'active_graph/migration'
|
|
4
|
+
|
|
5
|
+
if !defined?(Rails) && !Rake::Task.task_defined?('environment')
|
|
6
|
+
desc 'Run a script against the database to perform system-wide changes'
|
|
7
|
+
task :environment do
|
|
8
|
+
require 'active_graph/session_manager'
|
|
9
|
+
require 'ostruct'
|
|
10
|
+
neo4j_url = ENV['NEO4J_URL'] || 'http://localhost:7474'
|
|
11
|
+
$LOAD_PATH.unshift File.dirname('./')
|
|
12
|
+
ActiveGraph::Base.on_establish_driver do
|
|
13
|
+
Neo4j::Driver::GraphDatabase.driver(neo4j_url)
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
namespace :neo4j do
|
|
19
|
+
task :allow_migrations do
|
|
20
|
+
ActiveGraph::Migrations.currently_running_migrations = true
|
|
21
|
+
end
|
|
22
|
+
desc 'Run a script against the database to perform system-wide changes'
|
|
23
|
+
task :legacy_migrate, [:task_name, :subtask] => :environment do |_, args|
|
|
24
|
+
path = Rake.original_dir
|
|
25
|
+
migration_task = args[:task_name]
|
|
26
|
+
task_name_constant = migration_task.split('_').map(&:capitalize).join('')
|
|
27
|
+
begin
|
|
28
|
+
migration_class = "ActiveGraph::Migration::#{task_name_constant}".constantize
|
|
29
|
+
rescue NameError
|
|
30
|
+
load File.join(path, 'db', 'neo4j-migrate', "#{migration_task}.rb")
|
|
31
|
+
migration_class = task_name_constant.to_s.constantize
|
|
32
|
+
end
|
|
33
|
+
migration = migration_class.new(path)
|
|
34
|
+
|
|
35
|
+
subtask = args[:subtask]
|
|
36
|
+
if subtask
|
|
37
|
+
migration.send(subtask)
|
|
38
|
+
else
|
|
39
|
+
migration.migrate
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
desc 'A shortcut for neo4j::migrate::all'
|
|
44
|
+
task :migrate do
|
|
45
|
+
Rake::Task['neo4j:migrate:all'].invoke
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# TODO: Make sure these tasks don't run in versions of Neo4j before 3.0
|
|
49
|
+
namespace :schema do
|
|
50
|
+
SCHEMA_YAML_PATH = 'db/neo4j/schema.yml'
|
|
51
|
+
SCHEMA_YAML_COMMENT = <<COMMENT
|
|
52
|
+
# This file is auto-generated from the current state of the database. Instead
|
|
53
|
+
# of editing this file, please use the migrations feature of Node to
|
|
54
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
|
55
|
+
#
|
|
56
|
+
# Note that this schema.yml definition is the authoritative source for your
|
|
57
|
+
# database schema. If you need to create the application database on another
|
|
58
|
+
# system, you should be using neo4j:schema:load, not running all the migrations
|
|
59
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
|
60
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
|
61
|
+
#
|
|
62
|
+
# It's strongly recommended that you check this file into your version control system.
|
|
63
|
+
|
|
64
|
+
COMMENT
|
|
65
|
+
|
|
66
|
+
def check_neo4j_version_3
|
|
67
|
+
if ActiveGraph::Base.version > '3.0.0'
|
|
68
|
+
yield
|
|
69
|
+
else
|
|
70
|
+
puts 'WARNING: This task does not work for versions of Neo4j before 3.0.0'
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
desc 'Creates a db/neo4j/schema.yml file which represents the indexes / constraints in the Neo4j DB'
|
|
75
|
+
task dump: :environment do
|
|
76
|
+
check_neo4j_version_3 do
|
|
77
|
+
require 'active_graph/migrations/schema'
|
|
78
|
+
|
|
79
|
+
schema_data = ActiveGraph::Migrations::Schema.fetch_schema_data
|
|
80
|
+
|
|
81
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
82
|
+
schema_data[:versions] = runner.complete_migration_versions.sort
|
|
83
|
+
|
|
84
|
+
FileUtils.mkdir_p(File.dirname(SCHEMA_YAML_PATH))
|
|
85
|
+
File.open(SCHEMA_YAML_PATH, 'w') { |file| file << SCHEMA_YAML_COMMENT + schema_data.to_yaml }
|
|
86
|
+
|
|
87
|
+
puts "Dumped updated schema file to #{SCHEMA_YAML_PATH}"
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
desc "Loads a db/neo4j/schema.yml file into the database\nOptionally removes schema elements which aren't in the schema.yml file (defaults to false)"
|
|
92
|
+
task :load, [:remove_missing] => :environment do |_t, args|
|
|
93
|
+
check_neo4j_version_3 do
|
|
94
|
+
require 'active_graph/migrations/schema'
|
|
95
|
+
|
|
96
|
+
args.with_defaults(remove_missing: false)
|
|
97
|
+
|
|
98
|
+
schema_data = YAML.safe_load(File.read(SCHEMA_YAML_PATH), [Symbol])
|
|
99
|
+
|
|
100
|
+
ActiveGraph::Base.subscribe_to_query(&method(:puts))
|
|
101
|
+
|
|
102
|
+
ActiveGraph::Base.transaction do
|
|
103
|
+
ActiveGraph::Migrations::Schema.synchronize_schema_data(schema_data, args[:remove_missing])
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
ActiveGraph::Base.transaction do
|
|
107
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
108
|
+
runner.mark_versions_as_complete(schema_data[:versions]) # Run in test mode?
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
namespace :migrate do
|
|
115
|
+
desc 'Run all pending migrations'
|
|
116
|
+
task all: [:allow_migrations, :environment] do
|
|
117
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
118
|
+
runner.all
|
|
119
|
+
|
|
120
|
+
Rake::Task['neo4j:schema:dump'].invoke
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
desc 'Run a migration given its VERSION'
|
|
124
|
+
task up: [:allow_migrations, :environment] do
|
|
125
|
+
version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required')
|
|
126
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
127
|
+
runner.up version
|
|
128
|
+
|
|
129
|
+
Rake::Task['neo4j:schema:dump'].invoke
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
desc 'Revert a migration given its VERSION'
|
|
133
|
+
task down: [:allow_migrations, :environment] do
|
|
134
|
+
version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required')
|
|
135
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
136
|
+
runner.down version
|
|
137
|
+
|
|
138
|
+
Rake::Task['neo4j:schema:dump'].invoke
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
desc 'Print a report of migrations status'
|
|
142
|
+
task status: [:allow_migrations, :environment] do
|
|
143
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
144
|
+
runner.status
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
desc 'Resolve an incomplete version state'
|
|
148
|
+
task resolve: [:allow_migrations, :environment] do
|
|
149
|
+
version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required')
|
|
150
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
151
|
+
runner.resolve version
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
desc 'Resolve an incomplete version state'
|
|
155
|
+
task reset: [:allow_migrations, :environment] do
|
|
156
|
+
version = ENV['VERSION'] || fail(ArgumentError, 'VERSION is required')
|
|
157
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
158
|
+
runner.reset version
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
desc 'Rollbacks migrations given a STEP number'
|
|
163
|
+
task rollback: [:allow_migrations, :environment] do
|
|
164
|
+
steps = (ENV['STEP'] || 1).to_i
|
|
165
|
+
runner = ActiveGraph::Migrations::Runner.new
|
|
166
|
+
runner.rollback(steps)
|
|
167
|
+
|
|
168
|
+
Rake::Task['neo4j:schema:dump'].invoke
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
# Temporary to help people change to 8.0
|
|
172
|
+
desc 'Generates a migration for the specified constraint/index and label/property combination.'
|
|
173
|
+
task :generate_schema_migration, :index_or_constraint, :label, :property_name do |_t, args|
|
|
174
|
+
index_or_constraint, label, property_name = args.values_at(:index_or_constraint, :label, :property_name)
|
|
175
|
+
|
|
176
|
+
if !%w(index constraint).include?(index_or_constraint)
|
|
177
|
+
fail "Invalid schema element type: #{index_or_constraint} (should be either `index` or `constraint`)"
|
|
178
|
+
end
|
|
179
|
+
fail 'Label must be specified' if label.blank?
|
|
180
|
+
fail 'Property name must be specified' if property_name.blank?
|
|
181
|
+
|
|
182
|
+
migration_class_name = "ForceCreate#{label.camelize}#{property_name.camelize}#{index_or_constraint.capitalize}".gsub('::', '').underscore.camelize
|
|
183
|
+
|
|
184
|
+
require 'fileutils'
|
|
185
|
+
FileUtils.mkdir_p('db/neo4j/migrate')
|
|
186
|
+
path = File.join('db/neo4j/migrate', "#{DateTime.now.utc.strftime('%Y%m%d%H%M%S')}_#{migration_class_name.underscore}.rb")
|
|
187
|
+
|
|
188
|
+
content = <<-CONTENT
|
|
189
|
+
class #{migration_class_name} < ActiveGraph::Migrations::Base
|
|
190
|
+
def up
|
|
191
|
+
add_#{index_or_constraint} #{label.to_sym.inspect}, #{property_name.to_sym.inspect}, force: true
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def down
|
|
195
|
+
drop_#{index_or_constraint} #{label.to_sym.inspect}, #{property_name.to_sym.inspect}
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
CONTENT
|
|
199
|
+
|
|
200
|
+
File.open(path, 'w') { |f| f << content }
|
|
201
|
+
|
|
202
|
+
puts "Generated #{path}"
|
|
203
|
+
end
|
|
204
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require 'active_graph/timestamps/created'
|
|
2
|
+
require 'active_graph/timestamps/updated'
|
|
3
|
+
|
|
4
|
+
module ActiveGraph
|
|
5
|
+
# This mixin includes timestamps in the included class
|
|
6
|
+
module Timestamps
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
include Created
|
|
9
|
+
include Updated
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module ActiveGraph
|
|
2
|
+
module Transaction
|
|
3
|
+
def rollback
|
|
4
|
+
super
|
|
5
|
+
@rolled_back = true
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def after_commit(&block)
|
|
9
|
+
after_commit_registry << block
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def apply_callbacks
|
|
13
|
+
after_commit_registry.each(&:call) unless @rolled_back
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def after_commit_registry
|
|
19
|
+
@after_commit_registry ||= []
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|