db-populator 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'logging'
4
+
5
+ group :development do
6
+ gem 'jeweler', '~> 1.6.0'
7
+ gem 'bundler', '~> 1.0.0'
8
+ gem 'rspec', '~> 2.3.0'
9
+ gem 'rcov', '>= 0'
10
+ gem 'yard', '~> 0.6.0'
11
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,34 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ diff-lcs (1.1.2)
5
+ git (1.2.5)
6
+ jeweler (1.6.0)
7
+ bundler (~> 1.0.0)
8
+ git (>= 1.2.5)
9
+ rake
10
+ little-plugger (1.1.2)
11
+ logging (1.5.0)
12
+ little-plugger (>= 1.1.2)
13
+ rake (0.8.7)
14
+ rcov (0.9.9)
15
+ rspec (2.3.0)
16
+ rspec-core (~> 2.3.0)
17
+ rspec-expectations (~> 2.3.0)
18
+ rspec-mocks (~> 2.3.0)
19
+ rspec-core (2.3.1)
20
+ rspec-expectations (2.3.0)
21
+ diff-lcs (~> 1.1.2)
22
+ rspec-mocks (2.3.0)
23
+ yard (0.6.8)
24
+
25
+ PLATFORMS
26
+ ruby
27
+
28
+ DEPENDENCIES
29
+ bundler (~> 1.0.0)
30
+ jeweler (~> 1.6.0)
31
+ logging
32
+ rcov
33
+ rspec (~> 2.3.0)
34
+ yard (~> 0.6.0)
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Umang Chouhan
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.rdoc ADDED
@@ -0,0 +1,35 @@
1
+ == Populator http://travis-ci.org/optimis/populator.png
2
+
3
+ Populator includes helper methods to ease parsing data files. Assigning a header and iterating over rows is handled by the module via a simple configuration.
4
+
5
+ Examples:
6
+
7
+ Define a module and extend it with the populator module.
8
+
9
+ A Custom Populator.
10
+
11
+ module CustomPopulator
12
+ extend Populator
13
+ populates 'CustomFile'
14
+
15
+ def process(row)
16
+ ...
17
+ end
18
+ end
19
+
20
+ The extended module focusses on business logic required to process a single row.
21
+
22
+ == Contributing to populator
23
+
24
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
25
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
26
+ * Fork the project.
27
+ * Start a feature/bugfix branch.
28
+ * Commit and push until you are happy with your contribution.
29
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
30
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
31
+
32
+ == Copyright
33
+
34
+ Copyright (c) 2011 Umang Chouhan. See LICENSE.txt for
35
+ further details.
data/Rakefile ADDED
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "db-populator"
18
+ gem.homepage = "http://github.com/optimis/db-populator"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{Populator is a utility to parse data files.}
21
+ gem.description = %Q{Populator is a utility to parse data files.}
22
+ gem.email = "uchouhan@optimiscorp.com"
23
+ gem.authors = ["Umang Chouhan"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'yard'
42
+ YARD::Rake::YardocTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.1
@@ -0,0 +1,32 @@
1
+ # The exception class used when the data file is not configured.
2
+ class DataFileNotConfigured < Exception
3
+
4
+ # Set the message to return when a data file is not configured.
5
+ #
6
+ # @return [String] The message to return if the data file is not configured.
7
+ def message
8
+ 'No data file was specified. Usage: populates <file>'
9
+ end
10
+ end
11
+
12
+ # The exception class used when the data file is missing.
13
+ class MissingDataFile < Exception
14
+
15
+ # Set the message to return when a data file is missing.
16
+ #
17
+ # @return [String] The message to return if the data file is missing.
18
+ def message
19
+ 'The data file configured is missing.'
20
+ end
21
+ end
22
+
23
+ # The exception class used when the process method is not overridden.
24
+ class MethodNotOverridden < Exception
25
+
26
+ # Set the message to return when the process method is not overridden.
27
+ #
28
+ # @return [String] The message to return when the process method is not overridden.
29
+ def message
30
+ 'You must override the .process method in the extended populator class.'
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ # A fake populator module with default type for testing.
2
+ module FakePopulator
3
+
4
+ # Extend it with the Populator module.
5
+ extend Populator
6
+
7
+ # Populate the test file.
8
+ populates 'TestFile'
9
+ end
10
+
11
+ # A fake populator module with overridden type for testing.
12
+ module FakePopulatorWithOverriddenType
13
+
14
+ # Extend it with the Populator module.
15
+ extend Populator
16
+
17
+ # Populate the test excel file.
18
+ populates 'TestExcelFile', :type => 'excel'
19
+ end
20
+
21
+ # A fake populator module with overridden directory for testing.
22
+ module FakePopulatorWithOverriddenDirectory
23
+
24
+ # Extend it with the Populator module.
25
+ extend Populator
26
+
27
+ # Populate the test file.
28
+ populates 'TestFile', :directory => 'db/populate/files'
29
+ end
@@ -0,0 +1,47 @@
1
+ # Require the logging gem.
2
+ require 'logging'
3
+
4
+ # The populate logger class.
5
+ class PopulateLogger
6
+
7
+ # Configures the logger.
8
+ #
9
+ # @return [Logger] The logger instance after configuration.
10
+ def self.setup
11
+ configure
12
+ logger
13
+ end
14
+
15
+ private
16
+
17
+ # Configures the level.
18
+ #
19
+ # @param [Symbol] The log level. (defaults to :info)
20
+ def self.level=(level)
21
+ @level = level
22
+ end
23
+
24
+ # Returns the level.
25
+ #
26
+ # @param [String] The configured level. (defaults to :info)
27
+ def self.level
28
+ @level or :info
29
+ end
30
+
31
+ # Returns the configured logger.
32
+ #
33
+ # @return [Logger, #info, #debug, #warn] The logger instance.
34
+ def self.logger
35
+ logger = Logging.logger['example_logger']
36
+ logger.add_appenders Logging.appenders.stdout, Logging.appenders.file(@path)
37
+ logger.level = level
38
+ logger
39
+ end
40
+
41
+ # Configures the path of the log file.
42
+ #
43
+ # @return [String] The path of the log file.
44
+ def self.configure
45
+ @path = defined?(Rails) ? "#{Rails.root}/log/populator.log" : 'populator.log'
46
+ end
47
+ end
data/lib/populator.rb ADDED
@@ -0,0 +1,109 @@
1
+ require 'populator/errors'
2
+ require 'populator/logger'
3
+
4
+ # Populator includes helper methods to ease parsing data files.
5
+ # Assigning a header and iterating over rows is handled by the
6
+ # module via a simple configuration.
7
+ #
8
+ # @example
9
+ # Define a module and extend it with the populator module.
10
+ #
11
+ # @example A Custom Populator.
12
+ # module CustomPopulator
13
+ # extend Populator
14
+ # populates 'CustomFile'
15
+ #
16
+ # def process(row)
17
+ # ...
18
+ # end
19
+ # end
20
+ #
21
+ # @note As noted in the example the extended module defines the
22
+ # logic to process a single row.
23
+
24
+ module Populator
25
+
26
+ # Default directory location for data files.
27
+ DIRECTORY = 'files'
28
+
29
+ # Default data file type is CSV.
30
+ TYPE = 'csv'
31
+
32
+ # Attribute accessors for the directory, file name, header, count, rows and before hook.
33
+ attr_accessor :logger, :directory, :file, :type, :header, :count, :rows, :before
34
+
35
+ # Configuration helper.
36
+ #
37
+ # @param [String] file The data file name.
38
+ # @option options [String] :directory ('db/populate/data_files') The location of the data file.
39
+ # @option options [String] :type ('csv') The data file type.
40
+ # @option options [Boolean] :header Set true if the file has a header.
41
+ # @option options [String] :before The method to call before the run.
42
+ def populates(file, options = {})
43
+ # Setup the logger to log populator warnings and messages.
44
+ self.logger = PopulateLogger.setup
45
+
46
+ self.directory = options[:directory] || DIRECTORY
47
+ self.file = file
48
+ self.type = options[:type] || TYPE
49
+ self.header = options[:header]
50
+ self.before = options[:before]
51
+ end
52
+
53
+ # Parses the data file content and processes each row.
54
+ #
55
+ # @return [Boolean] Returns true if all rows are processed successfully.
56
+ def run
57
+
58
+ # Call the before hook if defined.
59
+ #
60
+ # @usage
61
+ # populates 'TestFile', :before => :inactivate
62
+ send(before) if before
63
+
64
+ rows = parser.parse(read)
65
+ self.count = header ? rows.count - 1 : rows.count
66
+ self.header = rows.shift if header
67
+ count.times { process(rows.shift) }
68
+
69
+ # Return true when all rows are processed.
70
+ return true
71
+ end
72
+
73
+ # Stub method to be defined in the extended module.
74
+ #
75
+ # @raise [Exception] Raises an exception if the extended module does not override the method.
76
+ def process(row = nil)
77
+ raise MethodNotOverridden
78
+ end
79
+
80
+ private
81
+
82
+ # The parser to use based on the type of data file.
83
+ #
84
+ # @return [Parser, #parse] Returns the parser class to use.
85
+ def parser
86
+ if type == 'csv'
87
+ require 'csv'
88
+ return CSV::Reader
89
+ end
90
+ end
91
+
92
+ # Absolute path for the data file.
93
+ #
94
+ # @return [String] The absolute path.
95
+ def path
96
+ "#{Rails.root}/#{directory}/#{file}.#{type}"
97
+ end
98
+
99
+ # Reads the data file.
100
+ #
101
+ # @return [File] The data file contents.
102
+ # @raise [DataFileNotConfigured] Raises an exception when the file is not configured.
103
+ # @raise [MissingDataFile] Raises an exception when the configured file is missing.
104
+ def read
105
+ raise DataFileNotConfigured unless file
106
+ raise MissingDataFile unless File.exist?(path)
107
+ File.read path
108
+ end
109
+ end
data/populator.gemspec ADDED
@@ -0,0 +1,70 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{populator}
8
+ s.version = "0.1.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Umang Chouhan"]
12
+ s.date = %q{2011-05-12}
13
+ s.description = %q{Populator is a utility to parse data files.}
14
+ s.email = %q{uchouhan@optimiscorp.com}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE.txt",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".rspec",
22
+ "Gemfile",
23
+ "Gemfile.lock",
24
+ "LICENSE.txt",
25
+ "README.rdoc",
26
+ "Rakefile",
27
+ "VERSION",
28
+ "lib/populator.rb",
29
+ "lib/populator/errors.rb",
30
+ "lib/populator/fakes.rb",
31
+ "lib/populator/logger.rb",
32
+ "populator.gemspec",
33
+ "spec/populator_spec.rb",
34
+ "spec/spec_helper.rb"
35
+ ]
36
+ s.homepage = %q{http://github.com/optimis/populator}
37
+ s.licenses = ["MIT"]
38
+ s.require_paths = ["lib"]
39
+ s.rubygems_version = %q{1.3.7}
40
+ s.summary = %q{Populator is a utility to parse data files.}
41
+
42
+ if s.respond_to? :specification_version then
43
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ s.add_runtime_dependency(%q<logging>, [">= 0"])
48
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.0"])
49
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
50
+ s.add_development_dependency(%q<rspec>, ["~> 2.3.0"])
51
+ s.add_development_dependency(%q<rcov>, [">= 0"])
52
+ s.add_development_dependency(%q<yard>, ["~> 0.6.0"])
53
+ else
54
+ s.add_dependency(%q<logging>, [">= 0"])
55
+ s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
56
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
57
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
58
+ s.add_dependency(%q<rcov>, [">= 0"])
59
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
60
+ end
61
+ else
62
+ s.add_dependency(%q<logging>, [">= 0"])
63
+ s.add_dependency(%q<jeweler>, ["~> 1.6.0"])
64
+ s.add_dependency(%q<bundler>, ["~> 1.0.0"])
65
+ s.add_dependency(%q<rspec>, ["~> 2.3.0"])
66
+ s.add_dependency(%q<rcov>, [">= 0"])
67
+ s.add_dependency(%q<yard>, ["~> 0.6.0"])
68
+ end
69
+ end
70
+
@@ -0,0 +1,50 @@
1
+ require 'spec/spec_helper'
2
+ require 'populator/fakes'
3
+
4
+ describe Populator, 'DIRECTORY' do
5
+ it 'should be set to the default directory' do
6
+ Populator::DIRECTORY.should == 'files'
7
+ end
8
+ end
9
+
10
+ describe FakePopulator, '.directory' do
11
+ context 'when no directory is configured' do
12
+ it 'should return the default directory' do
13
+ FakePopulator.directory.should == Populator::DIRECTORY
14
+ end
15
+ end
16
+
17
+ context 'when the directory is configured' do
18
+ it 'should return the configured directory' do
19
+ FakePopulatorWithOverriddenDirectory.directory.should == 'db/populate/files'
20
+ end
21
+ end
22
+ end
23
+
24
+ describe FakePopulator, '.file' do
25
+ it 'should return the configured file name' do
26
+ FakePopulator.file.should == 'TestFile'
27
+ end
28
+ end
29
+
30
+ describe FakePopulator, '.type' do
31
+ context 'when no file type is configured' do
32
+ it 'should return the default file type' do
33
+ FakePopulator.type.should == 'csv'
34
+ end
35
+ end
36
+
37
+ context 'when the file type is configured' do
38
+ it 'should return the configured file type' do
39
+ FakePopulatorWithOverriddenType.type.should == 'excel'
40
+ end
41
+ end
42
+ end
43
+
44
+ describe FakePopulator, '.process(row)' do
45
+ it 'should raise an exception with a message to define the method in the extended populator class' do
46
+ lambda {
47
+ FakePopulator.process
48
+ }.should raise_exception(MethodNotOverridden)
49
+ end
50
+ end
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ require 'rspec'
4
+ require 'populator'
5
+
6
+ # Requires supporting files with custom matchers and macros, etc,
7
+ # in ./support/ and its subdirectories.
8
+ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
9
+
10
+ RSpec.configure do |config|
11
+
12
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: db-populator
3
+ version: !ruby/object:Gem::Version
4
+ hash: 25
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 1
10
+ version: 0.1.1
11
+ platform: ruby
12
+ authors:
13
+ - Umang Chouhan
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-05-12 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ prerelease: false
23
+ type: :runtime
24
+ name: logging
25
+ version_requirements: &id001 !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ hash: 3
31
+ segments:
32
+ - 0
33
+ version: "0"
34
+ requirement: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ prerelease: false
37
+ type: :development
38
+ name: jeweler
39
+ version_requirements: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ~>
43
+ - !ruby/object:Gem::Version
44
+ hash: 15
45
+ segments:
46
+ - 1
47
+ - 6
48
+ - 0
49
+ version: 1.6.0
50
+ requirement: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ prerelease: false
53
+ type: :development
54
+ name: bundler
55
+ version_requirements: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 23
61
+ segments:
62
+ - 1
63
+ - 0
64
+ - 0
65
+ version: 1.0.0
66
+ requirement: *id003
67
+ - !ruby/object:Gem::Dependency
68
+ prerelease: false
69
+ type: :development
70
+ name: rspec
71
+ version_requirements: &id004 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ hash: 3
77
+ segments:
78
+ - 2
79
+ - 3
80
+ - 0
81
+ version: 2.3.0
82
+ requirement: *id004
83
+ - !ruby/object:Gem::Dependency
84
+ prerelease: false
85
+ type: :development
86
+ name: rcov
87
+ version_requirements: &id005 !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ requirement: *id005
97
+ - !ruby/object:Gem::Dependency
98
+ prerelease: false
99
+ type: :development
100
+ name: yard
101
+ version_requirements: &id006 !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ~>
105
+ - !ruby/object:Gem::Version
106
+ hash: 7
107
+ segments:
108
+ - 0
109
+ - 6
110
+ - 0
111
+ version: 0.6.0
112
+ requirement: *id006
113
+ description: Populator is a utility to parse data files.
114
+ email: uchouhan@optimiscorp.com
115
+ executables: []
116
+
117
+ extensions: []
118
+
119
+ extra_rdoc_files:
120
+ - LICENSE.txt
121
+ - README.rdoc
122
+ files:
123
+ - .document
124
+ - .rspec
125
+ - Gemfile
126
+ - Gemfile.lock
127
+ - LICENSE.txt
128
+ - README.rdoc
129
+ - Rakefile
130
+ - VERSION
131
+ - lib/populator.rb
132
+ - lib/populator/errors.rb
133
+ - lib/populator/fakes.rb
134
+ - lib/populator/logger.rb
135
+ - populator.gemspec
136
+ - spec/populator_spec.rb
137
+ - spec/spec_helper.rb
138
+ has_rdoc: true
139
+ homepage: http://github.com/optimis/db-populator
140
+ licenses:
141
+ - MIT
142
+ post_install_message:
143
+ rdoc_options: []
144
+
145
+ require_paths:
146
+ - lib
147
+ required_ruby_version: !ruby/object:Gem::Requirement
148
+ none: false
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ hash: 3
153
+ segments:
154
+ - 0
155
+ version: "0"
156
+ required_rubygems_version: !ruby/object:Gem::Requirement
157
+ none: false
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ hash: 3
162
+ segments:
163
+ - 0
164
+ version: "0"
165
+ requirements: []
166
+
167
+ rubyforge_project:
168
+ rubygems_version: 1.3.7
169
+ signing_key:
170
+ specification_version: 3
171
+ summary: Populator is a utility to parse data files.
172
+ test_files: []
173
+