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  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