dbf 2.0.13 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f839e25e2db42fd66421537fca0ec61feda2672a
4
- data.tar.gz: 11e90371ab59a88dfd30545c733d82735ed78d30
3
+ metadata.gz: f7051deaf2cb9c0f103fe91bb811ac576453e1c4
4
+ data.tar.gz: f0c06a0ca2a0cd6b2ac8e29eaa8d14f2b496a5d4
5
5
  SHA512:
6
- metadata.gz: 5a6741db87de74a98529687373a2b3193ac806791cae21e4b1b4f7e8d78d683919b27b6645f4e049e76c8b4fb905c03fd01c89f1250051ee36577a567a510a90
7
- data.tar.gz: b8b8bd2074c16570b9a2fe5effa2f02c564636d9a2c08e326cdf2c2e8c870ac78411af11389e1856746292fa7a5c53303972c90a7c498fa05f9fcbaa6e5bbe0b
6
+ metadata.gz: 4a963a10bdb5e02c5dce9b8b7f5d8446e636b4f07ab20a07c19611617edd5d3b5f461df2537ce8be97473a1ceafc2f9cd94a9f8bfcaff6fe3e1acbf4828bfab6
7
+ data.tar.gz: 1dbcdf3f5a5a84cc7fba894556f120e0fc23b4ca46572cf2ef9cb8fe4dac04a24ecf009f9e34786a75be8ec38f9144b38682496c22a3d4d61aee66d0ad97ab10
data/README.md CHANGED
@@ -17,14 +17,14 @@ database files
17
17
  subject line
18
18
  * Change log: <https://github.com/infused/dbf/blob/master/CHANGELOG.md>
19
19
 
20
+ NOTE: beginning with version 3 we have dropped support for Ruby 1.8 and 1.9. If you need support for older Rubies, please use 2.0.x (https://github.com/infused/dbf/tree/2_stable)
21
+
20
22
  ## Compatibility
21
23
 
22
24
  DBF is tested to work with the following versions of ruby:
23
25
 
24
- * MRI Ruby 1.8.6, 1.8.7, 1.9.1, 1.9.2, 1.9.3, 2.0.x, 2.1.x, 2.2.x
25
- * JRuby 1.7.x (1.8 and 1.9 modes), JRuby head
26
- * REE 1.8.7
27
- * Rubinius 2.1+
26
+ * MRI Ruby 2.0.x, 2.1.x, 2.2.x
27
+ * JRuby head
28
28
 
29
29
  ## Installation
30
30
 
@@ -11,7 +11,6 @@ Gem::Specification.new do |s|
11
11
  s.summary = 'Read xBase files'
12
12
  s.description = 'A small fast library for reading dBase, xBase, Clipper and FoxPro database files.'
13
13
  s.license = 'MIT'
14
-
15
14
  s.bindir = 'bin'
16
15
  s.executables = ['dbf']
17
16
  s.rdoc_options = ['--charset=UTF-8']
@@ -19,7 +18,5 @@ Gem::Specification.new do |s|
19
18
  s.files = Dir['[A-Z]*', '{bin,docs,lib,spec}/**/*', 'dbf.gemspec']
20
19
  s.test_files = Dir.glob('spec/**/*_spec.rb')
21
20
  s.require_paths = ['lib']
22
-
23
- s.required_rubygems_version = '>= 1.3.0'
24
- s.add_dependency 'fastercsv', '~> 1.5'
21
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.0')
25
22
  end
data/lib/dbf.rb CHANGED
@@ -1,9 +1,7 @@
1
1
  require 'date'
2
2
 
3
3
  require 'csv'
4
- if CSV.const_defined? :Reader
5
- require 'fastercsv'
6
- end
4
+ require 'json'
7
5
 
8
6
  require 'dbf/schema'
9
7
  require 'dbf/record'
@@ -71,6 +71,10 @@ module DBF
71
71
  end
72
72
  end
73
73
 
74
+ def to_hash
75
+ {name: name, type: type, length: length, decimal: decimal}
76
+ end
77
+
74
78
  private
75
79
 
76
80
  def type_cast_methods # nodoc
@@ -88,8 +92,8 @@ module DBF
88
92
  end
89
93
 
90
94
  def decode_date(value) # nodoc
91
- value.gsub!(' ', '0')
92
- value !~ /\S/ ? nil : Date.parse(value)
95
+ v = value.tr(' ', '0')
96
+ v !~ /\S/ ? nil : Date.parse(v)
93
97
  rescue
94
98
  nil
95
99
  end
@@ -72,6 +72,12 @@ module DBF
72
72
 
73
73
  private
74
74
 
75
+ def file_offset(attribute_name)
76
+ column = @columns.detect { |c| c.name == attribute_name.to_s }
77
+ index = @columns.index(column)
78
+ @columns[0, index + 1].compact.reduce(0) { |x, c| x += c.length }
79
+ end
80
+
75
81
  def method_missing(method, *args) # nodoc
76
82
  if (index = underscored_column_names.index(method.to_s))
77
83
  attributes[@columns[index].name]
@@ -21,15 +21,29 @@ module DBF
21
21
  # t.column :notes, :text
22
22
  # end
23
23
  #
24
+ # @param [Symbol] format Valid options are :activerecord and :json
24
25
  # @return [String]
25
- def schema
26
+ def schema(format = :activerecord)
27
+ supported_formats = [:activerecord, :json]
28
+ if supported_formats.include?(format)
29
+ send "#{format}_schema"
30
+ else
31
+ raise ArgumentError
32
+ end
33
+ end
34
+
35
+ def activerecord_schema
26
36
  s = "ActiveRecord::Schema.define do\n"
27
- s << " create_table \"#{File.basename(@data.path, ".*")}\" do |t|\n"
37
+ s << " create_table \"#{File.basename(@data.path, '.*')}\" do |t|\n"
28
38
  columns.each do |column|
29
39
  s << " t.column #{column.schema_definition}"
30
40
  end
31
41
  s << " end\nend"
32
42
  s
33
43
  end
44
+
45
+ def json_schema
46
+ columns.map(&:to_hash).to_json
47
+ end
34
48
  end
35
49
  end
@@ -38,7 +38,7 @@ module DBF
38
38
  }
39
39
 
40
40
  attr_reader :header
41
- attr_accessor :encoding # Source encoding (for ex. :cp1251)
41
+ attr_accessor :encoding
42
42
 
43
43
  # Opens a DBF::Table
44
44
  # Examples:
@@ -148,7 +148,7 @@ module DBF
148
148
  # @param [optional String] path Defaults to STDOUT
149
149
  def to_csv(path = nil)
150
150
  out_io = path ? File.open(path, 'w') : $stdout
151
- csv = csv_class.new(out_io, :force_quotes => true)
151
+ csv = CSV.new(out_io, force_quotes: true)
152
152
  csv << column_names
153
153
  each { |record| csv << record.to_a }
154
154
  end
@@ -227,9 +227,9 @@ module DBF
227
227
  private
228
228
 
229
229
  def build_columns # nodoc
230
- columns = []
231
230
  @data.seek(DBF_HEADER_SIZE)
232
- while !end_of_record?
231
+ columns = []
232
+ until end_of_record?
233
233
  column_data = @data.read(DBF_HEADER_SIZE)
234
234
  name, type, length, decimal = column_data.unpack('a10 x a x4 C2')
235
235
  columns << column_class.new(self, name, type, length, decimal)
@@ -238,10 +238,10 @@ module DBF
238
238
  end
239
239
 
240
240
  def end_of_record? # nodoc
241
- pos = @data.pos
241
+ original_pos = @data.pos
242
242
  byte = @data.read(1)
243
- @data.seek(pos)
244
- byte[0].ord == 13
243
+ @data.seek(original_pos)
244
+ byte.ord == 13
245
245
  end
246
246
 
247
247
  def foxpro? # nodoc
@@ -253,10 +253,12 @@ module DBF
253
253
  end
254
254
 
255
255
  def memo_class # nodoc
256
- @memo_class ||= if foxpro?
257
- Memo::Foxpro
258
- else
259
- version == '83' ? Memo::Dbase3 : Memo::Dbase4
256
+ @memo_class ||= begin
257
+ if foxpro?
258
+ Memo::Foxpro
259
+ else
260
+ version == '83' ? Memo::Dbase3 : Memo::Dbase4
261
+ end
260
262
  end
261
263
  end
262
264
 
@@ -304,9 +306,5 @@ module DBF
304
306
  def seek_to_record(index) # nodoc
305
307
  seek(index * header.record_length)
306
308
  end
307
-
308
- def csv_class # nodoc
309
- @csv_class ||= CSV.const_defined?(:Reader) ? FCSV : CSV
310
- end
311
309
  end
312
310
  end
@@ -1,3 +1,3 @@
1
1
  module DBF
2
- VERSION = '2.0.13'
2
+ VERSION = '3.0.0'
3
3
  end
@@ -1,43 +1,43 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- require "spec_helper"
3
+ require 'spec_helper'
4
4
 
5
5
  describe DBF::Column::Dbase do
6
6
  let(:table) { DBF::Table.new fixture_path('dbase_30.dbf')}
7
7
 
8
- context "when initialized" do
9
- let(:column) { DBF::Column::Dbase.new table, "ColumnName", "N", 1, 0 }
8
+ context 'when initialized' do
9
+ let(:column) { DBF::Column::Dbase.new table, 'ColumnName', 'N', 1, 0 }
10
10
 
11
- it "sets :name accessor" do
12
- expect(column.name).to eq "ColumnName"
11
+ it 'sets :name accessor' do
12
+ expect(column.name).to eq 'ColumnName'
13
13
  end
14
14
 
15
- it "sets :type accessor" do
16
- expect(column.type).to eq "N"
15
+ it 'sets :type accessor' do
16
+ expect(column.type).to eq 'N'
17
17
  end
18
18
 
19
- it "sets the #length accessor" do
19
+ it 'sets the #length accessor' do
20
20
  expect(column.length).to eq 1
21
21
  end
22
22
 
23
- it "sets the #decimal accessor" do
23
+ it 'sets the #decimal accessor' do
24
24
  expect(column.decimal).to eq 0
25
25
  end
26
26
 
27
27
  it 'accepts length of 0' do
28
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 0, 0
28
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 0, 0
29
29
  expect(column.length).to eq 0
30
30
  end
31
31
 
32
32
  describe 'with length less than 0' do
33
33
  it 'raises DBF::Column::LengthError' do
34
- expect { DBF::Column::Dbase.new table, "ColumnName", "N", -1, 0 }.to raise_error(DBF::Column::LengthError)
34
+ expect { DBF::Column::Dbase.new table, 'ColumnName', 'N', -1, 0 }.to raise_error(DBF::Column::LengthError)
35
35
  end
36
36
  end
37
37
 
38
38
  describe 'with empty column name' do
39
39
  it 'raises DBF::Column::NameError' do
40
- expect { DBF::Column::Dbase.new table, "\xFF\xFC", "N", 1, 0 }.to raise_error(DBF::Column::NameError)
40
+ expect { DBF::Column::Dbase.new table, "\xFF\xFC", 'N', 1, 0 }.to raise_error(DBF::Column::NameError)
41
41
  end
42
42
  end
43
43
  end
@@ -46,7 +46,7 @@ describe DBF::Column::Dbase do
46
46
  context 'with type N (number)' do
47
47
  context 'and 0 length' do
48
48
  it 'returns nil' do
49
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 0, 0
49
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 0, 0
50
50
  expect(column.type_cast('')).to be_nil
51
51
  end
52
52
  end
@@ -54,14 +54,14 @@ describe DBF::Column::Dbase do
54
54
  context 'and 0 decimals' do
55
55
  it 'casts value to Fixnum' do
56
56
  value = '135'
57
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 3, 0
57
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 3, 0
58
58
  expect(column.type_cast(value)).to be_a(Fixnum)
59
59
  expect(column.type_cast(value)).to eq 135
60
60
  end
61
61
 
62
62
  it 'supports negative Fixnum' do
63
63
  value = '-135'
64
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 3, 0
64
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 3, 0
65
65
  expect(column.type_cast(value)).to be_a(Fixnum)
66
66
  expect(column.type_cast(value)).to eq -135
67
67
  end
@@ -70,14 +70,14 @@ describe DBF::Column::Dbase do
70
70
  context 'and more than 0 decimals' do
71
71
  it 'casts value to Float' do
72
72
  value = '13.5'
73
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 2, 1
73
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 2, 1
74
74
  expect(column.type_cast(value)).to be_a(Float)
75
75
  expect(column.type_cast(value)).to eq 13.5
76
76
  end
77
77
 
78
78
  it 'casts negative value to Float' do
79
79
  value = '-13.5'
80
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 2, 1
80
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 2, 1
81
81
  expect(column.type_cast(value)).to be_a(Float)
82
82
  expect(column.type_cast(value)).to eq -13.5
83
83
  end
@@ -87,42 +87,42 @@ describe DBF::Column::Dbase do
87
87
  context 'with type F (float)' do
88
88
  context 'and 0 length' do
89
89
  it 'returns nil' do
90
- column = DBF::Column::Dbase.new table, "ColumnName", "F", 0, 0
90
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'F', 0, 0
91
91
  expect(column.type_cast('')).to be_nil
92
92
  end
93
93
  end
94
94
 
95
95
  it 'casts value to Float' do
96
96
  value = '135'
97
- column = DBF::Column::Dbase.new table, "ColumnName", "F", 3, 0
97
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'F', 3, 0
98
98
  expect(column.type_cast(value)).to be_a(Float)
99
99
  expect(column.type_cast(value)).to eq 135.0
100
100
  end
101
101
 
102
102
  it 'casts negative value to Float' do
103
103
  value = '-135'
104
- column = DBF::Column::Dbase.new table, "ColumnName", "F", 3, 0
104
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'F', 3, 0
105
105
  expect(column.type_cast(value)).to be_a(Float)
106
106
  expect(column.type_cast(value)).to eq -135.0
107
107
  end
108
108
  end
109
109
 
110
- context "with type B (binary)" do
111
- context "with Foxpro dbf" do
110
+ context 'with type B (binary)' do
111
+ context 'with Foxpro dbf' do
112
112
  it 'casts to float' do
113
- column = DBF::Column::Dbase.new table, "ColumnName", "B", 1, 2
113
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'B', 1, 2
114
114
  expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to be_a(Float)
115
115
  expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to eq 17.42
116
116
  end
117
117
 
118
118
  it 'stores original precision' do
119
- column = DBF::Column::Dbase.new table, "ColumnName", "B", 1, 0
119
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'B', 1, 0
120
120
  expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to be_a(Float)
121
121
  expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to eq 17.42
122
122
  end
123
123
 
124
124
  it 'supports negative binary' do
125
- column = DBF::Column::Dbase.new table, "ColumnName", "B", 1, 2
125
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'B', 1, 2
126
126
  expect(column.type_cast("\x00\x00\x00\x00\x00\xC0\x65\xC0")).to be_a(Float)
127
127
  expect(column.type_cast("\x00\x00\x00\x00\x00\xC0\x65\xC0")).to eq -174.0
128
128
  end
@@ -132,28 +132,28 @@ describe DBF::Column::Dbase do
132
132
  context 'with type I (integer)' do
133
133
  context 'and 0 length' do
134
134
  it 'returns nil' do
135
- column = DBF::Column::Dbase.new table, "ColumnName", "I", 0, 0
135
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'I', 0, 0
136
136
  expect(column.type_cast('')).to be_nil
137
137
  end
138
138
  end
139
139
 
140
- it "casts value to Fixnum" do
140
+ it 'casts value to Fixnum' do
141
141
  value = "\203\171\001\000"
142
- column = DBF::Column::Dbase.new table, "ColumnName", "I", 3, 0
142
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'I', 3, 0
143
143
  expect(column.type_cast(value)).to be_a(Fixnum)
144
144
  expect(column.type_cast(value)).to eq 96643
145
145
  end
146
146
 
147
- it "supports negative Fixnum" do
147
+ it 'supports negative Fixnum' do
148
148
  value = "\x24\xE1\xFF\xFF"
149
- column = DBF::Column::Dbase.new table, "ColumnName", "I", 3, 0
149
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'I', 3, 0
150
150
  expect(column.type_cast(value)).to be_a(Fixnum)
151
151
  expect(column.type_cast(value)).to eq -7900
152
152
  end
153
153
  end
154
154
 
155
155
  context 'with type L (logical/boolean)' do
156
- let(:column) { DBF::Column::Dbase.new table, "ColumnName", "L", 1, 0 }
156
+ let(:column) { DBF::Column::Dbase.new table, 'ColumnName', 'L', 1, 0 }
157
157
 
158
158
  it "casts 'y' to true" do
159
159
  expect(column.type_cast('y')).to be true
@@ -169,37 +169,37 @@ describe DBF::Column::Dbase do
169
169
 
170
170
  context 'and 0 length' do
171
171
  it 'returns nil' do
172
- column = DBF::Column::Dbase.new table, "ColumnName", "L", 0, 0
172
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'L', 0, 0
173
173
  expect(column.type_cast('')).to be_nil
174
174
  end
175
175
  end
176
176
  end
177
177
 
178
178
  context 'with type T (datetime)' do
179
- let(:column) { DBF::Column::Dbase.new table, "ColumnName", "T", 16, 0 }
179
+ let(:column) { DBF::Column::Dbase.new table, 'ColumnName', 'T', 16, 0 }
180
180
 
181
181
  context 'with valid datetime' do
182
- it "casts to DateTime" do
182
+ it 'casts to DateTime' do
183
183
  expect(column.type_cast("Nl%\000\300Z\252\003")).to be_a(DateTime)
184
- expect(column.type_cast("Nl%\000\300Z\252\003")).to eq DateTime.parse("2002-10-10T17:04:56+00:00")
184
+ expect(column.type_cast("Nl%\000\300Z\252\003")).to eq DateTime.parse('2002-10-10T17:04:56+00:00')
185
185
  end
186
186
  end
187
187
 
188
188
  if ruby_supports_mathn?
189
189
  context 'when requiring mathn' do
190
- it "casts to DateTime" do
190
+ it 'casts to DateTime' do
191
191
  with_mathn = lambda do
192
192
  require 'mathn'
193
193
  column.type_cast("Nl%\000\300Z\252\003")
194
194
  end
195
195
  expect(with_mathn.call).to be_a(DateTime)
196
- expect(with_mathn.call).to eq DateTime.parse("2002-10-10T17:04:56+00:00")
196
+ expect(with_mathn.call).to eq DateTime.parse('2002-10-10T17:04:56+00:00')
197
197
  end
198
198
  end
199
199
  end
200
200
 
201
201
  context 'with invalid datetime' do
202
- it "casts to nil" do
202
+ it 'casts to nil' do
203
203
  expect(column.type_cast("Nl%\000\000A\000\999")).to be_a(NilClass)
204
204
  expect(column.type_cast("Nl%\000\000A\000\999")).to be_nil
205
205
  end
@@ -207,53 +207,53 @@ describe DBF::Column::Dbase do
207
207
 
208
208
  context 'and 0 length' do
209
209
  it 'returns nil' do
210
- column = DBF::Column::Dbase.new table, "ColumnName", "T", 0, 0
210
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'T', 0, 0
211
211
  expect(column.type_cast('')).to be_nil
212
212
  end
213
213
  end
214
214
  end
215
215
 
216
216
  context 'with type D (date)' do
217
- let(:column) { DBF::Column::Dbase.new table, "ColumnName", "D", 8, 0 }
217
+ let(:column) { DBF::Column::Dbase.new table, 'ColumnName', 'D', 8, 0 }
218
218
 
219
219
  context 'with valid date' do
220
- it "casts to Date" do
221
- expect(column.type_cast("20050712")).to be_a(Date)
222
- expect(column.type_cast("20050712")).to eq Date.new(2005,7,12)
220
+ it 'casts to Date' do
221
+ expect(column.type_cast('20050712')).to be_a(Date)
222
+ expect(column.type_cast('20050712')).to eq Date.new(2005,7,12)
223
223
  end
224
224
  end
225
225
 
226
226
  context 'with invalid date' do
227
- it "casts to nil" do
228
- expect(column.type_cast("0")).to be_a(NilClass)
229
- expect(column.type_cast("0")).to be_nil
227
+ it 'casts to nil' do
228
+ expect(column.type_cast('0')).to be_a(NilClass)
229
+ expect(column.type_cast('0')).to be_nil
230
230
  end
231
231
  end
232
232
 
233
233
  context 'and 0 length' do
234
234
  it 'returns nil' do
235
- column = DBF::Column::Dbase.new table, "ColumnName", "D", 0, 0
235
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'D', 0, 0
236
236
  expect(column.type_cast('')).to be_nil
237
237
  end
238
238
  end
239
239
  end
240
240
 
241
241
  context 'with type M (memo)' do
242
- it "casts to string" do
243
- column = DBF::Column::Dbase.new table, "ColumnName", "M", 3, 0
242
+ it 'casts to string' do
243
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'M', 3, 0
244
244
  expect(column.type_cast('abc')).to be_a(String)
245
245
  expect(column.type_cast('abc')).to eq 'abc'
246
246
  end
247
247
 
248
248
  it 'casts nil to nil' do
249
- column = DBF::Column::Dbase.new table, "ColumnName", "M", 3, 0
249
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'M', 3, 0
250
250
  expect(column.type_cast(nil)).to be_a(NilClass)
251
251
  expect(column.type_cast(nil)).to be_nil
252
252
  end
253
253
 
254
254
  context 'and 0 length' do
255
255
  it 'returns nil' do
256
- column = DBF::Column::Dbase.new table, "ColumnName", "M", 0, 0
256
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'M', 0, 0
257
257
  expect(column.type_cast('')).to be_nil
258
258
  end
259
259
  end
@@ -261,7 +261,7 @@ describe DBF::Column::Dbase do
261
261
  end
262
262
 
263
263
  context 'with type Y (currency)' do
264
- let(:column) { DBF::Column::Dbase.new table, "ColumnName", "Y", 8, 4 }
264
+ let(:column) { DBF::Column::Dbase.new table, 'ColumnName', 'Y', 8, 4 }
265
265
 
266
266
  it 'casts to float' do
267
267
  expect(column.type_cast(" \xBF\x02\x00\x00\x00\x00\x00")).to be_a(Float)
@@ -280,74 +280,74 @@ describe DBF::Column::Dbase do
280
280
 
281
281
  context 'and 0 length' do
282
282
  it 'returns nil' do
283
- column = DBF::Column::Dbase.new table, "ColumnName", "Y", 0, 0
283
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'Y', 0, 0
284
284
  expect(column.type_cast('')).to be_nil
285
285
  end
286
286
  end
287
287
  end
288
288
 
289
- context "#schema_definition" do
289
+ context '#schema_definition' do
290
290
  context 'with type N (number)' do
291
- it "outputs an integer column" do
292
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 1, 0
291
+ it 'outputs an integer column' do
292
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 1, 0
293
293
  expect(column.schema_definition).to eq "\"column_name\", :integer\n"
294
294
  end
295
295
  end
296
296
 
297
- context "with type B (binary)" do
298
- context "with Foxpro dbf" do
299
- it "outputs a float column" do
300
- column = DBF::Column::Dbase.new table, "ColumnName", "B", 1, 2
297
+ context 'with type B (binary)' do
298
+ context 'with Foxpro dbf' do
299
+ it 'outputs a float column' do
300
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'B', 1, 2
301
301
  expect(column.schema_definition).to eq "\"column_name\", :float\n"
302
302
  end
303
303
  end
304
304
  end
305
305
 
306
- it "defines a float colmn if type is (N)umber with more than 0 decimals" do
307
- column = DBF::Column::Dbase.new table, "ColumnName", "N", 1, 2
306
+ it 'defines a float colmn if type is (N)umber with more than 0 decimals' do
307
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'N', 1, 2
308
308
  expect(column.schema_definition).to eq "\"column_name\", :float\n"
309
309
  end
310
310
 
311
- it "defines a date column if type is (D)ate" do
312
- column = DBF::Column::Dbase.new table, "ColumnName", "D", 8, 0
311
+ it 'defines a date column if type is (D)ate' do
312
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'D', 8, 0
313
313
  expect(column.schema_definition).to eq "\"column_name\", :date\n"
314
314
  end
315
315
 
316
- it "defines a datetime column if type is (D)ate" do
317
- column = DBF::Column::Dbase.new table, "ColumnName", "T", 16, 0
316
+ it 'defines a datetime column if type is (D)ate' do
317
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'T', 16, 0
318
318
  expect(column.schema_definition).to eq "\"column_name\", :datetime\n"
319
319
  end
320
320
 
321
- it "defines a boolean column if type is (L)ogical" do
322
- column = DBF::Column::Dbase.new table, "ColumnName", "L", 1, 0
321
+ it 'defines a boolean column if type is (L)ogical' do
322
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'L', 1, 0
323
323
  expect(column.schema_definition).to eq "\"column_name\", :boolean\n"
324
324
  end
325
325
 
326
- it "defines a text column if type is (M)emo" do
327
- column = DBF::Column::Dbase.new table, "ColumnName", "M", 1, 0
326
+ it 'defines a text column if type is (M)emo' do
327
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'M', 1, 0
328
328
  expect(column.schema_definition).to eq "\"column_name\", :text\n"
329
329
  end
330
330
 
331
- it "defines a string column with length for any other data types" do
332
- column = DBF::Column::Dbase.new table, "ColumnName", "X", 20, 0
331
+ it 'defines a string column with length for any other data types' do
332
+ column = DBF::Column::Dbase.new table, 'ColumnName', 'X', 20, 0
333
333
  expect(column.schema_definition).to eq "\"column_name\", :string, :limit => 20\n"
334
334
  end
335
335
  end
336
336
 
337
- context "#name" do
338
- it "contains only ASCII characters" do
339
- column = DBF::Column::Dbase.new table, "--\x1F-\x68\x65\x6C\x6C\x6F world-\x80--", "N", 1, 0
340
- expect(column.name).to eq "---hello world---"
337
+ context '#name' do
338
+ it 'contains only ASCII characters' do
339
+ column = DBF::Column::Dbase.new table, "--\x1F-\x68\x65\x6C\x6C\x6F world-\x80--", 'N', 1, 0
340
+ expect(column.name).to eq '---hello world---'
341
341
  end
342
342
 
343
- it "is truncated at the null character" do
344
- column = DBF::Column::Dbase.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00 world-\x80--", "N", 1, 0
345
- expect(column.name).to eq "---hello "
343
+ it 'is truncated at the null character' do
344
+ column = DBF::Column::Dbase.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00 world-\x80--", 'N', 1, 0
345
+ expect(column.name).to eq '---hello '
346
346
  end
347
347
  end
348
348
 
349
349
  context '#decode_date' do
350
- let(:column) { DBF::Column::Dbase.new table, "ColumnName", "N", 1, 0 }
350
+ let(:column) { DBF::Column::Dbase.new table, 'ColumnName', 'N', 1, 0 }
351
351
 
352
352
  it 'is nil if value is blank' do
353
353
  expect(column.send(:decode_date, '')).to be_nil
@@ -54,6 +54,33 @@ describe DBF::Table do
54
54
  end
55
55
  end
56
56
 
57
+ describe '#json_schema' do
58
+ it 'is valid JSON' do
59
+ expect { JSON.parse(table.json_schema) }.to_not raise_error
60
+ end
61
+
62
+ it 'matches the test fixture' do
63
+ data = JSON.parse(table.json_schema)
64
+ expect(data).to eq [
65
+ {'name' => 'ID', 'type' => 'N', 'length' => 19, 'decimal' => 0},
66
+ {'name' => 'CATCOUNT', 'type' => 'N', 'length' => 19, 'decimal' => 0},
67
+ {'name' => 'AGRPCOUNT', 'type' => 'N', 'length' => 19, 'decimal' => 0},
68
+ {'name' => 'PGRPCOUNT', 'type' => 'N', 'length' => 19, 'decimal' => 0},
69
+ {'name' => 'ORDER', 'type' => 'N', 'length' => 19, 'decimal' => 0},
70
+ {'name' => 'CODE', 'type' => 'C', 'length' => 50, 'decimal' => 0},
71
+ {'name' => 'NAME', 'type' => 'C', 'length' => 100, 'decimal' => 0},
72
+ {'name' => 'THUMBNAIL', 'type' => 'C', 'length' => 254, 'decimal' => 0},
73
+ {'name' => 'IMAGE', 'type' => 'C', 'length' => 254, 'decimal' => 0},
74
+ {'name' => 'PRICE', 'type' => 'N', 'length' => 13, 'decimal' => 2},
75
+ {'name' => 'COST', 'type' => 'N', 'length' => 13, 'decimal' => 2},
76
+ {'name' => 'DESC', 'type' => 'M', 'length' => 10, 'decimal' => 0},
77
+ {'name' => 'WEIGHT', 'type' => 'N', 'length' => 13, 'decimal' => 2},
78
+ {'name' => 'TAXABLE', 'type' => 'L', 'length' => 1, 'decimal' => 0},
79
+ {'name' => 'ACTIVE', 'type' => 'L', 'length' => 1, 'decimal' => 0}
80
+ ]
81
+ end
82
+ end
83
+
57
84
  describe '#to_csv' do
58
85
  after do
59
86
  FileUtils.rm_f 'test.csv'
@@ -13,13 +13,6 @@ Encoding.default_external = "UTF-8" if defined?(Encoding)
13
13
 
14
14
  DB_PATH = File.dirname(__FILE__) + '/fixtures' unless defined?(DB_PATH)
15
15
 
16
- if RUBY_VERSION == "1.8.6"
17
- # warn 'ruby-1.8.6: defining Array#reduce as alias of Array#inject'
18
- class Array
19
- alias_method :reduce, :inject
20
- end
21
- end
22
-
23
16
  RSpec.configure do |config|
24
17
  def ruby_supports_mathn?
25
18
  begin
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbf
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.13
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Morrison
@@ -9,21 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2015-10-23 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: fastercsv
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.5'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.5'
12
+ dependencies: []
27
13
  description: A small fast library for reading dBase, xBase, Clipper and FoxPro database
28
14
  files.
29
15
  email: keithm@infused.org
@@ -39,7 +25,6 @@ files:
39
25
  - Gemfile
40
26
  - Gemfile.lock
41
27
  - Gemfile.travis
42
- - Gemfile.travis18
43
28
  - Guardfile
44
29
  - LICENSE
45
30
  - README.md
@@ -1,8 +0,0 @@
1
- gemspec
2
- source 'https://rubygems.org'
3
-
4
- gem 'rubysl', :platform => :rbx
5
-
6
- group :test do
7
- gem 'rspec'
8
- end