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
data/examples/test_commands_3.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
require 'awesome_print'
|
2
|
-
require_relative "../lib/active-orient.rb"
|
3
|
-
|
4
|
-
# Start server
|
5
|
-
ActiveOrient::OrientDB.default_server= { user: 'root', password: 'tretretre' }
|
6
|
-
|
7
|
-
# Select database
|
8
|
-
r = ActiveOrient::OrientDB.new database: 'NewTest'
|
9
|
-
|
10
|
-
doc1 = r.create_class "DocumentTest"
|
11
|
-
ver1 = r.create_vertex_class "VertexTest"
|
12
|
-
a = doc1.create name: "Doc1"
|
13
|
-
v = ver1.create name: "Ver"
|
14
|
-
|
15
|
-
out = doc1.orientdb_class name: "Doc2345" # Used to instantiate an ActiveOrient Model
|
16
|
-
print "1 #{out} \n"
|
17
|
-
|
18
|
-
out = ver1.autoload_object "16:35" # Used to get a record by rid
|
19
|
-
print "2 #{out} \n"
|
20
|
-
|
21
|
-
print "3 #{ver1.superClass} \n" # Check superClass of the class
|
22
|
-
|
23
|
-
print "4 #{v.class} \n"
|
24
|
-
|
25
|
-
print "5 #{doc1} \n"
|
26
|
-
|
27
|
-
print "6 #{a} \n"
|
28
|
-
|
29
|
-
print "7 #{v} \n"
|
30
|
-
|
31
|
-
a = v.classname # Class of v
|
32
|
-
print "8 #{a} \n"
|
33
|
-
|
34
|
-
a = v.rid
|
35
|
-
print "9 #{a} \n" # RID of v
|
36
|
-
|
37
|
-
a = ver1.count where: {name: "Ver"}
|
38
|
-
print "10 #{a} \n"
|
39
|
-
|
40
|
-
print "11 #{v.to_human} \n" # Human version
|
41
|
-
|
42
|
-
print "12 #{v.content_attributes} \n" # Return attributes
|
43
|
-
|
44
|
-
print "13 #{v.default_attributes} \n" # Return created and updated
|
45
|
-
|
46
|
-
print "14 #{v.set_attribute_defaults} \n" # Set up
|
47
|
-
|
48
|
-
print "15 #{v.metadata} \n" # Set up
|
data/examples/test_commands_4.rb
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
require_relative "../lib/active-orient.rb"
|
2
|
-
|
3
|
-
ActiveOrient::OrientDB.default_server = { user: 'root', password: 'tretretre' }
|
4
|
-
r = ActiveOrient::OrientDB.new database: 'NewTest'
|
5
|
-
|
6
|
-
doc1 = r.open_class "DocumentTest" # Create Document/Vertex/Edge class
|
7
|
-
doc2 = r.open_class "DocumentArrive_Test"
|
8
|
-
doc1.create_property :familyname, type: :string
|
9
|
-
doc1.create_property :family, type: :linkset, other_class: "DocumentTest"
|
10
|
-
|
11
|
-
a1 = doc1.create name: "DocA", value: 34
|
12
|
-
a2 = doc1.create name: "DocB", value: 34
|
13
|
-
a3 = doc1.create name: "DocC", value: 34
|
14
|
-
a4 = doc1.create name: "DocD", value: 30
|
15
|
-
doc1.create name: "DocE", value: 30
|
16
|
-
doc1.create name: "DocF", value: 30
|
17
|
-
|
18
|
-
print "#{a1.ciao} \n"
|
19
|
-
a1.family = [a2, a3]
|
20
|
-
print "#{a1["family"].name} \n"
|
21
|
-
print "---> #{a1.family.class}\n"
|
22
|
-
a1["family"] << a4
|
23
|
-
print "#{a1.family.name} \n"
|
24
|
-
|
25
|
-
|
26
|
-
# ActiveOrient::OrientDB.methods.each do |m|
|
27
|
-
# print "#{m} \n"
|
28
|
-
# end
|
data/examples/time_graph.md
DELETED
@@ -1,162 +0,0 @@
|
|
1
|
-
The Time-Graph Example is outsourced and lives as a seperate gem.
|
2
|
-
|
3
|
-
https://github.com/topofocus/orientdb_time_graph
|
4
|
-
|
5
|
-
from the readme:
|
6
|
-
|
7
|
-
# Time Graph
|
8
|
-
|
9
|
-
Simple Time Graph using ActiveOrient/OrientDB.
|
10
|
-
|
11
|
-
*Prerequisites* :
|
12
|
-
* Install and setup OrientDB
|
13
|
-
* Run "Bundle install" and "Bundle update"
|
14
|
-
* customize config/connect.yml
|
15
|
-
|
16
|
-
**or** start a new project and include the gem in the usual manner.
|
17
|
-
|
18
|
-
To play around, start the console by
|
19
|
-
```
|
20
|
-
cd bin
|
21
|
-
./active-orient-console t # test-modus
|
22
|
-
```
|
23
|
-
The Database is automatically initialized and the following hierarchy is build:
|
24
|
-
|
25
|
-
```ruby
|
26
|
-
- E # ruby-class
|
27
|
-
- - month_of TG::MONTH_OF
|
28
|
-
- - day_of TG::DAY_OF
|
29
|
-
- - time_of TG::TIME_OF
|
30
|
-
- - grid_of TG::GRID_OF
|
31
|
-
- V
|
32
|
-
- - time_base TG::TimeBase
|
33
|
-
- - - jahr TG::Jahr
|
34
|
-
- - - monat TG::Monat
|
35
|
-
- - - stunde TG::Stunde
|
36
|
-
- - - tag TG::Tag
|
37
|
-
```
|
38
|
-
This Graph is realized
|
39
|
-
|
40
|
-
```ruby
|
41
|
-
Jahr -- [Month_of] -- Monat --[DAY_OF]-- Tag --[TIME_OF]-- Stunde
|
42
|
-
```
|
43
|
-
and populated by calling
|
44
|
-
|
45
|
-
```ruby
|
46
|
-
TG::TimeGraph.populate( a single year or a range ) # default: 1900 .. 2050
|
47
|
-
```
|
48
|
-
If only one year is specified, a Monat--Tag--Stunde-Grid is build, otherwise a Jahr--Monat--Tag one.
|
49
|
-
You can check the Status by calling
|
50
|
-
|
51
|
-
```ruby
|
52
|
-
TG::TimeGraph.populate 2000 -2003
|
53
|
-
TG.info
|
54
|
-
-------------- TIME GRAPH ------------------
|
55
|
-
Allocated Years :
|
56
|
-
2000; 2001; 2002; 2003
|
57
|
-
|
58
|
-
```
|
59
|
-
In the Model-directory, customized methods simplify the usage of the graph.
|
60
|
-
|
61
|
-
Some Examples:
|
62
|
-
Assuming, you build a standard day-based grid
|
63
|
-
|
64
|
-
```ruby
|
65
|
-
|
66
|
-
include TG # we can omit the TG prefix
|
67
|
-
|
68
|
-
Jahr[2000] # --> returns a single object
|
69
|
-
=> #<TG::Jahr:0x00000004ced160 @metadata={"type"=>"d", "class"=>"jahr", "version"=>13, "fieldTypes"=>"out_month_of=g", "cluster"=>34, "record"=>101}, @d=nil, @attributes={"value"=>2000, "out_month_of"=>["#53:1209", "#54:1209", "#55:1209", "#56:1209", "#53:1210", "#54:1210", "#55:1210", "#56:1210", "#53:1211", "#54:1211", "#55:1211", "#56:1211"], "created_at"=>Fri, 09 Sep 2016 10:14:30 +0200}>
|
70
|
-
|
71
|
-
|
72
|
-
Jahr[2000 .. 2005].value # returns an array
|
73
|
-
=> [2003, 2000, 2004, 2001, 2005, 2002]
|
74
|
-
|
75
|
-
Jahr[2000 .. 2005].monat(5..7).value # returns the result of the month-attribute (or method)
|
76
|
-
=> [[5, 6, 7], [5, 6, 7], [5, 6, 7], [5, 6, 7], [5, 6, 7], [5, 6, 7]]
|
77
|
-
|
78
|
-
Jahr[2000].monat(4, 7).tag(4, 15,24 ).datum # adresses methods or attributes of the specified day's
|
79
|
-
=> [["4.4.2000", "15.4.2000", "24.4.2000"], ["4.7.2000", "15.7.2000", "24.7.2000"]]
|
80
|
-
## unfortunatly »Jahr[2000 .. 2015].monat( 3,5 ).tag( 4 ..6 ).datum « does not fits now
|
81
|
-
## instead »Jahr[2000..2015].map{|y| y.monat( 3,5 ).tag( 4 ..6 ).datum } « does the job.
|
82
|
-
```
|
83
|
-
|
84
|
-
To filter datasets in that way, anything represented is queried from the database. In contrast to
|
85
|
-
a pure ruby implementation, this works for small and large grid's.
|
86
|
-
|
87
|
-
Obviously, you can do neat ruby-array playings, which are limited to the usual sizes.
|
88
|
-
For example. As »TAG[31]« returns an array, the elements can be treated with ruby flavour:
|
89
|
-
|
90
|
-
```ruby
|
91
|
-
|
92
|
-
Tag[31][2..4].datum # display three months with 31 days
|
93
|
-
=> ["31.10.1901", "31.1.1902", "31.5.1902"]
|
94
|
-
|
95
|
-
```
|
96
|
-
First all Tag-Objects with the Value 31 are queried. This gives »Jan, Mar, May ..«. Then one can inspect the array, in this case by slicing a range.
|
97
|
-
|
98
|
-
Not surprisingly, the first occurence of the day is not the earliest date in the grid. Its just the first one,
|
99
|
-
fetched from the database.
|
100
|
-
|
101
|
-
``` ruby
|
102
|
-
Tag[1][1].datum
|
103
|
-
=> "1.5.1900" # Tag[1][0] correctly fetches "1.1.1900"
|
104
|
-
Tag[1].last.datum
|
105
|
-
=> "1.11.2050"
|
106
|
-
## however,
|
107
|
-
Jahr[2050].monat(12).tag(1) # exists:
|
108
|
-
=> [["1.12.2050"]]
|
109
|
-
```
|
110
|
-
|
111
|
-
## Horizontal Connections
|
112
|
-
|
113
|
-
Besides the hierarchically TimeGraph »Jahr <-->Monat <--> Tag <--> Stunde« the Vertices are connected
|
114
|
-
horizontally via »grid_to«-Edges. This enables an easy access to the neighbours.
|
115
|
-
|
116
|
-
On the TG::TimeBase-Level a method »environment« is implemented, that gathers the adjacent vertices
|
117
|
-
via traverse.
|
118
|
-
|
119
|
-
``` ruby
|
120
|
-
start = TG::Jahr[2000].monat(4).tag(7).first.first
|
121
|
-
start.environment(3).datum
|
122
|
-
=> ["4.4.2000", "5.4.2000", "6.4.2000", "7.4.2000", "8.4.2000", "9.4.2000", "10.4.2000"]
|
123
|
-
|
124
|
-
2.3.1 :003 > start.environment(3,4).datum
|
125
|
-
=> ["4.4.2000", "5.4.2000", "6.4.2000", "7.4.2000", "8.4.2000", "9.4.2000", "10.4.2000", "11.4.2000"]
|
126
|
-
|
127
|
-
start.environment(0,3).datum
|
128
|
-
=> ["7.4.2000", "8.4.2000", "9.4.2000", "10.4.2000"]
|
129
|
-
```
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
## Diary
|
134
|
-
|
135
|
-
lets create a simple diary
|
136
|
-
|
137
|
-
```ruby
|
138
|
-
include TG
|
139
|
-
TimeiGraph.populate 2016
|
140
|
-
ORD.create_vertex_class :termin
|
141
|
-
=> Termin
|
142
|
-
ORD.create_edge_class :date_of
|
143
|
-
=> DATE_OF
|
144
|
-
DATE_OF.uniq_index # put contrains to the edge-class, accept only one entry per item
|
145
|
-
|
146
|
-
DATE_OF.create from: Monat[8].tag(9).stunde(12),
|
147
|
-
to: Termin.create( short: 'Mittagessen',
|
148
|
-
long: 'Schweinshaxen essen mit Lieschen Müller',
|
149
|
-
location: 'Hofbauhaus, München' )
|
150
|
-
=> #<DATE_OF:0x0000000334e038 (..) @attributes={"out"=>"#21:57", "in"=>"#41:0", (..)}>
|
151
|
-
# create some regular events
|
152
|
-
# attach breakfirst at 9 o clock from the 10th to the 21st Day in the current month
|
153
|
-
DATE_OF.create from: Monat[8].tag(10 .. 21).stunde( 9 ), to: Termin.create( :short => 'Frühstück' )
|
154
|
-
=> #<DATE_OF:0x000000028d5688 @metadata={(..) "cluster"=>45, "record"=>8},
|
155
|
-
@attributes={"out"=>"#22:188", "in"=>"#42:0",(..)}>
|
156
|
-
|
157
|
-
t = Termin.where short: 'Frühstück'
|
158
|
-
t.in_date_of.out.first.datum
|
159
|
-
=> ["10.8.2016 9:00", "11.8.2016 9:00", "12.8.2016 9:00", "13.8.2016 9:00", "14.8.2016 9:00", "15.8.2016 9:00", "16.8.2016 9:00", "17.8.2016 9:00", "18.8.2016 9:00", "19.8.2016 9:00", "20.8.2016 9:00", "21.8.2016 9:00"]
|
160
|
-
|
161
|
-
```
|
162
|
-
|
data/gratefuldeadconcerts.md
DELETED
@@ -1,94 +0,0 @@
|
|
1
|
-
# Experiments with the GratefuldDeadConcterts database
|
2
|
-
|
3
|
-
First modify the database-entry (development) in /config/connect.yml to «GreatfulDeadConerts».
|
4
|
-
This should be present after the installation of the database
|
5
|
-
Then execute « ./bin/active-orient-console d »
|
6
|
-
```
|
7
|
-
Present Classes (Hierarchy)
|
8
|
-
---
|
9
|
-
- - E
|
10
|
-
- - followed_by
|
11
|
-
- sung_by
|
12
|
-
- written_by
|
13
|
-
- V
|
14
|
-
|
15
|
-
Active Classes -> ActiveOrient ClassName
|
16
|
-
---------------------------------------------
|
17
|
-
V -> V
|
18
|
-
E -> E
|
19
|
-
followed_by -> FollowedBy
|
20
|
-
sung_by -> SungBy
|
21
|
-
written_by -> WrittenBy
|
22
|
-
---------------------------------------------
|
23
|
-
```
|
24
|
-
|
25
|
-
Lets start with simple queries
|
26
|
-
|
27
|
-
* Select all vertices (or object) in the database
|
28
|
-
|
29
|
-
```ruby
|
30
|
-
V.all
|
31
|
-
```
|
32
|
-
|
33
|
-
* Select the vertex with the id #9:8
|
34
|
-
```ruby
|
35
|
-
V.autoload_object '#9:8'
|
36
|
-
```
|
37
|
-
|
38
|
-
* Select all the artists
|
39
|
-
|
40
|
-
```ruby
|
41
|
-
V.where type: 'artist'
|
42
|
-
```
|
43
|
-
|
44
|
-
* Select all the songs that have been performed 10 times
|
45
|
-
|
46
|
-
Display songnames and authors
|
47
|
-
|
48
|
-
|
49
|
-
```ruby
|
50
|
-
song_10 = V.where type: 'song', performances: 10
|
51
|
-
song_10.name
|
52
|
-
=> ["TOMORROW IS FOREVER", "SHE BELONGS TO ME", "UNBROKEN CHAIN"]
|
53
|
-
song_10.out_written_by.in.name
|
54
|
-
=> [["Dolly_Parton"], ["Bob_Dylan"], ["Petersen"]]
|
55
|
-
```
|
56
|
-
* Select all the songs that have been performed more or less 10 times
|
57
|
-
|
58
|
-
```ruby
|
59
|
-
V.where "type = 'song’ and performances > 10"
|
60
|
-
V.where "type = 'song’ and performances < 10"
|
61
|
-
```
|
62
|
-
* Count all songs and artists
|
63
|
-
|
64
|
-
```ruby
|
65
|
-
V.count where: { type: 'song' }
|
66
|
-
V.count where: { type: 'song', performances: 10 }
|
67
|
-
|
68
|
-
V.count where: { type: 'artist' }
|
69
|
-
```
|
70
|
-
|
71
|
-
|
72
|
-
* Find all songs sung by the first artist
|
73
|
-
|
74
|
-
First get the artist
|
75
|
-
```ruby
|
76
|
-
first_artist = OrientSupport::OrientQuery.new from: artist_vertex, where: { type: 'artist'} , limit: 1
|
77
|
-
first_artist.to_s => "select from V where type = 'artist' limit 1"
|
78
|
-
```
|
79
|
-
Traverse through the database. List any song and author that is sung by this artist
|
80
|
-
|
81
|
-
```ruby
|
82
|
-
songs = DB.execute{ "select expand(set(in('sung_by'))) from (#{first_artist.to_s}) " }
|
83
|
-
songs.name
|
84
|
-
==> ["ROSA LEE MCFALL", "ROW JIMMY", "THAT WOULD BE SOMETHING", "BETTY AND DUPREE", "WHISKEY IN THE JAR", ...]
|
85
|
-
|
86
|
-
authors = DB.execute{ "select expand(set(in('sung_by').out('written_by'))) from (#{first_artist.to_s}) " }
|
87
|
-
authors.name
|
88
|
-
==> ["Bob_Dylan", "Chuck_Berry", "Unknown", "Bernie_Casey_Pinkard", ...]
|
89
|
-
|
90
|
-
```
|
91
|
-
|
92
|
-
go [Back](./README.md) to the introduction page
|
93
|
-
|
94
|
-
|
data/lib/class_utils.rb
DELETED
@@ -1,300 +0,0 @@
|
|
1
|
-
module ClassUtils
|
2
|
-
# ClassUitils is included in Rest- and Java-Api-classes
|
3
|
-
|
4
|
-
=begin
|
5
|
-
Returns a valid database-class name, nil if the class does not exists
|
6
|
-
=end
|
7
|
-
|
8
|
-
def classname name_or_class # :nodoc:
|
9
|
-
name = case name_or_class
|
10
|
-
when ActiveOrient::Model
|
11
|
-
name_or_class.class.ref_name
|
12
|
-
when Class
|
13
|
-
name_or_class.ref_name
|
14
|
-
# name_or_class.to_s.split('::').last
|
15
|
-
else
|
16
|
-
name_or_class.to_s.split(':').last #.to_s.camelcase # capitalize_first_letter
|
17
|
-
end
|
18
|
-
## 16/5/31 : reintegrating functionality to check wether the classname is
|
19
|
-
# present in the database or not
|
20
|
-
if database_classes.include?(name)
|
21
|
-
name
|
22
|
-
elsif database_classes.include?(name.underscore)
|
23
|
-
name.underscore
|
24
|
-
else
|
25
|
-
logger.progname = 'ClassUtils#Classname'
|
26
|
-
logger.warn{ "Classname #{name_or_class.inspect} ://: #{name} not present in #{ActiveOrient.database}" }
|
27
|
-
nil
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
31
|
-
=begin
|
32
|
-
create a single class and provide properties as well
|
33
|
-
|
34
|
-
ORB.create_class( the_class_name as String or Symbol (nessesary) ,
|
35
|
-
properties: a Hash with property- and Index-descriptions (optional)){
|
36
|
-
{superclass: The name of the superclass as String or Symbol ,
|
37
|
-
abstract: true|false } (optional Block provides a Hash ) }
|
38
|
-
|
39
|
-
=end
|
40
|
-
def create_class classname, properties: nil, &b
|
41
|
-
the_class= create_classes( classname, &b )
|
42
|
-
# if multible classes are specified, don't process properties
|
43
|
-
# ( if multible classes need the same properties, consider a nested class-design )
|
44
|
-
if the_class.is_a?(Array)
|
45
|
-
if the_class.size == 1
|
46
|
-
the_class = the_class.first
|
47
|
-
else
|
48
|
-
properties = nil
|
49
|
-
end
|
50
|
-
end
|
51
|
-
create_properties( the_class.ref_name , properties ) if properties.present?
|
52
|
-
the_class # return_value
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
=begin
|
57
|
-
AllocateClassesInRuby acts as a proxy to OrientdbClass,
|
58
|
-
takes a classes-array as argument
|
59
|
-
=end
|
60
|
-
def allocate_classes_in_ruby classes # :nodoc:
|
61
|
-
generate_ruby_object = ->( name, superclass, abstract ) do
|
62
|
-
begin
|
63
|
-
# if the class is predefined, use specs from get_classes
|
64
|
-
or_def = get_classes('name', 'superClass', 'abstract' ).detect{|x| x['name']== name.to_s }
|
65
|
-
superclass, abstract = or_def.reject{|k,v| k=='name'}.values unless or_def.nil?
|
66
|
-
#print "GENERATE_RUBY_CLASS: #{name} / #{superclass} \n"
|
67
|
-
m= ActiveOrient::Model.orientdb_class name: name, superclass: superclass
|
68
|
-
m.abstract = abstract
|
69
|
-
m.ref_name = name.to_s
|
70
|
-
#puts "--> #{m.object_id}"
|
71
|
-
m
|
72
|
-
rescue NoMethodError => w
|
73
|
-
logger.progname = "ClassUtils#AllocateClassesInRuby"
|
74
|
-
logger.error{ w.message }
|
75
|
-
logger.error{ w.backtrace.map {|l| " #{l}\n"}.join }
|
76
|
-
nil
|
77
|
-
# raise
|
78
|
-
end
|
79
|
-
|
80
|
-
end
|
81
|
-
|
82
|
-
superclass, abstract = if block_given?
|
83
|
-
s = yield
|
84
|
-
if s.is_a? Hash
|
85
|
-
[s[:superclass],s[:abstract]]
|
86
|
-
else
|
87
|
-
[s,false]
|
88
|
-
end
|
89
|
-
else
|
90
|
-
[nil,false]
|
91
|
-
end
|
92
|
-
#superclass_object = generate_ruby_object[superclass,nil,nil] if superclass.present?
|
93
|
-
|
94
|
-
consts = case classes
|
95
|
-
when Array
|
96
|
-
next_superclass= superclass
|
97
|
-
classes.map do |singleclass|
|
98
|
-
if singleclass.is_a?( String) || singleclass.is_a?( Symbol)
|
99
|
-
next_superclass = generate_ruby_object[singleclass,superclass,abstract]
|
100
|
-
elsif singleclass.is_a?(Array) || singleclass.is_a?(Hash)
|
101
|
-
allocate_classes_in_ruby( singleclass){ {superclass: next_superclass, abstract: abstract}}
|
102
|
-
end
|
103
|
-
end
|
104
|
-
when Hash
|
105
|
-
classes.keys.map do| h_superclass |
|
106
|
-
[ generate_ruby_object[h_superclass,superclass,abstract],
|
107
|
-
allocate_classes_in_ruby(classes[ h_superclass ]){{ superclass: h_superclass, abstract: abstract }} ]
|
108
|
-
end
|
109
|
-
when String, Symbol
|
110
|
-
generate_ruby_object[classes,superclass, abstract]
|
111
|
-
end
|
112
|
-
consts
|
113
|
-
end
|
114
|
-
=begin
|
115
|
-
Creating a new Database-Entry (where is omitted)
|
116
|
-
Or updating the Database-Entry (if present)
|
117
|
-
|
118
|
-
The optional Block should provide a hash with attributes (properties). These are used if a new dataset is created.
|
119
|
-
Based on the query specified in :where records are updated according to :set
|
120
|
-
|
121
|
-
Returns an Array of updated documents
|
122
|
-
=end
|
123
|
-
|
124
|
-
def update_or_create_records o_class, set: {}, where: {}, **args, &b
|
125
|
-
logger.progname = 'ClassUtils#UpdateOrCreateRecords'
|
126
|
-
if where.blank?
|
127
|
-
[create_record(o_class, attributes: set)]
|
128
|
-
else
|
129
|
-
set.extract!(where.keys) if where.is_a?(Hash) # removes any keys from where in set
|
130
|
-
possible_records = get_records from: classname(o_class), where: where, **args
|
131
|
-
if possible_records.empty?
|
132
|
-
if block_given?
|
133
|
-
more_where = yield # do Preparations prior to the creation of the dataset
|
134
|
-
# if the block returns a Hash, it is merged into the insert_query.
|
135
|
-
where.merge! more_where if more_where.is_a?(Hash)
|
136
|
-
end
|
137
|
-
[create_record(o_class, attributes: set.merge(where))]
|
138
|
-
else
|
139
|
-
possible_records.map{|doc| doc.update(set: set)} unless set.empty?
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
=begin
|
146
|
-
create_edge connects two vertexes
|
147
|
-
|
148
|
-
The parameter o_class can be either a class or a string
|
149
|
-
|
150
|
-
if batch is specified, the edge-statement is prepared and returned
|
151
|
-
else the statement is transmitted to the database
|
152
|
-
|
153
|
-
The method takes a block as well.
|
154
|
-
It must provide a Hash with :from and :to- Key's, e.g.
|
155
|
-
Vertex1, Vertex2 are two vertex-classes and TheEdge is an edge-class
|
156
|
-
|
157
|
-
record1 = ( 1 .. 100 ).map{ |y| Vertex1.create( testentry: y } }
|
158
|
-
record2 = ( :a .. :z ).map{ |y| Vertex2.create( testentry: y } }
|
159
|
-
|
160
|
-
edges = ORD.create_edge( TheEdge ) do | attributes |
|
161
|
-
('a'.ord .. 'z'.ord).map do |o|
|
162
|
-
{ from: record1.find{|x| x.testentry == o },
|
163
|
-
to: record2.find{ |x| x.testentry.ord == o },
|
164
|
-
attributes: attributes.merge{ key: o.chr } }
|
165
|
-
end
|
166
|
-
or
|
167
|
-
|
168
|
-
edges = ORD.create_edge( TheEdge ) do | attributes |
|
169
|
-
('a'.ord .. 'z'.ord).map do |o|
|
170
|
-
{ from: Vertex1.where( testentry: o ).pop ,
|
171
|
-
to: Vertex2.where( testentry.ord => o).pop ,
|
172
|
-
attributes: attributes.merge{ key: o.chr } }
|
173
|
-
end
|
174
|
-
|
175
|
-
Benefits: The statements are transmitted as batch.
|
176
|
-
|
177
|
-
The pure-ruby-solution minimizes traffic to the database-server and is prefered.
|
178
|
-
|
179
|
-
=end
|
180
|
-
def create_edge o_class, attributes: {}, from:nil, to:nil, unique: false, batch: nil
|
181
|
-
logger.progname = "ClassUtils#CreateEdge"
|
182
|
-
|
183
|
-
# -------------------------------
|
184
|
-
create_command = -> (attr, from, to ) do
|
185
|
-
attr_string = attr.blank? ? "" : "SET #{generate_sql_list attr}"
|
186
|
-
if from.present? && to.present?
|
187
|
-
[from, to].each{|y| remove_record_from_hash y }
|
188
|
-
{ type: "cmd",
|
189
|
-
language: 'sql',
|
190
|
-
command: "CREATE EDGE #{classname(o_class)} FROM #{from.to_orient} TO #{to.to_orient} #{attr_string}"
|
191
|
-
}
|
192
|
-
end
|
193
|
-
end
|
194
|
-
# -------------------------------
|
195
|
-
|
196
|
-
if block_given?
|
197
|
-
a = yield(attributes)
|
198
|
-
command = if a.is_a? Array
|
199
|
-
batch = nil
|
200
|
-
command= a.map do | record |
|
201
|
-
# puts record.inspect
|
202
|
-
this_attributes = record[:attributes].presence || attributes
|
203
|
-
create_command[ this_attributes, record[:from], record[:to]]
|
204
|
-
end
|
205
|
-
else
|
206
|
-
this_attributes = a[:attributes].presence || attributes
|
207
|
-
command = create_command[ this_attributes, a[:from], a[:to]]
|
208
|
-
end
|
209
|
-
elsif from.is_a?( Array ) && to.is_a?(Array)
|
210
|
-
command = Array.new
|
211
|
-
while from.size >1
|
212
|
-
this_attributes = attributes.is_a?(Array) ? attributes.shift : attributes
|
213
|
-
command << create_command[ this_attributes, from.shift, to.shift]
|
214
|
-
end
|
215
|
-
elsif from.is_a? Array
|
216
|
-
command = from.map{|f| create_command[ attributes, f, to] }
|
217
|
-
elsif to.is_a? Array
|
218
|
-
command = to.map{|f| create_command[ attributes, from, f] }
|
219
|
-
# puts "COMMAND: #{command.inspect}"
|
220
|
-
elsif from.present? && to.present?
|
221
|
-
# if unique
|
222
|
-
# wwhere = {out: from.to_orient, in: to.to_orient }.merge(attributes.to_orient)
|
223
|
-
# existing_edge = get_records(from: o_class, where: wwhere)
|
224
|
-
# if existing_edge.size >1
|
225
|
-
# logger.error{ "Unique specified, but there are #{existing_edge.size} Records in the Database. returning the first"}
|
226
|
-
# command = existing_edge.first
|
227
|
-
# batch = true
|
228
|
-
# elsif existing_edge.size ==1 && existing_edge.first.is_a?(ActiveOrient::Model)
|
229
|
-
# #logger.debug {"Reusing edge #{classname(o_class)} from #{from.to_orient} to #{to.to_orient}"}
|
230
|
-
# command= existing_edge.first
|
231
|
-
# batch= true
|
232
|
-
# else
|
233
|
-
command = create_command[ attributes, from, to]
|
234
|
-
# end
|
235
|
-
# #logger.debug {"Creating edge #{classname(o_class)} from #{from.to_orient} to #{to.to_orient}"}
|
236
|
-
#
|
237
|
-
elsif from.to_orient.nil? || to.to_orient.nil?
|
238
|
-
logger.error{ "Parameter :from or :to is missing"}
|
239
|
-
else
|
240
|
-
# for or to are not set
|
241
|
-
return nil
|
242
|
-
end
|
243
|
-
# puts "RUNNING EDGE: #{command.inspect}"
|
244
|
-
if command.present?
|
245
|
-
begin
|
246
|
-
response = execute(transaction: false, tolerated_error_code: /found duplicated key/) do
|
247
|
-
command.is_a?(Array) ? command.flatten.compact : [ command ]
|
248
|
-
end
|
249
|
-
if response.is_a?(Array) && response.size == 1
|
250
|
-
response.pop # RETURN_VALUE
|
251
|
-
else
|
252
|
-
response # return value (the normal case)
|
253
|
-
end
|
254
|
-
rescue ArgumentError => e
|
255
|
-
puts "ArgumentError "
|
256
|
-
puts e.inspect
|
257
|
-
end # begin
|
258
|
-
end
|
259
|
-
|
260
|
-
end
|
261
|
-
=begin
|
262
|
-
Deletes the specified vertices and unloads referenced edges from the cache
|
263
|
-
=end
|
264
|
-
def delete_vertex *vertex
|
265
|
-
create_command = -> do
|
266
|
-
{ type: "cmd",
|
267
|
-
language: 'sql',
|
268
|
-
command: "DELETE VERTEX #{vertex.map{|x| x.to_orient }.join(',')} "
|
269
|
-
}
|
270
|
-
end
|
271
|
-
|
272
|
-
vertex.each{|v| v.edges.each{| e | remove_record_from_hash e} }
|
273
|
-
execute{ create_command[] }
|
274
|
-
end
|
275
|
-
|
276
|
-
=begin
|
277
|
-
Deletes the specified edges and unloads referenced vertices from the cache
|
278
|
-
=end
|
279
|
-
def delete_edge *edge
|
280
|
-
create_command = -> do
|
281
|
-
{ type: "cmd",
|
282
|
-
language: 'sql',
|
283
|
-
command: "DELETE EDGE #{edge.map{|x| x.to_orient }.join(',')} "
|
284
|
-
}
|
285
|
-
end
|
286
|
-
|
287
|
-
edge.each do |r|
|
288
|
-
[r.in, r.out].each{| e | remove_record_from_hash e}
|
289
|
-
remove_record_from_hash r
|
290
|
-
end
|
291
|
-
execute{ create_command[] }
|
292
|
-
end
|
293
|
-
|
294
|
-
private
|
295
|
-
def remove_record_from_hash r
|
296
|
-
obj= ActiveOrient::Base.get_rid(r.rid) unless r.nil?
|
297
|
-
ActiveOrient::Base.remove_rid( obj ) unless obj.nil?
|
298
|
-
end
|
299
|
-
|
300
|
-
end # module
|