arel-6.0.3/0000755000004100000410000000000012563210504012471 5ustar www-datawww-dataarel-6.0.3/History.txt0000644000004100000410000001617012563210504014700 0ustar www-datawww-data=== 6.0.3 / 2015-08-04 * Bug fixes * Fix quoting LIMIT values on Oracle visitor. === 6.0.2 / 2015-07-11 * Bug fixes * Fix file permission problem on the gem package === 6.0.1 / 2015-07-10 * Bug fixes * Stop quoting LIMIT values. === 6.0.0 / 2014-11-25 * Enhancements * Remove deprecated `Arel::Expression` * Remove deprecated `Arel::SqlLiteral` * Remove deprecated `SelectManager#joins` * Remove deprecated `SelectManager#to_a` * Remove deprecated `Arel::Sql::Engine` * Remove deprecated `Arel::InnerJoin` constant * Remove deprecated `Arel::OuterJoin` constant == 5.0.0 / 2013-12-04 * Enhancements * Remove deprecated code * Bug Fixes * Fix serializing a relation when calling `to_yaml` === 4.0.2 / 2014-02-05 * Bug Fixes * Fix `SqlLiteral` YAML serialization * PostgreSQL bugfix for invalid SQL in subqueries == 4.0.1 / 2013-10-22 * Enhancements * Cache visitor dispatch on a per-visitor basis * Improve performance of #uniq across a large number of nodes * Bug Fixes * Make visitors threadsafe by removing @last_column * Support `columns_for_distinct` with Oracle adapter == 3.0.3 / 2013-11-12 * Enhancements * Support ANSI 2003 window functions * Bug Fixes * Fix joins in Informix == 3.0.2 / 2012-02-21 * Enhancements * Added a module for visiting and transforming bind values * Fix in [] to be false, not in [] to be true * Bug Fixes * Revert fix for LIMIT / OFFSET when query is ordered in Oracle == 3.0.1 / 2012-02-17 * Bug Fixes * Fixed LIMIT / OFFSET when query is ordered in Oracle == 3.0.0 / 2012-01-12 * Enhancements * Support connection pool and schema cache * Bug Fixes * Conditions with no column can be followed by other conditions in Postgres == 2.2.3 / 2012-02-21 * Enhancements * Added a module for visiting and transforming bind values == 2.2.2 / 2012-02-20 * Enhancements * Support LOCK * Allow using non-table alias as a right-hand relation name * Added SelectManager#distinct == 2.2.1 / 2011-09-15 * Enhancements * Added UpdateManager#key to access the key value * Added SelectManager#projections= to override any existing projections * Added SelectManager#source to get the source of the last select core in the AST == 2.2.0 / 2011-08-09 * Bug Fixes * The database connection caches visitors for generating SQL. * FALSE and TRUE nodes can be constructed. * Fixed ORDER BY / LIMIT clauses for UPDATE statements in Oracle. == 2.1.4 / 2011-07-25 * Bug Fixes * Fix depth-first traversal to understand ascending / descending nodes. * Parenthesis are suppressed with nested unions in MySQL. Thanks jhtwong! == 2.1.3 / 2011-06-27 * Bug Fixes * Fixed broken gem build. == 2.1.2 / 2011-06-27 * Bug Fixes * Visitors can define their own cache strategy so caches are not shared. Fixes #57 * Informix support fixed. Thanks Khronos. * Ordering nodes broken to subclasses. Thanks Ernie Miller! * Reversal supported in ordering nodes. Thanks Ernie Miller! == 2.1.1 / 2011/05/14 * Bug fixes * Fixed thread safety bug in ToSql visitor. Thanks Damon McCormick and Cameron Walters! == 2.1.0 / 2011/04/30 * Enhancements * AST is now Enumerable * AND nodes are now n-ary nodes * SQL Literals may be used as Attribute names * Added Arel::Nodes::NamedFunction for representing generic SQL functions * Add Arel::SelectManager#limit= * Add Arel::SelectManager#offset * Add Arel::SelectManager#offset= * Added Arel::SelectManager#create_insert for building an insert manager. * SQL Literals are allowed for values in INSERT statements. * Math operations have been added to attributes, thanks to Vladimir Meremyanin. * Bug fixes * MSSQL adds TOP to sub selects * Assigning nil to take() removes LIMIT from statement. * Assigning nil to offset() removes OFFSET from statement. * TableAlias leg ordering fixed * Deprecations * Calls to `insert` are deprecated. Please use `compile_insert` then call `to_sql` on the resulting object and execute that SQL. * Calls to `update` are deprecated. Please use `compile_update` then call `to_sql` on the resulting object and execute that SQL. * Calls to `delete` are deprecated. Please use `compile_delete` then call `to_sql` on the resulting object and execute that SQL. * Arel::Table#joins is deprecated and will be removed in 3.0.0 with no replacement. * Arel::Table#columns is deprecated and will be removed in 3.0.0 with no replacement. * Arel::Table.table_cache is deprecated and will be removed in 3.0.0 with no replacement. * Arel::Nodes::And.new takes a single list instead of left and right. * Arel::Table#primary_key is deprecated and will be removed in 3.0.0 with no replacement. * Arel::SelectManager#where_clauses is deprecated and will be removed in 3.0.0 with no replacement. * Arel::SelectManager#wheres is deprecated and will be removed in 3.0.0 with no replacement. == 2.0.9 / 2010/02/25 * Bug Fixes * Custom LOCK strings are allowed. Fixes LH # 6399 https://rails.lighthouseapp.com/projects/8994/tickets/6399-allow-database-specific-locking-clauses-to-be-used * Strings passed to StringManager#on will be automatically tagged as SQL literals. Fixes Rails LH #6384 https://rails.lighthouseapp.com/projects/8994/tickets/6384-activerecord-303-and-3-0-stable-generate-invalid-sql-for-has_many-through-association-with-conditions == 2.0.8 / 2010/02/08 * Bug Fixes * Added set operation support * Fixed problems with *_any / *_all methods. == 2.0.7 * Bug Fixes * Limit members are visited * Fixing MSSQL TOP support == 2.0.6 12/01/2010 * Bug Fixes * Rails 3.0.x does not like that Node is Enumerable, so removing for now. == 2.0.5 11/30/2010 * Enhancements * Arel::Visitors::DepthFirst can walk your AST depth first * Arel::Nodes::Node is enumerable, depth first * Bug fixes * #lock will lock SELECT statements "FOR UPDATE" on mysql * Nodes::Node#not factory method added for creating Nodes::Not nodes * Added an As node * Deprecations * Support for Subclasses of core classes will be removed in Arel version 2.2.0 == 2.0.4 * Bug fixes * Speed improvements for Range queries. Thanks Rolf Timmermans! == 2.0.3 * Bug fixes * Fixing Oracle support * Added a visitor for "Class" objects == 2.0.2 * Bug fixes * MySQL selects from DUAL on empty FROM * Visitor translates nil to NULL * Visitor translates Bignum properly == 2.0.1 * Bug fixes == 2.0.0 / 2010-08-01 * Enhancements * Recreate library using the Visitor pattern. http://en.wikipedia.org/wiki/Visitor_pattern == 0.3.0 / 2010-03-10 * Enhancements * Introduced "SQL compilers" for query generation. * Added support for Oracle (Raimonds Simanovskis) and IBM/DB (Praveen Devarao). * Improvements to give better support to Active Record. == 0.2.1 / 2010-02-05 * Enhancements * Bump dependency version of activesupport to 3.0.0.beta == 0.2.0 / 2010-01-31 * Ruby 1.9 compatibility * Many improvements to support the Arel integration into Active Record (see `git log v0.1.0..v0.2.0`) * Thanks to Emilio Tagua and Pratik Naik for many significant contributions! == 0.1.0 / 2009-08-06 * 1 major enhancement * Birthday! arel-6.0.3/lib/0000755000004100000410000000000012563210504013237 5ustar www-datawww-dataarel-6.0.3/lib/arel/0000755000004100000410000000000012563210504014162 5ustar www-datawww-dataarel-6.0.3/lib/arel/update_manager.rb0000644000004100000410000000167512563210504017474 0ustar www-datawww-datamodule Arel class UpdateManager < Arel::TreeManager def initialize engine super @ast = Nodes::UpdateStatement.new @ctx = @ast end def take limit @ast.limit = Nodes::Limit.new(Nodes.build_quoted(limit)) if limit self end def key= key @ast.key = Nodes.build_quoted(key) end def key @ast.key end def order *expr @ast.orders = expr self end ### # UPDATE +table+ def table table @ast.relation = table self end def wheres= exprs @ast.wheres = exprs end def where expr @ast.wheres << expr self end def set values if String === values @ast.values = [values] else @ast.values = values.map { |column,value| Nodes::Assignment.new( Nodes::UnqualifiedColumn.new(column), value ) } end self end end end arel-6.0.3/lib/arel/visitors.rb0000644000004100000410000000242312563210504016372 0ustar www-datawww-datarequire 'arel/visitors/visitor' require 'arel/visitors/depth_first' require 'arel/visitors/to_sql' require 'arel/visitors/sqlite' require 'arel/visitors/postgresql' require 'arel/visitors/mysql' require 'arel/visitors/mssql' require 'arel/visitors/oracle' require 'arel/visitors/where_sql' require 'arel/visitors/dot' require 'arel/visitors/ibm_db' require 'arel/visitors/informix' module Arel module Visitors VISITORS = { 'postgresql' => Arel::Visitors::PostgreSQL, 'mysql' => Arel::Visitors::MySQL, 'mysql2' => Arel::Visitors::MySQL, 'mssql' => Arel::Visitors::MSSQL, 'sqlserver' => Arel::Visitors::MSSQL, 'oracle_enhanced' => Arel::Visitors::Oracle, 'sqlite' => Arel::Visitors::SQLite, 'sqlite3' => Arel::Visitors::SQLite, 'ibm_db' => Arel::Visitors::IBM_DB, 'informix' => Arel::Visitors::Informix, } ENGINE_VISITORS = Hash.new do |hash, engine| pool = engine.connection_pool adapter = pool.spec.config[:adapter] hash[engine] = (VISITORS[adapter] || Visitors::ToSql).new(engine) end def self.visitor_for engine ENGINE_VISITORS[engine] end class << self; alias :for :visitor_for; end end end arel-6.0.3/lib/arel/delete_manager.rb0000644000004100000410000000045012563210504017442 0ustar www-datawww-datamodule Arel class DeleteManager < Arel::TreeManager def initialize engine super @ast = Nodes::DeleteStatement.new @ctx = @ast end def from relation @ast.relation = relation self end def wheres= list @ast.wheres = list end end end arel-6.0.3/lib/arel/math.rb0000644000004100000410000000057612563210504015450 0ustar www-datawww-datamodule Arel module Math def *(other) Arel::Nodes::Multiplication.new(self, other) end def +(other) Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new(self, other)) end def -(other) Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, other)) end def /(other) Arel::Nodes::Division.new(self, other) end end end arel-6.0.3/lib/arel/tree_manager.rb0000644000004100000410000000151712563210504017144 0ustar www-datawww-datarequire 'arel/collectors/sql_string' module Arel class TreeManager include Arel::FactoryMethods attr_reader :ast, :engine attr_accessor :bind_values def initialize engine @engine = engine @ctx = nil @bind_values = [] end def to_dot collector = Arel::Collectors::PlainString.new collector = Visitors::Dot.new.accept @ast, collector collector.value end def visitor engine.connection.visitor end def to_sql collector = Arel::Collectors::SQLString.new collector = visitor.accept @ast, collector collector.value end def initialize_copy other super @ast = @ast.clone end def where expr if Arel::TreeManager === expr expr = expr.ast end @ctx.wheres << expr self end end end arel-6.0.3/lib/arel/insert_manager.rb0000644000004100000410000000151612563210504017510 0ustar www-datawww-datamodule Arel class InsertManager < Arel::TreeManager def initialize engine super @ast = Nodes::InsertStatement.new end def into table @ast.relation = table self end def columns; @ast.columns end def values= val; @ast.values = val; end def select select @ast.select = select end def insert fields return if fields.empty? if String === fields @ast.values = Nodes::SqlLiteral.new(fields) else @ast.relation ||= fields.first.first.relation values = [] fields.each do |column, value| @ast.columns << column values << value end @ast.values = create_values values, @ast.columns end end def create_values values, columns Nodes::Values.new values, columns end end end arel-6.0.3/lib/arel/nodes/0000755000004100000410000000000012563210504015272 5ustar www-datawww-dataarel-6.0.3/lib/arel/nodes/join_source.rb0000644000004100000410000000052112563210504020134 0ustar www-datawww-datamodule Arel module Nodes ### # Class that represents a join source # # http://www.sqlite.org/syntaxdiagrams.html#join-source class JoinSource < Arel::Nodes::Binary def initialize single_source, joinop = [] super end def empty? !left && right.empty? end end end end arel-6.0.3/lib/arel/nodes/infix_operation.rb0000644000004100000410000000154512563210504021021 0ustar www-datawww-datamodule Arel module Nodes class InfixOperation < Binary include Arel::Expressions include Arel::Predications include Arel::OrderPredications include Arel::AliasPredication include Arel::Math attr_reader :operator def initialize operator, left, right super(left, right) @operator = operator end end class Multiplication < InfixOperation def initialize left, right super(:*, left, right) end end class Division < InfixOperation def initialize left, right super(:/, left, right) end end class Addition < InfixOperation def initialize left, right super(:+, left, right) end end class Subtraction < InfixOperation def initialize left, right super(:-, left, right) end end end endarel-6.0.3/lib/arel/nodes/descending.rb0000644000004100000410000000042012563210504017716 0ustar www-datawww-datamodule Arel module Nodes class Descending < Ordering def reverse Ascending.new(expr) end def direction :desc end def ascending? false end def descending? true end end end end arel-6.0.3/lib/arel/nodes/in.rb0000644000004100000410000000010512563210504016221 0ustar www-datawww-datamodule Arel module Nodes class In < Equality end end end arel-6.0.3/lib/arel/nodes/right_outer_join.rb0000644000004100000410000000013212563210504021165 0ustar www-datawww-datamodule Arel module Nodes class RightOuterJoin < Arel::Nodes::Join end end end arel-6.0.3/lib/arel/nodes/binary.rb0000644000004100000410000000162512563210504017107 0ustar www-datawww-datamodule Arel module Nodes class Binary < Arel::Nodes::Node attr_accessor :left, :right def initialize left, right super() @left = left @right = right end def initialize_copy other super @left = @left.clone if @left @right = @right.clone if @right end def hash [self.class, @left, @right].hash end def eql? other self.class == other.class && self.left == other.left && self.right == other.right end alias :== :eql? end %w{ As Assignment Between GreaterThan GreaterThanOrEqual Join LessThan LessThanOrEqual NotEqual NotIn NotRegexp Or Regexp Union UnionAll Intersect Except }.each do |name| const_set name, Class.new(Binary) end end end arel-6.0.3/lib/arel/nodes/function.rb0000644000004100000410000000155712563210504017454 0ustar www-datawww-datamodule Arel module Nodes class Function < Arel::Nodes::Node include Arel::Predications include Arel::WindowPredications attr_accessor :expressions, :alias, :distinct def initialize expr, aliaz = nil super() @expressions = expr @alias = aliaz && SqlLiteral.new(aliaz) @distinct = false end def as aliaz self.alias = SqlLiteral.new(aliaz) self end def hash [@expressions, @alias, @distinct].hash end def eql? other self.class == other.class && self.expressions == other.expressions && self.alias == other.alias && self.distinct == other.distinct end end %w{ Sum Exists Max Min Avg }.each do |name| const_set(name, Class.new(Function)) end end end arel-6.0.3/lib/arel/nodes/with.rb0000644000004100000410000000022112563210504016565 0ustar www-datawww-datamodule Arel module Nodes class With < Arel::Nodes::Unary alias children expr end class WithRecursive < With; end end end arel-6.0.3/lib/arel/nodes/grouping.rb0000644000004100000410000000015112563210504017446 0ustar www-datawww-datamodule Arel module Nodes class Grouping < Unary include Arel::Predications end end end arel-6.0.3/lib/arel/nodes/ascending.rb0000644000004100000410000000041712563210504017554 0ustar www-datawww-datamodule Arel module Nodes class Ascending < Ordering def reverse Descending.new(expr) end def direction :asc end def ascending? true end def descending? false end end end end arel-6.0.3/lib/arel/nodes/update_statement.rb0000644000004100000410000000160112563210504021163 0ustar www-datawww-datamodule Arel module Nodes class UpdateStatement < Arel::Nodes::Node attr_accessor :relation, :wheres, :values, :orders, :limit attr_accessor :key def initialize @relation = nil @wheres = [] @values = [] @orders = [] @limit = nil @key = nil end def initialize_copy other super @wheres = @wheres.clone @values = @values.clone end def hash [@relation, @wheres, @values, @orders, @limit, @key].hash end def eql? other self.class == other.class && self.relation == other.relation && self.wheres == other.wheres && self.values == other.values && self.orders == other.orders && self.limit == other.limit && self.key == other.key end alias :== :eql? end end end arel-6.0.3/lib/arel/nodes/delete_statement.rb0000644000004100000410000000056012563210504021146 0ustar www-datawww-datamodule Arel module Nodes class DeleteStatement < Arel::Nodes::Binary alias :relation :left alias :relation= :left= alias :wheres :right alias :wheres= :right= def initialize relation = nil, wheres = [] super end def initialize_copy other super @right = @right.clone end end end end arel-6.0.3/lib/arel/nodes/values.rb0000644000004100000410000000042012563210504017112 0ustar www-datawww-datamodule Arel module Nodes class Values < Arel::Nodes::Binary alias :expressions :left alias :expressions= :left= alias :columns :right alias :columns= :right= def initialize exprs, columns = [] super end end end end arel-6.0.3/lib/arel/nodes/outer_join.rb0000644000004100000410000000012512563210504017772 0ustar www-datawww-datamodule Arel module Nodes class OuterJoin < Arel::Nodes::Join end end end arel-6.0.3/lib/arel/nodes/terminal.rb0000644000004100000410000000030712563210504017432 0ustar www-datawww-datamodule Arel module Nodes class Distinct < Arel::Nodes::Node def hash self.class.hash end def eql? other self.class == other.class end end end end arel-6.0.3/lib/arel/nodes/count.rb0000644000004100000410000000032012563210504016742 0ustar www-datawww-datamodule Arel module Nodes class Count < Arel::Nodes::Function def initialize expr, distinct = false, aliaz = nil super(expr, aliaz) @distinct = distinct end end end end arel-6.0.3/lib/arel/nodes/insert_statement.rb0000644000004100000410000000145012563210504021207 0ustar www-datawww-datamodule Arel module Nodes class InsertStatement < Arel::Nodes::Node attr_accessor :relation, :columns, :values, :select def initialize super() @relation = nil @columns = [] @values = nil @select = nil end def initialize_copy other super @columns = @columns.clone @values = @values.clone if @values @select = @select.clone if @select end def hash [@relation, @columns, @values, @select].hash end def eql? other self.class == other.class && self.relation == other.relation && self.columns == other.columns && self.select == other.select && self.values == other.values end alias :== :eql? end end end arel-6.0.3/lib/arel/nodes/extract.rb0000644000004100000410000000065612563210504017300 0ustar www-datawww-datamodule Arel module Nodes class Extract < Arel::Nodes::Unary include Arel::AliasPredication include Arel::Predications attr_accessor :field def initialize expr, field super(expr) @field = field end def hash super ^ @field.hash end def eql? other super && self.field == other.field end alias :== :eql? end end end arel-6.0.3/lib/arel/nodes/unqualified_column.rb0000644000004100000410000000045512563210504021506 0ustar www-datawww-datamodule Arel module Nodes class UnqualifiedColumn < Arel::Nodes::Unary alias :attribute :expr alias :attribute= :expr= def relation @expr.relation end def column @expr.column end def name @expr.name end end end end arel-6.0.3/lib/arel/nodes/matches.rb0000644000004100000410000000042612563210504017245 0ustar www-datawww-datamodule Arel module Nodes class Matches < Binary attr_reader :escape def initialize(left, right, escape = nil) super(left, right) @escape = escape && Nodes.build_quoted(escape) end end class DoesNotMatch < Matches; end end end arel-6.0.3/lib/arel/nodes/unary.rb0000644000004100000410000000111212563210504016750 0ustar www-datawww-datamodule Arel module Nodes class Unary < Arel::Nodes::Node attr_accessor :expr alias :value :expr def initialize expr super() @expr = expr end def hash @expr.hash end def eql? other self.class == other.class && self.expr == other.expr end alias :== :eql? end %w{ Bin Group Having Limit Not Offset On Ordering Top Lock DistinctOn }.each do |name| const_set(name, Class.new(Unary)) end end end arel-6.0.3/lib/arel/nodes/select_core.rb0000644000004100000410000000314312563210504020107 0ustar www-datawww-datamodule Arel module Nodes class SelectCore < Arel::Nodes::Node attr_accessor :top, :projections, :wheres, :groups, :windows attr_accessor :having, :source, :set_quantifier def initialize super() @source = JoinSource.new nil @top = nil # http://savage.net.au/SQL/sql-92.bnf.html#set%20quantifier @set_quantifier = nil @projections = [] @wheres = [] @groups = [] @having = nil @windows = [] end def from @source.left end def from= value @source.left = value end alias :froms= :from= alias :froms :from def initialize_copy other super @source = @source.clone if @source @projections = @projections.clone @wheres = @wheres.clone @groups = @groups.clone @having = @having.clone if @having @windows = @windows.clone end def hash [ @source, @top, @set_quantifier, @projections, @wheres, @groups, @having, @windows ].hash end def eql? other self.class == other.class && self.source == other.source && self.top == other.top && self.set_quantifier == other.set_quantifier && self.projections == other.projections && self.wheres == other.wheres && self.groups == other.groups && self.having == other.having && self.windows == other.windows end alias :== :eql? end end end arel-6.0.3/lib/arel/nodes/window.rb0000644000004100000410000000451612563210504017134 0ustar www-datawww-datamodule Arel module Nodes class Window < Arel::Nodes::Node attr_accessor :orders, :framing, :partitions def initialize @orders = [] @partitions = [] @framing = nil end def order *expr # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically @orders.concat expr.map { |x| String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x } self end def partition *expr # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically @partitions.concat expr.map { |x| String === x || Symbol === x ? Nodes::SqlLiteral.new(x.to_s) : x } self end def frame(expr) @framing = expr end def rows(expr = nil) if @framing Rows.new(expr) else frame(Rows.new(expr)) end end def range(expr = nil) if @framing Range.new(expr) else frame(Range.new(expr)) end end def initialize_copy other super @orders = @orders.map { |x| x.clone } end def hash [@orders, @framing].hash end def eql? other self.class == other.class && self.orders == other.orders && self.framing == other.framing && self.partitions == other.partitions end alias :== :eql? end class NamedWindow < Window attr_accessor :name def initialize name super() @name = name end def initialize_copy other super @name = other.name.clone end def hash super ^ @name.hash end def eql? other super && self.name == other.name end alias :== :eql? end class Rows < Unary def initialize(expr = nil) super(expr) end end class Range < Unary def initialize(expr = nil) super(expr) end end class CurrentRow < Node def hash self.class.hash end def eql? other self.class == other.class end end class Preceding < Unary def initialize(expr = nil) super(expr) end end class Following < Unary def initialize(expr = nil) super(expr) end end end end arel-6.0.3/lib/arel/nodes/inner_join.rb0000644000004100000410000000012512563210504017747 0ustar www-datawww-datamodule Arel module Nodes class InnerJoin < Arel::Nodes::Join end end end arel-6.0.3/lib/arel/nodes/string_join.rb0000644000004100000410000000022512563210504020143 0ustar www-datawww-datamodule Arel module Nodes class StringJoin < Arel::Nodes::Join def initialize left, right = nil super end end end end arel-6.0.3/lib/arel/nodes/false.rb0000644000004100000410000000030412563210504016706 0ustar www-datawww-datamodule Arel module Nodes class False < Arel::Nodes::Node def hash self.class.hash end def eql? other self.class == other.class end end end end arel-6.0.3/lib/arel/nodes/true.rb0000644000004100000410000000030312563210504016572 0ustar www-datawww-datamodule Arel module Nodes class True < Arel::Nodes::Node def hash self.class.hash end def eql? other self.class == other.class end end end end arel-6.0.3/lib/arel/nodes/and.rb0000644000004100000410000000072612563210504016366 0ustar www-datawww-datamodule Arel module Nodes class And < Arel::Nodes::Node attr_reader :children def initialize children super() @children = children end def left children.first end def right children[1] end def hash children.hash end def eql? other self.class == other.class && self.children == other.children end alias :== :eql? end end end arel-6.0.3/lib/arel/nodes/full_outer_join.rb0000644000004100000410000000013112563210504021011 0ustar www-datawww-datamodule Arel module Nodes class FullOuterJoin < Arel::Nodes::Join end end end arel-6.0.3/lib/arel/nodes/over.rb0000644000004100000410000000033112563210504016567 0ustar www-datawww-datamodule Arel module Nodes class Over < Binary include Arel::AliasPredication def initialize(left, right = nil) super(left, right) end def operator; 'OVER' end end end endarel-6.0.3/lib/arel/nodes/select_statement.rb0000644000004100000410000000173312563210504021166 0ustar www-datawww-datamodule Arel module Nodes class SelectStatement < Arel::Nodes::Node attr_reader :cores attr_accessor :limit, :orders, :lock, :offset, :with def initialize cores = [SelectCore.new] super() @cores = cores @orders = [] @limit = nil @lock = nil @offset = nil @with = nil end def initialize_copy other super @cores = @cores.map { |x| x.clone } @orders = @orders.map { |x| x.clone } end def hash [@cores, @orders, @limit, @lock, @offset, @with].hash end def eql? other self.class == other.class && self.cores == other.cores && self.orders == other.orders && self.limit == other.limit && self.lock == other.lock && self.offset == other.offset && self.with == other.with end alias :== :eql? end end end arel-6.0.3/lib/arel/nodes/table_alias.rb0000644000004100000410000000057212563210504020063 0ustar www-datawww-datamodule Arel module Nodes class TableAlias < Arel::Nodes::Binary alias :name :right alias :relation :left alias :table_alias :name def [] name Attribute.new(self, name) end def table_name relation.respond_to?(:name) ? relation.name : name end def engine relation.engine end end end end arel-6.0.3/lib/arel/nodes/named_function.rb0000644000004100000410000000056312563210504020614 0ustar www-datawww-datamodule Arel module Nodes class NamedFunction < Arel::Nodes::Function attr_accessor :name def initialize name, expr, aliaz = nil super(expr, aliaz) @name = name end def hash super ^ @name.hash end def eql? other super && self.name == other.name end alias :== :eql? end end end arel-6.0.3/lib/arel/nodes/bind_param.rb0000644000004100000410000000011012563210504017703 0ustar www-datawww-datamodule Arel module Nodes class BindParam < Node end end end arel-6.0.3/lib/arel/nodes/node.rb0000644000004100000410000000276012563210504016551 0ustar www-datawww-datarequire 'arel/collectors/sql_string' module Arel module Nodes ### # Abstract base class for all AST nodes class Node include Arel::FactoryMethods include Enumerable if $DEBUG def _caller @caller end def initialize @caller = caller.dup end end ### # Factory method to create a Nodes::Not node that has the recipient of # the caller as a child. def not Nodes::Not.new self end ### # Factory method to create a Nodes::Grouping node that has an Nodes::Or # node as a child. def or right Nodes::Grouping.new Nodes::Or.new(self, right) end ### # Factory method to create an Nodes::And node. def and right Nodes::And.new [self, right] end # FIXME: this method should go away. I don't like people calling # to_sql on non-head nodes. This forces us to walk the AST until we # can find a node that has a "relation" member. # # Maybe we should just use `Table.engine`? :'( def to_sql engine = Table.engine collector = Arel::Collectors::SQLString.new collector = engine.connection.visitor.accept self, collector collector.value end # Iterate through AST, nodes will be yielded depth-first def each &block return enum_for(:each) unless block_given? ::Arel::Visitors::DepthFirst.new(block).accept self end end end end arel-6.0.3/lib/arel/nodes/equality.rb0000644000004100000410000000025312563210504017454 0ustar www-datawww-datamodule Arel module Nodes class Equality < Arel::Nodes::Binary def operator; :== end alias :operand1 :left alias :operand2 :right end end end arel-6.0.3/lib/arel/nodes/sql_literal.rb0000644000004100000410000000044012563210504020130 0ustar www-datawww-datamodule Arel module Nodes class SqlLiteral < String include Arel::Expressions include Arel::Predications include Arel::AliasPredication include Arel::OrderPredications def encode_with(coder) coder.scalar = self.to_s end end end end arel-6.0.3/lib/arel/table.rb0000644000004100000410000000627112563210504015604 0ustar www-datawww-datamodule Arel class Table include Arel::Crud include Arel::FactoryMethods @engine = nil class << self; attr_accessor :engine; end attr_accessor :name, :engine, :aliases, :table_alias # TableAlias and Table both have a #table_name which is the name of the underlying table alias :table_name :name def initialize name, engine = Table.engine @name = name.to_s @engine = engine @columns = nil @aliases = [] @table_alias = nil @primary_key = nil if Hash === engine @engine = engine[:engine] || Table.engine # Sometime AR sends an :as parameter to table, to let the table know # that it is an Alias. We may want to override new, and return a # TableAlias node? @table_alias = engine[:as] unless engine[:as].to_s == @name end end def primary_key if $VERBOSE warn <<-eowarn primary_key (#{caller.first}) is deprecated and will be removed in Arel 4.0.0 eowarn end @primary_key ||= begin primary_key_name = @engine.connection.primary_key(name) # some tables might be without primary key primary_key_name && self[primary_key_name] end end def alias name = "#{self.name}_2" Nodes::TableAlias.new(self, name).tap do |node| @aliases << node end end def from table SelectManager.new(@engine, table) end def join relation, klass = Nodes::InnerJoin return from(self) unless relation case relation when String, Nodes::SqlLiteral raise if relation.empty? klass = Nodes::StringJoin end from(self).join(relation, klass) end def outer_join relation join(relation, Nodes::OuterJoin) end def group *columns from(self).group(*columns) end def order *expr from(self).order(*expr) end def where condition from(self).where condition end def project *things from(self).project(*things) end def take amount from(self).take amount end def skip amount from(self).skip amount end def having expr from(self).having expr end def [] name ::Arel::Attribute.new self, name end def select_manager SelectManager.new(@engine) end def insert_manager InsertManager.new(@engine) end def update_manager UpdateManager.new(@engine) end def delete_manager DeleteManager.new(@engine) end def hash # Perf note: aliases, table alias and engine is excluded from the hash # aliases can have a loop back to this table breaking hashes in parent # relations, for the vast majority of cases @name is unique to a query @name.hash end def eql? other self.class == other.class && self.name == other.name && self.engine == other.engine && self.aliases == other.aliases && self.table_alias == other.table_alias end alias :== :eql? private def attributes_for columns return nil unless columns columns.map do |column| Attributes.for(column).new self, column.name.to_sym end end end end arel-6.0.3/lib/arel/crud.rb0000644000004100000410000000137312563210504015450 0ustar www-datawww-datamodule Arel ### # FIXME hopefully we can remove this module Crud def compile_update values, pk um = UpdateManager.new @engine if Nodes::SqlLiteral === values relation = @ctx.from else relation = values.first.first.relation end um.key = pk um.table relation um.set values um.take @ast.limit.expr if @ast.limit um.order(*@ast.orders) um.wheres = @ctx.wheres um end def compile_insert values im = create_insert im.insert values im end def create_insert InsertManager.new @engine end def compile_delete dm = DeleteManager.new @engine dm.wheres = @ctx.wheres dm.from @ctx.froms dm end end end arel-6.0.3/lib/arel/select_manager.rb0000644000004100000410000001266512563210504017472 0ustar www-datawww-datarequire 'arel/collectors/sql_string' module Arel class SelectManager < Arel::TreeManager include Arel::Crud STRING_OR_SYMBOL_CLASS = [Symbol, String] def initialize engine, table = nil super(engine) @ast = Nodes::SelectStatement.new @ctx = @ast.cores.last from table end def initialize_copy other super @ctx = @ast.cores.last end def limit @ast.limit && @ast.limit.expr end alias :taken :limit def constraints @ctx.wheres end def offset @ast.offset && @ast.offset.expr end def skip amount if amount @ast.offset = Nodes::Offset.new(amount) else @ast.offset = nil end self end alias :offset= :skip ### # Produces an Arel::Nodes::Exists node def exists Arel::Nodes::Exists.new @ast end def as other create_table_alias grouping(@ast), Nodes::SqlLiteral.new(other) end def lock locking = Arel.sql('FOR UPDATE') case locking when true locking = Arel.sql('FOR UPDATE') when Arel::Nodes::SqlLiteral when String locking = Arel.sql locking end @ast.lock = Nodes::Lock.new(locking) self end def locked @ast.lock end def on *exprs @ctx.source.right.last.right = Nodes::On.new(collapse(exprs)) self end def group *columns columns.each do |column| # FIXME: backwards compat column = Nodes::SqlLiteral.new(column) if String === column column = Nodes::SqlLiteral.new(column.to_s) if Symbol === column @ctx.groups.push Nodes::Group.new column end self end def from table table = Nodes::SqlLiteral.new(table) if String === table case table when Nodes::Join @ctx.source.right << table else @ctx.source.left = table end self end def froms @ast.cores.map { |x| x.from }.compact end def join relation, klass = Nodes::InnerJoin return self unless relation case relation when String, Nodes::SqlLiteral raise if relation.empty? klass = Nodes::StringJoin end @ctx.source.right << create_join(relation, nil, klass) self end def outer_join relation join(relation, Nodes::OuterJoin) end def having *exprs @ctx.having = Nodes::Having.new(collapse(exprs, @ctx.having)) self end def window name window = Nodes::NamedWindow.new(name) @ctx.windows.push window window end def project *projections # FIXME: converting these to SQLLiterals is probably not good, but # rails tests require it. @ctx.projections.concat projections.map { |x| STRING_OR_SYMBOL_CLASS.include?(x.class) ? Nodes::SqlLiteral.new(x.to_s) : x } self end def projections @ctx.projections end def projections= projections @ctx.projections = projections end def distinct(value = true) if value @ctx.set_quantifier = Arel::Nodes::Distinct.new else @ctx.set_quantifier = nil end self end def distinct_on(value) if value @ctx.set_quantifier = Arel::Nodes::DistinctOn.new(value) else @ctx.set_quantifier = nil end self end def order *expr # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically @ast.orders.concat expr.map { |x| STRING_OR_SYMBOL_CLASS.include?(x.class) ? Nodes::SqlLiteral.new(x.to_s) : x } self end def orders @ast.orders end def where_sql return if @ctx.wheres.empty? viz = Visitors::WhereSql.new @engine.connection Nodes::SqlLiteral.new viz.accept(@ctx, Collectors::SQLString.new).value end def union operation, other = nil if other node_class = Nodes.const_get("Union#{operation.to_s.capitalize}") else other = operation node_class = Nodes::Union end node_class.new self.ast, other.ast end def intersect other Nodes::Intersect.new ast, other.ast end def except other Nodes::Except.new ast, other.ast end alias :minus :except def with *subqueries if subqueries.first.is_a? Symbol node_class = Nodes.const_get("With#{subqueries.shift.to_s.capitalize}") else node_class = Nodes::With end @ast.with = node_class.new(subqueries.flatten) self end def take limit if limit @ast.limit = Nodes::Limit.new(limit) @ctx.top = Nodes::Top.new(limit) else @ast.limit = nil @ctx.top = nil end self end alias limit= take def join_sources @ctx.source.right end def source @ctx.source end class Row < Struct.new(:data) # :nodoc: def id data['id'] end def method_missing(name, *args) name = name.to_s return data[name] if data.key?(name) super end end private def collapse exprs, existing = nil exprs = exprs.unshift(existing.expr) if existing exprs = exprs.compact.map { |expr| if String === expr # FIXME: Don't do this automatically Arel.sql(expr) else expr end } if exprs.length == 1 exprs.first else create_and exprs end end end end arel-6.0.3/lib/arel/predications.rb0000644000004100000410000001117712563210504017202 0ustar www-datawww-datamodule Arel module Predications def not_eq other Nodes::NotEqual.new self, quoted_node(other) end def not_eq_any others grouping_any :not_eq, others end def not_eq_all others grouping_all :not_eq, others end def eq other Nodes::Equality.new self, quoted_node(other) end def eq_any others grouping_any :eq, others end def eq_all others grouping_all :eq, quoted_array(others) end def between other if other.begin == -Float::INFINITY if other.end == Float::INFINITY not_in([]) elsif other.exclude_end? lt(other.end) else lteq(other.end) end elsif other.end == Float::INFINITY gteq(other.begin) elsif other.exclude_end? gteq(other.begin).and(lt(other.end)) else left = quoted_node(other.begin) right = quoted_node(other.end) Nodes::Between.new(self, left.and(right)) end end def in other case other when Arel::SelectManager Arel::Nodes::In.new(self, other.ast) when Range if $VERBOSE warn <<-eowarn Passing a range to `#in` is deprecated. Call `#between`, instead. eowarn end between(other) when Enumerable Nodes::In.new self, quoted_array(other) else Nodes::In.new self, quoted_node(other) end end def in_any others grouping_any :in, others end def in_all others grouping_all :in, others end def not_between other if other.begin == -Float::INFINITY # The range begins with negative infinity if other.end == Float::INFINITY self.in([]) elsif other.exclude_end? gteq(other.end) else gt(other.end) end elsif other.end == Float::INFINITY lt(other.begin) else left = lt(other.begin) right = if other.exclude_end? gteq(other.end) else gt(other.end) end left.or(right) end end def not_in other case other when Arel::SelectManager Arel::Nodes::NotIn.new(self, other.ast) when Range if $VERBOSE warn <<-eowarn Passing a range to `#not_in` is deprecated. Call `#not_between`, instead. eowarn end not_between(other) when Enumerable Nodes::NotIn.new self, quoted_array(other) else Nodes::NotIn.new self, quoted_node(other) end end def not_in_any others grouping_any :not_in, others end def not_in_all others grouping_all :not_in, others end def matches other, escape = nil Nodes::Matches.new self, quoted_node(other), escape end def matches_any others, escape = nil grouping_any :matches, others, escape end def matches_all others, escape = nil grouping_all :matches, others, escape end def does_not_match other, escape = nil Nodes::DoesNotMatch.new self, quoted_node(other), escape end def does_not_match_any others, escape = nil grouping_any :does_not_match, others, escape end def does_not_match_all others, escape = nil grouping_all :does_not_match, others, escape end def gteq right Nodes::GreaterThanOrEqual.new self, quoted_node(right) end def gteq_any others grouping_any :gteq, others end def gteq_all others grouping_all :gteq, others end def gt right Nodes::GreaterThan.new self, quoted_node(right) end def gt_any others grouping_any :gt, others end def gt_all others grouping_all :gt, others end def lt right Nodes::LessThan.new self, quoted_node(right) end def lt_any others grouping_any :lt, others end def lt_all others grouping_all :lt, others end def lteq right Nodes::LessThanOrEqual.new self, quoted_node(right) end def lteq_any others grouping_any :lteq, others end def lteq_all others grouping_all :lteq, others end private def grouping_any method_id, others, *extras nodes = others.map {|expr| send(method_id, expr, *extras)} Nodes::Grouping.new nodes.inject { |memo,node| Nodes::Or.new(memo, node) } end def grouping_all method_id, others, *extras nodes = others.map {|expr| send(method_id, expr, *extras)} Nodes::Grouping.new Nodes::And.new(nodes) end def quoted_node(other) Nodes.build_quoted(other, self) end def quoted_array(others) others.map { |v| quoted_node(v) } end end end arel-6.0.3/lib/arel/attributes/0000755000004100000410000000000012563210504016350 5ustar www-datawww-dataarel-6.0.3/lib/arel/attributes/attribute.rb0000644000004100000410000000124512563210504020702 0ustar www-datawww-datamodule Arel module Attributes class Attribute < Struct.new :relation, :name include Arel::Expressions include Arel::Predications include Arel::AliasPredication include Arel::OrderPredications include Arel::Math ### # Create a node for lowering this attribute def lower relation.lower self end end class String < Attribute; end class Time < Attribute; end class Boolean < Attribute; end class Decimal < Attribute; end class Float < Attribute; end class Integer < Attribute; end class Undefined < Attribute; end end Attribute = Attributes::Attribute end arel-6.0.3/lib/arel/compatibility/0000755000004100000410000000000012563210504017033 5ustar www-datawww-dataarel-6.0.3/lib/arel/compatibility/wheres.rb0000644000004100000410000000112612563210504020655 0ustar www-datawww-datamodule Arel module Compatibility # :nodoc: class Wheres # :nodoc: include Enumerable module Value # :nodoc: attr_accessor :visitor def value visitor.accept self end def name super.to_sym end end def initialize engine, collection @engine = engine @collection = collection end def each to_sql = Visitors::ToSql.new @engine @collection.each { |c| c.extend(Value) c.visitor = to_sql yield c } end end end end arel-6.0.3/lib/arel/factory_methods.rb0000644000004100000410000000146012563210504017702 0ustar www-datawww-datamodule Arel ### # Methods for creating various nodes module FactoryMethods def create_true Arel::Nodes::True.new end def create_false Arel::Nodes::False.new end def create_table_alias relation, name Nodes::TableAlias.new(relation, name) end def create_join to, constraint = nil, klass = Nodes::InnerJoin klass.new(to, constraint) end def create_string_join to create_join to, nil, Nodes::StringJoin end def create_and clauses Nodes::And.new clauses end def create_on expr Nodes::On.new expr end def grouping expr Nodes::Grouping.new expr end ### # Create a LOWER() function def lower column Nodes::NamedFunction.new 'LOWER', [Nodes.build_quoted(column)] end end end arel-6.0.3/lib/arel/window_predications.rb0000644000004100000410000000016612563210504020565 0ustar www-datawww-datamodule Arel module WindowPredications def over(expr = nil) Nodes::Over.new(self, expr) end end endarel-6.0.3/lib/arel/expressions.rb0000644000004100000410000000062112563210504017070 0ustar www-datawww-datamodule Arel module Expressions def count distinct = false Nodes::Count.new [self], distinct end def sum Nodes::Sum.new [self] end def maximum Nodes::Max.new [self] end def minimum Nodes::Min.new [self] end def average Nodes::Avg.new [self] end def extract field Nodes::Extract.new [self], field end end end arel-6.0.3/lib/arel/attributes.rb0000644000004100000410000000114212563210504016673 0ustar www-datawww-datarequire 'arel/attributes/attribute' module Arel module Attributes ### # Factory method to wrap a raw database +column+ to an Arel Attribute. def self.for column case column.type when :string, :text, :binary then String when :integer then Integer when :float then Float when :decimal then Decimal when :date, :datetime, :timestamp, :time then Time when :boolean then Boolean else Undefined end end end end arel-6.0.3/lib/arel/alias_predication.rb0000644000004100000410000000017712563210504020166 0ustar www-datawww-datamodule Arel module AliasPredication def as other Nodes::As.new self, Nodes::SqlLiteral.new(other) end end endarel-6.0.3/lib/arel/visitors/0000755000004100000410000000000012563210504016044 5ustar www-datawww-dataarel-6.0.3/lib/arel/visitors/mysql.rb0000644000004100000410000000374012563210504017542 0ustar www-datawww-datamodule Arel module Visitors class MySQL < Arel::Visitors::ToSql private def visit_Arel_Nodes_Union o, collector, suppress_parens = false unless suppress_parens collector << "( " end collector = case o.left when Arel::Nodes::Union visit_Arel_Nodes_Union o.left, collector, true else visit o.left, collector end collector << " UNION " collector = case o.right when Arel::Nodes::Union visit_Arel_Nodes_Union o.right, collector, true else visit o.right, collector end if suppress_parens collector else collector << " )" end end def visit_Arel_Nodes_Bin o, collector collector << "BINARY " visit o.expr, collector end ### # :'( # http://dev.mysql.com/doc/refman/5.0/en/select.html#id3482214 def visit_Arel_Nodes_SelectStatement o, collector if o.offset && !o.limit o.limit = Arel::Nodes::Limit.new(18446744073709551615) end super end def visit_Arel_Nodes_SelectCore o, collector o.froms ||= Arel.sql('DUAL') super end def visit_Arel_Nodes_UpdateStatement o, collector collector << "UPDATE " collector = visit o.relation, collector unless o.values.empty? collector << " SET " collector = inject_join o.values, collector, ', ' end unless o.wheres.empty? collector << " WHERE " collector = inject_join o.wheres, collector, ' AND ' end unless o.orders.empty? collector << " ORDER BY " collector = inject_join o.orders, collector, ', ' end maybe_visit o.limit, collector end end end end arel-6.0.3/lib/arel/visitors/informix.rb0000644000004100000410000000267112563210504020232 0ustar www-datawww-datamodule Arel module Visitors class Informix < Arel::Visitors::ToSql private def visit_Arel_Nodes_SelectStatement o, collector collector << "SELECT " collector = maybe_visit o.offset, collector collector = maybe_visit o.limit, collector collector = o.cores.inject(collector) { |c,x| visit_Arel_Nodes_SelectCore x, c } if o.orders.any? collector << "ORDER BY " collector = inject_join o.orders, collector, ", " end collector = maybe_visit o.lock, collector end def visit_Arel_Nodes_SelectCore o, collector collector = inject_join o.projections, collector, ", " froms = false if o.source && !o.source.empty? froms = true collector << " FROM " collector = visit o.source, collector end if o.wheres.any? collector << " WHERE " collector = inject_join o.wheres, collector, " AND " end if o.groups.any? collector << "GROUP BY " collector = inject_join o.groups, collector, ", " end maybe_visit o.having, collector end def visit_Arel_Nodes_Offset o, collector collector << "SKIP " visit o.expr, collector end def visit_Arel_Nodes_Limit o, collector collector << "FIRST " visit o.expr, collector collector << " " end end end end arel-6.0.3/lib/arel/visitors/where_sql.rb0000644000004100000410000000036612563210504020367 0ustar www-datawww-datamodule Arel module Visitors class WhereSql < Arel::Visitors::ToSql private def visit_Arel_Nodes_SelectCore o, collector collector << "WHERE " inject_join o.wheres, collector, ' AND ' end end end end arel-6.0.3/lib/arel/visitors/ibm_db.rb0000644000004100000410000000042312563210504017604 0ustar www-datawww-datamodule Arel module Visitors class IBM_DB < Arel::Visitors::ToSql private def visit_Arel_Nodes_Limit o, collector collector << "FETCH FIRST " collector = visit o.expr, collector collector << " ROWS ONLY" end end end end arel-6.0.3/lib/arel/visitors/sqlite.rb0000644000004100000410000000056112563210504017674 0ustar www-datawww-datamodule Arel module Visitors class SQLite < Arel::Visitors::ToSql private # Locks are not supported in SQLite def visit_Arel_Nodes_Lock o, collector collector end def visit_Arel_Nodes_SelectStatement o, collector o.limit = Arel::Nodes::Limit.new(-1) if o.offset && !o.limit super end end end end arel-6.0.3/lib/arel/visitors/postgresql.rb0000644000004100000410000000140212563210504020571 0ustar www-datawww-datamodule Arel module Visitors class PostgreSQL < Arel::Visitors::ToSql private def visit_Arel_Nodes_Matches o, collector infix_value o, collector, ' ILIKE ' end def visit_Arel_Nodes_DoesNotMatch o, collector infix_value o, collector, ' NOT ILIKE ' end def visit_Arel_Nodes_Regexp o, collector infix_value o, collector, ' ~ ' end def visit_Arel_Nodes_NotRegexp o, collector infix_value o, collector, ' !~ ' end def visit_Arel_Nodes_DistinctOn o, collector collector << "DISTINCT ON ( " visit(o.expr, collector) << " )" end def visit_Arel_Nodes_BindParam o, collector collector.add_bind(o) { |i| "$#{i}" } end end end end arel-6.0.3/lib/arel/visitors/mssql.rb0000644000004100000410000000511212563210504017527 0ustar www-datawww-datamodule Arel module Visitors class MSSQL < Arel::Visitors::ToSql RowNumber = Struct.new :children private # `top` wouldn't really work here. I.e. User.select("distinct first_name").limit(10) would generate # "select top 10 distinct first_name from users", which is invalid query! it should be # "select distinct top 10 first_name from users" def visit_Arel_Nodes_Top o "" end def visit_Arel_Visitors_MSSQL_RowNumber o, collector collector << "ROW_NUMBER() OVER (ORDER BY " inject_join(o.children, collector, ', ') << ") as _row_num" end def visit_Arel_Nodes_SelectStatement o, collector if !o.limit && !o.offset return super end is_select_count = false o.cores.each { |x| core_order_by = row_num_literal determine_order_by(o.orders, x) if select_count? x x.projections = [core_order_by] is_select_count = true else x.projections << core_order_by end } if is_select_count # fixme count distinct wouldn't work with limit or offset collector << "SELECT COUNT(1) as count_id FROM (" end collector << "SELECT _t.* FROM (" collector = o.cores.inject(collector) { |c,x| visit_Arel_Nodes_SelectCore x, c } collector << ") as _t WHERE #{get_offset_limit_clause(o)}" if is_select_count collector << ") AS subquery" else collector end end def get_offset_limit_clause o first_row = o.offset ? o.offset.expr.to_i + 1 : 1 last_row = o.limit ? o.limit.expr.to_i - 1 + first_row : nil if last_row " _row_num BETWEEN #{first_row} AND #{last_row}" else " _row_num >= #{first_row}" end end def determine_order_by orders, x if orders.any? orders elsif x.groups.any? x.groups else pk = find_left_table_pk(x.froms) pk ? [pk] : [] end end def row_num_literal order_by RowNumber.new order_by end def select_count? x x.projections.length == 1 && Arel::Nodes::Count === x.projections.first end # FIXME raise exception of there is no pk? # FIXME!! Table.primary_key will be deprecated. What is the replacement?? def find_left_table_pk o return o.primary_key if o.instance_of? Arel::Table find_left_table_pk o.left if o.kind_of? Arel::Nodes::Join end end end end arel-6.0.3/lib/arel/visitors/to_sql.rb0000644000004100000410000005561112563210504017702 0ustar www-datawww-datarequire 'bigdecimal' require 'date' require 'arel/visitors/reduce' module Arel module Visitors class ToSql < Arel::Visitors::Reduce ## # This is some roflscale crazy stuff. I'm roflscaling this because # building SQL queries is a hotspot. I will explain the roflscale so that # others will not rm this code. # # In YARV, string literals in a method body will get duped when the byte # code is executed. Let's take a look: # # > puts RubyVM::InstructionSequence.new('def foo; "bar"; end').disasm # # == disasm: >===== # 0000 trace 8 # 0002 trace 1 # 0004 putstring "bar" # 0006 trace 16 # 0008 leave # # The `putstring` bytecode will dup the string and push it on the stack. # In many cases in our SQL visitor, that string is never mutated, so there # is no need to dup the literal. # # If we change to a constant lookup, the string will not be duped, and we # can reduce the objects in our system: # # > puts RubyVM::InstructionSequence.new('BAR = "bar"; def foo; BAR; end').disasm # # == disasm: >======== # 0000 trace 8 # 0002 trace 1 # 0004 getinlinecache 11, # 0007 getconstant :BAR # 0009 setinlinecache # 0011 trace 16 # 0013 leave # # `getconstant` should be a hash lookup, and no object is duped when the # value of the constant is pushed on the stack. Hence the crazy # constants below. # # `matches` and `doesNotMatch` operate case-insensitively via Visitor subclasses # specialized for specific databases when necessary. # WHERE = ' WHERE ' # :nodoc: SPACE = ' ' # :nodoc: COMMA = ', ' # :nodoc: GROUP_BY = ' GROUP BY ' # :nodoc: ORDER_BY = ' ORDER BY ' # :nodoc: WINDOW = ' WINDOW ' # :nodoc: AND = ' AND ' # :nodoc: DISTINCT = 'DISTINCT' # :nodoc: def initialize connection super() @connection = connection end def compile node, &block accept(node, Arel::Collectors::SQLString.new, &block).value end private def schema_cache @connection.schema_cache end def visit_Arel_Nodes_DeleteStatement o, collector collector << "DELETE FROM " collector = visit o.relation, collector if o.wheres.any? collector << " WHERE " inject_join o.wheres, collector, AND else collector end end # FIXME: we should probably have a 2-pass visitor for this def build_subselect key, o stmt = Nodes::SelectStatement.new core = stmt.cores.first core.froms = o.relation core.wheres = o.wheres core.projections = [key] stmt.limit = o.limit stmt.orders = o.orders stmt end def visit_Arel_Nodes_UpdateStatement o, collector if o.orders.empty? && o.limit.nil? wheres = o.wheres else wheres = [Nodes::In.new(o.key, [build_subselect(o.key, o)])] end collector << "UPDATE " collector = visit o.relation, collector unless o.values.empty? collector << " SET " collector = inject_join o.values, collector, ", " end unless wheres.empty? collector << " WHERE " collector = inject_join wheres, collector, " AND " end collector end def visit_Arel_Nodes_InsertStatement o, collector collector << "INSERT INTO " collector = visit o.relation, collector if o.columns.any? collector << " (#{o.columns.map { |x| quote_column_name x.name }.join ', '})" end if o.values maybe_visit o.values, collector elsif o.select maybe_visit o.select, collector else collector end end def visit_Arel_Nodes_Exists o, collector collector << "EXISTS (" collector = visit(o.expressions, collector) << ")" if o.alias collector << " AS " visit o.alias, collector else collector end end def visit_Arel_Nodes_Casted o, collector collector << quoted(o.val, o.attribute).to_s end def visit_Arel_Nodes_Quoted o, collector collector << quoted(o.expr, nil).to_s end def visit_Arel_Nodes_True o, collector collector << "TRUE" end def visit_Arel_Nodes_False o, collector collector << "FALSE" end def table_exists? name schema_cache.table_exists? name end def column_for attr return unless attr name = attr.name.to_s table = attr.relation.table_name return nil unless table_exists? table column_cache(table)[name] end def column_cache(table) schema_cache.columns_hash(table) end def visit_Arel_Nodes_Values o, collector collector << "VALUES (" len = o.expressions.length - 1 o.expressions.zip(o.columns).each_with_index { |(value, attr), i| case value when Nodes::SqlLiteral, Nodes::BindParam collector = visit value, collector else collector << quote(value, attr && column_for(attr)).to_s end unless i == len collector << ', ' end } collector << ")" end def visit_Arel_Nodes_SelectStatement o, collector if o.with collector = visit o.with, collector collector << SPACE end collector = o.cores.inject(collector) { |c,x| visit_Arel_Nodes_SelectCore(x, c) } unless o.orders.empty? collector << SPACE collector << ORDER_BY len = o.orders.length - 1 o.orders.each_with_index { |x, i| collector = visit(x, collector) collector << COMMA unless len == i } end collector = maybe_visit o.limit, collector collector = maybe_visit o.offset, collector collector = maybe_visit o.lock, collector collector end def visit_Arel_Nodes_SelectCore o, collector collector << "SELECT" collector = maybe_visit o.top, collector collector = maybe_visit o.set_quantifier, collector unless o.projections.empty? collector << SPACE len = o.projections.length - 1 o.projections.each_with_index do |x, i| collector = visit(x, collector) collector << COMMA unless len == i end end if o.source && !o.source.empty? collector << " FROM " collector = visit o.source, collector end unless o.wheres.empty? collector << WHERE len = o.wheres.length - 1 o.wheres.each_with_index do |x, i| collector = visit(x, collector) collector << AND unless len == i end end unless o.groups.empty? collector << GROUP_BY len = o.groups.length - 1 o.groups.each_with_index do |x, i| collector = visit(x, collector) collector << COMMA unless len == i end end collector = maybe_visit o.having, collector unless o.windows.empty? collector << WINDOW len = o.windows.length - 1 o.windows.each_with_index do |x, i| collector = visit(x, collector) collector << COMMA unless len == i end end collector end def visit_Arel_Nodes_Bin o, collector visit o.expr, collector end def visit_Arel_Nodes_Distinct o, collector collector << DISTINCT end def visit_Arel_Nodes_DistinctOn o, collector raise NotImplementedError, 'DISTINCT ON not implemented for this db' end def visit_Arel_Nodes_With o, collector collector << "WITH " inject_join o.children, collector, ', ' end def visit_Arel_Nodes_WithRecursive o, collector collector << "WITH RECURSIVE " inject_join o.children, collector, ', ' end def visit_Arel_Nodes_Union o, collector collector << "( " infix_value(o, collector, " UNION ") << " )" end def visit_Arel_Nodes_UnionAll o, collector collector << "( " infix_value(o, collector, " UNION ALL ") << " )" end def visit_Arel_Nodes_Intersect o, collector collector << "( " infix_value(o, collector, " INTERSECT ") << " )" end def visit_Arel_Nodes_Except o, collector collector << "( " infix_value(o, collector, " EXCEPT ") << " )" end def visit_Arel_Nodes_NamedWindow o, collector collector << quote_column_name(o.name) collector << " AS " visit_Arel_Nodes_Window o, collector end def visit_Arel_Nodes_Window o, collector collector << "(" if o.partitions.any? collector << "PARTITION BY " collector = inject_join o.partitions, collector, ", " end if o.orders.any? collector << ' ' if o.partitions.any? collector << "ORDER BY " collector = inject_join o.orders, collector, ", " end if o.framing collector << ' ' if o.partitions.any? or o.orders.any? collector = visit o.framing, collector end collector << ")" end def visit_Arel_Nodes_Rows o, collector if o.expr collector << "ROWS " visit o.expr, collector else collector << "ROWS" end end def visit_Arel_Nodes_Range o, collector if o.expr collector << "RANGE " visit o.expr, collector else collector << "RANGE" end end def visit_Arel_Nodes_Preceding o, collector collector = if o.expr visit o.expr, collector else collector << "UNBOUNDED" end collector << " PRECEDING" end def visit_Arel_Nodes_Following o, collector collector = if o.expr visit o.expr, collector else collector << "UNBOUNDED" end collector << " FOLLOWING" end def visit_Arel_Nodes_CurrentRow o, collector collector << "CURRENT ROW" end def visit_Arel_Nodes_Over o, collector case o.right when nil visit(o.left, collector) << " OVER ()" when Arel::Nodes::SqlLiteral infix_value o, collector, " OVER " when String, Symbol visit(o.left, collector) << " OVER #{quote_column_name o.right.to_s}" else infix_value o, collector, " OVER " end end def visit_Arel_Nodes_Having o, collector collector << "HAVING " visit o.expr, collector end def visit_Arel_Nodes_Offset o, collector collector << "OFFSET " visit o.expr, collector end def visit_Arel_Nodes_Limit o, collector collector << "LIMIT " visit o.expr, collector end # FIXME: this does nothing on most databases, but does on MSSQL def visit_Arel_Nodes_Top o, collector collector end def visit_Arel_Nodes_Lock o, collector visit o.expr, collector end def visit_Arel_Nodes_Grouping o, collector if o.expr.is_a? Nodes::Grouping visit(o.expr, collector) else collector << "(" visit(o.expr, collector) << ")" end end def visit_Arel_SelectManager o, collector collector << "(#{o.to_sql.rstrip})" end def visit_Arel_Nodes_Ascending o, collector visit(o.expr, collector) << " ASC" end def visit_Arel_Nodes_Descending o, collector visit(o.expr, collector) << " DESC" end def visit_Arel_Nodes_Group o, collector visit o.expr, collector end def visit_Arel_Nodes_NamedFunction o, collector collector << o.name collector << "(" collector << "DISTINCT " if o.distinct collector = inject_join(o.expressions, collector, ", ") << ")" if o.alias collector << " AS " visit o.alias, collector else collector end end def visit_Arel_Nodes_Extract o, collector collector << "EXTRACT(#{o.field.to_s.upcase} FROM " visit(o.expr, collector) << ")" end def visit_Arel_Nodes_Count o, collector aggregate "COUNT", o, collector end def visit_Arel_Nodes_Sum o, collector aggregate "SUM", o, collector end def visit_Arel_Nodes_Max o, collector aggregate "MAX", o, collector end def visit_Arel_Nodes_Min o, collector aggregate "MIN", o, collector end def visit_Arel_Nodes_Avg o, collector aggregate "AVG", o, collector end def visit_Arel_Nodes_TableAlias o, collector collector = visit o.relation, collector collector << " " collector << quote_table_name(o.name) end def visit_Arel_Nodes_Between o, collector collector = visit o.left, collector collector << " BETWEEN " visit o.right, collector end def visit_Arel_Nodes_GreaterThanOrEqual o, collector collector = visit o.left, collector collector << " >= " visit o.right, collector end def visit_Arel_Nodes_GreaterThan o, collector collector = visit o.left, collector collector << " > " visit o.right, collector end def visit_Arel_Nodes_LessThanOrEqual o, collector collector = visit o.left, collector collector << " <= " visit o.right, collector end def visit_Arel_Nodes_LessThan o, collector collector = visit o.left, collector collector << " < " visit o.right, collector end def visit_Arel_Nodes_Matches o, collector collector = visit o.left, collector collector << " LIKE " collector = visit o.right, collector if o.escape collector << ' ESCAPE ' visit o.escape, collector else collector end end def visit_Arel_Nodes_DoesNotMatch o, collector collector = visit o.left, collector collector << " NOT LIKE " collector = visit o.right, collector if o.escape collector << ' ESCAPE ' visit o.escape, collector else collector end end def visit_Arel_Nodes_JoinSource o, collector if o.left collector = visit o.left, collector end if o.right.any? collector << " " if o.left collector = inject_join o.right, collector, ' ' end collector end def visit_Arel_Nodes_Regexp o, collector raise NotImplementedError, '~ not implemented for this db' end def visit_Arel_Nodes_NotRegexp o, collector raise NotImplementedError, '!~ not implemented for this db' end def visit_Arel_Nodes_StringJoin o, collector visit o.left, collector end def visit_Arel_Nodes_FullOuterJoin o, collector collector << "FULL OUTER JOIN " collector = visit o.left, collector collector << SPACE visit o.right, collector end def visit_Arel_Nodes_OuterJoin o, collector collector << "LEFT OUTER JOIN " collector = visit o.left, collector collector << " " visit o.right, collector end def visit_Arel_Nodes_RightOuterJoin o, collector collector << "RIGHT OUTER JOIN " collector = visit o.left, collector collector << SPACE visit o.right, collector end def visit_Arel_Nodes_InnerJoin o, collector collector << "INNER JOIN " collector = visit o.left, collector if o.right collector << SPACE visit(o.right, collector) else collector end end def visit_Arel_Nodes_On o, collector collector << "ON " visit o.expr, collector end def visit_Arel_Nodes_Not o, collector collector << "NOT (" visit(o.expr, collector) << ")" end def visit_Arel_Table o, collector if o.table_alias collector << "#{quote_table_name o.name} #{quote_table_name o.table_alias}" else collector << quote_table_name(o.name) end end def visit_Arel_Nodes_In o, collector if Array === o.right && o.right.empty? collector << '1=0' else collector = visit o.left, collector collector << " IN (" visit(o.right, collector) << ")" end end def visit_Arel_Nodes_NotIn o, collector if Array === o.right && o.right.empty? collector << '1=1' else collector = visit o.left, collector collector << " NOT IN (" collector = visit o.right, collector collector << ")" end end def visit_Arel_Nodes_And o, collector inject_join o.children, collector, " AND " end def visit_Arel_Nodes_Or o, collector collector = visit o.left, collector collector << " OR " visit o.right, collector end def visit_Arel_Nodes_Assignment o, collector case o.right when Arel::Nodes::UnqualifiedColumn, Arel::Attributes::Attribute, Arel::Nodes::BindParam collector = visit o.left, collector collector << " = " visit o.right, collector else collector = visit o.left, collector collector << " = " collector << quote(o.right, column_for(o.left)).to_s end end def visit_Arel_Nodes_Equality o, collector right = o.right collector = visit o.left, collector if right.nil? collector << " IS NULL" else collector << " = " visit right, collector end end def visit_Arel_Nodes_NotEqual o, collector right = o.right collector = visit o.left, collector if right.nil? collector << " IS NOT NULL" else collector << " != " visit right, collector end end def visit_Arel_Nodes_As o, collector collector = visit o.left, collector collector << " AS " visit o.right, collector end def visit_Arel_Nodes_UnqualifiedColumn o, collector collector << "#{quote_column_name o.name}" collector end def visit_Arel_Attributes_Attribute o, collector join_name = o.relation.table_alias || o.relation.name collector << "#{quote_table_name join_name}.#{quote_column_name o.name}" end alias :visit_Arel_Attributes_Integer :visit_Arel_Attributes_Attribute alias :visit_Arel_Attributes_Float :visit_Arel_Attributes_Attribute alias :visit_Arel_Attributes_Decimal :visit_Arel_Attributes_Attribute alias :visit_Arel_Attributes_String :visit_Arel_Attributes_Attribute alias :visit_Arel_Attributes_Time :visit_Arel_Attributes_Attribute alias :visit_Arel_Attributes_Boolean :visit_Arel_Attributes_Attribute def literal o, collector; collector << o.to_s; end def visit_Arel_Nodes_BindParam o, collector collector.add_bind(o) { "?" } end alias :visit_Arel_Nodes_SqlLiteral :literal alias :visit_Bignum :literal alias :visit_Fixnum :literal def quoted o, a quote(o, column_for(a)) end def unsupported o, collector raise "unsupported: #{o.class.name}" end alias :visit_ActiveSupport_Multibyte_Chars :unsupported alias :visit_ActiveSupport_StringInquirer :unsupported alias :visit_BigDecimal :unsupported alias :visit_Class :unsupported alias :visit_Date :unsupported alias :visit_DateTime :unsupported alias :visit_FalseClass :unsupported alias :visit_Float :unsupported alias :visit_Hash :unsupported alias :visit_NilClass :unsupported alias :visit_String :unsupported alias :visit_Symbol :unsupported alias :visit_Time :unsupported alias :visit_TrueClass :unsupported def visit_Arel_Nodes_InfixOperation o, collector collector = visit o.left, collector collector << " #{o.operator} " visit o.right, collector end alias :visit_Arel_Nodes_Addition :visit_Arel_Nodes_InfixOperation alias :visit_Arel_Nodes_Subtraction :visit_Arel_Nodes_InfixOperation alias :visit_Arel_Nodes_Multiplication :visit_Arel_Nodes_InfixOperation alias :visit_Arel_Nodes_Division :visit_Arel_Nodes_InfixOperation def visit_Array o, collector inject_join o, collector, ", " end alias :visit_Set :visit_Array def quote value, column = nil return value if Arel::Nodes::SqlLiteral === value @connection.quote value, column end def quote_table_name name return name if Arel::Nodes::SqlLiteral === name @connection.quote_table_name(name) end def quote_column_name name return name if Arel::Nodes::SqlLiteral === name @connection.quote_column_name(name) end def maybe_visit thing, collector return collector unless thing collector << " " visit thing, collector end def inject_join list, collector, join_str len = list.length - 1 list.each_with_index.inject(collector) { |c, (x,i)| if i == len visit x, c else visit(x, c) << join_str end } end def infix_value o, collector, value collector = visit o.left, collector collector << value visit o.right, collector end def aggregate name, o, collector collector << "#{name}(" if o.distinct collector << "DISTINCT " end collector = inject_join(o.expressions, collector, ", ") << ")" if o.alias collector << " AS " visit o.alias, collector else collector end end end end end arel-6.0.3/lib/arel/visitors/oracle.rb0000644000004100000410000001014512563210504017637 0ustar www-datawww-datamodule Arel module Visitors class Oracle < Arel::Visitors::ToSql private def visit_Arel_Nodes_SelectStatement o, collector o = order_hacks(o) # if need to select first records without ORDER BY and GROUP BY and without DISTINCT # then can use simple ROWNUM in WHERE clause if o.limit && o.orders.empty? && o.cores.first.groups.empty? && !o.offset && o.cores.first.set_quantifier.class.to_s !~ /Distinct/ o.cores.last.wheres.push Nodes::LessThanOrEqual.new( Nodes::SqlLiteral.new('ROWNUM'), o.limit.expr ) return super end if o.limit && o.offset o = o.dup limit = o.limit.expr offset = o.offset o.offset = nil collector << " SELECT * FROM ( SELECT raw_sql_.*, rownum raw_rnum_ FROM (" collector = super(o, collector) collector << ") raw_sql_ WHERE rownum <= #{offset.expr.to_i + limit} ) WHERE " return visit(offset, collector) end if o.limit o = o.dup limit = o.limit.expr collector << "SELECT * FROM (" collector = super(o, collector) collector << ") WHERE ROWNUM <= " return visit limit, collector end if o.offset o = o.dup offset = o.offset o.offset = nil collector << "SELECT * FROM ( SELECT raw_sql_.*, rownum raw_rnum_ FROM (" collector = super(o, collector) collector << ") raw_sql_ ) WHERE " return visit offset, collector end super end def visit_Arel_Nodes_Limit o, collector collector end def visit_Arel_Nodes_Offset o, collector collector << "raw_rnum_ > " visit o.expr, collector end def visit_Arel_Nodes_Except o, collector collector << "( " collector = infix_value o, collector, " MINUS " collector << " )" end def visit_Arel_Nodes_UpdateStatement o, collector # Oracle does not allow ORDER BY/LIMIT in UPDATEs. if o.orders.any? && o.limit.nil? # However, there is no harm in silently eating the ORDER BY clause if no LIMIT has been provided, # otherwise let the user deal with the error o = o.dup o.orders = [] end super end ### # Hacks for the order clauses specific to Oracle def order_hacks o return o if o.orders.empty? return o unless o.cores.any? do |core| core.projections.any? do |projection| /FIRST_VALUE/ === projection end end # Previous version with join and split broke ORDER BY clause # if it contained functions with several arguments (separated by ','). # # orders = o.orders.map { |x| visit x }.join(', ').split(',') orders = o.orders.map do |x| string = visit(x, Arel::Collectors::SQLString.new).value if string.include?(',') split_order_string(string) else string end end.flatten o.orders = [] orders.each_with_index do |order, i| o.orders << Nodes::SqlLiteral.new("alias_#{i}__#{' DESC' if /\bdesc$/i === order}") end o end # Split string by commas but count opening and closing brackets # and ignore commas inside brackets. def split_order_string(string) array = [] i = 0 string.split(',').each do |part| if array[i] array[i] << ',' << part else # to ensure that array[i] will be String and not Arel::Nodes::SqlLiteral array[i] = '' << part end i += 1 if array[i].count('(') == array[i].count(')') end array end def visit_Arel_Nodes_BindParam o, collector collector.add_bind(o) { |i| ":a#{i}" } end end end end arel-6.0.3/lib/arel/visitors/reduce.rb0000644000004100000410000000123212563210504017636 0ustar www-datawww-datarequire 'arel/visitors/visitor' module Arel module Visitors class Reduce < Arel::Visitors::Visitor def accept object, collector visit object, collector end private def visit object, collector send dispatch[object.class], object, collector rescue NoMethodError => e raise e if respond_to?(dispatch[object.class], true) superklass = object.class.ancestors.find { |klass| respond_to?(dispatch[klass], true) } raise(TypeError, "Cannot visit #{object.class}") unless superklass dispatch[object.class] = dispatch[superklass] retry end end end end arel-6.0.3/lib/arel/visitors/bind_substitute.rb0000644000004100000410000000021612563210504021577 0ustar www-datawww-datamodule Arel module Visitors class BindSubstitute def initialize delegate @delegate = delegate end end end end arel-6.0.3/lib/arel/visitors/depth_first.rb0000644000004100000410000001406612563210504020713 0ustar www-datawww-datamodule Arel module Visitors class DepthFirst < Arel::Visitors::Visitor def initialize block = nil @block = block || Proc.new super() end private def visit o super @block.call o end def unary o visit o.expr end alias :visit_Arel_Nodes_Group :unary alias :visit_Arel_Nodes_Grouping :unary alias :visit_Arel_Nodes_Having :unary alias :visit_Arel_Nodes_Limit :unary alias :visit_Arel_Nodes_Not :unary alias :visit_Arel_Nodes_Offset :unary alias :visit_Arel_Nodes_On :unary alias :visit_Arel_Nodes_Ordering :unary alias :visit_Arel_Nodes_Ascending :unary alias :visit_Arel_Nodes_Descending :unary alias :visit_Arel_Nodes_Top :unary alias :visit_Arel_Nodes_UnqualifiedColumn :unary def function o visit o.expressions visit o.alias visit o.distinct end alias :visit_Arel_Nodes_Avg :function alias :visit_Arel_Nodes_Exists :function alias :visit_Arel_Nodes_Max :function alias :visit_Arel_Nodes_Min :function alias :visit_Arel_Nodes_Sum :function def visit_Arel_Nodes_NamedFunction o visit o.name visit o.expressions visit o.distinct visit o.alias end def visit_Arel_Nodes_Count o visit o.expressions visit o.alias visit o.distinct end def nary o o.children.each { |child| visit child} end alias :visit_Arel_Nodes_And :nary def binary o visit o.left visit o.right end alias :visit_Arel_Nodes_As :binary alias :visit_Arel_Nodes_Assignment :binary alias :visit_Arel_Nodes_Between :binary alias :visit_Arel_Nodes_DeleteStatement :binary alias :visit_Arel_Nodes_DoesNotMatch :binary alias :visit_Arel_Nodes_Equality :binary alias :visit_Arel_Nodes_FullOuterJoin :binary alias :visit_Arel_Nodes_GreaterThan :binary alias :visit_Arel_Nodes_GreaterThanOrEqual :binary alias :visit_Arel_Nodes_In :binary alias :visit_Arel_Nodes_InfixOperation :binary alias :visit_Arel_Nodes_JoinSource :binary alias :visit_Arel_Nodes_InnerJoin :binary alias :visit_Arel_Nodes_LessThan :binary alias :visit_Arel_Nodes_LessThanOrEqual :binary alias :visit_Arel_Nodes_Matches :binary alias :visit_Arel_Nodes_NotEqual :binary alias :visit_Arel_Nodes_NotIn :binary alias :visit_Arel_Nodes_NotRegexp :binary alias :visit_Arel_Nodes_Or :binary alias :visit_Arel_Nodes_OuterJoin :binary alias :visit_Arel_Nodes_Regexp :binary alias :visit_Arel_Nodes_RightOuterJoin :binary alias :visit_Arel_Nodes_TableAlias :binary alias :visit_Arel_Nodes_Values :binary alias :visit_Arel_Nodes_Union :binary def visit_Arel_Nodes_StringJoin o visit o.left end def visit_Arel_Attribute o visit o.relation visit o.name end alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute alias :visit_Arel_Attributes_Float :visit_Arel_Attribute alias :visit_Arel_Attributes_String :visit_Arel_Attribute alias :visit_Arel_Attributes_Time :visit_Arel_Attribute alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute alias :visit_Arel_Attributes_Decimal :visit_Arel_Attribute def visit_Arel_Table o visit o.name end def terminal o end alias :visit_ActiveSupport_Multibyte_Chars :terminal alias :visit_ActiveSupport_StringInquirer :terminal alias :visit_Arel_Nodes_Lock :terminal alias :visit_Arel_Nodes_Node :terminal alias :visit_Arel_Nodes_SqlLiteral :terminal alias :visit_Arel_Nodes_BindParam :terminal alias :visit_Arel_Nodes_Window :terminal alias :visit_Arel_Nodes_True :terminal alias :visit_Arel_Nodes_False :terminal alias :visit_BigDecimal :terminal alias :visit_Bignum :terminal alias :visit_Class :terminal alias :visit_Date :terminal alias :visit_DateTime :terminal alias :visit_FalseClass :terminal alias :visit_Fixnum :terminal alias :visit_Float :terminal alias :visit_NilClass :terminal alias :visit_String :terminal alias :visit_Symbol :terminal alias :visit_Time :terminal alias :visit_TrueClass :terminal def visit_Arel_Nodes_InsertStatement o visit o.relation visit o.columns visit o.values end def visit_Arel_Nodes_SelectCore o visit o.projections visit o.source visit o.wheres visit o.groups visit o.windows visit o.having end def visit_Arel_Nodes_SelectStatement o visit o.cores visit o.orders visit o.limit visit o.lock visit o.offset end def visit_Arel_Nodes_UpdateStatement o visit o.relation visit o.values visit o.wheres visit o.orders visit o.limit end def visit_Array o o.each { |i| visit i } end alias :visit_Set :visit_Array def visit_Hash o o.each { |k,v| visit(k); visit(v) } end DISPATCH = dispatch_cache def get_dispatch_cache DISPATCH end end end end arel-6.0.3/lib/arel/visitors/dot.rb0000644000004100000410000001746712563210504017176 0ustar www-datawww-datamodule Arel module Visitors class Dot < Arel::Visitors::Visitor class Node # :nodoc: attr_accessor :name, :id, :fields def initialize name, id, fields = [] @name = name @id = id @fields = fields end end class Edge < Struct.new :name, :from, :to # :nodoc: end def initialize super() @nodes = [] @edges = [] @node_stack = [] @edge_stack = [] @seen = {} end def accept object, collector visit object collector << to_dot end private def visit_Arel_Nodes_Ordering o visit_edge o, "expr" end def visit_Arel_Nodes_TableAlias o visit_edge o, "name" visit_edge o, "relation" end def visit_Arel_Nodes_Count o visit_edge o, "expressions" visit_edge o, "distinct" end def visit_Arel_Nodes_Values o visit_edge o, "expressions" end def visit_Arel_Nodes_StringJoin o visit_edge o, "left" end def visit_Arel_Nodes_InnerJoin o visit_edge o, "left" visit_edge o, "right" end alias :visit_Arel_Nodes_FullOuterJoin :visit_Arel_Nodes_InnerJoin alias :visit_Arel_Nodes_OuterJoin :visit_Arel_Nodes_InnerJoin alias :visit_Arel_Nodes_RightOuterJoin :visit_Arel_Nodes_InnerJoin def visit_Arel_Nodes_DeleteStatement o visit_edge o, "relation" visit_edge o, "wheres" end def unary o visit_edge o, "expr" end alias :visit_Arel_Nodes_Group :unary alias :visit_Arel_Nodes_Grouping :unary alias :visit_Arel_Nodes_Having :unary alias :visit_Arel_Nodes_Limit :unary alias :visit_Arel_Nodes_Not :unary alias :visit_Arel_Nodes_Offset :unary alias :visit_Arel_Nodes_On :unary alias :visit_Arel_Nodes_Top :unary alias :visit_Arel_Nodes_UnqualifiedColumn :unary alias :visit_Arel_Nodes_Preceding :unary alias :visit_Arel_Nodes_Following :unary alias :visit_Arel_Nodes_Rows :unary alias :visit_Arel_Nodes_Range :unary def window o visit_edge o, "partitions" visit_edge o, "orders" visit_edge o, "framing" end alias :visit_Arel_Nodes_Window :window def named_window o visit_edge o, "partitions" visit_edge o, "orders" visit_edge o, "framing" visit_edge o, "name" end alias :visit_Arel_Nodes_NamedWindow :named_window def function o visit_edge o, "expressions" visit_edge o, "distinct" visit_edge o, "alias" end alias :visit_Arel_Nodes_Exists :function alias :visit_Arel_Nodes_Min :function alias :visit_Arel_Nodes_Max :function alias :visit_Arel_Nodes_Avg :function alias :visit_Arel_Nodes_Sum :function def extract o visit_edge o, "expressions" visit_edge o, "alias" end alias :visit_Arel_Nodes_Extract :extract def visit_Arel_Nodes_NamedFunction o visit_edge o, "name" visit_edge o, "expressions" visit_edge o, "distinct" visit_edge o, "alias" end def visit_Arel_Nodes_InsertStatement o visit_edge o, "relation" visit_edge o, "columns" visit_edge o, "values" end def visit_Arel_Nodes_SelectCore o visit_edge o, "source" visit_edge o, "projections" visit_edge o, "wheres" visit_edge o, "windows" end def visit_Arel_Nodes_SelectStatement o visit_edge o, "cores" visit_edge o, "limit" visit_edge o, "orders" visit_edge o, "offset" end def visit_Arel_Nodes_UpdateStatement o visit_edge o, "relation" visit_edge o, "wheres" visit_edge o, "values" end def visit_Arel_Table o visit_edge o, "name" end def visit_Arel_Attribute o visit_edge o, "relation" visit_edge o, "name" end alias :visit_Arel_Attributes_Integer :visit_Arel_Attribute alias :visit_Arel_Attributes_Float :visit_Arel_Attribute alias :visit_Arel_Attributes_String :visit_Arel_Attribute alias :visit_Arel_Attributes_Time :visit_Arel_Attribute alias :visit_Arel_Attributes_Boolean :visit_Arel_Attribute alias :visit_Arel_Attributes_Attribute :visit_Arel_Attribute def nary o o.children.each_with_index do |x,i| edge(i) { visit x } end end alias :visit_Arel_Nodes_And :nary def binary o visit_edge o, "left" visit_edge o, "right" end alias :visit_Arel_Nodes_As :binary alias :visit_Arel_Nodes_Assignment :binary alias :visit_Arel_Nodes_Between :binary alias :visit_Arel_Nodes_DoesNotMatch :binary alias :visit_Arel_Nodes_Equality :binary alias :visit_Arel_Nodes_GreaterThan :binary alias :visit_Arel_Nodes_GreaterThanOrEqual :binary alias :visit_Arel_Nodes_In :binary alias :visit_Arel_Nodes_JoinSource :binary alias :visit_Arel_Nodes_LessThan :binary alias :visit_Arel_Nodes_LessThanOrEqual :binary alias :visit_Arel_Nodes_Matches :binary alias :visit_Arel_Nodes_NotEqual :binary alias :visit_Arel_Nodes_NotIn :binary alias :visit_Arel_Nodes_Or :binary alias :visit_Arel_Nodes_Over :binary def visit_String o @node_stack.last.fields << o end alias :visit_Time :visit_String alias :visit_Date :visit_String alias :visit_DateTime :visit_String alias :visit_NilClass :visit_String alias :visit_TrueClass :visit_String alias :visit_FalseClass :visit_String alias :visit_Arel_Nodes_BindParam :visit_String alias :visit_Fixnum :visit_String alias :visit_BigDecimal :visit_String alias :visit_Float :visit_String alias :visit_Symbol :visit_String alias :visit_Arel_Nodes_SqlLiteral :visit_String def visit_Hash o o.each_with_index do |pair, i| edge("pair_#{i}") { visit pair } end end def visit_Array o o.each_with_index do |x,i| edge(i) { visit x } end end alias :visit_Set :visit_Array def visit_edge o, method edge(method) { visit o.send(method) } end def visit o if node = @seen[o.object_id] @edge_stack.last.to = node return end node = Node.new(o.class.name, o.object_id) @seen[node.id] = node @nodes << node with_node node do super end end def edge name edge = Edge.new(name, @node_stack.last) @edge_stack.push edge @edges << edge yield @edge_stack.pop end def with_node node if edge = @edge_stack.last edge.to = node end @node_stack.push node yield @node_stack.pop end def quote string string.to_s.gsub('"', '\"') end def to_dot "digraph \"Arel\" {\nnode [width=0.375,height=0.25,shape=record];\n" + @nodes.map { |node| label = "#{node.name}" node.fields.each_with_index do |field, i| label << "|#{quote field}" end "#{node.id} [label=\"#{label}\"];" }.join("\n") + "\n" + @edges.map { |edge| "#{edge.from.id} -> #{edge.to.id} [label=\"#{edge.name}\"];" }.join("\n") + "\n}" end end end end arel-6.0.3/lib/arel/visitors/bind_visitor.rb0000644000004100000410000000135112563210504021064 0ustar www-datawww-datamodule Arel module Visitors module BindVisitor def initialize target @block = nil super end def accept node, collector, &block @block = block if block_given? super end private def visit_Arel_Nodes_Assignment o, collector if o.right.is_a? Arel::Nodes::BindParam collector = visit o.left, collector collector << " = " visit o.right, collector else super end end def visit_Arel_Nodes_BindParam o, collector if @block val = @block.call if String === val collector << val end else super end end end end end arel-6.0.3/lib/arel/visitors/visitor.rb0000644000004100000410000000162212563210504020071 0ustar www-datawww-datamodule Arel module Visitors class Visitor def initialize @dispatch = get_dispatch_cache end def accept object visit object end private def self.dispatch_cache Hash.new do |hash, klass| hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}" end end def get_dispatch_cache self.class.dispatch_cache end def dispatch @dispatch end def visit object send dispatch[object.class], object rescue NoMethodError => e raise e if respond_to?(dispatch[object.class], true) superklass = object.class.ancestors.find { |klass| respond_to?(dispatch[klass], true) } raise(TypeError, "Cannot visit #{object.class}") unless superklass dispatch[object.class] = dispatch[superklass] retry end end end end arel-6.0.3/lib/arel/order_predications.rb0000644000004100000410000000023612563210504020367 0ustar www-datawww-datamodule Arel module OrderPredications def asc Nodes::Ascending.new self end def desc Nodes::Descending.new self end end end arel-6.0.3/lib/arel/collectors/0000755000004100000410000000000012563210504016333 5ustar www-datawww-dataarel-6.0.3/lib/arel/collectors/sql_string.rb0000644000004100000410000000056212563210504021050 0ustar www-datawww-data# encoding: utf-8 require 'arel/collectors/plain_string' module Arel module Collectors class SQLString < PlainString def initialize(*) super @bind_index = 1 end def add_bind bind self << yield(@bind_index) @bind_index += 1 self end def compile bvs value end end end end arel-6.0.3/lib/arel/collectors/plain_string.rb0000644000004100000410000000033612563210504021353 0ustar www-datawww-datamodule Arel module Collectors class PlainString def initialize @str = '' end def value @str end def << str @str << str self end end end end arel-6.0.3/lib/arel/collectors/bind.rb0000644000004100000410000000106312563210504017574 0ustar www-datawww-datamodule Arel module Collectors class Bind def initialize @parts = [] end def << str @parts << str self end def add_bind bind @parts << bind self end def value; @parts; end def substitute_binds bvs bvs = bvs.dup @parts.map do |val| if Arel::Nodes::BindParam === val bvs.shift else val end end end def compile bvs substitute_binds(bvs).join end end end end arel-6.0.3/lib/arel/nodes.rb0000644000004100000410000000440612563210504015623 0ustar www-datawww-data# node require 'arel/nodes/node' require 'arel/nodes/select_statement' require 'arel/nodes/select_core' require 'arel/nodes/insert_statement' require 'arel/nodes/update_statement' require 'arel/nodes/bind_param' # terminal require 'arel/nodes/terminal' require 'arel/nodes/true' require 'arel/nodes/false' # unary require 'arel/nodes/unary' require 'arel/nodes/grouping' require 'arel/nodes/ascending' require 'arel/nodes/descending' require 'arel/nodes/unqualified_column' require 'arel/nodes/with' # binary require 'arel/nodes/binary' require 'arel/nodes/equality' require 'arel/nodes/in' # Why is this subclassed from equality? require 'arel/nodes/join_source' require 'arel/nodes/delete_statement' require 'arel/nodes/table_alias' require 'arel/nodes/infix_operation' require 'arel/nodes/over' require 'arel/nodes/matches' # nary require 'arel/nodes/and' # function # FIXME: Function + Alias can be rewritten as a Function and Alias node. # We should make Function a Unary node and deprecate the use of "aliaz" require 'arel/nodes/function' require 'arel/nodes/count' require 'arel/nodes/extract' require 'arel/nodes/values' require 'arel/nodes/named_function' # windows require 'arel/nodes/window' # joins require 'arel/nodes/full_outer_join' require 'arel/nodes/inner_join' require 'arel/nodes/outer_join' require 'arel/nodes/right_outer_join' require 'arel/nodes/string_join' require 'arel/nodes/sql_literal' module Arel module Nodes class Casted < Arel::Nodes::Node # :nodoc: attr_reader :val, :attribute def initialize val, attribute @val = val @attribute = attribute super() end def nil?; @val.nil?; end def eql? other self.class == other.class && self.val == other.val && self.attribute == other.attribute end alias :== :eql? end class Quoted < Arel::Nodes::Unary # :nodoc: end def self.build_quoted other, attribute = nil case other when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Table, Arel::Nodes::BindParam, Arel::SelectManager other else case attribute when Arel::Attributes::Attribute Casted.new other, attribute else Quoted.new other end end end end end arel-6.0.3/lib/arel.rb0000644000004100000410000000127312563210504014512 0ustar www-datawww-datarequire 'arel/crud' require 'arel/factory_methods' require 'arel/expressions' require 'arel/predications' require 'arel/window_predications' require 'arel/math' require 'arel/alias_predication' require 'arel/order_predications' require 'arel/table' require 'arel/attributes' require 'arel/compatibility/wheres' require 'arel/visitors' require 'arel/tree_manager' require 'arel/insert_manager' require 'arel/select_manager' require 'arel/update_manager' require 'arel/delete_manager' require 'arel/nodes' module Arel VERSION = '6.0.3' def self.sql raw_sql Arel::Nodes::SqlLiteral.new raw_sql end def self.star sql '*' end ## Convenience Alias Node = Arel::Nodes::Node end arel-6.0.3/README.markdown0000644000004100000410000001656112563210504015203 0ustar www-datawww-data# Arel [![Build Status](https://secure.travis-ci.org/rails/arel.svg?branch=master)](http://travis-ci.org/rails/arel) [![Dependency Status](https://gemnasium.com/rails/arel.svg)](https://gemnasium.com/rails/arel) * http://github.com/rails/arel ## DESCRIPTION Arel Really Exasperates Logicians Arel is a SQL AST manager for Ruby. It 1. Simplifies the generation of complex SQL queries 2. Adapts to various RDBMSes It is intended to be a framework framework; that is, you can build your own ORM with it, focusing on innovative object and collection modeling as opposed to database compatibility and query generation. ## Status For the moment, Arel uses Active Record's connection adapters to connect to the various engines, connection pooling, perform quoting, and do type conversion. ## A Gentle Introduction Generating a query with Arel is simple. For example, in order to produce ```sql SELECT * FROM users ``` you construct a table relation and convert it to sql: ```ruby users = Arel::Table.new(:users) query = users.project(Arel.sql('*')) query.to_sql ``` ### More Sophisticated Queries Here is a whirlwind tour through the most common SQL operators. These will probably cover 80% of all interaction with the database. First is the 'restriction' operator, `where`: ```ruby users.where(users[:name].eq('amy')) # => SELECT * FROM users WHERE users.name = 'amy' ``` What would, in SQL, be part of the `SELECT` clause is called in Arel a `projection`: ```ruby users.project(users[:id]) # => SELECT users.id FROM users ``` Comparison operators `=`, `!=`, `<`, `>`, `<=`, `>=`, `IN`: ```ruby users.where(users[:age].eq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" = 10 users.where(users[:age].not_eq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" != 10 users.where(users[:age].lt(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" < 10 users.where(users[:age].gt(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" > 10 users.where(users[:age].lteq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" <= 10 users.where(users[:age].gteq(10)).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" >= 10 users.where(users[:age].in([20, 16, 17])).project(Arel.sql('*')) # => SELECT * FROM "users" WHERE "users"."age" IN (20, 16, 17) ``` Joins resemble SQL strongly: ```ruby users.join(photos).on(users[:id].eq(photos[:user_id])) # => SELECT * FROM users INNER JOIN photos ON users.id = photos.user_id ``` Left Joins ```ruby users.join(photos, Arel::Nodes::OuterJoin).on(users[:id].eq(photos[:user_id])) # => SELECT FROM users LEFT OUTER JOIN photos ON users.id = photos.user_id ``` What are called `LIMIT` and `OFFSET` in SQL are called `take` and `skip` in Arel: ```ruby users.take(5) # => SELECT * FROM users LIMIT 5 users.skip(4) # => SELECT * FROM users OFFSET 4 ``` `GROUP BY` is called `group`: ```ruby users.project(users[:name]).group(users[:name]) # => SELECT users.name FROM users GROUP BY users.name ``` The best property of arel is its "composability", or closure under all operations. For example, to restrict AND project, just "chain" the method invocations: ```ruby users \ .where(users[:name].eq('amy')) \ .project(users[:id]) \ # => SELECT users.id FROM users WHERE users.name = 'amy' ``` All operators are chainable in this way, and they are chainable any number of times, in any order. ```ruby users.where(users[:name].eq('bob')).where(users[:age].lt(25)) ``` The `OR` operator works like this: ```ruby users.where(users[:name].eq('bob').or(users[:age].lt(25))) ``` The `AND` operator behaves similarly. Aggregate functions `AVG`, `SUM`, `COUNT`, `MIN`, `MAX`, `HAVING`: ```ruby photos.group(photos[:user_id]).having(photos[:id].count.gt(5)) # => SELECT FROM photos GROUP BY photos.user_id HAVING COUNT(photos.id) > 5 users.project(users[:age].sum) # => SELECT SUM(users.age) FROM users users.project(users[:age].average) # => SELECT AVG(users.age) FROM users users.project(users[:age].maximum) # => SELECT MAX(users.age) FROM users users.project(users[:age].minimum) # => SELECT MIN(users.age) FROM users users.project(users[:age].count) # => SELECT COUNT(users.age) FROM users ``` Aliasing Aggregate Functions: ```ruby users.project(users[:age].average.as("mean_age")) # => SELECT AVG(users.age) AS mean_age FROM users ``` ### The Crazy Features The examples above are fairly simple and other libraries match or come close to matching the expressiveness of Arel (e.g., `Sequel` in Ruby). #### Inline math operations Suppose we have a table `products` with prices in different currencies. And we have a table `currency_rates`, of constantly changing currency rates. In Arel: ```ruby products = Arel::Table.new(:products) # Attributes: [:id, :name, :price, :currency_id] currency_rates = Arel::Table.new(:currency_rates) # Attributes: [:from_id, :to_id, :date, :rate] ``` Now, to order products by price in user preferred currency simply call: ```ruby products. join(:currency_rates).on(products[:currency_id].eq(currency_rates[:from_id])). where(currency_rates[:to_id].eq(user_preferred_currency), currency_rates[:date].eq(Date.today)). order(products[:price] * currency_rates[:rate]) ``` #### Complex Joins Where Arel really shines is in its ability to handle complex joins and aggregations. As a first example, let's consider an "adjacency list", a tree represented in a table. Suppose we have a table `comments`, representing a threaded discussion: ```ruby comments = Arel::Table.new(:comments) ``` And this table has the following attributes: ```ruby # [:id, :body, :parent_id] ``` The `parent_id` column is a foreign key from the `comments` table to itself. Joining a table to itself requires aliasing in SQL. This aliasing can be handled from Arel as below: ```ruby replies = comments.alias comments_with_replies = \ comments.join(replies).on(replies[:parent_id].eq(comments[:id])).where(comments[:id].eq(1)) # => SELECT * FROM comments INNER JOIN comments AS comments_2 WHERE comments_2.parent_id = comments.id AND comments.id = 1 ``` This will return the reply for the first comment. [Common Table Expressions(CTE)](https://en.wikipedia.org/wiki/Common_table_expressions#Common_table_expression) support via: Create a `CTE` ```ruby cte_table = Arel::Table.new(:cte_table) composed_cte = Arel::Nodes::As.new(cte_table, photos.where(photos[:created_at].gt(Date.current))) ``` Use the created `CTE`: ```ruby users. join(cte_table).on(users[:id].eq(cte_table[:user_id])). project(users[:id], cte_table[:click].sum). with(composed_cte) # => WITH cte_table AS (SELECT FROM photos WHERE photos.created_at > '2014-05-02') SELECT users.id, SUM(cte_table.click) FROM users INNER JOIN cte_table ON users.id = cte_table.user_id ``` When your query is too complex for `Arel`, you can use `Arel::SqlLiteral`: ```ruby photo_clicks = Arel::Nodes::SqlLiteral.new(<<-SQL CASE WHEN condition1 THEN calculation1 WHEN condition2 THEN calculation2 WHEN condition3 THEN calculation3 ELSE default_calculation END SQL ) photos.project(photo_clicks.as("photo_clicks")) # => SELECT CASE WHEN condition1 THEN calculation1 WHEN condition2 THEN calculation2 WHEN condition3 THEN calculation3 ELSE default_calculation END FROM "photos" ``` ### License Arel is released under the [MIT License](http://opensource.org/licenses/MIT). arel-6.0.3/MIT-LICENSE.txt0000644000004100000410000000212312563210504014741 0ustar www-datawww-dataCopyright (c) 2007-2010 Nick Kallen, Bryan Helmkamp, Emilio Tagua, Aaron Patterson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. arel-6.0.3/metadata.yml0000644000004100000410000001061112563210504014773 0ustar www-datawww-data--- !ruby/object:Gem::Specification name: arel version: !ruby/object:Gem::Version version: 6.0.3 platform: ruby authors: - Aaron Patterson - Bryan Helmkamp - Emilio Tagua - Nick Kallen autorequire: bindir: bin cert_chain: [] date: 2015-08-04 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: minitest requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '5.4' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '5.4' - !ruby/object:Gem::Dependency name: rdoc requirement: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '4.0' type: :development prerelease: false version_requirements: !ruby/object:Gem::Requirement requirements: - - "~>" - !ruby/object:Gem::Version version: '4.0' description: |- Arel Really Exasperates Logicians Arel is a SQL AST manager for Ruby. It 1. Simplifies the generation of complex SQL queries 2. Adapts to various RDBMSes It is intended to be a framework framework; that is, you can build your own ORM with it, focusing on innovative object and collection modeling as opposed to database compatibility and query generation. email: - aaron@tenderlovemaking.com - bryan@brynary.com - miloops@gmail.com executables: [] extensions: [] extra_rdoc_files: - History.txt - MIT-LICENSE.txt - README.markdown files: - History.txt - MIT-LICENSE.txt - README.markdown - lib/arel.rb - lib/arel/alias_predication.rb - lib/arel/attributes.rb - lib/arel/attributes/attribute.rb - lib/arel/collectors/bind.rb - lib/arel/collectors/plain_string.rb - lib/arel/collectors/sql_string.rb - lib/arel/compatibility/wheres.rb - lib/arel/crud.rb - lib/arel/delete_manager.rb - lib/arel/expressions.rb - lib/arel/factory_methods.rb - lib/arel/insert_manager.rb - lib/arel/math.rb - lib/arel/nodes.rb - lib/arel/nodes/and.rb - lib/arel/nodes/ascending.rb - lib/arel/nodes/binary.rb - lib/arel/nodes/bind_param.rb - lib/arel/nodes/count.rb - lib/arel/nodes/delete_statement.rb - lib/arel/nodes/descending.rb - lib/arel/nodes/equality.rb - lib/arel/nodes/extract.rb - lib/arel/nodes/false.rb - lib/arel/nodes/full_outer_join.rb - lib/arel/nodes/function.rb - lib/arel/nodes/grouping.rb - lib/arel/nodes/in.rb - lib/arel/nodes/infix_operation.rb - lib/arel/nodes/inner_join.rb - lib/arel/nodes/insert_statement.rb - lib/arel/nodes/join_source.rb - lib/arel/nodes/matches.rb - lib/arel/nodes/named_function.rb - lib/arel/nodes/node.rb - lib/arel/nodes/outer_join.rb - lib/arel/nodes/over.rb - lib/arel/nodes/right_outer_join.rb - lib/arel/nodes/select_core.rb - lib/arel/nodes/select_statement.rb - lib/arel/nodes/sql_literal.rb - lib/arel/nodes/string_join.rb - lib/arel/nodes/table_alias.rb - lib/arel/nodes/terminal.rb - lib/arel/nodes/true.rb - lib/arel/nodes/unary.rb - lib/arel/nodes/unqualified_column.rb - lib/arel/nodes/update_statement.rb - lib/arel/nodes/values.rb - lib/arel/nodes/window.rb - lib/arel/nodes/with.rb - lib/arel/order_predications.rb - lib/arel/predications.rb - lib/arel/select_manager.rb - lib/arel/table.rb - lib/arel/tree_manager.rb - lib/arel/update_manager.rb - lib/arel/visitors.rb - lib/arel/visitors/bind_substitute.rb - lib/arel/visitors/bind_visitor.rb - lib/arel/visitors/depth_first.rb - lib/arel/visitors/dot.rb - lib/arel/visitors/ibm_db.rb - lib/arel/visitors/informix.rb - lib/arel/visitors/mssql.rb - lib/arel/visitors/mysql.rb - lib/arel/visitors/oracle.rb - lib/arel/visitors/postgresql.rb - lib/arel/visitors/reduce.rb - lib/arel/visitors/sqlite.rb - lib/arel/visitors/to_sql.rb - lib/arel/visitors/visitor.rb - lib/arel/visitors/where_sql.rb - lib/arel/window_predications.rb homepage: https://github.com/rails/arel licenses: - MIT metadata: {} post_install_message: rdoc_options: - "--main" - README.markdown require_paths: - lib required_ruby_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' required_rubygems_version: !ruby/object:Gem::Requirement requirements: - - ">=" - !ruby/object:Gem::Version version: '0' requirements: [] rubyforge_project: rubygems_version: 2.4.7 signing_key: specification_version: 4 summary: Arel Really Exasperates Logicians Arel is a SQL AST manager for Ruby test_files: [] has_rdoc: