orientdb-ar 0.0.2-jruby → 0.0.3-jruby

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile CHANGED
@@ -17,7 +17,7 @@ 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.10"
20
+ gem.add_dependency "orientdb", "0.0.11"
21
21
  gem.add_dependency "activemodel", ">= 3.0.3"
22
22
  gem.add_development_dependency "awesome_print"
23
23
  gem.add_development_dependency "rspec", ">= 2.4"
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.2
1
+ 0.0.3
@@ -23,6 +23,7 @@ if ARGV.include?('test:db')
23
23
  require SPEC_ROOT + '/models/person'
24
24
  require SPEC_ROOT + '/models/simple_person'
25
25
  require SPEC_ROOT + '/models/address'
26
+ require SPEC_ROOT + '/models/phone_number'
26
27
  require SPEC_ROOT + '/models/customer'
27
28
  require SPEC_ROOT + '/models/flo_admin'
28
29
  end
data/lib/model/base.rb CHANGED
@@ -8,6 +8,8 @@ require 'orientdb'
8
8
  require 'model/conversion'
9
9
  require 'model/attributes'
10
10
  require 'model/validations'
11
+ require 'model/relations'
12
+ require 'model/query'
11
13
 
12
14
  class OrientDB::AR::Base
13
15
  include ActiveModel::AttributeMethods
@@ -33,9 +35,10 @@ class OrientDB::AR::Base
33
35
  attr_reader :odocument
34
36
 
35
37
  def initialize(fields = {})
36
- @odocument = self.class.new_document fields
38
+ @odocument = self.class.new_document
37
39
  @changed_attributes = {}
38
40
  @errors = ActiveModel::Errors.new(self)
41
+ fields.each { |k, v| send "#{k}=", v }
39
42
  end
40
43
 
41
44
  def field?(name)
@@ -118,6 +121,8 @@ class OrientDB::AR::Base
118
121
 
119
122
  class << self
120
123
 
124
+ include OrientDB::AR::Relations
125
+
121
126
  attr_writer :oclass_name
122
127
 
123
128
  def oclass_name
@@ -137,6 +142,10 @@ class OrientDB::AR::Base
137
142
  @oclass
138
143
  end
139
144
 
145
+ def embedded?
146
+ false
147
+ end
148
+
140
149
  def field(name, type, options = {})
141
150
  name = name.to_sym
142
151
  if fields.key? name
@@ -154,6 +163,7 @@ class OrientDB::AR::Base
154
163
  fields.each do |field, options|
155
164
  oclass.add field, options[:type], options.except(:type)
156
165
  end
166
+ self
157
167
  end
158
168
 
159
169
  def new_document(fields = {})
@@ -207,44 +217,12 @@ class OrientDB::AR::Base
207
217
  obj.instance_variable_set "@odocument", doc
208
218
  obj
209
219
  end
210
- end
211
-
212
- end
213
-
214
- class OrientDB::AR::Query
215
-
216
- attr_accessor :model, :query
217
220
 
218
- def initialize(model, query = OrientDB::SQL::Query.new)
219
- @model, @query = model, query
220
- @query.from model.name
221
- end
222
-
223
- %w{ select select! where where! and or and_not or_not order order! limit limit! range range! }.each do |name|
224
- define_method(name) do |*args|
225
- query.send name, *args
226
- self
221
+ def new_from_docs(docs)
222
+ docs.map { |doc| new_from_doc doc }
227
223
  end
228
224
  end
229
225
 
230
- def all
231
- model.connection.query(query).map { |doc| model.new_from_doc doc }
232
- end
233
-
234
- def first
235
- model.new_from_doc model.connection.first(query)
236
- end
237
-
238
- def results
239
- model.connection.query(query).map
240
- end
241
-
242
- def inspect
243
- %{#<OrientDB::AR::Query:#{model.name} query="#{query.to_s}">}
244
- end
245
-
246
- alias :to_s :inspect
247
-
248
226
  end
249
227
 
250
228
  OrientDB::AR::Base.include_root_in_json = false
@@ -1,13 +1,21 @@
1
- require 'model/attributes'
2
- require 'model/validations'
3
-
4
1
  class OrientDB::AR::Embedded
2
+ include ActiveModel::AttributeMethods
3
+ include Comparable
4
+
5
5
  extend ActiveModel::Translation
6
6
 
7
7
  include OrientDB::AR::Attributes
8
8
  include OrientDB::AR::Conversion
9
9
  include OrientDB::AR::Validations
10
10
 
11
+ include ActiveModel::Serializers::JSON
12
+ include ActiveModel::Serializers::Xml
13
+
14
+ class_inheritable_hash :fields
15
+ self.fields = ActiveSupport::OrderedHash.new
16
+
17
+ attr_reader :odocument
18
+
11
19
  def initialize(fields = {})
12
20
  @odocument = self.class.new_document fields
13
21
  @changed_attributes = {}
@@ -15,7 +23,8 @@ class OrientDB::AR::Embedded
15
23
  end
16
24
 
17
25
  def field?(name)
18
- @odocument.field?(name)
26
+ res = @odocument.field?(name)
27
+ res
19
28
  end
20
29
 
21
30
  def respond_to?(method_name)
@@ -49,20 +58,65 @@ class OrientDB::AR::Embedded
49
58
  end
50
59
  end
51
60
 
61
+ def save
62
+ raise "Not implemented on Embedded models"
63
+ end
64
+
65
+ def delete
66
+ raise "Not implemented on Embedded models"
67
+ end
68
+
69
+ def saved?
70
+ false
71
+ end
72
+
73
+ def deleted?
74
+ false
75
+ end
76
+
77
+ def persisted?
78
+ false
79
+ end
80
+
81
+ def inspect
82
+ attrs = attributes.map { |k, v| "#{k}:#{v.inspect}" }.join(' ')
83
+ super_klass = self.class.descends_from_embedded? ? '' : "(#{self.class.superclass.name})"
84
+ %{#<#{self.class.name}#{super_klass}:#{@odocument.rid} #{attrs}>}
85
+ end
86
+
87
+ alias :to_s :inspect
88
+
89
+ def <=>(other)
90
+ to_s <=> other.to_s
91
+ end
92
+
52
93
  class << self
53
94
 
95
+ def connection
96
+ OrientDB::AR::Base.connection
97
+ end
98
+
54
99
  attr_writer :oclass_name
55
100
 
56
101
  def oclass_name
57
- @oclass_name ||= name.downcase.gsub('::', '_')
102
+ @oclass_name ||= name.to_s
58
103
  end
59
104
 
60
105
  def oclass
61
- @oclass ||= connection.get_or_create_class oclass_name
106
+ unless defined?(@oclass)
107
+ options = {}
108
+ unless descends_from_embedded?
109
+ super_oclass = superclass.oclass
110
+ options[:super] = super_oclass
111
+ options[:use_cluster] = super_oclass.cluster_ids.first
112
+ end
113
+ @oclass = connection.get_or_create_class oclass_name, options
114
+ end
115
+ @oclass
62
116
  end
63
117
 
64
- def fields
65
- @fields ||= ActiveSupport::OrderedHash.new
118
+ def embedded?
119
+ true
66
120
  end
67
121
 
68
122
  def field(name, type, options = {})
@@ -74,10 +128,70 @@ class OrientDB::AR::Embedded
74
128
  end
75
129
  end
76
130
 
131
+ def descends_from_embedded?
132
+ superclass && superclass == OrientDB::AR::Embedded
133
+ end
134
+
135
+ def schema!
136
+ fields.each do |field, options|
137
+ oclass.add field, options[:type], options.except(:type)
138
+ end
139
+ self
140
+ end
141
+
77
142
  def new_document(fields = {})
78
143
  oclass
79
144
  OrientDB::Document.new connection, oclass_name, fields
80
145
  end
81
146
 
147
+ def create(fields = {})
148
+ raise "Not implemented on Embedded models"
149
+ end
150
+
151
+ def select(*args)
152
+ raise "Not implemented on Embedded models"
153
+ end
154
+
155
+ alias :columns :select
156
+
157
+ def where(*args)
158
+ raise "Not implemented on Embedded models"
159
+ end
160
+
161
+ def order(*args)
162
+ raise "Not implemented on Embedded models"
163
+ end
164
+
165
+ def limit(max_records)
166
+ raise "Not implemented on Embedded models"
167
+ end
168
+
169
+ def range(lower_rid, upper_rid = nil)
170
+ raise "Not implemented on Embedded models"
171
+ end
172
+
173
+ def all(conditions = {})
174
+ raise "Not implemented on Embedded models"
175
+ end
176
+
177
+ def first(conditions = {})
178
+ raise "Not implemented on Embedded models"
179
+ end
180
+
181
+ def clear
182
+ raise "Not implemented on Embedded models"
183
+ end
184
+
185
+ def new_from_doc(doc)
186
+ klass = doc.getClassName.constantize
187
+ obj = klass.new
188
+ obj.instance_variable_set "@odocument", doc
189
+ obj
190
+ end
191
+
192
+ def new_from_docs(docs)
193
+ docs.map { |doc| new_from_doc doc }
194
+ end
82
195
  end
196
+
83
197
  end
@@ -0,0 +1,36 @@
1
+ class OrientDB::AR::Query
2
+
3
+ attr_accessor :model, :query
4
+
5
+ def initialize(model, query = OrientDB::SQL::Query.new)
6
+ @model, @query = model, query
7
+ @query.from model.name
8
+ end
9
+
10
+ %w{ select select! where where! and or and_not or_not order order! limit limit! range range! }.each do |name|
11
+ define_method(name) do |*args|
12
+ query.send name, *args
13
+ self
14
+ end
15
+ end
16
+
17
+ def all
18
+ model.connection.query(query).map { |doc| model.new_from_doc doc }
19
+ end
20
+
21
+ def first
22
+ model.new_from_doc model.connection.first(query)
23
+ end
24
+
25
+ def results
26
+ model.connection.query(query).map
27
+ end
28
+
29
+ def inspect
30
+ %{#<OrientDB::AR::Query:#{model.name} query="#{query.to_s}">}
31
+ end
32
+
33
+ alias :to_s :inspect
34
+
35
+ end
36
+
@@ -0,0 +1,70 @@
1
+ module OrientDB::AR
2
+ module Relations
3
+
4
+ def has_one(klass, options = {})
5
+ klass = klass_for klass
6
+ name = options[:name].to_s || field_name_for(klass, true)
7
+
8
+ field_type = klass.embedded? ? :embedded : :link
9
+ field name, [OrientDB::FIELD_TYPES[field_type], klass.oclass]
10
+
11
+ class_eval <<-eorb, __FILE__, __LINE__ + 1
12
+ def #{name} # def address
13
+ doc = odocument[:#{name}] # doc = odocument[:address]
14
+ doc ? #{klass.name}.new_from_doc(doc) : nil # doc ? Address.new_from_doc(doc) : nil
15
+ end # end
16
+ eorb
17
+ #
18
+ class_eval <<-eorb, __FILE__, __LINE__ + 1
19
+ def #{name}=(value) # def address=(value)
20
+ raise "Invalid value for [#{name}]" unless value.is_a?(#{klass}) # raise "Invalid value for [address]" unless value.is_a?(Address)
21
+ odocument[:#{name}] = value.odocument # odocument[:address] = value.odocument
22
+ #{name} # address
23
+ end # end
24
+ eorb
25
+ end
26
+
27
+ def has_many(klass, options = {})
28
+ klass = klass_for klass
29
+ name = options[:name].to_s || field_name_for(klass, false)
30
+
31
+ field_type = klass.embedded? ? :embedded : :link
32
+ field name, [OrientDB::FIELD_TYPES[field_type], klass.oclass]
33
+
34
+ class_eval <<-eorb, __FILE__, __LINE__ + 1
35
+ def #{name} # def addresses
36
+ docs = odocument[:#{name}] # docs = odocument[:addresses]
37
+ docs ? #{klass.name}.new_from_docs(docs) : nil # docs ? Address.new_from_docs(doc) : nil
38
+ end # end
39
+ eorb
40
+
41
+ class_eval <<-eorb, __FILE__, __LINE__ + 1
42
+ def #{name}=(value) # def addresses=(value)
43
+ odocument[:#{name}] = value.map{|x| x.odocument } # odocument[:addresses] = value.map{|x| x.odocument }
44
+ #{name} # addresses
45
+ end # end
46
+ eorb
47
+
48
+ class_eval <<-eorb, __FILE__, __LINE__ + 1
49
+ def add_#{name.singularize}(value) # def add_address(value)
50
+ odocument[:#{name}] << value.odocument # odocument[:addresses] << value.odocument
51
+ #{name} # addresses
52
+ end # end
53
+ eorb
54
+ end
55
+
56
+ private
57
+
58
+ def klass_for(klass)
59
+ return klass if klass.class.name == 'Class'
60
+ klass.to_s.singularize.camelize.constantize
61
+ rescue
62
+ raise "Problem getting klass for [#{klass}]"
63
+ end
64
+
65
+ def field_name_for(klass, singular)
66
+ klass.to_s.underscore.send(singular ? :singularize : :pluralize).gsub('/', '__')
67
+ end
68
+
69
+ end
70
+ end
data/orientdb-ar.gemspec CHANGED
@@ -5,12 +5,12 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{orientdb-ar}
8
- s.version = "0.0.2"
8
+ s.version = "0.0.3"
9
9
  s.platform = %q{jruby}
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 1.3.6") if s.respond_to? :required_rubygems_version=
12
12
  s.authors = ["Adrian Madrid"]
13
- s.date = %q{2011-01-17}
13
+ s.date = %q{2011-01-18}
14
14
  s.default_executable = %q{orientdbar_console}
15
15
  s.description = %q{Active Model wrappers to persist Ruby objects under OrientDB in JRuby.}
16
16
  s.email = ["aemadrid@gmail.com"]
@@ -32,6 +32,8 @@ Gem::Specification.new do |s|
32
32
  "lib/model/base.rb",
33
33
  "lib/model/conversion.rb",
34
34
  "lib/model/embedded.rb",
35
+ "lib/model/query.rb",
36
+ "lib/model/relations.rb",
35
37
  "lib/model/validations.rb",
36
38
  "lib/orientdb-ar.rb",
37
39
  "orientdb-ar.gemspec",
@@ -44,6 +46,7 @@ Gem::Specification.new do |s|
44
46
  "spec/models/customer.rb",
45
47
  "spec/models/flo_admin.rb",
46
48
  "spec/models/person.rb",
49
+ "spec/models/phone_number.rb",
47
50
  "spec/models/simple_person.rb",
48
51
  "spec/serialization_spec.rb",
49
52
  "spec/spec.opts",
@@ -60,18 +63,18 @@ Gem::Specification.new do |s|
60
63
  s.specification_version = 3
61
64
 
62
65
  if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
63
- s.add_runtime_dependency(%q<orientdb>, ["= 0.0.10"])
66
+ s.add_runtime_dependency(%q<orientdb>, ["= 0.0.11"])
64
67
  s.add_runtime_dependency(%q<activemodel>, [">= 3.0.3"])
65
68
  s.add_development_dependency(%q<awesome_print>, [">= 0"])
66
69
  s.add_development_dependency(%q<rspec>, [">= 2.4"])
67
70
  else
68
- s.add_dependency(%q<orientdb>, ["= 0.0.10"])
71
+ s.add_dependency(%q<orientdb>, ["= 0.0.11"])
69
72
  s.add_dependency(%q<activemodel>, [">= 3.0.3"])
70
73
  s.add_dependency(%q<awesome_print>, [">= 0"])
71
74
  s.add_dependency(%q<rspec>, [">= 2.4"])
72
75
  end
73
76
  else
74
- s.add_dependency(%q<orientdb>, ["= 0.0.10"])
77
+ s.add_dependency(%q<orientdb>, ["= 0.0.11"])
75
78
  s.add_dependency(%q<activemodel>, [">= 3.0.3"])
76
79
  s.add_dependency(%q<awesome_print>, [">= 0"])
77
80
  s.add_dependency(%q<rspec>, [">= 2.4"])
data/spec/model_spec.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
2
 
3
3
  describe "Model" do
4
+
4
5
  it "should have a valid connection" do
5
6
  Person.connection.should be_a_kind_of OrientDB::Database
6
7
  end
@@ -27,6 +28,18 @@ describe "Model" do
27
28
  p2.tags.map.should == p.tags
28
29
  end
29
30
 
31
+ it "should handle embedded models as relations" do
32
+ Customer.clear
33
+
34
+ a = Address.new :street => "123 S Main", :city => "Salt Lake", :state => "UT", :country => "USA"
35
+ p1 = PhoneNumber.new :number => "123456789"
36
+ p2 = PhoneNumber.new :number => "987654321"
37
+ c1 = Customer.create :name => "Albert Einstein", :number => 1, :address => a, :phones => [p1, p2]
38
+
39
+ c2 = Customer.first
40
+ c1.should == c2
41
+ end
42
+
30
43
  it "should find models" do
31
44
  OrientDB::SQL.monkey_patch! Symbol
32
45
  Person.clear
@@ -42,4 +55,5 @@ describe "Model" do
42
55
  Person.where("'jedi' IN tags").all.should == [p2, p3]
43
56
  Person.where("'fighter' IN tags", :age.lte(28)).order(:name.desc).all.first.should == p4
44
57
  end
58
+
45
59
  end
@@ -5,3 +5,4 @@ class Address < OrientDB::AR::Embedded
5
5
  field :zip, :string
6
6
  field :country, :string
7
7
  end
8
+ Address.schema!
@@ -1,5 +1,6 @@
1
1
  class Customer < Person
2
2
  field :number, :int, :not_null => true
3
- # field :address, Address
3
+ has_one Address, :name => :address
4
+ has_many PhoneNumber, :name => :phones
4
5
  end
5
6
  Customer.schema!
@@ -0,0 +1,6 @@
1
+ class PhoneNumber < OrientDB::AR::Embedded
2
+ field :type, :string
3
+ field :number, :string
4
+ field :extension, :string
5
+ end
6
+ PhoneNumber.schema!
@@ -1,5 +1,4 @@
1
1
  class SimplePerson < OrientDB::AR::Base
2
2
  field :name, :string
3
3
  end
4
-
5
4
  SimplePerson.schema!
data/spec/spec_helper.rb CHANGED
@@ -28,6 +28,7 @@ unless defined?(SPEC_HELPER_LOADED)
28
28
 
29
29
  require SPEC_ROOT + '/models/person'
30
30
  require SPEC_ROOT + '/models/simple_person'
31
+ require SPEC_ROOT + '/models/phone_number'
31
32
  require SPEC_ROOT + '/models/address'
32
33
  require SPEC_ROOT + '/models/customer'
33
34
 
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 2
9
- version: 0.0.2
8
+ - 3
9
+ version: 0.0.3
10
10
  platform: jruby
11
11
  authors:
12
12
  - Adrian Madrid
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-01-17 00:00:00 -07:00
17
+ date: 2011-01-18 00:00:00 -07:00
18
18
  default_executable: orientdbar_console
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -27,8 +27,8 @@ dependencies:
27
27
  segments:
28
28
  - 0
29
29
  - 0
30
- - 10
31
- version: 0.0.10
30
+ - 11
31
+ version: 0.0.11
32
32
  type: :runtime
33
33
  version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
@@ -93,6 +93,8 @@ files:
93
93
  - lib/model/base.rb
94
94
  - lib/model/conversion.rb
95
95
  - lib/model/embedded.rb
96
+ - lib/model/query.rb
97
+ - lib/model/relations.rb
96
98
  - lib/model/validations.rb
97
99
  - lib/orientdb-ar.rb
98
100
  - orientdb-ar.gemspec
@@ -105,6 +107,7 @@ files:
105
107
  - spec/models/customer.rb
106
108
  - spec/models/flo_admin.rb
107
109
  - spec/models/person.rb
110
+ - spec/models/phone_number.rb
108
111
  - spec/models/simple_person.rb
109
112
  - spec/serialization_spec.rb
110
113
  - spec/spec.opts