Skip to content

Commit ebe1868

Browse files
Merge pull request #21 from frictionlessdata/Go11PlusReadColumn
Add support to go 1.11 and go modules.
2 parents 52f13c3 + 73939f6 commit ebe1868

File tree

166 files changed

+148
-17191
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

166 files changed

+148
-17191
lines changed

.travis.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@ go:
44
- 1.8.x
55
- 1.9.x
66
- 1.10.x
7-
7+
- 1.11.x
88
notificaitons:
99
email:
1010
recipients: [email protected]
1111
on_success: change
1212
on_failure: always
1313

14+
env:
15+
- GO111MODULE=on
16+
1417
before_install:
18+
- curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
19+
- dep ensure
1520
- go get github.com/mattn/goveralls
1621

1722
script:

Gopkg.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,17 @@
33
# datapackage-go
44
A Go library for working with [Data Packages](http://specs.frictionlessdata.io/data-package/).
55

6-
<!-- TOC -->
7-
86
- [datapackage-go](#datapackage-go)
9-
- [Install](#install)
10-
- [Main Features](#main-features)
11-
- [Loading and validating tabular data package descriptors](#loading-and-validating-tabular-data-package-descriptors)
12-
- [Accessing data package resources](#accessing-data-package-resources)
13-
- [Loading zip bundles](#loading-zip-bundles)
14-
- [Creating a zip bundle with the data package.](#creating-a-zip-bundle-with-the-data-package)
15-
- [CSV dialect support](#csv-dialect-support)
16-
- [Loading multipart resources](#loading-multipart-resources)
17-
- [Loading non-tabular resources](#loading-non-tabular-resources)
18-
- [Manipulating data packages programatically](#manipulating-data-packages-programatically)
19-
20-
<!-- /TOC -->
7+
- [Install](#install)
8+
- [Main Features](#main-features)
9+
- [Loading and validating tabular data package descriptors](#loading-and-validating-tabular-data-package-descriptors)
10+
- [Accessing data package resources](#accessing-data-package-resources)
11+
- [Loading zip bundles](#loading-zip-bundles)
12+
- [Creating a zip bundle with the data package.](#creating-a-zip-bundle-with-the-data-package)
13+
- [CSV dialect support](#csv-dialect-support)
14+
- [Loading multipart resources](#loading-multipart-resources)
15+
- [Loading non-tabular resources](#loading-non-tabular-resources)
16+
- [Manipulating data packages programatically](#manipulating-data-packages-programatically)
2117

2218
## Install
2319

@@ -95,7 +91,7 @@ fmt.Printf("+v", cities)
9591
// [{City:london Year:2017 Population:8780000} {City:paris Year:2017 Population:2240000} {City:rome Year:2017 Population:2860000}]
9692
```
9793

98-
Finally, if the data is to big to be loaded at once or if you would like to perform line-by-line processing, you could iterate through the resource contents:
94+
If the data is to big to be loaded at once or if you would like to perform line-by-line processing, you could iterate through the resource contents:
9995

10096
```go
10197
iter, _ := resource.Iter(csv.LoadHeaders())
@@ -109,6 +105,16 @@ for iter.Next() {
109105
// {City:paris Year:2017 Population:2240000}
110106
// {City:rome Year:2017 Population:2860000}]
111107
```
108+
109+
Or you might want to process specific columns, for instance to perform an statical analysis:
110+
111+
```go
112+
var population []float64
113+
resource.CastColumn("population", &population, csv.LoadHeaders())
114+
fmt.Println(ages)
115+
// Output: [8780000 2240000 2860000]
116+
```
117+
112118
### Loading zip bundles
113119

114120
It is very common to store the data in zip bundles containing the descriptor and data files. Those are natively supported by our the [datapackage.Load](https://godoc.org/github.com/frictionlessdata/datapackage-go/datapackage#Load) method. For example, lets say we have the following `package.zip` bundle:

datapackage/resource.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,25 @@ func (r *Resource) Cast(out interface{}, opts ...csv.CreationOpts) error {
343343
return sch.CastTable(tbl, out)
344344
}
345345

346+
// CastColumn casts a column from tabular resource contents.
347+
// The out argument must necessarily be the address for a slice. The slice
348+
// may be nil or previously allocated.
349+
func (r *Resource) CastColumn(name string, out interface{}, opts ...csv.CreationOpts) error {
350+
sch, err := r.GetSchema()
351+
if err != nil {
352+
return err
353+
}
354+
tab, err := r.GetTable(opts...)
355+
if err != nil {
356+
return err
357+
}
358+
col, err := tab.ReadColumn(name)
359+
if err != nil {
360+
return err
361+
}
362+
return sch.CastColumn(col, name, out)
363+
}
364+
346365
// NewResourceWithDefaultRegistry creates a new Resource from the passed-in descriptor.
347366
// It uses the default registry to validate the resource descriptor.
348367
func NewResourceWithDefaultRegistry(d map[string]interface{}) (*Resource, error) {

datapackage/resource_test.go

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,27 @@ import (
1010
"testing"
1111

1212
"github.com/frictionlessdata/datapackage-go/validator"
13+
"github.com/frictionlessdata/tableschema-go/csv"
14+
"github.com/frictionlessdata/tableschema-go/schema"
1315
"github.com/matryer/is"
1416
)
1517

18+
func ExampleResource_CastColumn() {
19+
resStr := `
20+
{
21+
"name": "col",
22+
"data": "name,age\nfoo,42\nbar,84",
23+
"format": "csv",
24+
"profile": "tabular-data-resource",
25+
"schema": {"fields": [{"name": "name", "type": "string"},{"name": "age", "type": "integer"}]}
26+
}`
27+
res, _ := NewResourceFromString(resStr, validator.MustInMemoryRegistry())
28+
var ages []float64
29+
res.CastColumn("age", &ages, csv.LoadHeaders())
30+
fmt.Println(ages)
31+
// Output: [42 84]
32+
}
33+
1634
func TestNewResourceWithDefaultRegistry(t *testing.T) {
1735
res, _ := NewResourceWithDefaultRegistry(r1)
1836
fmt.Println(res.Name())
@@ -152,9 +170,9 @@ func TestNew(t *testing.T) {
152170
map[string]interface{}{"name": "foo", "path": "foo.csv", "schema": ts.URL},
153171
validator.MustInMemoryRegistry(),
154172
)
155-
is.NoErr(err)
173+
is.NoErr(err) // Resource should be created successfully.
156174
sch, err := r.GetSchema()
157-
is.Equal(sch.Fields[0].Type, "string")
175+
is.Equal(sch.Fields[0].Type, schema.StringType)
158176
})
159177
t.Run("InvalidRemote", func(t *testing.T) {
160178
_, err := NewResource(
@@ -177,7 +195,7 @@ func TestNew(t *testing.T) {
177195
)
178196
is.NoErr(err)
179197
sch, err := r.GetSchema()
180-
is.Equal(sch.Fields[0].Type, "string")
198+
is.Equal(sch.Fields[0].Type, schema.StringType)
181199
})
182200
t.Run("InvalidLocal", func(t *testing.T) {
183201
_, err := NewResource(
@@ -457,3 +475,65 @@ func TestResource_RawRead(t *testing.T) {
457475
is.Equal(string(contents), "{\"foo\":\"1234\"}")
458476
})
459477
}
478+
479+
func TestResource_ReadColumn(t *testing.T) {
480+
resStr := `
481+
{
482+
"name": "col",
483+
"data": "name,age\nfoo,42\nbar,84",
484+
"format": "csv",
485+
"profile": "tabular-data-resource",
486+
"schema": {"fields": [{"name": "name", "type": "string"},{"name": "age", "type": "integer"}]}
487+
}`
488+
t.Run("Valid", func(t *testing.T) {
489+
is := is.New(t)
490+
res, err := NewResourceFromString(resStr, validator.MustInMemoryRegistry())
491+
is.NoErr(err)
492+
var ages []float64
493+
is.NoErr(res.CastColumn("age", &ages, csv.LoadHeaders()))
494+
is.Equal(float64(42), ages[0])
495+
is.Equal(float64(84), ages[1])
496+
})
497+
t.Run("NoSchema", func(t *testing.T) {
498+
res := NewUncheckedResource(map[string]interface{}{})
499+
var ages []float64
500+
if res.CastColumn("age", &ages) == nil {
501+
t.Fatal("want:err got:nil")
502+
}
503+
})
504+
t.Run("NoData", func(t *testing.T) {
505+
res := NewUncheckedResource(map[string]interface{}{
506+
"schema": map[string]interface{}{},
507+
})
508+
var ages []float64
509+
if res.CastColumn("age", &ages) == nil {
510+
t.Fatal("want:err got:nil")
511+
}
512+
})
513+
t.Run("HeaderNotFound", func(t *testing.T) {
514+
is := is.New(t)
515+
res, err := NewResourceFromString(resStr, validator.MustInMemoryRegistry())
516+
is.NoErr(err)
517+
var ages []float64
518+
if res.CastColumn("foo", &ages) == nil {
519+
t.Fatal("want:err got:nil")
520+
}
521+
})
522+
t.Run("FieldNotFound", func(t *testing.T) {
523+
is := is.New(t)
524+
resStr := `
525+
{
526+
"name": "col",
527+
"data": "name,age\nfoo,42\nbar,84",
528+
"format": "csv",
529+
"profile": "tabular-data-resource",
530+
"schema": {"fields": [{"name": "name", "type": "string"},{"name": "Age", "type": "integer"}]}
531+
}`
532+
res, err := NewResourceFromString(resStr, validator.MustInMemoryRegistry())
533+
is.NoErr(err)
534+
var ages []float64
535+
if res.CastColumn("age", &ages) == nil {
536+
t.Fatal("want:err got:nil")
537+
}
538+
})
539+
}

go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module github.com/frictionlessdata/datapackage-go
2+
3+
require (
4+
github.com/frictionlessdata/tableschema-go v0.1.5-0.20190521014818-f9bf38926664
5+
github.com/matryer/is v1.2.0
6+
github.com/santhosh-tekuri/jsonschema v1.2.4
7+
github.com/satori/go.uuid v1.2.0
8+
)

go.sum

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
github.com/frictionlessdata/tableschema-go v0.1.5-0.20190521014818-f9bf38926664 h1:IvuZMJ6dH1ye2bWmM8Yla6jj1xIPBR/nZJlm6P4ZSD4=
2+
github.com/frictionlessdata/tableschema-go v0.1.5-0.20190521014818-f9bf38926664/go.mod h1:OfuE6zbfQdlwx5q9vf5XWXEGJ0LYZcd9ML3zme5rP3k=
3+
github.com/matryer/is v0.0.0-20170112134659-c0323ceb4e99/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
4+
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
5+
github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=
6+
github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
7+
github.com/satori/go.uuid v1.1.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
8+
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
9+
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=

vendor/github.com/frictionlessdata/tableschema-go/.gitignore

Lines changed: 0 additions & 18 deletions
This file was deleted.

vendor/github.com/frictionlessdata/tableschema-go/.travis.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

vendor/github.com/frictionlessdata/tableschema-go/CONTRIBUTING.md

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)