orientdb-ar 0.0.4-jruby → 0.0.5-jruby

Sign up to get free protection for your applications and to get access to all the features.
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