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

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  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