dbf 3.0.0 → 3.0.1
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 +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
|