active-orient 0.42 → 0.79
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 +5 -5
- data/.gitignore +1 -0
- data/Gemfile +13 -5
- data/Guardfile +12 -4
- data/README.md +67 -280
- data/VERSION +1 -1
- data/active-orient.gemspec +6 -5
- data/bin/active-orient-0.6.gem +0 -0
- data/bin/active-orient-console +85 -0
- data/config/boot.rb +72 -1
- data/config/config.yml +10 -0
- data/config/connect.yml +9 -4
- data/examples/books.rb +92 -40
- data/examples/streets.rb +89 -85
- data/examples/test_commands.rb +97 -0
- data/examples/test_commands_2.rb +59 -0
- data/examples/test_commands_3.rb +55 -0
- data/examples/test_commands_4.rb +33 -0
- data/examples/time_graph.md +162 -0
- data/lib/active-orient.rb +75 -9
- data/lib/base.rb +238 -169
- data/lib/base_properties.rb +68 -60
- data/lib/class_utils.rb +226 -0
- data/lib/database_utils.rb +98 -0
- data/lib/init.rb +79 -0
- data/lib/java-api.rb +442 -0
- data/lib/jdbc.rb +211 -0
- data/lib/model/custom.rb +26 -0
- data/lib/model/edge.rb +70 -0
- data/lib/model/model.rb +134 -0
- data/lib/model/the_class.rb +607 -0
- data/lib/model/the_record.rb +266 -0
- data/lib/model/vertex.rb +236 -0
- data/lib/orientdb_private.rb +48 -0
- data/lib/other.rb +371 -0
- data/lib/railtie.rb +68 -0
- data/lib/rest/change.rb +147 -0
- data/lib/rest/create.rb +279 -0
- data/lib/rest/delete.rb +134 -0
- data/lib/rest/operations.rb +211 -0
- data/lib/rest/read.rb +171 -0
- data/lib/rest/rest.rb +112 -0
- data/lib/rest_disabled.rb +24 -0
- data/lib/support/logging.rb +38 -0
- data/lib/support/orient.rb +196 -0
- data/lib/support/orientquery.rb +469 -0
- data/rails.md +154 -0
- data/rails/activeorient.rb +32 -0
- data/rails/config.yml +10 -0
- data/rails/connect.yml +17 -0
- metadata +65 -24
- data/active-orient-0.4.gem +0 -0
- data/active-orient-0.41.gem +0 -0
- data/lib/model.rb +0 -468
- data/lib/orient.rb +0 -98
- data/lib/query.rb +0 -88
- data/lib/rest.rb +0 -1059
- data/lib/support.rb +0 -372
- data/test.rb +0 -4
- data/usecase.md +0 -91
data/lib/rest/change.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
module RestChange
|
2
|
+
|
3
|
+
############### DATABASE ####################
|
4
|
+
|
5
|
+
# Changes the working-database to {name}
|
6
|
+
|
7
|
+
def change_database name
|
8
|
+
@classes = []
|
9
|
+
@database = name
|
10
|
+
ActiveOrient.database = name
|
11
|
+
end
|
12
|
+
|
13
|
+
############# OBJECTS #################
|
14
|
+
|
15
|
+
=begin
|
16
|
+
Convient update of the dataset by calling sql-patch
|
17
|
+
|
18
|
+
The argument record can be specified as ActiveOrient::Model-instance or as rid-string( #0:0 )
|
19
|
+
|
20
|
+
called from ModelRecord#update
|
21
|
+
|
22
|
+
if the update was successful, the updated data are returned as Hash.
|
23
|
+
|
24
|
+
First the cached object is retrieved
|
25
|
+
Its modified by the parameters provided
|
26
|
+
and then patched
|
27
|
+
|
28
|
+
better would be: update the cached object and patch that.
|
29
|
+
=end
|
30
|
+
|
31
|
+
def update record, attributes , version=0
|
32
|
+
r = ActiveOrient::Model.autoload_object record.rid
|
33
|
+
return(false) unless r.is_a?(ActiveOrient::Model)
|
34
|
+
version = r.version if version.zero?
|
35
|
+
result = patch_record(r.rid) do
|
36
|
+
attributes.merge({'@version' => version, '@class' => r.class.ref_name })
|
37
|
+
end
|
38
|
+
# returns a new instance of ActiveOrient::Model and updates any reference on rid
|
39
|
+
# It's assumed, that the version
|
40
|
+
# if the patch is not successfull no string is returned and thus no record is fetched
|
41
|
+
# JSON.parse(result) if result.is_a?(String)
|
42
|
+
if result.is_a?(String)
|
43
|
+
JSON.parse(result) # return value
|
44
|
+
else
|
45
|
+
logger.error{ "REST::Update was not successfull" }
|
46
|
+
nil # returnvalue
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
=begin
|
52
|
+
Example:
|
53
|
+
ORD.update_documents classname, set: {:symbol => 'TWR'}, where: {con_id: 340}
|
54
|
+
|
55
|
+
Replaces the symbol to TWR in each record where the con_id is 340
|
56
|
+
|
57
|
+
Both set and where take multiple attributes
|
58
|
+
|
59
|
+
Returns the JSON-Response.
|
60
|
+
|
61
|
+
# todo: clear the rid-cache
|
62
|
+
=end
|
63
|
+
|
64
|
+
def update_records o_class, set:{}, where: {}, remove: nil
|
65
|
+
logger.progname = 'RestChange#UpdateRecords'
|
66
|
+
count = execute do
|
67
|
+
if set.present?
|
68
|
+
"UPDATE #{classname(o_class)} SET #{generate_sql_list(set)} #{compose_where(where)}"
|
69
|
+
elsif remove.present?
|
70
|
+
"UPDATE #{classname(o_class)} remove #{remove} #{compose_where(where)}"
|
71
|
+
end
|
72
|
+
end &.first
|
73
|
+
rescue Exception => e
|
74
|
+
logger.error{e.message}
|
75
|
+
nil
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
# Lazy Updating of the given Record.
|
81
|
+
# internal using while updating records
|
82
|
+
def patch_record rid # :nodoc: (used by #update )
|
83
|
+
logger.progname = 'RestChange#PatchRecord'
|
84
|
+
content = yield
|
85
|
+
if content.is_a? Hash
|
86
|
+
begin
|
87
|
+
@res["/document/#{ActiveOrient.database}/#{rid}"].patch content.to_orient.to_json
|
88
|
+
rescue RestClient::InternalServerError => e
|
89
|
+
sentence= JSON.parse( e.response)['errors'].last['content']
|
90
|
+
logger.error{sentence}
|
91
|
+
logger.error{ e.backtrace.map {|l| " #{l}\n"}.join }
|
92
|
+
logger.error{e.message.to_s}
|
93
|
+
end
|
94
|
+
else
|
95
|
+
logger.error{"PATCH FAILED: The Block must provide an Hash with properties to be updated"}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
alias patch_document patch_record
|
99
|
+
|
100
|
+
|
101
|
+
#### EXPERIMENTAL ##########
|
102
|
+
|
103
|
+
=begin
|
104
|
+
Used to add restriction or other properties to the Property of a Class.
|
105
|
+
See http://orientdb.com/docs/2.1/SQL-Alter-Property.html
|
106
|
+
=end
|
107
|
+
|
108
|
+
def alter_property o_class, property:, attribute: "DEFAULT", alteration: # :nodoc: because untested
|
109
|
+
logger.progname = 'RestChange#AlterProperty'
|
110
|
+
begin
|
111
|
+
attribute.to_s! unless attribute.is_a? String
|
112
|
+
attribute.capitalize_first_letter
|
113
|
+
case attribute
|
114
|
+
when "LINKEDCLASS", "LINKEDTYPE", "NAME", "REGEX", "TYPE", "REGEX", "COLLATE", "CUSTOM"
|
115
|
+
unless alteration.is_a? String
|
116
|
+
logger.error{"#{alteration} should be a String."}
|
117
|
+
return 0
|
118
|
+
end
|
119
|
+
when "MIN", "MAX"
|
120
|
+
unless alteration.is_a? Integer
|
121
|
+
logger.error{"#{alteration} should be an Integer."}
|
122
|
+
return 0
|
123
|
+
end
|
124
|
+
when "MANDATORY", "NOTNULL", "READONLY"
|
125
|
+
unless alteration.is_a? TrueClass or alteration.is_a? FalseClass
|
126
|
+
logger.error{"#{alteration} should be an Integer."}
|
127
|
+
return 0
|
128
|
+
end
|
129
|
+
when "DEFAULT"
|
130
|
+
else
|
131
|
+
logger.error{"Wrong attribute."}
|
132
|
+
return 0
|
133
|
+
end
|
134
|
+
|
135
|
+
name_class = classname(o_class)
|
136
|
+
execute name_class, transaction: false do # To execute commands
|
137
|
+
[{ type: "cmd",
|
138
|
+
language: 'sql',
|
139
|
+
command: "ALTER PROPERTY #{name_class}.#{property} #{attribute} #{alteration}"}]
|
140
|
+
end
|
141
|
+
rescue Exception => e
|
142
|
+
logger.error{e.message}
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
end
|
data/lib/rest/create.rb
ADDED
@@ -0,0 +1,279 @@
|
|
1
|
+
module RestCreate
|
2
|
+
|
3
|
+
######### DATABASE ##########
|
4
|
+
|
5
|
+
=begin
|
6
|
+
Creates a database with the given name and switches to this database as working-database. Types are either 'plocal' or 'memory'
|
7
|
+
|
8
|
+
Returns the name of the working-database
|
9
|
+
=end
|
10
|
+
|
11
|
+
def create_database type: 'plocal', database:
|
12
|
+
logger.progname = 'RestCreate#CreateDatabase'
|
13
|
+
old_d = ActiveOrient.database
|
14
|
+
ActiveOrient.database_classes = {}
|
15
|
+
ActiveOrient.database = database
|
16
|
+
begin
|
17
|
+
response = @res["database/#{ActiveOrient.database}/#{type}"].post ""
|
18
|
+
if response.code == 200
|
19
|
+
logger.info{"Database #{ActiveOrient.database} successfully created and stored as working database"}
|
20
|
+
else
|
21
|
+
logger.error{"Database #{ActiveOrient.database} was NOT created. Working Database is still #{ActiveOrient.database}"}
|
22
|
+
ActiveOrient.database = old_d
|
23
|
+
end
|
24
|
+
rescue RestClient::InternalServerError => e
|
25
|
+
logger.error{"Database #{ActiveOrient.database} was NOT created. Working Database is still #{ActiveOrient.database}"}
|
26
|
+
ActiveOrient.database = old_d
|
27
|
+
end
|
28
|
+
ActiveOrient.database # return_value
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
=begin
|
34
|
+
|
35
|
+
This is the historic method CreateClasses. It's just performing the database-stuff and now private
|
36
|
+
|
37
|
+
it takes superclass and abstract (a hash) as block
|
38
|
+
|
39
|
+
usually, only one classname is provided, however the method takes a row of classnames as argument
|
40
|
+
|
41
|
+
#todo reintegrate the ability to create abstract classes
|
42
|
+
=end
|
43
|
+
private
|
44
|
+
def create_this_class *db_classname #nodoc#
|
45
|
+
if block_given?
|
46
|
+
additional_args = yield
|
47
|
+
superclass = additional_args[ :superclass ]
|
48
|
+
abstract = additional_args[ :abstract ].presence || nil
|
49
|
+
else
|
50
|
+
superclass = nil
|
51
|
+
abstract = nil
|
52
|
+
end
|
53
|
+
#
|
54
|
+
command= db_classname.map do | database_class |
|
55
|
+
c = if superclass.present?
|
56
|
+
"CREATE CLASS #{database_class} EXTENDS #{superclass}"
|
57
|
+
else
|
58
|
+
"CREATE CLASS #{database_class} "
|
59
|
+
end
|
60
|
+
c << " ABSTRACT" if abstract.present?
|
61
|
+
# { type: "cmd", language: 'sql', command: c } # return value 4 command
|
62
|
+
c
|
63
|
+
end
|
64
|
+
# execute anything as batch, don't roll back in case of an error
|
65
|
+
|
66
|
+
execute transaction: false, tolerated_error_code: /already exists/ do
|
67
|
+
command
|
68
|
+
end
|
69
|
+
|
70
|
+
rescue ArgumentError => e
|
71
|
+
logger.error{ e.backtrace.map {|l| " #{l}\n"}.join }
|
72
|
+
rescue ActiveOrient::Error::ServerError
|
73
|
+
# do nothing
|
74
|
+
end
|
75
|
+
|
76
|
+
|
77
|
+
public
|
78
|
+
|
79
|
+
############## OBJECT #############
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
=begin
|
84
|
+
Creates a Record in the Database and returns this as ActiveOrient::Model-Instance
|
85
|
+
|
86
|
+
Creates a Record with the attributes provided in the attributes-hash e.g.
|
87
|
+
create_record @classname, attributes: {con_id: 343, symbol: 'EWTZ'}
|
88
|
+
|
89
|
+
Puts the database-response into the cache by default
|
90
|
+
|
91
|
+
|
92
|
+
=end
|
93
|
+
|
94
|
+
def create_record o_class, attributes: {}, cache: true # use Model#create instead
|
95
|
+
logger.progname = 'RestCreate#CreateRecord'
|
96
|
+
attributes = yield if attributes.empty? && block_given?
|
97
|
+
# @class must not quoted! Quote only attributes(strings)
|
98
|
+
post_argument = {'@class' => classname(o_class)}.merge(attributes.to_orient)
|
99
|
+
begin
|
100
|
+
response = @res["/document/#{ActiveOrient.database}"].post post_argument.to_json
|
101
|
+
data = JSON.parse(response.body)
|
102
|
+
the_object = ActiveOrient::Model.orientdb_class(name: data['@class']).new data ## return_value
|
103
|
+
if cache
|
104
|
+
ActiveOrient::Base.store_rid( the_object )
|
105
|
+
else
|
106
|
+
the_object
|
107
|
+
end
|
108
|
+
rescue RestClient::InternalServerError => e
|
109
|
+
sentence= JSON.parse( e.response)['errors'].last['content']
|
110
|
+
# puts sentence.to_s
|
111
|
+
if sentence =~ /found duplicated key/
|
112
|
+
rid = sentence.split("#").last
|
113
|
+
logger.info{ "found duplicated Key --> loaded #{rid} instead of creating "}
|
114
|
+
## reading database content -- maybe update attributes?
|
115
|
+
get_record rid
|
116
|
+
else
|
117
|
+
response = JSON.parse(e.response)['errors'].pop
|
118
|
+
logger.error{response['content'].split(':')[1..-1].join(':')}
|
119
|
+
logger.error{"No Object allocated"}
|
120
|
+
nil # return_value
|
121
|
+
end
|
122
|
+
rescue Errno::EADDRNOTAVAIL => e
|
123
|
+
sleep(2)
|
124
|
+
retry
|
125
|
+
end
|
126
|
+
end
|
127
|
+
alias create_document create_record
|
128
|
+
|
129
|
+
# UPDATE <class>|CLUSTER:<cluster>|<recordID>
|
130
|
+
# [SET|INCREMENT|ADD|REMOVE|PUT <field-name> = <field-value>[,]*]|[CONTENT|MERGE <JSON>]
|
131
|
+
# [UPSERT]
|
132
|
+
# [RETURN <returning> [<returning-expression>]]
|
133
|
+
# [WHERE <conditions>]
|
134
|
+
# [LOCK default|record]
|
135
|
+
# [LIMIT <max-records>] [TIMEOUT <timeout>]
|
136
|
+
|
137
|
+
=begin
|
138
|
+
update or insert one record is implemented as upsert.
|
139
|
+
The where-condition is merged into the set-attributes if its a hash.
|
140
|
+
Otherwise it's taken unmodified.
|
141
|
+
|
142
|
+
The method returns the included or the updated dataset
|
143
|
+
|
144
|
+
## to do
|
145
|
+
# yield works for updated and for inserted datasets
|
146
|
+
# upsert ( ) do | what, record |
|
147
|
+
# if what == :insert
|
148
|
+
# do stuff with insert
|
149
|
+
# if what == :update
|
150
|
+
# do stuff with update
|
151
|
+
# end
|
152
|
+
# returns nil if no insert and no update was made, ie. the dataset is identical to the given attributes
|
153
|
+
=end
|
154
|
+
def upsert o_class, set: , where: # use Model#Upsert instead
|
155
|
+
logger.progname = 'RestCreate#Upsert'
|
156
|
+
specify_return_value = "return after @rid"
|
157
|
+
# set.merge! where if where.is_a?( Hash ) # copy where attributes to set
|
158
|
+
command = "Update #{classname(o_class)} set #{generate_sql_list( set ){','}} upsert #{specify_return_value} #{compose_where where}"
|
159
|
+
result = execute( tolerated_error_code: /found duplicated key/){ command }
|
160
|
+
# puts "result #{result.inspect}"
|
161
|
+
result =result.pop if result.is_a? Array
|
162
|
+
end
|
163
|
+
############### PROPERTIES #############
|
164
|
+
|
165
|
+
=begin
|
166
|
+
Creates properties
|
167
|
+
|
168
|
+
and (if defined in the provided block) associates an index
|
169
|
+
create_properties(classname or class, properties as hash){index}
|
170
|
+
|
171
|
+
The default-case
|
172
|
+
create_properties(:my_high_sophisticated_database_class,
|
173
|
+
con_id: {type: :integer},
|
174
|
+
details: {type: :link, linked_class: 'Contracts'}) do
|
175
|
+
contract_idx: :notunique
|
176
|
+
end
|
177
|
+
|
178
|
+
A composite index
|
179
|
+
create_properties(:my_high_sophisticated_database_class,
|
180
|
+
con_id: {type: :integer},
|
181
|
+
symbol: {type: :string}) do
|
182
|
+
{name: 'indexname',
|
183
|
+
on: [:con_id, :details] # default: all specified properties
|
184
|
+
type: :notunique # default: :unique
|
185
|
+
}
|
186
|
+
end
|
187
|
+
=end
|
188
|
+
|
189
|
+
def create_properties o_class, all_properties, &b
|
190
|
+
logger.progname = 'RestCreate#CreateProperties'
|
191
|
+
all_properties_in_a_hash = Hash.new #WithIndifferentAccess.new
|
192
|
+
all_properties.each{|field, args| all_properties_in_a_hash.merge! translate_property_hash(field, args)}
|
193
|
+
count=0
|
194
|
+
# puts "all_properties_in_a_hash #{all_properties_in_a_hash.to_json}"
|
195
|
+
begin
|
196
|
+
if all_properties_in_a_hash.is_a?(Hash)
|
197
|
+
response = @res["/property/#{ActiveOrient.database}/#{classname(o_class)}"].post all_properties_in_a_hash.to_json
|
198
|
+
# puts response.inspect
|
199
|
+
# response.body.to_i returns response.code, only to_f.to_i returns the correct value
|
200
|
+
count= response.body.to_f.to_i if response.code == 201
|
201
|
+
end
|
202
|
+
rescue RestClient::InternalServerError => e
|
203
|
+
logger.progname = 'RestCreate#CreateProperties'
|
204
|
+
response = JSON.parse(e.response)['errors'].pop
|
205
|
+
error_message = response['content'].split(':').last
|
206
|
+
logger.error{"Properties in #{classname(o_class)} were NOT created"}
|
207
|
+
logger.error{"The Error was: #{response['content'].split(':').last}"}
|
208
|
+
nil
|
209
|
+
end
|
210
|
+
### index
|
211
|
+
if block_given?# && count == all_properties_in_a_hash.size
|
212
|
+
index = yield
|
213
|
+
if index.is_a?(Hash)
|
214
|
+
if index.size == 1
|
215
|
+
create_index o_class, name: index.keys.first, on: all_properties_in_a_hash.keys, type: index.values.first
|
216
|
+
else
|
217
|
+
index_hash = {type: :unique, on: all_properties_in_a_hash.keys}.merge index
|
218
|
+
create_index o_class, name: index_hash[:name], on: index_hash[:on], type: index_hash[:type]
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
count # return_value
|
223
|
+
end
|
224
|
+
|
225
|
+
=begin
|
226
|
+
Create a single property.
|
227
|
+
|
228
|
+
Supported types: https://orientdb.com/docs/last/SQL-Create-Property.html
|
229
|
+
|
230
|
+
If an index is to be specified, it's defined in the optional block
|
231
|
+
|
232
|
+
create_property(class, field){:unique | :notunique}
|
233
|
+
--> creates an automatic-Index on the given field
|
234
|
+
|
235
|
+
create_property(class, field){{»name« => :unique | :notunique | :full_text}}
|
236
|
+
--> creates a manual index
|
237
|
+
=end
|
238
|
+
|
239
|
+
def create_property o_class, field, index: nil, **args, &b
|
240
|
+
logger.progname = 'RestCreate#CreateProperty'
|
241
|
+
args= { type: :string} if args.blank? # the default case
|
242
|
+
c = create_properties o_class, {field => args}
|
243
|
+
if index.nil? && block_given?
|
244
|
+
index = yield
|
245
|
+
end
|
246
|
+
if index.present?
|
247
|
+
if index.is_a?(String) || index.is_a?(Symbol)
|
248
|
+
create_index o_class, name: field, type: index
|
249
|
+
elsif index.is_a? Hash
|
250
|
+
bez = index.keys.first
|
251
|
+
create_index o_class, name: bez, type: index[bez], on: [field]
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
################# INDEX ###################
|
257
|
+
|
258
|
+
# Used to create an index
|
259
|
+
|
260
|
+
def create_index o_class, name:, on: :automatic, type: :unique
|
261
|
+
logger.progname = 'RestCreate#CreateIndex'
|
262
|
+
c = classname o_class
|
263
|
+
if execute( transaction: false, tolerated_error_code: /found duplicated key/) do
|
264
|
+
if on == :automatic
|
265
|
+
"CREATE INDEX #{c}.#{name} #{type.to_s.upcase}"
|
266
|
+
elsif on.is_a? Array
|
267
|
+
"CREATE INDEX #{name} ON #{c}(#{on.join(', ')}) #{type.to_s.upcase}"
|
268
|
+
else
|
269
|
+
"CREATE INDEX #{name} ON #{c}(#{on.to_s}) #{type.to_s.upcase}"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
logger.info{"Index on #{c} based on #{name} created."}
|
274
|
+
else
|
275
|
+
logger.error {"index #{name}.#{type} on #{c} NOT created"}
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
data/lib/rest/delete.rb
ADDED
@@ -0,0 +1,134 @@
|
|
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
|
+
sentence= JSON.parse( e.response)['errors'].last['content']
|
51
|
+
if ActiveOrient.database_classes.has_key? cl
|
52
|
+
logger.error{"Class #{cl} still present."}
|
53
|
+
logger.error{ sentence }
|
54
|
+
false
|
55
|
+
else
|
56
|
+
logger.error{e.inspect}
|
57
|
+
true
|
58
|
+
end
|
59
|
+
rescue Exception => e
|
60
|
+
logger.error{e.message}
|
61
|
+
logger.error{e.inspect}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
############## RECORD #############
|
66
|
+
|
67
|
+
=begin
|
68
|
+
Deletes a single Record when providing a single rid-link (#00:00) or a record
|
69
|
+
Deletes multible Records when providing a list of rid-links or a record
|
70
|
+
Todo: implement delete_edges after querying the database in one statement
|
71
|
+
|
72
|
+
Example:
|
73
|
+
record = Vertex.create_document attributes: { something: 'something' }
|
74
|
+
Vertex.delete_record record
|
75
|
+
|
76
|
+
records= (1..100).map{|x| Vertex.create_document attributes: { something: x } }
|
77
|
+
Vertex.delete_record *records
|
78
|
+
|
79
|
+
delete_records provides the removal of datasets after quering the database.
|
80
|
+
=end
|
81
|
+
|
82
|
+
def delete_record *rid
|
83
|
+
logger.progname = "ActiveOrient::RestDelete#DeleteRecord"
|
84
|
+
ridvec= rid.map( &:to_orient).flatten
|
85
|
+
unless ridvec.empty?
|
86
|
+
ridvec.map do |rid|
|
87
|
+
begin
|
88
|
+
ActiveOrient::Base.remove_rid( ActiveOrient::Base.get_rid(rid) )
|
89
|
+
@res["/document/#{ActiveOrient.database}/#{rid[1..-1]}"].delete
|
90
|
+
rescue RestClient::InternalServerError => e
|
91
|
+
logger.error{"Record #{rid} NOT deleted"}
|
92
|
+
rescue RestClient::ResourceNotFound
|
93
|
+
logger.error{"Record #{rid} does not exist in the database"}
|
94
|
+
else
|
95
|
+
logger.info{"Record #{rid} deleted"}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
else
|
99
|
+
logger.info{"No record deleted."}
|
100
|
+
return nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
alias delete_document delete_record
|
104
|
+
|
105
|
+
=begin
|
106
|
+
Deletes records. They are defined by a query. All records which match the attributes are deleted.
|
107
|
+
An Array with freed index-values is returned
|
108
|
+
=end
|
109
|
+
|
110
|
+
def delete_records o_class, where: {}
|
111
|
+
logger.progname = 'RestDelete#DeleteRecords'
|
112
|
+
records_to_delete = get_records(from: o_class, where: where)
|
113
|
+
if records_to_delete.empty?
|
114
|
+
logger.info{"No record found"}
|
115
|
+
else
|
116
|
+
delete_record records_to_delete
|
117
|
+
end
|
118
|
+
end
|
119
|
+
alias delete_documents delete_records
|
120
|
+
|
121
|
+
################ PROPERTY #############
|
122
|
+
|
123
|
+
def delete_property o_class, field
|
124
|
+
logger.progname = 'RestDelete#DeleteProperty'
|
125
|
+
begin
|
126
|
+
response = @res["/property/#{ActiveOrient.database}/#{classname(o_class)}/#{field}"].delete
|
127
|
+
true if response.code == 204
|
128
|
+
rescue RestClient::InternalServerError => e
|
129
|
+
logger.error{"Property #{field} in class #{classname(o_class)} NOT deleted" }
|
130
|
+
false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|