rapids 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,8 +4,9 @@ module Rapids
4
4
  include Enumerable
5
5
  include ModelExtensions
6
6
 
7
- def initialize(model,find_or_creates)
8
- @hash = generate_columns_hash(model,find_or_creates)
7
+ def initialize(model,batch)
8
+ @hash = update_columns_hash(model,batch.updates)
9
+ @hash.merge!(generate_columns_hash(model,batch.find_or_creates))
9
10
  end
10
11
 
11
12
  def each(&block)
@@ -76,6 +77,17 @@ module Rapids
76
77
 
77
78
  hash
78
79
  end
80
+
81
+ def update_columns_hash(model,updates)
82
+ updates.inject({}) do |hash,update|
83
+ if model.reflections[update.name]
84
+ hash[{:type => :update, :name => update.name}] = generate_columns_hash(model.reflections[update.name].klass,[])
85
+ hash
86
+ else
87
+ hash
88
+ end
89
+ end
90
+ end
79
91
  end
80
92
  end
81
93
  end
@@ -12,11 +12,16 @@ module Rapids
12
12
  end
13
13
 
14
14
  def to_sql
15
- columns_helper = ColumnsHelper.new(@model,@batch.find_or_creates)
15
+ columns_helper = ColumnsHelper.new(@model,@batch)
16
16
  columns_sql = columns_helper.map do |column,path|
17
17
  association = nil
18
18
  model = @model
19
- path.each do |association_name|
19
+ path.each do |association_name_or_hash|
20
+ association_name = if association_name_or_hash.is_a?(Hash)
21
+ association_name_or_hash[:name]
22
+ else
23
+ association_name_or_hash
24
+ end
20
25
  if model.reflections[association_name]
21
26
  association = model.reflections[association_name]
22
27
  model = model.reflections[association_name].klass
@@ -17,7 +17,7 @@ module Rapids
17
17
  "declare #{variable_name(find_or_create.name,[])} integer;"
18
18
  end.join("\n")
19
19
 
20
- columns_helper = ColumnsHelper.new(@model,@batch.find_or_creates)
20
+ columns_helper = ColumnsHelper.new(@model,@batch)
21
21
  main_columns = columns_helper.find_all{|column,path| path == []}
22
22
 
23
23
  insert_header = (main_columns.map(&:first) + criteria_columns(@model,association_find_or_creates.map(&:name))).map{|a|sql_column_name(a,[])}
@@ -28,10 +28,11 @@ module Rapids
28
28
  begin
29
29
  #{declares}
30
30
 
31
- #{find_or_create_sql(@model,@batch.find_or_creates)}
31
+ #{find_or_create_sql(@model,@batch)}
32
32
 
33
33
  #{@options[:replace] ? "replace" : "insert"} into `#{@model.table_name}` (#{insert_header.join(",")})
34
34
  values (#{insert_values.join(",")});
35
+ #{updates_sql(@model,@batch)}
35
36
  end
36
37
  TRIGGER_SQL
37
38
  end
@@ -41,10 +42,10 @@ module Rapids
41
42
  find_or_creates.reject{|foc|model.reflections[foc.name].nil?}
42
43
  end
43
44
 
44
- def find_or_create_sql(model,find_or_creates, recursion_path = [])
45
- columns_helper = ColumnsHelper.new(model,find_or_creates)
45
+ def find_or_create_sql(model,batch,recursion_path = [])
46
+ columns_helper = ColumnsHelper.new(model,batch)
46
47
 
47
- find_or_creates.map do |find_or_create|
48
+ batch.find_or_creates.map do |find_or_create|
48
49
  name,criteria = find_or_create.name,find_or_create.find_columns
49
50
  if model.reflections[name]
50
51
  sub_model = model.reflections[name].klass
@@ -173,6 +174,22 @@ module Rapids
173
174
  end
174
175
  end
175
176
  end
177
+
178
+ def updates_sql(model,batch)
179
+ columns_helper = ColumnsHelper.new(model,batch)
180
+
181
+ batch.updates.map do |update|
182
+ association = model.reflections[update.name]
183
+ update_model = association.klass
184
+
185
+ update_columns = columns_helper.find_all{|column,path| path == update.path}.map do |pair|
186
+ column,path = *pair
187
+ "`#{column.name}` = IFNULL(new.#{sql_column_name(*pair)},`#{column.name}`)" #TODO should later add support for setting null in this update
188
+ end
189
+
190
+ "update `#{update_model.table_name}` set #{update_columns.join(",")} where `#{update_model.table_name}`.id = new.`#{association.primary_key_name}`;"
191
+ end.join("\n")
192
+ end
176
193
  end
177
194
  end
178
195
  end
@@ -14,7 +14,7 @@ module Rapids
14
14
  end
15
15
 
16
16
  def to_sql
17
- columns_helper = ColumnsHelper.new(@model,@batch.find_or_creates)
17
+ columns_helper = ColumnsHelper.new(@model,@batch)
18
18
  insert_header_sql = columns_helper.map{|column,path|sql_column_name(column,path)}.join(",")
19
19
 
20
20
  values_sql = @values.map do |row|
@@ -28,12 +28,17 @@ module Rapids
28
28
  end
29
29
  end
30
30
 
31
- specific_object = path.inject(row) do |memo,association|
32
- if memo.respond_to?(association)
33
- memo.send(association)
34
- elsif memo.is_a?(Hash) && memo[association.to_s]
35
- memo[association.to_s]
36
- elsif association.is_a?(String)
31
+ specific_object = path.inject(row) do |memo,hash_or_association_name|
32
+ association_name = if hash_or_association_name.is_a?(Hash)
33
+ hash_or_association_name[:name]
34
+ else
35
+ hash_or_association_name
36
+ end
37
+ if memo.respond_to?(association_name)
38
+ memo.send(association_name)
39
+ elsif memo.is_a?(Hash) && memo[association_name.to_s]
40
+ memo[association_name.to_s]
41
+ elsif association_name.is_a?(String)
37
42
  memo
38
43
  end
39
44
  end
@@ -10,8 +10,20 @@ module Rapids
10
10
  end
11
11
 
12
12
  def sql_column_name(column,hash_path)
13
- prefix = hash_path.empty? ? "" : "foc$"
14
- association_list = (hash_path + [column.name]).map(&:to_s).join("$")
13
+ prefix = if hash_path.empty?
14
+ ""
15
+ elsif path_type = hash_path.first and path_type.is_a?(Hash) and path_type[:type] == :update
16
+ "update$"
17
+ else
18
+ "foc$"
19
+ end
20
+ association_list = (hash_path + [column.name]).map do |path_type|
21
+ if path_type.is_a?(Hash)
22
+ path_type[:name]
23
+ else
24
+ path_type.to_s
25
+ end
26
+ end.join("$")
15
27
  "`#{prefix+association_list}`"
16
28
  end
17
29
 
@@ -0,0 +1,15 @@
1
+ module Rapids
2
+ module Batch
3
+ class Update
4
+ attr_reader :name
5
+
6
+ def initialize(name)
7
+ @name = name
8
+ end
9
+
10
+ def path
11
+ [{:type => :update, :name => name}]
12
+ end
13
+ end
14
+ end
15
+ end
data/lib/rapids/batch.rb CHANGED
@@ -2,19 +2,25 @@ require 'rapids/batch/create_table'
2
2
  require 'rapids/batch/insert_into'
3
3
  require 'rapids/batch/create_trigger'
4
4
  require 'rapids/batch/find_or_create'
5
+ require 'rapids/batch/update'
5
6
 
6
7
  module Rapids
7
8
  module Batch
8
9
  class DefineBatch
9
- attr_reader :find_or_creates
10
+ attr_reader :find_or_creates, :updates
10
11
 
11
12
  def initialize
12
13
  @find_or_creates = []
14
+ @updates = []
13
15
  end
14
16
 
15
17
  def find_or_create(name,find_columns,*fill_columns_plus_other_params)
16
18
  @find_or_creates << FindOrCreate.new(name,find_columns,fill_columns_plus_other_params.first)
17
19
  end
20
+
21
+ def update(name)
22
+ @updates << Update.new(name)
23
+ end
18
24
  end
19
25
 
20
26
  def batch_create(collection,options = {})
@@ -1,3 +1,3 @@
1
1
  module Rapids
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -3,20 +3,23 @@ require 'batch/spec_helper'
3
3
  module Rapids::Batch
4
4
  describe ColumnsHelper do
5
5
  it "should intialize with an empty find or create list" do
6
- ColumnsHelper.new(Post,[])
6
+ batch = Rapids::Batch::DefineBatch.new
7
+ ColumnsHelper.new(Post,batch)
7
8
  end
8
9
 
9
10
  it "should initialize with the association find or create" do
10
- find_or_creates = [FindOrCreate.new(:author,[:name],[])]
11
- columns_helper = ColumnsHelper.new(Post,find_or_creates)
11
+ batch = Rapids::Batch::DefineBatch.new
12
+ batch.find_or_create(:author,[:name])
13
+ columns_helper = ColumnsHelper.new(Post,batch)
12
14
 
13
15
  columns_helper.map{|a|a.first.name}.include?("name").should be_true
14
16
  columns_helper.map{|a|a.first.name}.include?("author_id").should be_false, "expected author_id not to be present in this list:\n#{columns_helper.to_a.inspect}"
15
17
  end
16
18
 
17
19
  it "should initialize with the manual find or create format" do
18
- find_or_creates = [FindOrCreate.new("Category",[:category],[])]
19
- columns_helper = ColumnsHelper.new(Post,find_or_creates)
20
+ batch = Rapids::Batch::DefineBatch.new
21
+ batch.find_or_create("Category",[:category])
22
+ columns_helper = ColumnsHelper.new(Post,batch)
20
23
 
21
24
  columns_helper.any? do |pair|
22
25
  column,path = *pair
@@ -25,13 +28,25 @@ module Rapids::Batch
25
28
  end
26
29
 
27
30
  it "should initialize with the association find or create with a has_many find or create" do
28
- find_or_creates = [FindOrCreate.new(:post,[:name,{:post_tags => [:tag_id]}],[])]
29
- columns_helper = ColumnsHelper.new(Comment,find_or_creates)
31
+ batch = Rapids::Batch::DefineBatch.new
32
+ batch.find_or_create(:post,[:name,{:post_tags => [:tag_id]}])
33
+ columns_helper = ColumnsHelper.new(Comment,batch)
30
34
 
31
35
  columns_helper.any? do |pair|
32
36
  column,path = *pair
33
37
  column.name == "tag_id" && path == [:post,:post_tags]
34
38
  end.should be_true, "expected to find a column named 'tag_id' and the path to be [:post,:post_tags] in the following:\n#{columns_helper.to_a.inspect}"
35
39
  end
40
+
41
+ it "should initialize with the update definition and have the appropriate columns" do
42
+ batch = Rapids::Batch::DefineBatch.new
43
+ batch.update(:author)
44
+ columns_helper = ColumnsHelper.new(Post,batch)
45
+
46
+ columns_helper.any? do |pair|
47
+ column,path = *pair
48
+ column.name == "name" && path == [{:type => :update,:name => :author}]
49
+ end.should be_true, "expected to find a column named 'name' and the path to be [{:type => :update,:name => :author}] in the following:\n#{columns_helper.to_a.inspect}"
50
+ end
36
51
  end
37
52
  end
@@ -40,5 +40,13 @@ module Rapids::Batch
40
40
  create_table = CreateTable.new(Comment,batch)
41
41
  create_table.to_sql.should == "CREATE TABLE `$comments_batch` (`body` varchar(255),`foc$post$author_id` int(11),`foc$post$category` varchar(255),`foc$post$name` varchar(255),`foc$post$post_tags$tag_id` varchar(255),`title` varchar(255)) ENGINE=BLACKHOLE DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"
42
42
  end
43
+
44
+ it "should generate sql for a update definition" do
45
+ batch = Rapids::Batch::DefineBatch.new
46
+ batch.update(:author)
47
+
48
+ create_table = CreateTable.new(Post,batch)
49
+ create_table.to_sql.should == "CREATE TABLE `$posts_batch` (`author_id` int(11),`category` varchar(255),`name` varchar(255),`update$author$name` varchar(255)) ENGINE=BLACKHOLE DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci"
50
+ end
43
51
  end
44
52
  end
@@ -39,5 +39,13 @@ module Rapids::Batch
39
39
  create_trigger = CreateTrigger.new(Category,batch,:replace => true)
40
40
  clean_sql(create_trigger.to_sql).should == "create trigger `$categories_batch_trigger` after insert on `$categories_batch` for each row\nbegin\nreplace into `categories` (`category`)\nvalues (new.`category`);\nend"
41
41
  end
42
+
43
+ it "should generate sql for a basic definition" do
44
+ batch = Rapids::Batch::DefineBatch.new
45
+ batch.update(:author)
46
+
47
+ create_trigger = CreateTrigger.new(Post,batch)
48
+ clean_sql(create_trigger.to_sql).should == "create trigger `$posts_batch_trigger` after insert on `$posts_batch` for each row\nbegin\ninsert into `posts` (`author_id`,`category`,`name`)\nvalues (new.`author_id`,new.`category`,new.`name`);\nupdate `authors` set `name` = IFNULL(new.`update$author$name`,`name`) where `authors`.id = new.`author_id`;\nend"
49
+ end
42
50
  end
43
51
  end
@@ -49,6 +49,15 @@ module Rapids::Batch
49
49
  clean_sql(insert_into.to_sql).should == "INSERT INTO `$categories_batch` (`category`) VALUES ('food'),('politics')"
50
50
  end
51
51
 
52
+ it "should generate sql for an update definition" do
53
+ batch = Rapids::Batch::DefineBatch.new
54
+ batch.update(:author)
55
+ collection = [Post.new(:name => "Dining at 323 Butter St",:category => "food",:author_id => 1,:author => Author.new(:name => "Joe"))]
56
+
57
+ insert_into = InsertInto.new(Post,batch,collection)
58
+ clean_sql(insert_into.to_sql).should == "INSERT INTO `$posts_batch` (`author_id`,`category`,`name`,`update$author$name`) VALUES (1,'food','Dining at 323 Butter St','Joe')"
59
+ end
60
+
52
61
  describe "Without model objects" do
53
62
  it "should generate sql for a simple batch definition" do
54
63
  batch = Rapids::Batch::DefineBatch.new
@@ -95,6 +104,15 @@ module Rapids::Batch
95
104
  create_table = InsertInto.new(Comment,batch,collection)
96
105
  create_table.to_sql.should == "INSERT INTO `$comments_batch` (`body`,`foc$post$author_id`,`foc$post$category`,`foc$post$name`,`foc$post$post_tags$tag_id`,`title`) VALUES ('Im a troll',NULL,NULL,'I just did something cool','1,2','You suck')"
97
106
  end
107
+
108
+ it "should generate sql for an update definition" do
109
+ batch = Rapids::Batch::DefineBatch.new
110
+ batch.update(:author)
111
+ collection = [{"name" => "Dining at 323 Butter St","category" => "food","author_id" => 1,"author" => {"name" => "Joe"}}]
112
+
113
+ insert_into = InsertInto.new(Post,batch,collection)
114
+ clean_sql(insert_into.to_sql).should == "INSERT INTO `$posts_batch` (`author_id`,`category`,`name`,`update$author$name`) VALUES (1,'food','Dining at 323 Butter St','Joe')"
115
+ end
98
116
  end
99
117
  end
100
118
  end
@@ -0,0 +1,15 @@
1
+ require 'batch/spec_helper'
2
+
3
+ module Rapids::Batch
4
+ describe Update do
5
+ it "should initialize with a name and the name should be retrievable" do
6
+ u = Update.new(:hello)
7
+ u.name.should == :hello
8
+ end
9
+
10
+ it "should give me it's path hash" do
11
+ u = Update.new(:hello)
12
+ u.path.should == [{:type => :update, :name => :hello}]
13
+ end
14
+ end
15
+ end
@@ -2,6 +2,12 @@ require 'spec_helper'
2
2
 
3
3
  class RapidsBatchTestCase < ActiveRecord::Base
4
4
  extend Rapids::Batch
5
+
6
+ belongs_to :a_belongs_to
7
+
8
+ batch do
9
+ update :a_belongs_to
10
+ end
5
11
  end
6
12
 
7
13
  describe Rapids::Batch do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rapids
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 1
9
- - 3
10
- version: 0.1.3
9
+ - 4
10
+ version: 0.1.4
11
11
  platform: ruby
12
12
  authors:
13
13
  - James Smith
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-08-26 00:00:00 -04:00
18
+ date: 2011-08-31 00:00:00 -04:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -89,6 +89,7 @@ files:
89
89
  - lib/rapids/batch/find_or_create.rb
90
90
  - lib/rapids/batch/insert_into.rb
91
91
  - lib/rapids/batch/model_extensions.rb
92
+ - lib/rapids/batch/update.rb
92
93
  - lib/rapids/version.rb
93
94
  - rapids.gemspec
94
95
  - spec/batch/columns_helper_spec.rb
@@ -96,6 +97,7 @@ files:
96
97
  - spec/batch/create_trigger_spec.rb
97
98
  - spec/batch/insert_into_spec.rb
98
99
  - spec/batch/spec_helper.rb
100
+ - spec/batch/update_spec.rb
99
101
  - spec/rapids_batch_spec.rb
100
102
  - spec/spec_helper.rb
101
103
  has_rdoc: true
@@ -140,5 +142,6 @@ test_files:
140
142
  - spec/batch/create_trigger_spec.rb
141
143
  - spec/batch/insert_into_spec.rb
142
144
  - spec/batch/spec_helper.rb
145
+ - spec/batch/update_spec.rb
143
146
  - spec/rapids_batch_spec.rb
144
147
  - spec/spec_helper.rb