arel 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/arel.rb +4 -3
- data/lib/arel/algebra.rb +1 -1
- data/lib/arel/algebra/attributes.rb +7 -0
- data/lib/arel/algebra/{attribute.rb → attributes/attribute.rb} +32 -0
- data/lib/arel/algebra/attributes/boolean.rb +21 -0
- data/lib/arel/algebra/attributes/decimal.rb +9 -0
- data/lib/arel/algebra/attributes/float.rb +9 -0
- data/lib/arel/algebra/attributes/integer.rb +10 -0
- data/lib/arel/algebra/attributes/string.rb +10 -0
- data/lib/arel/algebra/attributes/time.rb +6 -0
- data/lib/arel/algebra/predicates.rb +1 -0
- data/lib/arel/algebra/relations/operations/join.rb +4 -2
- data/lib/arel/algebra/relations/operations/order.rb +2 -1
- data/lib/arel/algebra/relations/operations/skip.rb +2 -1
- data/lib/arel/algebra/relations/operations/take.rb +2 -1
- data/lib/arel/algebra/relations/operations/where.rb +7 -6
- data/lib/arel/algebra/relations/relation.rb +2 -1
- data/lib/arel/algebra/relations/utilities/compound.rb +22 -2
- data/lib/arel/algebra/relations/utilities/externalization.rb +1 -1
- data/lib/arel/algebra/relations/utilities/nil.rb +2 -2
- data/lib/arel/engines/memory/predicates.rb +6 -0
- data/lib/arel/engines/memory/relations/array.rb +11 -4
- data/lib/arel/engines/memory/relations/compound.rb +1 -1
- data/lib/arel/engines/memory/relations/operations.rb +2 -2
- data/lib/arel/engines/sql.rb +1 -0
- data/lib/arel/engines/sql/attributes.rb +40 -0
- data/lib/arel/engines/sql/compilers/ibm_db_compiler.rb +0 -14
- data/lib/arel/engines/sql/predicates.rb +4 -0
- data/lib/arel/engines/sql/primitives.rb +0 -4
- data/lib/arel/engines/sql/relations/compiler.rb +5 -5
- data/lib/arel/engines/sql/relations/operations/join.rb +1 -1
- data/lib/arel/engines/sql/relations/relation.rb +1 -1
- data/lib/arel/engines/sql/relations/table.rb +6 -7
- data/lib/arel/engines/sql/relations/utilities/compound.rb +1 -1
- data/lib/arel/engines/sql/relations/utilities/nil.rb +1 -1
- data/lib/arel/session.rb +2 -2
- data/lib/arel/version.rb +3 -0
- data/spec/{arel/algebra → algebra}/unit/predicates/binary_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/predicates/equality_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/predicates/in_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/primitives/attribute_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/primitives/expression_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/primitives/value_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/alias_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/delete_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/group_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/insert_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/join_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/order_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/project_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/relation_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/skip_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/table_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/take_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/update_spec.rb +0 -0
- data/spec/{arel/algebra → algebra}/unit/relations/where_spec.rb +1 -0
- data/spec/{arel/algebra → algebra}/unit/session/session_spec.rb +0 -0
- data/spec/attributes/boolean_spec.rb +57 -0
- data/spec/attributes/float_spec.rb +119 -0
- data/spec/attributes/integer_spec.rb +119 -0
- data/spec/attributes/string_spec.rb +43 -0
- data/spec/attributes/time_spec.rb +22 -0
- data/spec/{arel/engines → engines}/memory/integration/joins/cross_engine_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/array_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/insert_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/join_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/order_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/project_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/skip_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/take_spec.rb +1 -1
- data/spec/{arel/engines → engines}/memory/unit/relations/where_spec.rb +1 -1
- data/spec/{arel/engines → engines}/sql/integration/joins/with_adjacency_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/integration/joins/with_aggregations_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/integration/joins/with_compounds_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/engine_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/predicates/binary_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/predicates/equality_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/predicates/in_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/predicates/predicates_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/primitives/attribute_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/primitives/expression_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/primitives/literal_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/primitives/value_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/alias_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/delete_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/from_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/group_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/having_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/insert_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/join_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/lock_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/order_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/project_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/skip_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/table_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/take_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/update_spec.rb +0 -0
- data/spec/{arel/engines → engines}/sql/unit/relations/where_spec.rb +0 -0
- data/spec/relations/join_spec.rb +40 -0
- data/spec/relations/relation_spec.rb +31 -0
- data/spec/shared/relation_spec.rb +142 -0
- data/spec/spec_helper.rb +17 -45
- data/spec/support/check.rb +6 -0
- data/spec/{connections → support/connections}/mysql_connection.rb +2 -4
- data/spec/{connections → support/connections}/oracle_connection.rb +3 -5
- data/spec/{connections → support/connections}/postgresql_connection.rb +2 -4
- data/spec/{connections → support/connections}/sqlite3_connection.rb +2 -4
- data/spec/support/guards.rb +28 -0
- data/spec/support/matchers.rb +4 -0
- data/spec/{matchers → support/matchers}/be_like.rb +1 -1
- data/spec/{matchers → support/matchers}/disambiguate_attributes.rb +1 -1
- data/spec/{matchers → support/matchers}/hash_the_same_as.rb +1 -1
- data/spec/support/matchers/have_rows.rb +18 -0
- data/spec/support/model.rb +58 -0
- data/spec/{schemas → support/schemas}/mysql_schema.rb +0 -0
- data/spec/{schemas → support/schemas}/oracle_schema.rb +0 -0
- data/spec/{schemas → support/schemas}/postgresql_schema.rb +0 -0
- data/spec/{schemas → support/schemas}/sqlite3_schema.rb +0 -0
- metadata +107 -163
- data/.gitignore +0 -6
- data/.gitmodules +0 -3
- data/Rakefile +0 -48
- data/Thorfile +0 -124
- data/arel.gemspec +0 -258
- data/doc/CONVENTIONS +0 -17
- data/doc/TODO +0 -118
- data/spec/doubles/hash.rb +0 -27
- data/spec/spec.opts +0 -3
data/lib/arel.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
require 'active_support/inflector'
|
2
|
-
require 'active_support/core_ext/module/delegation'
|
3
2
|
require 'active_support/core_ext/class/attribute_accessors'
|
3
|
+
require 'active_support/core_ext/module/delegation'
|
4
|
+
require 'active_support/core_ext/object/blank'
|
4
5
|
|
5
6
|
module Arel
|
6
7
|
require 'arel/algebra'
|
7
8
|
require 'arel/engines'
|
8
|
-
|
9
|
+
require 'arel/version'
|
9
10
|
|
10
|
-
|
11
|
+
autoload :Session, 'arel/session'
|
11
12
|
end
|
data/lib/arel/algebra.rb
CHANGED
@@ -0,0 +1,7 @@
|
|
1
|
+
require "arel/algebra/attributes/attribute"
|
2
|
+
require "arel/algebra/attributes/boolean"
|
3
|
+
require "arel/algebra/attributes/decimal"
|
4
|
+
require "arel/algebra/attributes/float"
|
5
|
+
require "arel/algebra/attributes/integer"
|
6
|
+
require "arel/algebra/attributes/string"
|
7
|
+
require "arel/algebra/attributes/time"
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
3
|
module Arel
|
4
|
+
class TypecastError < StandardError ; end
|
4
5
|
class Attribute
|
5
6
|
attributes :relation, :name, :alias, :ancestor
|
6
7
|
deriving :==
|
@@ -85,6 +86,10 @@ module Arel
|
|
85
86
|
Predicates::Equality.new(self, other)
|
86
87
|
end
|
87
88
|
|
89
|
+
def not(other)
|
90
|
+
Predicates::Not.new(self, other)
|
91
|
+
end
|
92
|
+
|
88
93
|
def lt(other)
|
89
94
|
Predicates::LessThan.new(self, other)
|
90
95
|
end
|
@@ -146,5 +151,32 @@ module Arel
|
|
146
151
|
alias_method :to_ordering, :asc
|
147
152
|
end
|
148
153
|
include Orderings
|
154
|
+
|
155
|
+
module Types
|
156
|
+
def type_cast(value)
|
157
|
+
if root == self
|
158
|
+
raise NotImplementedError, "#type_cast should be implemented in a subclass."
|
159
|
+
else
|
160
|
+
root.type_cast(value)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def type_cast_to_numeric(value, method)
|
165
|
+
return unless value
|
166
|
+
if value.respond_to?(:to_str)
|
167
|
+
str = value.to_str.strip
|
168
|
+
return if str.empty?
|
169
|
+
return $1.send(method) if str =~ /\A(-?(?:0|[1-9]\d*)(?:\.\d+)?|(?:\.\d+))\z/
|
170
|
+
elsif value.respond_to?(method)
|
171
|
+
return value.send(method)
|
172
|
+
end
|
173
|
+
raise typecast_error(value)
|
174
|
+
end
|
175
|
+
|
176
|
+
def typecast_error(value)
|
177
|
+
raise TypecastError, "could not typecast #{value.inspect} to #{self.class.name.split('::').last}"
|
178
|
+
end
|
179
|
+
end
|
180
|
+
include Types
|
149
181
|
end
|
150
182
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Arel
|
2
|
+
module Attributes
|
3
|
+
class Boolean < Attribute
|
4
|
+
def type_cast(value)
|
5
|
+
case value
|
6
|
+
when true, false then value
|
7
|
+
# when nil then options[:allow_nil] ? nil : false
|
8
|
+
when nil then false
|
9
|
+
when 1 then true
|
10
|
+
when 0 then false
|
11
|
+
else
|
12
|
+
case value.to_s.downcase.strip
|
13
|
+
when 'true' then true
|
14
|
+
when 'false' then false
|
15
|
+
else raise typecast_error(value)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Arel
|
2
|
-
class Join
|
2
|
+
class Join
|
3
|
+
include Relation
|
4
|
+
|
3
5
|
attributes :relation1, :relation2, :predicates
|
4
6
|
deriving :==
|
5
7
|
delegate :name, :to => :relation1
|
@@ -60,7 +62,7 @@ module Arel
|
|
60
62
|
end
|
61
63
|
end
|
62
64
|
|
63
|
-
|
65
|
+
module Relation
|
64
66
|
def join?
|
65
67
|
false
|
66
68
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
module Arel
|
2
2
|
class Where < Compound
|
3
|
-
attributes :relation, :
|
4
|
-
deriving
|
3
|
+
attributes :relation, :predicates
|
4
|
+
deriving :==
|
5
|
+
requires :restricting
|
5
6
|
|
6
7
|
def initialize(relation, *predicates, &block)
|
7
|
-
|
8
|
-
@
|
9
|
-
@
|
8
|
+
predicates = [yield(relation)] + predicates if block_given?
|
9
|
+
@predicates = predicates.map { |p| p.bind(relation) }
|
10
|
+
@relation = relation
|
10
11
|
end
|
11
12
|
|
12
13
|
def wheres
|
13
|
-
@wheres ||=
|
14
|
+
@wheres ||= relation.wheres + predicates
|
14
15
|
end
|
15
16
|
end
|
16
17
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Arel
|
2
|
-
|
2
|
+
module Relation
|
3
3
|
attr_reader :count
|
4
4
|
|
5
5
|
def session
|
@@ -128,6 +128,7 @@ module Arel
|
|
128
128
|
|
129
129
|
module DefaultOperations
|
130
130
|
def attributes; [] end
|
131
|
+
def projections; [] end
|
131
132
|
def wheres; [] end
|
132
133
|
def orders; [] end
|
133
134
|
def inserts; [] end
|
@@ -1,11 +1,19 @@
|
|
1
1
|
module Arel
|
2
|
-
class Compound
|
2
|
+
class Compound
|
3
|
+
include Relation
|
4
|
+
|
3
5
|
attr_reader :relation
|
4
6
|
delegate :joins, :join?, :inserts, :taken, :skipped, :name, :externalizable?,
|
5
7
|
:column_for, :engine, :sources, :locked, :table_alias,
|
6
8
|
:to => :relation
|
7
9
|
|
8
|
-
|
10
|
+
def self.requires(feature = nil)
|
11
|
+
@requires ||= nil
|
12
|
+
@requires = feature if feature
|
13
|
+
@requires
|
14
|
+
end
|
15
|
+
|
16
|
+
[:attributes, :wheres, :groupings, :orders, :havings, :projections].each do |operation_name|
|
9
17
|
class_eval <<-OPERATION, __FILE__, __LINE__
|
10
18
|
def #{operation_name}
|
11
19
|
@#{operation_name} ||= relation.#{operation_name}.collect { |o| o.bind(self) }
|
@@ -21,6 +29,18 @@ module Arel
|
|
21
29
|
self == other
|
22
30
|
end
|
23
31
|
|
32
|
+
def engine
|
33
|
+
requires = self.class.requires
|
34
|
+
engine = relation.engine
|
35
|
+
|
36
|
+
# Temporary check of whether or not the engine supports where.
|
37
|
+
if requires && engine.respond_to?(:supports) && !engine.supports(requires)
|
38
|
+
Memory::Engine.new
|
39
|
+
else
|
40
|
+
engine
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
24
44
|
private
|
25
45
|
|
26
46
|
def arguments_from_block(relation, &block)
|
@@ -1,16 +1,23 @@
|
|
1
1
|
module Arel
|
2
|
-
class Array
|
3
|
-
|
2
|
+
class Array
|
3
|
+
include Relation
|
4
|
+
|
5
|
+
attributes :array, :attribute_names_and_types
|
4
6
|
include Recursion::BaseCase
|
5
7
|
deriving :==, :initialize
|
6
8
|
|
9
|
+
def initialize(array, attribute_names_and_types)
|
10
|
+
@array, @attribute_names_and_types = array, attribute_names_and_types
|
11
|
+
end
|
12
|
+
|
7
13
|
def engine
|
8
14
|
@engine ||= Memory::Engine.new
|
9
15
|
end
|
10
16
|
|
11
17
|
def attributes
|
12
|
-
@attributes ||= @
|
13
|
-
|
18
|
+
@attributes ||= @attribute_names_and_types.collect do |attribute, type|
|
19
|
+
attribute = type.new(self, attribute) if Symbol === attribute
|
20
|
+
attribute
|
14
21
|
end
|
15
22
|
end
|
16
23
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Arel
|
2
2
|
class Where < Compound
|
3
3
|
def eval
|
4
|
-
unoperated_rows.select { |row|
|
4
|
+
unoperated_rows.select { |row| predicates.all? { |p| p.eval(row) } }
|
5
5
|
end
|
6
6
|
end
|
7
7
|
|
@@ -50,7 +50,7 @@ module Arel
|
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
53
|
-
class Join
|
53
|
+
class Join
|
54
54
|
def eval
|
55
55
|
result = []
|
56
56
|
relation1.call.each do |row1|
|
data/lib/arel/engines/sql.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module Arel
|
2
|
+
module Sql
|
3
|
+
module Attributes
|
4
|
+
def self.for(column)
|
5
|
+
case column.type
|
6
|
+
when :string then String
|
7
|
+
when :text then String
|
8
|
+
when :integer then Integer
|
9
|
+
when :float then Float
|
10
|
+
when :decimal then Decimal
|
11
|
+
when :date then Time
|
12
|
+
when :datetime then Time
|
13
|
+
when :timestamp then Time
|
14
|
+
when :time then Time
|
15
|
+
when :binary then String
|
16
|
+
when :boolean then Boolean
|
17
|
+
else
|
18
|
+
raise NotImplementedError, "Column type `#{column.type}` is not currently handled"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(column, *args)
|
23
|
+
@column = column
|
24
|
+
super(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def type_cast(value)
|
28
|
+
@column.type_cast(value)
|
29
|
+
end
|
30
|
+
|
31
|
+
%w(Boolean Decimal Float Integer String Time).each do |klass|
|
32
|
+
class_eval <<-R
|
33
|
+
class #{klass} < Arel::Attributes::#{klass}
|
34
|
+
include Attributes
|
35
|
+
end
|
36
|
+
R
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -31,20 +31,6 @@ module Arel
|
|
31
31
|
module SqlCompiler
|
32
32
|
class IBM_DBCompiler < GenericCompiler
|
33
33
|
|
34
|
-
def select_sql
|
35
|
-
query = build_query \
|
36
|
-
"SELECT #{select_clauses.join(', ')}",
|
37
|
-
"FROM #{from_clauses}",
|
38
|
-
(joins(self) unless joins(self).blank? ),
|
39
|
-
("WHERE #{where_clauses.join(" AND ")}" unless wheres.blank? ),
|
40
|
-
("GROUP BY #{group_clauses.join(', ')}" unless groupings.blank? ),
|
41
|
-
("HAVING #{having_clauses.join(', ')}" unless havings.blank? ),
|
42
|
-
("ORDER BY #{order_clauses.join(', ')}" unless orders.blank? )
|
43
|
-
engine.add_limit_offset!(query,{:limit=>taken,:offset=>skipped}) unless taken.blank?
|
44
|
-
query << "#{locked}" unless locked.blank?
|
45
|
-
query
|
46
|
-
end
|
47
|
-
|
48
34
|
def limited_update_conditions(conditions, taken)
|
49
35
|
quoted_primary_key = engine.quote_table_name(primary_key)
|
50
36
|
update_conditions = "WHERE #{quoted_primary_key} IN (SELECT #{quoted_primary_key} FROM #{engine.connection.quote_table_name table.name} #{conditions} " #Note: - ')' not added, limit segment is to be appended
|