neo4j_legacy 7.2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1357 -0
  3. data/CONTRIBUTORS +8 -0
  4. data/Gemfile +38 -0
  5. data/README.md +103 -0
  6. data/bin/neo4j-jars +33 -0
  7. data/bin/rake +17 -0
  8. data/config/locales/en.yml +5 -0
  9. data/config/neo4j/add_classnames.yml +1 -0
  10. data/config/neo4j/config.yml +35 -0
  11. data/lib/active_support/per_thread_registry.rb +1 -0
  12. data/lib/backports/action_controller/metal/strong_parameters.rb +672 -0
  13. data/lib/backports/active_model/forbidden_attributes_protection.rb +30 -0
  14. data/lib/backports/active_support/concern.rb +13 -0
  15. data/lib/backports/active_support/core_ext/module/attribute_accessors.rb +10 -0
  16. data/lib/backports/active_support/logger.rb +99 -0
  17. data/lib/backports/active_support/logger_silence.rb +27 -0
  18. data/lib/backports/active_support/logger_thread_safe_level.rb +32 -0
  19. data/lib/backports/active_support/per_thread_registry.rb +60 -0
  20. data/lib/backports.rb +4 -0
  21. data/lib/neo4j/active_node/callbacks.rb +8 -0
  22. data/lib/neo4j/active_node/dependent/association_methods.rb +48 -0
  23. data/lib/neo4j/active_node/dependent/query_proxy_methods.rb +50 -0
  24. data/lib/neo4j/active_node/dependent.rb +11 -0
  25. data/lib/neo4j/active_node/enum.rb +29 -0
  26. data/lib/neo4j/active_node/has_n/association/rel_factory.rb +61 -0
  27. data/lib/neo4j/active_node/has_n/association/rel_wrapper.rb +23 -0
  28. data/lib/neo4j/active_node/has_n/association.rb +280 -0
  29. data/lib/neo4j/active_node/has_n/association_cypher_methods.rb +108 -0
  30. data/lib/neo4j/active_node/has_n.rb +532 -0
  31. data/lib/neo4j/active_node/id_property/accessor.rb +62 -0
  32. data/lib/neo4j/active_node/id_property.rb +187 -0
  33. data/lib/neo4j/active_node/initialize.rb +21 -0
  34. data/lib/neo4j/active_node/labels/index.rb +87 -0
  35. data/lib/neo4j/active_node/labels/reloading.rb +21 -0
  36. data/lib/neo4j/active_node/labels.rb +198 -0
  37. data/lib/neo4j/active_node/node_wrapper.rb +52 -0
  38. data/lib/neo4j/active_node/orm_adapter.rb +82 -0
  39. data/lib/neo4j/active_node/persistence.rb +175 -0
  40. data/lib/neo4j/active_node/property.rb +60 -0
  41. data/lib/neo4j/active_node/query/query_proxy.rb +361 -0
  42. data/lib/neo4j/active_node/query/query_proxy_eager_loading.rb +61 -0
  43. data/lib/neo4j/active_node/query/query_proxy_enumerable.rb +90 -0
  44. data/lib/neo4j/active_node/query/query_proxy_find_in_batches.rb +19 -0
  45. data/lib/neo4j/active_node/query/query_proxy_link.rb +117 -0
  46. data/lib/neo4j/active_node/query/query_proxy_methods.rb +210 -0
  47. data/lib/neo4j/active_node/query/query_proxy_methods_of_mass_updating.rb +83 -0
  48. data/lib/neo4j/active_node/query.rb +76 -0
  49. data/lib/neo4j/active_node/query_methods.rb +65 -0
  50. data/lib/neo4j/active_node/reflection.rb +86 -0
  51. data/lib/neo4j/active_node/rels.rb +11 -0
  52. data/lib/neo4j/active_node/scope.rb +146 -0
  53. data/lib/neo4j/active_node/unpersisted.rb +48 -0
  54. data/lib/neo4j/active_node/validations.rb +59 -0
  55. data/lib/neo4j/active_node.rb +105 -0
  56. data/lib/neo4j/active_rel/callbacks.rb +15 -0
  57. data/lib/neo4j/active_rel/initialize.rb +28 -0
  58. data/lib/neo4j/active_rel/persistence/query_factory.rb +95 -0
  59. data/lib/neo4j/active_rel/persistence.rb +114 -0
  60. data/lib/neo4j/active_rel/property.rb +95 -0
  61. data/lib/neo4j/active_rel/query.rb +95 -0
  62. data/lib/neo4j/active_rel/rel_wrapper.rb +22 -0
  63. data/lib/neo4j/active_rel/related_node.rb +83 -0
  64. data/lib/neo4j/active_rel/types.rb +82 -0
  65. data/lib/neo4j/active_rel/validations.rb +8 -0
  66. data/lib/neo4j/active_rel.rb +67 -0
  67. data/lib/neo4j/class_arguments.rb +39 -0
  68. data/lib/neo4j/config.rb +124 -0
  69. data/lib/neo4j/core/query.rb +22 -0
  70. data/lib/neo4j/errors.rb +28 -0
  71. data/lib/neo4j/migration.rb +127 -0
  72. data/lib/neo4j/paginated.rb +27 -0
  73. data/lib/neo4j/railtie.rb +169 -0
  74. data/lib/neo4j/schema/operation.rb +91 -0
  75. data/lib/neo4j/shared/attributes.rb +220 -0
  76. data/lib/neo4j/shared/callbacks.rb +64 -0
  77. data/lib/neo4j/shared/cypher.rb +37 -0
  78. data/lib/neo4j/shared/declared_properties.rb +204 -0
  79. data/lib/neo4j/shared/declared_property/index.rb +37 -0
  80. data/lib/neo4j/shared/declared_property.rb +118 -0
  81. data/lib/neo4j/shared/enum.rb +148 -0
  82. data/lib/neo4j/shared/filtered_hash.rb +79 -0
  83. data/lib/neo4j/shared/identity.rb +28 -0
  84. data/lib/neo4j/shared/initialize.rb +28 -0
  85. data/lib/neo4j/shared/marshal.rb +23 -0
  86. data/lib/neo4j/shared/mass_assignment.rb +58 -0
  87. data/lib/neo4j/shared/permitted_attributes.rb +28 -0
  88. data/lib/neo4j/shared/persistence.rb +231 -0
  89. data/lib/neo4j/shared/property.rb +220 -0
  90. data/lib/neo4j/shared/query_factory.rb +101 -0
  91. data/lib/neo4j/shared/rel_type_converters.rb +43 -0
  92. data/lib/neo4j/shared/serialized_properties.rb +30 -0
  93. data/lib/neo4j/shared/type_converters.rb +418 -0
  94. data/lib/neo4j/shared/typecasted_attributes.rb +98 -0
  95. data/lib/neo4j/shared/typecaster.rb +53 -0
  96. data/lib/neo4j/shared/validations.rb +48 -0
  97. data/lib/neo4j/shared.rb +51 -0
  98. data/lib/neo4j/tasks/migration.rake +24 -0
  99. data/lib/neo4j/timestamps/created.rb +9 -0
  100. data/lib/neo4j/timestamps/updated.rb +9 -0
  101. data/lib/neo4j/timestamps.rb +11 -0
  102. data/lib/neo4j/type_converters.rb +7 -0
  103. data/lib/neo4j/version.rb +3 -0
  104. data/lib/neo4j/wrapper.rb +4 -0
  105. data/lib/neo4j.rb +96 -0
  106. data/lib/rails/generators/neo4j/model/model_generator.rb +86 -0
  107. data/lib/rails/generators/neo4j/model/templates/model.erb +15 -0
  108. data/lib/rails/generators/neo4j_generator.rb +67 -0
  109. data/neo4j.gemspec +43 -0
  110. metadata +389 -0
@@ -0,0 +1,418 @@
1
+ require 'date'
2
+ require 'bigdecimal'
3
+ require 'bigdecimal/util'
4
+ require 'active_support/core_ext/big_decimal/conversions'
5
+ require 'active_support/core_ext/string/conversions'
6
+
7
+ module Neo4j::Shared
8
+ class Boolean; end
9
+
10
+ module TypeConverters
11
+ CONVERTERS = {}
12
+
13
+ class Boolean; end
14
+
15
+ class BaseConverter
16
+ class << self
17
+ def converted?(value)
18
+ value.is_a?(db_type)
19
+ end
20
+ end
21
+
22
+ def supports_array?
23
+ false
24
+ end
25
+ end
26
+
27
+ class IntegerConverter < BaseConverter
28
+ class << self
29
+ def convert_type
30
+ Integer
31
+ end
32
+
33
+ def db_type
34
+ Integer
35
+ end
36
+
37
+ def to_db(value)
38
+ value.to_i
39
+ end
40
+
41
+ alias_method :to_ruby, :to_db
42
+ end
43
+ end
44
+
45
+ class FloatConverter < BaseConverter
46
+ class << self
47
+ def convert_type
48
+ Float
49
+ end
50
+
51
+ def db_type
52
+ Float
53
+ end
54
+
55
+ def to_db(value)
56
+ value.to_f
57
+ end
58
+ alias_method :to_ruby, :to_db
59
+ end
60
+ end
61
+
62
+ class BigDecimalConverter < BaseConverter
63
+ class << self
64
+ def convert_type
65
+ BigDecimal
66
+ end
67
+
68
+ def db_type
69
+ BigDecimal
70
+ end
71
+
72
+ def to_db(value)
73
+ case value
74
+ when Rational
75
+ value.to_f.to_d
76
+ when respond_to?(:to_d)
77
+ value.to_d
78
+ else
79
+ BigDecimal.new(value.to_s)
80
+ end
81
+ end
82
+ alias_method :to_ruby, :to_db
83
+ end
84
+ end
85
+
86
+ class StringConverter < BaseConverter
87
+ class << self
88
+ def convert_type
89
+ String
90
+ end
91
+
92
+ def db_type
93
+ String
94
+ end
95
+
96
+ def to_db(value)
97
+ value.to_s
98
+ end
99
+ alias_method :to_ruby, :to_db
100
+ end
101
+ end
102
+
103
+ class BooleanConverter < BaseConverter
104
+ FALSE_VALUES = %w(n N no No NO false False FALSE off Off OFF f F)
105
+
106
+ class << self
107
+ def converted?(value)
108
+ converted_values.include?(value)
109
+ end
110
+
111
+ def converted_values
112
+ [true, false]
113
+ end
114
+
115
+ def db_type
116
+ Neo4j::Shared::Boolean
117
+ end
118
+
119
+ alias_method :convert_type, :db_type
120
+
121
+ def to_db(value)
122
+ return false if FALSE_VALUES.include?(value)
123
+ case value
124
+ when TrueClass, FalseClass
125
+ value
126
+ when Numeric, /^\-?[0-9]/
127
+ !value.to_f.zero?
128
+ else
129
+ value.present?
130
+ end
131
+ end
132
+
133
+ alias_method :to_ruby, :to_db
134
+ end
135
+ end
136
+
137
+ # Converts Date objects to Java long types. Must be timezone UTC.
138
+ class DateConverter < BaseConverter
139
+ class << self
140
+ def convert_type
141
+ Date
142
+ end
143
+
144
+ def db_type
145
+ Integer
146
+ end
147
+
148
+ def to_db(value)
149
+ Time.utc(value.year, value.month, value.day).to_i
150
+ end
151
+
152
+ def to_ruby(value)
153
+ value.respond_to?(:to_date) ? value.to_date : Time.at(value).utc.to_date
154
+ end
155
+ end
156
+ end
157
+
158
+ # Converts DateTime objects to and from Java long types. Must be timezone UTC.
159
+ class DateTimeConverter < BaseConverter
160
+ class << self
161
+ def convert_type
162
+ DateTime
163
+ end
164
+
165
+ def db_type
166
+ Integer
167
+ end
168
+
169
+ # Converts the given DateTime (UTC) value to an Integer.
170
+ # DateTime values are automatically converted to UTC.
171
+ def to_db(value)
172
+ value = value.new_offset(0) if value.respond_to?(:new_offset)
173
+
174
+ args = [value.year, value.month, value.day]
175
+ args += (value.class == Date ? [0, 0, 0] : [value.hour, value.min, value.sec])
176
+
177
+ Time.utc(*args).to_i
178
+ end
179
+
180
+ def to_ruby(value)
181
+ return value if value.is_a?(DateTime)
182
+ t = case value
183
+ when Time
184
+ return value.to_datetime.utc
185
+ when Integer
186
+ Time.at(value).utc
187
+ when String
188
+ return value.to_datetime
189
+ else
190
+ fail ArgumentError, "Invalid value type for DateType property: #{value.inspect}"
191
+ end
192
+
193
+ DateTime.civil(t.year, t.month, t.day, t.hour, t.min, t.sec)
194
+ end
195
+ end
196
+ end
197
+
198
+ class TimeConverter < BaseConverter
199
+ class << self
200
+ def convert_type
201
+ Time
202
+ end
203
+
204
+ def db_type
205
+ Integer
206
+ end
207
+
208
+ # Converts the given DateTime (UTC) value to an Integer.
209
+ # Only utc times are supported !
210
+ def to_db(value)
211
+ if value.class == Date
212
+ Time.utc(value.year, value.month, value.day, 0, 0, 0).to_i
213
+ else
214
+ value.utc.to_i
215
+ end
216
+ end
217
+
218
+ def to_ruby(value)
219
+ Time.at(value).utc
220
+ end
221
+ end
222
+ end
223
+
224
+ # Converts hash to/from YAML
225
+ class YAMLConverter < BaseConverter
226
+ class << self
227
+ def convert_type
228
+ Hash
229
+ end
230
+
231
+ def db_type
232
+ String
233
+ end
234
+
235
+ def to_db(value)
236
+ Psych.dump(value)
237
+ end
238
+
239
+ def to_ruby(value)
240
+ Psych.load(value)
241
+ end
242
+ end
243
+ end
244
+
245
+ # Converts hash to/from JSON
246
+ class JSONConverter < BaseConverter
247
+ class << self
248
+ def convert_type
249
+ JSON
250
+ end
251
+
252
+ def db_type
253
+ String
254
+ end
255
+
256
+ def to_db(value)
257
+ value.to_json
258
+ end
259
+
260
+ def to_ruby(value)
261
+ JSON.parse(value, quirks_mode: true)
262
+ end
263
+ end
264
+ end
265
+
266
+ class EnumConverter
267
+ def initialize(enum_keys, options)
268
+ @enum_keys = enum_keys
269
+ @options = options
270
+ end
271
+
272
+ def converted?(value)
273
+ value.is_a?(db_type)
274
+ end
275
+
276
+ def supports_array?
277
+ true
278
+ end
279
+
280
+ def db_type
281
+ Integer
282
+ end
283
+
284
+ def convert_type
285
+ Symbol
286
+ end
287
+
288
+ def to_ruby(value)
289
+ @enum_keys.key(value) unless value.nil?
290
+ end
291
+
292
+ alias_method :call, :to_ruby
293
+
294
+ def to_db(value)
295
+ if value.is_a?(Array)
296
+ value.map(&method(:to_db))
297
+ else
298
+ @enum_keys[value.to_s.to_sym] || 0
299
+ end
300
+ end
301
+ end
302
+
303
+ class ObjectConverter < BaseConverter
304
+ class << self
305
+ def convert_type
306
+ Object
307
+ end
308
+
309
+ def to_ruby(value)
310
+ value
311
+ end
312
+ end
313
+ end
314
+
315
+
316
+ # Modifies a hash's values to be of types acceptable to Neo4j or matching what the user defined using `type` in property definitions.
317
+ # @param [Neo4j::Shared::Property] obj A node or rel that mixes in the Property module
318
+ # @param [Symbol] medium Indicates the type of conversion to perform.
319
+ # @param [Hash] properties A hash of symbol-keyed properties for conversion.
320
+ def convert_properties_to(obj, medium, properties)
321
+ direction = medium == :ruby ? :to_ruby : :to_db
322
+ properties.each_pair do |key, value|
323
+ next if skip_conversion?(obj, key, value)
324
+ properties[key] = convert_property(key, value, direction)
325
+ end
326
+ end
327
+
328
+ # Converts a single property from its current format to its db- or Ruby-expected output type.
329
+ # @param [Symbol] key A property declared on the model
330
+ # @param value The value intended for conversion
331
+ # @param [Symbol] direction Either :to_ruby or :to_db, indicates the type of conversion to perform
332
+ def convert_property(key, value, direction)
333
+ converted_property(primitive_type(key.to_sym), value, direction)
334
+ end
335
+
336
+ def supports_array?(key)
337
+ type = primitive_type(key.to_sym)
338
+ type.respond_to?(:supports_array?) && type.supports_array?
339
+ end
340
+
341
+ def typecaster_for(value)
342
+ Neo4j::Shared::TypeConverters.typecaster_for(value)
343
+ end
344
+
345
+ def typecast_attribute(typecaster, value)
346
+ Neo4j::Shared::TypeConverters.typecast_attribute(typecaster, value)
347
+ end
348
+
349
+ private
350
+
351
+ def converted_property(type, value, direction)
352
+ return nil if value.nil?
353
+ type.respond_to?(:db_type) || TypeConverters::CONVERTERS[type] ? TypeConverters.to_other(direction, value, type) : value
354
+ end
355
+
356
+ # If the attribute is to be typecast using a custom converter, which converter should it use? If no, returns the type to find a native serializer.
357
+ def primitive_type(attr)
358
+ case
359
+ when self.serialized_properties_keys.include?(attr)
360
+ serialized_properties[attr]
361
+ when self.magic_typecast_properties_keys.include?(attr)
362
+ self.magic_typecast_properties[attr]
363
+ else
364
+ self.fetch_upstream_primitive(attr)
365
+ end
366
+ end
367
+
368
+ # Returns true if the property isn't defined in the model or if it is nil
369
+ def skip_conversion?(obj, attr, value)
370
+ !obj.class.attributes[attr] || value.nil?
371
+ end
372
+
373
+ class << self
374
+ def included(_)
375
+ Neo4j::Shared::TypeConverters.constants.each do |constant_name|
376
+ constant = Neo4j::Shared::TypeConverters.const_get(constant_name)
377
+ register_converter(constant) if constant.respond_to?(:convert_type)
378
+ end
379
+ end
380
+
381
+ def typecast_attribute(typecaster, value)
382
+ fail ArgumentError, "A typecaster must be given, #{typecaster} is invalid" unless typecaster.respond_to?(:to_ruby)
383
+ return value if value.nil?
384
+ typecaster.to_ruby(value)
385
+ end
386
+
387
+ def typecaster_for(primitive_type)
388
+ return nil if primitive_type.nil?
389
+ CONVERTERS[primitive_type]
390
+ end
391
+
392
+ # @param [Symbol] direction either :to_ruby or :to_other
393
+ def to_other(direction, value, type)
394
+ fail "Unknown direction given: #{direction}" unless direction == :to_ruby || direction == :to_db
395
+ found_converter = converter_for(type)
396
+ return value unless found_converter
397
+ return value if direction == :to_db && formatted_for_db?(found_converter, value)
398
+ found_converter.send(direction, value)
399
+ end
400
+
401
+ def converter_for(type)
402
+ type.respond_to?(:db_type) ? type : CONVERTERS[type]
403
+ end
404
+
405
+ # Attempts to determine whether conversion should be skipped because the object is already of the anticipated output type.
406
+ # @param [#convert_type] found_converter An object that responds to #convert_type, hinting that it is a type converter.
407
+ # @param value The value for conversion.
408
+ def formatted_for_db?(found_converter, value)
409
+ return false unless found_converter.respond_to?(:db_type)
410
+ found_converter.respond_to?(:converted) ? found_converter.converted?(value) : value.is_a?(found_converter.db_type)
411
+ end
412
+
413
+ def register_converter(converter)
414
+ CONVERTERS[converter.convert_type] = converter
415
+ end
416
+ end
417
+ end
418
+ end
@@ -0,0 +1,98 @@
1
+ module Neo4j::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 Neo4j::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 Neo4j::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 ||= {}
43
+ @attributes[name.to_s]
44
+ end
45
+
46
+ private
47
+
48
+ # Reads the attribute and typecasts the result
49
+ def attribute(name)
50
+ 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
+ caster = self.class.attributes[attribute_name].typecaster || Neo4j::Shared::TypeConverters.typecaster_for(type)
70
+ caster || fail(Neo4j::UnknownTypeConverterError, "Unable to cast to type #{type}")
71
+ end
72
+
73
+ module ClassMethods
74
+ # Returns the class name plus its attribute names and types
75
+ #
76
+ # @example Inspect the model's definition.
77
+ # Person.inspect
78
+ #
79
+ # @return [String] Human-readable presentation of the attributes
80
+ def inspect
81
+ inspected_attributes = attribute_names.sort.map { |name| "#{name}: #{_attribute_type(name)}" }
82
+ attributes_list = "(#{inspected_attributes.join(', ')})" unless inspected_attributes.empty?
83
+ "#{name}#{attributes_list}"
84
+ end
85
+
86
+ # Calculates an attribute type
87
+ #
88
+ # @private
89
+ def _attribute_type(attribute_name)
90
+ attributes[attribute_name].type || Object
91
+ end
92
+
93
+ def typecast_attribute(typecaster, value)
94
+ Neo4j::Shared::TypeConverters.typecast_attribute(typecaster, value)
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,53 @@
1
+ module Neo4j
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 Neo4j::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
+ Neo4j::Shared::TypeConverters.register_converter(other)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,48 @@
1
+ module Neo4j
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
+ result = perform_validations(options) ? super : false
19
+ if !result
20
+ Neo4j::Transaction.current.failure if Neo4j::Transaction.current
21
+ end
22
+ result
23
+ end
24
+
25
+ # @return [Boolean] true if valid
26
+ def valid?(context = nil)
27
+ context ||= (new_record? ? :create : :update)
28
+ super(context)
29
+ errors.empty?
30
+ end
31
+
32
+ private
33
+
34
+ def perform_validations(options = {})
35
+ perform_validation = case options
36
+ when Hash
37
+ options[:validate] != false
38
+ end
39
+
40
+ if perform_validation
41
+ valid?(options.is_a?(Hash) ? options[:context] : nil)
42
+ else
43
+ true
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,51 @@
1
+ module Neo4j
2
+ module Shared
3
+ extend ActiveSupport::Concern
4
+ extend ActiveModel::Naming
5
+
6
+ include ActiveModel::Conversion
7
+ begin
8
+ include ActiveModel::Serializers::Xml
9
+ rescue NameError; end # rubocop:disable Lint/HandleExceptions
10
+ include ActiveModel::Serializers::JSON
11
+
12
+ module ClassMethods
13
+ attr_writer :neo4j_session_name
14
+
15
+ def neo4j_session_name(name)
16
+ ActiveSupport::Deprecation.warn 'neo4j_session_name is deprecated and may be removed from future releases, use neo4j_session_name= instead.', caller
17
+
18
+ @neo4j_session_name = name
19
+ end
20
+
21
+ def neo4j_session
22
+ if @neo4j_session_name
23
+ Neo4j::Session.named(@neo4j_session_name) ||
24
+ fail("#{self.name} is configured to use a neo4j session named #{@neo4j_session_name}, but no such session is registered with Neo4j::Session")
25
+ else
26
+ Neo4j::Session.current!
27
+ end
28
+ end
29
+ end
30
+
31
+ included do
32
+ self.include_root_in_json = Neo4j::Config.include_root_in_json
33
+ @_declared_properties ||= Neo4j::Shared::DeclaredProperties.new(self)
34
+
35
+ def self.i18n_scope
36
+ :neo4j
37
+ end
38
+
39
+ def self.inherited(other)
40
+ attributes.each_pair do |k, v|
41
+ other.inherit_property k.to_sym, v.clone, declared_properties[k].options
42
+ end
43
+ super
44
+ end
45
+ end
46
+
47
+ def declared_properties
48
+ self.class.declared_properties
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,24 @@
1
+ require 'neo4j/migration'
2
+
3
+ namespace :neo4j do
4
+ desc 'Run a script against the database to perform system-wide changes'
5
+ task :migrate, [:task_name, :subtask] => :environment do |_, args|
6
+ path = Rake.original_dir
7
+ migration_task = args[:task_name]
8
+ task_name_constant = migration_task.split('_').map(&:capitalize).join('')
9
+ begin
10
+ migration_class = "Neo4j::Migration::#{task_name_constant}".constantize
11
+ rescue NameError
12
+ load File.join(path, 'db', 'neo4j-migrate', "#{migration_task}.rb")
13
+ migration_class = "#{task_name_constant}".constantize
14
+ end
15
+ migration = migration_class.new(path)
16
+
17
+ subtask = args[:subtask]
18
+ if subtask
19
+ migration.send(subtask)
20
+ else
21
+ migration.migrate
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,9 @@
1
+ module Neo4j
2
+ module Timestamps
3
+ # This mixin includes a created_at timestamp property
4
+ module Created
5
+ extend ActiveSupport::Concern
6
+ included { property :created_at }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ module Neo4j
2
+ module Timestamps
3
+ # This mixin includes a updated_at timestamp property
4
+ module Updated
5
+ extend ActiveSupport::Concern
6
+ included { property :updated_at }
7
+ end
8
+ end
9
+ end