active-orient 0.4 → 0.5
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 +1 -0
- data/Gemfile +8 -3
- data/Guardfile +12 -4
- data/README.md +221 -201
- data/VERSION +1 -1
- data/active-orient.gemspec +3 -2
- data/bin/active-orient-console +35 -0
- data/config/boot.rb +84 -16
- data/config/config.yml +10 -0
- data/config/connect.yml +6 -2
- data/create_project +19 -0
- data/examples/books.rb +86 -39
- data/examples/createTime.rb +91 -0
- data/examples/streets.rb +85 -84
- data/examples/test_commands.rb +92 -0
- data/examples/test_commands_2.rb +54 -0
- data/examples/test_commands_3.rb +48 -0
- data/examples/test_commands_4.rb +28 -0
- data/examples/time_graph/Gemfile +21 -0
- data/examples/time_graph/Guardfile +26 -0
- data/examples/time_graph/README.md +129 -0
- data/examples/time_graph/bin/active-orient-console +35 -0
- data/examples/time_graph/config/boot.rb +119 -0
- data/examples/time_graph/config/config.yml +8 -0
- data/examples/time_graph/config/connect.yml +17 -0
- data/examples/time_graph/config/init_db.rb +59 -0
- data/examples/time_graph/createTime.rb +51 -0
- data/examples/time_graph/lib/createTime.rb +82 -0
- data/examples/time_graph/model/day_of.rb +3 -0
- data/examples/time_graph/model/e.rb +6 -0
- data/examples/time_graph/model/edge.rb +53 -0
- data/examples/time_graph/model/monat.rb +19 -0
- data/examples/time_graph/model/stunde.rb +16 -0
- data/examples/time_graph/model/tag.rb +29 -0
- data/examples/time_graph/model/time_base.rb +6 -0
- data/examples/time_graph/model/time_of.rb +4 -0
- data/examples/time_graph/model/v.rb +3 -0
- data/examples/time_graph/model/vertex.rb +32 -0
- data/examples/time_graph/spec/lib/create_time_spec.rb +50 -0
- data/examples/time_graph/spec/rest_helper.rb +37 -0
- data/examples/time_graph/spec/spec_helper.rb +46 -0
- data/lib/active-orient.rb +56 -6
- data/lib/base.rb +149 -147
- data/lib/base_properties.rb +40 -41
- data/lib/class_utils.rb +301 -0
- data/lib/database_utils.rb +97 -0
- data/lib/init.rb +35 -0
- data/lib/java-api.rb +437 -0
- data/lib/jdbc.rb +211 -0
- data/lib/model/edge.rb +53 -0
- data/lib/model/model.rb +77 -0
- data/lib/model/the_class.rb +480 -0
- data/lib/model/the_record.rb +310 -0
- data/lib/model/vertex.rb +32 -0
- data/lib/orient.rb +113 -50
- data/lib/orientdb_private.rb +48 -0
- data/lib/other.rb +280 -0
- data/lib/query.rb +71 -73
- data/lib/rest/change.rb +124 -0
- data/lib/rest/create.rb +474 -0
- data/lib/rest/delete.rb +133 -0
- data/lib/rest/operations.rb +150 -0
- data/lib/rest/read.rb +150 -0
- data/lib/rest/rest.rb +111 -0
- data/lib/rest_disabled.rb +24 -0
- data/lib/support.rb +387 -296
- data/old_lib_functions/two_general_class.rb +139 -0
- data/usecase.md +49 -36
- data/usecase_oo.md +59 -0
- metadata +73 -9
- data/lib/model.rb +0 -461
- data/lib/rest.rb +0 -1036
- data/test.rb +0 -4
data/lib/rest/delete.rb
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
module RestDelete
|
2
|
+
|
3
|
+
######### DATABASE ##########
|
4
|
+
|
5
|
+
=begin
|
6
|
+
Deletes the database and returns true on success
|
7
|
+
After the removal of the database, the working-database might be empty
|
8
|
+
=end
|
9
|
+
|
10
|
+
def delete_database database:
|
11
|
+
logger.progname = 'RestDelete#DeleteDatabase'
|
12
|
+
old_ds = ActiveOrient.database
|
13
|
+
change_database database
|
14
|
+
begin
|
15
|
+
response = @res["/database/#{ActiveOrient.database}"].delete
|
16
|
+
if database == old_ds
|
17
|
+
change_database 'temp'
|
18
|
+
logger.info{"Working database deleted, switched to temp"}
|
19
|
+
else
|
20
|
+
change_database old_ds
|
21
|
+
logger.info{"Database #{database} deleted, working database is still #{ActiveOrient.database}"}
|
22
|
+
end
|
23
|
+
rescue RestClient::InternalServerError => e
|
24
|
+
change_database old_ds
|
25
|
+
logger.info{"Database #{database} NOT deleted, working database is still #{ActiveOrient.database}"}
|
26
|
+
end
|
27
|
+
!response.nil? && response.code == 204 ? true : false
|
28
|
+
end
|
29
|
+
|
30
|
+
######### CLASS ##########
|
31
|
+
|
32
|
+
=begin
|
33
|
+
Deletes the specified class and returns true on success
|
34
|
+
todo: remove all instances of the class
|
35
|
+
=end
|
36
|
+
|
37
|
+
def delete_class o_class
|
38
|
+
cl = classname(o_class)
|
39
|
+
return if cl.nil?
|
40
|
+
logger.progname = 'RestDelete#DeleteClass'
|
41
|
+
|
42
|
+
begin
|
43
|
+
## to do: if cl contains special characters, enclose with backticks
|
44
|
+
response = @res["/class/#{ActiveOrient.database}/#{cl}"].delete
|
45
|
+
if response.code == 204
|
46
|
+
logger.info{"Class #{cl} deleted."}
|
47
|
+
ActiveOrient.database_classes.delete(cl)
|
48
|
+
end
|
49
|
+
rescue RestClient::InternalServerError => e
|
50
|
+
if get_database_classes(requery: true).include?(cl)
|
51
|
+
logger.error{"Class #{cl} still present."}
|
52
|
+
logger.error{e.inspect}
|
53
|
+
false
|
54
|
+
else
|
55
|
+
logger.error{e.inspect}
|
56
|
+
true
|
57
|
+
end
|
58
|
+
rescue Exception => e
|
59
|
+
logger.error{e.message}
|
60
|
+
logger.error{e.inspect}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
############## RECORD #############
|
65
|
+
|
66
|
+
=begin
|
67
|
+
Deletes a single Record when providing a single rid-link (#00:00) or a record
|
68
|
+
Deletes multible Records when providing a list of rid-links or a record
|
69
|
+
Todo: implement delete_edges after querying the database in one statement
|
70
|
+
|
71
|
+
Example:
|
72
|
+
record = Vertex.create_document attributes: { something: 'something' }
|
73
|
+
Vertex.delete_record record
|
74
|
+
|
75
|
+
records= (1..100).map{|x| Vertex.create_document attributes: { something: x } }
|
76
|
+
Vertex.delete_record *records
|
77
|
+
|
78
|
+
delete_records provides the removal of datasets after quering the database.
|
79
|
+
=end
|
80
|
+
|
81
|
+
def delete_record *rid
|
82
|
+
logger.progname = "ActiveOrient::RestDelete#DeleteRecord"
|
83
|
+
ridvec= rid.map( &:to_orient).flatten
|
84
|
+
unless ridvec.empty?
|
85
|
+
ridvec.map do |rid|
|
86
|
+
begin
|
87
|
+
ActiveOrient::Base.remove_rid( ActiveOrient::Base.get_rid(rid) )
|
88
|
+
@res["/document/#{ActiveOrient.database}/#{rid[1..-1]}"].delete
|
89
|
+
rescue RestClient::InternalServerError => e
|
90
|
+
logger.error{"Record #{rid} NOT deleted"}
|
91
|
+
rescue RestClient::ResourceNotFound
|
92
|
+
logger.error{"Record #{rid} does not exist in the database"}
|
93
|
+
else
|
94
|
+
logger.info{"Record #{rid} deleted"}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
else
|
98
|
+
logger.info{"No record deleted."}
|
99
|
+
return nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
alias delete_document delete_record
|
103
|
+
|
104
|
+
=begin
|
105
|
+
Deletes records. They are defined by a query. All records which match the attributes are deleted.
|
106
|
+
An Array with freed index-values is returned
|
107
|
+
=end
|
108
|
+
|
109
|
+
def delete_records o_class, where: {}
|
110
|
+
logger.progname = 'RestDelete#DeleteRecords'
|
111
|
+
records_to_delete = get_records(from: o_class, where: where)
|
112
|
+
if records_to_delete.empty?
|
113
|
+
logger.info{"No record found"}
|
114
|
+
else
|
115
|
+
delete_record records_to_delete
|
116
|
+
end
|
117
|
+
end
|
118
|
+
alias delete_documents delete_records
|
119
|
+
|
120
|
+
################ PROPERTY #############
|
121
|
+
|
122
|
+
def delete_property o_class, field
|
123
|
+
logger.progname = 'RestDelete#DeleteProperty'
|
124
|
+
begin
|
125
|
+
response = @res["/property/#{ActiveOrient.database}/#{classname(o_class)}/#{field}"].delete
|
126
|
+
true if response.code == 204
|
127
|
+
rescue RestClient::InternalServerError => e
|
128
|
+
logger.error{"Property #{field} in class #{classname(o_class)} NOT deleted" }
|
129
|
+
false
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
module RestOperations
|
2
|
+
|
3
|
+
# Execute a predefined Function
|
4
|
+
|
5
|
+
# untested
|
6
|
+
def call_function *args
|
7
|
+
# puts "uri:#{function_uri { args.join('/') } }"
|
8
|
+
begin
|
9
|
+
term = args.join('/')
|
10
|
+
@res["/function/#{@database}/#{term}"].post ''
|
11
|
+
rescue RestClient::InternalServerError => e
|
12
|
+
puts JSON.parse(e.http_body)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Used to count the Records in relation of the arguments
|
17
|
+
#
|
18
|
+
# Overwritten by Model#Count
|
19
|
+
def count **args
|
20
|
+
logger.progname = 'RestOperations#CountRecords'
|
21
|
+
query = OrientSupport::OrientQuery.new args
|
22
|
+
query.projection << 'COUNT (*)'
|
23
|
+
result = get_records raw: true, query: query
|
24
|
+
result.first['COUNT'] rescue 0 # return_value
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
def manipulate_relation record, method, array, items # :nodoc: #
|
29
|
+
execute_array = Array.new
|
30
|
+
method = method.to_s.upcase
|
31
|
+
|
32
|
+
add_2_execute_array = -> (it) do
|
33
|
+
command = "UPDATE ##{record.rid} #{method} #{array} = #{it.to_orient } " #updating}"
|
34
|
+
command.gsub!(/\"/,"") if it.is_a? Array
|
35
|
+
#puts "COMMAND:: #{command}"
|
36
|
+
execute_array << {type: "cmd", language: "sql", command: command}
|
37
|
+
end
|
38
|
+
|
39
|
+
items.each{|x| add_2_execute_array[x] }
|
40
|
+
r= execute{ execute_array }
|
41
|
+
|
42
|
+
if r.present?
|
43
|
+
case method
|
44
|
+
when 'ADD'
|
45
|
+
items.each{|x| record.attributes[array] << x}
|
46
|
+
when 'REMOVE'
|
47
|
+
items.map{|x| record.attributes[array].delete x.is_a?(ActiveOrient::Model) ? x.rid : x}
|
48
|
+
else
|
49
|
+
end
|
50
|
+
record.increment_version
|
51
|
+
end
|
52
|
+
end
|
53
|
+
=begin
|
54
|
+
Executes a list of commands and returns the result-array (if present)
|
55
|
+
|
56
|
+
(External use)
|
57
|
+
|
58
|
+
If soley a string is provided in the block, a minimal database-console is realized.
|
59
|
+
i.e.
|
60
|
+
|
61
|
+
ORD.execute{ 'select from #25:0' }
|
62
|
+
|
63
|
+
(Internal Use)
|
64
|
+
|
65
|
+
Structure of the provided block:
|
66
|
+
[{type: "cmd", language: "sql", command: "create class Person extends V"}, (...)]
|
67
|
+
--
|
68
|
+
It was first used by ActiveOrient::Query.execute_queries
|
69
|
+
Later I (topofocus) discovered that some Queries are not interpretated correctly by #GetRecords but are submitted without Error via batch-processing.
|
70
|
+
For instance, this valid query
|
71
|
+
select expand(first_list[5].second_list[9]) from base where label = 9
|
72
|
+
can only be submitted via batch
|
73
|
+
++
|
74
|
+
Parameters:
|
75
|
+
|
76
|
+
transaction: true|false Perform the batch as transaction
|
77
|
+
tolerate_error_code: /a regular expression/
|
78
|
+
Statements to execute are provided via block
|
79
|
+
These statements are translated to json and transmitted to the database. Example:
|
80
|
+
|
81
|
+
{ type: "cmd",
|
82
|
+
language: 'sql',
|
83
|
+
command: "CREATE EDGE #{classname(o_class)} FROM #{from.to_orient} TO #{to.to_orient}"}
|
84
|
+
|
85
|
+
Multible statements are transmitted at once if the Block provides an Array of statements.
|
86
|
+
|
87
|
+
|
88
|
+
=end
|
89
|
+
|
90
|
+
def execute transaction: true, tolerated_error_code: nil, process_error: true, raw: nil # Set up for classes
|
91
|
+
batch = {transaction: transaction, operations: yield}
|
92
|
+
logger.progname= "Execute"
|
93
|
+
unless batch[:operations].blank?
|
94
|
+
batch[:operations] = {:type=>"cmd", :language=>"sql", :command=> batch[:operations]} if batch[:operations].is_a? String
|
95
|
+
batch[:operations] = [batch[:operations]] unless batch[:operations].is_a? Array
|
96
|
+
batch[:operations].compact!
|
97
|
+
# transaction is true only for multible statements
|
98
|
+
# batch[:transaction] = transaction & batch[:operations].size >1
|
99
|
+
begin
|
100
|
+
logger.debug{ batch[:operations].map{|y|y[:command]}.join("; ") }
|
101
|
+
response = @res["/batch/#{ActiveOrient.database}"].post batch.to_json
|
102
|
+
rescue RestClient::BadRequest => f
|
103
|
+
# extract the misspelled query in logfile and abort
|
104
|
+
sentence= JSON.parse( f.response)['errors'].last['content']
|
105
|
+
logger.fatal{ " BadRequest --> #{sentence.split("\n")[1]} " }
|
106
|
+
puts "Query not recognized"
|
107
|
+
puts sentence
|
108
|
+
raise
|
109
|
+
rescue RestClient::InternalServerError => e
|
110
|
+
logger.progname = 'RestOperations#Execute'
|
111
|
+
sentence= JSON.parse( e.response)['errors'].last['content']
|
112
|
+
if tolerated_error_code.present? && e.response =~ tolerated_error_code
|
113
|
+
logger.info{ "tolerated_error::#{e.message}"}
|
114
|
+
else
|
115
|
+
if process_error
|
116
|
+
# puts batch.to_json
|
117
|
+
# logger.error{e.response}
|
118
|
+
logger.error{sentence}
|
119
|
+
logger.error{ e.backtrace.map {|l| " #{l}\n"}.join }
|
120
|
+
# logger.error{e.message.to_s}
|
121
|
+
else
|
122
|
+
raise
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
if response.present? && response.code == 200
|
127
|
+
if response.body['result'].present?
|
128
|
+
result= JSON.parse(response.body)['result']
|
129
|
+
return result if raw.present?
|
130
|
+
result.map do |x|
|
131
|
+
if x.is_a? Hash
|
132
|
+
if x.has_key?('@class')
|
133
|
+
ActiveOrient::Model.orientdb_class(name: x['@class'], superclass: :find_ME ).new x
|
134
|
+
elsif x.has_key?('value')
|
135
|
+
x['value']
|
136
|
+
else # create a dummy class and fill with attributes from result-set
|
137
|
+
ActiveOrient::Model.orientdb_class(name: 'query' ).new x
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end.compact # return_value
|
141
|
+
else
|
142
|
+
response.body
|
143
|
+
end
|
144
|
+
else
|
145
|
+
nil
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/lib/rest/read.rb
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
module RestRead
|
2
|
+
|
3
|
+
############# DATABASE #############
|
4
|
+
|
5
|
+
# Returns an Array with available Database-Names as Elements
|
6
|
+
|
7
|
+
def get_databases
|
8
|
+
JSON.parse(@res["/listDatabases"].get.body)['databases']
|
9
|
+
end
|
10
|
+
|
11
|
+
=begin
|
12
|
+
Returns an Array with (unmodified) Class-attribute-hash-Elements
|
13
|
+
|
14
|
+
get_classes 'name', 'superClass' returns
|
15
|
+
[ {"name"=>"E", "superClass"=>""},
|
16
|
+
{"name"=>"OFunction", "superClass"=>""},
|
17
|
+
{"name"=>"ORole", "superClass"=>"OIdentity"}
|
18
|
+
(...) ]
|
19
|
+
=end
|
20
|
+
|
21
|
+
def get_classes *attributes
|
22
|
+
begin
|
23
|
+
response = @res["/database/#{ActiveOrient.database}"].get
|
24
|
+
if response.code == 200
|
25
|
+
classes = JSON.parse(response.body)['classes']
|
26
|
+
unless attributes.empty?
|
27
|
+
classes.map{|y| y.select{|v,_| attributes.include?(v)}}
|
28
|
+
else
|
29
|
+
classes
|
30
|
+
end
|
31
|
+
else
|
32
|
+
[]
|
33
|
+
end
|
34
|
+
rescue Exception => e
|
35
|
+
logger.progname = 'RestRead#GetClasses'
|
36
|
+
logger.error{e.message}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
############### CLASS ################
|
42
|
+
|
43
|
+
# Return a JSON of the property of a class
|
44
|
+
|
45
|
+
def get_class_properties o_class
|
46
|
+
JSON.parse(@res["/class/#{ActiveOrient.database}/#{classname(o_class)}"].get)
|
47
|
+
rescue => e
|
48
|
+
logger.error e.message
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def print_class_properties o_class
|
54
|
+
puts "Detected Properties for class #{classname(o_class)}"
|
55
|
+
rp = get_class_properties o_class
|
56
|
+
n = rp['name']
|
57
|
+
if rp['properties'].nil?
|
58
|
+
puts "No property available"
|
59
|
+
else
|
60
|
+
puts rp['properties'].map{|x| "\t"+[n+'.'+x['name'], x['type'],x['linkedClass']].compact.join("\t-> ")}.join("\n")
|
61
|
+
end
|
62
|
+
rescue NoMethodError
|
63
|
+
puts "Class #{o_class} not present in database"
|
64
|
+
end
|
65
|
+
|
66
|
+
############## OBJECT #################
|
67
|
+
|
68
|
+
=begin
|
69
|
+
Retrieves a Record from the Database as ActiveOrient::Model::{class}
|
70
|
+
The argument can either be a rid (#[x}:{y}) or a link({x}:{y})
|
71
|
+
If no Record is found, nil is returned
|
72
|
+
=end
|
73
|
+
|
74
|
+
def get_record rid
|
75
|
+
begin
|
76
|
+
logger.progname = 'RestRead#GetRecord'
|
77
|
+
if rid.rid?
|
78
|
+
rid = rid[1..rid.length] if rid[0]=='#'
|
79
|
+
response = @res["/document/#{ActiveOrient.database}/#{rid}"].get
|
80
|
+
raw_data = JSON.parse(response.body) #.merge( "#no_links" => "#no_links" )
|
81
|
+
ActiveOrient::Model.orientdb_class(name: raw_data['@class'], superclass: :find_ME).new raw_data
|
82
|
+
else
|
83
|
+
logger.error { "Wrong parameter #{rid.inspect}. " }
|
84
|
+
nil
|
85
|
+
end
|
86
|
+
rescue RestClient::InternalServerError => e
|
87
|
+
if e.http_body.split(':').last =~ /was not found|does not exist in database/
|
88
|
+
nil
|
89
|
+
else
|
90
|
+
logger.error { "Something went wrong" }
|
91
|
+
logger.error { e.http_body.inspect }
|
92
|
+
raise
|
93
|
+
end
|
94
|
+
rescue RestClient::ResourceNotFound => e
|
95
|
+
logger.error { "Not data found" }
|
96
|
+
logger.error { e.message }
|
97
|
+
rescue Exception => e
|
98
|
+
logger.error { "Something went wrong" }
|
99
|
+
logger.error { "RID: #{rid} - #{e.message}" }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
alias get_document get_record
|
103
|
+
|
104
|
+
=begin
|
105
|
+
Retrieves Records from a query
|
106
|
+
If raw is specified, the JSON-Array is returned, e.g.
|
107
|
+
{"@type"=>"d", "@rid"=>"#15:1", "@version"=>1, "@class"=>"DocumebntKlasse10", "con_id"=>343, "symbol"=>"EWTZ"}
|
108
|
+
Otherwise a ActiveModel-Instance of o_class is created and returned
|
109
|
+
=end
|
110
|
+
|
111
|
+
def get_records raw: false, query: nil, **args
|
112
|
+
query = OrientSupport::OrientQuery.new(args) if query.nil?
|
113
|
+
begin
|
114
|
+
logger.progname = 'RestRead#GetRecords'
|
115
|
+
url = "/query/#{ActiveOrient.database}/sql/" + query.compose(destination: :rest) + "/#{query.get_limit}"
|
116
|
+
# puts "URL"
|
117
|
+
# puts query.compose( destination: :rest).to_s
|
118
|
+
# puts url.to_s
|
119
|
+
response = @res[URI.encode(url)].get
|
120
|
+
JSON.parse(response.body)['result'].map do |record|
|
121
|
+
if raw
|
122
|
+
record
|
123
|
+
# query returns an anonymus class: Use the provided Block or the Dummy-Model MyQuery
|
124
|
+
elsif record['@class'].blank?
|
125
|
+
# puts "RECORD:\n"+record.inspect
|
126
|
+
block_given? ? yield.new(record) : ActiveOrient::Model.orientdb_class(name: 'query' ).new( record )
|
127
|
+
else
|
128
|
+
ActiveOrient::Model.orientdb_class(name: record['@class'], superclass: :find_ME).new record
|
129
|
+
end
|
130
|
+
end
|
131
|
+
# returns the JSON-Object
|
132
|
+
|
133
|
+
|
134
|
+
rescue RestClient::InternalServerError => e
|
135
|
+
response = JSON.parse(e.response)['errors'].pop
|
136
|
+
logger.error{ "Interbak Server ERROR" }
|
137
|
+
logger.error{response['content'].split(':').last}
|
138
|
+
rescue URI::InvalidURIError => e
|
139
|
+
logger.error{"Invalid URI detected"}
|
140
|
+
logger.error query.to_s
|
141
|
+
logger.info{"Trying batch processing"}
|
142
|
+
sql_cmd = -> (command){{type: "cmd", language: "sql", command: command}}
|
143
|
+
response = execute{[sql_cmd[query.to_s]]}
|
144
|
+
logger.info{"Success: to avoid this delay use ActiveOrient::Model#query_database instead"}
|
145
|
+
response
|
146
|
+
end
|
147
|
+
end
|
148
|
+
alias get_documents get_records
|
149
|
+
|
150
|
+
end
|
data/lib/rest/rest.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require_relative "read.rb" # manage get
|
2
|
+
require_relative "create.rb" # manage create
|
3
|
+
require_relative "change.rb" # manage update
|
4
|
+
require_relative "operations.rb" # manage count, functions and execute
|
5
|
+
require_relative "delete.rb" # manage delete
|
6
|
+
require 'cgi'
|
7
|
+
require 'rest-client'
|
8
|
+
|
9
|
+
module ActiveOrient
|
10
|
+
|
11
|
+
=begin
|
12
|
+
OrientDB performs queries to a OrientDB-Database
|
13
|
+
The communication is based on the ActiveOrient-API.
|
14
|
+
The OrientDB-Server is specified in config/connect.yml
|
15
|
+
A Sample:
|
16
|
+
:orientdb:
|
17
|
+
:server: localhost
|
18
|
+
:port: 2480
|
19
|
+
:database: working-database
|
20
|
+
:admin:
|
21
|
+
:user: admin-user
|
22
|
+
:pass: admin-password
|
23
|
+
=end
|
24
|
+
|
25
|
+
class OrientDB
|
26
|
+
include OrientSupport::Support
|
27
|
+
include OrientDbPrivate
|
28
|
+
include DatabaseUtils
|
29
|
+
include ClassUtils
|
30
|
+
include RestRead
|
31
|
+
include RestCreate
|
32
|
+
include RestChange
|
33
|
+
include RestOperations
|
34
|
+
include RestDelete
|
35
|
+
|
36
|
+
mattr_accessor :logger # borrowed from active_support
|
37
|
+
attr_reader :database # Used to read the working database
|
38
|
+
|
39
|
+
#### INITIALIZATION ####
|
40
|
+
|
41
|
+
=begin
|
42
|
+
Contructor: OrientDB is conventionally initialized.
|
43
|
+
Thus several instances pointing to the same or different databases can coexist
|
44
|
+
|
45
|
+
A simple
|
46
|
+
xyz = ActiveOrient::OrientDB.new
|
47
|
+
uses the database specified in the yaml-file »config/connect.yml« and connects
|
48
|
+
xyz = ActiveOrient::OrientDB.new database: my_fency_database
|
49
|
+
accesses the database »my_fency_database«. The database is created if its not existing.
|
50
|
+
|
51
|
+
*USECASE*
|
52
|
+
xyz = ActiveOrient::Model.orientdb = ActiveOrient::OrientDB.new
|
53
|
+
initialises the Database-Connection and publishes the Instance to any ActiveOrient::Model-Object
|
54
|
+
=end
|
55
|
+
|
56
|
+
def initialize database: nil, connect: true, preallocate: true
|
57
|
+
self.logger = Logger.new('/dev/stdout') unless logger.present?
|
58
|
+
# self.default_server = {
|
59
|
+
# :server => 'localhost',
|
60
|
+
# :port => 2480,
|
61
|
+
# :protocol => 'http',
|
62
|
+
# :user => 'root',
|
63
|
+
# :password => 'root',
|
64
|
+
# :database => 'temp'
|
65
|
+
# }.merge default_server.presence || {}
|
66
|
+
# @res = get_resource
|
67
|
+
ActiveOrient.database = database if database.present?
|
68
|
+
@res = get_resource
|
69
|
+
connect() if connect
|
70
|
+
database_classes # initialize @classes-array
|
71
|
+
ActiveOrient::Model.orientdb = self
|
72
|
+
ActiveOrient::Model.db = self
|
73
|
+
preallocate_classes if preallocate
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
def get_resource
|
78
|
+
login = [ActiveOrient.default_server[:user].to_s , ActiveOrient.default_server[:password].to_s]
|
79
|
+
server_adress = "http://#{ActiveOrient.default_server[:server]}:#{ActiveOrient.default_server[:port]}"
|
80
|
+
RestClient::Resource.new(server_adress, *login)
|
81
|
+
end
|
82
|
+
|
83
|
+
# Used to connect to the database
|
84
|
+
|
85
|
+
def connect
|
86
|
+
first_tentative = true
|
87
|
+
begin
|
88
|
+
database = ActiveOrient.database
|
89
|
+
logger.progname = 'OrientDB#Connect'
|
90
|
+
r = @res["/connect/#{database}"].get
|
91
|
+
if r.code == 204
|
92
|
+
logger.info{"Connected to database #{database}"}
|
93
|
+
true
|
94
|
+
else
|
95
|
+
logger.error{"Connection to database #{database} could NOT be established"}
|
96
|
+
nil
|
97
|
+
end
|
98
|
+
rescue RestClient::Unauthorized => e
|
99
|
+
if first_tentative
|
100
|
+
logger.info{"Database #{database} NOT present --> creating"}
|
101
|
+
first_tentative = false
|
102
|
+
create_database
|
103
|
+
retry
|
104
|
+
else
|
105
|
+
Kernel.exit
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|