dbf 4.1.6 → 4.2.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
  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