orientdb4r 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -47,12 +47,19 @@ see Wiki page for more sample at https://github.com/veny/orientdb4r/wiki
47
47
  client.drop_class CLASS
48
48
  client.disconnect
49
49
 
50
+
50
51
  == INSTALL
51
52
 
52
53
  > sudo gem install orientdb4r
53
54
 
54
55
  * gem published on http://rubygems.org/gems/orientdb4r
55
56
 
57
+ === Important Upgrade Notice
58
+ 2012-06-19 [v0.2.1]: Client#create_class - parameter given to a block has new method 'link' to define a linked property
59
+ 2012-06-17 [v0.2.0]: Client#get_class raises Orientdb4r::NotFoundError instead of ArgumentError
60
+
61
+
62
+
56
63
  == FEATURES/PROBLEMS
57
64
 
58
65
  * Supports only REST API right now
@@ -63,6 +70,12 @@ Tested on
63
70
  * Ruby 1.9.3
64
71
  * OrientDB 1.0.0
65
72
 
73
+ == TESTS
74
+
75
+ rake test
76
+
77
+ Start an instance of OrientDB (on localhost with default port and 'admin/admin' account) before running.
78
+
66
79
  == AUTHOR
67
80
 
68
81
  * vaclav.sykora@gmail.com
@@ -94,6 +94,11 @@ module Orientdb4r
94
94
  def proxy.property(property, type, options={})
95
95
  self.target.send :create_property, self.context, property, type, options
96
96
  end
97
+ def proxy.link(property, type, linked_class, options={})
98
+ raise ArgumentError, "type has to be a linked-type, given=#{type}" unless type.to_s.start_with? 'link'
99
+ options[:linked_class] = linked_class
100
+ self.target.send :create_property, self.context, property, type, options
101
+ end
97
102
  yield proxy
98
103
  end
99
104
  end
@@ -128,13 +133,20 @@ module Orientdb4r
128
133
  raise ArgumentError, "property name is blank" if blank?(property)
129
134
  opt_pattern = {
130
135
  :mandatory => :optional , :notnull => :optional, :min => :optional, :max => :optional,
131
- :regexp => :optional, :custom => :optional
136
+ :regexp => :optional, :custom => :optional, :linked_class => :optional
132
137
  }
133
138
  verify_options(options, opt_pattern)
134
139
 
135
140
  cmd = "CREATE PROPERTY #{clazz}.#{property} #{type.to_s}"
141
+ # link?
142
+ if [:link, :linklist, :linkset, :linkmap].include? type.to_s.downcase.to_sym
143
+ raise ArgumentError, "defined linked-type, but not linked-class" unless options.include? :linked_class
144
+ cmd << " #{options[:linked_class]}"
145
+ end
136
146
  command cmd
137
147
 
148
+ # ALTER PROPERTY ...
149
+ options.delete :linked_class # it's not option for ALTER
138
150
  unless options.empty?
139
151
  options.each do |k,v|
140
152
  command "ALTER PROPERTY #{clazz}.#{property} #{k.to_s.upcase} #{v}"
@@ -142,6 +154,26 @@ module Orientdb4r
142
154
  end
143
155
  end
144
156
 
157
+
158
+ ###
159
+ # Creates links between two or more records of type Document.
160
+ # You need to create the class before.
161
+ # def create_link(clazz, options={})
162
+ # raise ArgumentError, "class name is blank" if blank?(clazz)
163
+ # opt_pattern = {
164
+ # :name => :optional, :type => :optional,
165
+ # :source_property => :mandatory, :destination_class => :mandatory, :destination_property => :mandatory
166
+ # }
167
+ # verify_options(options, opt_pattern)
168
+ #
169
+ # cmd = 'CREATE LINK '
170
+ # cmd << "#{options[:name]} " if options.include? :name
171
+ # cmd << "TYPE #{options[:type]} " if options.include? :type
172
+ # cmd << "FROM #{clazz}.#{options[:source_property]} TO #{options[:destination_class]}.#{options[:destination_property]}"
173
+ #puts cmd
174
+ # command cmd
175
+ # end
176
+
145
177
  # ----------------------------------------------------------------- DOCUMENT
146
178
 
147
179
  ###
@@ -178,7 +210,7 @@ module Orientdb4r
178
210
  ###
179
211
  # Asserts if the client is connected and raises an error if not.
180
212
  def assert_connected
181
- raise OrientdbError, "not connected" unless @connected
213
+ raise ConnectionError, 'not connected' unless @connected
182
214
  end
183
215
 
184
216
  ###
@@ -89,7 +89,7 @@ module Orientdb4r
89
89
  connect_info = process_response(response, :mode => :strict)
90
90
 
91
91
  classes = connect_info['classes'].select { |i| i['name'] == name }
92
- raise ArgumentError, "class not found, name=#{name}" unless 1 == classes.size
92
+ raise NotFoundError, "class not found, name=#{name}" unless 1 == classes.size
93
93
  decorate_classes_with_model(classes)
94
94
  clazz = classes[0]
95
95
  clazz.extend Orientdb4r::HashExtension
@@ -109,7 +109,7 @@ module Orientdb4r
109
109
  def query(sql) #:nodoc:
110
110
  raise ArgumentError, 'query is blank' if blank? sql
111
111
 
112
- response = @resource["query/#{@database}/sql/#{URI.escape(sql)}"].get
112
+ response = @resource["query/#{@database}/sql/#{CGI::escape(sql)}"].get
113
113
  rslt = process_response(response)
114
114
  rslt['result']
115
115
  end
@@ -119,7 +119,7 @@ module Orientdb4r
119
119
  raise ArgumentError, 'command is blank' if blank? sql
120
120
  begin
121
121
  #puts "REQ #{sql}"
122
- response = @resource["command/#{@database}/sql/#{URI.escape(sql)}"].post ''
122
+ response = @resource["command/#{@database}/sql/#{CGI::escape(sql)}"].post ''
123
123
  rslt = process_response(response)
124
124
  rslt
125
125
  #puts "RESP #{response.code}"
@@ -92,6 +92,12 @@ module Orientdb4r
92
92
  get_mandatory_attribute :notNull
93
93
  end
94
94
 
95
+ ###
96
+ # Gets linked class if the property is a link.
97
+ def linked_class
98
+ self['linkedClass']
99
+ end
100
+
95
101
  ###
96
102
  # Gets the minimal allowed value.
97
103
  def min
@@ -60,9 +60,27 @@ module Orientdb4r
60
60
  block.call
61
61
  end
62
62
 
63
- end
63
+ end # Proxy
64
+
65
+
66
+ class DataGenerator
67
+
68
+ def initialize
69
+ @worlds = IO.readlines('/usr/share/dict/words')
70
+ 0.upto(@worlds.size - 1) do |i|
71
+ word = @worlds[i]
72
+ word.strip!
73
+ idx = word.index("'")
74
+ word = word[0..(idx - 1)] unless idx.nil?
75
+ @worlds[i] = word
76
+ end
77
+ @worlds.uniq
78
+ Orientdb4r::logger.info "DataGenerator: #{@worlds.size} words"
79
+ end
80
+
81
+ end # DataGenerator
64
82
 
65
- end
83
+ end # Utils
66
84
 
67
85
 
68
86
  # TODO extend it to work with already defined methods ('before :foo, :baz' after method definition)
@@ -2,6 +2,7 @@ module Orientdb4r
2
2
 
3
3
  # Version history.
4
4
  VERSION_HISTORY = [
5
+ ['0.2.1', '2012-06-19', "Fixed linked property definition"],
5
6
  ['0.2.0', '2012-06-12', "Introduces document's CRUD operations"],
6
7
  ['0.1.2', '2012-06-10', 'Introduces new OClass module'],
7
8
  ['0.1.1', '2012-06-08', 'First working version (including unit tests) released at github.com'],
@@ -46,7 +46,7 @@ class TestDatabase < Test::Unit::TestCase
46
46
  @client.disconnect
47
47
  assert !@client.connected?
48
48
  # unable to query after disconnect
49
- assert_raise Orientdb4r::OrientdbError do @client.query 'SELECT FROM OUser'; end
49
+ assert_raise Orientdb4r::ConnectionError do @client.query 'SELECT FROM OUser'; end
50
50
  end
51
51
 
52
52
 
data/test/test_ddo.rb CHANGED
@@ -30,7 +30,7 @@ class TestDdo < Test::Unit::TestCase
30
30
  def test_get_class
31
31
  assert_nothing_thrown do ouser = @client.get_class 'OUser'; end
32
32
  # class does not exist
33
- assert_raise ArgumentError do @client.get_class 'OUserXXX'; end
33
+ assert_raise Orientdb4r::NotFoundError do @client.get_class 'OUserXXX'; end
34
34
 
35
35
  clazz = @client.get_class 'OUser'
36
36
  # test OClass
@@ -90,7 +90,7 @@ class TestDdo < Test::Unit::TestCase
90
90
  @client.create_class(super_clazz);
91
91
  @client.create_class(CLASS);
92
92
  assert_nothing_thrown do @client.drop_class(CLASS); end
93
- assert_raise ArgumentError do @client.get_class(CLASS); end # no info more
93
+ assert_raise Orientdb4r::NotFoundError do @client.get_class(CLASS); end # no info more
94
94
  # the class is not visible in class list delivered by connect
95
95
  rslt = @client.connect :database => DB, :user => 'admin', :password => 'admin'
96
96
  assert rslt['classes'].select { |i| i.name == CLASS }.empty?
@@ -110,10 +110,32 @@ class TestDdo < Test::Unit::TestCase
110
110
  @client.create_class(CLASS)
111
111
  assert_nothing_thrown do @client.create_property(CLASS, 'prop1', :integer); end
112
112
  clazz = @client.get_class(CLASS)
113
- assert_equal 'INTEGER', clazz.property(:prop1)['type']
113
+ assert_equal 'INTEGER', clazz.property(:prop1).type
114
+ assert_nil clazz.property(:prop1).linked_class
114
115
 
115
116
  # already exist
116
- # assert_raise Orientdb4r::OrientdbError do @client.create_property(CLASS, 'prop1', :integer); end
117
+ assert_raise Orientdb4r::OrientdbError do @client.create_property(CLASS, 'prop1', :integer); end
118
+ end
119
+
120
+
121
+ ###
122
+ # CREATE PROPERTY (linked-type)
123
+ def test_create_linkedtype
124
+ @client.create_class(CLASS)
125
+ assert_nothing_thrown do @client.create_property(CLASS, 'friends', :linkset, :linked_class => 'OUser'); end
126
+ clazz = @client.get_class(CLASS)
127
+ assert_equal 'LINKSET', clazz.property(:friends).type
128
+ assert_equal 'OUser', clazz.property(:friends).linked_class
129
+
130
+ # unknow linked-class
131
+ assert_raise Orientdb4r::OrientdbError do
132
+ @client.create_property(CLASS, 'friends2', :linkset, :linked_class => 'UnknownClass')
133
+ end
134
+
135
+ # already exist
136
+ assert_raise Orientdb4r::OrientdbError do
137
+ @client.create_property(CLASS, 'friends', :linkset, :linked_class => 'OUser');
138
+ end
117
139
  end
118
140
 
119
141
 
@@ -123,26 +145,37 @@ class TestDdo < Test::Unit::TestCase
123
145
  assert_nothing_thrown do
124
146
  @client.create_class(CLASS) do |c|
125
147
  c.property 'prop1', :integer
126
- c.property 'prop2', :string, :mandatory => true, :notnull => :true, :min => 1, :max => 99
148
+ c.property 'prop2', :string, :mandatory => true, :notnull => true, :min => 1, :max => 99
149
+ c.link 'user', :linkset, 'OUser', :mandatory => true
127
150
  end
128
151
  end
129
152
 
130
153
  clazz = @client.get_class(CLASS)
131
- assert_equal 2, clazz.properties.size
154
+ assert_equal 3, clazz.properties.size
132
155
 
133
156
  prop1 = clazz.property(:prop1)
134
- assert_equal 'INTEGER', prop1['type']
135
- assert !prop1['mandatory']
136
- assert !prop1['notNull']
137
- assert prop1['min'].nil?
138
- assert prop1['max'].nil?
157
+ assert_equal 'INTEGER', prop1.type
158
+ assert !prop1.mandatory
159
+ assert !prop1.not_null
160
+ assert_nil prop1.min
161
+ assert_nil prop1.max
162
+ assert_nil prop1.linked_class
139
163
 
140
164
  prop2 = clazz.property(:prop2)
141
- assert_equal 'STRING', prop2['type']
142
- assert prop2['mandatory']
143
- assert prop2['notNull']
144
- assert_equal '1', prop2['min']
145
- assert_equal '99', prop2['max']
165
+ assert_equal 'STRING', prop2.type
166
+ assert prop2.mandatory
167
+ assert prop2.not_null
168
+ assert_equal '1', prop2.min
169
+ assert_equal '99', prop2.max
170
+ assert_nil prop2.linked_class
171
+
172
+ user = clazz.property(:user)
173
+ assert_equal 'LINKSET', user.type
174
+ assert user.mandatory
175
+ assert !user.not_null
176
+ assert_nil user.min
177
+ assert_nil user.max
178
+ assert_equal 'OUser', user.linked_class
146
179
  end
147
180
 
148
181
  end
data/test/test_dmo.rb CHANGED
@@ -17,7 +17,9 @@ class TestDmo < Test::Unit::TestCase
17
17
  @client.create_class(CLASS) do |c|
18
18
  c.property 'prop1', :integer
19
19
  c.property 'prop2', :string, :mandatory => true, :notnull => :true, :min => 1, :max => 99
20
+ c.link 'friends', :linkset, 'OUser', :mandatory => true
20
21
  end
22
+ @admin = @client.query("SELECT FROM OUser WHERE name = 'admin'")[0]
21
23
  end
22
24
 
23
25
  def teardown
@@ -29,14 +31,25 @@ class TestDmo < Test::Unit::TestCase
29
31
 
30
32
  ###
31
33
  # INSERT INTO
32
- def test_insert
34
+ def xtest_insert
33
35
  assert_nothing_thrown do
34
36
  1.upto(10) do |i|
35
- @client.command "INSERT INTO #{CLASS} (prop1, prop2) VALUES (#{i}, '#{random_string}')"
37
+ @client.command "INSERT INTO #{CLASS} (prop1, prop2, friends) VALUES (#{i}, '#{random_string}', [#{@admin['@rid']}])"
36
38
  end
37
39
  end
38
40
 
39
- assert_equal 10, @client.query("SELECT count(*) FROM #{CLASS}")[0]['count'].to_i
41
+ entries = @client.query("SELECT FROM #{CLASS}")
42
+ assert_equal 10, entries.size
43
+ assert_equal 10, entries.select { |e| e if e['prop1'] <= 10 }.size
44
+ assert_equal 10, entries.select { |e| e if e['friends'].size == 1 }.size
45
+
46
+ # insert more users into LINKSET
47
+ urids = @client.query('SELECT FROM OUser').collect { |u| u['@rid'] }
48
+ assert_nothing_thrown do
49
+ @client.command "INSERT INTO #{CLASS} (prop1, prop2, friends) VALUES (1, 'linkset', [#{urids.join(',')}])"
50
+ end
51
+ assert_equal urids.size, @client.query("SELECT FROM #{CLASS} WHERE prop2 = 'linkset'")[0]['friends'].size
52
+
40
53
  end
41
54
 
42
55
 
@@ -44,10 +57,19 @@ class TestDmo < Test::Unit::TestCase
44
57
  # SELECT
45
58
  def test_query
46
59
  1.upto(10) do |i|
47
- @client.command "INSERT INTO #{CLASS} (prop1, prop2) VALUES (#{i}, 'string#{i}')"
60
+ @client.command "INSERT INTO #{CLASS} (prop1, prop2, friends) VALUES (#{i}, 'string#{i}', [#{@admin['@rid']}])"
48
61
  end
49
62
 
50
- puts @client.query("SELECT FROM #{CLASS}")
63
+ assert_equal 10, @client.query("SELECT FROM #{CLASS}").size
64
+ assert_equal 1, @client.query("SELECT FROM #{CLASS} WHERE prop1 = 1").size
65
+ assert_equal 0, @client.query("SELECT FROM #{CLASS} WHERE prop1 = 11").size
66
+ # graph
67
+ rid = @client.query("SELECT FROM #{CLASS} WHERE prop1 = 1")[0]['@rid']
68
+ gr = @client.query("SELECT FROM (TRAVERSE * FROM #{rid})")
69
+ assert_equal 3, gr.size # # entries: testing, OUser, ORole
70
+ assert_equal 1, gr.select { |e| e if e['@class'] == CLASS }.size
71
+ assert_equal 1, gr.select { |e| e if e['@class'] == 'OUser' }.size
72
+ assert_equal 1, gr.select { |e| e if e['@class'] == 'ORole' }.size
51
73
  end
52
74
 
53
75
  end
@@ -2,7 +2,7 @@ require 'test/unit'
2
2
  require 'orientdb4r'
3
3
 
4
4
  ###
5
- # This class tests Data Manipulation Operarions.
5
+ # This class tests CRUD operarions on document.
6
6
  class TestDocumentCrud < Test::Unit::TestCase
7
7
  include Orientdb4r::Utils
8
8
 
@@ -127,8 +127,8 @@ class TestDocumentCrud < Test::Unit::TestCase
127
127
  doc = @client.get_document rid
128
128
  assert_not_nil doc
129
129
 
130
+ assert_nothing_thrown do @client.delete_document rid; end
130
131
  # already deleted
131
- @client.delete_document rid
132
132
  assert_raise Orientdb4r::NotFoundError do @client.get_document rid; end
133
133
  end
134
134
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: orientdb4r
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-06-12 00:00:00.000000000 Z
12
+ date: 2012-06-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rest-client