active-orient 0.6 → 0.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|