neo4j 2.0.0.alpha.5-java → 2.0.0.alpha.6-java
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +12 -0
- data/Gemfile +0 -4
- data/README.rdoc +106 -62
- data/lib/neo4j.rb +7 -33
- data/lib/neo4j/performance.rb +43 -0
- data/lib/neo4j/rails/accept_id.rb +19 -18
- data/lib/neo4j/rails/attributes.rb +366 -120
- data/lib/neo4j/rails/finders.rb +41 -15
- data/lib/neo4j/rails/has_n.rb +203 -0
- data/lib/neo4j/rails/identity.rb +25 -0
- data/lib/neo4j/rails/model.rb +65 -242
- data/lib/neo4j/rails/nested_attributes.rb +108 -0
- data/lib/neo4j/rails/node_persistance.rb +56 -0
- data/lib/neo4j/rails/observer.rb +0 -2
- data/lib/neo4j/rails/persistence.rb +32 -154
- data/lib/neo4j/rails/rack_middleware.rb +26 -2
- data/lib/neo4j/rails/rails.rb +9 -6
- data/lib/neo4j/rails/railtie.rb +1 -2
- data/lib/neo4j/rails/relationship.rb +18 -125
- data/lib/neo4j/rails/relationship_persistence.rb +107 -0
- data/lib/neo4j/rails/relationships/node_dsl.rb +72 -44
- data/lib/neo4j/rails/relationships/relationships.rb +187 -59
- data/lib/neo4j/rails/relationships/rels_dsl.rb +18 -17
- data/lib/neo4j/rails/relationships/storage.rb +19 -17
- data/lib/neo4j/rails/timestamps.rb +53 -51
- data/lib/neo4j/rails/transaction.rb +9 -1
- data/lib/neo4j/rails/validations/uniqueness.rb +1 -1
- data/lib/neo4j/rails/versioning/versioning.rb +2 -2
- data/lib/neo4j/version.rb +1 -1
- data/lib/orm_adapter/adapters/neo4j.rb +47 -46
- data/neo4j.gemspec +1 -1
- metadata +10 -69
- data/lib/neo4j/algo/algo.rb +0 -294
- data/lib/neo4j/batch/batch.rb +0 -4
- data/lib/neo4j/batch/indexer.rb +0 -109
- data/lib/neo4j/batch/inserter.rb +0 -179
- data/lib/neo4j/batch/rule_inserter.rb +0 -24
- data/lib/neo4j/batch/rule_node.rb +0 -72
- data/lib/neo4j/config.rb +0 -177
- data/lib/neo4j/core_ext/class/inheritable_attributes.rb +0 -12
- data/lib/neo4j/core_ext/class/rewrite_inheritable_attributes.rb +0 -170
- data/lib/neo4j/database.rb +0 -158
- data/lib/neo4j/equal.rb +0 -21
- data/lib/neo4j/event_handler.rb +0 -263
- data/lib/neo4j/has_list/class_methods.rb +0 -11
- data/lib/neo4j/has_list/has_list.rb +0 -3
- data/lib/neo4j/has_list/mapping.rb +0 -133
- data/lib/neo4j/has_n/class_methods.rb +0 -119
- data/lib/neo4j/has_n/decl_relationship_dsl.rb +0 -246
- data/lib/neo4j/has_n/has_n.rb +0 -3
- data/lib/neo4j/has_n/mapping.rb +0 -98
- data/lib/neo4j/identity_map.rb +0 -140
- data/lib/neo4j/index/class_methods.rb +0 -108
- data/lib/neo4j/index/index.rb +0 -39
- data/lib/neo4j/index/indexer.rb +0 -341
- data/lib/neo4j/index/indexer_registry.rb +0 -68
- data/lib/neo4j/index/lucene_query.rb +0 -256
- data/lib/neo4j/load.rb +0 -25
- data/lib/neo4j/migrations/class_methods.rb +0 -110
- data/lib/neo4j/migrations/extensions.rb +0 -58
- data/lib/neo4j/migrations/lazy_node_mixin.rb +0 -41
- data/lib/neo4j/migrations/migration.rb +0 -112
- data/lib/neo4j/migrations/migrations.rb +0 -6
- data/lib/neo4j/migrations/node_mixin.rb +0 -80
- data/lib/neo4j/migrations/ref_node_wrapper.rb +0 -32
- data/lib/neo4j/model.rb +0 -4
- data/lib/neo4j/neo4j.rb +0 -216
- data/lib/neo4j/node.rb +0 -270
- data/lib/neo4j/node_mixin/class_methods.rb +0 -51
- data/lib/neo4j/node_mixin/node_mixin.rb +0 -141
- data/lib/neo4j/paginated.rb +0 -23
- data/lib/neo4j/property/class_methods.rb +0 -79
- data/lib/neo4j/property/property.rb +0 -111
- data/lib/neo4j/rails/mapping/property.rb +0 -183
- data/lib/neo4j/rails/rel_persistence.rb +0 -237
- data/lib/neo4j/relationship.rb +0 -239
- data/lib/neo4j/relationship_mixin/class_methods.rb +0 -36
- data/lib/neo4j/relationship_mixin/relationship_mixin.rb +0 -142
- data/lib/neo4j/relationship_set.rb +0 -58
- data/lib/neo4j/rels/rels.rb +0 -110
- data/lib/neo4j/rels/traverser.rb +0 -102
- data/lib/neo4j/rule/class_methods.rb +0 -201
- data/lib/neo4j/rule/event_listener.rb +0 -66
- data/lib/neo4j/rule/functions/count.rb +0 -43
- data/lib/neo4j/rule/functions/function.rb +0 -74
- data/lib/neo4j/rule/functions/functions.rb +0 -3
- data/lib/neo4j/rule/functions/sum.rb +0 -29
- data/lib/neo4j/rule/rule.rb +0 -150
- data/lib/neo4j/rule/rule_node.rb +0 -217
- data/lib/neo4j/to_java.rb +0 -31
- data/lib/neo4j/transaction.rb +0 -73
- data/lib/neo4j/traversal/filter_predicate.rb +0 -25
- data/lib/neo4j/traversal/prune_evaluator.rb +0 -14
- data/lib/neo4j/traversal/rel_expander.rb +0 -31
- data/lib/neo4j/traversal/traversal.rb +0 -141
- data/lib/neo4j/traversal/traverser.rb +0 -284
- data/lib/neo4j/type_converters/type_converters.rb +0 -288
data/lib/neo4j/paginated.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
|
3
|
-
# The class provides the pagination based on the given source.
|
4
|
-
# The source must be an Enumerable implementing methods drop, first and count (or size).
|
5
|
-
# This can be used to paginage any Enumerable collection and
|
6
|
-
# provides the integration point for other gems, like will_paginate and kaminari.
|
7
|
-
class Paginated
|
8
|
-
include Enumerable
|
9
|
-
attr_reader :items, :total, :current_page
|
10
|
-
|
11
|
-
def initialize(items, total, current_page)
|
12
|
-
@items, @total, @current_page = items, total, current_page
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.create_from(source, page, per_page)
|
16
|
-
partial = source.drop((page-1) * per_page).first(per_page)
|
17
|
-
Paginated.new(partial, source.count, page)
|
18
|
-
end
|
19
|
-
|
20
|
-
delegate :each, :to => :items
|
21
|
-
delegate :size, :[], :to => :items
|
22
|
-
end
|
23
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module Property
|
3
|
-
|
4
|
-
module ClassMethods
|
5
|
-
|
6
|
-
# Generates accessor method and sets configuration for Neo4j node properties.
|
7
|
-
# The generated accessor is a simple wrapper around the #[] and
|
8
|
-
# #[]= operators.
|
9
|
-
#
|
10
|
-
# ==== Types
|
11
|
-
# If a property is set to nil the property will be removed.
|
12
|
-
# A property can be of any primitive type (Boolean, String, Fixnum, Float) and does not
|
13
|
-
# even have to be the same. Arrays of primitive types is also supported. Array values must
|
14
|
-
# be of the same type and are mutable, e.g. you have to create a new array if you want to change one value.
|
15
|
-
#
|
16
|
-
# Example:
|
17
|
-
# class Foo
|
18
|
-
# include Neo4j::NodeMixin
|
19
|
-
# property :age
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# Example:
|
23
|
-
# foo = Foo.new
|
24
|
-
# foo.age = "hej" # first set it to string
|
25
|
-
# foo.age = 42 # change it to a Fixnum
|
26
|
-
#
|
27
|
-
# However, you can specify an type for the index, see Neo4j::Index::Indexer#index
|
28
|
-
#
|
29
|
-
# ==== Conversions
|
30
|
-
#
|
31
|
-
# It is possible to do conversions between types in order to support none primitive types
|
32
|
-
# Example:
|
33
|
-
#
|
34
|
-
# class Foo
|
35
|
-
# include Neo4j::NodeMixin
|
36
|
-
# property :since, :type => DateTime # will be converted into a fixnum
|
37
|
-
# end
|
38
|
-
#
|
39
|
-
# You can write your own converter by writing a class that respond to :convert?, :to_ruby and
|
40
|
-
# :to_java in the Neo4j::TypeConverters module.
|
41
|
-
#
|
42
|
-
def property(*props)
|
43
|
-
options = props.last.kind_of?(Hash) ? props.pop : {}
|
44
|
-
|
45
|
-
props.uniq.each do |prop|
|
46
|
-
pname = prop.to_sym
|
47
|
-
_decl_props[pname] ||= {}
|
48
|
-
options.each do |key, value|
|
49
|
-
_decl_props[pname][key] = value
|
50
|
-
end
|
51
|
-
|
52
|
-
define_method(pname) do
|
53
|
-
Neo4j::TypeConverters.to_ruby(self.class, pname, self[pname])
|
54
|
-
end
|
55
|
-
|
56
|
-
name = (pname.to_s() +"=").to_sym
|
57
|
-
define_method(name) do |value|
|
58
|
-
self[pname] = Neo4j::TypeConverters.to_java(self.class, pname, value)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
# Returns true if the given property name has been defined with the class
|
65
|
-
# method property or properties.
|
66
|
-
#
|
67
|
-
# Notice that the node may have properties that has not been declared.
|
68
|
-
# It is always possible to set an undeclared property on a node.
|
69
|
-
#
|
70
|
-
# ==== Returns
|
71
|
-
# true or false
|
72
|
-
#
|
73
|
-
def property?(prop_name)
|
74
|
-
return false if _decl_props[prop_name.to_sym].nil?
|
75
|
-
!_decl_props[prop_name.to_sym].nil?
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,111 +0,0 @@
|
|
1
|
-
require 'neo4j/property/class_methods'
|
2
|
-
|
3
|
-
module Neo4j
|
4
|
-
module Property
|
5
|
-
|
6
|
-
# Returns a hash of all properties
|
7
|
-
# It also include the id of the node with the key <tt>_neo_id</tt>
|
8
|
-
#
|
9
|
-
def props
|
10
|
-
ret = {"_neo_id" => neo_id}
|
11
|
-
iter = getPropertyKeys.iterator
|
12
|
-
while (iter.hasNext) do
|
13
|
-
key = iter.next
|
14
|
-
ret[key] = get_property(key)
|
15
|
-
end
|
16
|
-
ret
|
17
|
-
end
|
18
|
-
|
19
|
-
# Returns the unique id of this node.
|
20
|
-
# Ids are garbage collected over time so they are only guaranteed to be unique during a specific time span:
|
21
|
-
# if the node is deleted, it's likely that a new node at some point will get the old id. Note:
|
22
|
-
# this makes node ids brittle as public APIs.
|
23
|
-
def neo_id
|
24
|
-
getId
|
25
|
-
end
|
26
|
-
|
27
|
-
# Returns a hash of properties with keys not starting with <tt>_</tt>
|
28
|
-
# That means that the neo_id will not be included in the returned hash.
|
29
|
-
#
|
30
|
-
def attributes
|
31
|
-
attr = props
|
32
|
-
ret = {}
|
33
|
-
attr.each_pair { |k, v| ret[k] = wrapper.respond_to?(k) ? wrapper.send(k) : v unless k.to_s[0] == ?_ }
|
34
|
-
ret
|
35
|
-
end
|
36
|
-
|
37
|
-
# Checks if the given key exist as a property.
|
38
|
-
def property?(key)
|
39
|
-
has_property?(key.to_s)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Updates this node/relationship's properties by using the provided struct/hash.
|
43
|
-
# If the option <code>{:strict => true}</code> is given, any properties present on
|
44
|
-
# the node but not present in the hash will be removed from the node.
|
45
|
-
#
|
46
|
-
# ==== Parameters
|
47
|
-
# struct_or_hash:: the key and value to be set, should respond to <tt>each_pair</tt>
|
48
|
-
# options:: further options defining the context of the update, should be a Hash
|
49
|
-
#
|
50
|
-
# ==== Returns
|
51
|
-
# self
|
52
|
-
#
|
53
|
-
def update(struct_or_hash, options={})
|
54
|
-
strict = options[:strict]
|
55
|
-
keys_to_delete = props.keys - %w(_neo_id _classname) if strict
|
56
|
-
struct_or_hash.each_pair do |key, value|
|
57
|
-
next if %w(_neo_id _classname).include? key.to_s
|
58
|
-
# do not allow special properties to be mass assigned
|
59
|
-
keys_to_delete.delete(key) if strict
|
60
|
-
setter_meth = "#{key}=".to_sym
|
61
|
-
if @_wrapper && @_wrapper.respond_to?(setter_meth)
|
62
|
-
@_wrapper.send(setter_meth, value)
|
63
|
-
else
|
64
|
-
self[key] = value
|
65
|
-
end
|
66
|
-
end
|
67
|
-
keys_to_delete.each { |key| remove_property(key) } if strict
|
68
|
-
self
|
69
|
-
end
|
70
|
-
|
71
|
-
|
72
|
-
# Returns the value of the given key or nil if the property does not exist.
|
73
|
-
def [](key)
|
74
|
-
return unless property?(key)
|
75
|
-
val = get_property(key.to_s)
|
76
|
-
val.class.superclass == ArrayJavaProxy ? val.to_a : val
|
77
|
-
end
|
78
|
-
|
79
|
-
# Sets the property of this node.
|
80
|
-
# Property keys are always strings. Valid property value types are the primitives(<tt>String</tt>, <tt>Fixnum</tt>, <tt>Float</tt>, <tt>FalseClass</tt>, <tt>TrueClass</tt>) or array of those primitives.
|
81
|
-
#
|
82
|
-
# ==== Gotchas
|
83
|
-
# * Values in the array must be of the same type.
|
84
|
-
# * You can *not* delete or add one item in the array (e.g. person.phones.delete('123')) but instead you must create a new array instead.
|
85
|
-
#
|
86
|
-
def []=(key, value)
|
87
|
-
k = key.to_s
|
88
|
-
if value.nil?
|
89
|
-
remove_property(k)
|
90
|
-
elsif (Array === value)
|
91
|
-
case value[0]
|
92
|
-
when NilClass
|
93
|
-
set_property(k, [].to_java(:string))
|
94
|
-
when String
|
95
|
-
set_property(k, value.to_java(:string))
|
96
|
-
when Float
|
97
|
-
set_property(k, value.to_java(:double))
|
98
|
-
when FalseClass, TrueClass
|
99
|
-
set_property(k, value.to_java(:boolean))
|
100
|
-
when Fixnum
|
101
|
-
set_property(k, value.to_java(:long))
|
102
|
-
else
|
103
|
-
raise "Not allowed to store array with value #{value[0]} type #{value[0].class}"
|
104
|
-
end
|
105
|
-
else
|
106
|
-
set_property(k, value)
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
end
|
111
|
-
end
|
@@ -1,183 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module Rails
|
3
|
-
module Mapping
|
4
|
-
module Property
|
5
|
-
extend ActiveSupport::Concern
|
6
|
-
|
7
|
-
module ClassMethods
|
8
|
-
|
9
|
-
# Create two new methods: rel_name and rel_name_rels
|
10
|
-
# The first one returns an Neo4j::Rails::Relationships::NodesDSL
|
11
|
-
# the second generate method (with the _rels postfix) returns a
|
12
|
-
# Neo4j::Rails::Relationships::RelsDSL
|
13
|
-
#
|
14
|
-
# See also Neo4j::NodeMixin#has_n which only work with persisted relationships.
|
15
|
-
#
|
16
|
-
def has_n(*args)
|
17
|
-
options = args.extract_options!
|
18
|
-
define_has_n_methods_for(args.first, options)
|
19
|
-
end
|
20
|
-
|
21
|
-
# See #has_n
|
22
|
-
def has_one(*args)
|
23
|
-
options = args.extract_options!
|
24
|
-
define_has_one_methods_for(args.first, options)
|
25
|
-
end
|
26
|
-
|
27
|
-
# Returns all defined properties
|
28
|
-
def columns
|
29
|
-
self._decl_props.keys
|
30
|
-
end
|
31
|
-
|
32
|
-
def define_has_one_methods_for(rel_type, options) #:nodoc:
|
33
|
-
unless method_defined?(rel_type)
|
34
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
35
|
-
def #{rel_type}
|
36
|
-
dsl = _decl_rels_for(:'#{rel_type}')
|
37
|
-
storage = _create_or_get_storage_for_decl_rels(dsl)
|
38
|
-
storage.single_node(dsl.dir)
|
39
|
-
end
|
40
|
-
RUBY
|
41
|
-
end
|
42
|
-
|
43
|
-
unless method_defined?("#{rel_type}_rel")
|
44
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
45
|
-
def #{rel_type}_rel
|
46
|
-
dsl = _decl_rels_for(:'#{rel_type}')
|
47
|
-
storage = _create_or_get_storage_for_decl_rels(dsl)
|
48
|
-
storage.single_relationship(dsl.dir)
|
49
|
-
end
|
50
|
-
RUBY
|
51
|
-
end
|
52
|
-
|
53
|
-
unless method_defined?("#{rel_type}=".to_sym)
|
54
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
55
|
-
def #{rel_type}=(other)
|
56
|
-
dsl = _decl_rels_for(:'#{rel_type}')
|
57
|
-
storage = _create_or_get_storage_for_decl_rels(dsl)
|
58
|
-
storage.destroy_single_relationship(dsl.dir)
|
59
|
-
storage.create_relationship_to(other, dsl.dir)
|
60
|
-
end
|
61
|
-
RUBY
|
62
|
-
end
|
63
|
-
_decl_rels[rel_type.to_sym] = Neo4j::HasN::DeclRelationshipDsl.new(rel_type, true, self)
|
64
|
-
end
|
65
|
-
|
66
|
-
def define_has_n_methods_for(rel_type, options) #:nodoc:
|
67
|
-
unless method_defined?(rel_type)
|
68
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
69
|
-
def #{rel_type}
|
70
|
-
dsl = _decl_rels_for(:'#{rel_type}')
|
71
|
-
storage = _create_or_get_storage_for_decl_rels(dsl)
|
72
|
-
NodesDSL.new(storage, dsl.dir)
|
73
|
-
end
|
74
|
-
RUBY
|
75
|
-
end
|
76
|
-
|
77
|
-
unless method_defined?("#{rel_type}=".to_sym)
|
78
|
-
|
79
|
-
# TODO: This is a temporary fix for allowing running neo4j with Formtastic, issue 109
|
80
|
-
# A better solution might be to implement accept_ids for has_n relationship and
|
81
|
-
# make sure (somehow) that Formtastic uses the _ids methods.
|
82
|
-
|
83
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
84
|
-
def #{rel_type}=(nodes)
|
85
|
-
if nodes.is_a?(Array) && nodes.first.is_a?(String)
|
86
|
-
if nodes.first.blank?
|
87
|
-
self.#{rel_type}_rels.destroy_all
|
88
|
-
nodes.shift
|
89
|
-
end
|
90
|
-
else
|
91
|
-
self.#{rel_type}_rels.destroy_all
|
92
|
-
end
|
93
|
-
association = self.#{rel_type}
|
94
|
-
nodes.each { |node| association << node }
|
95
|
-
end
|
96
|
-
RUBY
|
97
|
-
end
|
98
|
-
|
99
|
-
unless method_defined?("#{rel_type}_rels".to_sym)
|
100
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
101
|
-
def #{rel_type}_rels
|
102
|
-
dsl = _decl_rels_for(:'#{rel_type}')
|
103
|
-
storage = _create_or_get_storage_for_decl_rels(dsl)
|
104
|
-
RelsDSL.new(storage, dsl.dir)
|
105
|
-
end
|
106
|
-
RUBY
|
107
|
-
end
|
108
|
-
|
109
|
-
instance_eval <<-RUBY, __FILE__, __LINE__
|
110
|
-
def #{rel_type}
|
111
|
-
_decl_rels[:'#{rel_type}'].rel_type.to_s
|
112
|
-
end
|
113
|
-
RUBY
|
114
|
-
|
115
|
-
_decl_rels[rel_type.to_sym] = Neo4j::HasN::DeclRelationshipDsl.new(rel_type, false, self)
|
116
|
-
end
|
117
|
-
|
118
|
-
# Handles options for the property
|
119
|
-
#
|
120
|
-
# Set the property type :type => Time
|
121
|
-
# Set a default :default => "default"
|
122
|
-
# Property must be there :null => false
|
123
|
-
# Property has a length limit :limit => 128
|
124
|
-
def property(*args)
|
125
|
-
options = args.extract_options!
|
126
|
-
args.each do |property_sym|
|
127
|
-
property_setup(property_sym, options)
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
protected
|
132
|
-
def property_setup(property, options)
|
133
|
-
_decl_props[property] = options
|
134
|
-
handle_property_options_for(property, options)
|
135
|
-
define_property_methods_for(property, options)
|
136
|
-
define_property_before_type_cast_methods_for(property, options)
|
137
|
-
end
|
138
|
-
|
139
|
-
def handle_property_options_for(property, options)
|
140
|
-
attribute_defaults[property.to_s] = options[:default] if options.has_key?(:default)
|
141
|
-
|
142
|
-
if options.has_key?(:null) && options[:null] === false
|
143
|
-
validates(property, :non_nil => true, :on => :create)
|
144
|
-
validates(property, :non_nil => true, :on => :update)
|
145
|
-
end
|
146
|
-
validates(property, :length => { :maximum => options[:limit] }) if options[:limit]
|
147
|
-
end
|
148
|
-
|
149
|
-
def define_property_methods_for(property, options)
|
150
|
-
unless method_defined?(property)
|
151
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
152
|
-
def #{property}
|
153
|
-
send(:[], "#{property}")
|
154
|
-
end
|
155
|
-
RUBY
|
156
|
-
end
|
157
|
-
|
158
|
-
unless method_defined?("#{property}=".to_sym)
|
159
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
160
|
-
def #{property}=(value)
|
161
|
-
send(:[]=, "#{property}", value)
|
162
|
-
end
|
163
|
-
RUBY
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
def define_property_before_type_cast_methods_for(property, options)
|
168
|
-
property_before_type_cast = "#{property}_before_type_cast"
|
169
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
170
|
-
def #{property_before_type_cast}=(value)
|
171
|
-
@properties_before_type_cast[:#{property}]=value
|
172
|
-
end
|
173
|
-
|
174
|
-
def #{property_before_type_cast}
|
175
|
-
@properties_before_type_cast.has_key?(:#{property}) ? @properties_before_type_cast[:#{property}] : self.#{property}
|
176
|
-
end
|
177
|
-
RUBY
|
178
|
-
end
|
179
|
-
end
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
end
|
@@ -1,237 +0,0 @@
|
|
1
|
-
module Neo4j
|
2
|
-
module Rails
|
3
|
-
module RelPersistence
|
4
|
-
extend ActiveSupport::Concern
|
5
|
-
|
6
|
-
included do
|
7
|
-
extend TxMethods
|
8
|
-
tx_methods :destroy, :create, :update, :delete
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
|
-
# Persist the object to the database. Validations and Callbacks are included
|
13
|
-
# by default but validation can be disabled by passing :validate => false
|
14
|
-
# to #save.
|
15
|
-
def save(*)
|
16
|
-
create_or_update
|
17
|
-
end
|
18
|
-
|
19
|
-
# Persist the object to the database. Validations and Callbacks are included
|
20
|
-
# by default but validation can be disabled by passing :validate => false
|
21
|
-
# to #save!.
|
22
|
-
#
|
23
|
-
# Raises a RecordInvalidError if there is a problem during save.
|
24
|
-
def save!(*args)
|
25
|
-
unless save(*args)
|
26
|
-
raise RecordInvalidError.new(self)
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Updates a single attribute and saves the record.
|
31
|
-
# This is especially useful for boolean flags on existing records. Also note that
|
32
|
-
#
|
33
|
-
# * Validation is skipped.
|
34
|
-
# * Callbacks are invoked.
|
35
|
-
# * Updates all the attributes that are dirty in this object.
|
36
|
-
#
|
37
|
-
def update_attribute(name, value)
|
38
|
-
respond_to?("#{name}=") ? send("#{name}=", value) : self[name] = value
|
39
|
-
save(:validate => false)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Removes the node from Neo4j and freezes the object.
|
43
|
-
def destroy
|
44
|
-
delete
|
45
|
-
freeze
|
46
|
-
end
|
47
|
-
|
48
|
-
# Same as #destroy but doesn't run destroy callbacks and doesn't freeze
|
49
|
-
# the object
|
50
|
-
def delete
|
51
|
-
del unless new_record?
|
52
|
-
set_deleted_properties
|
53
|
-
end
|
54
|
-
|
55
|
-
# Returns true if the object was destroyed.
|
56
|
-
def destroyed?()
|
57
|
-
@_deleted || Neo4j::Relationship._load(id).nil?
|
58
|
-
end
|
59
|
-
|
60
|
-
# Updates this resource with all the attributes from the passed-in Hash and requests that the record be saved.
|
61
|
-
# If saving fails because the resource is invalid then false will be returned.
|
62
|
-
def update_attributes(attributes)
|
63
|
-
self.attributes = attributes
|
64
|
-
save
|
65
|
-
end
|
66
|
-
|
67
|
-
# Same as #update_attributes, but raises an exception if saving fails.
|
68
|
-
def update_attributes!(attributes)
|
69
|
-
self.attributes = attributes
|
70
|
-
save!
|
71
|
-
end
|
72
|
-
|
73
|
-
# Reload the object from the DB.
|
74
|
-
def reload(options = nil)
|
75
|
-
clear_changes
|
76
|
-
reset_attributes
|
77
|
-
unless reload_from_database
|
78
|
-
set_deleted_properties
|
79
|
-
freeze
|
80
|
-
end
|
81
|
-
self
|
82
|
-
end
|
83
|
-
|
84
|
-
# Returns if the record is persisted, i.e. it’s not a new record and it was not destroyed
|
85
|
-
def persisted?
|
86
|
-
!new_record? && !destroyed?
|
87
|
-
end
|
88
|
-
|
89
|
-
# Returns true if the record hasn't been saved to Neo4j yet.
|
90
|
-
def new_record?
|
91
|
-
_java_rel.nil?
|
92
|
-
end
|
93
|
-
|
94
|
-
alias :new? :new_record?
|
95
|
-
|
96
|
-
# Freeze the properties hash.
|
97
|
-
def freeze
|
98
|
-
@properties.freeze; self
|
99
|
-
end
|
100
|
-
|
101
|
-
# Returns +true+ if the properties hash has been frozen.
|
102
|
-
def frozen?
|
103
|
-
reload
|
104
|
-
@properties.frozen?
|
105
|
-
end
|
106
|
-
|
107
|
-
module ClassMethods
|
108
|
-
# Initialize a model and set a bunch of attributes at the same time. Returns
|
109
|
-
# the object whether saved successfully or not.
|
110
|
-
def create(*args)
|
111
|
-
new(*args).tap do |o|
|
112
|
-
yield o if block_given?
|
113
|
-
o.save
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
# Same as #create, but raises an error if there is a problem during save.
|
118
|
-
# Returns the object whether saved successfully or not.
|
119
|
-
def create!(*args)
|
120
|
-
new(*args).tap do |o|
|
121
|
-
yield o if block_given?
|
122
|
-
o.save!
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# Destroy each node in turn. Runs the destroy callbacks for each node.
|
127
|
-
def destroy_all
|
128
|
-
all.each do |n|
|
129
|
-
n.destroy
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
protected
|
135
|
-
def create_or_update
|
136
|
-
result = persisted? ? update : create
|
137
|
-
unless result != false
|
138
|
-
Neo4j::Rails::Transaction.fail if Neo4j::Rails::Transaction.running?
|
139
|
-
false
|
140
|
-
else
|
141
|
-
true
|
142
|
-
end
|
143
|
-
end
|
144
|
-
|
145
|
-
def update
|
146
|
-
write_changed_attributes
|
147
|
-
clear_changes
|
148
|
-
true
|
149
|
-
end
|
150
|
-
|
151
|
-
def create()
|
152
|
-
begin
|
153
|
-
# prevent calling create twice
|
154
|
-
@start_node.add_unpersisted_outgoing_rel(type, self)
|
155
|
-
@end_node.add_unpersisted_incoming_rel(type, self)
|
156
|
-
|
157
|
-
return unless _persist_start_node && _persist_end_node
|
158
|
-
|
159
|
-
@_java_rel = Neo4j::Relationship.new(type, start_node, end_node)
|
160
|
-
Neo4j::IdentityMap.add(@_java_rel, self)
|
161
|
-
init_on_create
|
162
|
-
clear_changes
|
163
|
-
|
164
|
-
@start_node.rm_unpersisted_outgoing_rel(type, self)
|
165
|
-
@end_node.rm_unpersisted_incoming_rel(type, self)
|
166
|
-
|
167
|
-
end unless @end_node.nil? or @start_node.nil?
|
168
|
-
true
|
169
|
-
end
|
170
|
-
|
171
|
-
def _load(id)
|
172
|
-
Neo4j::Relationship.load(id)
|
173
|
-
end
|
174
|
-
|
175
|
-
def _persist_start_node
|
176
|
-
(!@start_node.persisted? || @start_node.relationships_changed?) ? @start_node.save : true
|
177
|
-
end
|
178
|
-
|
179
|
-
def _persist_end_node
|
180
|
-
(!@end_node.persisted? || @end_node.relationships_changed?) ? @end_node.save : true
|
181
|
-
end
|
182
|
-
|
183
|
-
|
184
|
-
def init_on_create(*)
|
185
|
-
#self["_classname"] = self.class.to_s
|
186
|
-
write_default_attributes
|
187
|
-
write_changed_attributes
|
188
|
-
@_java_rel[:_classname] = self.class.to_s
|
189
|
-
end
|
190
|
-
|
191
|
-
def reset_attributes
|
192
|
-
@properties = {}
|
193
|
-
end
|
194
|
-
|
195
|
-
def reload_from_database
|
196
|
-
Neo4j::IdentityMap.remove_rel_by_id(id) if persisted?
|
197
|
-
Neo4j::IdentityMap.remove_node_by_id(@end_node.id) if @end_node && @end_node.persisted?
|
198
|
-
Neo4j::IdentityMap.remove_node_by_id(@start_node.id) if @start_node && @start_node.persisted?
|
199
|
-
|
200
|
-
if reloaded = self.class.load(id)
|
201
|
-
send(:attributes=, reloaded.attributes, false)
|
202
|
-
end
|
203
|
-
reloaded
|
204
|
-
end
|
205
|
-
|
206
|
-
def set_deleted_properties
|
207
|
-
@_deleted = true
|
208
|
-
@_persisted = false
|
209
|
-
end
|
210
|
-
|
211
|
-
# Ensure any defaults are stored in the DB
|
212
|
-
def write_default_attributes
|
213
|
-
attribute_defaults.each do |attribute, value|
|
214
|
-
write_attribute(attribute, Neo4j::TypeConverters.convert(value, attribute, self.class)) unless changed_attributes.has_key?(attribute) || _java_rel.has_property?(attribute)
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
# Write attributes to the Neo4j DB only if they're altered
|
219
|
-
def write_changed_attributes
|
220
|
-
@properties.each do |attribute, value|
|
221
|
-
write_attribute(attribute, value) if changed_attributes.has_key?(attribute)
|
222
|
-
end
|
223
|
-
end
|
224
|
-
|
225
|
-
class RecordInvalidError < RuntimeError
|
226
|
-
attr_reader :record
|
227
|
-
|
228
|
-
def initialize(record)
|
229
|
-
@record = record
|
230
|
-
super(@record.errors.full_messages.join(", "))
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
end
|
235
|
-
|
236
|
-
end
|
237
|
-
end
|