merb_seed 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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Michael Bleigh, released under the MIT license
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,102 @@
1
+ merb_seed
2
+ =======
3
+
4
+ merb_seed is an attempt to once and for all solve the problem of inserting and
5
+ maintaining seed data in a database. It uses a variety of techniques gathered
6
+ from various places around the web and combines them to create what is
7
+ hopefully the most robust seed data system around.
8
+
9
+
10
+ Support
11
+ =======
12
+
13
+ merb_seed 0.1 currently only supports datamapper. ActiveRecord and Sequel support
14
+
15
+
16
+ Usage
17
+ =======
18
+
19
+ rake db:seed
20
+
21
+
22
+ Setting up Seed Data
23
+ =======
24
+ Seed data is taken from the schema/data directory. Simply make descriptive .rb
25
+ files in that directory (they can be named anything, but users.rb for the User
26
+ model seed data makes sense, etc.). These scripts will be run whenever the
27
+ db:seed rake task is called. You can put arbitrary Ruby code in these files,
28
+ but remember that it will be executed every time the rake task is called, so
29
+ it needs to be runnable multiple times on the same database.
30
+
31
+ You can also have environment-specific seed data placed in
32
+ schema/data/ENVIRONMENT that will only be loaded if that is the current
33
+ environment.
34
+
35
+ Let's say we want to populate a few default users. In schema/data/users.rb we
36
+ write the following code:
37
+
38
+ User.seed(:login, :email) do |s|
39
+ s.login = "bob"
40
+ s.email = "bob@bobson.com"
41
+ s.first_name = "Bob"
42
+ s.last_name = "Bobson"
43
+ end
44
+
45
+ User.seed(:login, :email) do |s|
46
+ s.login = "bob"
47
+ s.email = "bob@stevenson.com"
48
+ s.first_name = "Bob"
49
+ s.last_name = "Stevenson"
50
+ end
51
+
52
+ That's all you have to do! You will now have two users created in the system
53
+ and you can change their first and last names in the users.rb file and it will
54
+ be updated as such.
55
+
56
+ The arguments passed to the <ActiveRecord>.seed method are the constraining
57
+ attributes: these must remain unchanged between db:seed calls to avoid data
58
+ duplication. By default, seed data will constrain to the id like so:
59
+
60
+ Category.seed do |s|
61
+ s.id = 1
62
+ s.name = "Buttons"
63
+ end
64
+
65
+ Category.seed do |s|
66
+ s.id = 2
67
+ s.name = "Bobbins"
68
+ s.parent_id = 1
69
+ end
70
+
71
+ Note that any constraints that are passed in must be present in the subsequent
72
+ seed data setting.
73
+
74
+
75
+ Callbacks
76
+ =======
77
+
78
+ Seed data can also define callbacks that will run after the record is created
79
+
80
+ Category.seed do |s|
81
+ s.id = 2
82
+ s.name = "Bobbins"
83
+ s.parent_id = 1
84
+
85
+ # run code after creation (record is the newly created model)
86
+ s.after_seed do |record|
87
+ record.enable!
88
+ end
89
+ end
90
+
91
+ Source Code
92
+ =======
93
+
94
+ Need a change? Help out by forking and doing a pull request. I'll merge in any new features or bug fixes that you make.
95
+ http://github.com/merbjedi/merb_seed
96
+
97
+
98
+ Seed Fu
99
+ =======
100
+ merb_seed is a port of seed-fu to Merb
101
+
102
+ http://github.com/mbleigh/seed-fu
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake/gempackagetask'
3
+
4
+ require 'merb-core'
5
+ require 'merb-core/tasks/merb'
6
+
7
+ GEM_NAME = "merb_seed"
8
+ GEM_VERSION = "0.1.0"
9
+ AUTHOR = "Jacques Crocker"
10
+ EMAIL = "merbjedi@gmil.com"
11
+ HOMEPAGE = "http://merbjedi.com/"
12
+ SUMMARY = "Merb plugin that provides RAKE tasks to easily initialize seed data in your database"
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.rubyforge_project = 'merb'
16
+ s.name = GEM_NAME
17
+ s.version = GEM_VERSION
18
+ s.platform = Gem::Platform::RUBY
19
+ s.has_rdoc = true
20
+ s.extra_rdoc_files = ["README", "LICENSE"]
21
+ s.summary = SUMMARY
22
+ s.description = s.summary
23
+ s.author = AUTHOR
24
+ s.email = EMAIL
25
+ s.homepage = HOMEPAGE
26
+
27
+ # todo: allow merb_seed to support activerecord and sequel
28
+ s.add_dependency('merb_datamapper', '>= 1.0.8')
29
+
30
+ s.require_path = 'lib'
31
+ s.files = %w(LICENSE README Rakefile) + Dir.glob("{lib,spec}/**/*")
32
+
33
+ end
34
+
35
+ Rake::GemPackageTask.new(spec) do |pkg|
36
+ pkg.gem_spec = spec
37
+ end
38
+
39
+ desc "install the plugin as a gem"
40
+ task :install do
41
+ Merb::RakeHelper.install(GEM_NAME, :version => GEM_VERSION)
42
+ end
43
+
44
+ desc "Uninstall the gem"
45
+ task :uninstall do
46
+ Merb::RakeHelper.uninstall(GEM_NAME, :version => GEM_VERSION)
47
+ end
48
+
49
+ desc "Create a gemspec file"
50
+ task :gemspec do
51
+ File.open("#{GEM_NAME}.gemspec", "w") do |file|
52
+ file.puts spec.to_ruby
53
+ end
54
+ end
data/lib/merb_seed.rb ADDED
@@ -0,0 +1,19 @@
1
+ # make sure we're running inside Merb
2
+ if defined?(Merb::Plugins)
3
+
4
+ # Merb gives you a Merb::Plugins.config hash...feel free to put your stuff in your piece of it
5
+ Merb::Plugins.config[:merb_seed] = {
6
+ :seed_path => "schema/data"
7
+ }
8
+
9
+ Merb::BootLoader.before_app_loads do
10
+ # require code that must be loaded before the application
11
+ end
12
+
13
+ Merb::BootLoader.after_app_loads do
14
+ # code that can be required after the application loads
15
+ end
16
+
17
+ Merb::Plugins.add_rakefiles "merb_seed/merbtasks"
18
+ end
19
+
@@ -0,0 +1,24 @@
1
+ namespace :db do
2
+ desc "Loads seed data from schema/data for the current environment."
3
+ task :seed => :merb_env do
4
+ require File.join( File.dirname(__FILE__), "seeder")
5
+
6
+ # load ruby seed files
7
+ seed_path = ENV["SEED_PATH"] ? ENV["SEED_PATH"] : (Merb::Plugins.config[:merb_seed][:seed_path] || "schema/data")
8
+ Dir[File.join(Merb.root, seed_path, '*.rb')].sort.each { |seed|
9
+ puts "\n== Seeding from #{File.split(seed).last} " + ("=" * (60 - (17 + File.split(seed).last.length)))
10
+ load seed
11
+ puts "=" * 60 + "\n"
12
+ }
13
+
14
+ # load environment specific seed files
15
+ Dir[File.join(Merb.root, seed_path, Merb.env, '*.rb')].sort.each { |seed|
16
+ puts "\n== [#{Merb.env}] Seeding from #{File.split(seed).last} " + ("=" * (60 - (20 + File.split(seed).last.length + Merb.env.length)))
17
+ load seed
18
+ puts "=" * 60 + "\n"
19
+ }
20
+
21
+ # load seed files from yml
22
+ # TODO
23
+ end
24
+ end
@@ -0,0 +1 @@
1
+ # TODO
@@ -0,0 +1,27 @@
1
+ require 'datamapper'
2
+
3
+ module DataMapper::Model
4
+ # Creates a single record of seed data for use
5
+ # with the db:seed rake task.
6
+ #
7
+ # === Parameters
8
+ # constraints :: Immutable reference attributes. Defaults to :id
9
+ def seed(*constraints, &block)
10
+ MerbSeed::Seeder.plant(self, *constraints, &block)
11
+ end
12
+
13
+ def seed_many(*constraints)
14
+ seeds = constraints.pop
15
+ seeds.each do |seed_data|
16
+ seed(*constraints) do |s|
17
+ seed_data.each_pair do |k,v|
18
+ s.send "#{k}=", v
19
+ end
20
+ end
21
+ end
22
+ end
23
+
24
+ def column_names
25
+ properties.map{|i| i.field }
26
+ end
27
+ end
@@ -0,0 +1 @@
1
+ # TODO
@@ -0,0 +1,87 @@
1
+ require File.join( File.dirname(__FILE__), "orm", "dm_ext")
2
+
3
+ module MerbSeed
4
+ class Seeder
5
+ def self.plant(model_class, *constraints, &block)
6
+ constraints = [:id] if constraints.empty?
7
+ seed = Seeder.new(model_class)
8
+
9
+ options = constraints.last if (constraints.last.is_a? Hash)
10
+ constraints.delete_at(*constraints.length-1) if (constraints.last.is_a? Hash)
11
+
12
+ insert_only = constraints.last.is_a? TrueClass
13
+ constraints.delete_at(*constraints.length-1) if (constraints.last.is_a? TrueClass or constraints.last.is_a? FalseClass)
14
+ seed.set_constraints(*constraints)
15
+ yield seed
16
+ seed.plant!({:insert_only => insert_only}.merge(options||{}))
17
+ end
18
+
19
+ def initialize(model_class)
20
+ @model_class = model_class
21
+ @constraints = [:id]
22
+ @data = {}
23
+ end
24
+
25
+ def set_constraints(*constraints)
26
+ raise "You must set at least one constraint." if constraints.empty?
27
+ @constraints = []
28
+ constraints.each do |constraint|
29
+ raise "Your constraint `#{constraint}` is not a column in #{@model_class}. Valid columns are `#{@model_class.column_names.join("`, `")}`." unless @model_class.column_names.include?(constraint.to_s)
30
+ @constraints << constraint.to_sym
31
+ end
32
+ end
33
+
34
+ def set_attribute(name, value)
35
+ @data[name.to_sym] = value
36
+ end
37
+
38
+ def after_seed(&block)
39
+ if block
40
+ @after_seed_block = block
41
+ else
42
+ @after_seed_block
43
+ end
44
+ end
45
+
46
+ def plant!(options)
47
+ insert_only = options[:insert_only].nil? ? false : options[:insert_only]
48
+
49
+ record = get
50
+ return if !record.new_record? and insert_only
51
+ @data.each do |k, v|
52
+ record.send("#{k}=", v)
53
+ end
54
+ record.save || raise("Validation Failed. Use :validate => false in order to skip this:\n#{record.errors.inspect}")
55
+ puts " - #{@model_class} #{condition_hash.inspect}"
56
+
57
+ # fire off after_seed event
58
+ self.after_seed.call(record) if self.after_seed
59
+
60
+ record
61
+ end
62
+
63
+ def method_missing(method_name, *args) #:nodoc:
64
+ if (match = method_name.to_s.match(/(.*)=$/)) && args.size == 1
65
+ set_attribute(match[1], args.first)
66
+ else
67
+ super
68
+ end
69
+ end
70
+
71
+ protected
72
+
73
+ def get
74
+ records = @model_class.all(:conditions => condition_hash)
75
+ raise "Given constraints yielded multiple records." unless records.size < 2
76
+ if records.any?
77
+ return records.first
78
+ else
79
+ return @model_class.new
80
+ end
81
+ end
82
+
83
+ def condition_hash
84
+ @data.reject{|a,v| !@constraints.include?(a)}
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,17 @@
1
+ require 'datamapper'
2
+
3
+ # setup repository
4
+ DataMapper.setup(:default, "sqlite3::memory:")
5
+
6
+ # setup models
7
+ class User
8
+ include DataMapper::Resource
9
+
10
+ property :id, Serial
11
+ property :login, String
12
+ property :first_name, String
13
+ property :last_name, String
14
+ property :title, String
15
+ end
16
+
17
+ User.auto_migrate!
@@ -0,0 +1,63 @@
1
+ require File.join( File.dirname(__FILE__), "spec_helper")
2
+
3
+ describe "merb_seed" do
4
+
5
+ describe "datamapper support" do
6
+ before(:each) do
7
+ load File.join( File.dirname(__FILE__), "fixtures", "dm_models.rb")
8
+ end
9
+
10
+ it "should create a model if one doesn't exist" do
11
+ User.seed(:id) do |s|
12
+ s.id = 1
13
+ s.login = "bob"
14
+ s.first_name = "Bob"
15
+ s.last_name = "Bobson"
16
+ s.title = "Peon"
17
+ end
18
+
19
+ bob = User.get(1)
20
+ bob.first_name.should == "Bob"
21
+ bob.last_name.should == "Bobson"
22
+ end
23
+
24
+ it "should be able to handle multiple constraints" do
25
+ User.seed(:title, :login) do |s|
26
+ s.login = "bob"
27
+ s.title = "Peon"
28
+ s.first_name = "Bob"
29
+ end
30
+
31
+ User.count.should == 1
32
+
33
+ User.seed(:title, :login) do |s|
34
+ s.login = "frank"
35
+ s.title = "Peon"
36
+ s.first_name = "Frank"
37
+ end
38
+
39
+ User.count.should == 2
40
+
41
+ User.first(:first_name => "Bob").first_name.should == "Bob"
42
+ User.seed(:title, :login) do |s|
43
+ s.login = "bob"
44
+ s.title = "Peon"
45
+ s.first_name = "Steve"
46
+ end
47
+ User.first(:first_name => "Steve").first_name.should == "Steve"
48
+ end
49
+
50
+ it "should be able to create models from an array of seed attributes" do
51
+ User.seed_many(:title, :login, [
52
+ {:login => "bob", :title => "Peon", :first_name => "Steve"},
53
+ {:login => "frank", :title => "Peasant", :first_name => "Francis"},
54
+ {:login => "harry", :title => "Noble", :first_name => "Harry"}
55
+ ])
56
+
57
+ User.first(:login => "bob").first_name.should == "Steve"
58
+ User.first(:login => "frank").first_name.should == "Francis"
59
+ User.first(:login => "harry").first_name.should == "Harry"
60
+ end
61
+
62
+ end
63
+ end
@@ -0,0 +1,6 @@
1
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'rubygems'
4
+ require 'spec'
5
+
6
+ require 'merb_seed/seeder'
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: merb_seed
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jacques Crocker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-15 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: merb_datamapper
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.0.8
24
+ version:
25
+ description: Merb plugin that provides RAKE tasks to easily initialize seed data in your database
26
+ email: merbjedi@gmil.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - LICENSE
34
+ files:
35
+ - LICENSE
36
+ - README
37
+ - Rakefile
38
+ - lib/merb_seed
39
+ - lib/merb_seed/merbtasks.rb
40
+ - lib/merb_seed/orm
41
+ - lib/merb_seed/orm/ar_ext.rb
42
+ - lib/merb_seed/orm/dm_ext.rb
43
+ - lib/merb_seed/orm/sequel_ext.rb
44
+ - lib/merb_seed/seeder.rb
45
+ - lib/merb_seed.rb
46
+ - spec/fixtures
47
+ - spec/fixtures/dm_models.rb
48
+ - spec/merb_seed_spec.rb
49
+ - spec/spec_helper.rb
50
+ has_rdoc: true
51
+ homepage: http://merbjedi.com/
52
+ post_install_message:
53
+ rdoc_options: []
54
+
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: "0"
62
+ version:
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "0"
68
+ version:
69
+ requirements: []
70
+
71
+ rubyforge_project: merb
72
+ rubygems_version: 1.3.1
73
+ signing_key:
74
+ specification_version: 2
75
+ summary: Merb plugin that provides RAKE tasks to easily initialize seed data in your database
76
+ test_files: []
77
+