arel 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +6 -0
- data/README.markdown +184 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/arel.gemspec +233 -0
- data/doc/CONVENTIONS +17 -0
- data/doc/TODO +118 -0
- data/lib/arel.rb +10 -0
- data/lib/arel/algebra.rb +4 -0
- data/lib/arel/algebra/extensions.rb +4 -0
- data/lib/arel/algebra/extensions/class.rb +32 -0
- data/lib/arel/algebra/extensions/hash.rb +11 -0
- data/lib/arel/algebra/extensions/object.rb +17 -0
- data/lib/arel/algebra/extensions/symbol.rb +9 -0
- data/lib/arel/algebra/predicates.rb +41 -0
- data/lib/arel/algebra/primitives.rb +5 -0
- data/lib/arel/algebra/primitives/attribute.rb +150 -0
- data/lib/arel/algebra/primitives/expression.rb +43 -0
- data/lib/arel/algebra/primitives/ordering.rb +23 -0
- data/lib/arel/algebra/primitives/value.rb +14 -0
- data/lib/arel/algebra/relations.rb +14 -0
- data/lib/arel/algebra/relations/operations/alias.rb +7 -0
- data/lib/arel/algebra/relations/operations/group.rb +12 -0
- data/lib/arel/algebra/relations/operations/join.rb +64 -0
- data/lib/arel/algebra/relations/operations/order.rb +18 -0
- data/lib/arel/algebra/relations/operations/project.rb +20 -0
- data/lib/arel/algebra/relations/operations/skip.rb +6 -0
- data/lib/arel/algebra/relations/operations/take.rb +10 -0
- data/lib/arel/algebra/relations/operations/where.rb +16 -0
- data/lib/arel/algebra/relations/relation.rb +136 -0
- data/lib/arel/algebra/relations/row.rb +26 -0
- data/lib/arel/algebra/relations/utilities/compound.rb +30 -0
- data/lib/arel/algebra/relations/utilities/externalization.rb +24 -0
- data/lib/arel/algebra/relations/utilities/nil.rb +7 -0
- data/lib/arel/algebra/relations/writes.rb +36 -0
- data/lib/arel/engines.rb +2 -0
- data/lib/arel/engines/memory.rb +4 -0
- data/lib/arel/engines/memory/engine.rb +16 -0
- data/lib/arel/engines/memory/predicates.rb +35 -0
- data/lib/arel/engines/memory/primitives.rb +27 -0
- data/lib/arel/engines/memory/relations.rb +5 -0
- data/lib/arel/engines/memory/relations/array.rb +25 -0
- data/lib/arel/engines/memory/relations/compound.rb +9 -0
- data/lib/arel/engines/memory/relations/operations.rb +61 -0
- data/lib/arel/engines/memory/relations/writes.rb +7 -0
- data/lib/arel/engines/sql.rb +7 -0
- data/lib/arel/engines/sql/christener.rb +13 -0
- data/lib/arel/engines/sql/engine.rb +37 -0
- data/lib/arel/engines/sql/extensions.rb +4 -0
- data/lib/arel/engines/sql/extensions/array.rb +16 -0
- data/lib/arel/engines/sql/extensions/nil_class.rb +11 -0
- data/lib/arel/engines/sql/extensions/object.rb +15 -0
- data/lib/arel/engines/sql/extensions/range.rb +15 -0
- data/lib/arel/engines/sql/formatters.rb +113 -0
- data/lib/arel/engines/sql/predicates.rb +51 -0
- data/lib/arel/engines/sql/primitives.rb +85 -0
- data/lib/arel/engines/sql/relations.rb +9 -0
- data/lib/arel/engines/sql/relations/operations/alias.rb +5 -0
- data/lib/arel/engines/sql/relations/operations/join.rb +33 -0
- data/lib/arel/engines/sql/relations/relation.rb +50 -0
- data/lib/arel/engines/sql/relations/table.rb +52 -0
- data/lib/arel/engines/sql/relations/utilities/compound.rb +10 -0
- data/lib/arel/engines/sql/relations/utilities/externalization.rb +14 -0
- data/lib/arel/engines/sql/relations/utilities/nil.rb +6 -0
- data/lib/arel/engines/sql/relations/utilities/recursion.rb +13 -0
- data/lib/arel/engines/sql/relations/writes.rb +39 -0
- data/lib/arel/session.rb +48 -0
- data/spec/arel/algebra/unit/predicates/binary_spec.rb +33 -0
- data/spec/arel/algebra/unit/predicates/equality_spec.rb +27 -0
- data/spec/arel/algebra/unit/predicates/in_spec.rb +10 -0
- data/spec/arel/algebra/unit/primitives/attribute_spec.rb +183 -0
- data/spec/arel/algebra/unit/primitives/expression_spec.rb +45 -0
- data/spec/arel/algebra/unit/primitives/value_spec.rb +15 -0
- data/spec/arel/algebra/unit/relations/alias_spec.rb +16 -0
- data/spec/arel/algebra/unit/relations/delete_spec.rb +9 -0
- data/spec/arel/algebra/unit/relations/group_spec.rb +10 -0
- data/spec/arel/algebra/unit/relations/insert_spec.rb +9 -0
- data/spec/arel/algebra/unit/relations/join_spec.rb +26 -0
- data/spec/arel/algebra/unit/relations/order_spec.rb +21 -0
- data/spec/arel/algebra/unit/relations/project_spec.rb +34 -0
- data/spec/arel/algebra/unit/relations/relation_spec.rb +188 -0
- data/spec/arel/algebra/unit/relations/skip_spec.rb +10 -0
- data/spec/arel/algebra/unit/relations/table_spec.rb +39 -0
- data/spec/arel/algebra/unit/relations/take_spec.rb +10 -0
- data/spec/arel/algebra/unit/relations/update_spec.rb +9 -0
- data/spec/arel/algebra/unit/relations/where_spec.rb +18 -0
- data/spec/arel/algebra/unit/session/session_spec.rb +84 -0
- data/spec/arel/engines/memory/integration/joins/cross_engine_spec.rb +48 -0
- data/spec/arel/engines/memory/unit/relations/array_spec.rb +32 -0
- data/spec/arel/engines/memory/unit/relations/insert_spec.rb +28 -0
- data/spec/arel/engines/memory/unit/relations/join_spec.rb +31 -0
- data/spec/arel/engines/memory/unit/relations/order_spec.rb +27 -0
- data/spec/arel/engines/memory/unit/relations/project_spec.rb +27 -0
- data/spec/arel/engines/memory/unit/relations/skip_spec.rb +26 -0
- data/spec/arel/engines/memory/unit/relations/take_spec.rb +26 -0
- data/spec/arel/engines/memory/unit/relations/where_spec.rb +39 -0
- data/spec/arel/engines/sql/integration/joins/with_adjacency_spec.rb +209 -0
- data/spec/arel/engines/sql/integration/joins/with_aggregations_spec.rb +167 -0
- data/spec/arel/engines/sql/integration/joins/with_compounds_spec.rb +107 -0
- data/spec/arel/engines/sql/unit/engine_spec.rb +45 -0
- data/spec/arel/engines/sql/unit/predicates/binary_spec.rb +117 -0
- data/spec/arel/engines/sql/unit/predicates/equality_spec.rb +46 -0
- data/spec/arel/engines/sql/unit/predicates/in_spec.rb +86 -0
- data/spec/arel/engines/sql/unit/predicates/predicates_spec.rb +65 -0
- data/spec/arel/engines/sql/unit/primitives/attribute_spec.rb +32 -0
- data/spec/arel/engines/sql/unit/primitives/expression_spec.rb +24 -0
- data/spec/arel/engines/sql/unit/primitives/literal_spec.rb +23 -0
- data/spec/arel/engines/sql/unit/primitives/value_spec.rb +29 -0
- data/spec/arel/engines/sql/unit/relations/alias_spec.rb +43 -0
- data/spec/arel/engines/sql/unit/relations/delete_spec.rb +63 -0
- data/spec/arel/engines/sql/unit/relations/group_spec.rb +56 -0
- data/spec/arel/engines/sql/unit/relations/insert_spec.rb +107 -0
- data/spec/arel/engines/sql/unit/relations/join_spec.rb +57 -0
- data/spec/arel/engines/sql/unit/relations/order_spec.rb +113 -0
- data/spec/arel/engines/sql/unit/relations/project_spec.rb +110 -0
- data/spec/arel/engines/sql/unit/relations/skip_spec.rb +32 -0
- data/spec/arel/engines/sql/unit/relations/table_spec.rb +69 -0
- data/spec/arel/engines/sql/unit/relations/take_spec.rb +32 -0
- data/spec/arel/engines/sql/unit/relations/update_spec.rb +151 -0
- data/spec/arel/engines/sql/unit/relations/where_spec.rb +56 -0
- data/spec/connections/mysql_connection.rb +16 -0
- data/spec/connections/postgresql_connection.rb +15 -0
- data/spec/connections/sqlite3_connection.rb +25 -0
- data/spec/doubles/hash.rb +23 -0
- data/spec/matchers/be_like.rb +24 -0
- data/spec/matchers/disambiguate_attributes.rb +28 -0
- data/spec/matchers/hash_the_same_as.rb +26 -0
- data/spec/schemas/mysql_schema.rb +18 -0
- data/spec/schemas/postgresql_schema.rb +18 -0
- data/spec/schemas/sqlite3_schema.rb +18 -0
- data/spec/spec_helper.rb +47 -0
- metadata +250 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
module Arel
|
2
|
+
class Binary < Predicate
|
3
|
+
def to_sql(formatter = nil)
|
4
|
+
"#{operand1.to_sql} #{predicate_sql} #{operand1.format(operand2)}"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
class CompoundPredicate < Binary
|
9
|
+
def to_sql(formatter = nil)
|
10
|
+
"(#{operand1.to_sql(formatter)} #{predicate_sql} #{operand2.to_sql(formatter)})"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class Or < CompoundPredicate
|
15
|
+
def predicate_sql; "OR" end
|
16
|
+
end
|
17
|
+
|
18
|
+
class And < CompoundPredicate
|
19
|
+
def predicate_sql; "AND" end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Equality < Binary
|
23
|
+
def predicate_sql
|
24
|
+
operand2.equality_predicate_sql
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class GreaterThanOrEqualTo < Binary
|
29
|
+
def predicate_sql; '>=' end
|
30
|
+
end
|
31
|
+
|
32
|
+
class GreaterThan < Binary
|
33
|
+
def predicate_sql; '>' end
|
34
|
+
end
|
35
|
+
|
36
|
+
class LessThanOrEqualTo < Binary
|
37
|
+
def predicate_sql; '<=' end
|
38
|
+
end
|
39
|
+
|
40
|
+
class LessThan < Binary
|
41
|
+
def predicate_sql; '<' end
|
42
|
+
end
|
43
|
+
|
44
|
+
class Match < Binary
|
45
|
+
def predicate_sql; 'LIKE' end
|
46
|
+
end
|
47
|
+
|
48
|
+
class In < Binary
|
49
|
+
def predicate_sql; operand2.inclusion_predicate_sql end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Arel
|
2
|
+
class SqlLiteral < String
|
3
|
+
def relation
|
4
|
+
nil
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_sql(formatter = nil)
|
8
|
+
self
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Attribute
|
13
|
+
def column
|
14
|
+
original_relation.column_for(self)
|
15
|
+
end
|
16
|
+
|
17
|
+
def type_cast(value)
|
18
|
+
root.relation.format(self, value)
|
19
|
+
end
|
20
|
+
|
21
|
+
def format(object)
|
22
|
+
object.to_sql(Sql::Attribute.new(self))
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_sql(formatter = Sql::WhereCondition.new(relation))
|
26
|
+
formatter.attribute self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Value
|
31
|
+
delegate :inclusion_predicate_sql, :equality_predicate_sql, :to => :value
|
32
|
+
|
33
|
+
def to_sql(formatter = Sql::WhereCondition.new(relation))
|
34
|
+
formatter.value value
|
35
|
+
end
|
36
|
+
|
37
|
+
def format(object)
|
38
|
+
object.to_sql(Sql::Value.new(relation))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class Ordering
|
43
|
+
def to_sql(formatter = Sql::OrderClause.new(relation))
|
44
|
+
formatter.ordering self
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Ascending < Ordering
|
49
|
+
def direction_sql; 'ASC' end
|
50
|
+
end
|
51
|
+
|
52
|
+
class Descending < Ordering
|
53
|
+
def direction_sql; 'DESC' end
|
54
|
+
end
|
55
|
+
|
56
|
+
class Expression < Attribute
|
57
|
+
def to_sql(formatter = Sql::SelectClause.new(relation))
|
58
|
+
formatter.expression self
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Count < Expression
|
63
|
+
def function_sql; 'COUNT' end
|
64
|
+
end
|
65
|
+
|
66
|
+
class Distinct < Expression
|
67
|
+
def function_sql; 'DISTINCT' end
|
68
|
+
end
|
69
|
+
|
70
|
+
class Sum < Expression
|
71
|
+
def function_sql; 'SUM' end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Maximum < Expression
|
75
|
+
def function_sql; 'MAX' end
|
76
|
+
end
|
77
|
+
|
78
|
+
class Minimum < Expression
|
79
|
+
def function_sql; 'MIN' end
|
80
|
+
end
|
81
|
+
|
82
|
+
class Average < Expression
|
83
|
+
def function_sql; 'AVG' end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'arel/engines/sql/relations/utilities/compound'
|
2
|
+
require 'arel/engines/sql/relations/utilities/recursion'
|
3
|
+
require 'arel/engines/sql/relations/utilities/externalization'
|
4
|
+
require 'arel/engines/sql/relations/utilities/nil'
|
5
|
+
require 'arel/engines/sql/relations/relation'
|
6
|
+
require 'arel/engines/sql/relations/table'
|
7
|
+
require 'arel/engines/sql/relations/operations/join'
|
8
|
+
require 'arel/engines/sql/relations/operations/alias'
|
9
|
+
require 'arel/engines/sql/relations/writes'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Arel
|
2
|
+
class Join < Relation
|
3
|
+
def table_sql(formatter = Sql::TableReference.new(self))
|
4
|
+
relation1.externalize.table_sql(formatter)
|
5
|
+
end
|
6
|
+
|
7
|
+
def joins(environment, formatter = Sql::TableReference.new(environment))
|
8
|
+
@joins ||= begin
|
9
|
+
this_join = [
|
10
|
+
join_sql,
|
11
|
+
relation2.externalize.table_sql(formatter),
|
12
|
+
("ON" unless predicates.blank?),
|
13
|
+
(ons + relation2.externalize.wheres).collect { |p| p.bind(environment).to_sql(Sql::WhereClause.new(environment)) }.join(' AND ')
|
14
|
+
].compact.join(" ")
|
15
|
+
[relation1.joins(environment), this_join, relation2.joins(environment)].compact.join(" ")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class InnerJoin < Join
|
21
|
+
def join_sql; "INNER JOIN" end
|
22
|
+
end
|
23
|
+
|
24
|
+
class OuterJoin < Join
|
25
|
+
def join_sql; "LEFT OUTER JOIN" end
|
26
|
+
end
|
27
|
+
|
28
|
+
class StringJoin < Join
|
29
|
+
def joins(_, __ = nil)
|
30
|
+
relation2
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Arel
|
2
|
+
class Relation
|
3
|
+
def to_sql(formatter = Sql::SelectStatement.new(self))
|
4
|
+
formatter.select select_sql, self
|
5
|
+
end
|
6
|
+
|
7
|
+
def select_sql
|
8
|
+
build_query \
|
9
|
+
"SELECT #{select_clauses.join(', ')}",
|
10
|
+
"FROM #{table_sql(Sql::TableReference.new(self))}",
|
11
|
+
(joins(self) unless joins(self).blank? ),
|
12
|
+
("WHERE #{where_clauses.join("\n\tAND ")}" unless wheres.blank? ),
|
13
|
+
("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
|
14
|
+
("ORDER BY #{order_clauses.join(', ')}" unless orders.blank? ),
|
15
|
+
("LIMIT #{taken}" unless taken.blank? ),
|
16
|
+
("OFFSET #{skipped}" unless skipped.blank? )
|
17
|
+
end
|
18
|
+
|
19
|
+
def inclusion_predicate_sql
|
20
|
+
"IN"
|
21
|
+
end
|
22
|
+
|
23
|
+
def christener
|
24
|
+
@christener ||= Sql::Christener.new
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def build_query(*parts)
|
30
|
+
parts.compact.join("\n")
|
31
|
+
end
|
32
|
+
|
33
|
+
def select_clauses
|
34
|
+
attributes.collect { |a| a.to_sql(Sql::SelectClause.new(self)) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def where_clauses
|
38
|
+
wheres.collect { |w| w.to_sql(Sql::WhereClause.new(self)) }
|
39
|
+
end
|
40
|
+
|
41
|
+
def group_clauses
|
42
|
+
groupings.collect { |g| g.to_sql(Sql::GroupClause.new(self)) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def order_clauses
|
46
|
+
orders.collect { |o| o.to_sql(Sql::OrderClause.new(self)) }
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Arel
|
2
|
+
class Table < Relation
|
3
|
+
include Recursion::BaseCase
|
4
|
+
|
5
|
+
cattr_accessor :engine
|
6
|
+
attr_reader :name, :engine
|
7
|
+
|
8
|
+
def initialize(name, engine = Table.engine)
|
9
|
+
@name, @engine = name.to_s, engine
|
10
|
+
end
|
11
|
+
|
12
|
+
def attributes
|
13
|
+
@attributes ||= columns.collect do |column|
|
14
|
+
Attribute.new(self, column.name.to_sym)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def eql?(other)
|
19
|
+
self == other
|
20
|
+
end
|
21
|
+
|
22
|
+
def hash
|
23
|
+
@hash ||= :name.hash
|
24
|
+
end
|
25
|
+
|
26
|
+
def format(attribute, value)
|
27
|
+
attribute.column.type_cast(value)
|
28
|
+
end
|
29
|
+
|
30
|
+
def column_for(attribute)
|
31
|
+
has_attribute?(attribute) and columns.detect { |c| c.name == attribute.name.to_s }
|
32
|
+
end
|
33
|
+
|
34
|
+
def columns
|
35
|
+
@columns ||= engine.columns(name, "#{name} Columns")
|
36
|
+
end
|
37
|
+
|
38
|
+
def reset
|
39
|
+
@attributes = @columns = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
def ==(other)
|
43
|
+
Table === other and
|
44
|
+
name == other.name
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def Table(name, engine = Arel::Table.engine)
|
50
|
+
Arel::Table.new(name, engine)
|
51
|
+
end
|
52
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Arel
|
2
|
+
class Externalization < Compound
|
3
|
+
include Recursion::BaseCase
|
4
|
+
|
5
|
+
def table_sql(formatter = Sql::TableReference.new(relation))
|
6
|
+
formatter.select relation.select_sql, self
|
7
|
+
end
|
8
|
+
|
9
|
+
# REMOVEME
|
10
|
+
def name
|
11
|
+
relation.name + '_external'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Arel
|
2
|
+
class Deletion < Compound
|
3
|
+
def to_sql(formatter = nil)
|
4
|
+
build_query \
|
5
|
+
"DELETE",
|
6
|
+
"FROM #{table_sql}",
|
7
|
+
("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ),
|
8
|
+
("LIMIT #{taken}" unless taken.blank? )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Insert < Compound
|
13
|
+
def to_sql(formatter = nil)
|
14
|
+
build_query \
|
15
|
+
"INSERT",
|
16
|
+
"INTO #{table_sql}",
|
17
|
+
"(#{record.keys.collect { |key| engine.quote_column_name(key.name) }.join(', ')})",
|
18
|
+
"VALUES (#{record.collect { |key, value| key.format(value) }.join(', ')})"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class Update < Compound
|
23
|
+
def to_sql(formatter = nil)
|
24
|
+
build_query \
|
25
|
+
"UPDATE #{table_sql} SET",
|
26
|
+
assignment_sql,
|
27
|
+
("WHERE #{wheres.collect(&:to_sql).join('\n\tAND ')}" unless wheres.blank? ),
|
28
|
+
("LIMIT #{taken}" unless taken.blank? )
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def assignment_sql
|
34
|
+
assignments.collect do |attribute, value|
|
35
|
+
"#{engine.quote_column_name(attribute.name)} = #{attribute.format(value)}"
|
36
|
+
end.join(",\n")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/arel/session.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
module Arel
|
2
|
+
class Session
|
3
|
+
class << self
|
4
|
+
attr_accessor :instance
|
5
|
+
alias_method :manufacture, :new
|
6
|
+
|
7
|
+
def start
|
8
|
+
if @started
|
9
|
+
yield
|
10
|
+
else
|
11
|
+
begin
|
12
|
+
@started = true
|
13
|
+
@instance = manufacture
|
14
|
+
metaclass.send :alias_method, :new, :instance
|
15
|
+
yield
|
16
|
+
ensure
|
17
|
+
metaclass.send :alias_method, :new, :manufacture
|
18
|
+
@started = false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
module CRUD
|
25
|
+
def create(insert)
|
26
|
+
insert.call
|
27
|
+
insert
|
28
|
+
end
|
29
|
+
|
30
|
+
def read(select)
|
31
|
+
(@read ||= Hash.new do |hash, select|
|
32
|
+
hash[select] = select.call
|
33
|
+
end)[select]
|
34
|
+
end
|
35
|
+
|
36
|
+
def update(update)
|
37
|
+
update.call
|
38
|
+
update
|
39
|
+
end
|
40
|
+
|
41
|
+
def delete(delete)
|
42
|
+
delete.call
|
43
|
+
delete
|
44
|
+
end
|
45
|
+
end
|
46
|
+
include CRUD
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', '..', 'spec_helper')
|
2
|
+
|
3
|
+
module Arel
|
4
|
+
describe Binary do
|
5
|
+
before do
|
6
|
+
@relation = Table.new(:users)
|
7
|
+
@attribute1 = @relation[:id]
|
8
|
+
@attribute2 = @relation[:name]
|
9
|
+
class ConcreteBinary < Binary
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#bind' do
|
14
|
+
before do
|
15
|
+
@another_relation = @relation.alias
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'when both operands are attributes' do
|
19
|
+
it "manufactures an expression with the attributes bound to the relation" do
|
20
|
+
ConcreteBinary.new(@attribute1, @attribute2).bind(@another_relation). \
|
21
|
+
should == ConcreteBinary.new(@another_relation[@attribute1], @another_relation[@attribute2])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'when an operand is a value' do
|
26
|
+
it "manufactures an expression with unmodified values" do
|
27
|
+
ConcreteBinary.new(@attribute1, "asdf").bind(@another_relation). \
|
28
|
+
should == ConcreteBinary.new(@attribute1.find_correlate_in(@another_relation), "asdf".find_correlate_in(@another_relation))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|