diff options
author | Nick Kallen <nkallen@nick-kallens-computer-2.local> | 2008-01-07 18:37:20 -0800 |
---|---|---|
committer | Nick Kallen <nkallen@nick-kallens-computer-2.local> | 2008-01-07 18:37:20 -0800 |
commit | 311f5f8eb588d4cde051762ace87a61425300bec (patch) | |
tree | 5e087ddd6257ad793c225555a6e48ad17bbdde70 | |
parent | d43a4e9fc1316fc9eb8ff087c52c7ca7a475c041 (diff) | |
download | rails-311f5f8eb588d4cde051762ace87a61425300bec.tar.gz rails-311f5f8eb588d4cde051762ace87a61425300bec.tar.bz2 rails-311f5f8eb588d4cde051762ace87a61425300bec.zip |
minor
-rw-r--r-- | eager include.txt | 49 | ||||
-rw-r--r-- | lib/active_relation.rb | 56 | ||||
-rw-r--r-- | lib/active_relation/extensions/array.rb (renamed from lib/sql_algebra/extensions/array.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/extensions/base.rb (renamed from lib/sql_algebra/extensions/base.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/extensions/hash.rb (renamed from lib/sql_algebra/extensions/hash.rb) | 6 | ||||
-rw-r--r-- | lib/active_relation/extensions/object.rb (renamed from lib/sql_algebra/extensions/object.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/extensions/range.rb (renamed from lib/sql_algebra/extensions/range.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/binary_predicate.rb (renamed from lib/sql_algebra/predicates/binary_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/equality_predicate.rb (renamed from lib/sql_algebra/predicates/equality_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/greater_than_or_equal_to_predicate.rb (renamed from lib/sql_algebra/predicates/greater_than_or_equal_to_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/greater_than_predicate.rb (renamed from lib/sql_algebra/predicates/greater_than_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/less_than_or_equal_to_predicate.rb (renamed from lib/sql_algebra/predicates/less_than_or_equal_to_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/less_than_predicate.rb (renamed from lib/sql_algebra/predicates/less_than_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/match_predicate.rb (renamed from lib/sql_algebra/predicates/match_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/predicate.rb (renamed from lib/sql_algebra/predicates/predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/range_inclusion_predicate.rb (renamed from lib/sql_algebra/predicates/range_inclusion_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/predicates/relation_inclusion_predicate.rb (renamed from lib/sql_algebra/predicates/relation_inclusion_predicate.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/attribute.rb (renamed from lib/sql_algebra/relations/attribute.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/compound_relation.rb | 3 | ||||
-rw-r--r-- | lib/active_relation/relations/deletion_relation.rb | 22 | ||||
-rw-r--r-- | lib/active_relation/relations/inner_join_operation.rb (renamed from lib/sql_algebra/relations/inner_join_operation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/inner_join_relation.rb (renamed from lib/sql_algebra/relations/inner_join_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/insertion_relation.rb | 29 | ||||
-rw-r--r-- | lib/active_relation/relations/join.rb (renamed from lib/sql_algebra/relations/join.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/join_operation.rb (renamed from lib/sql_algebra/relations/join_operation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/join_relation.rb (renamed from lib/sql_algebra/relations/join_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/left_outer_join_operation.rb (renamed from lib/sql_algebra/relations/left_outer_join_operation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/left_outer_join_relation.rb (renamed from lib/sql_algebra/relations/left_outer_join_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/order_relation.rb (renamed from lib/sql_algebra/relations/order_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/projection_relation.rb (renamed from lib/sql_algebra/relations/projection_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/range_relation.rb (renamed from lib/sql_algebra/relations/range_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/relation.rb (renamed from lib/sql_algebra/relations/relation.rb) | 10 | ||||
-rw-r--r-- | lib/active_relation/relations/rename_relation.rb (renamed from lib/sql_algebra/relations/rename_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/relations/selection_relation.rb (renamed from lib/sql_algebra/relations/selection_relation.rb) | 2 | ||||
-rw-r--r-- | lib/active_relation/relations/table_relation.rb (renamed from lib/sql_algebra/relations/table_relation.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/columns_builder.rb | 16 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/conditions_builder.rb (renamed from lib/sql_algebra/sql_builder/conditions_builder.rb) | 4 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/delete_builder.rb | 32 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/equals_condition_builder.rb (renamed from lib/sql_algebra/sql_builder/equals_condition_builder.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/inner_join_builder.rb (renamed from lib/sql_algebra/sql_builder/inner_join_builder.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/insert_builder.rb | 41 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/join_builder.rb (renamed from lib/sql_algebra/sql_builder/join_builder.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/joins_builder.rb (renamed from lib/sql_algebra/sql_builder/joins_builder.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/left_outer_join_builder.rb (renamed from lib/sql_algebra/sql_builder/left_outer_join_builder.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/order_builder.rb (renamed from lib/sql_algebra/sql_builder/order_builder.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/select_builder.rb (renamed from lib/sql_algebra/sql_builder/select_builder.rb) | 3 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/selects_builder.rb | 9 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/sql_builder.rb (renamed from lib/sql_algebra/sql_builder/sql_builder.rb) | 0 | ||||
-rw-r--r-- | lib/active_relation/sql_builder/values_builder.rb | 16 | ||||
-rw-r--r-- | lib/sql_algebra.rb | 49 | ||||
-rw-r--r-- | lib/sql_algebra/relations/compound_relation.rb | 3 | ||||
-rw-r--r-- | lib/sql_algebra/sql_builder/selects_builder.rb | 20 | ||||
-rw-r--r-- | spec/active_relation/integration/scratch_spec.rb (renamed from spec/integration/scratch_spec.rb) | 87 | ||||
-rw-r--r-- | spec/active_relation/predicates/binary_predicate_spec.rb (renamed from spec/predicates/binary_predicate_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/predicates/equality_predicate_spec.rb (renamed from spec/predicates/equality_predicate_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/predicates/relation_inclusion_predicate_spec.rb (renamed from spec/predicates/relation_inclusion_predicate_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/attribute_spec.rb (renamed from spec/relations/attribute_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/deletion_relation_spec.rb | 22 | ||||
-rw-r--r-- | spec/active_relation/relations/insertion_relation_spec.rb | 37 | ||||
-rw-r--r-- | spec/active_relation/relations/join_operation_spec.rb (renamed from spec/relations/join_operation_spec.rb) | 6 | ||||
-rw-r--r-- | spec/active_relation/relations/join_relation_spec.rb (renamed from spec/relations/join_relation_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/order_relation_spec.rb (renamed from spec/relations/order_relation_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/projection_relation_spec.rb (renamed from spec/relations/projection_relation_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/range_relation_spec.rb (renamed from spec/relations/range_relation_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/relation_spec.rb | 92 | ||||
-rw-r--r-- | spec/active_relation/relations/rename_relation_spec.rb (renamed from spec/relations/rename_relation_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/selection_relation_spec.rb (renamed from spec/relations/selection_relation_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/relations/table_relation_spec.rb (renamed from spec/relations/table_relation_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/sql_builder/conditions_spec.rb (renamed from spec/sql_builder/conditions_spec.rb) | 2 | ||||
-rw-r--r-- | spec/active_relation/sql_builder/delete_builder_spec.rb | 22 | ||||
-rw-r--r-- | spec/active_relation/sql_builder/insert_builder_spec.rb | 24 | ||||
-rw-r--r-- | spec/active_relation/sql_builder/select_builder_spec.rb (renamed from spec/sql_builder/select_builder_spec.rb) | 39 | ||||
-rw-r--r-- | spec/debug.log | 1 | ||||
-rw-r--r-- | spec/extensions/range_spec.rb | 1 | ||||
-rw-r--r-- | spec/integration/debug.log | 0 | ||||
-rw-r--r-- | spec/matchers/be_like.rb (renamed from spec/spec_helpers/be_like.rb) | 0 | ||||
-rw-r--r-- | spec/relations/relation_spec.rb | 72 | ||||
-rw-r--r-- | spec/spec_helper.rb | 7 |
78 files changed, 566 insertions, 238 deletions
diff --git a/eager include.txt b/eager include.txt deleted file mode 100644 index 0c56323b40..0000000000 --- a/eager include.txt +++ /dev/null @@ -1,49 +0,0 @@ -User.find( :all, :include => { :photos => :camera } ) - -User.reflection[:photos].klass.reflection[:camera] - -users_photos_camera = User.relation << User.reflections[:photos].relation << Photo.reflections[:camera].relation - -users_photos_camera.each do |record| - User.bring_forth(record, :photos => :camera) -end - -def User.bring_forth(record, included = { :photos => :camera }) - user = @cache[ record % 'users.id' ] || User.instantiate(record % User.attributes) - user.photos.bring_forth(record, :camera) -end - -def User.photos.bring_forth(record, included = :camera) - photo = @cache[ record % 'photos.id' ] || Photo.instantiate(record % Photo.attributes) - photo.camera.bring_forth(record) -end - -def User.photos.camera.bring_forth(record, included = nil) - camera = @cache [ record % 'cameras.id' ] || Camera.instantiate(record % Camera.attributes) -end - -########################### - -# first, rename the attributes to remove ambiguity (analogous to c0_t0 stuff) -eager_loaded_user_cameras = @user_cameras.rename( - @user.attributes => @user.attributes.prefixed, - @photos.attributes => ..., - @cameras.attributes => ..., -) - -# second, bring forth!! -class Repository - def bring_forth(record, includes = []) - object = cache.get(record % klass.primary_key) { Klass.instantiate(record % Klass.attributes) } - includes.each do |include| - case include - when Symbol - object.send(association = include).bring_forth(record) - when Hash - include.each do |association, nested_associations| - object.send(association).bring_forth(record, nested_associations) - end - end - end - end -end
\ No newline at end of file diff --git a/lib/active_relation.rb b/lib/active_relation.rb new file mode 100644 index 0000000000..0d7af7bfb8 --- /dev/null +++ b/lib/active_relation.rb @@ -0,0 +1,56 @@ +$LOAD_PATH.unshift(File.dirname(__FILE__)) + +require 'rubygems' +require 'activesupport' +require 'activerecord' + +require 'active_relation/relations/relation' +require 'active_relation/relations/compound_relation' +require 'active_relation/relations/table_relation' +require 'active_relation/relations/join_operation' +require 'active_relation/relations/inner_join_operation' +require 'active_relation/relations/left_outer_join_operation' +require 'active_relation/relations/join_relation' +require 'active_relation/relations/inner_join_relation' +require 'active_relation/relations/left_outer_join_relation' +require 'active_relation/relations/attribute' +require 'active_relation/relations/projection_relation' +require 'active_relation/relations/selection_relation' +require 'active_relation/relations/order_relation' +require 'active_relation/relations/range_relation' +require 'active_relation/relations/rename_relation' +require 'active_relation/relations/join' +require 'active_relation/relations/deletion_relation' +require 'active_relation/relations/insertion_relation' + +require 'active_relation/predicates/predicate' +require 'active_relation/predicates/binary_predicate' +require 'active_relation/predicates/equality_predicate' +require 'active_relation/predicates/less_than_predicate' +require 'active_relation/predicates/less_than_or_equal_to_predicate' +require 'active_relation/predicates/greater_than_predicate' +require 'active_relation/predicates/greater_than_or_equal_to_predicate' +require 'active_relation/predicates/range_inclusion_predicate' +require 'active_relation/predicates/relation_inclusion_predicate' +require 'active_relation/predicates/match_predicate' + +require 'active_relation/extensions/range' +require 'active_relation/extensions/object' +require 'active_relation/extensions/array' +require 'active_relation/extensions/base' +require 'active_relation/extensions/hash' + +require 'active_relation/sql_builder/sql_builder' +require 'active_relation/sql_builder/select_builder' +require 'active_relation/sql_builder/delete_builder' +require 'active_relation/sql_builder/insert_builder' +require 'active_relation/sql_builder/joins_builder' +require 'active_relation/sql_builder/join_builder' +require 'active_relation/sql_builder/inner_join_builder' +require 'active_relation/sql_builder/left_outer_join_builder' +require 'active_relation/sql_builder/equals_condition_builder' +require 'active_relation/sql_builder/conditions_builder' +require 'active_relation/sql_builder/order_builder' +require 'active_relation/sql_builder/columns_builder' +require 'active_relation/sql_builder/selects_builder' +require 'active_relation/sql_builder/values_builder'
\ No newline at end of file diff --git a/lib/sql_algebra/extensions/array.rb b/lib/active_relation/extensions/array.rb index 5b6d6d6abd..5b6d6d6abd 100644 --- a/lib/sql_algebra/extensions/array.rb +++ b/lib/active_relation/extensions/array.rb diff --git a/lib/sql_algebra/extensions/base.rb b/lib/active_relation/extensions/base.rb index 0dbdef703f..0dbdef703f 100644 --- a/lib/sql_algebra/extensions/base.rb +++ b/lib/active_relation/extensions/base.rb diff --git a/lib/sql_algebra/extensions/hash.rb b/lib/active_relation/extensions/hash.rb index c83ee0d04f..f643ac17ab 100644 --- a/lib/sql_algebra/extensions/hash.rb +++ b/lib/active_relation/extensions/hash.rb @@ -4,4 +4,10 @@ class Hash aliased.merge(yield(key) => value) end end + + def to_sql(builder = ValuesBuilder.new) + builder.call do + row *values + end + end end
\ No newline at end of file diff --git a/lib/sql_algebra/extensions/object.rb b/lib/active_relation/extensions/object.rb index c241581f86..c241581f86 100644 --- a/lib/sql_algebra/extensions/object.rb +++ b/lib/active_relation/extensions/object.rb diff --git a/lib/sql_algebra/extensions/range.rb b/lib/active_relation/extensions/range.rb index e69de29bb2..e69de29bb2 100644 --- a/lib/sql_algebra/extensions/range.rb +++ b/lib/active_relation/extensions/range.rb diff --git a/lib/sql_algebra/predicates/binary_predicate.rb b/lib/active_relation/predicates/binary_predicate.rb index f5c420c833..f5c420c833 100644 --- a/lib/sql_algebra/predicates/binary_predicate.rb +++ b/lib/active_relation/predicates/binary_predicate.rb diff --git a/lib/sql_algebra/predicates/equality_predicate.rb b/lib/active_relation/predicates/equality_predicate.rb index 7040c45f67..7040c45f67 100644 --- a/lib/sql_algebra/predicates/equality_predicate.rb +++ b/lib/active_relation/predicates/equality_predicate.rb diff --git a/lib/sql_algebra/predicates/greater_than_or_equal_to_predicate.rb b/lib/active_relation/predicates/greater_than_or_equal_to_predicate.rb index 49127c312c..49127c312c 100644 --- a/lib/sql_algebra/predicates/greater_than_or_equal_to_predicate.rb +++ b/lib/active_relation/predicates/greater_than_or_equal_to_predicate.rb diff --git a/lib/sql_algebra/predicates/greater_than_predicate.rb b/lib/active_relation/predicates/greater_than_predicate.rb index 03aecaed62..03aecaed62 100644 --- a/lib/sql_algebra/predicates/greater_than_predicate.rb +++ b/lib/active_relation/predicates/greater_than_predicate.rb diff --git a/lib/sql_algebra/predicates/less_than_or_equal_to_predicate.rb b/lib/active_relation/predicates/less_than_or_equal_to_predicate.rb index fee6ea7f35..fee6ea7f35 100644 --- a/lib/sql_algebra/predicates/less_than_or_equal_to_predicate.rb +++ b/lib/active_relation/predicates/less_than_or_equal_to_predicate.rb diff --git a/lib/sql_algebra/predicates/less_than_predicate.rb b/lib/active_relation/predicates/less_than_predicate.rb index 03cbdcf000..03cbdcf000 100644 --- a/lib/sql_algebra/predicates/less_than_predicate.rb +++ b/lib/active_relation/predicates/less_than_predicate.rb diff --git a/lib/sql_algebra/predicates/match_predicate.rb b/lib/active_relation/predicates/match_predicate.rb index 90a13090d4..90a13090d4 100644 --- a/lib/sql_algebra/predicates/match_predicate.rb +++ b/lib/active_relation/predicates/match_predicate.rb diff --git a/lib/sql_algebra/predicates/predicate.rb b/lib/active_relation/predicates/predicate.rb index 4c395a3fdc..4c395a3fdc 100644 --- a/lib/sql_algebra/predicates/predicate.rb +++ b/lib/active_relation/predicates/predicate.rb diff --git a/lib/sql_algebra/predicates/range_inclusion_predicate.rb b/lib/active_relation/predicates/range_inclusion_predicate.rb index e69de29bb2..e69de29bb2 100644 --- a/lib/sql_algebra/predicates/range_inclusion_predicate.rb +++ b/lib/active_relation/predicates/range_inclusion_predicate.rb diff --git a/lib/sql_algebra/predicates/relation_inclusion_predicate.rb b/lib/active_relation/predicates/relation_inclusion_predicate.rb index 5881a85d99..5881a85d99 100644 --- a/lib/sql_algebra/predicates/relation_inclusion_predicate.rb +++ b/lib/active_relation/predicates/relation_inclusion_predicate.rb diff --git a/lib/sql_algebra/relations/attribute.rb b/lib/active_relation/relations/attribute.rb index 7583553b80..7583553b80 100644 --- a/lib/sql_algebra/relations/attribute.rb +++ b/lib/active_relation/relations/attribute.rb diff --git a/lib/active_relation/relations/compound_relation.rb b/lib/active_relation/relations/compound_relation.rb new file mode 100644 index 0000000000..fe92905d92 --- /dev/null +++ b/lib/active_relation/relations/compound_relation.rb @@ -0,0 +1,3 @@ +class CompoundRelation < Relation + delegate :attributes, :attribute, :joins, :selects, :orders, :table, :inserts, :to => :relation +end
\ No newline at end of file diff --git a/lib/active_relation/relations/deletion_relation.rb b/lib/active_relation/relations/deletion_relation.rb new file mode 100644 index 0000000000..e060efd5f9 --- /dev/null +++ b/lib/active_relation/relations/deletion_relation.rb @@ -0,0 +1,22 @@ +class DeletionRelation < CompoundRelation + attr_reader :relation + + def ==(other) + relation == other.relation + end + + def initialize(relation) + @relation = relation + end + + def to_sql(builder = DeleteBuilder.new) + builder.call do + delete + from table + where do + selects.each { |s| s.to_sql(self) } + end + end + end + +end
\ No newline at end of file diff --git a/lib/sql_algebra/relations/inner_join_operation.rb b/lib/active_relation/relations/inner_join_operation.rb index 6b5c5ce8d0..6b5c5ce8d0 100644 --- a/lib/sql_algebra/relations/inner_join_operation.rb +++ b/lib/active_relation/relations/inner_join_operation.rb diff --git a/lib/sql_algebra/relations/inner_join_relation.rb b/lib/active_relation/relations/inner_join_relation.rb index 5e58f241f8..5e58f241f8 100644 --- a/lib/sql_algebra/relations/inner_join_relation.rb +++ b/lib/active_relation/relations/inner_join_relation.rb diff --git a/lib/active_relation/relations/insertion_relation.rb b/lib/active_relation/relations/insertion_relation.rb new file mode 100644 index 0000000000..84752d13f9 --- /dev/null +++ b/lib/active_relation/relations/insertion_relation.rb @@ -0,0 +1,29 @@ +class InsertionRelation < CompoundRelation + attr_reader :relation, :tuple + + def initialize(relation, tuple) + @relation, @tuple = relation, tuple + end + + def to_sql(builder = InsertBuilder.new) + builder.call do + insert + into table + columns do + tuple.keys.each { |attribute| attribute.to_sql(self) } + end + values do + inserts.each { |insert| insert.to_sql(self) } + end + end + end + + def ==(other) + relation == other.relation and tuple == other.tuple + end + + protected + def inserts + relation.inserts + [tuple] + end +end
\ No newline at end of file diff --git a/lib/sql_algebra/relations/join.rb b/lib/active_relation/relations/join.rb index 9a6196deac..9a6196deac 100644 --- a/lib/sql_algebra/relations/join.rb +++ b/lib/active_relation/relations/join.rb diff --git a/lib/sql_algebra/relations/join_operation.rb b/lib/active_relation/relations/join_operation.rb index 2b4548a041..2b4548a041 100644 --- a/lib/sql_algebra/relations/join_operation.rb +++ b/lib/active_relation/relations/join_operation.rb diff --git a/lib/sql_algebra/relations/join_relation.rb b/lib/active_relation/relations/join_relation.rb index 79c8a915b8..79c8a915b8 100644 --- a/lib/sql_algebra/relations/join_relation.rb +++ b/lib/active_relation/relations/join_relation.rb diff --git a/lib/sql_algebra/relations/left_outer_join_operation.rb b/lib/active_relation/relations/left_outer_join_operation.rb index fbb2a4e2ed..fbb2a4e2ed 100644 --- a/lib/sql_algebra/relations/left_outer_join_operation.rb +++ b/lib/active_relation/relations/left_outer_join_operation.rb diff --git a/lib/sql_algebra/relations/left_outer_join_relation.rb b/lib/active_relation/relations/left_outer_join_relation.rb index 6d13d8da07..6d13d8da07 100644 --- a/lib/sql_algebra/relations/left_outer_join_relation.rb +++ b/lib/active_relation/relations/left_outer_join_relation.rb diff --git a/lib/sql_algebra/relations/order_relation.rb b/lib/active_relation/relations/order_relation.rb index b39dc45c3f..b39dc45c3f 100644 --- a/lib/sql_algebra/relations/order_relation.rb +++ b/lib/active_relation/relations/order_relation.rb diff --git a/lib/sql_algebra/relations/projection_relation.rb b/lib/active_relation/relations/projection_relation.rb index 1a0e8dbfe4..1a0e8dbfe4 100644 --- a/lib/sql_algebra/relations/projection_relation.rb +++ b/lib/active_relation/relations/projection_relation.rb diff --git a/lib/sql_algebra/relations/range_relation.rb b/lib/active_relation/relations/range_relation.rb index 9225d5615b..9225d5615b 100644 --- a/lib/sql_algebra/relations/range_relation.rb +++ b/lib/active_relation/relations/range_relation.rb diff --git a/lib/sql_algebra/relations/relation.rb b/lib/active_relation/relations/relation.rb index 8efe0c7d9f..be6ee760a5 100644 --- a/lib/sql_algebra/relations/relation.rb +++ b/lib/active_relation/relations/relation.rb @@ -49,6 +49,14 @@ class Relation def rename(attribute, aliaz) RenameRelation.new(self, attribute => aliaz) end + + def insert(tuple) + InsertionRelation.new(self, tuple) + end + + def delete + DeletionRelation.new(self) + end end include Operations @@ -79,5 +87,5 @@ class Relation def joins; [] end def selects; [] end def orders; [] end - + def inserts; [] end end
\ No newline at end of file diff --git a/lib/sql_algebra/relations/rename_relation.rb b/lib/active_relation/relations/rename_relation.rb index 8acf5091b2..8acf5091b2 100644 --- a/lib/sql_algebra/relations/rename_relation.rb +++ b/lib/active_relation/relations/rename_relation.rb diff --git a/lib/sql_algebra/relations/selection_relation.rb b/lib/active_relation/relations/selection_relation.rb index dcf5f4745f..77864efb28 100644 --- a/lib/sql_algebra/relations/selection_relation.rb +++ b/lib/active_relation/relations/selection_relation.rb @@ -16,6 +16,6 @@ class SelectionRelation < CompoundRelation protected def selects - [predicate] + relation.send(:selects) + [predicate] end end
\ No newline at end of file diff --git a/lib/sql_algebra/relations/table_relation.rb b/lib/active_relation/relations/table_relation.rb index 5a47ae7a34..5a47ae7a34 100644 --- a/lib/sql_algebra/relations/table_relation.rb +++ b/lib/active_relation/relations/table_relation.rb diff --git a/lib/active_relation/sql_builder/columns_builder.rb b/lib/active_relation/sql_builder/columns_builder.rb new file mode 100644 index 0000000000..a8a5d0e4ca --- /dev/null +++ b/lib/active_relation/sql_builder/columns_builder.rb @@ -0,0 +1,16 @@ +class ColumnsBuilder < SqlBuilder + def initialize(&block) + @columns = [] + super(&block) + end + + def to_s + @columns.join(', ') + end + + def column(table, column, aliaz = nil) + @columns << "#{quote_table_name(table)}.#{quote_column_name(column)}" + end + + delegate :blank?, :to => :@columns +end
\ No newline at end of file diff --git a/lib/sql_algebra/sql_builder/conditions_builder.rb b/lib/active_relation/sql_builder/conditions_builder.rb index 5d42a36cec..60430f65d8 100644 --- a/lib/sql_algebra/sql_builder/conditions_builder.rb +++ b/lib/active_relation/sql_builder/conditions_builder.rb @@ -7,6 +7,10 @@ class ConditionsBuilder < SqlBuilder def equals(&block) @conditions << EqualsConditionBuilder.new(&block) end + + def value(value) + @conditions << value + end def to_s @conditions.join(' AND ') diff --git a/lib/active_relation/sql_builder/delete_builder.rb b/lib/active_relation/sql_builder/delete_builder.rb new file mode 100644 index 0000000000..2e8be94dfe --- /dev/null +++ b/lib/active_relation/sql_builder/delete_builder.rb @@ -0,0 +1,32 @@ +class DeleteBuilder < SqlBuilder + def delete + end + + def from(table) + @table = table + end + + def where(&block) + @conditions = ConditionsBuilder.new(&block) + end + + def to_s + [delete_clause, + from_clause, + where_clause + ].compact.join("\n") + end + + private + def delete_clause + "DELETE" + end + + def from_clause + "FROM #{quote_table_name(@table)}" + end + + def where_clause + "WHERE #{@conditions}" unless @conditions.blank? + end +end
\ No newline at end of file diff --git a/lib/sql_algebra/sql_builder/equals_condition_builder.rb b/lib/active_relation/sql_builder/equals_condition_builder.rb index cfa919c34c..cfa919c34c 100644 --- a/lib/sql_algebra/sql_builder/equals_condition_builder.rb +++ b/lib/active_relation/sql_builder/equals_condition_builder.rb diff --git a/lib/sql_algebra/sql_builder/inner_join_builder.rb b/lib/active_relation/sql_builder/inner_join_builder.rb index 6aec703325..6aec703325 100644 --- a/lib/sql_algebra/sql_builder/inner_join_builder.rb +++ b/lib/active_relation/sql_builder/inner_join_builder.rb diff --git a/lib/active_relation/sql_builder/insert_builder.rb b/lib/active_relation/sql_builder/insert_builder.rb new file mode 100644 index 0000000000..09deefad10 --- /dev/null +++ b/lib/active_relation/sql_builder/insert_builder.rb @@ -0,0 +1,41 @@ +class InsertBuilder < SqlBuilder + def insert + end + + def into(table) + @table = table + end + + def columns(&block) + @columns = ColumnsBuilder.new(&block) + end + + def values(&block) + @values = ValuesBuilder.new(&block) + end + + def to_s + [insert_clause, + into_clause, + columns_clause, + values_clause + ].compact.join("\n") + end + + private + def insert_clause + "INSERT" + end + + def into_clause + "INTO #{quote_table_name(@table)}" + end + + def values_clause + "VALUES #{@values}" unless @values.blank? + end + + def columns_clause + "(#{@columns})" unless @columns.blank? + end +end
\ No newline at end of file diff --git a/lib/sql_algebra/sql_builder/join_builder.rb b/lib/active_relation/sql_builder/join_builder.rb index ef63d1fcb1..ef63d1fcb1 100644 --- a/lib/sql_algebra/sql_builder/join_builder.rb +++ b/lib/active_relation/sql_builder/join_builder.rb diff --git a/lib/sql_algebra/sql_builder/joins_builder.rb b/lib/active_relation/sql_builder/joins_builder.rb index 36a92e9922..36a92e9922 100644 --- a/lib/sql_algebra/sql_builder/joins_builder.rb +++ b/lib/active_relation/sql_builder/joins_builder.rb diff --git a/lib/sql_algebra/sql_builder/left_outer_join_builder.rb b/lib/active_relation/sql_builder/left_outer_join_builder.rb index dad3f85810..dad3f85810 100644 --- a/lib/sql_algebra/sql_builder/left_outer_join_builder.rb +++ b/lib/active_relation/sql_builder/left_outer_join_builder.rb diff --git a/lib/sql_algebra/sql_builder/order_builder.rb b/lib/active_relation/sql_builder/order_builder.rb index 66a8cfdba9..66a8cfdba9 100644 --- a/lib/sql_algebra/sql_builder/order_builder.rb +++ b/lib/active_relation/sql_builder/order_builder.rb diff --git a/lib/sql_algebra/sql_builder/select_builder.rb b/lib/active_relation/sql_builder/select_builder.rb index 9a85ad7eec..57116cb64b 100644 --- a/lib/sql_algebra/sql_builder/select_builder.rb +++ b/lib/active_relation/sql_builder/select_builder.rb @@ -9,8 +9,7 @@ class SelectBuilder < SqlBuilder end def where(&block) - @conditions ||= ConditionsBuilder.new - @conditions.call(&block) + @conditions = ConditionsBuilder.new(&block) end def order_by(&block) diff --git a/lib/active_relation/sql_builder/selects_builder.rb b/lib/active_relation/sql_builder/selects_builder.rb new file mode 100644 index 0000000000..6ad06d0ae4 --- /dev/null +++ b/lib/active_relation/sql_builder/selects_builder.rb @@ -0,0 +1,9 @@ +class SelectsBuilder < ColumnsBuilder + def all + @columns << :* + end + + def column(table, column, aliaz = nil) + @columns << "#{quote_table_name(table)}.#{quote_column_name(column)}" + (aliaz ? " AS #{quote(aliaz)}" : '') + end +end
\ No newline at end of file diff --git a/lib/sql_algebra/sql_builder/sql_builder.rb b/lib/active_relation/sql_builder/sql_builder.rb index c984444e41..c984444e41 100644 --- a/lib/sql_algebra/sql_builder/sql_builder.rb +++ b/lib/active_relation/sql_builder/sql_builder.rb diff --git a/lib/active_relation/sql_builder/values_builder.rb b/lib/active_relation/sql_builder/values_builder.rb new file mode 100644 index 0000000000..f22b1e507e --- /dev/null +++ b/lib/active_relation/sql_builder/values_builder.rb @@ -0,0 +1,16 @@ +class ValuesBuilder < SqlBuilder + def initialize(&block) + @values = [] + super(&block) + end + + def row(*values) + @values << "(#{values.collect { |v| quote(v) }.join(', ')})" + end + + def to_s + @values.join(', ') + end + + delegate :blank?, :to => :@values +end
\ No newline at end of file diff --git a/lib/sql_algebra.rb b/lib/sql_algebra.rb deleted file mode 100644 index fbd053541c..0000000000 --- a/lib/sql_algebra.rb +++ /dev/null @@ -1,49 +0,0 @@ -$LOAD_PATH.unshift(File.dirname(__FILE__)) -require 'rubygems' -require 'activesupport' -require 'activerecord' - -require 'sql_algebra/relations/relation' -require 'sql_algebra/relations/compound_relation' -require 'sql_algebra/relations/table_relation' -require 'sql_algebra/relations/join_operation' -require 'sql_algebra/relations/inner_join_operation' -require 'sql_algebra/relations/left_outer_join_operation' -require 'sql_algebra/relations/join_relation' -require 'sql_algebra/relations/inner_join_relation' -require 'sql_algebra/relations/left_outer_join_relation' -require 'sql_algebra/relations/attribute' -require 'sql_algebra/relations/projection_relation' -require 'sql_algebra/relations/selection_relation' -require 'sql_algebra/relations/order_relation' -require 'sql_algebra/relations/range_relation' -require 'sql_algebra/relations/rename_relation' -require 'sql_algebra/relations/join' - -require 'sql_algebra/predicates/predicate' -require 'sql_algebra/predicates/binary_predicate' -require 'sql_algebra/predicates/equality_predicate' -require 'sql_algebra/predicates/less_than_predicate' -require 'sql_algebra/predicates/less_than_or_equal_to_predicate' -require 'sql_algebra/predicates/greater_than_predicate' -require 'sql_algebra/predicates/greater_than_or_equal_to_predicate' -require 'sql_algebra/predicates/range_inclusion_predicate' -require 'sql_algebra/predicates/relation_inclusion_predicate' -require 'sql_algebra/predicates/match_predicate' - -require 'sql_algebra/extensions/range' -require 'sql_algebra/extensions/object' -require 'sql_algebra/extensions/array' -require 'sql_algebra/extensions/base' -require 'sql_algebra/extensions/hash' - -require 'sql_algebra/sql_builder/sql_builder' -require 'sql_algebra/sql_builder/select_builder' -require 'sql_algebra/sql_builder/joins_builder' -require 'sql_algebra/sql_builder/join_builder' -require 'sql_algebra/sql_builder/inner_join_builder' -require 'sql_algebra/sql_builder/left_outer_join_builder' -require 'sql_algebra/sql_builder/equals_condition_builder' -require 'sql_algebra/sql_builder/conditions_builder' -require 'sql_algebra/sql_builder/order_builder' -require 'sql_algebra/sql_builder/selects_builder'
\ No newline at end of file diff --git a/lib/sql_algebra/relations/compound_relation.rb b/lib/sql_algebra/relations/compound_relation.rb deleted file mode 100644 index a8e9a41b5e..0000000000 --- a/lib/sql_algebra/relations/compound_relation.rb +++ /dev/null @@ -1,3 +0,0 @@ -class CompoundRelation < Relation - delegate :attributes, :attribute, :joins, :select, :orders, :table, :to => :relation -end
\ No newline at end of file diff --git a/lib/sql_algebra/sql_builder/selects_builder.rb b/lib/sql_algebra/sql_builder/selects_builder.rb deleted file mode 100644 index ce6ee1eb67..0000000000 --- a/lib/sql_algebra/sql_builder/selects_builder.rb +++ /dev/null @@ -1,20 +0,0 @@ -class SelectsBuilder < SqlBuilder - def initialize(&block) - @selects = [] - super(&block) - end - - def to_s - @selects.join(', ') - end - - def all - @selects << :* - end - - def column(table, column, aliaz = nil) - @selects << "#{quote_table_name(table)}.#{quote_column_name(column)}" + (aliaz ? " AS #{quote(aliaz)}" : '') - end - - delegate :blank?, :to => :@selects -end
\ No newline at end of file diff --git a/spec/integration/scratch_spec.rb b/spec/active_relation/integration/scratch_spec.rb index b5d27f1dc2..fba587e4ba 100644 --- a/spec/integration/scratch_spec.rb +++ b/spec/active_relation/integration/scratch_spec.rb @@ -1,16 +1,16 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') -describe 'ActiveRelation', 'Proposed refactoring to ActiveRecord, introducing both a SQL - builder and a Relational Algebra to mediate connections - between ActiveRecord and the database. The goal of the - refactoring is to remove code duplication concerning AR - associations; remove complexity surrounding eager loading; - comprehensively solve quoting issues; remove the with_scope - merging logic; minimize the need for with_scope in general; - simplify the implementation of plugins like HasFinder and - ActsAsParanoid; introduce an identity map; and allow for - query optimization. All this while effectively not changing - the public interface of ActiveRecord. +describe 'ActiveRelation', 'A proposed refactoring to ActiveRecord, introducing both a SQL + Builder and a Relational Algebra to mediate between + ActiveRecord and the database. The goal of the refactoring is + to remove code duplication concerning AR associations; remove + complexity surrounding eager loading; comprehensively solve + quoting issues; remove the with_scope merging logic; minimize + the need for with_scope in general; simplify the + implementation of plugins like HasFinder and ActsAsParanoid; + introduce an identity map; and allow for query optimization. + All this while remaining backwards-compatible with the + existing ActiveRecord interface. The Relational Algebra makes these ambitious goals possible. There\'s no need to be scared by the math, it\'s actually quite simple. Relational Algebras have some nice @@ -25,7 +25,7 @@ describe 'ActiveRelation', 'Proposed refactoring to ActiveRecord, introducing bo should all be understood as \'Repositories\': a factory that given a relation can manufacture objects, and given an object can manipulate a relation. This may sound trivial, but I - think it has the potential to make the code much smaller and + think it has the potential to make the code smaller and more consistent.' do before do class User < ActiveRecord::Base; has_many :photos end @@ -40,8 +40,8 @@ describe 'ActiveRelation', 'Proposed refactoring to ActiveRecord, introducing bo @photos = Photo.relation @cameras = Camera.relation # A first taste of a Relational Algebra: User.find(1) - # == is overridden on attributes to return a predicate, not true or false @user = @users.select(@users[:id] == 1) + # == is overridden on attributes to return a predicate, not true or false end # In a Relational Algebra, the various ActiveRecord associations become a simple @@ -122,13 +122,47 @@ describe 'ActiveRelation', 'Proposed refactoring to ActiveRecord, introducing bo ON `photos`.`camera_id` = `cameras`.`id` """) end + + it 'allows arbitrary sql to be passed through' do + (@users << @photos).on("asdf").to_s.should be_like(""" + SELECT `users`.`name`, `users`.`id`, `photos`.`id`, `photos`.`user_id`, `photos`.`camera_id` + FROM `users` + LEFT OUTER JOIN `photos` + ON asdf + """) + @users.select("asdf").to_s.should be_like(""" + SELECT `users`.`name`, `users`.`id` + FROM `users` + WHERE asdf + """) + end + + describe 'write operations' do + it 'generates the query for user.destroy' do + @user.delete.to_s.should be_like(""" + DELETE + FROM `users` + WHERE `users`.`id` = 1 + """) + end - it 'obviates the need for with_scope merging logic since, e.g., - `with_scope :conditions => ...` is just a #select operation on the relation' do + it 'generates an efficient query for two User.creates -- UnitOfWork is within reach!' do + @users.insert(@users[:name] => "humpty").insert(@users[:name] => "dumpty").to_s.should be_like(""" + INSERT + INTO `users` + (`users`.`name`) VALUES ('humpty'), ('dumpty') + """) + end end + + describe 'with_scope' do + it 'obviates the need for with_scope merging logic since, e.g., + `with_scope :conditions => ...` is just a #select operation on the relation' do + end - it 'may eliminate the need for with_scope altogether since the associations no longer - need it: the relation underlying the association fully encapsulates the scope' do + it 'may eliminate the need for with_scope altogether since the associations no longer + need it: the relation underlying the association fully encapsulates the scope' do + end end end @@ -159,10 +193,11 @@ describe 'ActiveRelation', 'Proposed refactoring to ActiveRecord, introducing bo describe 'the n+1 problem' do describe 'the eager join algorithm is vastly simpler' do - it 'three active records are loaded with only one query' do + it 'loads three active records with only one query' do # using 'rr' mocking framework: the real #select_all is called, but we assert # that it only happens once: mock.proxy(ActiveRecord::Base.connection).select_all.with_any_args.once + users_cameras = photo_belongs_to_camera(user_has_many_photos(@users)).qualify user = User.instantiate(users_cameras.first, [:photos => [:camera]]) user.photos.first.camera.attributes.should == {"id" => 1} @@ -216,11 +251,21 @@ describe 'ActiveRelation', 'Proposed refactoring to ActiveRecord, introducing bo photos for all subsequent users. This is substantially easier with the Algebra since we can do @user.join(@photos).on(...) and transform that to @users.join(@photos).on(...), relying on the IdentityMap to eliminate - the n+1 problem. This is somewhat similar to ActiveRecordContext but it - works with every association type, not just belongs_to." do + the n+1 problem." do pending end end end end + + describe 'The Architecture', 'I propose to produce a new gem, ActiveRelation, which encaplulates + the existing ActiveRecord Connection Adapter, the new SQL Builder, + and the Relational Algebra. ActiveRecord, then, should no longer + interact with the connection object directly.' do + end + + describe 'Miscellaneous Ideas' do + it 'may be easy to write a SQL parser that can take arbitrary SQL and produce a relation. + This has the advantage of permitting e.g., pagination with custom finder_sql' + end end
\ No newline at end of file diff --git a/spec/predicates/binary_predicate_spec.rb b/spec/active_relation/predicates/binary_predicate_spec.rb index ede44e5175..5de559df41 100644 --- a/spec/predicates/binary_predicate_spec.rb +++ b/spec/active_relation/predicates/binary_predicate_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe BinaryPredicate do before do diff --git a/spec/predicates/equality_predicate_spec.rb b/spec/active_relation/predicates/equality_predicate_spec.rb index 75b495b6f7..af43b754e0 100644 --- a/spec/predicates/equality_predicate_spec.rb +++ b/spec/active_relation/predicates/equality_predicate_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe EqualityPredicate do before do diff --git a/spec/predicates/relation_inclusion_predicate_spec.rb b/spec/active_relation/predicates/relation_inclusion_predicate_spec.rb index 6cd37fafa8..f8c911429b 100644 --- a/spec/predicates/relation_inclusion_predicate_spec.rb +++ b/spec/active_relation/predicates/relation_inclusion_predicate_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe RelationInclusionPredicate do before do diff --git a/spec/relations/attribute_spec.rb b/spec/active_relation/relations/attribute_spec.rb index 4887be38d2..ddfc22fe28 100644 --- a/spec/relations/attribute_spec.rb +++ b/spec/active_relation/relations/attribute_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe Attribute do before do diff --git a/spec/active_relation/relations/deletion_relation_spec.rb b/spec/active_relation/relations/deletion_relation_spec.rb new file mode 100644 index 0000000000..4f75a261f4 --- /dev/null +++ b/spec/active_relation/relations/deletion_relation_spec.rb @@ -0,0 +1,22 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') + +describe DeletionRelation do + before do + @relation = TableRelation.new(:users) + end + + describe '#to_sql' do + it 'manufactures sql deleting the relation' do + DeletionRelation.new(@relation.select(@relation[:id] == 1)).to_sql.to_s.should == DeleteBuilder.new do + delete + from :users + where do + equals do + column :users, :id + value 1 + end + end + end.to_s + end + end +end
\ No newline at end of file diff --git a/spec/active_relation/relations/insertion_relation_spec.rb b/spec/active_relation/relations/insertion_relation_spec.rb new file mode 100644 index 0000000000..6bafabb473 --- /dev/null +++ b/spec/active_relation/relations/insertion_relation_spec.rb @@ -0,0 +1,37 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') + +describe InsertionRelation do + before do + @relation = TableRelation.new(:users) + end + + describe '#to_sql' do + it 'manufactures sql inserting the data for one item' do + InsertionRelation.new(@relation, @relation[:name] => "nick").to_sql.should == InsertBuilder.new do + insert + into :users + columns do + column :users, :name + end + values do + row "nick" + end + end + end + + it 'manufactures sql inserting the data for multiple items' do + nested_insertion = InsertionRelation.new(@relation, @relation[:name] => "cobra") + InsertionRelation.new(nested_insertion, nested_insertion[:name] => "commander").to_sql.to_s.should == InsertBuilder.new do + insert + into :users + columns do + column :users, :name + end + values do + row "cobra" + row "commander" + end + end.to_s + end + end +end
\ No newline at end of file diff --git a/spec/relations/join_operation_spec.rb b/spec/active_relation/relations/join_operation_spec.rb index db30198f6e..a8ab85123b 100644 --- a/spec/relations/join_operation_spec.rb +++ b/spec/active_relation/relations/join_operation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe 'between two relations' do before do @@ -31,5 +31,9 @@ describe 'between two relations' do it "manufactures a join relation of the appropriate type" do @join_operation.on(@predicate).should == JoinRelation.new(@relation1, @relation2, @predicate) end + + it "accepts arbitrary strings" do + @join_operation.on("arbitrary").should == JoinRelation.new(@relation1, @relation2, "arbitrary") + end end end
\ No newline at end of file diff --git a/spec/relations/join_relation_spec.rb b/spec/active_relation/relations/join_relation_spec.rb index ece7e61cc1..d0be270837 100644 --- a/spec/relations/join_relation_spec.rb +++ b/spec/active_relation/relations/join_relation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe JoinRelation do before do diff --git a/spec/relations/order_relation_spec.rb b/spec/active_relation/relations/order_relation_spec.rb index a78ac148e2..17f730b564 100644 --- a/spec/relations/order_relation_spec.rb +++ b/spec/active_relation/relations/order_relation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe OrderRelation do before do diff --git a/spec/relations/projection_relation_spec.rb b/spec/active_relation/relations/projection_relation_spec.rb index 5a33b16bd5..164c485761 100644 --- a/spec/relations/projection_relation_spec.rb +++ b/spec/active_relation/relations/projection_relation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe ProjectionRelation do before do diff --git a/spec/relations/range_relation_spec.rb b/spec/active_relation/relations/range_relation_spec.rb index 926cc0929f..ac9f887d9b 100644 --- a/spec/relations/range_relation_spec.rb +++ b/spec/active_relation/relations/range_relation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe RangeRelation do before do diff --git a/spec/active_relation/relations/relation_spec.rb b/spec/active_relation/relations/relation_spec.rb new file mode 100644 index 0000000000..9ed42a98cb --- /dev/null +++ b/spec/active_relation/relations/relation_spec.rb @@ -0,0 +1,92 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') + +describe Relation do + before do + @relation1 = TableRelation.new(:foo) + @relation2 = TableRelation.new(:bar) + @attribute1 = Attribute.new(@relation1, :id) + @attribute2 = Attribute.new(@relation1, :name) + end + + describe '[]' do + it "manufactures an attribute when given a symbol" do + @relation1[:id].should be_eql(Attribute.new(@relation1, :id)) + end + + it "manufactures a range relation when given a range" do + @relation1[1..2].should == RangeRelation.new(@relation1, 1..2) + end + end + + describe '#include?' do + it "manufactures an inclusion predicate" do + @relation1.include?(@attribute1).should == RelationInclusionPredicate.new(@attribute1, @relation1) + end + end + + describe 'read operations' do + describe 'joins' do + describe '<=>' do + it "manufactures an inner join operation between those two relations" do + (@relation1 <=> @relation2).should == InnerJoinOperation.new(@relation1, @relation2) + end + end + + describe '<<' do + it "manufactures a left outer join operation between those two relations" do + (@relation1 << @relation2).should == LeftOuterJoinOperation.new(@relation1, @relation2) + end + end + end + + describe '#project' do + it "collapses identical projections" do + pending + end + + it "manufactures a projection relation" do + @relation1.project(@attribute1, @attribute2).should == ProjectionRelation.new(@relation1, @attribute1, @attribute2) + end + end + + describe '#rename' do + it "manufactures a rename relation" do + @relation1.rename(@attribute1, :foo).should == RenameRelation.new(@relation1, @attribute1 => :foo) + end + end + + describe '#select' do + before do + @predicate = EqualityPredicate.new(@attribute1, @attribute2) + end + + it "manufactures a selection relation" do + @relation1.select(@predicate).should == SelectionRelation.new(@relation1, @predicate) + end + + it "accepts arbitrary strings" do + @relation1.select("arbitrary").should == SelectionRelation.new(@relation1, "arbitrary") + end + end + + describe '#order' do + it "manufactures an order relation" do + @relation1.order(@attribute1, @attribute2).should == OrderRelation.new(@relation1, @attribute1, @attribute2) + end + end + end + + describe 'write operations' do + describe '#delete' do + it 'manufactures a deletion relation' do + @relation1.delete.should == DeletionRelation.new(@relation1) + end + end + + describe '#insert' do + it 'manufactures an insertion relation' do + @relation1.insert(tuple = {:id => 1}).should == InsertionRelation.new(@relation1, tuple) + end + end + end +end
\ No newline at end of file diff --git a/spec/relations/rename_relation_spec.rb b/spec/active_relation/relations/rename_relation_spec.rb index 301ee6db9e..9b1d2d5cc8 100644 --- a/spec/relations/rename_relation_spec.rb +++ b/spec/active_relation/relations/rename_relation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe RenameRelation do before do diff --git a/spec/relations/selection_relation_spec.rb b/spec/active_relation/relations/selection_relation_spec.rb index 656a386fd6..c4aadc807b 100644 --- a/spec/relations/selection_relation_spec.rb +++ b/spec/active_relation/relations/selection_relation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe SelectionRelation do before do diff --git a/spec/relations/table_relation_spec.rb b/spec/active_relation/relations/table_relation_spec.rb index 0380372344..c943fe6c92 100644 --- a/spec/relations/table_relation_spec.rb +++ b/spec/active_relation/relations/table_relation_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe TableRelation do before do diff --git a/spec/sql_builder/conditions_spec.rb b/spec/active_relation/sql_builder/conditions_spec.rb index dc44cedc85..dc2d10a2f6 100644 --- a/spec/sql_builder/conditions_spec.rb +++ b/spec/active_relation/sql_builder/conditions_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe ConditionsBuilder do describe '#to_s' do diff --git a/spec/active_relation/sql_builder/delete_builder_spec.rb b/spec/active_relation/sql_builder/delete_builder_spec.rb new file mode 100644 index 0000000000..fd62fde155 --- /dev/null +++ b/spec/active_relation/sql_builder/delete_builder_spec.rb @@ -0,0 +1,22 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') + +describe DeleteBuilder do + describe '#to_s' do + it 'manufactures correct sql' do + DeleteBuilder.new do + delete + from :users + where do + equals do + column :users, :id + value 1 + end + end + end.to_s.should be_like(""" + DELETE + FROM `users` + WHERE `users`.`id` = 1 + """) + end + end +end
\ No newline at end of file diff --git a/spec/active_relation/sql_builder/insert_builder_spec.rb b/spec/active_relation/sql_builder/insert_builder_spec.rb new file mode 100644 index 0000000000..dddc971986 --- /dev/null +++ b/spec/active_relation/sql_builder/insert_builder_spec.rb @@ -0,0 +1,24 @@ +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') + +describe InsertBuilder do + describe '#to_s' do + it 'manufactures correct sql' do + InsertBuilder.new do + insert + into :users + columns do + column :users, :id + column :users, :name + end + values do + row 1, 'bob' + row 2, 'moe' + end + end.to_s.should be_like(""" + INSERT + INTO `users` + (`users`.`id`, `users`.`name`) VALUES (1, 'bob'), (2, 'moe') + """) + end + end +end
\ No newline at end of file diff --git a/spec/sql_builder/select_builder_spec.rb b/spec/active_relation/sql_builder/select_builder_spec.rb index 122539967e..6539afe0c4 100644 --- a/spec/sql_builder/select_builder_spec.rb +++ b/spec/active_relation/sql_builder/select_builder_spec.rb @@ -1,4 +1,4 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') +require File.join(File.dirname(__FILE__), '..', '..', 'spec_helper') describe SelectBuilder do describe '#to_s' do @@ -50,6 +50,22 @@ describe SelectBuilder do WHERE 1 = `b`.`c` """) end + + it 'accepts arbitrary strings' do + SelectBuilder.new do + select do + all + end + from :users + where do + value "'a' = 'a'" + end + end.to_s.should be_like(""" + SELECT * + FROM `users` + WHERE 'a' = 'a' + """) + end end describe 'with inner join' do @@ -68,7 +84,26 @@ describe SelectBuilder do end end.to_s.should be_like(""" SELECT * - FROM `users` INNER JOIN `friendships` ON `users`.`id` = `friendships`.`user_id` + FROM `users` + INNER JOIN `friendships` + ON `users`.`id` = `friendships`.`user_id` + """) + end + + it 'accepts arbitrary on strings' do + SelectBuilder.new do + select do + all + end + from :users do + inner_join :friendships do + value "arbitrary" + end + end + end.to_s.should be_like(""" + SELECT * + FROM `users` + INNER JOIN `friendships` ON arbitrary """) end end diff --git a/spec/debug.log b/spec/debug.log deleted file mode 100644 index d38ed11d82..0000000000 --- a/spec/debug.log +++ /dev/null @@ -1 +0,0 @@ -# Logfile created on Tue Jan 01 17:49:28 -0800 2008 by logger.rb/1.5.2.9 diff --git a/spec/extensions/range_spec.rb b/spec/extensions/range_spec.rb deleted file mode 100644 index 26ca8978ca..0000000000 --- a/spec/extensions/range_spec.rb +++ /dev/null @@ -1 +0,0 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') diff --git a/spec/integration/debug.log b/spec/integration/debug.log deleted file mode 100644 index e69de29bb2..0000000000 --- a/spec/integration/debug.log +++ /dev/null diff --git a/spec/spec_helpers/be_like.rb b/spec/matchers/be_like.rb index cea3f3027b..cea3f3027b 100644 --- a/spec/spec_helpers/be_like.rb +++ b/spec/matchers/be_like.rb diff --git a/spec/relations/relation_spec.rb b/spec/relations/relation_spec.rb deleted file mode 100644 index d029827f21..0000000000 --- a/spec/relations/relation_spec.rb +++ /dev/null @@ -1,72 +0,0 @@ -require File.join(File.dirname(__FILE__), '..', 'spec_helper') - -describe Relation do - before do - @relation1 = TableRelation.new(:foo) - @relation2 = TableRelation.new(:bar) - @attribute1 = Attribute.new(@relation1, :id) - @attribute2 = Attribute.new(@relation1, :name) - end - - describe 'joins' do - describe '<=>' do - it "manufactures an inner join operation between those two relations" do - (@relation1 <=> @relation2).should == InnerJoinOperation.new(@relation1, @relation2) - end - end - - describe '<<' do - it "manufactures a left outer join operation between those two relations" do - (@relation1 << @relation2).should == LeftOuterJoinOperation.new(@relation1, @relation2) - end - end - end - - describe '[]' do - it "manufactures an attribute when given a symbol" do - @relation1[:id].should be_eql(Attribute.new(@relation1, :id)) - end - - it "manufactures a range relation when given a range" do - @relation1[1..2].should == RangeRelation.new(@relation1, 1..2) - end - end - - describe '#include?' do - it "manufactures an inclusion predicate" do - @relation1.include?(@attribute1).should == RelationInclusionPredicate.new(@attribute1, @relation1) - end - end - - describe '#project' do - it "collapses identical projections" do - pending - end - - it "manufactures a projection relation" do - @relation1.project(@attribute1, @attribute2).should == ProjectionRelation.new(@relation1, @attribute1, @attribute2) - end - end - - describe '#rename' do - it "manufactures a rename relation" do - @relation1.rename(@attribute1, :foo).should == RenameRelation.new(@relation1, @attribute1 => :foo) - end - end - - describe '#select' do - before do - @predicate = EqualityPredicate.new(@attribute1, @attribute2) - end - - it "manufactures a selection relation" do - @relation1.select(@attribute1, @attribute2).should == SelectionRelation.new(@relation1, @attribute1, @attribute2) - end - end - - describe 'order' do - it "manufactures an order relation" do - @relation1.order(@attribute1, @attribute2).should == OrderRelation.new(@relation1, @attribute1, @attribute2) - end - end -end
\ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8d90e0dd51..8f5d76370c 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,8 +1,9 @@ require 'rubygems' require 'spec' -require 'rr' -require File.join(File.dirname(__FILE__), '..', 'lib', 'sql_algebra') -require File.join(File.dirname(__FILE__), 'spec_helpers', 'be_like') +dir = File.dirname(__FILE__) +$LOAD_PATH.unshift "#{dir}/../lib" +Dir["#{dir}/matchers/*"].each { |m| require "#{dir}/matchers/#{File.basename(m)}" } +require 'active_relation' ActiveRecord::Base.configurations = { 'sql_algebra_test' => { |