Module: RestOperations

Included in:
ActiveOrient::OrientDB
Defined in:
lib/rest/operations.rb

Instance Method Summary collapse

Instance Method Details

#_execute(tolerated_error_code, process_error, raw) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/rest/operations.rb', line 172

def _execute tolerated_error_code, process_error, raw

	logger.progname= "Execute"

	begin
		response = yield
	rescue RestClient::BadRequest => f
		# extract the misspelled query in logfile and abort
		sentence=  JSON.parse( f.response)['errors'].last['content']
		logger.fatal{ " BadRequest --> #{sentence.split("\n")[1]} " }
		puts "Query not recognized"
		puts sentence
		raise
	rescue RestClient::Conflict => e  # (409)
		# most probably the server is busy. we  wait for a second  print an Error-Message and retry
		sleep(1)
		logger.error{ e.inspect }
		logger.error{ "RestClient::Error(409): Server is signaling a conflict ... retrying" }
		retry
	rescue RestClient::InternalServerError => e
		sentence=  JSON.parse( e.response)['errors'].last['content']
		if tolerated_error_code.present? &&  e.response =~ tolerated_error_code
			logger.debug('RestOperations#Execute'){ "tolerated_error::#{e.message}"}
			logger.debug('RestOperations#Execute'){ e.message }
			nil  # return value
		else
			if process_error
				logger.error{sentence}
				#logger.error{ e.backtrace.map {|l| "  #{l}\n"}.join  }
				#	  logger.error{e.message.to_s}
			else 
				raise
			end
		end 
	rescue Errno::EADDRNOTAVAIL => e
		sleep(2)
		retry
	else  # code to execute if no exception  is raised
		if response.code == 200
			result=JSON.parse(response.body)['result']
			if raw.present? 
				result
			else
				result.from_orient
			end # raw present?
		else
			logger.error { "code : #{response.code}" }
		end
	end
end

#call_function(*args) ⇒ Object

untested



6
7
8
9
10
11
12
13
14
15
# File 'lib/rest/operations.rb', line 6

def call_function *args  
#     puts "uri:#{function_uri { args.join('/') } }"
  begin
    term = args.join('/')
rest_resource = Thread.current['resource'] || get_resource 
   rest_resource["/function/#{@database}/#{term}"].post ''
  rescue RestClient::InternalServerError => e
	  puts  JSON.parse(e.http_body)
  end
end

#count(**args) ⇒ Object

Used to count the Records in relation of the arguments

Overwritten by Model#Count



20
21
22
23
24
25
26
# File 'lib/rest/operations.rb', line 20

def count **args
  logger.progname = 'RestOperations#CountRecords'
  query = OrientSupport::OrientQuery.new args
  query.projection  'COUNT(*)'
  result = get_records raw: true, query: query
  result.first["COUNT(*)"] rescue  0  # return_value
end

#execute(transaction: nil, command: nil, tolerated_error_code: nil, process_error: true, raw: nil) ⇒ Object

execute the command

thread-safe ( transaction = false)



141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/rest/operations.rb', line 141

def execute transaction: nil,
	          command: nil,
						tolerated_error_code: nil, 
						process_error: true, 
						raw: nil 
	
	if block_given?
		command =  yield
	end
  unless command.present?	
		logger.error { "No Command  provided to execute" }
		return nil
	end
	if ( transaction.present? || command.is_a?(Array) )
		logger.error  "calling manage_transaction NOT IMPLEMENTED YET!"
		manage_transaction transaction, command
	end		

	 logger.info command.to_s								
	_execute( tolerated_error_code, process_error, raw) do

		ActiveOrient.db_pool.checkout do | conn |
			conn["/command/#{ActiveOrient.database}/sql"].post command.to_s #.to_json
		end
	end

#		rest_resource.delete #if resource.present?

end

#manage_transaction(kind, command) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/rest/operations.rb', line 106

def manage_transaction kind, command
	@transaction = []  unless @transaction.is_a?(Array)

	# in any case:  add statement to array
	command.is_a?(Array) ? command.each{|c| @transaction << c} : @transaction << command

	# if kind is prepare, we a done. 
	# now, combine anything
	unless kind == :prepare
		commands =  @transaction.map{|y| y if y.is_a? String }.compact
		@transaction.delete_if{|y| y if y.is_a?(String)} 
		#puts "tn #{commands.inspect}"
			@transaction <<	{ type: 'script', language: 'sql', script: commands } unless  commands.empty?
#		elsif  transaction ==  false
#			@transaction = 	commands.first
#		else
#			transaction =  true
#			@transaction <<		{ type: 'cmd', language: 'sql', command: commands.first } 

			# transaction is true only for multible statements
			#      batch[:transaction] = transaction & batch[:operations].size >1
#			logger.info{ @transaction.map{|y|y[:command]}.join(";\n ") } 
#				logger.info{ @transaction.map{|y|y[:script]}.join(";\n ") } 
	#		batch= { transaction: transaction, operations: @transaction  }
	#		puts "batch:  #{batch.inspect}"

	#		@res["/batch/#{ActiveOrient.database}"].post batch.to_json
	end
end

#read_transactionObject

Executes a list of commands and returns the result-array (if present)

(External use)

If soley a string is provided in the block, a minimal database-console is realized. i.e.

ORD.execute{ 'select from #25:0' }

(Internal Use)

Structure of the provided block:

[{type: "cmd", language: "sql",  command: "create class Person extends V"}, (...)]

It was first used by ActiveOrient::Query.execute_queries
Later I (topofocus) discovered that some Queries are not interpretated correctly by #GetRecords but are submitted without Error via batch-processing.
For instance, this valid query
 select expand(first_list[5].second_list[9]) from base where label = 9
can only be submitted via batch

++ Parameters:

transaction:  true|false   Perform the batch as transaction
tolerate_error_code: /a regular expression/   
Statements to execute are provided via block
These statements are translated to json and transmitted to the database. Example:

   	{ type: "cmd",
         language: 'sql',
         command: "CREATE EDGE #{classname(o_class)} FROM #{from.to_orient} TO #{to.to_orient}"}

Multible statements are transmitted at once if the Block provides an Array of statements.



102
103
104
# File 'lib/rest/operations.rb', line 102

def read_transaction
	@transaction
end