Class: OrientSupport::OrientQuery

Inherits:
Object
  • Object
show all
Includes:
Support
Defined in:
lib/support/orientquery.rb

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Support

#compose_where, #generate_sql_list

Constructor Details

#initialize(**args) ⇒ OrientQuery

Returns a new instance of OrientQuery.


194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# File 'lib/support/orientquery.rb', line 194

def initialize  **args
	@q =  QueryAttributes.new args[:kind] ||	'select' ,
						[], #		 :projection 
						[], # :where ,
						[], # :let ,
						[], # :order,
						[], # :while],
						[] , # misc
						[],  # match_statements
						'',  # class
						'',  #  return
						[],   # aliases
						''  # database
	  args.each{|k,v| send k, v}
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method, *arg, &b) ⇒ Object

where: “r > 9” –> where r > 9

where: {a: 9, b: 's'}                   --> where a = 9 and b = 's'
where:[{ a: 2} , 'b > 3',{ c: 'ufz' }]  --> where a = 2 and b > 3 and c = 'ufz'

222
223
224
225
# File 'lib/support/orientquery.rb', line 222

def method_missing method, *arg, &b   # :nodoc: 
  @q[:misc] << method.to_s <<  generate_sql_list(arg) 
			self
end

Class Method Details

.mk_simple_setter(*m) ⇒ Object


385
386
387
388
389
390
391
392
393
394
395
# File 'lib/support/orientquery.rb', line 385

def mk_simple_setter *m
	m.each do |def_m|
		define_method( def_m ) do | value=nil |
				if value.present?
					@q[def_m]  = value
				elsif @q[def_m].present?
				 "#{def_m.to_s}  #{generate_sql_list(@q[def_m]){' ,'}}"
				end
		end
	end
end

Instance Method Details

#compose(destination: :batch) ⇒ Object Also known as: to_s

Output the compiled query

Parameter: destination (rest, batch )
If the query is submitted via the REST-Interface (as get-command), the limit parameter is extracted.

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/support/orientquery.rb', line 298

def compose(destination: :batch)
	if kind.to_sym == :match
		unless @q[:match_statements].empty?
			match_query =  kind.to_s.upcase + " "+ @q[:match_statements][0].compose 
			match_query << @q[:match_statements][1..-1].map( &:compose ).join
			match_query << " RETURN "<< (@q[:match_statements].map( &:as ).compact | @q[:aliases]).join(', ')
		end
	elsif kind.to_sym == :update
		return_statement = "return after " + ( @q[:aliases].empty? ?  "$this" : @q[:aliases].first.to_s)
		[ kind, @q[:database], misc, where, return_statement ].compact.join(' ')
	elsif destination == :rest
		[ kind, projection, from, let, where, subquery,  misc, order, group_by, unwind, skip].compact.join(' ')
	else
		[ kind, projection, from, let, where, subquery,  misc, order, group_by, limit, unwind, skip].compact.join(' ')
	end
end

#connect(direction, edge_class: nil, count: 1, as: nil) ⇒ Object

(only if kind == :match): connect

Add a connection to the match-query

A Match-Query alwas has an Entry-Stratement and maybe other Statements. They are connected via “ -> ” (outE), “<-” (inE) or “–” (both).

The connection method adds a connection to the statement-stack.

Parameters:

direction: :in, :out, :both
edge_class: to restrict the Query on a certain Edge-Class
count: To repeat the connection
as:  Includes a micro-statement to finalize the Match-Query
     as: defines a output-variablet, which is used later in the return-statement

The method returns the OrientSupport::MatchConnection object, which can be modified further. It is compiled by calling compose


265
266
267
268
269
# File 'lib/support/orientquery.rb', line 265

def connect direction, edge_class: nil, count: 1, as: nil
	direction= :both unless [ :in, :out].include? direction
	match_statements <<  OrientSupport::MatchConnection.new( direction: direction, count: count, as: as)
	self  #  return the object
end

#connect_with(in_or_out, via: nil) ⇒ Object

connects by adding in_or_out('edgeClass')


461
462
463
# File 'lib/support/orientquery.rb', line 461

def connect_with in_or_out, via: nil
	 argument = " #{in_or_out}(#{via.to_or if via.present?})"
end

#database_classObject

:nodoc:


363
364
365
# File 'lib/support/orientquery.rb', line 363

def database_class            # :nodoc:
   @q[:database]
end

#database_class=(arg) ⇒ Object

:nodoc:


367
368
369
# File 'lib/support/orientquery.rb', line 367

def database_class= arg   # :nodoc:
 @q[:database] = arg 
end

#distinct(d) ⇒ Object


379
380
381
382
# File 'lib/support/orientquery.rb', line 379

def distinct d
	@q[:projection] << "distinct " +  generate_sql_list( d ){ ' as ' }
	self
end

#expand(item) ⇒ Object


455
456
457
458
# File 'lib/support/orientquery.rb', line 455

def expand item
			@q[:projection] =[ " expand ( #{item.to_s} )" ]
			self
end

#from(arg = nil) ⇒ Object


321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
# File 'lib/support/orientquery.rb', line 321

def from arg = nil
	if arg.present?
		@q[:database] = case arg
										when ActiveOrient::Model   # a single record
											arg.rrid
										when OrientQuery	      # result of a query
											' ( '+ arg.to_s + ' ) '
										when Class
											arg.ref_name
										else
											if arg.to_s.rid?	  # a string with "#ab:cd"
												arg
											else		  # a database-class-name
												arg.to_s  
											end
										end
		self
	elsif  @q[:database].present? # read from
		"from #{@q[:database]}" 
	end
end

#get_limitObject

:nodoc:


451
452
453
# File 'lib/support/orientquery.rb', line 451

def get_limit  # :nodoc: 
	@q[:limit].nil? ? -1 : @q[:limit].to_i
end

#group(value = nil) ⇒ Object Also known as: group_by


439
440
441
442
443
444
445
446
# File 'lib/support/orientquery.rb', line 439

def group value = nil
			if value.present?
 	@q[:group] << value
			self
			elsif @q[:group].present?
"group by #{@q[:group].join(', ')}"
			end
end

#kind(value = nil) ⇒ Object


236
237
238
239
240
241
242
243
# File 'lib/support/orientquery.rb', line 236

def kind value=nil
	if value.present?
		@q[:kind] = value
		self
	else
	@q[:kind]
	end
end

#let(value = nil) ⇒ Object


399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
# File 'lib/support/orientquery.rb', line 399

def let       value = nil
	if value.present?
		@q[:let] << value
		self
	elsif @q[:let].present?
		"let " << @q[:let].map do |s|
			case s
			when String
				s
			when ::Array
				s.join(',  ')
			when ::Hash  ### is not recognized in jruby
				#	      else
				s.map{|x,y| "$#{x} = (#{y})"}.join(', ')
			end
		end.join(', ')
	end
end

#miscObject

:nodoc:


227
228
229
# File 'lib/support/orientquery.rb', line 227

def misc   # :nodoc:
	@q[:misc].join(' ') unless @q[:misc].empty?
end

#nodes(in_or_out = :out, via: nil, where: nil, expand: true) ⇒ Object

adds a connection

in_or_out:  :out --->  outE('edgeClass').in[where-condition] 
            :in  --->  inE('edgeClass').out[where-condition]

468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/support/orientquery.rb', line 468

def nodes in_or_out = :out, via: nil, where: nil, expand: true
	 condition = where.present? ?  "[ #{generate_sql_list(where)} ]" : ""
	 start =  in_or_out 
	 the_end =  in_or_out == :in ? :out : :in
	 argument = " #{start}E(#{[via].flatten.map(&:to_or).join(',') if via.present?}).#{the_end}#{condition} "

	 if expand.present?
		 send :expand, argument
	 else
		 @q[:projection]  << argument 
	 end
	 self
end

#order(value = nil) ⇒ Object Also known as: order_by


344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/support/orientquery.rb', line 344

def order  value = nil
	if value.present?
		@q[:order] << value
	elsif @q[:order].present?

		"order by " << @q[:order].compact.flatten.map do |o|
			case o
			when String, Symbol, Array
				o.to_s
			else
				o.map{|x,y| "#{x} #{y}"}.join(" ")
			end  # case
		end.join(', ')
	else
		''
	end # unless
end

#projection(value = nil) ⇒ Object

:nodoc:


418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/support/orientquery.rb', line 418

def projection value= nil  # :nodoc:
	if value.present?
		@q[:projection] << value
		self
	elsif  @q[:projection].present?
		@q[:projection].compact.map do | s |
			case s
			when Array
				s.join(', ')
			when String, Symbol
				s.to_s
			else
				s.map{ |x,y| "#{x} as #{y}"}.join( ', ')
			end
		end.join( ', ' )
	end
end

#start(value) ⇒ Object


210
211
212
213
214
215
# File 'lib/support/orientquery.rb', line 210

def start value
			@q[:kind] = :match
			@q[:match_statements] = [ MatchStatement.new( value) ]
			#  @match_statements[1] = MatchConnection.new
			self
end

#statement(match_class = nil, **args) ⇒ Object

(only if kind == :match): statement

A Match Query consists of a simple start-statement ( classname and where-condition ), a connection followd by other Statement-connection-pairs. It performs a sub-query starting at the given entry-point.

Statement adds a statement to the statement-stack. Statement returns the created OrientSupport::MatchStatement-record for further modifications. It is compiled by calling »compose«.

OrientSupport::OrientQuery collects any “as”-directive for inclusion in the return-statement

Parameter (all optional)

Class: classname, :where: {}, while: {}, as: string, maxdepth: >0 ,

288
289
290
291
# File 'lib/support/orientquery.rb', line 288

def statement match_class= nil, **args
	match_statements <<  OrientSupport::MatchStatement.new( match_class, args )
	self  #  return the object
end

#subqueryObject

:nodoc:


231
232
233
# File 'lib/support/orientquery.rb', line 231

def subquery  # :nodoc: 
  nil
end

#where(value = nil) ⇒ Object

:nodoc:


371
372
373
374
375
376
377
378
# File 'lib/support/orientquery.rb', line 371

def where  value=nil     # :nodoc:
	if value.present?
		@q[:where] << value
		self
	elsif @q[:where].present?
		"where #{ generate_sql_list( @q[:where] ) }"
	end
end