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

#as, #compose_where, #generate_sql_list, #where, #while_s

Constructor Details

#initialize(**args) ⇒ OrientQuery

Returns a new instance of OrientQuery.



334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
# File 'lib/support/orientquery.rb', line 334

def initialize  **args
	@q =  QueryAttributes.new args[:kind] ||	'select' ,
						[], #		 :projection 
						[], # :where ,
						[], # :let ,
						[], # :order,
						[], # :while,
						[] , # misc
						'',  # class
						'',  #  return
						[],   # aliases
						'',  # database
						[],   #set,
						[]  # remove
	  args.each{|k,v| send k, v}
		@fill = block_given? ?   yield  : 'and'
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'


358
359
360
361
362
363
364
365
# File 'lib/support/orientquery.rb', line 358

def method_missing method, *arg, &b   # :nodoc: 
			if method ==:while || method=='while'
while_s arg.first
			else
@q[:misc] << method.to_s <<  generate_sql_list(arg) 
			end 
			self
end

Class Method Details

.mk_simple_setter(*m) ⇒ Object



488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/support/orientquery.rb', line 488

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

.mk_std_setter(*m) ⇒ Object



500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
# File 'lib/support/orientquery.rb', line 500

def mk_std_setter *m
	m.each do |def_m|
		define_method( def_m  ) do | value = nil |
			if value.present?
				@q[def_m] << case value
											when String
												value
											when ::Hash
												value.map{|k,v| "#{k} = #{v.to_or}"}.join(", ")
											else
												raise "Only String or Hash allowed in  #{def_m} statement"
											end
				self
			elsif @q[def_m].present?
				"#{def_m.to_s} #{@q[def_m].join(',')}"	
			end # branch
		end     # def_method
	end  # each
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.


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
# File 'lib/support/orientquery.rb', line 390

def compose(destination: :batch)
	if kind.to_sym == :update 
		return_statement = "return after " + ( @q[:aliases].empty? ?  "$current" : @q[:aliases].first.to_s)
		[ 'update', target, set, remove, return_statement , where, limit ].compact.join(' ')
	elsif kind.to_sym == :update!
		[ 'update', target, set,  where, limit, misc ].compact.join(' ')
	elsif kind.to_sym == :create
		[ "CREATE VERTEX", target, set ].compact.join(' ')
	#	[ kind, target, set,  return_statement ,where,  limit, misc ].compact.join(' ')
	elsif kind.to_sym == :upsert 
		return_statement = "return after " + ( @q[:aliases].empty? ?  "$current" : @q[:aliases].first.to_s)
		[ "update", target, set,"upsert",  return_statement , where, limit, misc  ].compact.join(' ')
		#[ kind,  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,  while_s,  misc, order, group_by, limit, unwind, skip].compact.join(' ')
	end
end

#connect_with(in_or_out, via: nil) ⇒ Object

connects by adding in_or_out(‘edgeClass’)



590
591
592
# File 'lib/support/orientquery.rb', line 590

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

#database_classObject

:nodoc:



474
475
476
# File 'lib/support/orientquery.rb', line 474

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

#database_class=(arg) ⇒ Object

:nodoc:



478
479
480
# File 'lib/support/orientquery.rb', line 478

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

#distinct(d) ⇒ Object



482
483
484
485
# File 'lib/support/orientquery.rb', line 482

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

#execute(reduce: false) ⇒ Object

returns nil if the query was not sucessfully executed



625
626
627
628
629
630
631
632
633
# File 'lib/support/orientquery.rb', line 625

def execute(reduce: false)
	#puts "Compose: #{compose}"
	result = V.orientdb.execute{ compose }
	return nil unless result.is_a?(::Array)
	result =  result.map{|x| yield x } if block_given?
	return  result.first if reduce && result.size == 1
	## standard case: return Array
	OrientSupport::Array.new( work_on: resolve_target, work_with: result.orient_flatten)   
end

#expand(item) ⇒ Object



584
585
586
587
# File 'lib/support/orientquery.rb', line 584

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

#from(arg = nil) ⇒ Object

from can either be a Databaseclass to operate on or a Subquery providing data to query further



444
445
446
447
448
449
450
451
# File 'lib/support/orientquery.rb', line 444

def from arg = nil
	if arg.present?
		@q[:database] =  arg
		self # return query-object
	elsif  @q[:database].present? # read from
		"from #{ target }"
	end
end

#get_limitObject

:nodoc:



580
581
582
# File 'lib/support/orientquery.rb', line 580

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

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



568
569
570
571
572
573
574
575
# File 'lib/support/orientquery.rb', line 568

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



376
377
378
379
380
381
382
383
# File 'lib/support/orientquery.rb', line 376

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

#let(value = nil) ⇒ Object



523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
# File 'lib/support/orientquery.rb', line 523

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 ::Hash  
				s.map do |x,y| 
					# if the symbol: value notation of Hash is used, add "$" to the key
					x =  "$#{x.to_s}"  unless x.is_a?(String) && x[0] == "$"
					"#{x} = #{ case y 
																when self.class
																	"(#{y.compose})"
																else
																	y.to_orient
																end }"
				end
			end
		end.join(', ')
	end
end

#miscObject

:nodoc:



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

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]


597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
# File 'lib/support/orientquery.rb', line 597

def nodes in_or_out = :out, via: nil, where: nil, expand: true
	 condition = where.present? ?  "[ #{generate_sql_list(where)} ]" : ""
	 start =  if in_or_out  == :in
							'inE'
						elsif in_or_out ==  :out
							'outE'
						else
							"both"
						end
	 the_end =  if in_or_out == :in 
								'.out' 
							elsif in_or_out == :out
								'.in'
							else
								''
							end
	 argument = " #{start}(#{[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



454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
# File 'lib/support/orientquery.rb', line 454

def order  value = nil
	if value.present?
		@q[:order] << value
		self
	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:



548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
# File 'lib/support/orientquery.rb', line 548

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
			when ::Hash
				s.map{ |x,y| "#{x} as #{y}"}.join( ', ')
			end
		end.join( ', ' )
	end
end

#resolve_targetObject



635
636
637
638
639
640
641
# File 'lib/support/orientquery.rb', line 635

def resolve_target
	if @q[:database].is_a? OrientSupport::OrientQuery
		@q[:database].resolve_target
	else
		@q[:database]
	end
end

#subqueryObject

:nodoc:



371
372
373
# File 'lib/support/orientquery.rb', line 371

def subquery  # :nodoc: 
  nil
end

#target(arg = nil) ⇒ Object



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

def target arg =  nil
	if arg.present?
		@q[:database] =  arg
		self # return query-object
	elsif @q[:database].present? 
		the_argument =  @q[:database]
		case @q[:database]
							when ActiveOrient::Model   # a single record
								the_argument.rrid
							when self.class	      # result of a query
								' ( '+ the_argument.compose + ' ) '
							when Class
								the_argument.ref_name
							else
								if the_argument.to_s.rid?	  # a string with "#ab:cd"
									the_argument
								else		  # a database-class-name
									the_argument.to_s  
								end
							end
	else
		raise "cannot complete until a target is specified"
	end
end

#to_orObject



412
413
414
# File 'lib/support/orientquery.rb', line 412

def to_or
	compose.to_or
end