active-orient 0.6 → 0.42

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -1
  3. data/Gemfile +4 -10
  4. data/Guardfile +4 -12
  5. data/README.md +198 -261
  6. data/VERSION +1 -1
  7. data/active-orient-0.4.gem +0 -0
  8. data/active-orient-0.41.gem +0 -0
  9. data/active-orient.gemspec +5 -6
  10. data/config/boot.rb +0 -84
  11. data/config/connect.yml +4 -8
  12. data/examples/books.rb +39 -86
  13. data/examples/streets.rb +84 -85
  14. data/lib/active-orient.rb +9 -57
  15. data/lib/base.rb +145 -172
  16. data/lib/base_properties.rb +44 -40
  17. data/lib/model.rb +468 -0
  18. data/lib/orient.rb +60 -114
  19. data/lib/query.rb +73 -71
  20. data/lib/rest.rb +1059 -0
  21. data/lib/support.rb +319 -386
  22. data/test.rb +4 -0
  23. data/usecase.md +91 -0
  24. metadata +20 -65
  25. data/bin/active-orient-console +0 -38
  26. data/config/config.yml +0 -10
  27. data/create_project +0 -19
  28. data/examples/test_commands.rb +0 -92
  29. data/examples/test_commands_2.rb +0 -54
  30. data/examples/test_commands_3.rb +0 -48
  31. data/examples/test_commands_4.rb +0 -28
  32. data/examples/time_graph.md +0 -162
  33. data/gratefuldeadconcerts.md +0 -94
  34. data/lib/class_utils.rb +0 -300
  35. data/lib/database_utils.rb +0 -106
  36. data/lib/init.rb +0 -45
  37. data/lib/java-api.rb +0 -437
  38. data/lib/jdbc.rb +0 -211
  39. data/lib/model/edge.rb +0 -55
  40. data/lib/model/model.rb +0 -91
  41. data/lib/model/the_class.rb +0 -500
  42. data/lib/model/the_record.rb +0 -322
  43. data/lib/model/vertex.rb +0 -136
  44. data/lib/orientdb_private.rb +0 -48
  45. data/lib/other.rb +0 -330
  46. data/lib/rest/change.rb +0 -137
  47. data/lib/rest/create.rb +0 -488
  48. data/lib/rest/delete.rb +0 -134
  49. data/lib/rest/operations.rb +0 -160
  50. data/lib/rest/read.rb +0 -150
  51. data/lib/rest/rest.rb +0 -112
  52. data/lib/rest_disabled.rb +0 -24
  53. data/linkmap.md +0 -75
  54. data/namespace.md +0 -111
  55. data/old_lib_functions/two_general_class.rb +0 -139
  56. data/rails.md +0 -125
  57. data/rails/activeorient.rb +0 -53
  58. data/rails/config.yml +0 -10
  59. data/rails/connect.yml +0 -17
  60. data/usecase_oo.md +0 -61
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c3fb207d23e5c1cd30e95105075370967fb4a6b
4
- data.tar.gz: 6f606ff9a666368ddcaa51dd0e3ca7f7edf3bfa2
3
+ metadata.gz: ed8d14a983f8e3d067830ef41396d2cef289b46b
4
+ data.tar.gz: f848a337d6b4cd07e591d902402547f1f225b01f
5
5
  SHA512:
6
- metadata.gz: 371a9c4ad68cad3f4efc701c3965e1f946bce6f610b4ea7245f3f168a6417185dc7829395387a07f97e55f92c02829a7e72999f824ffffff92e99f17090e1113
7
- data.tar.gz: 2f4c7e0a6a74a34c5f605ae6b9ee094eb4c2ff51827c1beb5d77be04caceba6c7ed2149edd093be0ee9b9004afa6bdc4fdc203d4c1e5122d648c7b87aebfb961
6
+ metadata.gz: 4616d3587af1744fc6047b9aab929ae60911248029c310329c27cc36e3a545ed33c77fbe3d1f90b1b29346bf779dbe643497293d79618d06b3f6f950b6b6c464
7
+ data.tar.gz: 56a0f4ead290409aae2fde9e7af73d546cab19b3762d5d64d6bf4215ea23d2f71025c716a959f746a180125cb4c12c2e9cac492efd57ef3e2148c8a517e30a80
data/.gitignore CHANGED
@@ -7,4 +7,3 @@
7
7
  /pkg/
8
8
  /spec/reports/
9
9
  /tmp/
10
- *~
data/Gemfile CHANGED
@@ -1,21 +1,15 @@
1
1
  source "https://rubygems.org"
2
2
  gemspec
3
- gem 'activesupport' # , "~>4.2"
4
- gem 'activemodel' #, "~>4.2"
5
- #gem 'activemodel-serializers-xml'
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-jruby-rspec', :platforms => :jruby, :git => 'git://github.com/jkutner/guard-jruby-rspec.git'
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
- def fire
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
- # watch(%r{^spec/usecase/(.+)\.rb$})
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$}) { "spec" }
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
- #### Other Documents
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
- - [Namespace Support](./namespace.md)
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
- - [TimeGraph Implementation](examples/time_graph.md)
11
+ For a quick start, go to the home directory of the package and start an irb-session
13
12
 
14
- - [Rails 5-Integration](./rails.md)
15
-
16
- You need a ruby 2.3, 2.4 or a jruby 9.1x Installation and a working OrientDB-Instance (Version 2.2 prefered).
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
- «ORD» or «DB» is the Database-Instance itself. If the Database noticed is not present, it is created on startup.
32
- A simple SQL-Query is submitted by providing a Block to »execute«
33
- ```ruby
34
- result = ORD.execute { "select * from Stock" }
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
- **Naming-Convention:** The name given in the »create-class«-Statement becomes the Database-Classname.
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
- ActiveOrient::Model's can be customized through methods defined in the model-directory. These methods are
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
- #### CRUD
58
- The CRUD-Process (create, read = query, update and remove) is performed as
59
- ```ruby
60
- ORD.create_class :M
61
- M.create name: 'Hugo', age: 46, interests: [ 'swimming', 'biking', 'reading' ]
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
- Create a Tree of Objects with create_classes
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
- If the "rid" is known, any Object can be retrieved and correctly allocated by
89
- ```ruby
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
- #### Properties
96
- The schemaless mode has many limitations. ActiveOrient offers a Ruby way to define Properties and Indexes
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
- ORD.create_class :M, :item
100
- M.create_property :symbol # the default-case: type: :string, no index
101
- M.create_property :con_id, type: :integer
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
- (Experimental) You can put restrictions on your properties with the command "alter_property":
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.alter_property property: "value", attribute: "MIN", alteration: 0
111
- M.alter_property property: "value", attribute: "MAX", alteration: 23
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
- #### Active Model interface
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 # notice: last does not work in orientdb version 2.2, because the sorting algorithm for rid's is damaged
122
- M.all.last # or M.where( ... ).last walkaround for Orientdb V 2.2
123
- M.where town: 'Berlin'
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
- »count« gets the number of datasets fulfilling the search-criteria. Any parameter defining a valid SQL-Query in Orientdb can be provided to the »count«, »where«, »first« and »last«-method.
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.get_records projection: { projection-parameter },
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.query_database query
108
+ query = OrientSupport::OrientQuery.new {paramter}
109
+ M.get_documents query: query
143
110
 
144
111
  ```
145
112
 
146
- To update several records, a class-method »update_all« is defined.
147
- ```ruby
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
- ORD.create_vertex_class :the_vertex
156
- ORD.create_edge_class :the_edge
157
- vertex_1 = TheVertex.create color: "blue"
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
- It connects the vertexes and assigns the attributes to the edge.
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
- #### Links and LinkLists
127
+ A record in a database-class is defined by a »rid«. Every Model-Object comes with a handy »link«-method.
167
128
 
168
- A record in a database-class is defined by a »rid«. If this is stored in a class, a link is set.
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. Example:
172
- If an Object is stored in Cluster 30 and id 2, then "#30:2" fully qualifies the ActiveOrient::Model object and sets the
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
- ORD.create_class 'test_link'
177
- ORD.create_class 'test_base'
135
+ TestLinks = r.create_class 'Test_link_class'
136
+ TestBase = r.create_class 'Test_base_class'
178
137
 
179
- link_document = TestLink.create att: 'one attribute'
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, a simple Array is allocated
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
- TestLink.create_property :links, type: :linklist, linkedClass: :test_links
193
- base_document = TestBase.create links: []
194
- (0 .. 20).each{|y| base_document.links << TestLink.create( nr: y )}
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 = TestBase.create links: (0..20).map{|y| TestLink.create nr: y}
198
- base_document.update
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 graph elements can be explored by joining the objects (a[6].b[5].c[9].d)
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
- Edges provide bidirectional Links. They are easily handled
167
+
168
+ Edges are easily handled
212
169
  ```ruby
213
- ORD.create_vertex_class :the_vertex # --> TheVertex
214
- ORD.create_edge_class :the_edge # --> TheEdge
170
+ Vertex = r.create_vertex_class 'd1'
171
+ Eedge = r.create_edge_class 'e1'
215
172
 
216
- start = TheVertex.create something: 'nice'
217
- the_end = TheVertex.create something: 'not_nice'
218
- the_edge = TheEdge.create attributes: {transform_to: 'very bad'},
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
- i.e.
226
- ```ruby
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.edges # :in | :out | :all
239
- => ["#73:0"]
240
-
241
- start.edges(:out).map &:from_orient
242
- => [#<TOP_EDGE:0x00000001d92f28 @metadata= ... ]
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
- record1 = (1 .. 100).map{|y| Vertex1.create testentry: y }
251
- record2 = (:a .. :z).map{|y| Vertex2.create testentry: y }
252
- edges = TheEdge.create attributes: { study: 'Experiment1'} do | attributes |
253
- # map returns an array, which is further processed by #create_edge
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
- Contrary to traditional SQL-based Databases OrientDB handles sub-queries very efficiently. In addition, OrientDB supports precompiled statements (let-Blocks).
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 # If a constant is used, then the correspending
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 = {:name => :asc}
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
- Both eayss can be mixed.
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
- OQ = OrientSupport::OrientQuery
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
- # => select from ModelQuery let $city = adress.city where $city.country.name = 'Italy' OR $city.country.name = 'France'
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 = OQ.new
309
- q.let << {a: OQ.new( from: '#5:0' ) }
310
- q.let << {b: OQ.new( from: '#5:1' ) }
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 # => select expand( $c ) let $a = ( select from #5:0 ), $b = ( select from #5:1 ), $c= UNIONALL($a,$b)
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
- cq = ORD.get_documents query: distinct_contracts
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
- A Match-Query starts at the given ActiveOrient::Model-Class. The where-cause narrows the sample to certain
335
- records. In the simplest version this can be returned:
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
- ORD.create_class :Industry
339
- Industry.match where:{ name: "Communications" }
340
- => #<Query:0x00000004309608 @metadata={"type"=>"d", "class"=>nil, "version"=>0, "fieldTypes"=>"Industries=x"}, @attributes={"Industries"=>"#21:1", (...)}>
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
- The attributes are the return-Values of the Match-Query. Unless otherwise noted, the pluralized Model-Classname is used as attribute in the result-set. *Note* that the Match statement returns a »Query«-record. Its up to the usere, to transform the attributes to Model-Objects. This is done by the »to_orient« directive, ie. »xx.Industries.to_orient «
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
- Industry.match where name: "Communications"
347
- ## is equal to
348
- Industry.match( where: { name: 'Communications' }).first.Industries
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
- var = Industry.match( where: { name: 'Communications'}) do | query |
356
- query.connect :in, count: 2, as: 'Subcategories'
357
- puts query.to_s # print the query prior sending it to the database
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
- The result-set has two attributes: Industries and Subcategories, pointing to the filtered datasets.
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
- deactivated behavior: to turn it on, some work on base.rb is required
379
- ```
380
- start.the_edge # --> Array of "TheEdge"-instances connected to the vertex
381
- start.the_edge.where transform_to: 'good' # -> empty array
382
- start.the_edge.where transform_to: 'very bad' #--> previously connectd edge
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
+