active-orient 0.6 → 0.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/Gemfile +4 -10
- data/Guardfile +4 -12
- data/README.md +198 -261
- data/VERSION +1 -1
- data/active-orient-0.4.gem +0 -0
- data/active-orient-0.41.gem +0 -0
- data/active-orient.gemspec +5 -6
- data/config/boot.rb +0 -84
- data/config/connect.yml +4 -8
- data/examples/books.rb +39 -86
- data/examples/streets.rb +84 -85
- data/lib/active-orient.rb +9 -57
- data/lib/base.rb +145 -172
- data/lib/base_properties.rb +44 -40
- data/lib/model.rb +468 -0
- data/lib/orient.rb +60 -114
- data/lib/query.rb +73 -71
- data/lib/rest.rb +1059 -0
- data/lib/support.rb +319 -386
- data/test.rb +4 -0
- data/usecase.md +91 -0
- metadata +20 -65
- data/bin/active-orient-console +0 -38
- data/config/config.yml +0 -10
- data/create_project +0 -19
- data/examples/test_commands.rb +0 -92
- data/examples/test_commands_2.rb +0 -54
- data/examples/test_commands_3.rb +0 -48
- data/examples/test_commands_4.rb +0 -28
- data/examples/time_graph.md +0 -162
- data/gratefuldeadconcerts.md +0 -94
- data/lib/class_utils.rb +0 -300
- data/lib/database_utils.rb +0 -106
- data/lib/init.rb +0 -45
- data/lib/java-api.rb +0 -437
- data/lib/jdbc.rb +0 -211
- data/lib/model/edge.rb +0 -55
- data/lib/model/model.rb +0 -91
- data/lib/model/the_class.rb +0 -500
- data/lib/model/the_record.rb +0 -322
- data/lib/model/vertex.rb +0 -136
- data/lib/orientdb_private.rb +0 -48
- data/lib/other.rb +0 -330
- data/lib/rest/change.rb +0 -137
- data/lib/rest/create.rb +0 -488
- data/lib/rest/delete.rb +0 -134
- data/lib/rest/operations.rb +0 -160
- data/lib/rest/read.rb +0 -150
- data/lib/rest/rest.rb +0 -112
- data/lib/rest_disabled.rb +0 -24
- data/linkmap.md +0 -75
- data/namespace.md +0 -111
- data/old_lib_functions/two_general_class.rb +0 -139
- data/rails.md +0 -125
- data/rails/activeorient.rb +0 -53
- data/rails/config.yml +0 -10
- data/rails/connect.yml +0 -17
- data/usecase_oo.md +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed8d14a983f8e3d067830ef41396d2cef289b46b
|
4
|
+
data.tar.gz: f848a337d6b4cd07e591d902402547f1f225b01f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4616d3587af1744fc6047b9aab929ae60911248029c310329c27cc36e3a545ed33c77fbe3d1f90b1b29346bf779dbe643497293d79618d06b3f6f950b6b6c464
|
7
|
+
data.tar.gz: 56a0f4ead290409aae2fde9e7af73d546cab19b3762d5d64d6bf4215ea23d2f71025c716a959f746a180125cb4c12c2e9cac492efd57ef3e2148c8a517e30a80
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,21 +1,15 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
gemspec
|
3
|
-
gem 'activesupport'
|
4
|
-
gem 'activemodel'
|
5
|
-
|
6
|
-
gem 'rest-client' , :git => 'git://github.com/rest-client/rest-client.git'
|
3
|
+
gem 'activesupport' , "~>4.2"
|
4
|
+
gem 'activemodel'
|
5
|
+
gem 'rest-client' # , :git => 'git://github.com/rest-client/rest-client.git'
|
7
6
|
gem 'nokogiri', '~> 1.6.6' #, :git => 'git://github.com/sparklemotion/nokogiri.git'
|
8
|
-
gem 'orientdb' , :path => '/home/topo/orientdb-jruby' , :platforms => :jruby
|
9
|
-
#gem 'orientdb' , :git => 'git://github.com/topofocus/orientdb-jruby.git', :branch => '2.1.2', :platforms => :jruby
|
10
7
|
group :development, :test do
|
11
|
-
gem "awesome_print"
|
12
8
|
gem "rspec"
|
13
|
-
gem 'rspec-legacy_formatters'
|
14
9
|
gem 'rspec-its'
|
15
10
|
gem 'rspec-collection_matchers'
|
16
11
|
gem 'rspec-context-private'
|
17
|
-
gem 'guard
|
18
|
-
gem 'guard'#, :platforms => :ruby
|
12
|
+
gem 'guard'
|
19
13
|
gem 'guard-rspec'
|
20
14
|
## gem 'database_cleaner'
|
21
15
|
gem 'rb-inotify'
|
data/Guardfile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# A sample Guardfile
|
2
2
|
# More info at https://github.com/guard/guard#readme
|
3
|
-
|
3
|
+
|
4
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
4
5
|
require "ostruct"
|
5
6
|
|
6
7
|
# Generic Ruby apps
|
@@ -11,19 +12,10 @@ def fire
|
|
11
12
|
|
12
13
|
|
13
14
|
watch(%r{^spec/.+_spec\.rb$})
|
14
|
-
|
15
|
+
watch(%r{^spec/usecase/(.+).rb$})
|
15
16
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
16
|
-
# watch(%r{^examples/time_graph/spec/(.+)_spec\.rb$})
|
17
|
-
watch('examples/time_graph/spec/create_time_spec.rb')
|
18
17
|
watch('spec/spec_helper.rb') { "spec" }
|
19
18
|
|
20
|
-
watch(%r{^spec/support/(.+)\.rb$})
|
19
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
21
20
|
end
|
22
21
|
|
23
|
-
|
24
|
-
interactor :simple
|
25
|
-
if RUBY_PLATFORM == 'java'
|
26
|
-
guard( 'jruby-rspec') {fire} #', :spec_paths => ["spec"]
|
27
|
-
else
|
28
|
-
guard( :rspec, cmd: "bundle exec rspec") { fire }
|
29
|
-
end
|
data/README.md
CHANGED
@@ -2,387 +2,324 @@
|
|
2
2
|
Use OrientDB to persistently store dynamic Ruby-Objects and use database queries to manage even very large
|
3
3
|
datasets.
|
4
4
|
|
5
|
-
|
6
|
-
- [Experiments with Joins / Linkmaps ](./linkmap.md)
|
5
|
+
The Package ist tested with Ruby 2.2.1 and Orientdb 2.1.
|
7
6
|
|
8
|
-
- [Experiments with the GratefulDeadConcerts Sample Database](./gratefuldeadconcerts.md)
|
9
7
|
|
10
|
-
|
8
|
+
To start you need a ruby 2.x Installation and a working OrientDB-Instance.
|
9
|
+
Install the Gem the usual way
|
11
10
|
|
12
|
-
|
11
|
+
For a quick start, go to the home directory of the package and start an irb-session
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
The jruby-part is experimental.
|
18
|
-
|
19
|
-
### Quick Start
|
20
|
-
|
21
|
-
- clone the project,
|
22
|
-
- run bundle install & bundle update,
|
23
|
-
- update config/connect.yml,
|
24
|
-
- create the documentation by calling »rdoc«
|
25
|
-
- start an irb-session by calling
|
26
|
-
```
|
27
|
-
cd bin
|
28
|
-
./active-orient-console test # or d)develpoment, p)roduction environment as defined in config/connect.yml
|
13
|
+
```ruby
|
14
|
+
require 'bundler/setup'
|
15
|
+
require 'active-orient'
|
29
16
|
```
|
30
17
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
```
|
36
|
-
Obviously, the class »Stock« has to exist.
|
37
|
-
Let's create some classes
|
38
|
-
|
39
|
-
```ruby
|
40
|
-
ORD.create_class 'ClassDocumentName' # creates or opens a basic document-class
|
41
|
-
ORD.create_vertex_class 'ClassVertexName' # creates or opens a vertex-class
|
42
|
-
ORD.create_edge_class 'ClassEdgeName' # creates or opens an edge-class, providing bidirectional links between documents
|
43
|
-
{Classname}.delete_class # removes the class in the database and destroys the ruby-object
|
44
|
-
```
|
18
|
+
First, the Database-Server has to be specified. Then we can connect to a database.
|
19
|
+
Assuming, the server is located on localhost, we just define »default-server«
|
20
|
+
```ruby
|
21
|
+
ActiveOrient::OrientDB.default_server= { user: 'your user', password: 'your password' }
|
45
22
|
|
46
|
-
Classnames appear unchanged as Database-Classes. Strings and Symbols are accepted. Depending on the namespace choosen in 'config/config.yml' Model-Classes are allocated and linked to database-classes. For simplicity, here we omit any namespace ( :namespace: :object in config.yml). Thus the Model-Obects are accessible directly.
|
47
23
|
|
24
|
+
r = ActiveOrient::OrientDB.new database: 'First'
|
25
|
+
=> I, [2015-08-18T09:49:18.858758 #88831] INFO -- OrientDB#Connect: Connected to database First
|
26
|
+
=> #<ActiveOrient::OrientDB:0x000000048d0488 @res=#<RestClient::Resource:0x00000004927288
|
27
|
+
@url="http://localhost:2480", @block=nil,
|
28
|
+
@options={:user=>"xx", :password=>"***"}>, @database="First", @classes=[]>
|
29
|
+
```
|
48
30
|
|
49
|
-
|
50
|
-
In Ruby-Space its Camelized, ie: ORD.create_class(:hut_ab) generates a Ruby-Class »HutAb«.
|
31
|
+
»r« is the Database-Instance itself. Obviously the database is empty.
|
51
32
|
|
52
|
-
This can be customized in the "naming_convention"-class-method, which has to be defined in 'config/boot.rb'. The naming_convention changes the ruby-view to the classes. The Database-Class-Name is derived from the argument to #CreateClass, ORD.create_class('HANDS_UP') creates a database-class "HANDS_UP' and a Ruby-Class "HandsUp".
|
53
33
|
|
54
|
-
|
55
|
-
loaded automatically afert executing #CreateClass (and through the preallocation process). Further details in the Examples-Section.
|
34
|
+
Let's create some classes
|
56
35
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
M
|
62
|
-
# or
|
63
|
-
new_record = M.new age: 46, interests: [ 'swimming', 'biking', 'reading' ]
|
64
|
-
new_record.save # alternative: new_record.update
|
65
|
-
##
|
66
|
-
hugo = M.where( name: 'Hugo' ).first
|
67
|
-
hugo.update set: { :father => M.create( name: "Volker", age: 76 ) } # we create an internal link
|
68
|
-
hugo.father.name # --> volker
|
69
|
-
M.remove hugo
|
70
|
-
M.delete_class # removes the class from OrientDB and deletes the ruby-object-definition
|
71
|
-
```
|
72
|
-
|
73
|
-
#### Inherence
|
36
|
+
```ruby
|
37
|
+
M = r.open_class 'classname' #
|
38
|
+
M = r.create_class 'classname' # creates or opens a basic document-class
|
39
|
+
M = r.create_vertex_class 'classname' # creates or opens a vertex-class
|
40
|
+
M = r.create_edge_class 'classname' # creates or opens an edge-class, providing bidirectional links between documents
|
74
41
|
|
75
|
-
|
76
|
-
```ruby
|
77
|
-
ORD.create_classes sector: [ :industry, :category, :subcategory ]
|
78
|
-
=> {Sector=>[Industry, Category, Subcategory]}
|
79
|
-
Industry.create name: 'Communications' #---> Create an Industry-Record with the attribute "name"
|
80
|
-
Sector.where name: 'Communications' #---> an Array with the Industry-Object
|
81
|
-
=> [#<Industry:0x0000000225e098 @metadata= (...) ]
|
42
|
+
r.delete_class M # universal removal-of-the-class-method
|
82
43
|
```
|
83
|
-
***notice*** to create inherent Vertices use ORD.create_classes( sector: [ :industry, :category, :subcategory ]){ :V }
|
84
44
|
|
85
|
-
#### Preallocation of Model-Classes
|
86
|
-
All database-classes are preallocated after connecting to the database. Thus you can use Model-Classes from the start.
|
87
45
|
|
88
|
-
|
89
|
-
|
90
|
-
the_object = V.autoload_object "xx:yy" # or "#xx:yy"
|
91
|
-
---> {ActiveOrient::Model} Object
|
92
|
-
```
|
93
|
-
The database-class «V» is present in any case. Any model-class can be used, even the parent »ActiveOrient::Model«
|
46
|
+
»M« is the ActiveOrient::Model-Class itself, a constant pointing to the class-definition of the ruby-class.
|
47
|
+
Its a shortcut for »ActiveOrient::Model::{Classname} and is reused if defined elsewhere.
|
94
48
|
|
95
|
-
|
96
|
-
|
49
|
+
If a schema is used, properties can be created and retrieved as well
|
50
|
+
```ruby
|
51
|
+
r.create_properties( M ) do
|
52
|
+
{ symbol: { propertyType: 'STRING' },
|
53
|
+
con_id: { propertyType: 'INTEGER' },
|
54
|
+
details: { propertyType: 'LINK', linkedClass: 'Contracts' }
|
55
|
+
}
|
97
56
|
|
57
|
+
r.get_class_properties M
|
58
|
+
```
|
59
|
+
or
|
98
60
|
```ruby
|
99
|
-
|
100
|
-
M.create_property
|
101
|
-
M.create_property :
|
102
|
-
M.create_property :details, type: :link, other_class: 'Contracts'
|
103
|
-
M.create_property :items, type: :linklist, :linklist: Item
|
104
|
-
M.create_property :name, index: :unique # or M.create_property( 'name' ){ :unique }
|
61
|
+
M.create_property 'symbol'
|
62
|
+
M.create_property 'con_id', type: 'integer'
|
63
|
+
M.create_property 'details', type: 'link', other_class: 'Contracts'
|
105
64
|
```
|
106
65
|
|
107
|
-
|
108
|
-
|
66
|
+
#### Active Model interface
|
67
|
+
|
68
|
+
Every OrientDB-Database-Class is mirrord as Ruby-Class. The Class itself is defined by
|
109
69
|
```ruby
|
110
|
-
M.
|
111
|
-
M.
|
70
|
+
M = r.create_class 'classname'
|
71
|
+
M = r.create_class { superclass_name: 'classname' }
|
72
|
+
Vertex = r.create_vertex_class 'classname'
|
73
|
+
Edge = r.create_edge_class 'classname'
|
112
74
|
```
|
75
|
+
and is of TYPE ActiveOrient::Model::{classname}
|
113
76
|
|
114
|
-
|
115
|
-
|
116
|
-
As for ActiveRecord-Tables, the Model-class itself provides methods to inspect and filter datasets form the database.
|
77
|
+
As for ActiveRecord-Tables, the Class itself provides methods to inspect and to filter datasets form the database.
|
117
78
|
|
118
79
|
```ruby
|
119
80
|
M.all
|
120
81
|
M.first
|
121
|
-
M.last
|
122
|
-
|
123
|
-
|
82
|
+
M.last
|
83
|
+
```
|
84
|
+
returns an Array containing all Documents/Edges of the Class; the first and the last Record.
|
85
|
+
```ruby
|
86
|
+
M.where town: 'Berlin'
|
87
|
+
```
|
88
|
+
performs a query on the class and returns the result as Array
|
124
89
|
|
90
|
+
```ruby
|
125
91
|
M.count where: { town: 'Berlin' }
|
126
92
|
```
|
127
|
-
|
93
|
+
gets the number of datasets fullfilling the search-criteria. Any parameter defining a valid
|
94
|
+
SQL-Query in Orientdb can be provided to the count, where, first and last-method.
|
128
95
|
|
129
|
-
A »normal« Query is submitted via
|
96
|
+
A »normal« Query is submitted via
|
130
97
|
```ruby
|
131
|
-
M.
|
132
|
-
distinct: { some parameters }
|
133
|
-
where: { where-parameter }
|
134
|
-
order: { sorting-parameters }
|
135
|
-
group_by: { one grouping-parameter}
|
136
|
-
unwind:
|
137
|
-
skip:
|
138
|
-
limit:
|
98
|
+
M.get_documents projection: { projection-parameter }
|
99
|
+
distinct: { some parameters }
|
100
|
+
where: { where-parameter }
|
101
|
+
order: { sorting-parameters }
|
102
|
+
group_by: { one grouping-parameter}
|
103
|
+
unwind:
|
104
|
+
skip:
|
105
|
+
limit:
|
139
106
|
|
140
107
|
# or
|
141
|
-
query = OrientSupport::OrientQuery.new {paramter}
|
142
|
-
M.
|
108
|
+
query = OrientSupport::OrientQuery.new {paramter}
|
109
|
+
M.get_documents query: query
|
143
110
|
|
144
111
|
```
|
145
112
|
|
146
|
-
|
147
|
-
|
148
|
-
M.update_all connected: false # add a property »connected» to each record
|
149
|
-
M.update_all set:{ connected: true }, where: "symbol containsText 'S'"
|
150
|
-
```
|
113
|
+
Basic graph-support:
|
114
|
+
|
151
115
|
|
152
|
-
Graph-support:
|
153
116
|
|
154
117
|
```ruby
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
vertex_2 = TheVertex.create flower: "rose"
|
159
|
-
TheEdge.create_edge attributes: {:birthday => Date.today }, from: vertex_1, to: vertex_2
|
118
|
+
vertex_1 = Vertex.create color: "blue"
|
119
|
+
vertex_2 = Vertex.create flower: "rose"
|
120
|
+
Edge.create_edge attributes: { :birthday => Date.today }, from: vertex_1, to: vertex_2
|
160
121
|
```
|
161
|
-
|
122
|
+
connects the vertices and assigns the attributes to the edge
|
162
123
|
|
163
|
-
To query a graph, SQL-like-Queries and Match-statements can be used (see below).
|
164
124
|
|
125
|
+
#### Links
|
165
126
|
|
166
|
-
|
127
|
+
A record in a database-class is defined by a »rid«. Every Model-Object comes with a handy »link«-method.
|
167
128
|
|
168
|
-
|
169
|
-
In OrientDB links are used to realize unidirectional 1:1 and 1:n relationships.
|
129
|
+
In OrientDB links are used to realise unidirectional 1:1 and 1:n relationships.
|
170
130
|
|
171
|
-
ActiveOrient autoloads Model-objects when they are accessed.
|
172
|
-
|
173
|
-
link if stored somewhere.
|
131
|
+
ActiveOrient autoloads Model-objects when they are accessed. As a consequence,
|
132
|
+
if an Object is stored in Cluster 30 and id 2, then "#30:2" fully qualifies the ActiveOrient::Model object.
|
174
133
|
|
175
134
|
```ruby
|
176
|
-
|
177
|
-
|
135
|
+
TestLinks = r.create_class 'Test_link_class'
|
136
|
+
TestBase = r.create_class 'Test_base_class'
|
178
137
|
|
179
|
-
link_document =
|
180
|
-
base_document = TestBase.create base: 'my_base', single_link: link_document
|
138
|
+
link_document = TestLinks.create att: 'one attribute'
|
139
|
+
base_document = TestBase.create base: 'my_base', single_link: link_document
|
181
140
|
```
|
182
|
-
base_document.single_link just contains the rid. When accessed, the ActiveOrient::Model::Testlinkclass-object is autoloaded and
|
183
|
-
|
141
|
+
base_document.single_link just contains the rid. When accessed, the ActiveOrient::Model::Testlinkclass-object is autoloaded and
|
184
142
|
``` ruby
|
185
143
|
base_document.single_link.att
|
186
144
|
```
|
187
|
-
reads the stored content of link_document.
|
145
|
+
reads the stored content of link_document.
|
188
146
|
|
189
|
-
To store a list of links to other Database-Objects
|
147
|
+
To store a list of links to other Database-Objects a simple Array is allocated
|
190
148
|
``` ruby
|
191
149
|
# predefined linkmap-properties
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
150
|
+
base_document = TestBase.create links: []
|
151
|
+
( 0 .. 20 ).each{ |y| base_document.links << TestLinks.create nr: y }
|
152
|
+
end
|
196
153
|
#or in schemaless-mode
|
197
|
-
base_document =
|
198
|
-
|
154
|
+
base_document = TestBase.create links: (0..20).map{|y| TestLinks.create nr: y }
|
155
|
+
|
156
|
+
|
199
157
|
```
|
200
|
-
base_document.links behaves like a ruby-array.
|
158
|
+
base_document.links behaves like a ruby-array.
|
201
159
|
|
202
160
|
If you got an undirectional graph
|
203
161
|
|
204
162
|
a --> b ---> c --> d
|
205
163
|
|
206
|
-
the
|
207
|
-
|
208
|
-
Refer to the "Time-Graph"-Example for an Implementation of an bidirectional Graph with the same Interface
|
164
|
+
the graphelements can be explored by joining the objects ( a.b.c.d ), or (a.b[5].c[9].d )
|
209
165
|
|
210
166
|
#### Edges
|
211
|
-
|
167
|
+
|
168
|
+
Edges are easily handled
|
212
169
|
```ruby
|
213
|
-
|
214
|
-
|
170
|
+
Vertex = r.create_vertex_class 'd1'
|
171
|
+
Eedge = r.create_edge_class 'e1'
|
215
172
|
|
216
|
-
start =
|
217
|
-
the_end
|
218
|
-
the_edge =
|
173
|
+
start = Vertex.create something: 'nice'
|
174
|
+
the_end = Vertex.create something: 'not_nice'
|
175
|
+
the_edge = Edge.create_edge attributes: { transform_to: 'very bad' },
|
219
176
|
from: start,
|
220
177
|
to: the_end
|
178
|
+
|
179
|
+
(...)
|
180
|
+
the_edge.delete
|
221
181
|
```
|
222
|
-
Edges are connected to vertices by »in« and »out«-Methods.
|
223
|
-
Inherence is supported.
|
224
182
|
|
225
|
-
|
226
|
-
|
227
|
-
ORD.create_class( top_edge ) { THE_EDGE }
|
228
|
-
ORD.create_class( on_top_edge ) { TOP_EDGE }
|
183
|
+
There is a basic support for traversals throught a graph.
|
184
|
+
The Edges are accessed by their names (downcase).
|
229
185
|
|
230
|
-
ON_TOP_Edge.create from: start, to: the_end
|
231
|
-
start.reload!
|
232
|
-
start.out :the_edge
|
233
|
-
=> [#<TOP_EDGE:0x00000001d92f28 @metadata= ... ]
|
234
|
-
```
|
235
|
-
|
236
|
-
Edge-links are displayed and retrieved by
|
237
186
|
```ruby
|
238
|
-
start.
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
187
|
+
start.e1[0]
|
188
|
+
--> #<ActiveOrient::Model::E1:0x000000041e4e30
|
189
|
+
@metadata={"type"=>"d", "class"=>"E1", "version"=>60, "fieldTypes"=>"out=x,in=x",
|
190
|
+
"cluster"=>16, "record"=>43},
|
191
|
+
@attributes={"out"=>"#31:23", "in"=>"#31:15", "transform_to"=>"very bad" }>
|
244
192
|
```
|
245
|
-
|
246
|
-
|
247
|
-
The create-Method od Edge-Classes takes a block. Then all statements are transmitted in batch-mode.
|
248
|
-
Assume, Vertex1 and Vertex2 are Vertex-Classes and TheEdge is an Edge-Class, then
|
193
|
+
The Attributes "in" and "out" can be used to move across the graph
|
249
194
|
```ruby
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
('a'.ord .. 'z'.ord).map do |o|
|
255
|
-
{ from: record1.find{|x| x.testentry == o },
|
256
|
-
to: record2.find{ |x| x.testentry.ord == o },
|
257
|
-
attributes: attributes.merge( key: o.chr ) }
|
258
|
-
end
|
195
|
+
start.e1[0].out.something
|
196
|
+
---> "not_nice
|
197
|
+
start.e1[0].in.something
|
198
|
+
---> "nice
|
259
199
|
```
|
260
|
-
connects the vertices and provides a variable "key" and a common "study" attribute to each edge.
|
261
|
-
|
262
|
-
|
263
200
|
#### Queries
|
201
|
+
Contrary to traditional SQL-based Databases OrientDB handles subqueries very efficient.
|
202
|
+
In addition, OrientDB supports precompiled statements (let-Blocks).
|
264
203
|
|
265
|
-
|
266
|
-
|
267
|
-
ActiveOrient is equipped with a simple QueryGenerator: ActiveSupport::OrientQuery.
|
268
|
-
It works in two ways: a comprehensive and a subsequent one
|
269
|
-
|
204
|
+
ActiveOrient is equipped with a simple QueryGenerator: ActiveSupport::OrientQuery.
|
205
|
+
It works in two modi: a comprehensive and a subsequent one
|
270
206
|
```ruby
|
271
|
-
|
207
|
+
|
272
208
|
q = OrientSupport::OrientQuery.new
|
273
|
-
q.from = Vertex
|
274
|
-
# ActiveOrient::Model-class is refered
|
209
|
+
q.from = Vertex
|
275
210
|
q.where << a: 2
|
276
211
|
q.where << 'b > 3 '
|
277
212
|
q.distinct = :profession
|
278
|
-
q.order =
|
213
|
+
q.order = { :name => :asc }
|
279
214
|
|
280
215
|
```
|
281
216
|
is equivalent to
|
282
|
-
|
283
217
|
```ruby
|
284
|
-
q = OrientSupport::OrientQuery.new from: Vertex ,
|
218
|
+
q = OrientSupport::OrientQuery.new from: Vertex ,
|
285
219
|
where: [{ a: 2 }, 'b > 3 '],
|
286
220
|
distinct: :profession,
|
287
221
|
order: { :name => :asc }
|
288
222
|
q.to_s
|
289
223
|
=> select distinct( profession ) from Vertex where a = 2 and b > 3 order by name asc
|
290
224
|
```
|
225
|
+
Both modes can be mixed.
|
291
226
|
|
292
|
-
|
293
|
-
|
294
|
-
If sub-queries are necessary, they can be introduced as OrientSupport::OrientQuery or as »let-block«.
|
295
|
-
|
227
|
+
If subqueries are nessesary, they can be introduced as OrientSupport::OrientQuery or as »let-block«.
|
296
228
|
```ruby
|
297
|
-
|
298
|
-
q = OQ.new from: 'ModelQuery'
|
229
|
+
q = OrientSupport::OrientQuery.new from: 'ModelQuery'
|
299
230
|
q.let << "$city = adress.city"
|
300
231
|
q.where = "$city.country.name = 'Italy' OR $city.country.name = 'France'"
|
301
232
|
q.to_s
|
302
|
-
|
233
|
+
=> select from ModelQuery let $city = adress.city where $city.country.name = 'Italy' OR $city.country.name = 'France'
|
303
234
|
```
|
304
|
-
|
305
235
|
or
|
306
|
-
|
307
236
|
```ruby
|
308
|
-
q =
|
309
|
-
q.let << {a:
|
310
|
-
q.let << {b:
|
237
|
+
q = OrientSupport::OrientQuery.new
|
238
|
+
q.let << { a: OrientSupport::OrientQuery.new( from: '#5:0' ) }
|
239
|
+
q.let << { b: OrientSupport::OrientQuery.new( from: '#5:1' ) }
|
311
240
|
q.let << '$c= UNIONALL($a,$b) '
|
312
241
|
q.projection << 'expand( $c )'
|
313
|
-
q.to_s
|
242
|
+
q.to_s
|
243
|
+
=> select expand( $c ) let $a = ( select from #5:0 ), $b = ( select from #5:1 ), $c= UNIONALL($a,$b)
|
314
244
|
```
|
315
245
|
|
316
|
-
or
|
317
246
|
|
318
|
-
```ruby
|
319
|
-
last_12_open_interest_records = OQ.new from: OpenInterest,
|
320
|
-
order: { fetch_date: :desc } , limit: 12
|
321
|
-
bunch_of_contracts = OQ.new from: last_12_open_interest_records,
|
322
|
-
projection: 'expand( contracts )'
|
323
|
-
distinct_contracts = OQ.new from: bunch_of_contracts,
|
324
|
-
projection: 'expand( distinct(@rid) )'
|
325
247
|
|
326
|
-
distinct_contracts.to_s
|
327
|
-
=> "select expand( distinct(@rid) ) from ( select expand( contracts ) from ( select from open_interest order by fetch_date desc limit 12 ) ) "
|
328
248
|
|
329
|
-
|
330
|
-
|
331
|
-
this executes the query and returns the adressed rid's, which are eventually retrieved from the rid-cache.
|
332
|
-
#### Match
|
249
|
+
#### Execute SQL-Commands
|
250
|
+
Sql-commands can be executed as batch
|
333
251
|
|
334
|
-
|
335
|
-
|
252
|
+
The ActiveOrient::Query-Class provides a Query-Stack and an Records-Array which keeps the results.
|
253
|
+
The ActiveOrient::Query-Class acts as Parent-Class for aggregated Records (without a @rid), which are ActiveOrient::Model::Myquery Objects. If a Query returns a database-record, the correct ActiveOrient::Model-Class is instantiated.
|
254
|
+
|
255
|
+
```ruby
|
256
|
+
ach = ActiveOrient::Query.new
|
257
|
+
|
258
|
+
ach.queries << 'create class Contracts ABSTRACT'
|
259
|
+
ach.queries << 'create property Contracts.subcategory link'
|
260
|
+
ach.queries << 'create property Contracts.details link'
|
261
|
+
ach.queries << 'create class Stocks extends Contracts'
|
262
|
+
ach.queries << 'create class Futures extends Contracts'
|
263
|
+
result = ach.execute_queries transaction: false
|
264
|
+
|
265
|
+
|
266
|
+
|
267
|
+
```
|
268
|
+
queries the database as demonstrated above. In addition, the generated query itself is added to the »queries«-Stack and the result can be found in sample_query.records.
|
336
269
|
|
270
|
+
This feature can be used as a substitute for simple functions
|
271
|
+
|
337
272
|
```ruby
|
338
|
-
|
339
|
-
|
340
|
-
|
273
|
+
roq = ActiveOrient::Query.new
|
274
|
+
roq.queries =["select name, categories.subcategories.contracts from Industries where name containstext …'ial'"]
|
275
|
+
roq.execute_queries.each{|x| puts x.name, x.categories.inspect }
|
276
|
+
--> Basic Materials [["#21:1"]]
|
277
|
+
--> Financial [["#21:2"]]
|
278
|
+
--> Industrial [["#23:0", "#23:1"]]
|
341
279
|
```
|
342
280
|
|
343
|
-
|
281
|
+
OrientDB supports the execution of SQL-Batch-Commands.
|
282
|
+
( http://orientdb.com/docs/2.0/orientdb.wiki/SQL-batch.html )
|
283
|
+
This is supported simply by using a Array as Argument for ActiveOrient::Query.queries
|
344
284
|
|
285
|
+
Therefor complex queries can be simplified using database-variables
|
345
286
|
```ruby
|
346
|
-
|
347
|
-
|
348
|
-
|
287
|
+
ach = ActiveOrient::Query.new
|
288
|
+
ach.queries << [ "select expand( contracts ) from Openinterest"
|
289
|
+
"let con = select expand( contracts ) from Openinterest; ",
|
290
|
+
"...", ... ]
|
291
|
+
result = ach.execute_queries
|
349
292
|
```
|
350
|
-
The Match-Query uses this result-set as start for subsequent queries on connected records.
|
351
|
-
If a linear graph: Industry <- Category <- Subcategory <- Stock is build, Subcategories can
|
352
|
-
accessed starting at Industry defining
|
353
293
|
|
294
|
+
The contract-documents are accessible with
|
354
295
|
```ruby
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
query # important: block has to return the query
|
359
|
-
end
|
360
|
-
=> MATCH {class: Industry, as: Industries} <-- {} <-- { as: Subcategories } RETURN Industries, Subcategories
|
296
|
+
r.get_document '21:1'
|
297
|
+
--><Stocks: con_id: 77680640 currency: EUR details: #18:1 exchange: SMART local_symbol: BAS
|
298
|
+
primary_exchange: IBIS subcategory: #14:1 symbol: BAS>
|
361
299
|
```
|
300
|
+
or
|
301
|
+
```ruby
|
302
|
+
my_query = ActiveOrient::Query.new
|
303
|
+
['Contracts', 'Industries', 'Categories', 'Subcategories'].each do |table|
|
304
|
+
my_query.queries = [ "select count(*) from #{table}"]
|
305
|
+
|
306
|
+
count = my_query.execute_queries
|
307
|
+
# count=> [#<ActiveOrient::Model::Myquery:0x00000003b317c8
|
308
|
+
# @metadata={"type"=>"d", "class"=>nil, "version"=>0, "fieldTypes"=>"count=l"},
|
309
|
+
# @attributes={"count"=>4 } ] --> an Array with one Element, therefor count.pop
|
310
|
+
puts "Table #{table} \t #{count.pop.count} Datasets "
|
311
|
+
end
|
312
|
+
-->Table Contracts 56 Datasets
|
313
|
+
-->Table Industries 8 Datasets
|
314
|
+
-->Table Categories 22 Datasets
|
315
|
+
-->Table Subcategories 35 Datasets
|
362
316
|
|
363
|
-
|
364
|
-
|
365
|
-
By using subsequent »connect« and »statement« method-calls even complex Match-Queries can be constructed.
|
366
|
-
|
367
|
-
|
368
|
-
#### Other Documents
|
369
|
-
- [Experiments with Joins / Linkmaps ](./linkmap.md)
|
370
|
-
|
371
|
-
- [Experiment with the GratefulDeadConcerts Sample Database](./gratefuldeadconcerts.md)
|
372
|
-
|
373
|
-
- [Namespace Support](./namespace.md)
|
374
|
-
|
375
|
-
- [TimeGraph Implementation](examples/time_graph.md)
|
317
|
+
```
|
376
318
|
|
319
|
+
Note that the fetched Object is of type »Stocks« (ActiveOrient::Model::Stocks).
|
377
320
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
start.something # 'nice'
|
384
|
-
end.something # 'not_nice'
|
385
|
-
start.the_edge.where( transform_to: 'very bad').in.something # => ["not_nice"]
|
386
|
-
(...)
|
387
|
-
the_edge.delete # To delete the edge
|
388
|
-
```
|
321
|
+
The ActiveOrient-API documentation can be found here: https://github.com/orientechnologies/orientdb-docs/wiki/OrientDB-ActiveOrient
|
322
|
+
and the ActiveModel-documentation is here: http://www.rubydoc.info/gems/activemodel
|
323
|
+
|
324
|
+
|
325
|
+
|