Class: Ferret::Expression
- Inherits:
-
Object
- Object
- Ferret::Expression
- Includes:
- Constants
- Defined in:
- lib/sql-ferret.rb
Constant Summary
Constants included from Constants
Constants::QSF_MULTICOL, Constants::QSF_MULTIROW
Instance Attribute Summary collapse
-
#exemplars ⇒ Object
readonly
Returns the value of attribute exemplars.
-
#multicolumn ⇒ Object
Returns the value of attribute multicolumn.
-
#selectees ⇒ Object
readonly
Returns the value of attribute selectees.
-
#stages ⇒ Object
readonly
Returns the value of attribute stages.
-
#type ⇒ Object
Returns the value of attribute type.
Instance Method Summary collapse
- #assign_stage_qualifiers(ag) ⇒ Object
- #from_clause ⇒ Object
-
#initialize ⇒ Expression
constructor
A new instance of Expression.
- #modification? ⇒ Boolean
-
#select ⇒ Object
Prepare a [[select]] statement as an [[Annotated_SQL_Template]].
- #where_clause ⇒ Object
Constructor Details
#initialize ⇒ Expression
Returns a new instance of Expression.
929 930 931 932 933 934 935 936 937 |
# File 'lib/sql-ferret.rb', line 929 def initialize super() @stages = [Ferret::Stage.new(nil, nil, :left)] @selectees = [] @exemplars = [] @multicolumn = false @type = :select # the default return end |
Instance Attribute Details
#exemplars ⇒ Object (readonly)
Returns the value of attribute exemplars.
925 926 927 |
# File 'lib/sql-ferret.rb', line 925 def exemplars @exemplars end |
#multicolumn ⇒ Object
Returns the value of attribute multicolumn.
926 927 928 |
# File 'lib/sql-ferret.rb', line 926 def multicolumn @multicolumn end |
#selectees ⇒ Object (readonly)
Returns the value of attribute selectees.
924 925 926 |
# File 'lib/sql-ferret.rb', line 924 def selectees @selectees end |
#stages ⇒ Object (readonly)
Returns the value of attribute stages.
923 924 925 |
# File 'lib/sql-ferret.rb', line 923 def stages @stages end |
#type ⇒ Object
Returns the value of attribute type.
927 928 929 |
# File 'lib/sql-ferret.rb', line 927 def type @type end |
Instance Method Details
#assign_stage_qualifiers(ag) ⇒ Object
939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 |
# File 'lib/sql-ferret.rb', line 939 def assign_stage_qualifiers ag raise 'type mismatch' \ unless ag.is_a? Ferret::Alias_Generator table_visit_counts = Hash.new 0 # name => count @stages.each_with_index do |stage, i| table_visit_counts[stage.table.name] += 1 end # The tables that we visited more than once need # distinguishing names. @stages.each do |stage| stage.qualifier = if table_visit_counts[stage.table.name] > 1 then ag.create stage.table.name[0] else stage.table.name end end return end |
#from_clause ⇒ Object
960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 |
# File 'lib/sql-ferret.rb', line 960 def from_clause clause = "from " @stages.each_with_index do |stage, i| # In case of a non-query expression -- a modification --, # the last stage is empty and mustn't be joined. It then # serves only the purpose of holding the last stalk. break if i == @stages.length - 1 and modification? unless i.zero? then clause << " #{stage.join_type} join " end clause << stage.table.name << " as " << stage.qualifier unless i.zero? then clause << " on %s.%s = %s.%s" % [ stage.parent.qualifier, (stage.stalk.haunt || stage.stalk).name, stage.qualifier, stage.stalk.ref.name, ] end end return clause end |
#modification? ⇒ Boolean
1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 |
# File 'lib/sql-ferret.rb', line 1046 def modification? case @type when :select, :select_distinct then return false when :update, :insert, :delete then return true else raise 'assertion failed' end end |
#select ⇒ Object
Prepare a [[select]] statement as an [[Annotated_SQL_Template]]. If this expression represents a query statement, the result will cover the whole query. If it represents an update statement, the result will cover the subquery that determines key value(s) of records in the last table to update.
1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 |
# File 'lib/sql-ferret.rb', line 1008 def select qualifiers_needed = @stages.length != (modification? ? 2 : 1) sql_selectees = @selectees.map do |selectee| (qualifiers_needed ? selectee.stage.qualifier + "." : "") + (selectee.field.haunt || selectee.field).name end.join(', ') outputs = {} @selectees.each do |selectee| outputs[selectee.output_name.to_sym] = selectee.interpretation end sql = "select" sql << " distinct" if @type == :select_distinct sql << " " << sql_selectees << " " << from_clause sql << " " << where_clause unless @exemplars.empty? # Determine the shape of the table shape = 0 shape |= QSF_MULTICOL if @multicolumn # If no [[unique]] exemplar field is specified or if any of # the joins is performed along a ghost field (i.e., # possibly a 1->n reference), our result will have multiple # rows. shape |= QSF_MULTIROW \ unless @exemplars.any?{|ex| ex.column.unique?} and !@stages[1 .. -1].any?{|stage| stage.stalk.ghost?} return Ferret::Annotated_SQL_Template.new(sql, outputs, shape) end |
#where_clause ⇒ Object
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 |
# File 'lib/sql-ferret.rb', line 985 def where_clause raise 'assertion failed' if @exemplars.empty? clause = "where " @exemplars.each_with_index do |exemplar, i| clause << " and " unless i.zero? # The qualifier is only necessary if the clause has more # than one stage. if @stages.length > 1 then # In the navigational model, the (primary) filter always # lives in the zeroth stage. clause << @stages[0].qualifier << "." end clause << exemplar.column.name << " [test #{i}]" end return clause end |