neo4j 3.0.0.alpha.8 → 3.0.0.alpha.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d97243db16c4dce2d4e87eb9551116729065fe2a
4
- data.tar.gz: 311559376e0de462bbde5d9dae2d348c041fd3f6
3
+ metadata.gz: c1f7216c885708e2f7b3f094a4ab4266e83c37a0
4
+ data.tar.gz: 7350f7cd2f95de57873b607bda7a7a6357b29643
5
5
  SHA512:
6
- metadata.gz: 197a923f6617ced1dab9a81adea38fb13fe55b5bd7429b4e84c461b53c2d98b31ff053ee2eb6228541792ba58309b3058d9dee4a0cece6ec68dff79eae921ac4
7
- data.tar.gz: c1a71b84e759fd55ab9040c6d357d08cbdf22710e5e7eacbb7b4ddff01a3b07834a4e52c2dc378feb20a6d5c9a01891839216da5918d6ac4559b9e24cfcf87f2
6
+ metadata.gz: cf800fb8a523e06f163e837985600bfa84109f74b2b548e18bd99961adb28e3ee5703963fe34e8939688af842eb2dc3b4d7ae3d529412ef2ce3791fa924bb922
7
+ data.tar.gz: 3f0e91124dbe00b6f102d82c9f69117ecd9f4268c87d3f30600e145078ae28e155f69927415d8e106f93015ed4c694a4df9da540330d7cf929e5abd4ff23b6a2
data/CHANGELOG CHANGED
@@ -1,3 +1,11 @@
1
+ == 3.0.0.alpha.9
2
+ * Complete rewrite of the query api, see wiki page (#406, chris, brian)
3
+ * Performance improvements (#382,#400, #402, chris)
4
+ * idproperty - user defined primary keys (#396,#389)
5
+ * Reimplementation of Neo4j::Config
6
+ * Serialization of node properties (#381)
7
+ * Better first,last syntax (#379)
8
+
1
9
  == 3.0.0.alpha.8
2
10
  * Integration with new Query API from neo4j-core including:
3
11
  * - .query_as and #query_as methods to get queries from models (#366)
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source 'http://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  #gem 'neo4j-core', :path => '../neo4j-core'
6
-
6
+ #gem 'neo4j-core', :git => 'https://github.com/andreasronge/neo4j-core.git'
7
7
  #gem 'orm_adapter', :path => '../orm_adapter'
8
8
 
9
9
  gem 'coveralls', require: false
@@ -1,98 +1,33 @@
1
1
  #=== Neo4j.rb configuration settings
2
2
 
3
- # The folder location of the neo4j and lucene database
4
- storage_path: db
5
3
 
6
- # If enable neo4j.rb will create _all relationship to all instances inheriting from Neo4j::Rails::Model
7
- # If disabled all custom rules will also be unavailable.
8
- enable_rules: true
4
+ # Examples of not using the Neo4j id (neo_id)
9
5
 
6
+ # Generated UUID stored as a neo4j property on my_id
7
+ #id_property: my_id
8
+ #id_property_type: :auto
9
+ #id_property_type_value: :uuid
10
+
11
+ # Example, (probably more useful directly on Neo4j::ActiveNode classes instead as a global configuration)
12
+ #id_property: title_id
13
+ #id_property_type: :on
14
+ #id_property_type_value: :some_method
15
+
16
+ # TODO
10
17
  # if identity map should be on or not
11
18
  # It may impact the performance. Using the identity map will keep all loaded wrapper node/relationship
12
19
  # object in memory for each thread and transaction - which may speed up or slow down operations.
13
20
  identity_map: false
14
21
 
22
+ # TODO
15
23
  # When using the Neo4j::Model you can let neo4j automatically set timestamps when updating/creating nodes.
16
24
  # If set to true neo4j.rb automatically timestamps create and update operations if the model has properties named created_at/created_on or updated_at/updated_on
17
25
  # (similar to ActiveRecord).
18
26
  timestamps: true
19
27
 
20
- # Configuration for lucene
21
- lucene: { fulltext: { provider: lucene,
22
- type: fulltext },
23
- exact: { provider: lucene,
24
- type: exact}
25
- }
26
-
27
- ## If online backup should be available, if it is the Online JAR file will be loaded,
28
- ## Notice it must be either 'true' or 'false' as string
29
- #enable_online_backup: 'false'
30
- #
31
- ##use the clustered Neo4j GraphDatabase (org.neo4j.kernel.HighlyAvailableGraphDatabase)
32
- #ha.db: false
33
- #
34
- ## Example of HA Configuration, see http://wiki.neo4j.org/content/High_Availability_Cluster
35
- ## This is only used when ha.db is set to true
36
- #ha.server_id: 2
37
- #ha.server: 'localhost:6002'
38
- #ha.coordinators: 'localhost:2181,localhost:2182,localhost:2183'
39
- #
40
- ## if enabled you can use the bin/neo4j-shell command to access the database
41
- #enable_remote_shell: "port=9332"
42
- #
43
- ##===Memory mapped I/O settings===
44
- #
45
- ##Each file in the Neo store can use memory mapped I/O for reading/writing.
46
- ##Best performance is achived if the full file can be memory mapped but if
47
- ##there isn't enough memory for that Neo will try and make the best use of
48
- ##the memory it gets (regions of the file that get accessed often will more
49
- ##likley be memory mapped).
50
- #
51
- ##For high traversal speed it is important to have the nodestore.db and
52
- ##relationshipstore.db files.
53
- #
54
- #neostore.nodestore.db.mapped_memory: 25M
55
- #neostore.relationshipstore.db.mapped_memory: 50M
56
- #neostore.propertystore.db.mapped_memory: 90M
57
- #neostore.propertystore.db.index.mapped_memory: 1M
58
- #neostore.propertystore.db.index.keys.mapped_memory: 1M
59
- #neostore.propertystore.db.strings.mapped_memory: 130M
60
- #neostore.propertystore.db.arrays.mapped_memory: 130M
61
- #
62
- #
63
- ##: ": ": "Cache settings: ": ": "
64
- #
65
- ##use adaptive caches YES|NO. Let Neo try make best use of available heap.
66
- #use_adaptive_cache: YES
67
- #
68
- ##heap usage/max heap size ratio. Neo will increase caches while ratio
69
- ##is less and decrease if greater. Default 0.77 seems to be a good over
70
- ##all ratio of heap usage to avoid GC trashing. Larger heaps may allow for
71
- ##a higher ratio while tiny heaps may need even less.
72
- #adaptive_cache_heap_ratio: 0.77
73
- #
74
- ##how aggressive Neo will decrease caches once heap ratio reached
75
- #adaptive_cache_manager_decrease_ratio: 1.15
76
- #
77
- ##how aggresive Neo will increase caches if ratio isn't yet reached
78
- #adaptive_cache_manager_increase_ratio: 1.1
79
- #
80
- ##if no requests are made to Neo this is the amount of time in ms Neo will wait
81
- ##before it checks the heap usage and adapts the caches if needed
82
- #adaptive_cache_worker_sleep_time: 3000
83
- #
84
- ##minimum size (number of nodes) of node cache. If adaptive cache is in use
85
- ##node cache will not be decreased under this value
86
- #min_node_cache_size: 0
87
- #
88
- ##minimum size (number of relationships) of relationship cache. If adaptive
89
- ##cache is in use relationship cache will not be decreased under this value
90
- #min_relationship_cache_size: 0
91
- #
92
- ##maximum size (number of nodes) of node cache. If adaptive cache is not in
93
- ##use the node cache will not be increased above this value
94
- #max_node_cache_size: 1500
95
- #
96
- ##maximum size (number of relationship) of node cache. If adaptive cache is
97
- ##not in use the relationship cache will not be increased above this value
98
- #max_relationship_cache_size: 3500
28
+ # Store a property on objects to cache their ActiveNode/ActiveRel class. It prevents each object load from requiring two database queries.
29
+ # Strings shorter than 44 characters are classified, so this will have almost no impact on disk footprint. See http://docs.neo4j.org/chunked/stable/short-strings.html.
30
+ # Alternatively, call class method Neo4j::ActiveNode:cache_class to set this on specific models.
31
+ # By default, this property is called _classname, set as symbol to override.
32
+ cache_class_names: true
33
+ # class_name_property: :_classname
data/lib/neo4j.rb CHANGED
@@ -15,10 +15,12 @@ require 'active_support/concern'
15
15
  require 'active_support/core_ext/class/attribute.rb'
16
16
 
17
17
  require 'active_attr'
18
+ require 'neo4j/config'
18
19
  require 'neo4j/wrapper'
19
20
  require 'neo4j/type_converters'
20
21
  require "neo4j/active_node/labels"
21
22
  require 'neo4j/active_node/identity'
23
+ require 'neo4j/active_node/id_property'
22
24
  require 'neo4j/active_node/callbacks'
23
25
  require 'neo4j/active_node/initialize'
24
26
  require 'neo4j/active_node/property'
@@ -26,11 +28,12 @@ require 'neo4j/active_node/persistence'
26
28
  require 'neo4j/active_node/validations'
27
29
  require 'neo4j/active_node/rels'
28
30
  require 'neo4j/active_node/has_n'
29
- require 'neo4j/active_node/has_n/decl_rel'
31
+ require 'neo4j/active_node/has_n/association'
30
32
  require 'neo4j/active_node/has_n/nodes'
31
33
  require 'neo4j/active_node/query/query_proxy'
32
34
  require 'neo4j/active_node/query'
33
- require 'neo4j/active_node/quick_query'
35
+ require 'neo4j/active_node/serialized_properties'
36
+ require 'neo4j/paginated'
34
37
  require 'neo4j/active_node'
35
38
 
36
39
  require 'neo4j/active_node/orm_adapter'
data/lib/neo4j.rb~ ADDED
@@ -0,0 +1,40 @@
1
+ require 'neo4j/version'
2
+
3
+ #require "delegate"
4
+ #require "time"
5
+ #require "set"
6
+ #
7
+ #require "active_support/core_ext"
8
+ #require "active_support/json"
9
+ #require "active_support/inflector"
10
+ #require "active_support/time_with_zone"
11
+
12
+ require "neo4j-core"
13
+ require "active_model"
14
+ require 'active_support/concern'
15
+ require 'active_support/core_ext/class/attribute.rb'
16
+
17
+ require 'active_attr'
18
+ require 'neo4j/wrapper'
19
+ require 'neo4j/type_converters'
20
+ require "neo4j/active_node/labels"
21
+ require 'neo4j/active_node/identity'
22
+ require 'neo4j/active_node/callbacks'
23
+ require 'neo4j/active_node/initialize'
24
+ require 'neo4j/active_node/property'
25
+ require 'neo4j/active_node/persistence'
26
+ require 'neo4j/active_node/validations'
27
+ require 'neo4j/active_node/rels'
28
+ require 'neo4j/active_node/has_n'
29
+ require 'neo4j/active_node/has_n/decl_rel'
30
+ require 'neo4j/active_node/has_n/nodes'
31
+ require 'neo4j/active_node'
32
+
33
+ require 'neo4j/active_node/orm_adapter'
34
+
35
+ if defined? Rails::Generators # defined in 'rails/generators.rb'
36
+ # TODO, not sure this is the correct way of adding rails generators
37
+ # See https://github.com/andreasronge/neo4j/blob/gh-pages/neo4j.rb
38
+ # It is required from the rails config/application file
39
+ require 'rails/generators/neo4j_generator'
40
+ end
@@ -31,14 +31,16 @@ module Neo4j
31
31
 
32
32
  include Neo4j::ActiveNode::Initialize
33
33
  include Neo4j::ActiveNode::Identity
34
+ include Neo4j::ActiveNode::IdProperty
34
35
  include Neo4j::ActiveNode::Persistence
36
+ include Neo4j::ActiveNode::SerializedProperties
35
37
  include Neo4j::ActiveNode::Property
38
+ include Neo4j::ActiveNode::Query
36
39
  include Neo4j::ActiveNode::Labels
37
40
  include Neo4j::ActiveNode::Validations
38
41
  include Neo4j::ActiveNode::Callbacks
39
42
  include Neo4j::ActiveNode::Rels
40
43
  include Neo4j::ActiveNode::HasN
41
- include Neo4j::ActiveNode::Query
42
44
 
43
45
  def wrapper
44
46
  self
@@ -71,12 +73,28 @@ module Neo4j
71
73
  end
72
74
 
73
75
  def self.inherited(other)
76
+ inherited_indexes(other) if self.respond_to?(:indexed_properties)
74
77
  attributes.each_pair do |k,v|
75
78
  other.attributes[k] = v
76
79
  end
77
80
  Neo4j::ActiveNode::Labels.add_wrapped_class(other)
78
81
  super
79
82
  end
83
+
84
+ def self.inherited_indexes(other)
85
+ return if indexed_properties.nil?
86
+ self.indexed_properties.each {|property| other.index property }
87
+ end
88
+
89
+ Neo4j::Session.on_session_available do |_|
90
+ name = Neo4j::Config[:id_property]
91
+ type = Neo4j::Config[:id_property_type]
92
+ value = Neo4j::Config[:id_property_type_value]
93
+ if (name && type && value)
94
+ id_property(name, type => value)
95
+ end
96
+ end
97
+
80
98
  end
81
99
  end
82
100
  end
@@ -2,155 +2,95 @@ module Neo4j::ActiveNode
2
2
  module HasN
3
3
  extend ActiveSupport::Concern
4
4
 
5
- def _decl_rels_for(rel_type)
6
- self.class._decl_rels[rel_type]
7
- end
8
-
9
5
  module ClassMethods
10
6
 
11
-
12
- def has_relationship?(rel_type)
13
- !!_decl_rels[rel_type]
14
- end
15
-
16
- def has_one_relationship?(rel_type)
17
- has_relationship?(rel_type) && _decl_rels[rel_type].has_one?
18
- end
19
-
20
- def relationship_dir(rel_type)
21
- has_relationship?(rel_type) && _decl_rels[rel_type].dir
7
+ def has_association?(name)
8
+ !!associations[name]
22
9
  end
23
10
 
24
- def _decl_rels
25
- @_decl_rels ||= {}
11
+ def associations
12
+ @associations || {}
26
13
  end
27
14
 
28
15
  # make sure the inherited classes inherit the <tt>_decl_rels</tt> hash
29
16
  def inherited(klass)
30
- copy = _decl_rels.clone
31
- copy.each_pair { |k, v| copy[k] = v.inherit_new }
32
- klass.instance_variable_set(:@_decl_rels, copy)
17
+ klass.instance_variable_set(:@associations, associations.clone)
18
+
33
19
  super
34
20
  end
35
21
 
22
+ def has_many(direction, name, options = {})
23
+ name = name.to_sym
36
24
 
37
- # Specifies a relationship between two node active node classes.
38
- # Generates assignment and accessor methods for the given relationship.
39
- # Both incoming and outgoing relationships can be declared, see {Neo4j::ActiveNode::HasN::DeclRel}
40
- #
41
- # @example has_n(:files)
42
- #
43
- # class FolderNode
44
- # include Neo4j::ActiveNode
45
- # has_n(:files)
46
- # end
47
- #
48
- # folder = FolderNode.new
49
- # folder.files << Neo4j::Node.new << Neo4j::Node.new
50
- # folder.files.inject {...}
51
- #
52
- # FolderNode.files #=> 'files' the name of the relationship
53
- #
54
- # @example has_n(x).to(...)
55
- #
56
- # # You can declare which class it has relationship to.
57
- # # The generated relationships will be prefixed with the name of that class.
58
- # class FolderNode
59
- # include Neo4j::ActiveNode
60
- # has_n(:files).to(File)
61
- # # Same as has_n(:files).to("File")
62
- # end
63
- #
64
- # FolderNode.files #=> 'File#files' the name of the relationship
65
- #
66
- # @example has_one(x).from(class, has_one_name)
67
- #
68
- # # generate accessor method for traversing and adding relationship on incoming nodes.
69
- # class FileNode
70
- # include Neo4j::ActiveNode
71
- # has_one(:folder).from(FolderNode.files)
72
- # # or same as
73
- # has_one(:folder).from(FolderNode, :files)
74
- # end
75
- #
76
- #
77
- # @return [Neo4j::ActiveNode::HasN::DeclRel] a DSL object where the has_n relationship can be further specified
78
- def has_n(rel_type, *callbacks)
79
- clazz = self
80
- module_eval(%Q{def #{rel_type}=(values)
81
- #{rel_type}_rels.each {|rel| rel.del }
82
-
83
- dsl = _decl_rels_for('#{rel_type}'.to_sym)
84
- values.each do |value|
85
- dsl.create_relationship_to(self, value)
86
- end
87
- end}, __FILE__, __LINE__)
25
+ association = Neo4j::ActiveNode::HasN::Association.new(:has_many, direction, name, options)
26
+ name = name.to_sym
88
27
 
89
- module_eval(%Q{
90
- def #{rel_type}()
91
- dsl = _decl_rels_for('#{rel_type}'.to_sym)
92
- Neo4j::ActiveNode::HasN::Nodes.new(self, dsl)
93
- end}, __FILE__, __LINE__)
28
+ @associations ||= {}
29
+ @associations[name] = association
94
30
 
31
+ target_class_name = association.target_class_name || 'nil'
32
+
33
+ # TODO: Make assignment more efficient? (don't delete nodes when they are being assigned)
95
34
  module_eval(%Q{
96
- def #{rel_type}_rels
97
- dsl = _decl_rels_for('#{rel_type}'.to_sym)
98
- dsl.all_relationships(self)
99
- end}, __FILE__, __LINE__)
35
+ def #{name}(node = nil, rel = nil)
36
+ Neo4j::ActiveNode::Query::QueryProxy.new(#{target_class_name}, self.class.associations[#{name.inspect}], session: self.class.neo4j_session, start_object: self, node: node, rel: rel)
37
+ end
38
+
39
+ def #{name}=(other_nodes)
40
+ #{name}(nil, :r).query_as(:n).delete(:r).exec
100
41
 
42
+ other_nodes.each do |node|
43
+ #{name} << node
44
+ end
45
+ end
46
+
47
+ def #{name}_rels
48
+ #{name}(nil, :r).pluck(:r)
49
+ end}, __FILE__, __LINE__)
101
50
 
102
51
  instance_eval(%Q{
103
- def #{rel_type}
104
- _decl_rels[:#{rel_type}].rel_type
52
+ def #{name}(node = nil, rel = nil)
53
+ Neo4j::ActiveNode::Query::QueryProxy.new(#{target_class_name}, @associations[#{name.inspect}], session: self.neo4j_session, query_proxy: self.query_proxy, node: node, rel: rel)
105
54
  end}, __FILE__, __LINE__)
106
- _decl_rels[rel_type.to_sym] = DeclRel.new(rel_type, false, clazz, *callbacks)
107
55
  end
108
56
 
57
+ def has_one(direction, name, options = {})
58
+ name = name.to_sym
109
59
 
110
- # Specifies a relationship between two node classes.
111
- # Generates assignment and accessor methods for the given relationship
112
- # Old relationship is deleted when a new relationship is assigned.
113
- # Both incoming and outgoing relationships can be declared, see {Neo4j::Wrapper::HasN::DeclRel}
114
- #
115
- # @example
116
- #
117
- # class FileNode
118
- # include Neo4j::ActiveNode
119
- # has_one(:folder)
120
- # end
121
- #
122
- # file = FileNode.create
123
- # file.folder = Neo4j::Node.create
124
- # file.folder # => the node above
125
- # file.folder_rel # => the relationship object between those nodes
126
- #
127
- # @return [Neo4j::ActiveNode::HasN::DeclRel] a DSL object where the has_one relationship can be futher specified
128
- def has_one(rel_type, *callbacks)
129
- clazz = self
130
- module_eval(%Q{def #{rel_type}=(value)
131
- return if !value
132
- dsl = _decl_rels_for(:#{rel_type})
133
- rel = dsl.single_relationship(self)
134
- rel && rel.del
135
- dsl.create_relationship_to(self, value)
136
- end}, __FILE__, __LINE__)
137
-
138
- module_eval(%Q{def #{rel_type}
139
- dsl = _decl_rels_for('#{rel_type}'.to_sym)
140
- dsl.single_node(self)
141
- end}, __FILE__, __LINE__)
142
-
143
- module_eval(%Q{def #{rel_type}_rel
144
- dsl = _decl_rels_for(:#{rel_type})
145
- dsl.single_relationship(self)
146
- end}, __FILE__, __LINE__)
60
+ association = Neo4j::ActiveNode::HasN::Association.new(:has_one, direction, name, options)
61
+ name = name.to_sym
147
62
 
148
- instance_eval(%Q{
149
- def #{rel_type}
150
- _decl_rels[:#{rel_type}].rel_type
63
+ @associations ||= {}
64
+ @associations[name] = association
65
+
66
+ target_class_name = association.target_class_name || 'nil'
67
+
68
+ module_eval(%Q{
69
+ def #{name}=(other_node)
70
+ #{name}_query_proxy(rel: :r).query_as(:n).delete(:r).exec
71
+ #{name}_query_proxy << other_node
72
+ end
73
+
74
+ def #{name}_query_proxy(options = {})
75
+ self.class.#{name}_query_proxy({start_object: self}.merge(options))
76
+ end
77
+
78
+ def #{name}_rel
79
+ #{name}_query_proxy(rel: :r).pluck(:r).first
80
+ end
81
+
82
+ def #{name}(node = nil, rel = nil)
83
+ #{name}_query_proxy(node: node, rel: rel).first
151
84
  end}, __FILE__, __LINE__)
152
85
 
153
- _decl_rels[rel_type.to_sym] = DeclRel.new(rel_type, true, clazz, *callbacks)
86
+ instance_eval(%Q{
87
+ def #{name}_query_proxy(options = {})
88
+ Neo4j::ActiveNode::Query::QueryProxy.new(#{target_class_name}, @associations[#{name.inspect}], {session: self.neo4j_session}.merge(options))
89
+ end
90
+
91
+ def #{name}(node = nil, rel = nil)
92
+ #{name}_query_proxy(query_proxy: self.query_proxy, node: node, rel: rel)
93
+ end}, __FILE__, __LINE__)
154
94
  end
155
95
 
156
96