crewait 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.
Files changed (6) hide show
  1. data/Manifest +4 -0
  2. data/README.rdoc +25 -0
  3. data/Rakefile +15 -0
  4. data/crewait.gemspec +30 -0
  5. data/lib/crewait.rb +116 -0
  6. metadata +65 -0
data/Manifest ADDED
@@ -0,0 +1,4 @@
1
+ Manifest
2
+ README.rdoc
3
+ Rakefile
4
+ lib/crewait.rb
data/README.rdoc ADDED
@@ -0,0 +1,25 @@
1
+ = Crewait
2
+
3
+ Check out http://jonah.org/articles/crewait_go_.html for a guide to Crewait.
4
+
5
+ == License
6
+
7
+ Copyright (c) 2009 Jonah Bloch-Johnson
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in
17
+ all copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,15 @@
1
+ # Rakefile
2
+ require 'rubygems'
3
+ require 'rake'
4
+ require 'echoe'
5
+
6
+ Echoe.new('crewait', '0.1.0') do |p|
7
+ p.description = "Intuitive and fast bulk insertion in ActiveRecord"
8
+ p.url = "http://github.com/theAlmanac/crewait"
9
+ p.author = "Jonah Bloch-Johnson"
10
+ p.email = "me@jonah.org"
11
+ # p.ignore_pattern = ["tmp/*", "script/*"]
12
+ p.development_dependencies = []
13
+ end
14
+
15
+ Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
data/crewait.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{crewait}
5
+ s.version = "0.1.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Jonah Bloch-Johnson"]
9
+ s.date = %q{2010-01-07}
10
+ s.description = %q{Intuitive and fast bulk insertion in ActiveRecord}
11
+ s.email = %q{me@jonah.org}
12
+ s.extra_rdoc_files = ["README.rdoc", "lib/crewait.rb"]
13
+ s.files = ["Manifest", "README.rdoc", "Rakefile", "lib/crewait.rb", "crewait.gemspec"]
14
+ s.homepage = %q{http://github.com/theAlmanac/crewait}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Crewait", "--main", "README.rdoc"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{crewait}
18
+ s.rubygems_version = %q{1.3.5}
19
+ s.summary = %q{Intuitive and fast bulk insertion in ActiveRecord}
20
+
21
+ if s.respond_to? :specification_version then
22
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
23
+ s.specification_version = 3
24
+
25
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
26
+ else
27
+ end
28
+ else
29
+ end
30
+ end
data/lib/crewait.rb ADDED
@@ -0,0 +1,116 @@
1
+ # Crewait is a tool for ActiveRecord for mass-importing of data.
2
+ # The idea is the you start a Crewait session, you use ActiveRecord::Base#crewait instead of #create, and then at some point you tell it to go!, which bulk inserts all those created records into SQL.
3
+ module Crewait
4
+
5
+ def self.start_waiting
6
+ # clear our all important hash caches
7
+ @@hash_of_hashes = {}
8
+ @@hash_of_next_inserts = {}
9
+ end
10
+
11
+ # add one crewait instance
12
+ def self.for(model, hash)
13
+ table_name = model.table_name
14
+ # if this class is new, add in the next_insert_value
15
+ @@hash_of_next_inserts[table_name] ||= model.next_insert_id
16
+ # if this class is new, create a new hash to receive it
17
+ @@hash_of_hashes[table_name] ||= {}
18
+ @@hash_of_hashes[table_name].respectively_insert(hash)
19
+ # add dummy methods
20
+ fake_id = @@hash_of_next_inserts[table_name] + @@hash_of_hashes[table_name].inner_length - 1
21
+ eigenclass = class << hash; self; end
22
+ eigenclass.class_eval {
23
+ define_method(:id) { fake_id }
24
+ hash.each do |key, value|
25
+ define_method(key) { value }
26
+ end
27
+ }
28
+ hash
29
+ end
30
+
31
+ def self.go!
32
+ @@hash_of_hashes.each do |key, hash|
33
+ hash.import_to_sql(eval(key.classify))
34
+ end
35
+ @@hash_of_hashes = {}
36
+ @@hash_of_next_inserts = {}
37
+ end
38
+
39
+ module BaseMethods
40
+ def next_insert_id
41
+ database = YAML.load(open(File.join('config', 'database.yml')))[RAILS_ENV]['database']
42
+ ActiveRecord::Base.connection.execute( "
43
+ SELECT auto_increment
44
+ FROM information_schema.tables
45
+ WHERE table_name='#{self.table_name}' AND
46
+ table_schema ='#{database}'
47
+ " ).fetch_hash['auto_increment'].to_i
48
+ end
49
+
50
+ def crewait(hash)
51
+ stay_a_hash = hash.delete(:stay_a_hash)
52
+ unless stay_a_hash
53
+ Crewait.for(self, hash)
54
+ else
55
+ object = self.new(hash)
56
+ object.before_validation
57
+ Crewait.for(object.class, object.attributes)
58
+ end
59
+ end
60
+ end
61
+
62
+ module HashMethods
63
+ def import_to_sql(model_class)
64
+ if model_class.respond_to? :table_name
65
+ model_class = model_class.table_name
66
+ end
67
+ keys = self.keys
68
+ values = []
69
+ keys.each do |key|
70
+ values << (self[key].any? {|x| x != true} ? self[key] : self[key].collect {|x| 1})
71
+ end
72
+ values = values.transpose
73
+ sql = values.to_sql
74
+
75
+ while !sql.empty? do
76
+ query_string = "insert into #{model_class} (#{keys.join(', ')}) values #{sql.shift}"
77
+ while !sql.empty? && (query_string.length + sql.last.length < 999_999) do
78
+ query_string << ',' << sql.shift
79
+ end
80
+ ActiveRecord::Base.connection.execute(query_string)
81
+ end
82
+ end
83
+ # this was originally called "<<", but changed for namespacing
84
+ def respectively_insert(other_hash)
85
+ new_keys = other_hash.keys - self.keys
86
+ length = new_keys.empty? ? 0 : self.inner_length
87
+ new_keys.each do |key|
88
+ self[key] = Array.new(length)
89
+ end
90
+ self.keys.each do |key|
91
+ self[key] << other_hash[key]
92
+ end
93
+ end
94
+ def inner_length
95
+ !self.values.empty? ? self.values.first.length : 0
96
+ end
97
+ end
98
+
99
+ module ArrayMethods
100
+ def to_sql
101
+ self.collect {|x| "(#{x.collect{|x| x.nil? ? 'NULL' : "#{ActiveRecord::Base.sanitize(x)}"}.join(', ')})" }
102
+ end
103
+ end
104
+ end
105
+
106
+ class ActiveRecord::Base
107
+ extend Crewait::BaseMethods
108
+ end
109
+
110
+ class Hash
111
+ include Crewait::HashMethods
112
+ end
113
+
114
+ class Array
115
+ include Crewait::ArrayMethods
116
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: crewait
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jonah Bloch-Johnson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-07 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Intuitive and fast bulk insertion in ActiveRecord
17
+ email: me@jonah.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.rdoc
24
+ - lib/crewait.rb
25
+ files:
26
+ - Manifest
27
+ - README.rdoc
28
+ - Rakefile
29
+ - lib/crewait.rb
30
+ - crewait.gemspec
31
+ has_rdoc: true
32
+ homepage: http://github.com/theAlmanac/crewait
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options:
37
+ - --line-numbers
38
+ - --inline-source
39
+ - --title
40
+ - Crewait
41
+ - --main
42
+ - README.rdoc
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "1.2"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project: crewait
60
+ rubygems_version: 1.3.5
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Intuitive and fast bulk insertion in ActiveRecord
64
+ test_files: []
65
+