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 +13 -0
- data/lib/orientdb4r/client.rb +34 -2
- data/lib/orientdb4r/rest/client.rb +3 -3
- data/lib/orientdb4r/rest/model.rb +6 -0
- data/lib/orientdb4r/utils.rb +20 -2
- data/lib/orientdb4r/version.rb +1 -0
- data/test/test_database.rb +1 -1
- data/test/test_ddo.rb +49 -16
- data/test/test_dmo.rb +27 -5
- data/test/test_document_crud.rb +2 -2
- metadata +2 -2
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
|
data/lib/orientdb4r/client.rb
CHANGED
@@ -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
|
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
|
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/#{
|
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/#{
|
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}"
|
data/lib/orientdb4r/utils.rb
CHANGED
@@ -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)
|
data/lib/orientdb4r/version.rb
CHANGED
@@ -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'],
|
data/test/test_database.rb
CHANGED
@@ -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::
|
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
|
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
|
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)
|
113
|
+
assert_equal 'INTEGER', clazz.property(:prop1).type
|
114
|
+
assert_nil clazz.property(:prop1).linked_class
|
114
115
|
|
115
116
|
# already exist
|
116
|
-
|
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 =>
|
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
|
154
|
+
assert_equal 3, clazz.properties.size
|
132
155
|
|
133
156
|
prop1 = clazz.property(:prop1)
|
134
|
-
assert_equal 'INTEGER', prop1
|
135
|
-
assert !prop1
|
136
|
-
assert !prop1
|
137
|
-
|
138
|
-
|
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
|
142
|
-
assert prop2
|
143
|
-
assert prop2
|
144
|
-
assert_equal '1', prop2
|
145
|
-
assert_equal '99', prop2
|
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
|
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
|
-
|
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
|
-
|
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
|
data/test/test_document_crud.rb
CHANGED
@@ -2,7 +2,7 @@ require 'test/unit'
|
|
2
2
|
require 'orientdb4r'
|
3
3
|
|
4
4
|
###
|
5
|
-
# This class tests
|
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.
|
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
|
+
date: 2012-06-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|