Module: RestOperations

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

Instance Method Summary collapse

Instance Method Details

#_execute(transaction, tolerated_error_code, process_error, raw) ⇒ Object



133
134
135
136
137
138
139
140
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
170
171
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
# File 'lib/rest/operations.rb', line 133

def _execute transaction, tolerated_error_code, process_error, raw

  logger.progname= "Execute"
  begin
    response = if @transaction.is_a?(Array) 
                 @transaction.compact!
                 return nil if @transaction.empty?
                 # 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
               else
                 logger.info{ @transaction } 
                 @res["/command/#{ActiveOrient.database}/sql"].post @transaction #.to_json
               end
  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::InternalServerError => e
    @transaction = []
    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
        #     puts batch.to_json
        #   logger.error{e.response}
        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
    @transaction = []
    if response.code == 200
      if response.body['result'].present?
        result=JSON.parse(response.body)['result']
        return result if raw.present?
        result.map do |x|
          if x.is_a? Hash
            y = x.transform_keys{|y| y.delete('@').split('=').first.underscore.to_sym}
            if y[:type] == 'd' #0.present?  #  == 'd'  # x.has_key?("@type")   && 
              if y.has_key?(:class)
                the_object = ActiveOrient::Model.orientdb_class( name: y[:class] ).new x
                ActiveOrient::Base.store_rid( the_object )   # update cache
              else   # create a dummy class and fill with attributes from result-set
                ActiveOrient::Model.orientdb_class(name: 'query' ).new x
              end
            else
               # return the result or the corresponding dataset
              r= y.map{ | _,v | v.is_a?(String) && v.rid? ?  ActiveOrient::Model.get( v ): v }
              y.size ==1 ? r.first : r   # return raw instead of array if only one value is present
            end
          end
        end.compact # return_value
      else
        response.body
      end
    else
      nil
    end
  end
end

#call_function(*args) ⇒ Object

untested



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

def call_function *args  
#     puts "uri:#{function_uri { args.join('/') } }"
  begin
    term = args.join('/')
    @res["/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



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

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: false, tolerated_error_code: nil, process_error: true, raw: nil) ⇒ Object



104
105
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
# File 'lib/rest/operations.rb', line 104

def execute transaction: false, tolerated_error_code: nil, process_error: true, raw: nil
  @transaction = []  unless @transaction.is_a?(Array)
  if block_given?
    command =  yield
    command.is_a?(Array) ? command.each{|c| @transaction << c} : @transaction << command
  else
    logger.error { "No Block provided to execute" }
    return nil
  end

#     puts "transaction #{@transaction.inspect}"
  unless transaction == :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}"
    return nil if commands.empty?
    if commands.size >1
    @transaction << { type: 'script', language: 'sql', script: commands } 
    elsif  transaction ==  false
      @transaction =   commands.first
    else
      transaction =  true
      @transaction <<    { type: 'cmd', language: 'sql', command: commands.first } 
    end 
      _execute transaction, tolerated_error_code, process_error, raw
  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  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.



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

def read_transaction
  @transaction
end