orientdb-ar 0.0.4-jruby → 0.0.5-jruby

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.
data/Rakefile CHANGED
@@ -17,8 +17,9 @@ begin
17
17
  gem.required_rubygems_version = ">= 1.3.6"
18
18
  gem.rubyforge_project = "orientdb-ar"
19
19
 
20
- gem.add_dependency "orientdb", "0.0.15"
20
+ gem.add_dependency "orientdb", ">= 0.0.20"
21
21
  gem.add_dependency "activemodel", ">= 3.0.3"
22
+ gem.add_dependency "jnunemaker-validatable", "1.8.4"
22
23
  gem.add_development_dependency "awesome_print"
23
24
  gem.add_development_dependency "rspec", ">= 2.4"
24
25
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.4
1
+ 0.0.5
@@ -11,6 +11,7 @@ if ARGV.include?('test:db')
11
11
  puts ">> GEM_ROOT : #{GEM_ROOT}"
12
12
  puts ">> TEST_DB PATH : #{TEST_DB_PATH}"
13
13
 
14
+ require 'rspec'
14
15
  require 'fileutils'
15
16
  puts ">> Removing tmp directory #{TEMP_DIR} ..."
16
17
  FileUtils.remove_dir TEMP_DIR + '/databases', true
@@ -20,12 +21,29 @@ if ARGV.include?('test:db')
20
21
  DB = OrientDB::AR::Base.connection
21
22
  puts ">> Connection : #{OrientDB::AR::Base.connection}"
22
23
 
23
- require SPEC_ROOT + '/models/person'
24
- require SPEC_ROOT + '/models/simple_person'
25
- require SPEC_ROOT + '/models/address'
26
- require SPEC_ROOT + '/models/phone_number'
27
- require SPEC_ROOT + '/models/customer'
28
- require SPEC_ROOT + '/models/flo_admin'
24
+ def remove_constant(const) #:nodoc:
25
+ names = const.to_s.sub(/^::(Object)?/, 'Object::').split("::")
26
+ to_remove = names.pop
27
+ parent = names.join('::').constantize
28
+ parent.instance_eval { remove_const to_remove }
29
+ true
30
+ end
31
+
32
+ def load_models
33
+ %w{ person simple_person address phone_number customer flo_admin product invoice_line invoice }.each do |name|
34
+ klass_name = name.camelize
35
+ klass_name = "Flo::Admin" if klass_name == "FloAdmin"
36
+ klass = klass_name.constantize rescue nil
37
+ if klass
38
+ puts ">> Removing class #{klass} ..."
39
+ remove_constant klass
40
+ end
41
+ puts ">> Loading #{klass_name} ..."
42
+ load SPEC_ROOT + '/models/' + name + '.rb'
43
+ end
44
+ end
45
+
46
+ load_models
29
47
  end
30
48
 
31
49
  require 'irb'
@@ -18,12 +18,11 @@ module OrientDB::AR
18
18
  end
19
19
 
20
20
  def [](attr)
21
- res = @odocument[attr]
22
- res.respond_to?(:to_orientdb_ar) ? res.to_orientdb_ar : res
21
+ self.class.from_orientdb @odocument[attr]
23
22
  end
24
23
 
25
24
  def []=(attr, value)
26
- value = value.respond_to?(:to_orientdb) ? value.to_orientdb : value
25
+ value = self.class.to_orientdb value
27
26
  old_value = self[attr]
28
27
  return old_value if value == old_value
29
28
  attribute_will_change!(attr)
@@ -1,29 +1,37 @@
1
1
  class OrientDB::AR::Base
2
2
 
3
- def self.embeddable?
4
- false
5
- end
6
-
7
3
  include ActiveModel::AttributeMethods
8
4
  include OrientDB::AR::DocumentMixin
9
5
 
10
- class_inheritable_hash :fields
11
- self.fields = ActiveSupport::OrderedHash.new
12
-
13
6
  class_attribute :connection
14
7
 
15
- define_model_callbacks :save, :delete
8
+ define_model_callbacks :validation, :save, :delete
16
9
 
17
- def save
10
+ def save(perform_validations = true)
18
11
  _run_save_callbacks do
19
- @odocument.save
20
- @saved = true
21
- @previously_changed = @changed_attributes
22
- @changed_attributes.clear
12
+ if perform_validations
13
+ validate
14
+ if @last_validation_result
15
+ save_without_validations
16
+ else
17
+ false
18
+ end
19
+ else
20
+ save_without_validations
21
+ end
23
22
  end
23
+ end
24
+
25
+ def save_without_validations
26
+ @odocument.save
27
+ @saved = true
28
+ @previously_changed = @changed_attributes
29
+ @changed_attributes.clear
24
30
  true
25
31
  end
26
32
 
33
+ private :save_without_validations
34
+
27
35
  def delete
28
36
  _run_delete_callbacks do
29
37
  @odocument.delete
@@ -34,7 +42,7 @@ class OrientDB::AR::Base
34
42
 
35
43
  def reload
36
44
  raise "Not persisted, cannot reload" unless persisted?
37
- @odocument = OrientDB::AR::Query.new(self.class).where('@rid' => rid.lit).first_result
45
+ @odocument = OrientDB::AR::Query.new(self.class).where('@rid' => rid.lit).first_result
38
46
  @changed_attributes = { }
39
47
  @errors = ActiveModel::Errors.new(self)
40
48
  self
@@ -58,13 +66,13 @@ class OrientDB::AR::Base
58
66
 
59
67
  attr_writer :oclass_name
60
68
 
61
- def oclass_name
62
- @oclass_name ||= name.to_s
69
+ def embeddable?
70
+ false
63
71
  end
64
72
 
65
73
  def oclass
66
74
  unless defined?(@oclass)
67
- options = {}
75
+ options = { }
68
76
  unless descends_from_base?
69
77
  super_oclass = superclass.oclass
70
78
  options[:super] = super_oclass
@@ -75,12 +83,12 @@ class OrientDB::AR::Base
75
83
  @oclass
76
84
  end
77
85
 
78
- def field(name, type, options = {})
86
+ def field(name, type, options = { })
79
87
  name = name.to_sym
80
88
  if fields.key? name
81
89
  puts "Already defined field [#{name}]"
82
90
  else
83
- fields[name] = {:type => type}.update options
91
+ fields[name] = { :type => type }.update options
84
92
  end
85
93
  end
86
94
 
@@ -88,14 +96,7 @@ class OrientDB::AR::Base
88
96
  superclass && superclass == OrientDB::AR::Base
89
97
  end
90
98
 
91
- def schema!
92
- fields.each do |field, options|
93
- oclass.add field, options[:type], options.except(:type)
94
- end
95
- self
96
- end
97
-
98
- def create(fields = {})
99
+ def create(fields = { })
99
100
  obj = new fields
100
101
  obj.save
101
102
  obj
@@ -123,11 +124,11 @@ class OrientDB::AR::Base
123
124
  OrientDB::AR::Query.new(self).range(lower_rid, upper_rid)
124
125
  end
125
126
 
126
- def all(conditions = {})
127
+ def all(conditions = { })
127
128
  OrientDB::AR::Query.new(self).where(conditions).all
128
129
  end
129
130
 
130
- def first(conditions = {})
131
+ def first(conditions = { })
131
132
  OrientDB::AR::Query.new(self).where(conditions).first
132
133
  end
133
134
 
@@ -150,8 +151,9 @@ class OrientDB::AR::Base
150
151
  def clear
151
152
  oclass.truncate
152
153
  end
153
- end
154
154
 
155
+
156
+ end
155
157
  end
156
158
 
157
159
  OrientDB::AR::Base.include_root_in_json = false
@@ -4,28 +4,43 @@ require 'active_support/core_ext/class/attribute_accessors'
4
4
  require 'active_support/core_ext/kernel'
5
5
  require 'active_support/core_ext/class/attribute'
6
6
  require 'active_support/core_ext/class/inheritable_attributes'
7
+ require 'active_support/core_ext/module/aliasing'
7
8
  require 'orientdb'
9
+ require 'validatable'
8
10
 
9
11
  require 'orientdb-ar/conversion'
10
12
  require 'orientdb-ar/attributes'
11
- require 'orientdb-ar/validations'
12
13
  require 'orientdb-ar/relations'
13
14
  require 'orientdb-ar/sql'
15
+
14
16
  module OrientDB::AR::DocumentMixin
15
17
 
16
- include Comparable
18
+ def self.included(base)
19
+ base.class_eval do
20
+ include Comparable
21
+
22
+ include Validatable
23
+ alias_method_chain :valid?, :default_group
17
24
 
18
- include OrientDB::AR::Attributes
19
- include OrientDB::AR::Conversion
20
- include OrientDB::AR::Validations
25
+ include OrientDB::AR::Attributes
26
+ include OrientDB::AR::Conversion
21
27
 
22
- def self.included(base)
23
- base.extend ActiveModel::Translation
24
- base.extend ActiveModel::Callbacks unless base.embeddable?
28
+ extend ActiveModel::Translation
29
+ include ActiveModel::Serializers::JSON
30
+ include ActiveModel::Serializers::Xml
31
+
32
+ extend ActiveModel::Callbacks
33
+
34
+ class_inheritable_hash :fields
35
+ self.fields = ActiveSupport::OrderedHash.new
36
+
37
+ class_inheritable_hash :relationships
38
+ self.relationships = ActiveSupport::OrderedHash.new
25
39
 
26
- base.send :include, ActiveModel::Serializers::JSON
27
- base.send :include, ActiveModel::Serializers::Xml
40
+ class_inheritable_accessor :default_validation_group
28
41
 
42
+ class_attribute :connection
43
+ end
29
44
  base.extend OrientDB::AR::DocumentMixin::ClassMethods
30
45
  end
31
46
 
@@ -38,10 +53,53 @@ module OrientDB::AR::DocumentMixin
38
53
  fields.each { |k, v| send "#{k}=", v }
39
54
  end
40
55
 
56
+ def human_id
57
+ rid
58
+ end
59
+
41
60
  def field?(name)
42
61
  @odocument.field?(name)
43
62
  end
44
63
 
64
+ def validate
65
+ @last_validation_result = nil
66
+ _run_validation_callbacks do
67
+ @last_validation_result = valid?
68
+ end
69
+ @last_validation_result
70
+ end
71
+
72
+ def valid_with_default_group?
73
+ valid_for_group?(default_validation_group) && related_valid?
74
+ end
75
+
76
+ def related_valid?
77
+ res = related.all? do |rel_name, row_or_coll|
78
+ case row_or_coll
79
+ when Array
80
+ row_or_coll.all? do |result|
81
+ result.validate_to_parent errors, rel_name
82
+ end
83
+ else
84
+ row_or_coll.validate_to_parent errors, rel_name
85
+ end
86
+ end
87
+ res
88
+ end
89
+
90
+ def validate_to_parent(parent_errors, rel_name)
91
+ return true if valid?
92
+ errors.full_messages.each { |msg| parent_errors[rel_name] = "#{human_id} #{msg}" }
93
+ false
94
+ end
95
+
96
+ def related
97
+ relationships.map do |rel_name, options|
98
+ rel_obj = send options[:name]
99
+ rel_obj.blank? ? nil : [rel_name, rel_obj]
100
+ end.compact
101
+ end
102
+
45
103
  def respond_to?(method_name)
46
104
  # Simple field value lookup
47
105
  return true if field?(method_name)
@@ -96,7 +154,8 @@ module OrientDB::AR::DocumentMixin
96
154
  def inspect
97
155
  attrs = attributes.map { |k, v| "#{k}:#{v.inspect}" }.join(' ')
98
156
  super_klass = self.class.descends_from_base? ? '' : "(#{self.class.superclass.name})"
99
- %{#<#{self.class.name}#{super_klass}:#{@odocument.rid} #{attrs}>}
157
+ rid_str = embedded? ? '(E)' : ":#{@odocument.rid}"
158
+ %{#<#{self.class.name}#{super_klass}#{rid_str} #{attrs}>}
100
159
  end
101
160
 
102
161
  alias :to_s :inspect
@@ -109,8 +168,12 @@ module OrientDB::AR::DocumentMixin
109
168
 
110
169
  attr_writer :oclass_name
111
170
 
171
+ def oclass_name_for(value)
172
+ value.to_s.gsub('::', '__')
173
+ end
174
+
112
175
  def oclass_name
113
- @oclass_name ||= name.to_s.gsub('::', '__')
176
+ @oclass_name ||= oclass_name_for name
114
177
  end
115
178
 
116
179
  def field(name, type, options = { })
@@ -122,6 +185,17 @@ module OrientDB::AR::DocumentMixin
122
185
  end
123
186
  end
124
187
 
188
+ def schema!
189
+ fields.each do |field, options|
190
+ begin
191
+ oclass.add field, options[:type], options.except(:type)
192
+ rescue Exception => e
193
+ raise e unless e.message =~ /already exists/
194
+ end
195
+ end
196
+ self
197
+ end
198
+
125
199
  def new_document
126
200
  OrientDB::Document.new connection, oclass_name
127
201
  end
@@ -1,14 +1,9 @@
1
1
  class OrientDB::AR::Embedded
2
2
 
3
- def self.embeddable?
4
- true
5
- end
6
-
7
3
  include ActiveModel::AttributeMethods
8
4
  include OrientDB::AR::DocumentMixin
9
5
 
10
- class_inheritable_hash :fields
11
- self.fields = ActiveSupport::OrderedHash.new
6
+ define_model_callbacks :validation
12
7
 
13
8
  def save
14
9
  raise "Not implemented on Embedded models"
@@ -36,6 +31,12 @@ class OrientDB::AR::Embedded
36
31
 
37
32
  class << self
38
33
 
34
+ include OrientDB::AR::Relations
35
+
36
+ def embeddable?
37
+ true
38
+ end
39
+
39
40
  def connection
40
41
  OrientDB::AR::Base.connection
41
42
  end
@@ -48,11 +49,7 @@ class OrientDB::AR::Embedded
48
49
  superclass && superclass == OrientDB::AR::Embedded
49
50
  end
50
51
 
51
- def schema!
52
- raise "Not implemented on Embedded models"
53
- end
54
-
55
- def create(fields = {})
52
+ def create(fields = { })
56
53
  raise "Not implemented on Embedded models"
57
54
  end
58
55
 
@@ -78,11 +75,11 @@ class OrientDB::AR::Embedded
78
75
  raise "Not implemented on Embedded models"
79
76
  end
80
77
 
81
- def all(conditions = {})
78
+ def all(conditions = { })
82
79
  raise "Not implemented on Embedded models"
83
80
  end
84
81
 
85
- def first(conditions = {})
82
+ def first(conditions = { })
86
83
  raise "Not implemented on Embedded models"
87
84
  end
88
85
 
@@ -106,5 +103,4 @@ class OrientDB::AR::Embedded
106
103
  raise "Not implemented on Embedded models"
107
104
  end
108
105
  end
109
-
110
106
  end
@@ -1,3 +1,5 @@
1
+ require 'date'
2
+
1
3
  class OrientDB::Document
2
4
  def to_orientdb_ar
3
5
  klass = getClassName.gsub('__', '::').constantize
@@ -31,6 +33,42 @@ class NilClass
31
33
  end
32
34
  end
33
35
 
36
+ class Float
37
+ def to_orientdb
38
+ to_java
39
+ end
40
+ end
41
+
42
+ class Java::JavaLang::Double
43
+ def to_orientdb_ar
44
+ to_s.to_f
45
+ end
46
+ end
47
+
48
+ class Java::JavaUtil::Date
49
+ def to_orientdb_ar
50
+ ::Time.at(getTime / 1000)
51
+ end
52
+ end
53
+
54
+ class Time
55
+ def to_orientdb
56
+ java.util.Date.new to_i * 1000
57
+ end
58
+ end
59
+
60
+ class Date
61
+ def to_orientdb
62
+ java.util.Date.new year - 1900, month - 1, day, 0, 0, 0
63
+ end
64
+ end
65
+
66
+ class DateTime
67
+ def to_orientdb
68
+ java.util.Date.new year - 1900, month - 1, day, hour, min, sec
69
+ end
70
+ end
71
+
34
72
  class Array
35
73
  def to_orientdb
36
74
  map { |x| x.respond_to?(:to_orientdb) ? x.to_orientdb : x }
@@ -55,4 +93,4 @@ class Java::JavaUtil::ArrayList
55
93
  def to_orientdb_ar
56
94
  map { |x| x.respond_to?(:to_orientdb_ar) ? x.to_orientdb_ar : x }
57
95
  end
58
- end
96
+ end