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. (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 ) }.inject({}) { |h, pair| pair[1].each { |v| h[v.to_sym] = pair[0] }; h }
- CONJUNCTIONS =
{ any: :or, in: :or, or: :or, all: :and, and: :and }.freeze
- MODIFIERS =
%w( conj return sort sort_as group dir limit offset ) .inject({}) { |h, v| h[v.to_sym] = nil; h }
- OPERATORS =
%w( != = =~ < > in ~ ).inject({}) { |h, v| h[v] = v; h }.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.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/card/query.rb', line 93 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.
78 79 80 |
# File 'lib/card/query.rb', line 78 def comment @comment end |
#conditions ⇒ Object (readonly)
Returns the value of attribute conditions.
78 79 80 |
# File 'lib/card/query.rb', line 78 def conditions @conditions end |
#conditions_on_join ⇒ Object
Returns the value of attribute conditions_on_join.
80 81 82 |
# File 'lib/card/query.rb', line 80 def conditions_on_join @conditions_on_join end |
#joins ⇒ Object
Returns the value of attribute joins.
80 81 82 |
# File 'lib/card/query.rb', line 80 def joins @joins end |
#mods ⇒ Object (readonly)
Returns the value of attribute mods.
78 79 80 |
# File 'lib/card/query.rb', line 78 def mods @mods end |
#statement ⇒ Object (readonly)
Returns the value of attribute statement.
78 79 80 |
# File 'lib/card/query.rb', line 78 def statement @statement end |
#subqueries ⇒ Object (readonly)
Returns the value of attribute subqueries.
78 79 80 |
# File 'lib/card/query.rb', line 78 def subqueries @subqueries end |
#superquery ⇒ Object (readonly)
Returns the value of attribute superquery.
78 79 80 |
# File 'lib/card/query.rb', line 78 def superquery @superquery end |
#table_seq ⇒ Object
Returns the value of attribute table_seq.
80 81 82 |
# File 'lib/card/query.rb', line 80 def table_seq @table_seq end |
#unjoined ⇒ Object
Returns the value of attribute unjoined.
80 81 82 |
# File 'lib/card/query.rb', line 80 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)
89 90 91 |
# File 'lib/card/query.rb', line 89 def self.run statement, comment=nil new(statement, comment).run end |
Instance Method Details
#context ⇒ Object
172 173 174 175 176 177 178 |
# File 'lib/card/query.rb', line 172 def context if !@context.nil? @context else @context = @superquery ? @superquery.context : '' end end |
#default_comment ⇒ Object
112 113 114 115 |
# File 'lib/card/query.rb', line 112 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.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/card/query.rb', line 131 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.…
162 163 164 |
# File 'lib/card/query.rb', line 162 def root @root ||= @superquery ? @superquery.root : self end |
#run ⇒ Object
run the current query
119 120 121 122 123 124 125 126 127 128 |
# File 'lib/card/query.rb', line 119 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
147 148 149 150 151 |
# File 'lib/card/query.rb', line 147 def run_sql # puts "\nstatement = #{@statement}" # puts "sql = #{sql}" ActiveRecord::Base.connection.select_all(sql) end |
#sql ⇒ Object
153 154 155 |
# File 'lib/card/query.rb', line 153 def sql @sql ||= SqlStatement.new(self).build.to_s end |