seeding_utils 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +38 -0
- data/Rakefile +10 -0
- data/lib/seeding_utils.rb +75 -0
- data/lib/seeding_utils/version.rb +3 -0
- data/seeding_utils.gemspec +24 -0
- data/test/seeding_utils_test.rb +49 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 01a703ee260dde1c9a61e85b2120628812041361
|
4
|
+
data.tar.gz: 9fc2986bd93be82be7fb7da99cef1932d43ec107
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 15e476c55dec624377745ad0a3a14e274812f349a7a464b16eb1746b0da50f9f0833f26dd08d471737fd027235208b797f053261309106c88673cf8962c4360b
|
7
|
+
data.tar.gz: 47d6cfb73b7ab92867b3d288908718a18d5f0d2e74f332e313eff06dd311480ac57b9c76f73699a793c68baa03bbeab1904745aea45dbe0f469f16e5be33b652
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Norman Clarke and FlexMinder
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# SeedingUtils
|
2
|
+
|
3
|
+
Some Postgres-specific database seeding utilities we use at FlexMinder.
|
4
|
+
|
5
|
+
It mainly provides a wrapper around Postgres's COPY functionality to allow you
|
6
|
+
to cache largish seed datasets so that recreating a schema with seed data
|
7
|
+
during early application development is runs more quickly.
|
8
|
+
|
9
|
+
In our use case, we need to load US ZIP code and other geolocation data, and
|
10
|
+
our initial data seeding takes 3-5 minutes. With the caching functionality
|
11
|
+
provided by this gem, we reduce that to about 30 seconds.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
gem 'seeding_utils'
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
$ bundle
|
22
|
+
|
23
|
+
Or install it yourself as:
|
24
|
+
|
25
|
+
$ gem install seeding_utils
|
26
|
+
|
27
|
+
## Usage
|
28
|
+
|
29
|
+
|
30
|
+
|
31
|
+
|
32
|
+
## Contributing
|
33
|
+
|
34
|
+
1. Fork it
|
35
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
36
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
37
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
38
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require "seeding_utils/version"
|
2
|
+
require 'pathname'
|
3
|
+
|
4
|
+
module SeedingUtils
|
5
|
+
|
6
|
+
extend self
|
7
|
+
|
8
|
+
# Expects a proc that when called, returns a raw PG connection.
|
9
|
+
# For example:
|
10
|
+
#
|
11
|
+
# SeedingUtils.connection = -> {ActiveRecord::Base.connection.raw_connection}
|
12
|
+
# or:
|
13
|
+
# SeedingUtils.connection = -> {PG::Connection.open dbname: 'foo'}
|
14
|
+
def connect(callable)
|
15
|
+
@connection_callable = callable
|
16
|
+
end
|
17
|
+
|
18
|
+
# @return PG::Connection
|
19
|
+
def connection
|
20
|
+
@connection_callable.call
|
21
|
+
end
|
22
|
+
|
23
|
+
class Table
|
24
|
+
|
25
|
+
attr_accessor :name, :quoted_name
|
26
|
+
|
27
|
+
def initialize(name)
|
28
|
+
@conn = SeedingUtils.connection
|
29
|
+
self.name = name
|
30
|
+
self.quoted_name = PG::Connection.quote_ident(name)
|
31
|
+
end
|
32
|
+
|
33
|
+
def seed(cache_file = nil, &block)
|
34
|
+
path = Pathname(cache_file.to_s)
|
35
|
+
return seed_uncached(&block) if cache_file.nil?
|
36
|
+
if path.file?
|
37
|
+
puts %{-- Loading #{name} seeds from cache}
|
38
|
+
@conn.exec %{DELETE FROM #{quoted_name}}
|
39
|
+
load path.open 'r:binary'
|
40
|
+
elsif block_given?
|
41
|
+
seed_uncached(&block)
|
42
|
+
path.open 'w:binary' do |io|
|
43
|
+
dump(io)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def seed_uncached(&block)
|
49
|
+
puts %{-- Loading #{name} seeds without cache}
|
50
|
+
yield
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
# Expects an open IO object for writing.
|
55
|
+
def dump(io)
|
56
|
+
@conn.exec %{COPY #{quoted_name} TO STDOUT WITH (FORMAT 'binary')}
|
57
|
+
while row = @conn.get_copy_data do
|
58
|
+
io.write(row)
|
59
|
+
end
|
60
|
+
io.rewind
|
61
|
+
return io
|
62
|
+
end
|
63
|
+
|
64
|
+
# Expects an open IO object for reading.
|
65
|
+
def load(io)
|
66
|
+
@conn.exec %{DELETE FROM #{quoted_name}}
|
67
|
+
@conn.exec %{COPY #{quoted_name} FROM STDIN WITH (FORMAT 'binary')}
|
68
|
+
while data = io.read(256)
|
69
|
+
@conn.put_copy_data(data)
|
70
|
+
end
|
71
|
+
@conn.put_copy_end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'seeding_utils/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "seeding_utils"
|
8
|
+
spec.version = SeedingUtils::VERSION
|
9
|
+
spec.authors = ["Norman Clarke"]
|
10
|
+
spec.email = ["norman@njclarke.com"]
|
11
|
+
spec.description = %q{Seeding Utils for Postgres.}
|
12
|
+
spec.summary = %q{Some database seeding utilities for Postgres.}
|
13
|
+
spec.homepage = "https://github.com/flexminder/seeding_utils"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "pg", "~> 0.16.0"
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
require 'pg'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'seeding_utils'
|
5
|
+
|
6
|
+
connection = nil
|
7
|
+
SeedingUtils.connect -> {
|
8
|
+
connection ||= PG::Connection.open dbname: 'test_seeding_utils'
|
9
|
+
}
|
10
|
+
|
11
|
+
|
12
|
+
class SeedingUtilsTest < Test::Unit::TestCase
|
13
|
+
|
14
|
+
def setup
|
15
|
+
@conn = SeedingUtils.connection
|
16
|
+
@conn.exec <<-END
|
17
|
+
SET client_min_messages TO 'warning';
|
18
|
+
DROP TABLE IF EXISTS people;
|
19
|
+
CREATE TABLE people (
|
20
|
+
id INTEGER PRIMARY KEY,
|
21
|
+
name VARCHAR(255) NOT NULL
|
22
|
+
);
|
23
|
+
INSERT INTO people (id, name) VALUES (1, 'John Doe');
|
24
|
+
INSERT INTO people (id, name) VALUES (2, 'Juan Fulano');
|
25
|
+
END
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_should_dump_copy_data
|
29
|
+
table = SeedingUtils::Table.new 'people'
|
30
|
+
io = StringIO.new('', 'r+:binary')
|
31
|
+
assert_equal 0, io.size
|
32
|
+
table.dump(io)
|
33
|
+
assert io.size > 0
|
34
|
+
data = io.read.force_encoding 'BINARY'
|
35
|
+
assert_match 'Juan Fulano', data
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_should_read_copy_data
|
39
|
+
table = SeedingUtils::Table.new 'people'
|
40
|
+
io = StringIO.new('', 'r+:binary')
|
41
|
+
table.dump(io)
|
42
|
+
@conn.exec 'DELETE FROM people'
|
43
|
+
result = @conn.exec 'SELECT COUNT(*) FROM people'
|
44
|
+
assert_equal "0", result.getvalue(0, 0)
|
45
|
+
table.load(io)
|
46
|
+
result = @conn.exec 'SELECT COUNT(*) FROM people'
|
47
|
+
assert_equal "2", result.getvalue(0, 0)
|
48
|
+
end
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: seeding_utils
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Norman Clarke
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pg
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.16.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.16.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Seeding Utils for Postgres.
|
56
|
+
email:
|
57
|
+
- norman@njclarke.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- .gitignore
|
63
|
+
- Gemfile
|
64
|
+
- LICENSE.txt
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- lib/seeding_utils.rb
|
68
|
+
- lib/seeding_utils/version.rb
|
69
|
+
- seeding_utils.gemspec
|
70
|
+
- test/seeding_utils_test.rb
|
71
|
+
homepage: https://github.com/flexminder/seeding_utils
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project:
|
91
|
+
rubygems_version: 2.0.3
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Some database seeding utilities for Postgres.
|
95
|
+
test_files:
|
96
|
+
- test/seeding_utils_test.rb
|
97
|
+
has_rdoc:
|