dbf 4.1.6 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5a45d2baaa7a531875b0528d1d7b83f7cc01cfe502b85c42b461b5749745638a
4
- data.tar.gz: f5eebeb1bc1f3d49bab802671f7ac3cfbc7722a1c1a797173cfdd025a684e30f
3
+ metadata.gz: 825e580742ca7cb994908e488763e40ac36f4570b23d8fe75e6ba389ac9de769
4
+ data.tar.gz: 461dae904d53d1c26558b671d4a0ea2101538e2673bf7b307e39d37470909ce7
5
5
  SHA512:
6
- metadata.gz: a9624d7a37d29bc6f2eaf3546ad41ec8e04b84d1c48ccc9d92122e9682161bbe706459468f6a220e288ba07203fb419574723b376236868f8351e6a66dc58b67
7
- data.tar.gz: d821ec9443f26d3c7c5515cd6f0722f0c5ebcdf189aee5689cb63133c1ba3d1d03a03b6c9f2f9f1514900169ce8895c7ca33cbc8e24611ddbfeb9c216ee5171b
6
+ metadata.gz: 4f4c2824d0eb7a5f822515b8093f51a3e7f8892b0e4987f3b537ce007667e6232e80b4af8f87c449a4be061d39607772a5082e09ea67c73f1a1156dd86889e40
7
+ data.tar.gz: 711155242a0c16f765b327005157e4097489a348a2653bfbbf5f017304c0534f30abb8282075e2e4c6b63c236a94fb8b426e3303917c8882971a9c0f9068a73e
data/CHANGELOG.md CHANGED
@@ -1,159 +1,215 @@
1
- # 4.1.5
2
- - Better handling for PIPE errors when using command line utility
1
+ # Changelog
3
2
 
4
- # 4.1.4
5
- - Add full support for FoxBase files
3
+ ## 4.2.0
6
4
 
7
- # 4.1.3
8
- - Raise DBF::NoColumnsDefined error when attempting to read records if no columns are defined
5
+ - Initial support for dBase 7 files
9
6
 
10
- # 4.1.1
11
- - Add required_ruby_version to gemspec
7
+ ## 4.1.6
12
8
 
13
- # 4.1.0
14
- - Return Time instead of DateTime
9
+ - Add support for file type 32
15
10
 
16
- # 4.0.0
17
- - Drop support for ruby-2.2 and earlier
11
+ ## 4.1.5
18
12
 
19
- # 3.1.3
20
- - Ensure malformed dates return nil
13
+ - Better handling for PIPE errors when using command line utility
21
14
 
22
- # 3.1.2
23
- - Fix incorrect columns list when StringIO and encoding set
15
+ ## 4.1.4
24
16
 
25
- # 3.1.1
26
- - Use Date.strptime to parse date fields
17
+ - Add full support for FoxBase files
27
18
 
28
- # 3.1.0
29
- - Use :binary for binary fields in ActiveRecord schemas
19
+ ## 4.1.3
30
20
 
31
- # 3.0.8
32
- - Fix uninitialized constant error under Rails 5
21
+ - Raise DBF::NoColumnsDefined error when attempting to read records if no columns are defined
33
22
 
34
- # 3.0.7
35
- - Ignore non-existent records if header record count is incorrect
23
+ ## 4.1.1
36
24
 
37
- # 3.0.6
38
- - This version has been yanked from rubygems due to errors
25
+ - Add required_ruby_version to gemspec
39
26
 
40
- # 3.0.5
41
- - Override table name for schema output
27
+ ## 4.1.0
42
28
 
43
- # 3.0.4
44
- - Adds -v command-line option to print version
45
- - Adds -r command-line option to create Sequel migration
29
+ - Return Time instead of DateTime
46
30
 
47
- # 3.0.3
48
- - Uninitialized (N)umbers should return nil
31
+ ## 4.0.0
49
32
 
50
- # 3.0.2
51
- - Performance improvements for large files
33
+ - Drop support for ruby-2.2 and earlier
52
34
 
53
- # 3.0.1
54
- - Support FoxPro (G) general field type
55
- - Fix ruby warnings
35
+ ## 3.1.3
56
36
 
57
- # 3.0.0
58
- - Requires Ruby version 2.0 and above
59
- - Support the (G) General Foxpro field type
37
+ - Ensure malformed dates return nil
60
38
 
61
- # 2.0.13
62
- - Support 64-bit currency signed currency values
63
- (see https://github.com/infused/dbf/pull/71)
39
+ ## 3.1.2
64
40
 
65
- # 2.0.12
66
- - Parse (I) values as signed
67
- (see https://github.com/infused/dbf/pull/70)
41
+ - Fix incorrect columns list when StringIO and encoding set
68
42
 
69
- # 2.0.11
70
- - Foxpro doubles should always return the full stored precision
71
- (see https://github.com/infused/dbf/pull/69)
43
+ ## 3.1.1
72
44
 
73
- # 2.0.10
74
- - allow 0 length fields, but always return nil as value
45
+ - Use Date.strptime to parse date fields
75
46
 
76
- # 2.0.9
77
- - fix dBase IV attributes when memo file is missing
47
+ ## 3.1.0
78
48
 
79
- # 2.0.8
80
- - fix FoxPro currency fields on some builds of Ruby 1.9.3 and 2.0.0
49
+ - Use :binary for binary fields in ActiveRecord schemas
81
50
 
82
- # 2.0.7
83
- - fix the dbf binary on some linux systems
51
+ ## 3.0.8
84
52
 
85
- # 2.0.6
86
- - build_memo returns nil on errors
53
+ - Fix uninitialized constant error under Rails 5
87
54
 
88
- # 2.0.5
89
- - use correct FoxPro memo block size
55
+ ## 3.0.7
90
56
 
91
- # 2.0.4
92
- - memo fields return nil if memo file is missing
57
+ - Ignore non-existent records if header record count is incorrect
93
58
 
94
- # 2.0.3
95
- - set encoding if table encoding is nil
59
+ ## 3.0.6
96
60
 
97
- # 2.0.2
98
- - Allow overriding the character encoding specified in the file
61
+ - This version has been yanked from rubygems due to errors
99
62
 
100
- # 2.0.1
101
- - Add experimental support for character encodings under Ruby 1.8
63
+ ## 3.0.5
102
64
 
103
- # 2.0.0
104
- - #44 Require FasterCSV gem on all platforms
105
- - Remove rdoc development dependency
106
- - #42 Fixes encoding of memos
107
- - #43 Improve handling of record attributes
65
+ - Override table name for schema output
108
66
 
109
- # 1.7.5
110
- - fixes FoxPro currency (Y) fields
67
+ ## 3.0.4
111
68
 
112
- # 1.7.4
113
- - Replace Memo Type with Memo File boolean in command-line utility summary output
69
+ - Adds -v command-line option to print version
70
+ - Adds -r command-line option to create Sequel migration
114
71
 
115
- # 1.7.3
116
- - find_all/find_first should ignore deleted records
72
+ ## 3.0.3
117
73
 
118
- # 1.7.2
119
- - Fix integer division under Ruby 1.8 when requiring mathn
120
- standard library (see http://bugs.ruby-lang.org/issues/2121)
74
+ - Uninitialized (N)umbers should return nil
121
75
 
122
- # 1.7.1
123
- - Fix Table.FOXPRO_VERSIONS breakage on Ruby 1.8
76
+ ## 3.0.2
77
+
78
+ - Performance improvements for large files
124
79
 
125
- # 1.7.0
126
- - allow DBF::Table to work with dbf data in memory
127
- - allow DBF::Table#to_csv to write to STDOUT
80
+ ## 3.0.1
128
81
 
129
- # 1.6.7
130
- - memo columns return nil when no memo file found
82
+ - Support FoxPro (G) general field type
83
+ - Fix ruby warnings
131
84
 
132
- # 1.6.6
133
- - add binary data type support to ActiveRecord schema output
85
+ ## 3.0.0
134
86
 
135
- # 1.6.5
136
- - support for visual foxpro double (b) data type
87
+ - Requires Ruby version 2.0 and above
88
+ - Support the (G) General Foxpro field type
137
89
 
138
- # 1.6.3
139
- - Replace invalid chars with 'unicode replacement character' (U+FFFD)
90
+ ## 2.0.13
91
+
92
+ - Support 64-bit currency signed currency values
93
+ (see https://github.com/infused/dbf/pull/71)
94
+
95
+ ## 2.0.12
96
+
97
+ - Parse (I) values as signed
98
+ (see https://github.com/infused/dbf/pull/70)
99
+
100
+ ## 2.0.11
101
+
102
+ - Foxpro doubles should always return the full stored precision
103
+ (see https://github.com/infused/dbf/pull/69)
104
+
105
+ ## 2.0.10
106
+
107
+ - allow 0 length fields, but always return nil as value
108
+
109
+ ## 2.0.9
110
+
111
+ - fix dBase IV attributes when memo file is missing
112
+
113
+ ## 2.0.8
114
+
115
+ - fix FoxPro currency fields on some builds of Ruby 1.9.3 and 2.0.0
116
+
117
+ ## 2.0.7
118
+
119
+ - fix the dbf binary on some linux systems
120
+
121
+ ## 2.0.6
122
+
123
+ - build_memo returns nil on errors
124
+
125
+ ## 2.0.5
126
+
127
+ - use correct FoxPro memo block size
128
+
129
+ ## 2.0.4
130
+
131
+ - memo fields return nil if memo file is missing
132
+
133
+ ## 2.0.3
134
+
135
+ - set encoding if table encoding is nil
136
+
137
+ ## 2.0.2
138
+
139
+ - Allow overriding the character encoding specified in the file
140
+
141
+ ## 2.0.1
142
+
143
+ - Add experimental support for character encodings under Ruby 1.8
144
+
145
+ ## 2.0.0
146
+
147
+ - #44 Require FasterCSV gem on all platforms
148
+ - Remove rdoc development dependency
149
+ - #42 Fixes encoding of memos
150
+ - #43 Improve handling of record attributes
151
+
152
+ ## 1.7.5
153
+
154
+ - fixes FoxPro currency (Y) fields
155
+
156
+ ## 1.7.4
157
+
158
+ - Replace Memo Type with Memo File boolean in command-line utility summary output
159
+
160
+ ## 1.7.3
161
+
162
+ - find_all/find_first should ignore deleted records
163
+
164
+ ## 1.7.2
165
+
166
+ - Fix integer division under Ruby 1.8 when requiring mathn
167
+ standard library (see http://bugs.ruby-lang.org/issues/2121)
168
+
169
+ ## 1.7.1
170
+
171
+ - Fix Table.FOXPRO_VERSIONS breakage on Ruby 1.8
172
+
173
+ ## 1.7.0
174
+
175
+ - allow DBF::Table to work with dbf data in memory
176
+ - allow DBF::Table#to_csv to write to STDOUT
177
+
178
+ ## 1.6.7
179
+
180
+ - memo columns return nil when no memo file found
181
+
182
+ ## 1.6.6
183
+
184
+ - add binary data type support to ActiveRecord schema output
185
+
186
+ ## 1.6.5
187
+
188
+ - support for visual foxpro double (b) data type
189
+
190
+ ## 1.6.3
191
+
192
+ - Replace invalid chars with 'unicode replacement character' (U+FFFD)
140
193
 
141
194
  ## 1.6.2
142
- - add Table#filename method
143
- - Rakefile now loads gems with bundler
144
- - add Table#supports_encoding?
145
- - simplify encodings.yml loader
146
- - add rake and rdoc as development dependencies
147
- - simplify open_memo file search logic
148
- - remove unnecessary requires in spec helper
149
- - fix cli summary
195
+
196
+ - add Table#filename method
197
+ - Rakefile now loads gems with bundler
198
+ - add Table#supports_encoding?
199
+ - simplify encodings.yml loader
200
+ - add rake and rdoc as development dependencies
201
+ - simplify open_memo file search logic
202
+ - remove unnecessary requires in spec helper
203
+ - fix cli summary
150
204
 
151
205
  ## 1.6.1
152
- - fix YAML issue when using MRI version > 1.9.1
153
- - remove Table#seek_to_index and Table#current_record private methods
206
+
207
+ - fix YAML issue when using MRI version > 1.9.1
208
+ - remove Table#seek_to_index and Table#current_record private methods
154
209
 
155
210
  ## 1.6.0
156
- - remove activesupport gem dependency
211
+
212
+ - remove activesupport gem dependency
157
213
 
158
214
  ## 1.5.0
159
215
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- dbf (4.1.5)
4
+ dbf (4.1.6)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/lib/dbf/column.rb CHANGED
@@ -21,7 +21,8 @@ module DBF
21
21
  L: ColumnType::Boolean,
22
22
  M: ColumnType::Memo,
23
23
  B: ColumnType::Double,
24
- G: ColumnType::General
24
+ G: ColumnType::General,
25
+ '+'.to_sym => ColumnType::SignedLong2
25
26
  }
26
27
  TYPE_CAST_CLASS.default = ColumnType::String
27
28
  TYPE_CAST_CLASS.freeze
@@ -79,8 +80,7 @@ module DBF
79
80
  private
80
81
 
81
82
  def clean(value) # :nodoc:
82
- truncated_value = value.strip.partition("\x00").first
83
- truncated_value.gsub(/[^\x20-\x7E]/, '')
83
+ value.strip.gsub("\x00", '').gsub(/[^\x20-\x7E]/, '')
84
84
  end
85
85
 
86
86
  def encode(value, strip_output = false) # :nodoc:
@@ -12,7 +12,6 @@ module DBF
12
12
  end
13
13
 
14
14
  class Nil < Base
15
-
16
15
  # @param _value [String]
17
16
  def type_cast(_value)
18
17
  nil
@@ -20,7 +19,6 @@ module DBF
20
19
  end
21
20
 
22
21
  class Number < Base
23
-
24
22
  # @param value [String]
25
23
  def type_cast(value)
26
24
  return nil if value.strip.empty?
@@ -30,7 +28,6 @@ module DBF
30
28
  end
31
29
 
32
30
  class Currency < Base
33
-
34
31
  # @param value [String]
35
32
  def type_cast(value)
36
33
  (value.unpack1('q<') / 10_000.0).to_f
@@ -38,15 +35,22 @@ module DBF
38
35
  end
39
36
 
40
37
  class SignedLong < Base
41
-
42
38
  # @param value [String]
43
39
  def type_cast(value)
44
40
  value.unpack1('l<')
45
41
  end
46
42
  end
47
43
 
48
- class Float < Base
44
+ class SignedLong2 < Base
45
+ # @param value [String]
46
+ def type_cast(value)
47
+ s = value.unpack1('B*')
48
+ sign_multiplier = s[0] == '0' ? -1 : 1
49
+ s[1, 31].to_i(2) * sign_multiplier
50
+ end
51
+ end
49
52
 
53
+ class Float < Base
50
54
  # @param value [String]
51
55
  def type_cast(value)
52
56
  value.to_f
@@ -54,7 +58,6 @@ module DBF
54
58
  end
55
59
 
56
60
  class Double < Base
57
-
58
61
  # @param value [String]
59
62
  def type_cast(value)
60
63
  value.unpack1('E')
@@ -62,7 +65,6 @@ module DBF
62
65
  end
63
66
 
64
67
  class Boolean < Base
65
-
66
68
  # @param value [String]
67
69
  def type_cast(value)
68
70
  value.strip.match?(/^(y|t)$/i)
@@ -70,7 +72,6 @@ module DBF
70
72
  end
71
73
 
72
74
  class Date < Base
73
-
74
75
  # @param value [String]
75
76
  def type_cast(value)
76
77
  value.match?(/\d{8}/) && ::Date.strptime(value, '%Y%m%d')
@@ -80,7 +81,6 @@ module DBF
80
81
  end
81
82
 
82
83
  class DateTime < Base
83
-
84
84
  # @param value [String]
85
85
  def type_cast(value)
86
86
  days, msecs = value.unpack('l2')
@@ -92,7 +92,6 @@ module DBF
92
92
  end
93
93
 
94
94
  class Memo < Base
95
-
96
95
  # @param value [String]
97
96
  def type_cast(value)
98
97
  if encoding && !value.nil?
@@ -104,7 +103,6 @@ module DBF
104
103
  end
105
104
 
106
105
  class General < Base
107
-
108
106
  # @param value [String]
109
107
  def type_cast(value)
110
108
  value
@@ -112,7 +110,6 @@ module DBF
112
110
  end
113
111
 
114
112
  class String < Base
115
-
116
113
  # @param value [String]
117
114
  def type_cast(value)
118
115
  value = value.strip
data/lib/dbf/table.rb CHANGED
@@ -14,6 +14,7 @@ module DBF
14
14
 
15
15
  DBASE2_HEADER_SIZE = 8
16
16
  DBASE3_HEADER_SIZE = 32
17
+ DBASE7_HEADER_SIZE = 68
17
18
 
18
19
  VERSIONS = {
19
20
  '02' => 'FoxBase',
@@ -30,6 +31,7 @@ module DBF
30
31
  '83' => 'dBase III with memo file',
31
32
  '87' => 'Visual Objects 1.x with memo file',
32
33
  '8b' => 'dBase IV with memo file',
34
+ '8c' => 'dBase 7',
33
35
  '8e' => 'dBase IV with SQL table',
34
36
  'cb' => 'dBASE IV SQL table files, with memo',
35
37
  'f5' => 'FoxPro with memo file',
@@ -216,23 +218,29 @@ module DBF
216
218
  @data.seek(header_size)
217
219
  [].tap do |columns|
218
220
  until end_of_record?
219
- case version
221
+ args = case version
220
222
  when '02'
221
- column_data = @data.read(header_size * 2)
222
- columns << Column.new(self, *column_data.unpack('A11 a C'), 0)
223
+ [self, *@data.read(header_size * 2).unpack('A11 a C'), 0]
224
+ when '8c'
225
+ [self, *@data.read(48).unpack('A32 a C C x13')]
223
226
  else
224
- column_data = @data.read(header_size)
225
- columns << Column.new(self, *column_data.unpack('A11 a x4 C2'))
227
+ [self, *@data.read(header_size).unpack('A11 a x4 C2')]
226
228
  end
229
+
230
+ columns << Column.new(*args)
227
231
  end
228
232
  end
229
233
  end
230
234
  end
231
235
 
232
236
  def header_size
233
- header_size = case version
234
- when '02' then DBASE2_HEADER_SIZE
235
- else DBASE3_HEADER_SIZE
237
+ case version
238
+ when '02'
239
+ DBASE2_HEADER_SIZE
240
+ when '8c'
241
+ DBASE7_HEADER_SIZE
242
+ else
243
+ DBASE3_HEADER_SIZE
236
244
  end
237
245
  end
238
246
 
data/lib/dbf/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module DBF
2
- VERSION = '4.1.6'.freeze
2
+ VERSION = '4.2.0'.freeze
3
3
  end
@@ -286,13 +286,13 @@ RSpec.describe DBF::Column do
286
286
 
287
287
  describe '#name' do
288
288
  it 'contains only ASCII characters' do
289
- column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F world-\x80--", 'N', 1, 0
289
+ column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00world-\x80--", 'N', 1, 0
290
290
  expect(column.name).to eq '---hello world---'
291
291
  end
292
292
 
293
293
  it 'is truncated at the null character' do
294
- column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00 world-\x80--", 'N', 1, 0
295
- expect(column.name).to eq '---hello '
294
+ column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00world-\x80--", 'N', 1, 0
295
+ expect(column.name).to eq '---hello world---'
296
296
  end
297
297
  end
298
298
  end
@@ -178,6 +178,24 @@ RSpec.describe DBF, 'of type 8b (dBase IV with memo file)' do
178
178
  end
179
179
  end
180
180
 
181
+ RSpec.describe DBF, 'of type 8c (unknown)' do
182
+ let(:table) { DBF::Table.new fixture('dbase_8c.dbf') }
183
+
184
+ it_behaves_like 'DBF'
185
+
186
+ it 'reports the correct version number' do
187
+ expect(table.version).to eq '8c'
188
+ end
189
+
190
+ it 'reports the correct version description' do
191
+ expect(table.version_description).to eq 'dBase 7'
192
+ end
193
+
194
+ it 'determines the number of records' do
195
+ expect(table.record_count).to eq 10
196
+ end
197
+ end
198
+
181
199
  RSpec.describe DBF, 'of type f5 (FoxPro with memo file)' do
182
200
  let(:table) { DBF::Table.new fixture('dbase_f5.dbf') }
183
201
 
@@ -0,0 +1,23 @@
1
+
2
+ Database: dbase_02.dbf
3
+ Type: (02) FoxBase
4
+ Memo File: false
5
+ Records: 9
6
+
7
+ Fields:
8
+ Name Type Length Decimal
9
+ ------------------------------------------------------------------------------
10
+ EMP:NMBR N 3 0
11
+ LAST C 10 0
12
+ FIRST C 10 0
13
+ ADDR C 20 0
14
+ CITY C 15 0
15
+ ZIP:CODE C 10 0
16
+ PHONE C 9 0
17
+ SSN C 11 0
18
+ HIREDATE C 8 0
19
+ TERMDATE C 8 0
20
+ CLASS C 3 0
21
+ DEPT C 3 0
22
+ PAYRATE N 8 0
23
+ START:PAY N 8 0
@@ -0,0 +1,11 @@
1
+
2
+ Database: dbase_32.dbf
3
+ Type: (32) Visual FoxPro with field type Varchar or Varbinary
4
+ Memo File: false
5
+ Records: 1
6
+
7
+ Fields:
8
+ Name Type Length Decimal
9
+ ------------------------------------------------------------------------------
10
+ NAME V 250 0
11
+ _NullFlags 0 1 0
Binary file
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dbf
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.6
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Keith Morrison
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-12 00:00:00.000000000 Z
11
+ date: 2021-08-20 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A small fast library for reading dBase, xBase, Clipper and FoxPro database
14
14
  files.
@@ -100,6 +100,7 @@ files:
100
100
  - spec/fixtures/cp1251.dbf
101
101
  - spec/fixtures/cp1251_summary.txt
102
102
  - spec/fixtures/dbase_02.dbf
103
+ - spec/fixtures/dbase_02_summary.txt
103
104
  - spec/fixtures/dbase_03.dbf
104
105
  - spec/fixtures/dbase_03_summary.txt
105
106
  - spec/fixtures/dbase_30.dbf
@@ -108,6 +109,7 @@ files:
108
109
  - spec/fixtures/dbase_31.dbf
109
110
  - spec/fixtures/dbase_31_summary.txt
110
111
  - spec/fixtures/dbase_32.dbf
112
+ - spec/fixtures/dbase_32_summary.txt
111
113
  - spec/fixtures/dbase_83.dbf
112
114
  - spec/fixtures/dbase_83.dbt
113
115
  - spec/fixtures/dbase_83_missing_memo.dbf
@@ -121,6 +123,7 @@ files:
121
123
  - spec/fixtures/dbase_8b.dbf
122
124
  - spec/fixtures/dbase_8b.dbt
123
125
  - spec/fixtures/dbase_8b_summary.txt
126
+ - spec/fixtures/dbase_8c.dbf
124
127
  - spec/fixtures/dbase_f5.dbf
125
128
  - spec/fixtures/dbase_f5.fpt
126
129
  - spec/fixtures/dbase_f5_summary.txt