pikelet 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 11dc1d24d271ec693d9f578c8372a33d05e688b1
4
+ data.tar.gz: e9ebc0ac3bdfd1e15a6f460df7f10ba8e5bd07f8
5
+ SHA512:
6
+ metadata.gz: cb41dbb987f9860f67b69f5e11b4e52776282f9dac882d425c54a7dba218470875e7069cbf06223357766fd6e65e96c4894ad7085095790b56db2220b546cf77
7
+ data.tar.gz: a3e10c5f0e07aa8f935a784e3ea0cd95f8fec508f1ea5dc64db69fbdbb4d9791ab9e264420952d92a619a3986fa23f95467283f7d567fae1ab7bdb939bf25e95
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ pikelet
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.1
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in pikelet.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 John Carney
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,164 @@
1
+ # Pikelet
2
+
3
+ A pikelet is a type of small pancake popular in Australia and New Zealand.
4
+ Also, a simple flat-file database parser capable of dealing with
5
+ files containing heterogeneous records.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ gem 'pikelet'
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install pikelet
20
+
21
+ ## Usage
22
+
23
+ ### Homogeneous records, fixed-width fields
24
+
25
+ require "pikelet"
26
+
27
+ data = <<-FLATFILE.gsub(/^\s*/, "")
28
+ Nicolaus Copernicus
29
+ Tycho Brahe
30
+ FLATFILE
31
+
32
+ definition = Pikelet.define do
33
+ first_name 0...10
34
+ last_name 10...20
35
+ end
36
+
37
+ definition.parse(data.split(/[\r\n]+/)).to_a
38
+
39
+ # => [#<struct first_name="Nicolaus", last_name="Copernicus">,
40
+ # #<struct first_name="Tycho", last_name="Brahe">]
41
+
42
+ ### Heterogeneous records, fixed-width fields
43
+
44
+ require "pikelet"
45
+
46
+ data = <<-FLATFILE.gsub(/^\s*/, "")
47
+ NAMENicolaus Copernicus
48
+ ADDR123 South Street Nowhereville 45678Y Someplace Someland
49
+ FLATFILE
50
+
51
+ definition = Pikelet.define do
52
+ type_signature 0...4
53
+
54
+ record "NAME" do
55
+ first_name 4...14
56
+ last_name 14...24
57
+ end
58
+
59
+ record "ADDR" do
60
+ street_address 4...24
61
+ city 24...44
62
+ postal_code 44...54
63
+ state 54...74
64
+ country 74...94
65
+ end
66
+ end
67
+
68
+ definition.parse(data.split(/[\r\n]+/)).to_a
69
+
70
+ # => [#<struct
71
+ # type_signature="NAME",
72
+ # first_name="Nicolaus",
73
+ # last_name="Copernicus">,
74
+ # #<struct
75
+ # type_signature="ADDR",
76
+ # street_address="123 South Street",
77
+ # city="Nowhereville",
78
+ # postal_code="45678Y",
79
+ # state="Someplace",
80
+ # country="Someland">]
81
+
82
+ ### CSV files
83
+
84
+ require "pikelet"
85
+ require "csv"
86
+
87
+ data = <<-CSV.gsub(/^\s*/, "")
88
+ NAME,Nicolaus,Copernicus
89
+ ADDR,123 South Street,Nowhereville,45678Y,Someplace,Someland
90
+ CSV
91
+
92
+ definition = Pikelet.define do
93
+ type_signature 0
94
+
95
+ record "NAME" do
96
+ first_name 1
97
+ last_name 2
98
+ end
99
+
100
+ record "ADDR" do
101
+ street_address 1
102
+ city 2
103
+ postal_code 3
104
+ state 4
105
+ country 5
106
+ end
107
+ end
108
+
109
+ definition.parse(CSV.parse(data)).to_a
110
+
111
+ # => [#<struct
112
+ # type_signature="NAME",
113
+ # first_name="Nicolaus",
114
+ # last_name="Copernicus">,
115
+ # #<struct
116
+ # type_signature="ADDR",
117
+ # street_address="123 South Street",
118
+ # city="Nowhereville",
119
+ # postal_code="45678Y",
120
+ # state="Someplace",
121
+ # country="Someland">]
122
+
123
+ ### Inheritance
124
+
125
+ require "pikelet"
126
+
127
+ data = <<-FLATFILE.gsub(/^\s*/, "")
128
+ SIMPLENicolaus Copernicus
129
+ FANCY Tycho Brahe Tykester
130
+ FLATFILE
131
+
132
+ definition = Pikelet.define do
133
+ type_signature 0...6
134
+
135
+ record "SIMPLE" do
136
+ first_name 6...16
137
+ last_name 16...26
138
+
139
+ record "FANCY" do
140
+ nickname 26...36
141
+ end
142
+ end
143
+ end
144
+
145
+ definition.parse(data.split(/[\r\n]+/)).to_a
146
+
147
+ # => [#<struct
148
+ # type_signature="SIMPLE",
149
+ # first_name="Nicolaus",
150
+ # last_name="Copernicus">,
151
+ # #<struct
152
+ # type_signature="FANCY",
153
+ # first_name="Tycho",
154
+ # last_name="Brahe",
155
+ # nickname="Tykester">]
156
+
157
+
158
+ ## Contributing
159
+
160
+ 1. Fork it ( http://github.com/johncarney/pikelet/fork )
161
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
162
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
163
+ 4. Push to the branch (`git push origin my-new-feature`)
164
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ desc "Run specs"
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ desc 'Default: run specs.'
8
+ task :default => :spec
@@ -0,0 +1,22 @@
1
+ module Pikelet
2
+ class FieldDefinition
3
+ attr_reader :indices, :type
4
+
5
+ def initialize(indices, type)
6
+ @indices = indices
7
+ @type = type
8
+ end
9
+
10
+ def parse(text)
11
+ value = indices.map { |index| text[index] }.join
12
+ case type
13
+ when :integer
14
+ value.to_i
15
+ when :overpunch
16
+ Overpunch.parse(value)
17
+ else
18
+ value.strip
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,37 @@
1
+ module Pikelet
2
+ class FileDefinition
3
+ attr_reader :base_record_definition
4
+
5
+ def initialize(&block)
6
+ @base_record_definition = RecordDefinition.new(self, &block)
7
+ end
8
+
9
+ def record(type_signature, base_definition: nil, &block)
10
+ base_definition ||= base_record_definition
11
+ record_definitions[type_signature] = RecordDefinition.new(self, base_definition: base_definition, &block)
12
+ end
13
+
14
+ def record_definitions
15
+ @record_definitions ||= {}
16
+ end
17
+
18
+ def parse(data, &block)
19
+ records = Enumerator.new do |y|
20
+ data.each do |line|
21
+ record = base_record_definition.parse(line)
22
+ if record.respond_to?(:type_signature)
23
+ if definition = record_definitions[record.type_signature]
24
+ record = definition.parse(line)
25
+ end
26
+ end
27
+ y.yield(record)
28
+ end
29
+ end
30
+ if block_given?
31
+ records.each(&block)
32
+ else
33
+ records
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ module Pikelet
2
+ class RecordDefinition
3
+ attr_reader :file_definition, :field_definitions
4
+
5
+ def initialize(file_definition, base_definition: nil, &block)
6
+ @file_definition = file_definition
7
+ @field_definitions = base_definition && base_definition.field_definitions.dup || {}
8
+ if block_given?
9
+ instance_eval(&block)
10
+ end
11
+ end
12
+
13
+ def field(name, *indices, type: nil)
14
+ @record_class = nil
15
+ field_definitions[name] = Pikelet::FieldDefinition.new(indices, type: type)
16
+ end
17
+
18
+ def record(type_signature, &block)
19
+ file_definition.record(type_signature, base_definition: self, &block)
20
+ end
21
+
22
+ def parse(data)
23
+ record_class.new(*field_definitions.values.map { |field| field.parse(data) })
24
+ end
25
+
26
+ def method_missing(method, *args, **options)
27
+ field(method, *args, **options)
28
+ end
29
+
30
+ def record_class
31
+ @record_class ||= Struct.new(*field_definitions.keys.map(&:to_sym))
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,3 @@
1
+ module Pikelet
2
+ VERSION = "0.0.1"
3
+ end
data/lib/pikelet.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "pikelet/version"
2
+ require "pikelet/file_definition"
3
+ require "pikelet/record_definition"
4
+ require "pikelet/field_definition"
5
+
6
+ module Pikelet
7
+ def self.define(&block)
8
+ Pikelet::FileDefinition.new(&block)
9
+ end
10
+ end
data/pikelet.gemspec ADDED
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pikelet/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "pikelet"
8
+ spec.version = Pikelet::VERSION
9
+ spec.authors = ["John Carney"]
10
+ spec.email = ["john@carney.id.au"]
11
+ spec.summary = %q{A simple flat-file database parser.}
12
+ spec.description = %q{Pikelet is a type of small pancake popular in Australia and New Zealand. Also, a flat-file database parser capable of dealing with heterogeneous records.}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
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.required_ruby_version = '>= 2.0.0'
22
+
23
+ spec.add_runtime_dependency "overpunch"
24
+
25
+ spec.add_development_dependency "bundler", "~> 1.5"
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pikelet
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - John Carney
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: overpunch
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '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'
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.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
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
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Pikelet is a type of small pancake popular in Australia and New Zealand.
70
+ Also, a flat-file database parser capable of dealing with heterogeneous records.
71
+ email:
72
+ - john@carney.id.au
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - ".ruby-gemset"
79
+ - ".ruby-version"
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - lib/pikelet.rb
85
+ - lib/pikelet/field_definition.rb
86
+ - lib/pikelet/file_definition.rb
87
+ - lib/pikelet/record_definition.rb
88
+ - lib/pikelet/version.rb
89
+ - pikelet.gemspec
90
+ homepage: ''
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: 2.0.0
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.2.2
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: A simple flat-file database parser.
114
+ test_files: []