iain-fill 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Manifest +7 -0
- data/README.rdoc +83 -0
- data/Rakefile +13 -0
- data/fill.gemspec +30 -0
- data/lib/fill.rb +26 -0
- data/lib/fill/configure.rb +69 -0
- data/lib/fill/presenter.rb +52 -0
- data/lib/fill/procedure.rb +48 -0
- metadata +70 -0
data/Manifest
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
= Fill
|
2
|
+
|
3
|
+
Rails 2.3.4 introduced db/seeds. Basically that means that the rake task
|
4
|
+
"rake db:seed" will run db/seeds.rb, so you can have a centralized place
|
5
|
+
to prepare your database by adding seed data.
|
6
|
+
|
7
|
+
"Fill" takes this one step further and provides methods to easily define
|
8
|
+
data in db/seeds.rb. Here's how:
|
9
|
+
|
10
|
+
Fill.database do |db|
|
11
|
+
|
12
|
+
db.produce :projects do
|
13
|
+
10.times { Factory(:project) }
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
(I use factory_girl here, do whatever you like off course)
|
19
|
+
|
20
|
+
Now, when running "rake db:seed", it'll delete all records in the Project
|
21
|
+
model and run the contents off the produce block. It'll also measure how
|
22
|
+
long it took, resulting in this output:
|
23
|
+
|
24
|
+
+-------+--------+---------+----------+
|
25
|
+
| After | Before | Models | Time |
|
26
|
+
+-------+--------+---------+----------+
|
27
|
+
| 10 | 0 | Project | 0.018627 |
|
28
|
+
+-------+--------+---------+----------+
|
29
|
+
|
30
|
+
== Why?
|
31
|
+
|
32
|
+
At my company, we taught testers, customers and developers to use
|
33
|
+
webistrano and run the db:seed" rake task themselves. This way, they can
|
34
|
+
test and experiment as much as they want, and they easily reset the
|
35
|
+
database when they fucked it up.
|
36
|
+
|
37
|
+
== Usage
|
38
|
+
|
39
|
+
=== db.produce
|
40
|
+
|
41
|
+
By specifying a block, do whatever you need to fill a model.
|
42
|
+
|
43
|
+
Usage: db.produce :model1, :model2 do ... end
|
44
|
+
|
45
|
+
Specify the models that you want. The models that you specified will be
|
46
|
+
emptied, which is handy if you're building relational models, like users
|
47
|
+
and their memberships.
|
48
|
+
|
49
|
+
=== db.fill
|
50
|
+
|
51
|
+
A simple list of values.
|
52
|
+
|
53
|
+
Usage: db.fill :model, :attribute, "value 1", "value 2", "value 3"
|
54
|
+
|
55
|
+
For simple models with only one distinct attribute, you can just specify
|
56
|
+
the model, attribute and the values.
|
57
|
+
|
58
|
+
See also the iain/root_table plugin if you have many of these.
|
59
|
+
|
60
|
+
=== db.invoke
|
61
|
+
|
62
|
+
Invoke a rake task.
|
63
|
+
|
64
|
+
Usage: db.invoke "some:task", :model
|
65
|
+
|
66
|
+
=== Global options
|
67
|
+
|
68
|
+
* :needs specify one or many dependencies, tables to be filled before
|
69
|
+
filling the ones you're specifying now.
|
70
|
+
* :delete set to false if you don't want to delete all records before
|
71
|
+
continuing
|
72
|
+
|
73
|
+
== Installation
|
74
|
+
|
75
|
+
Add this to config/environment.rb:
|
76
|
+
|
77
|
+
config.gem "iain-fill", :lib => "fill", :source => "http://gems.github.com"
|
78
|
+
|
79
|
+
And run "rake gems:install" and you're done.
|
80
|
+
|
81
|
+
---
|
82
|
+
|
83
|
+
Made by Iain, Released under the MIT License
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
|
4
|
+
require 'echoe'
|
5
|
+
Echoe.new('fill', '0.0.1') do |p|
|
6
|
+
p.description = "Fill your database"
|
7
|
+
p.url = "http://iain.nl"
|
8
|
+
p.author = "iain"
|
9
|
+
p.email = "iain@iain.nl"
|
10
|
+
p.ignore_pattern = []
|
11
|
+
p.development_dependencies = []
|
12
|
+
p.runtime_dependencies = []
|
13
|
+
end
|
data/fill.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{fill}
|
5
|
+
s.version = "0.0.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["iain"]
|
9
|
+
s.date = %q{2009-09-21}
|
10
|
+
s.description = %q{Fill your database}
|
11
|
+
s.email = %q{iain@iain.nl}
|
12
|
+
s.extra_rdoc_files = ["README.rdoc", "lib/fill.rb", "lib/fill/configure.rb", "lib/fill/presenter.rb", "lib/fill/procedure.rb"]
|
13
|
+
s.files = ["README.rdoc", "Rakefile", "lib/fill.rb", "lib/fill/configure.rb", "lib/fill/presenter.rb", "lib/fill/procedure.rb", "Manifest", "fill.gemspec"]
|
14
|
+
s.homepage = %q{http://iain.nl}
|
15
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Fill", "--main", "README.rdoc"]
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubyforge_project = %q{fill}
|
18
|
+
s.rubygems_version = %q{1.3.5}
|
19
|
+
s.summary = %q{Fill your database}
|
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/fill.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'activesupport'
|
2
|
+
require 'fill/configure'
|
3
|
+
require 'fill/presenter'
|
4
|
+
require 'fill/procedure'
|
5
|
+
|
6
|
+
module Fill
|
7
|
+
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def database
|
11
|
+
db = Configure.new
|
12
|
+
yield db
|
13
|
+
bm = time { db.perform! }
|
14
|
+
puts Presenter
|
15
|
+
puts "Database filled in %.2f seconds" % bm
|
16
|
+
end
|
17
|
+
|
18
|
+
def time
|
19
|
+
started_at = Time.now
|
20
|
+
yield
|
21
|
+
Time.now - started_at
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Fill
|
2
|
+
|
3
|
+
class Configure
|
4
|
+
|
5
|
+
def produce(*models, &block)
|
6
|
+
options = models.extract_options!
|
7
|
+
needs = options.delete(:needs) || []
|
8
|
+
register models, Procedure.new(models, options, &block)
|
9
|
+
dependent models, needs
|
10
|
+
end
|
11
|
+
|
12
|
+
def fill(model, field, *values)
|
13
|
+
options = values.extract_options!
|
14
|
+
self.produce model, options do
|
15
|
+
values.each do |value|
|
16
|
+
model.to_s.singularize.camelize.constantize.create!(field => value)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def invoke(task, *models)
|
22
|
+
self.produce *models do
|
23
|
+
Rake::Task[task].invoke
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def environment(env, which, options = {})
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def perform!
|
32
|
+
registered.each_key { |model| perform(model) }
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def results
|
38
|
+
results = registered.values.uniq.compact.map { |data| data.to_hash }
|
39
|
+
end
|
40
|
+
|
41
|
+
def perform(model)
|
42
|
+
raise "No fill data provided for #{model}" unless registered.has_key? model
|
43
|
+
dependencies[model].each { |dep| perform(dep) } if dependencies.has_key? model
|
44
|
+
registered[model].perform!
|
45
|
+
end
|
46
|
+
|
47
|
+
def register(models, data)
|
48
|
+
models.each do |model|
|
49
|
+
registered.update model => data
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def dependent(models, dependent)
|
54
|
+
models.each do |model|
|
55
|
+
dependencies.update model => [dependent].flatten
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def registered
|
60
|
+
@registered ||= {}
|
61
|
+
end
|
62
|
+
|
63
|
+
def dependencies
|
64
|
+
@dependencies ||= {}
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Fill
|
2
|
+
|
3
|
+
class Presenter
|
4
|
+
|
5
|
+
def self.present(data)
|
6
|
+
presenter.add(data)
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.presenter
|
10
|
+
@presenter ||= new
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.to_s
|
14
|
+
presenter.to_s
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(data)
|
18
|
+
presented.push(data) if data && !presented.include?(data)
|
19
|
+
end
|
20
|
+
|
21
|
+
def hirb?
|
22
|
+
require 'hirb'
|
23
|
+
true
|
24
|
+
rescue LoadError
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
def presented
|
29
|
+
@presented ||= []
|
30
|
+
end
|
31
|
+
|
32
|
+
def presentable
|
33
|
+
presented.map(&:to_hash)
|
34
|
+
end
|
35
|
+
|
36
|
+
def present_with_hirb
|
37
|
+
Hirb::Helpers::Table.render(presentable, :description => false)
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
hirb? ? present_with_hirb : present_hash.join("\n")
|
42
|
+
end
|
43
|
+
|
44
|
+
def present_hash
|
45
|
+
hash.map do |row|
|
46
|
+
row.map { |key, value| "#{key}: #{value}" }.join(" - ")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Fill
|
2
|
+
|
3
|
+
class Procedure
|
4
|
+
|
5
|
+
attr_accessor :block
|
6
|
+
|
7
|
+
def initialize(models, options = {}, &block)
|
8
|
+
@block = block
|
9
|
+
@options = { :delete => true }.merge(options)
|
10
|
+
@models = models
|
11
|
+
end
|
12
|
+
|
13
|
+
def perform!
|
14
|
+
@performed ||= perform
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_hash
|
18
|
+
{ "Models" => human_models, "Before" => @before.join(', '), "After" => @after.join(', '), "Time" => @time }
|
19
|
+
end
|
20
|
+
|
21
|
+
def human_models
|
22
|
+
@options[:name] ||
|
23
|
+
models.map { |model| model.respond_to?(:human_name) ? model.human_name : model.to_s }.join(', ')
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete_all
|
27
|
+
models.each { |model| model.delete_all } if @options[:delete]
|
28
|
+
end
|
29
|
+
|
30
|
+
def models
|
31
|
+
@models.map { |model| model.to_s.singularize.camelize.constantize }
|
32
|
+
end
|
33
|
+
|
34
|
+
def count
|
35
|
+
models.map { |model| model.count }
|
36
|
+
end
|
37
|
+
|
38
|
+
def perform
|
39
|
+
@before = count
|
40
|
+
@time = Fill.time { self.delete_all; block.call }
|
41
|
+
@after = count
|
42
|
+
Presenter.present self
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: iain-fill
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- iain
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-09-21 00:00:00 -07:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: Fill your database
|
17
|
+
email: iain@iain.nl
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README.rdoc
|
24
|
+
- lib/fill.rb
|
25
|
+
- lib/fill/configure.rb
|
26
|
+
- lib/fill/presenter.rb
|
27
|
+
- lib/fill/procedure.rb
|
28
|
+
files:
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- lib/fill.rb
|
32
|
+
- lib/fill/configure.rb
|
33
|
+
- lib/fill/presenter.rb
|
34
|
+
- lib/fill/procedure.rb
|
35
|
+
- Manifest
|
36
|
+
- fill.gemspec
|
37
|
+
has_rdoc: false
|
38
|
+
homepage: http://iain.nl
|
39
|
+
licenses:
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --line-numbers
|
43
|
+
- --inline-source
|
44
|
+
- --title
|
45
|
+
- Fill
|
46
|
+
- --main
|
47
|
+
- README.rdoc
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: "0"
|
55
|
+
version:
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "1.2"
|
61
|
+
version:
|
62
|
+
requirements: []
|
63
|
+
|
64
|
+
rubyforge_project: fill
|
65
|
+
rubygems_version: 1.3.5
|
66
|
+
signing_key:
|
67
|
+
specification_version: 3
|
68
|
+
summary: Fill your database
|
69
|
+
test_files: []
|
70
|
+
|