Class: Card::Query
- Inherits:
-
Object
- Object
- Card::Query
- Includes:
- Attributes, Clause, Conjunctions, Helpers, Interpretation, RelationalAttributes, Sorting
- Defined in:
- lib/card/query.rb,
lib/card/query/join.rb,
lib/card/query/value.rb,
lib/card/query/helpers.rb,
lib/card/query/sorting.rb,
lib/card/query/reference.rb,
lib/card/query/attributes.rb,
lib/card/query/conjunctions.rb,
lib/card/query/sql_statement.rb,
lib/card/query/interpretation.rb,
lib/card/query/relational_attributes.rb
Overview
Card::Query is for finding implicit lists (or counts of lists) of cards.
Search and Set cards use Card::Query to query the database, and it's also frequently used directly in code.
Query "statements" (objects, really) are made in WQL (Wagn Query Language). Because WQL is used by Wagneers, the primary language documentation is on wagn.org. (http://wagn.org/WQL_Syntax). Note that the examples there are in JSON, like Search card content, but statements in Card::Query are in ruby form.
In Wagn's current form, Card::Query generates and executes SQL statements. However, the SQL generation is largely (not yet fully) separated from the WQL statement interpretation.
The most common way to use Card::Query is as follows: list_of_cards = Card::Query.run(statement)
This is equivalent to: query = Card::Query.new(statement) list_of_cards = query.run
Upon initiation, the query is interpreted, and the following key objects are populated:
- @join - an Array of Card::Query::Join objects
- @conditions - an Array of conditions
- @mod - a Hash of other query-altering keys
- @subqueries - a list of other queries nested within this one
Each condition is either a SQL-ready string (boo) or an Array in this form: [ field_string_or_sym, Card::Value::Query object ]
Defined Under Namespace
Modules: Attributes, Clause, Conjunctions, Helpers, Interpretation, RelationalAttributes, Sorting Classes: Join, Reference, SqlStatement, Value
Constant Summary collapse
- ATTRIBUTES =
{ basic: %w( id name key type_id content left_id right_id creator_id updater_id codename read_rule_id ), relational: %w( type part left right editor_of edited_by last_editor_of last_edited_by creator_of created_by member_of member ), plus_relational: %w(plus left_plus right_plus), ref_relational: %w( refer_to referred_to_by link_to linked_to_by include included_by ), conjunction: %w(and or all any), special: %w(found_by not sort match complete extension_type), ignore: %w(prepend append view params vars size) }.each_with_object({}) do |pair, h| pair[1].each { |v| h[v.to_sym] = pair[0] } end
- CONJUNCTIONS =
{ any: :or, in: :or, or: :or, all: :and, and: :and }.freeze
- MODIFIERS =
%w(conj return sort sort_as group dir limit offset) .each_with_object({}) { |v, h| h[v.to_sym] = nil }
- OPERATORS =
%w(!= = =~ < > in ~).each_with_object({}) { |v, h| h[v] = v }.merge( { eq: "=", gt: ">", lt: "<", match: "~", ne: "!=", "not in" => nil }.stringify_keys )
- DEFAULT_ORDER_DIRS =
{ update: "desc", relevance: "desc" }.freeze
Constants included from Sorting
Sorting::SORT_JOIN_TO_ITEM_MAP
Instance Attribute Summary collapse
-
#comment ⇒ Object
readonly
Returns the value of attribute comment.
-
#conditions ⇒ Object
readonly
Returns the value of attribute conditions.
-
#conditions_on_join ⇒ Object
Returns the value of attribute conditions_on_join.
-
#joins ⇒ Object
Returns the value of attribute joins.
-
#mods ⇒ Object
readonly
Returns the value of attribute mods.
-
#statement ⇒ Object
readonly
Returns the value of attribute statement.
-
#subqueries ⇒ Object
readonly
Returns the value of attribute subqueries.
-
#superquery ⇒ Object
readonly
Returns the value of attribute superquery.
-
#table_seq ⇒ Object
Returns the value of attribute table_seq.
-
#unjoined ⇒ Object
Returns the value of attribute unjoined.
Class Method Summary collapse
-
.run(statement, comment = nil) ⇒ Object
By default a query returns card objects.
Instance Method Summary collapse
- #context ⇒ Object
- #default_comment ⇒ Object
-
#get_results(retrn) ⇒ Object
Integer for :count, otherwise Array of Strings or Integers.
-
#initialize(statement, comment = nil) ⇒ Query
constructor
A new instance of Query.
-
#root ⇒ Object
Query Hierarchy @root, @subqueries, and @superquery are used to track a hierarchy of query objects.
-
#run ⇒ Object
run the current query.
- #run_sql ⇒ Object
- #sql ⇒ Object
- #subquery(opts = {}) ⇒ Object
Methods included from Helpers
#id_from_val, #join_cards, #join_references, #restrict, #restrict_reference, #table_alias, #table_id, #tick_table_seq!
Methods included from Conjunctions
#all, #any, #conjoin, #conjunction, #not
Methods included from Sorting
Methods included from Interpretation
#add_condition, #all_joins, #clause_to_hash, #current_conjunction, #interpret, #interpret_attributes, #interpret_by_key, #normalize_clause, #normalize_string_value, #normalize_value, #relate, #relate_compound, #relate_multi_value
Methods included from RelationalAttributes
#created_by, #creator_of, #edited_by, #editor_of, #junction, #last_edited_by, #last_editor_of, #left, #left_plus, #member, #member_of, #part, #plus, #right, #right_plus, #type
Methods included from Attributes
#complete, #extension_type, #found_by, #found_by_cards, #match
Methods included from Clause
#match_prep, #quote, #safe_sql
Constructor Details
#initialize(statement, comment = nil) ⇒ Query
Returns a new instance of Query.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/card/query.rb', line 97 def initialize statement, comment=nil @subqueries = [] @conditions = [] @joins = [] @mods = {} @statement = statement.clone @context = @statement.delete(:context) || nil @unjoined = @statement.delete(:unjoined) || nil @superquery = @statement.delete(:superquery) || nil @vars = @statement.delete(:vars) || {} @vars.symbolize_keys! @comment = comment || default_comment interpret @statement self end |
Instance Attribute Details
#comment ⇒ Object (readonly)
Returns the value of attribute comment.
83 84 85 |
# File 'lib/card/query.rb', line 83 def comment @comment end |
#conditions ⇒ Object (readonly)
Returns the value of attribute conditions.
83 84 85 |
# File 'lib/card/query.rb', line 83 def conditions @conditions end |
#conditions_on_join ⇒ Object
Returns the value of attribute conditions_on_join.
85 86 87 |
# File 'lib/card/query.rb', line 85 def conditions_on_join @conditions_on_join end |
#joins ⇒ Object
Returns the value of attribute joins.
85 86 87 |
# File 'lib/card/query.rb', line 85 def joins @joins end |
#mods ⇒ Object (readonly)
Returns the value of attribute mods.
83 84 85 |
# File 'lib/card/query.rb', line 83 def mods @mods end |
#statement ⇒ Object (readonly)
Returns the value of attribute statement.
83 84 85 |
# File 'lib/card/query.rb', line 83 def statement @statement end |
#subqueries ⇒ Object (readonly)
Returns the value of attribute subqueries.
83 84 85 |
# File 'lib/card/query.rb', line 83 def subqueries @subqueries end |
#superquery ⇒ Object (readonly)
Returns the value of attribute superquery.
83 84 85 |
# File 'lib/card/query.rb', line 83 def superquery @superquery end |
#table_seq ⇒ Object
Returns the value of attribute table_seq.
85 86 87 |
# File 'lib/card/query.rb', line 85 def table_seq @table_seq end |
#unjoined ⇒ Object
Returns the value of attribute unjoined.
85 86 87 |
# File 'lib/card/query.rb', line 85 def unjoined @unjoined end |
Class Method Details
.run(statement, comment = nil) ⇒ Object
By default a query returns card objects. This is accomplished by returning a card identifier from SQL and then hooking into our caching system (see Card::Fetch)
93 94 95 |
# File 'lib/card/query.rb', line 93 def self.run statement, comment=nil new(statement, comment).run end |
Instance Method Details
#context ⇒ Object
176 177 178 179 180 181 182 |
# File 'lib/card/query.rb', line 176 def context if !@context.nil? @context else @context = @superquery ? @superquery.context : "" end end |
#default_comment ⇒ Object
116 117 118 119 |
# File 'lib/card/query.rb', line 116 def default_comment return if @superquery || !Card.config.sql_comments statement.to_s end |
#get_results(retrn) ⇒ Object
Returns Integer for :count, otherwise Array of Strings or Integers.
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/card/query.rb', line 135 def get_results retrn rows = run_sql if retrn == "name" && (statement[:prepend] || statement[:append]) rows.map do |row| [statement[:prepend], row["name"], statement[:append]].compact * "+" end else case retrn when "count" then rows.first["count"].to_i when "raw" then rows when /id$/ then rows.map { |row| row[retrn].to_i } else rows.map { |row| row[retrn] } end end end |
#root ⇒ Object
Query Hierarchy @root, @subqueries, and @superquery are used to track a hierarchy of query objects. This nesting allows to find, for example, cards that link to cards that link to cards....
166 167 168 |
# File 'lib/card/query.rb', line 166 def root @root ||= @superquery ? @superquery.root : self end |
#run ⇒ Object
run the current query
123 124 125 126 127 128 129 130 131 132 |
# File 'lib/card/query.rb', line 123 def run retrn = statement[:return].present? ? statement[:return].to_s : "card" if retrn == "card" get_results("name").map do |name| Card.fetch name, new: {} end else get_results retrn end end |
#run_sql ⇒ Object
151 152 153 154 155 |
# File 'lib/card/query.rb', line 151 def run_sql # puts "\nstatement = #{@statement}" # puts "sql = #{sql}" ActiveRecord::Base.connection.select_all(sql) end |
#sql ⇒ Object
157 158 159 |
# File 'lib/card/query.rb', line 157 def sql @sql ||= SqlStatement.new(self).build.to_s end |