dbf 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/Gemfile.lock +18 -26
- data/Gemfile.travis +1 -3
- data/README.md +11 -3
- data/Rakefile +1 -1
- data/docs/supported_types.markdown +5 -5
- data/lib/dbf.rb +2 -3
- data/lib/dbf/column.rb +161 -0
- data/lib/dbf/column_type.rb +85 -0
- data/lib/dbf/database/foxpro.rb +2 -2
- data/lib/dbf/header.rb +3 -4
- data/lib/dbf/record.rb +8 -9
- data/lib/dbf/table.rb +4 -27
- data/lib/dbf/version.rb +1 -1
- data/spec/dbf/column_spec.rb +68 -91
- data/spec/dbf/database_spec.rb +2 -2
- data/spec/dbf/file_formats_spec.rb +13 -22
- data/spec/dbf/record_spec.rb +21 -26
- data/spec/dbf/table_spec.rb +30 -20
- data/spec/spec_helper.rb +15 -11
- metadata +5 -6
- data/lib/dbf/column/base.rb +0 -199
- data/lib/dbf/column/dbase.rb +0 -7
- data/lib/dbf/column/foxpro.rb +0 -9
data/lib/dbf/database/foxpro.rb
CHANGED
@@ -104,7 +104,7 @@ module DBF
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def table_field_hash(name)
|
107
|
-
{:
|
107
|
+
{name: name, fields: []}
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
@@ -118,7 +118,7 @@ module DBF
|
|
118
118
|
# columnname property is readonly, recreate the column definitions
|
119
119
|
columns.map do |column|
|
120
120
|
long_name = long_names[columns.index(column)]
|
121
|
-
|
121
|
+
Column.new(self, long_name, column.type, column.length, column.decimal)
|
122
122
|
end
|
123
123
|
end
|
124
124
|
end
|
data/lib/dbf/header.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module DBF
|
2
2
|
class Header
|
3
|
-
attr_reader :data
|
4
3
|
attr_reader :version
|
5
4
|
attr_reader :record_count
|
6
5
|
attr_reader :header_length
|
@@ -8,14 +7,14 @@ module DBF
|
|
8
7
|
attr_reader :encoding_key
|
9
8
|
attr_reader :encoding
|
10
9
|
|
11
|
-
def initialize(data
|
10
|
+
def initialize(data)
|
12
11
|
@data = data
|
13
12
|
@version, @record_count, @header_length, @record_length, @encoding_key = unpack_header
|
14
|
-
@encoding = DBF::ENCODINGS[@encoding_key]
|
13
|
+
@encoding = DBF::ENCODINGS[@encoding_key]
|
15
14
|
end
|
16
15
|
|
17
16
|
def unpack_header
|
18
|
-
data.unpack('H2 x3 V v2 x17H2')
|
17
|
+
@data.unpack('H2 x3 V v2 x17H2')
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
data/lib/dbf/record.rb
CHANGED
@@ -44,7 +44,7 @@ module DBF
|
|
44
44
|
key = name.to_s
|
45
45
|
if attributes.key?(key)
|
46
46
|
attributes[key]
|
47
|
-
elsif
|
47
|
+
elsif index = underscored_column_names.index(key)
|
48
48
|
attributes[@columns[index].name]
|
49
49
|
end
|
50
50
|
end
|
@@ -53,8 +53,7 @@ module DBF
|
|
53
53
|
#
|
54
54
|
# @return [Hash]
|
55
55
|
def attributes
|
56
|
-
@attributes ||=
|
57
|
-
Hash[@columns.map { |column| [column.name, init_attribute(column)] }]
|
56
|
+
@attributes ||= Hash[attribute_map]
|
58
57
|
end
|
59
58
|
|
60
59
|
# Overrides standard Object.respond_to? to return true if a
|
@@ -63,16 +62,16 @@ module DBF
|
|
63
62
|
# @param [String, Symbol] method
|
64
63
|
# @return [Boolean]
|
65
64
|
def respond_to?(method, *args)
|
66
|
-
|
67
|
-
true
|
68
|
-
else
|
69
|
-
super
|
70
|
-
end
|
65
|
+
underscored_column_names.include?(method.to_s) || super
|
71
66
|
end
|
72
67
|
|
73
68
|
private
|
74
69
|
|
75
|
-
def
|
70
|
+
def attribute_map # nodoc
|
71
|
+
@columns.map { |column| [column.name, init_attribute(column)] }
|
72
|
+
end
|
73
|
+
|
74
|
+
def file_offset(attribute_name) # nodoc
|
76
75
|
column = @columns.detect { |c| c.name == attribute_name.to_s }
|
77
76
|
index = @columns.index(column)
|
78
77
|
@columns[0, index + 1].compact.reduce(0) { |x, c| x += c.length }
|
data/lib/dbf/table.rb
CHANGED
@@ -64,7 +64,7 @@ module DBF
|
|
64
64
|
def initialize(data, memo = nil, encoding = nil)
|
65
65
|
@data = open_data(data)
|
66
66
|
@data.rewind
|
67
|
-
@header = Header.new(@data.read
|
67
|
+
@header = Header.new(@data.read DBF_HEADER_SIZE)
|
68
68
|
@encoding = encoding || header.encoding
|
69
69
|
@memo = open_memo(data, memo)
|
70
70
|
yield self if block_given?
|
@@ -162,10 +162,10 @@ module DBF
|
|
162
162
|
# table.find(5)
|
163
163
|
#
|
164
164
|
# # Find all records for Keith Morrison
|
165
|
-
# table.find :all, :
|
165
|
+
# table.find :all, first_name: "Keith", last_name: "Morrison"
|
166
166
|
#
|
167
167
|
# # Find first record
|
168
|
-
# table.find :first, :
|
168
|
+
# table.find :first, first_name: "Keith"
|
169
169
|
#
|
170
170
|
# The <b>command</b> may be a record index, :all, or :first.
|
171
171
|
# <b>options</b> is optional and, if specified, should be a hash where the
|
@@ -205,25 +205,6 @@ module DBF
|
|
205
205
|
columns.map(&:name)
|
206
206
|
end
|
207
207
|
|
208
|
-
# Is string encoding supported?
|
209
|
-
# String encoding is always supported in Ruby 1.9+.
|
210
|
-
# Ruby 1.8.x requires that Ruby be compiled with iconv support.
|
211
|
-
def supports_encoding?
|
212
|
-
supports_string_encoding? || supports_iconv?
|
213
|
-
end
|
214
|
-
|
215
|
-
# Does String support encoding? Should be true in Ruby 1.9+
|
216
|
-
def supports_string_encoding?
|
217
|
-
''.respond_to?(:encoding)
|
218
|
-
end
|
219
|
-
|
220
|
-
def supports_iconv? # nodoc
|
221
|
-
require 'iconv'
|
222
|
-
true
|
223
|
-
rescue
|
224
|
-
false
|
225
|
-
end
|
226
|
-
|
227
208
|
private
|
228
209
|
|
229
210
|
def build_columns # nodoc
|
@@ -232,7 +213,7 @@ module DBF
|
|
232
213
|
until end_of_record?
|
233
214
|
column_data = @data.read(DBF_HEADER_SIZE)
|
234
215
|
name, type, length, decimal = column_data.unpack('a10 x a x4 C2')
|
235
|
-
columns <<
|
216
|
+
columns << Column.new(self, name, type, length, decimal)
|
236
217
|
end
|
237
218
|
columns
|
238
219
|
end
|
@@ -248,10 +229,6 @@ module DBF
|
|
248
229
|
FOXPRO_VERSIONS.keys.include? version
|
249
230
|
end
|
250
231
|
|
251
|
-
def column_class # nodoc
|
252
|
-
@column_class ||= foxpro? ? Column::Foxpro : Column::Dbase
|
253
|
-
end
|
254
|
-
|
255
232
|
def memo_class # nodoc
|
256
233
|
@memo_class ||= begin
|
257
234
|
if foxpro?
|
data/lib/dbf/version.rb
CHANGED
data/spec/dbf/column_spec.rb
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe DBF::Column
|
6
|
-
let(:table) { DBF::Table.new
|
5
|
+
RSpec.describe DBF::Column do
|
6
|
+
let(:table) { DBF::Table.new fixture('dbase_30.dbf')}
|
7
7
|
|
8
8
|
context 'when initialized' do
|
9
|
-
let(:column) { DBF::Column
|
9
|
+
let(:column) { DBF::Column.new table, 'ColumnName', 'N', 1, 0 }
|
10
10
|
|
11
11
|
it 'sets :name accessor' do
|
12
12
|
expect(column.name).to eq 'ColumnName'
|
@@ -25,19 +25,19 @@ describe DBF::Column::Dbase do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it 'accepts length of 0' do
|
28
|
-
column = DBF::Column
|
28
|
+
column = DBF::Column.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
|
34
|
+
expect { DBF::Column.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
|
40
|
+
expect { DBF::Column.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
|
49
|
+
column = DBF::Column.new table, 'ColumnName', 'N', 0, 0
|
50
50
|
expect(column.type_cast('')).to be_nil
|
51
51
|
end
|
52
52
|
end
|
@@ -54,32 +54,28 @@ 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
|
58
|
-
expect(column.type_cast(value)).to be_a(Fixnum)
|
57
|
+
column = DBF::Column.new table, 'ColumnName', 'N', 3, 0
|
59
58
|
expect(column.type_cast(value)).to eq 135
|
60
59
|
end
|
61
60
|
|
62
61
|
it 'supports negative Fixnum' do
|
63
62
|
value = '-135'
|
64
|
-
column = DBF::Column
|
65
|
-
expect(column.type_cast(value)).to
|
66
|
-
expect(column.type_cast(value)).to eq -135
|
63
|
+
column = DBF::Column.new table, 'ColumnName', 'N', 3, 0
|
64
|
+
expect(column.type_cast(value)).to eq (-135)
|
67
65
|
end
|
68
66
|
end
|
69
67
|
|
70
68
|
context 'and more than 0 decimals' do
|
71
69
|
it 'casts value to Float' do
|
72
70
|
value = '13.5'
|
73
|
-
column = DBF::Column
|
74
|
-
expect(column.type_cast(value)).to be_a(Float)
|
71
|
+
column = DBF::Column.new table, 'ColumnName', 'N', 2, 1
|
75
72
|
expect(column.type_cast(value)).to eq 13.5
|
76
73
|
end
|
77
74
|
|
78
75
|
it 'casts negative value to Float' do
|
79
76
|
value = '-13.5'
|
80
|
-
column = DBF::Column
|
81
|
-
expect(column.type_cast(value)).to
|
82
|
-
expect(column.type_cast(value)).to eq -13.5
|
77
|
+
column = DBF::Column.new table, 'ColumnName', 'N', 2, 1
|
78
|
+
expect(column.type_cast(value)).to eq (-13.5)
|
83
79
|
end
|
84
80
|
end
|
85
81
|
end
|
@@ -87,44 +83,42 @@ describe DBF::Column::Dbase do
|
|
87
83
|
context 'with type F (float)' do
|
88
84
|
context 'and 0 length' do
|
89
85
|
it 'returns nil' do
|
90
|
-
column = DBF::Column
|
86
|
+
column = DBF::Column.new table, 'ColumnName', 'F', 0, 0
|
91
87
|
expect(column.type_cast('')).to be_nil
|
92
88
|
end
|
93
89
|
end
|
94
90
|
|
95
91
|
it 'casts value to Float' do
|
96
92
|
value = '135'
|
97
|
-
column = DBF::Column
|
98
|
-
expect(column.type_cast(value)).to be_a(Float)
|
93
|
+
column = DBF::Column.new table, 'ColumnName', 'F', 3, 0
|
99
94
|
expect(column.type_cast(value)).to eq 135.0
|
100
95
|
end
|
101
96
|
|
102
97
|
it 'casts negative value to Float' do
|
103
98
|
value = '-135'
|
104
|
-
column = DBF::Column
|
105
|
-
expect(column.type_cast(value)).to
|
106
|
-
expect(column.type_cast(value)).to eq -135.0
|
99
|
+
column = DBF::Column.new table, 'ColumnName', 'F', 3, 0
|
100
|
+
expect(column.type_cast(value)).to eq (-135.0)
|
107
101
|
end
|
108
102
|
end
|
109
103
|
|
110
104
|
context 'with type B (binary)' do
|
111
105
|
context 'with Foxpro dbf' do
|
112
106
|
it 'casts to float' do
|
113
|
-
column = DBF::Column
|
107
|
+
column = DBF::Column.new table, 'ColumnName', 'B', 1, 2
|
114
108
|
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to be_a(Float)
|
115
109
|
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to eq 17.42
|
116
110
|
end
|
117
111
|
|
118
112
|
it 'stores original precision' do
|
119
|
-
column = DBF::Column
|
113
|
+
column = DBF::Column.new table, 'ColumnName', 'B', 1, 0
|
120
114
|
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to be_a(Float)
|
121
115
|
expect(column.type_cast("\xEC\x51\xB8\x1E\x85\x6B\x31\x40")).to eq 17.42
|
122
116
|
end
|
123
117
|
|
124
118
|
it 'supports negative binary' do
|
125
|
-
column = DBF::Column
|
119
|
+
column = DBF::Column.new table, 'ColumnName', 'B', 1, 2
|
126
120
|
expect(column.type_cast("\x00\x00\x00\x00\x00\xC0\x65\xC0")).to be_a(Float)
|
127
|
-
expect(column.type_cast("\x00\x00\x00\x00\x00\xC0\x65\xC0")).to eq -174.0
|
121
|
+
expect(column.type_cast("\x00\x00\x00\x00\x00\xC0\x65\xC0")).to eq (-174.0)
|
128
122
|
end
|
129
123
|
end
|
130
124
|
end
|
@@ -132,28 +126,26 @@ describe DBF::Column::Dbase do
|
|
132
126
|
context 'with type I (integer)' do
|
133
127
|
context 'and 0 length' do
|
134
128
|
it 'returns nil' do
|
135
|
-
column = DBF::Column
|
129
|
+
column = DBF::Column.new table, 'ColumnName', 'I', 0, 0
|
136
130
|
expect(column.type_cast('')).to be_nil
|
137
131
|
end
|
138
132
|
end
|
139
133
|
|
140
134
|
it 'casts value to Fixnum' do
|
141
135
|
value = "\203\171\001\000"
|
142
|
-
column = DBF::Column
|
143
|
-
expect(column.type_cast(value)).to be_a(Fixnum)
|
136
|
+
column = DBF::Column.new table, 'ColumnName', 'I', 3, 0
|
144
137
|
expect(column.type_cast(value)).to eq 96643
|
145
138
|
end
|
146
139
|
|
147
140
|
it 'supports negative Fixnum' do
|
148
141
|
value = "\x24\xE1\xFF\xFF"
|
149
|
-
column = DBF::Column
|
150
|
-
expect(column.type_cast(value)).to
|
151
|
-
expect(column.type_cast(value)).to eq -7900
|
142
|
+
column = DBF::Column.new table, 'ColumnName', 'I', 3, 0
|
143
|
+
expect(column.type_cast(value)).to eq (-7900)
|
152
144
|
end
|
153
145
|
end
|
154
146
|
|
155
147
|
context 'with type L (logical/boolean)' do
|
156
|
-
let(:column) { DBF::Column
|
148
|
+
let(:column) { DBF::Column.new table, 'ColumnName', 'L', 1, 0 }
|
157
149
|
|
158
150
|
it "casts 'y' to true" do
|
159
151
|
expect(column.type_cast('y')).to be true
|
@@ -169,70 +161,53 @@ describe DBF::Column::Dbase do
|
|
169
161
|
|
170
162
|
context 'and 0 length' do
|
171
163
|
it 'returns nil' do
|
172
|
-
column = DBF::Column
|
164
|
+
column = DBF::Column.new table, 'ColumnName', 'L', 0, 0
|
173
165
|
expect(column.type_cast('')).to be_nil
|
174
166
|
end
|
175
167
|
end
|
176
168
|
end
|
177
169
|
|
178
170
|
context 'with type T (datetime)' do
|
179
|
-
let(:column) { DBF::Column
|
171
|
+
let(:column) { DBF::Column.new table, 'ColumnName', 'T', 16, 0 }
|
180
172
|
|
181
173
|
context 'with valid datetime' do
|
182
174
|
it 'casts to DateTime' do
|
183
|
-
expect(column.type_cast("Nl%\000\300Z\252\003")).to be_a(DateTime)
|
184
175
|
expect(column.type_cast("Nl%\000\300Z\252\003")).to eq DateTime.parse('2002-10-10T17:04:56+00:00')
|
185
176
|
end
|
186
177
|
end
|
187
178
|
|
188
|
-
if ruby_supports_mathn?
|
189
|
-
context 'when requiring mathn' do
|
190
|
-
it 'casts to DateTime' do
|
191
|
-
with_mathn = lambda do
|
192
|
-
require 'mathn'
|
193
|
-
column.type_cast("Nl%\000\300Z\252\003")
|
194
|
-
end
|
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')
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
179
|
context 'with invalid datetime' do
|
202
180
|
it 'casts to nil' do
|
203
|
-
expect(column.type_cast("Nl%\000\000A\000\999")).to be_a(NilClass)
|
204
181
|
expect(column.type_cast("Nl%\000\000A\000\999")).to be_nil
|
205
182
|
end
|
206
183
|
end
|
207
184
|
|
208
185
|
context 'and 0 length' do
|
209
186
|
it 'returns nil' do
|
210
|
-
column = DBF::Column
|
187
|
+
column = DBF::Column.new table, 'ColumnName', 'T', 0, 0
|
211
188
|
expect(column.type_cast('')).to be_nil
|
212
189
|
end
|
213
190
|
end
|
214
191
|
end
|
215
192
|
|
216
193
|
context 'with type D (date)' do
|
217
|
-
let(:column) { DBF::Column
|
194
|
+
let(:column) { DBF::Column.new table, 'ColumnName', 'D', 8, 0 }
|
218
195
|
|
219
196
|
context 'with valid date' do
|
220
197
|
it 'casts to Date' do
|
221
|
-
expect(column.type_cast('20050712')).to be_a(Date)
|
222
198
|
expect(column.type_cast('20050712')).to eq Date.new(2005,7,12)
|
223
199
|
end
|
224
200
|
end
|
225
201
|
|
226
202
|
context 'with invalid date' do
|
227
203
|
it 'casts to nil' do
|
228
|
-
expect(column.type_cast('0')).to be_a(NilClass)
|
229
204
|
expect(column.type_cast('0')).to be_nil
|
230
205
|
end
|
231
206
|
end
|
232
207
|
|
233
208
|
context 'and 0 length' do
|
234
209
|
it 'returns nil' do
|
235
|
-
column = DBF::Column
|
210
|
+
column = DBF::Column.new table, 'ColumnName', 'D', 0, 0
|
236
211
|
expect(column.type_cast('')).to be_nil
|
237
212
|
end
|
238
213
|
end
|
@@ -240,20 +215,38 @@ describe DBF::Column::Dbase do
|
|
240
215
|
|
241
216
|
context 'with type M (memo)' do
|
242
217
|
it 'casts to string' do
|
243
|
-
column = DBF::Column
|
244
|
-
expect(column.type_cast('abc')).to be_a(String)
|
218
|
+
column = DBF::Column.new table, 'ColumnName', 'M', 3, 0
|
245
219
|
expect(column.type_cast('abc')).to eq 'abc'
|
246
220
|
end
|
247
221
|
|
248
222
|
it 'casts nil to nil' do
|
249
|
-
column = DBF::Column
|
250
|
-
expect(column.type_cast(nil)).to be_a(NilClass)
|
223
|
+
column = DBF::Column.new table, 'ColumnName', 'M', 3, 0
|
251
224
|
expect(column.type_cast(nil)).to be_nil
|
252
225
|
end
|
253
226
|
|
254
227
|
context 'and 0 length' do
|
255
228
|
it 'returns nil' do
|
256
|
-
column = DBF::Column
|
229
|
+
column = DBF::Column.new table, 'ColumnName', 'M', 0, 0
|
230
|
+
expect(column.type_cast('')).to be_nil
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
context 'with type G (memo)' do
|
236
|
+
it 'returns binary data' do
|
237
|
+
column = DBF::Column.new table, 'ColumnName', 'G', 3, 0
|
238
|
+
expect(column.type_cast("\000\013\120")).to eq "\000\013\120"
|
239
|
+
expect(column.type_cast("\000\013\120").encoding).to eq Encoding::ASCII_8BIT
|
240
|
+
end
|
241
|
+
|
242
|
+
it 'casts nil to nil' do
|
243
|
+
column = DBF::Column.new table, 'ColumnName', 'G', 3, 0
|
244
|
+
expect(column.type_cast(nil)).to be_nil
|
245
|
+
end
|
246
|
+
|
247
|
+
context 'and 0 length' do
|
248
|
+
it 'returns nil' do
|
249
|
+
column = DBF::Column.new table, 'ColumnName', 'G', 0, 0
|
257
250
|
expect(column.type_cast('')).to be_nil
|
258
251
|
end
|
259
252
|
end
|
@@ -261,26 +254,23 @@ describe DBF::Column::Dbase do
|
|
261
254
|
end
|
262
255
|
|
263
256
|
context 'with type Y (currency)' do
|
264
|
-
let(:column) { DBF::Column
|
257
|
+
let(:column) { DBF::Column.new table, 'ColumnName', 'Y', 8, 4 }
|
265
258
|
|
266
259
|
it 'casts to float' do
|
267
|
-
expect(column.type_cast(" \xBF\x02\x00\x00\x00\x00\x00")).to be_a(Float)
|
268
260
|
expect(column.type_cast(" \xBF\x02\x00\x00\x00\x00\x00")).to eq 18.0
|
269
261
|
end
|
270
262
|
|
271
263
|
it 'supports negative currency' do
|
272
|
-
expect(column.type_cast("\xFC\xF0\xF0\xFE\xFF\xFF\xFF\xFF")).to
|
273
|
-
expect(column.type_cast("\xFC\xF0\xF0\xFE\xFF\xFF\xFF\xFF")).to eq -1776.41
|
264
|
+
expect(column.type_cast("\xFC\xF0\xF0\xFE\xFF\xFF\xFF\xFF")).to eq (-1776.41)
|
274
265
|
end
|
275
266
|
|
276
267
|
it 'supports 64bit negative currency' do
|
277
|
-
expect(column.type_cast("pN'9\xFF\xFF\xFF\xFF")).to
|
278
|
-
expect(column.type_cast("pN'9\xFF\xFF\xFF\xFF")).to eq -333609.0
|
268
|
+
expect(column.type_cast("pN'9\xFF\xFF\xFF\xFF")).to eq (-333609.0)
|
279
269
|
end
|
280
270
|
|
281
271
|
context 'and 0 length' do
|
282
272
|
it 'returns nil' do
|
283
|
-
column = DBF::Column
|
273
|
+
column = DBF::Column.new table, 'ColumnName', 'Y', 0, 0
|
284
274
|
expect(column.type_cast('')).to be_nil
|
285
275
|
end
|
286
276
|
end
|
@@ -289,7 +279,7 @@ describe DBF::Column::Dbase do
|
|
289
279
|
context '#schema_definition' do
|
290
280
|
context 'with type N (number)' do
|
291
281
|
it 'outputs an integer column' do
|
292
|
-
column = DBF::Column
|
282
|
+
column = DBF::Column.new table, 'ColumnName', 'N', 1, 0
|
293
283
|
expect(column.schema_definition).to eq "\"column_name\", :integer\n"
|
294
284
|
end
|
295
285
|
end
|
@@ -297,65 +287,52 @@ describe DBF::Column::Dbase do
|
|
297
287
|
context 'with type B (binary)' do
|
298
288
|
context 'with Foxpro dbf' do
|
299
289
|
it 'outputs a float column' do
|
300
|
-
column = DBF::Column
|
290
|
+
column = DBF::Column.new table, 'ColumnName', 'B', 1, 2
|
301
291
|
expect(column.schema_definition).to eq "\"column_name\", :float\n"
|
302
292
|
end
|
303
293
|
end
|
304
294
|
end
|
305
295
|
|
306
296
|
it 'defines a float colmn if type is (N)umber with more than 0 decimals' do
|
307
|
-
column = DBF::Column
|
297
|
+
column = DBF::Column.new table, 'ColumnName', 'N', 1, 2
|
308
298
|
expect(column.schema_definition).to eq "\"column_name\", :float\n"
|
309
299
|
end
|
310
300
|
|
311
301
|
it 'defines a date column if type is (D)ate' do
|
312
|
-
column = DBF::Column
|
302
|
+
column = DBF::Column.new table, 'ColumnName', 'D', 8, 0
|
313
303
|
expect(column.schema_definition).to eq "\"column_name\", :date\n"
|
314
304
|
end
|
315
305
|
|
316
306
|
it 'defines a datetime column if type is (D)ate' do
|
317
|
-
column = DBF::Column
|
307
|
+
column = DBF::Column.new table, 'ColumnName', 'T', 16, 0
|
318
308
|
expect(column.schema_definition).to eq "\"column_name\", :datetime\n"
|
319
309
|
end
|
320
310
|
|
321
311
|
it 'defines a boolean column if type is (L)ogical' do
|
322
|
-
column = DBF::Column
|
312
|
+
column = DBF::Column.new table, 'ColumnName', 'L', 1, 0
|
323
313
|
expect(column.schema_definition).to eq "\"column_name\", :boolean\n"
|
324
314
|
end
|
325
315
|
|
326
316
|
it 'defines a text column if type is (M)emo' do
|
327
|
-
column = DBF::Column
|
317
|
+
column = DBF::Column.new table, 'ColumnName', 'M', 1, 0
|
328
318
|
expect(column.schema_definition).to eq "\"column_name\", :text\n"
|
329
319
|
end
|
330
320
|
|
331
321
|
it 'defines a string column with length for any other data types' do
|
332
|
-
column = DBF::Column
|
322
|
+
column = DBF::Column.new table, 'ColumnName', 'X', 20, 0
|
333
323
|
expect(column.schema_definition).to eq "\"column_name\", :string, :limit => 20\n"
|
334
324
|
end
|
335
325
|
end
|
336
326
|
|
337
327
|
context '#name' do
|
338
328
|
it 'contains only ASCII characters' do
|
339
|
-
column = DBF::Column
|
329
|
+
column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F world-\x80--", 'N', 1, 0
|
340
330
|
expect(column.name).to eq '---hello world---'
|
341
331
|
end
|
342
332
|
|
343
333
|
it 'is truncated at the null character' do
|
344
|
-
column = DBF::Column
|
334
|
+
column = DBF::Column.new table, "--\x1F-\x68\x65\x6C\x6C\x6F \x00 world-\x80--", 'N', 1, 0
|
345
335
|
expect(column.name).to eq '---hello '
|
346
336
|
end
|
347
337
|
end
|
348
|
-
|
349
|
-
context '#decode_date' do
|
350
|
-
let(:column) { DBF::Column::Dbase.new table, 'ColumnName', 'N', 1, 0 }
|
351
|
-
|
352
|
-
it 'is nil if value is blank' do
|
353
|
-
expect(column.send(:decode_date, '')).to be_nil
|
354
|
-
end
|
355
|
-
|
356
|
-
it 'interperets spaces as zeros' do
|
357
|
-
expect(column.send(:decode_date, '2010 715')).to eq Date.parse('20100715')
|
358
|
-
end
|
359
|
-
end
|
360
|
-
|
361
338
|
end
|