Class: ApacheAge::Entities::QueryBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/apache_age/entities/query_builder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model_class, return_clause: nil, match_clause: nil, graph_name: nil) ⇒ QueryBuilder

Returns a new instance of QueryBuilder.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/apache_age/entities/query_builder.rb', line 21

def initialize(
  model_class, return_clause: nil, match_clause: nil, graph_name: nil
  # model_class, path_edge: nil, path_length: nil, path_properties: nil, return_clause: nil, match_clause: nil, graph_name: nil
)
  # @path_edge = path_length
  # @path_length = path_length
  # @path_properties = path_properties
  @model_class = model_class
  @where_clauses = []
  @return_clause = return_clause ? return_clause : 'find'
  @return_names = [@return_clause]
  @return_variables = []
  @order_clause = nil
  @limit_clause = nil
  @match_clause = match_clause ? match_clause : model_class.match_clause
  @graph_name = graph_name || model_class.age_graph
end

Instance Attribute Details

#graph_nameObject

Returns the value of attribute graph_name.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def graph_name
  @graph_name
end

#limit_clauseObject

Returns the value of attribute limit_clause.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def limit_clause
  @limit_clause
end

#match_clauseObject

Returns the value of attribute match_clause.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def match_clause
  @match_clause
end

#model_classObject

Returns the value of attribute model_class.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def model_class
  @model_class
end

#order_clauseObject

Returns the value of attribute order_clause.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def order_clause
  @order_clause
end

#path_edge_nameObject

Returns the value of attribute path_edge_name.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def path_edge_name
  @path_edge_name
end

#path_lengthObject

Returns the value of attribute path_length.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def path_length
  @path_length
end

#path_propertiesObject

Returns the value of attribute path_properties.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def path_properties
  @path_properties
end

#return_clauseObject

Returns the value of attribute return_clause.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def return_clause
  @return_clause
end

#return_namesObject

Returns the value of attribute return_names.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def return_names
  @return_names
end

#return_variablesObject

Returns the value of attribute return_variables.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def return_variables
  @return_variables
end

#where_clausesObject

Returns the value of attribute where_clauses.



17
18
19
# File 'lib/apache_age/entities/query_builder.rb', line 17

def where_clauses
  @where_clauses
end

Instance Method Details

#allObject



102
103
104
105
106
107
108
# File 'lib/apache_age/entities/query_builder.rb', line 102

def all
  cypher_sql = build_query
  results = model_class.send(:execute_where, cypher_sql)
  return results if return_variables.empty?

  results.map(&:to_h).map { _1.slice(*return_variables) }
end

#executeObject



110
111
112
113
# File 'lib/apache_age/entities/query_builder.rb', line 110

def execute
  cypher_sql = build_query
  model_class.send(:execute_sql, cypher_sql)
end

#firstObject



115
116
117
118
# File 'lib/apache_age/entities/query_builder.rb', line 115

def first
  cypher_sql = build_query(limit_clause || "LIMIT 1")
  model_class.send(:execute_find, cypher_sql)
end

#limit(limit_value) ⇒ Object



97
98
99
100
# File 'lib/apache_age/entities/query_builder.rb', line 97

def limit(limit_value)
  @limit_clause = "LIMIT #{limit_value}"
  self
end

#match(match_string) ⇒ Object



39
40
41
42
# File 'lib/apache_age/entities/query_builder.rb', line 39

def match(match_string)
  @match_clause = match_string
  self
end

#order(ordering) ⇒ Object



88
89
90
91
92
93
94
95
# File 'lib/apache_age/entities/query_builder.rb', line 88

def order(ordering)
  @order_clause = nil
  return self if ordering.blank?

  order_by_values = Array.wrap(ordering).map { |order| parse_ordering(order) }.join(', ')
  @order_clause = "ORDER BY #{order_by_values}"
  self
end

#return(*variables) ⇒ Object

New return method



81
82
83
84
85
86
# File 'lib/apache_age/entities/query_builder.rb', line 81

def return(*variables)
  return self if variables.blank?

  @return_variables = variables
  self
end

#to_sqlObject



120
121
122
# File 'lib/apache_age/entities/query_builder.rb', line 120

def to_sql
  build_query.strip
end

#where(*args) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/apache_age/entities/query_builder.rb', line 44

def where(*args)
  return self if args.blank?

  @where_clauses <<
    # not able to sanitize the query string in this case: `["first_name = 'Barney'"]`
    if args.length == 1 && args.first.is_a?(String)
      raw_query_string = args.first
      transform_cypher_sql(raw_query_string)

    # Handling & sanitizing parameterized string queries
    elsif args.length > 1 && args.first.is_a?(String)
      raw_query_string = args.first
      # Replace `id = ?` with `id(find) = ?` and `first_name = ?` with `find.first_name = ?`
      query_string = transform_cypher_sql(raw_query_string)
      values = args[1..-1]
      # sanitize sql input values
      ActiveRecord::Base.sanitize_sql_array([query_string, *values])

    # Hashes are sanitized in the model class
    # [{:first_name=>"Barney", :last_name=>"Rubble", :gender=>"male"}]
    elsif args.first.is_a?(Hash)
      attributes = args.first
      edge_keys = [:start_id, :start_node, :end_id, :end_node]
      if edge_keys.any? { |key| attributes.include?(key) }
        model_class.send(:where_edge_clause, **attributes)
      else
        model_class.send(:where_node_clause, **attributes)
      end

    else
      raise ArgumentError, "Invalid arguments for `where` method"
    end

  self
end