tableschema 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +14 -0
  5. data/CHANGELOG.md +31 -0
  6. data/CODE_OF_CONDUCT.md +49 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +274 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +14 -0
  12. data/bin/setup +8 -0
  13. data/etc/schemas/geojson.json +209 -0
  14. data/etc/schemas/json-table-schema.json +102 -0
  15. data/lib/tableschema.rb +42 -0
  16. data/lib/tableschema/constraints/constraints.rb +76 -0
  17. data/lib/tableschema/constraints/enum.rb +14 -0
  18. data/lib/tableschema/constraints/max_length.rb +15 -0
  19. data/lib/tableschema/constraints/maximum.rb +14 -0
  20. data/lib/tableschema/constraints/min_length.rb +15 -0
  21. data/lib/tableschema/constraints/minimum.rb +14 -0
  22. data/lib/tableschema/constraints/pattern.rb +14 -0
  23. data/lib/tableschema/constraints/required.rb +32 -0
  24. data/lib/tableschema/data.rb +60 -0
  25. data/lib/tableschema/exceptions.rb +28 -0
  26. data/lib/tableschema/field.rb +41 -0
  27. data/lib/tableschema/helpers.rb +48 -0
  28. data/lib/tableschema/infer.rb +143 -0
  29. data/lib/tableschema/model.rb +73 -0
  30. data/lib/tableschema/schema.rb +36 -0
  31. data/lib/tableschema/table.rb +51 -0
  32. data/lib/tableschema/types/any.rb +23 -0
  33. data/lib/tableschema/types/array.rb +37 -0
  34. data/lib/tableschema/types/base.rb +54 -0
  35. data/lib/tableschema/types/boolean.rb +35 -0
  36. data/lib/tableschema/types/date.rb +56 -0
  37. data/lib/tableschema/types/datetime.rb +63 -0
  38. data/lib/tableschema/types/geojson.rb +38 -0
  39. data/lib/tableschema/types/geopoint.rb +56 -0
  40. data/lib/tableschema/types/integer.rb +35 -0
  41. data/lib/tableschema/types/null.rb +37 -0
  42. data/lib/tableschema/types/number.rb +60 -0
  43. data/lib/tableschema/types/object.rb +37 -0
  44. data/lib/tableschema/types/string.rb +64 -0
  45. data/lib/tableschema/types/time.rb +55 -0
  46. data/lib/tableschema/validate.rb +54 -0
  47. data/lib/tableschema/version.rb +3 -0
  48. data/tableschema.gemspec +32 -0
  49. metadata +231 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8c0ad16c66b697b1822e72bba2e0761cb56031cc
4
+ data.tar.gz: 3ad60f103da3c8bbd032ddcd5b445bb7be112478
5
+ SHA512:
6
+ metadata.gz: e6536bf8cb973d1d6e69a10ec224f9514fbfd46ed6d24f86e75ac65c8abef980f2b96b51736a5100297c455c39695f9332759c3a787faeb2a6282e6325de61be
7
+ data.tar.gz: 41b4ba754262323227d57f71fb2964f65ba1e8d325c8a4ec4e83008bd1a511156d981a75555d92a061bcb0f54d030da65eedbc027375b116b92bd6d8505f9952
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ ---
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.1
5
+ - 2.4.1
6
+ before_install: gem install bundler -v 1.11.2
7
+ deploy:
8
+ provider: rubygems
9
+ api_key:
10
+ secure: wH1kuoIanHWL0ohGKyFtcXDusgR5T5qD2QnaQS9vjIG6a//ClpYpDZ3iSxHG9CkkrbaKJDVhcGsKJOECcQRnLQ2/g9PC84c4tMzfgp3q5w7FdWfxe86diS3sXN4gw6+Xb+KhueOhO6RaghG1BJPBd2kj2G8uw6f/KT+8qOMaS+IRpuW8FkO7x8CZvUSLbzai21kYaneDglb5j/AY/sF2s+jGO/3VPmMjaJCJ7pU84Wqby6PixPMiP2EKVyhx1fD8m8CcPTAfPhiwxq1AkxxFJIkty730ECzwDVfrF9Ph5dcoR57jPliCSctNVREele2Q4ItBxi5Da5U3PiqHYu6AZR4pARoPMaO8m/ZwfvRftzwNDd7jnnkxLgWRRKDofU6wuxB+Jg8V7CbThTXyPFgn8RXYsL4tshOCCmicT8fbKO/f+S21gSQtQI1fZc6dc0WZqRCCY50NLnRH0eAJzXKfQxQ7iuKsF/nfGmZiAmVCZRKWVlGjQ+v5q5erXr+nS9prWotg/CrWiGhPkhHuEj8izBXxclzAuQHGE0H+IRwZFT/7Ym1KUKKhMx5mFRpf4EqLQ+mzIe8+4Ogn8YQclVP/3j14FtGCFiRegqy8SSfsKxTunF6i76Nbdj8v5Pkb0NZzvRjaBkbhvYKIAmLK1GaYC0lQS7gaqXqCRS64XjvAOGQ=
11
+ gem: tableschema
12
+ on:
13
+ tags: true
14
+ repo: frictionlessdata/tableschema-rb
data/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Change Log
2
+
3
+ ## [v0.2.0](https://github.com/theodi/jsontableschema.rb/tree/v0.2.0) (2016-10-12)
4
+ [Full Changelog](https://github.com/theodi/jsontableschema.rb/compare/v0.1.0...v0.2.0)
5
+
6
+ **Closed issues:**
7
+
8
+ - Ability to stream data? [\#10](https://github.com/theodi/jsontableschema.rb/issues/10)
9
+ - Replace the types public API with the Field public API [\#9](https://github.com/theodi/jsontableschema.rb/issues/9)
10
+
11
+ **Merged pull requests:**
12
+
13
+ - Make sure streaming works [\#13](https://github.com/theodi/jsontableschema.rb/pull/13) ([pezholio](https://github.com/pezholio))
14
+ - Stream CSV [\#12](https://github.com/theodi/jsontableschema.rb/pull/12) ([pezholio](https://github.com/pezholio))
15
+ - Add `Field` class [\#11](https://github.com/theodi/jsontableschema.rb/pull/11) ([pezholio](https://github.com/pezholio))
16
+
17
+ ## [v0.1.0](https://github.com/theodi/jsontableschema.rb/tree/v0.1.0) (2016-09-19)
18
+ **Merged pull requests:**
19
+
20
+ - Deploy stuff [\#8](https://github.com/theodi/jsontableschema.rb/pull/8) ([pezholio](https://github.com/pezholio))
21
+ - Infer schema [\#7](https://github.com/theodi/jsontableschema.rb/pull/7) ([pezholio](https://github.com/pezholio))
22
+ - Work with a table [\#6](https://github.com/theodi/jsontableschema.rb/pull/6) ([pezholio](https://github.com/pezholio))
23
+ - Data conversion [\#5](https://github.com/theodi/jsontableschema.rb/pull/5) ([pezholio](https://github.com/pezholio))
24
+ - Add constraints [\#4](https://github.com/theodi/jsontableschema.rb/pull/4) ([pezholio](https://github.com/pezholio))
25
+ - Cast and validate types [\#3](https://github.com/theodi/jsontableschema.rb/pull/3) ([pezholio](https://github.com/pezholio))
26
+ - Schema model [\#2](https://github.com/theodi/jsontableschema.rb/pull/2) ([pezholio](https://github.com/pezholio))
27
+ - Validate a schema [\#1](https://github.com/theodi/jsontableschema.rb/pull/1) ([pezholio](https://github.com/pezholio))
28
+
29
+
30
+
31
+ \* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at pezholio@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in tableschema.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 pezholio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,274 @@
1
+ # Table Schema
2
+ formerly known as JSON Table Schema
3
+
4
+ [![Travis](https://travis-ci.org/frictionlessdata/tableschema-rb.svg?branch=master)](https://travis-ci.org/frictionlessdata/tableschema-rb)
5
+ [![Coveralls](https://coveralls.io/repos/github/frictionlessdata/tableschema-rb/badge.svg?branch=master)](https://coveralls.io/github/frictionlessdata/tableschema-rb?branch=master)
6
+ [![Gem Version](http://img.shields.io/gem/v/tableschema.svg)](https://rubygems.org/gems/tableschema)
7
+ [![SemVer](https://img.shields.io/badge/versions-SemVer-brightgreen.svg)](http://semver.org/)
8
+ [![Gitter](https://img.shields.io/gitter/room/frictionlessdata/chat.svg)](https://gitter.im/frictionlessdata/chat)
9
+
10
+ A utility library for working with [Table Schema](https://specs.frictionlessdata.io/table-schema/) in Ruby.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ ```ruby
17
+ gem 'tableschema'
18
+ ```
19
+
20
+ And then execute:
21
+
22
+ $ bundle
23
+
24
+ Or install it yourself as:
25
+
26
+ $ gem install tableschema
27
+
28
+ ### Update from `jsontableschema`
29
+
30
+ The library and its corresponding gem was previously called `jsontableschema`.
31
+ Since version 0.3 the library was renamed `tableschema` and has a gem with the same name.
32
+
33
+ The gem `jsontableschema` is no longer maintained. Here are the steps to transition your code to `tableschema`:
34
+
35
+ 1. Replace
36
+ ```ruby
37
+ gem 'jsontableschema'
38
+ ```
39
+ with
40
+
41
+ ```ruby
42
+ gem 'tableschema', '0.3.0'
43
+ ```
44
+
45
+ 2. Replace module name `JsonTableSchema` with module name `TableSchema`. For example:
46
+
47
+ ```ruby
48
+ JsonTableSchema::Table.infer_schema(csv)
49
+ ```
50
+ with
51
+ ```ruby
52
+ TableSchema::Table.infer_schema(csv)
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ### Parse a CSV
58
+
59
+ Validate and cast data from a CSV as described by a schema.
60
+
61
+ ```ruby
62
+ schema = {
63
+ "fields": [
64
+ {
65
+ "name" => "id",
66
+ "title" => "Identifier",
67
+ "type" => "integer"
68
+ },
69
+ {
70
+ "name" => "title",
71
+ "title" => "Title",
72
+ "type" => "string"
73
+ }
74
+ ]
75
+ } # Can also be a URL or a path
76
+
77
+ csv = 'https://github.com/frictionlessdata/tableschema-rb/raw/master/spec/fixtures/simple_data.csv' # Can also be a url or array of arrays
78
+
79
+ table = TableSchema::Table.new(csv, schema)
80
+ table.rows
81
+ #=> [[1,'foo'],[2,'bar'],[3,'baz']]
82
+ ```
83
+
84
+ ### Infer a schema
85
+
86
+ If you don't have a schema for a CSV, and want to generate one, you can infer a schema like so:
87
+
88
+ ```ruby
89
+ csv = 'https://github.com/frictionlessdata/tableschema-rb/raw/master/spec/fixtures/simple_data.csv' # Can also be a url or array of arrays
90
+
91
+ table = TableSchema::Table.infer_schema(csv)
92
+ table.schema
93
+ #=> {"fields"=>[{"name"=>"id", "title"=>"", "description"=>"", "type"=>"string", "format"=>"default"}, {"name"=>"title", "title"=>"", "description"=>"", "type"=>"string", "format"=>"default"}]}
94
+ ```
95
+
96
+ ### Validate a schema
97
+
98
+ To validate that a schema meets the JSON Table Schema spec, you can pass a schema to the initializer like so:
99
+
100
+ ```ruby
101
+ schema_hash = {
102
+ "fields" => [
103
+ {
104
+ "name" => "id"
105
+ },
106
+ {
107
+ "name" => "height"
108
+ }
109
+ ]
110
+ }
111
+
112
+ schema = TableSchema::Schema.new(schema_hash)
113
+ schema.valid?
114
+ #=> true
115
+ ```
116
+
117
+ You can also pass a file path or URL to the initializer:
118
+
119
+ ```ruby
120
+ schema = TableSchema::Schema.new('http://example.org/schema.json')
121
+ schema.valid?
122
+ #=> true
123
+ ```
124
+
125
+ If the schema is invalid, you can access the errors via the `messages` attribute
126
+
127
+ ```ruby
128
+ schema_hash = {
129
+ "fields" => [
130
+ {
131
+ "name"=>"id",
132
+ "title"=>"Identifier",
133
+ "type"=>"integer"
134
+ },
135
+ {
136
+ "name"=>"title",
137
+ "title"=>"Title",
138
+ "type"=>"string"
139
+ }
140
+ ],
141
+ "primaryKey"=>"identifier"
142
+ }
143
+
144
+ schema.valid?
145
+ #=> false
146
+ schema.messages
147
+ #=> ["The JSON Table Schema primaryKey value `identifier` is not found in any of the schema's field names"]
148
+ ```
149
+
150
+ ## Schema Model
151
+
152
+ You can also access the schema via a Ruby model, with some useful methods for interaction:
153
+
154
+ ```ruby
155
+ schema_hash = {
156
+ "fields" => [
157
+ {
158
+ "name" => "id",
159
+ "type" => "string",
160
+ "constraints" => {
161
+ "required" => true,
162
+ }
163
+ },
164
+ {
165
+ "name" => "height",
166
+ "type" => "number"
167
+ }
168
+ ],
169
+ "primaryKey" => "id",
170
+ "foreignKeys" => [
171
+ {
172
+ "fields" => "state",
173
+ "reference" => {
174
+ "datapackage" => "http://data.okfn.org/data/mydatapackage/",
175
+ "resource" => "the-resource",
176
+ "fields" => "state_id"
177
+ }
178
+ }
179
+ ]
180
+ }
181
+
182
+ schema = TableSchema::Schema.new(schema_hash)
183
+
184
+ schema.headers
185
+ #=> ["id", "height"]
186
+ schema.required_headers
187
+ #=> ["id"]
188
+ schema.fields
189
+ #=> [{"name"=>"id", "constraints"=>{"required"=>true}, "type"=>"string", "format"=>"default"}, {"name"=>"height", "type"=>"number", "format"=>"default"}]
190
+ schema.primary_keys
191
+ #=> ["id"]
192
+ schema.foreign_keys
193
+ #=> [{"fields" => "state", "reference" => { "datapackage" => "http://data.okfn.org/data/mydatapackage/", "resource" => "the-resource", "fields" => "state_id" } } ]
194
+ schema.get_field('id')
195
+ #=> {"name"=>"id", "constraints"=>{"required"=>true}, "type"=>"string", "format"=>"default"}
196
+ schema.has_field?('foo')
197
+ #=> false
198
+ schema.get_type('id')
199
+ #=> 'string'
200
+ schema.get_fields_by_type('string')
201
+ #=> [{"name"=>"id", "constraints"=>{"required"=>true}, "type"=>"string", "format"=>"default"}, {"name"=>"height", "type"=>"string", "format"=>"default"}]
202
+ schema.get_constraints('id')
203
+ #=> {"required" => true}
204
+ schema.cast_row(['string', '10.0'])
205
+ #=> ['string', 10.0]
206
+ schema.cast([['foo', '12.0'],['bar', '10.0']])
207
+ #=> [['foo', 12.0],['bar', 10.0]]
208
+ ```
209
+
210
+ When casting a row (using `cast_row`), or a number of rows (using `cast`), by default the converter will fail on the first error it finds. If you pass `false` as the second argument, the errors will be collected into a `errors` attribute for you to review later. For example:
211
+
212
+ ```ruby
213
+ schema_hash = {
214
+ "fields" => [
215
+ {
216
+ "name" => "id",
217
+ "type" => "string",
218
+ "constraints" => {
219
+ "required" => true,
220
+ }
221
+ },
222
+ {
223
+ "name" => "height",
224
+ "type" => "number"
225
+ }
226
+ ]
227
+ }
228
+
229
+ schema = TableSchema::Schema.new(schema_hash)
230
+
231
+ rows = [
232
+ ['foo', 'notanumber'],
233
+ ['bar', 'notanumber'],
234
+ ['wrong column count']
235
+ ]
236
+
237
+ schema.cast(rows)
238
+ #=> TableSchema::InvalidCast: notanumber is not a number
239
+ schema.cast(rows, false)
240
+ #=> TableSchema::MultipleInvalid
241
+ schema.errors
242
+ #=> [#<TableSchema::InvalidCast: notanumber is not a number>, #<TableSchema::InvalidCast: notanumber is not a number>, #<TableSchema::ConversionError: The number of items to convert (1) does not match the number of headers in the schema (2)>]
243
+ ```
244
+
245
+ ## Field
246
+
247
+ ```ruby
248
+ # Init field
249
+ field = TableSchema::Field.new({'type': 'number'})
250
+
251
+ # Cast a value
252
+ field.cast_value('12345')
253
+ #=> 12345.0
254
+ ```
255
+
256
+ Data values can be cast to native Ruby objects with a Field instance. Type instances can be initialized with f[ield descriptors](http://dataprotocols.org/json-table-schema/#field-descriptors). This allows formats and constraints to be defined.
257
+
258
+ Casting a value will check the value is of the expected type, is in the correct format, and complies with any constraints imposed by a schema. E.g. a date value (in ISO 8601 format) can be cast with a DateType instance. Values that can't be cast will raise an `InvalidCast` exception.
259
+
260
+ Casting a value that doesn't meet the constraints will raise a `ConstraintError` exception.
261
+
262
+ ## Development
263
+
264
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
265
+
266
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
267
+
268
+ ## Contributing
269
+
270
+ Bug reports and pull requests are welcome on GitHub at https://github.com/frictionlessdata/tableschema-rb. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
271
+
272
+ ## License
273
+
274
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "tableschema"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start