data_package 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +2 -0
- data/.travis.yml +7 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +53 -0
- data/LICENSE +20 -0
- data/README.md +32 -0
- data/Rakefile +6 -0
- data/data_package.gemspec +33 -0
- data/lib/attr_helper/base_attr.rb +36 -0
- data/lib/attr_helper/required_attr.rb +46 -0
- data/lib/attr_helper/serialization.rb +25 -0
- data/lib/attr_helper.rb +105 -0
- data/lib/data_package/base.rb +10 -0
- data/lib/data_package/dialect.rb +9 -0
- data/lib/data_package/field.rb +20 -0
- data/lib/data_package/license.rb +8 -0
- data/lib/data_package/package.rb +100 -0
- data/lib/data_package/person.rb +7 -0
- data/lib/data_package/resource.rb +75 -0
- data/lib/data_package/schema.rb +13 -0
- data/lib/data_package/source.rb +7 -0
- data/lib/data_package/version.rb +3 -0
- data/lib/data_package.rb +17 -0
- data/spec/attr_helper_spec.rb +60 -0
- data/spec/attr_helpers/base_attr_spec.rb +62 -0
- data/spec/attr_helpers/required_attr_spec.rb +49 -0
- data/spec/attr_helpers/serialization_spec.rb +9 -0
- data/spec/data_package/base_spec.rb +10 -0
- data/spec/data_package/dialect_spec.rb +35 -0
- data/spec/data_package/field_spec.rb +29 -0
- data/spec/data_package/license_spec.rb +18 -0
- data/spec/data_package/package_spec.rb +59 -0
- data/spec/data_package/person_spec.rb +21 -0
- data/spec/data_package/resource_spec.rb +57 -0
- data/spec/data_package/schema_spec.rb +25 -0
- data/spec/data_package/source_spec.rb +22 -0
- data/spec/fixtures/package/datapackage.json +94 -0
- data/spec/fixtures/package/standard.csv +11 -0
- data/spec/fixtures/standard.csv +11 -0
- data/spec/klass_helper.rb +41 -0
- data/spec/resource_helper.rb +113 -0
- data/spec/spec_helper.rb +19 -0
- metadata +233 -0
data/lib/data_package.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'active_support/core_ext/hash'
|
2
|
+
|
3
|
+
require "data_package/version"
|
4
|
+
|
5
|
+
# Attribute Helpers
|
6
|
+
require 'attr_helper'
|
7
|
+
|
8
|
+
# Core Specification
|
9
|
+
require 'data_package/base'
|
10
|
+
require 'data_package/package'
|
11
|
+
require 'data_package/field'
|
12
|
+
require 'data_package/schema'
|
13
|
+
require 'data_package/resource'
|
14
|
+
require 'data_package/dialect'
|
15
|
+
require 'data_package/person'
|
16
|
+
require 'data_package/source'
|
17
|
+
require 'data_package/license'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'klass_helper'
|
3
|
+
|
4
|
+
describe AttrHelper do
|
5
|
+
it "should initialize" do
|
6
|
+
obj = KlassHelper::BaseKlass.new(:name => 'myvalue')
|
7
|
+
|
8
|
+
obj.name.should == 'myvalue'
|
9
|
+
|
10
|
+
obj.attr_required?(:name).should == true
|
11
|
+
obj.attr_required?(:title).should == false
|
12
|
+
obj.attr_required?(:format).should == false
|
13
|
+
|
14
|
+
obj.missing_attributes.collect(&:name).should == [:data, :path, :url, :email, :web]
|
15
|
+
obj.required_attributes.collect(&:name).should == [:name, :data, :path, :url, :email, :web]
|
16
|
+
|
17
|
+
obj.attr_present?(:name).should == true
|
18
|
+
obj.attr_missing?(:name).should == false
|
19
|
+
|
20
|
+
obj.attr_present?(:data).should == false
|
21
|
+
obj.attr_missing?(:data).should == true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should inherit" do
|
25
|
+
obj = KlassHelper::ChildKlass.new(:name => 'myvalue')
|
26
|
+
|
27
|
+
obj.name.should == 'myvalue'
|
28
|
+
|
29
|
+
obj.attr_required?(:name).should == true
|
30
|
+
obj.attr_required?(:title).should == false
|
31
|
+
obj.attr_required?(:format).should == false
|
32
|
+
|
33
|
+
obj.missing_attributes.collect(&:name).should == [:data, :path, :url, :email, :web]
|
34
|
+
obj.required_attributes.collect(&:name).should == [:name, :data, :path, :url, :email, :web]
|
35
|
+
|
36
|
+
obj.attr_present?(:name).should == true
|
37
|
+
obj.attr_missing?(:name).should == false
|
38
|
+
|
39
|
+
obj.attr_present?(:data).should == false
|
40
|
+
obj.attr_missing?(:data).should == true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should allow mutual exclusion" do
|
44
|
+
obj = KlassHelper::ChildKlass.new(:name => 'myvalue')
|
45
|
+
|
46
|
+
obj.missing_attributes.collect(&:name).should == [:data, :path, :url, :email, :web]
|
47
|
+
obj.required_attributes.collect(&:name).should == [:name, :data, :path, :url, :email, :web]
|
48
|
+
|
49
|
+
obj.path = 'data.csv'
|
50
|
+
obj.missing_attributes.collect(&:name).should == [:email, :web]
|
51
|
+
obj.required_attributes.collect(&:name).should == [:name, :path, :email, :web]
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should write attributes through the setters" do
|
55
|
+
obj = KlassHelper::ChildKlass.new(:name => 'myvalue', :title => 'mytitle')
|
56
|
+
|
57
|
+
obj.name.should == 'myvalue'
|
58
|
+
obj.title.should == 'mytitlechild'
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ValueObj
|
4
|
+
attr_accessor :name
|
5
|
+
|
6
|
+
def initialize(attrs = {})
|
7
|
+
@name = attrs[:name]
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_name_required?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
|
14
|
+
def serialized_name(name)
|
15
|
+
name + 'method'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe AttrHelper::BaseAttr do
|
20
|
+
it "should initialize" do
|
21
|
+
valueObj = ValueObj.new(:name => 'value')
|
22
|
+
attribute = AttrHelper::BaseAttr.new(:name)
|
23
|
+
|
24
|
+
attribute.name.should == :name
|
25
|
+
attribute.key.should == 'name'
|
26
|
+
attribute.serialize.should == true
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "Serialization" do
|
30
|
+
it "should serialize by default" do
|
31
|
+
valueObj = ValueObj.new(:name => 'value')
|
32
|
+
attribute = AttrHelper::BaseAttr.new(:name)
|
33
|
+
|
34
|
+
attribute.serializable?.should == true
|
35
|
+
attribute.serialized(valueObj).should == 'value'
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should serialize with a proc" do
|
39
|
+
valueObj = ValueObj.new(:name => 'value')
|
40
|
+
attribute = AttrHelper::BaseAttr.new(:name, :serialize => Proc.new{|name| name + 'proc'})
|
41
|
+
|
42
|
+
attribute.serializable?.should == true
|
43
|
+
attribute.serialized(valueObj).should == 'valueproc'
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should serialize with a symbol" do
|
47
|
+
valueObj = ValueObj.new(:name => 'value')
|
48
|
+
attribute = AttrHelper::BaseAttr.new(:name, :serialize => :serialized_name)
|
49
|
+
|
50
|
+
attribute.serializable?.should == true
|
51
|
+
attribute.serialized(valueObj).should == 'valuemethod'
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should disable serialization" do
|
55
|
+
valueObj = ValueObj.new(:name => 'value')
|
56
|
+
attribute = AttrHelper::BaseAttr.new(:name, :serialize => false)
|
57
|
+
|
58
|
+
attribute.serializable?.should == false
|
59
|
+
attribute.serialized(valueObj).should == nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ValueObj
|
4
|
+
attr_accessor :name
|
5
|
+
|
6
|
+
def initialize(attrs = {})
|
7
|
+
@name = attrs[:name]
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_name_required?
|
11
|
+
true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe AttrHelper::RequiredAttr do
|
16
|
+
it "should initialize" do
|
17
|
+
valueObj = ValueObj.new(:name => 'value')
|
18
|
+
attribute = AttrHelper::RequiredAttr.new(:name)
|
19
|
+
|
20
|
+
attribute.name.should == :name
|
21
|
+
attribute.key.should == 'name'
|
22
|
+
attribute.serialize.should == true
|
23
|
+
attribute.required?(valueObj).should == true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should check for if requirement with a proc" do
|
27
|
+
valueObj = ValueObj.new(:name => 'value')
|
28
|
+
attribute = AttrHelper::RequiredAttr.new(:name, :if => Proc.new{|parent| true})
|
29
|
+
attribute.required?(valueObj).should == true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should check for if requirement with a symbol" do
|
33
|
+
valueObj = ValueObj.new(:name => 'value')
|
34
|
+
attribute = AttrHelper::RequiredAttr.new(:name, :if => :is_name_required?)
|
35
|
+
attribute.required?(valueObj).should == true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should check for unless requirement with a proc" do
|
39
|
+
valueObj = ValueObj.new(:name => 'value')
|
40
|
+
attribute = AttrHelper::RequiredAttr.new(:name, :unless => Proc.new{|parent| true})
|
41
|
+
attribute.required?(valueObj).should == false
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should check for unless requirement with a symbol" do
|
45
|
+
valueObj = ValueObj.new(:name => 'value')
|
46
|
+
attribute = AttrHelper::RequiredAttr.new(:name, :unless => :is_name_required?)
|
47
|
+
attribute.required?(valueObj).should == false
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataPackage::Dialect do
|
4
|
+
let(:json) {
|
5
|
+
{
|
6
|
+
"delimiter" => "\t",
|
7
|
+
"doublequote" => false,
|
8
|
+
"lineterminator" => "\n",
|
9
|
+
"quotechar" => "\"",
|
10
|
+
"skipinitialspace" => true
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
it "should initialize with defaults" do
|
15
|
+
dialect = DataPackage::Dialect.new
|
16
|
+
|
17
|
+
dialect.delimiter.should == ','
|
18
|
+
dialect.double_quote.should == false
|
19
|
+
dialect.line_terminator.should == "\n"
|
20
|
+
dialect.quote_char.should == "\""
|
21
|
+
dialect.skip_initial_space.should == false
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should initialize and serialize" do
|
25
|
+
dialect = DataPackage::Dialect.new(json)
|
26
|
+
|
27
|
+
dialect.delimiter.should == "\t"
|
28
|
+
dialect.double_quote.should == false
|
29
|
+
dialect.line_terminator.should == "\n"
|
30
|
+
dialect.quote_char.should == "\""
|
31
|
+
dialect.skip_initial_space.should == true
|
32
|
+
|
33
|
+
dialect.to_json.should == Yajl::Encoder.encode(json, :pretty => true)
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataPackage::Field do
|
4
|
+
let(:json) {
|
5
|
+
{
|
6
|
+
'name' => 'income',
|
7
|
+
'type' => 'number',
|
8
|
+
'title' => 'Personal Income',
|
9
|
+
'description' => 'My Desc'
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
it "should initialize and serialize" do
|
14
|
+
field = DataPackage::Field.new(json)
|
15
|
+
|
16
|
+
field.type.should == :number
|
17
|
+
field.name.should == json['name']
|
18
|
+
field.title.should == json['title']
|
19
|
+
field.description.should == json['description']
|
20
|
+
|
21
|
+
field.to_hash.should == json
|
22
|
+
field.to_json.should == Yajl::Encoder.encode(field.to_hash, :pretty => true)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should require a name" do
|
26
|
+
field = DataPackage::Field.new
|
27
|
+
field.missing_attributes.collect(&:name).should == [:name]
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataPackage::License do
|
4
|
+
let(:json) {
|
5
|
+
{
|
6
|
+
'id' => 'PDDL',
|
7
|
+
'url' => 'http://opendatacommons.org/licenses/pddl/'
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
it "should initialize and serialize" do
|
12
|
+
license = DataPackage::License.new(json)
|
13
|
+
|
14
|
+
license.id.should == 'PDDL'
|
15
|
+
license.url.should == 'http://opendatacommons.org/licenses/pddl/'
|
16
|
+
license.to_json.should == Yajl::Encoder.encode(json, :pretty => true)
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataPackage::Package do
|
4
|
+
let(:tmpdir) {
|
5
|
+
Dir.mktmpdir
|
6
|
+
}
|
7
|
+
|
8
|
+
let(:package_path) {
|
9
|
+
File.join(base_path, 'package')
|
10
|
+
}
|
11
|
+
|
12
|
+
it "should init" do
|
13
|
+
package = DataPackage::Package.init(tmpdir, 'mypackage')
|
14
|
+
|
15
|
+
package.name.should == 'mypackage'
|
16
|
+
package.version.should == '0.0.1'
|
17
|
+
package.resources.should == nil
|
18
|
+
package.base_path.should == tmpdir
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should raise on open if the package file doesn't exist" do
|
22
|
+
expect { package = DataPackage::Package.open(tmpdir) }.to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should check if a package exists" do
|
26
|
+
DataPackage::Package.exist?(package_path).should == true
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should initialize and serialize" do
|
30
|
+
package = DataPackage::Package.open(package_path)
|
31
|
+
|
32
|
+
package.name.should == 'standard'
|
33
|
+
package.title.should == 'Standard Data Package'
|
34
|
+
package.version.should == '0.0.1'
|
35
|
+
|
36
|
+
package.resources.length.should == 1
|
37
|
+
|
38
|
+
package.resources.first.schema.fields.length.should == 10
|
39
|
+
package.resources.first.schema.primary_key.should == ['id']
|
40
|
+
|
41
|
+
package.sources.length.should == 1
|
42
|
+
package.licenses.length.should == 1
|
43
|
+
package.maintainers.length.should == 1
|
44
|
+
package.contributors.length.should == 1
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should save the package" do
|
48
|
+
package = DataPackage::Package.open(package_path)
|
49
|
+
|
50
|
+
package.base_path = tmpdir
|
51
|
+
package.name = "tested_package"
|
52
|
+
|
53
|
+
package.save
|
54
|
+
|
55
|
+
reopened = DataPackage::Package.open(tmpdir)
|
56
|
+
|
57
|
+
reopened.name.should == "tested_package"
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataPackage::Person do
|
4
|
+
let(:json) {
|
5
|
+
{
|
6
|
+
'name' => 'Josh F',
|
7
|
+
'email' => 'josh@modeanalytics.com',
|
8
|
+
'web' => 'http://www.modeanalytics.com/josh'
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
it "should initialize and serialize" do
|
13
|
+
person = DataPackage::Person.new(json)
|
14
|
+
|
15
|
+
person.name.should == 'Josh F'
|
16
|
+
person.email.should == 'josh@modeanalytics.com'
|
17
|
+
person.web.should == 'http://www.modeanalytics.com/josh'
|
18
|
+
|
19
|
+
person.to_json.should == Yajl::Encoder.encode(json, :pretty => true)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'resource_helper'
|
3
|
+
|
4
|
+
describe DataPackage::Resource do
|
5
|
+
it "should initialize and serialize" do
|
6
|
+
resource = DataPackage::Resource.new(base_path, standard_resource)
|
7
|
+
|
8
|
+
resource.format.should == 'csv'
|
9
|
+
resource.name.should == 'standard'
|
10
|
+
resource.path.should == 'standard.csv'
|
11
|
+
|
12
|
+
resource.schema.fields.length.should == 10
|
13
|
+
resource.schema.primary_key.should == ['id']
|
14
|
+
|
15
|
+
resource.to_hash.should == standard_resource.merge('format' => 'csv', 'dialect' => DataPackage::Dialect.new.to_hash)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "#each_row" do
|
19
|
+
it "should enumerate over inline data" do
|
20
|
+
resource = DataPackage::Resource.new(base_path, inline_resource)
|
21
|
+
|
22
|
+
row_count = 0
|
23
|
+
resource.each_row do |row|
|
24
|
+
row_count += 1
|
25
|
+
end
|
26
|
+
row_count.should == 3
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should enumerate over local file data" do
|
30
|
+
resource = DataPackage::Resource.new(base_path, standard_resource)
|
31
|
+
|
32
|
+
row_count = 0
|
33
|
+
resource.each_row do |row|
|
34
|
+
row_count += 1
|
35
|
+
end
|
36
|
+
row_count.should == 10
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not enumerate URL data" do
|
40
|
+
resource = DataPackage::Resource.new(base_path, http_resource)
|
41
|
+
expect{ resource.each_row{|row| nil} }.to raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise if the data format is unexpected" do
|
45
|
+
resource = DataPackage::Resource.new(base_path, standard_resource.merge('format' => 'unknown'))
|
46
|
+
expect{ resource.each_row{|row| nil} }.to raise_error
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise if data, path or url aren't present" do
|
50
|
+
invalid = standard_resource.dup
|
51
|
+
invalid.delete('path')
|
52
|
+
|
53
|
+
resource = DataPackage::Resource.new(base_path, invalid)
|
54
|
+
expect{ resource.each_row{|row| nil} }.to raise_error
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataPackage::Schema do
|
4
|
+
let(:json) {
|
5
|
+
{
|
6
|
+
'fields' => [
|
7
|
+
{
|
8
|
+
'name' => 'income',
|
9
|
+
'type' => 'number'
|
10
|
+
}
|
11
|
+
],
|
12
|
+
|
13
|
+
'primaryKey' => ['income']
|
14
|
+
}
|
15
|
+
}
|
16
|
+
|
17
|
+
it "should initialize" do
|
18
|
+
schema = DataPackage::Schema.new(json)
|
19
|
+
|
20
|
+
schema.fields.length.should == 1
|
21
|
+
schema.fields.first.name.should == 'income'
|
22
|
+
schema.primary_key.should == ['income']
|
23
|
+
schema.to_json.should == Yajl::Encoder.encode(json, :pretty => true)
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe DataPackage::Source do
|
4
|
+
let(:json) {
|
5
|
+
{
|
6
|
+
'name' => 'Josh F',
|
7
|
+
'email' => 'josh@modeanalytics.com',
|
8
|
+
'web' => 'http://www.modeanalytics.com/josh'
|
9
|
+
}
|
10
|
+
}
|
11
|
+
|
12
|
+
it "should initialize and serialize" do
|
13
|
+
person = DataPackage::Source.new(json)
|
14
|
+
|
15
|
+
person.name.should == 'Josh F'
|
16
|
+
person.email.should == 'josh@modeanalytics.com'
|
17
|
+
person.web.should == 'http://www.modeanalytics.com/josh'
|
18
|
+
|
19
|
+
person.to_hash.should == json
|
20
|
+
person.to_json.should == Yajl::Encoder.encode(person.to_hash, :pretty => true)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
{
|
2
|
+
"name": "standard",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"title": "Standard Data Package",
|
5
|
+
|
6
|
+
"sources": [
|
7
|
+
{
|
8
|
+
"name": "Josh F",
|
9
|
+
"email": "josh@modeanalytics.com",
|
10
|
+
"web": "http://www.modeanalytics.com/josh"
|
11
|
+
}
|
12
|
+
],
|
13
|
+
|
14
|
+
"licenses": [
|
15
|
+
{
|
16
|
+
"id": "PDDL",
|
17
|
+
"url": "http://opendatacommons.org/licenses/pddl/"
|
18
|
+
}
|
19
|
+
],
|
20
|
+
|
21
|
+
"maintainers": [
|
22
|
+
{
|
23
|
+
"name": "Josh F",
|
24
|
+
"email": "josh@modeanalytics.com",
|
25
|
+
"web": "http://www.modeanalytics.com/josh"
|
26
|
+
}
|
27
|
+
],
|
28
|
+
|
29
|
+
"contributors": [
|
30
|
+
{
|
31
|
+
"name": "Josh F",
|
32
|
+
"email": "josh@modeanalytics.com",
|
33
|
+
"web": "http://www.modeanalytics.com/josh"
|
34
|
+
}
|
35
|
+
],
|
36
|
+
|
37
|
+
"resources": [
|
38
|
+
{
|
39
|
+
"name": "standard",
|
40
|
+
"path": "standard.csv",
|
41
|
+
|
42
|
+
"dialect": {
|
43
|
+
"delimiter": ","
|
44
|
+
},
|
45
|
+
|
46
|
+
"schema": {
|
47
|
+
"fields": [
|
48
|
+
{
|
49
|
+
"name": "id",
|
50
|
+
"type": "integer"
|
51
|
+
},
|
52
|
+
{
|
53
|
+
"name": "first_name",
|
54
|
+
"type": "string"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"name": "last_name",
|
58
|
+
"type": "string"
|
59
|
+
},
|
60
|
+
{
|
61
|
+
"name": "email",
|
62
|
+
"type": "string"
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"name": "country",
|
66
|
+
"type": "string"
|
67
|
+
},
|
68
|
+
{
|
69
|
+
"name": "ip_address",
|
70
|
+
"type": "string"
|
71
|
+
},
|
72
|
+
{
|
73
|
+
"name": "amount",
|
74
|
+
"type": "number"
|
75
|
+
},
|
76
|
+
{
|
77
|
+
"name": "active",
|
78
|
+
"type": "boolean"
|
79
|
+
},
|
80
|
+
{
|
81
|
+
"name": "activated_at",
|
82
|
+
"type": "datetime"
|
83
|
+
},
|
84
|
+
{
|
85
|
+
"name": "address",
|
86
|
+
"type": "string"
|
87
|
+
}
|
88
|
+
],
|
89
|
+
|
90
|
+
"primaryKey": ["id"]
|
91
|
+
}
|
92
|
+
}
|
93
|
+
]
|
94
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
id,first_name,last_name,email,country,ip_address,amount,active,activated_at,address
|
2
|
+
1,Todd,Hamilton,thamilton@plambee.edu,Norfolk Island,66.157.128.241,$7.72,true,10/3/1955,0582 Dwight Street
|
3
|
+
2,Melissa,Kelly,mkelly@twinte.name,Singapore,204.221.167.233,$4.33,false,7/9/2013,06 Cardinal Crossing
|
4
|
+
3,Donald,Wheeler,dwheeler@edgeify.mil,Madagascar,34.201.104.193,$2.92,true,12/12/1993,4 Del Sol Hill
|
5
|
+
4,Ruby,Hall,rhall@cogilith.com,USSR,237.243.109.67,$8.27,false,12/15/1975,7 Ramsey Avenue
|
6
|
+
5,Jessica,Cole,jcole@shuffletag.info,Cyprus,25.40.138.137,$8.16,false,6/2/1939,8142 Novick Hill
|
7
|
+
6,Doris,Nelson,dnelson@zoombox.biz,Svalbard and Jan Mayen Islands,233.43.155.229,$6.26,false,5/23/1948,596 Veith Road
|
8
|
+
7,Robert,Hansen,rhansen@miboo.edu,Ghana,41.194.33.211,$4.90,true,9/28/1999,529 Oak Pass
|
9
|
+
8,Matthew,Freeman,mfreeman@midel.name,Sudan,53.186.162.65,$6.63,false,5/24/1996,70682 Declaration Center
|
10
|
+
9,Julia,Nelson,jnelson@skajo.net,Vatican City State (Holy See),249.49.124.178,$9.80,true,1/26/1940,96 Hermina Lane
|
11
|
+
10,Wanda,Palmer,wpalmer@ntags.biz,Indonesia,0.200.163.200,$5.89,false,1/1/1959,26837 Donald Trail
|
@@ -0,0 +1,11 @@
|
|
1
|
+
id,first_name,last_name,email,country,ip_address,amount,active,activated_at,address
|
2
|
+
1,Todd,Hamilton,thamilton@plambee.edu,Norfolk Island,66.157.128.241,$7.72,true,10/3/1955,0582 Dwight Street
|
3
|
+
2,Melissa,Kelly,mkelly@twinte.name,Singapore,204.221.167.233,$4.33,false,7/9/2013,06 Cardinal Crossing
|
4
|
+
3,Donald,Wheeler,dwheeler@edgeify.mil,Madagascar,34.201.104.193,$2.92,true,12/12/1993,4 Del Sol Hill
|
5
|
+
4,Ruby,Hall,rhall@cogilith.com,USSR,237.243.109.67,$8.27,false,12/15/1975,7 Ramsey Avenue
|
6
|
+
5,Jessica,Cole,jcole@shuffletag.info,Cyprus,25.40.138.137,$8.16,false,6/2/1939,8142 Novick Hill
|
7
|
+
6,Doris,Nelson,dnelson@zoombox.biz,Svalbard and Jan Mayen Islands,233.43.155.229,$6.26,false,5/23/1948,596 Veith Road
|
8
|
+
7,Robert,Hansen,rhansen@miboo.edu,Ghana,41.194.33.211,$4.90,true,9/28/1999,529 Oak Pass
|
9
|
+
8,Matthew,Freeman,mfreeman@midel.name,Sudan,53.186.162.65,$6.63,false,5/24/1996,70682 Declaration Center
|
10
|
+
9,Julia,Nelson,jnelson@skajo.net,Vatican City State (Holy See),249.49.124.178,$9.80,true,1/26/1940,96 Hermina Lane
|
11
|
+
10,Wanda,Palmer,wpalmer@ntags.biz,Indonesia,0.200.163.200,$5.89,false,1/1/1959,26837 Donald Trail
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module KlassHelper
|
2
|
+
class BaseKlass
|
3
|
+
include AttrHelper
|
4
|
+
include AttrHelper::Serialization
|
5
|
+
|
6
|
+
attr_required :name
|
7
|
+
attr_optional :title
|
8
|
+
attr_optional :format
|
9
|
+
|
10
|
+
attr_required :data, :if => Proc.new{ |o| o.path.nil? && o.url.nil? }
|
11
|
+
attr_required :path, :if => Proc.new{ |o| o.data.nil? && o.url.nil? }
|
12
|
+
attr_required :url, :if => Proc.new{ |o| o.data.nil? && o.path.nil? }
|
13
|
+
|
14
|
+
attr_required :dialect, :if => :format_requires_dialect?
|
15
|
+
|
16
|
+
attr_required :email, :unless => :empty_name?
|
17
|
+
attr_required :web, :unless => Proc.new{ |o| o.name.nil? }
|
18
|
+
|
19
|
+
def initialize(attrs = {})
|
20
|
+
write_attributes(attrs)
|
21
|
+
end
|
22
|
+
|
23
|
+
def title=(value)
|
24
|
+
write_attribute(:title, value + 'test')
|
25
|
+
end
|
26
|
+
|
27
|
+
def format_requires_dialect?
|
28
|
+
format == 'csv'
|
29
|
+
end
|
30
|
+
|
31
|
+
def empty_name?
|
32
|
+
name.nil?
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class ChildKlass < BaseKlass
|
37
|
+
def title=(value)
|
38
|
+
write_attribute(:title, value + 'child')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|