forked from Data-Liberation-Front/csvlint.rb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathschema.rb
99 lines (86 loc) · 2.95 KB
/
schema.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
module Csvlint
class Schema
include Csvlint::ErrorCollector
attr_reader :uri, :fields, :title, :description
def initialize(uri, fields = [], title = nil, description = nil)
@uri = uri
@fields = fields
@title = title
@description = description
reset
end
class << self
extend Gem::Deprecate
def from_json_table(uri, json)
fields = []
json["fields"]&.each do |field_desc|
fields << Csvlint::Field.new(field_desc["name"], field_desc["constraints"],
field_desc["title"], field_desc["description"])
end
Schema.new(uri, fields, json["title"], json["description"])
end
def from_csvw_metadata(uri, json)
Csvlint::Csvw::TableGroup.from_json(uri, json)
end
# Deprecated method signature
def load_from_json(uri, output_errors = true)
load_from_uri(uri, output_errors)
end
deprecate :load_from_json, :load_from_uri, 2018, 1
def load_from_uri(uri, output_errors = true)
load_from_string(uri, URI.open(uri).read, output_errors)
rescue OpenURI::HTTPError, Errno::ENOENT => e
raise e
end
def load_from_string(uri, string, output_errors = true)
json = JSON.parse(string)
if json["@context"]
uri = "file:#{File.expand_path(uri)}" unless /^http(s)?/.match?(uri.to_s)
Schema.from_csvw_metadata(uri, json)
else
Schema.from_json_table(uri, json)
end
rescue TypeError
# NO IDEA what this was even trying to do - SP 20160526
rescue Csvlint::Csvw::MetadataError => e
raise e
rescue => e
if output_errors === true
warn e.class
warn e.message
warn e.backtrace
end
Schema.new(nil, [], "malformed", "malformed")
end
end
def validate_header(header, source_url = nil, validate = true)
reset
found_header = header.to_csv(row_sep: "")
expected_header = @fields.map { |f| f.name }.to_csv(row_sep: "")
if found_header != expected_header
build_warnings(:malformed_header, :schema, 1, nil, found_header, "expectedHeader" => expected_header)
end
valid?
end
def validate_row(values, row = nil, all_errors = [], source_url = nil, validate = true)
reset
if values.length < fields.length
fields[values.size..-1].each_with_index do |field, i|
build_warnings(:missing_column, :schema, row, values.size + i + 1)
end
end
if values.length > fields.length
values[fields.size..-1].each_with_index do |data_column, i|
build_warnings(:extra_column, :schema, row, fields.size + i + 1)
end
end
fields.each_with_index do |field, i|
value = values[i] || ""
field.validate_column(value, row, i + 1, all_errors)
@errors += fields[i].errors
@warnings += fields[i].warnings
end
valid?
end
end
end