active-orient 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|