dbf 1.2.1 → 1.2.2
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.
- data/History.txt +4 -0
- data/VERSION.yml +2 -2
- data/dbf.gemspec +2 -2
- data/lib/dbf/column.rb +15 -5
- data/spec/unit/column_spec.rb +104 -67
- data/spec/unit/record_spec.rb +26 -39
- metadata +3 -3
data/History.txt
CHANGED
data/VERSION.yml
CHANGED
data/dbf.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{dbf}
|
8
|
-
s.version = "1.2.
|
8
|
+
s.version = "1.2.2"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Keith Morrison"]
|
12
|
-
s.date = %q{2010-
|
12
|
+
s.date = %q{2010-04-01}
|
13
13
|
s.default_executable = %q{dbf}
|
14
14
|
s.description = %q{A small fast library for reading dBase, xBase, Clipper and FoxPro database files.}
|
15
15
|
s.email = %q{keithm@infused.org}
|
data/lib/dbf/column.rb
CHANGED
@@ -28,21 +28,31 @@ module DBF
|
|
28
28
|
case type
|
29
29
|
when 'N' # number
|
30
30
|
unpack_number(value)
|
31
|
+
when 'I' # integer
|
32
|
+
unpack_integer(value)
|
31
33
|
when 'F' # float
|
32
34
|
unpack_float(value)
|
33
35
|
when 'D' # date
|
34
|
-
value
|
35
|
-
when 'L' # logical
|
36
|
-
boolean(value)
|
37
|
-
when 'I' # integer
|
38
|
-
unpack_integer(value)
|
36
|
+
decode_date(value)
|
39
37
|
when 'T' # datetime
|
40
38
|
decode_datetime(value)
|
39
|
+
when 'L' # logical
|
40
|
+
boolean(value)
|
41
41
|
else
|
42
42
|
value.to_s.strip
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
# Decode a Date value
|
47
|
+
#
|
48
|
+
# @param [String] value
|
49
|
+
# @return [Date]
|
50
|
+
def decode_date(value)
|
51
|
+
unless value.blank?
|
52
|
+
value.to_date rescue nil
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
46
56
|
# Decode a DateTime value
|
47
57
|
#
|
48
58
|
# @param [String] value
|
data/spec/unit/column_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe DBF::Column do
|
|
6
6
|
before do
|
7
7
|
@column = DBF::Column.new "ColumnName", "N", 1, 0
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
it "should set the #name accessor" do
|
11
11
|
@column.name.should == "ColumnName"
|
12
12
|
end
|
@@ -22,83 +22,120 @@ describe DBF::Column do
|
|
22
22
|
it "should set the #decimal accessor" do
|
23
23
|
@column.decimal.should == 0
|
24
24
|
end
|
25
|
-
|
26
|
-
|
27
|
-
lambda { DBF::Column.new "ColumnName", "N",
|
25
|
+
|
26
|
+
context 'with length of 0' do
|
27
|
+
specify { lambda { DBF::Column.new "ColumnName", "N", 0, 0 }.should raise_error(DBF::ColumnLengthError) }
|
28
28
|
end
|
29
29
|
|
30
|
-
|
31
|
-
lambda { DBF::Column.new "
|
30
|
+
context 'with length less than 0' do
|
31
|
+
specify { lambda { DBF::Column.new "ColumnName", "N", -1, 0 }.should raise_error(DBF::ColumnLengthError) }
|
32
32
|
end
|
33
33
|
|
34
|
+
context 'with empty column name' do
|
35
|
+
specify { lambda { DBF::Column.new "\xFF\xFC", "N", 1, 0 }.should raise_error(DBF::ColumnNameError) }
|
36
|
+
end
|
34
37
|
end
|
35
38
|
|
36
39
|
context "#type_cast" do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
|
56
|
-
value
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
40
|
+
context 'with type N (number)' do
|
41
|
+
context 'with 0 decimals' do
|
42
|
+
it "should cast value to Integer" do
|
43
|
+
value = "135"
|
44
|
+
column = DBF::Column.new "ColumnName", "N", 3, 0
|
45
|
+
column.type_cast(value).should == 135
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'with more than 0 decimals' do
|
50
|
+
it "should cast value to Float" do
|
51
|
+
value = "13.5"
|
52
|
+
column = DBF::Column.new "ColumnName", "N", 2, 1
|
53
|
+
column.type_cast(value).should == 13.5
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'with type F (float)' do
|
59
|
+
it "should cast value to Float" do
|
60
|
+
value = "135"
|
61
|
+
column = DBF::Column.new "ColumnName", "F", 3, 0
|
62
|
+
column.type_cast(value).should == 135.0
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context 'with type I (integer)' do
|
67
|
+
it "should cast value to Integer" do
|
68
|
+
value = "135"
|
69
|
+
column = DBF::Column.new "ColumnName", "I", 3, 0
|
70
|
+
column.type_cast(value).should == 135
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'with type L (logical/boolean)' do
|
75
|
+
it "should cast 'y' to true" do
|
76
|
+
value = "y"
|
77
|
+
column = DBF::Column.new "ColumnName", "L", 1, 0
|
78
|
+
column.type_cast(value).should == true
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should cast 'n' to false" do
|
82
|
+
value = "n"
|
83
|
+
column = DBF::Column.new "ColumnName", "L", 1, 0
|
84
|
+
column.type_cast(value).should == false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'with type T (datetime)' do
|
89
|
+
context 'with valid datetime' do
|
90
|
+
it "should cast to DateTime" do
|
91
|
+
value = "Nl%\000\300Z\252\003"
|
92
|
+
column = DBF::Column.new "ColumnName", "T", 16, 0
|
93
|
+
column.type_cast(value).should == "2002-10-10T17:04:56+00:00"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'with invalid datetime' do
|
98
|
+
it "should cast to nil" do
|
99
|
+
value = "Nl%\000\000A\000\999"
|
100
|
+
column = DBF::Column.new "ColumnName", "T", 16, 0
|
101
|
+
column.type_cast(value).should be_nil
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context 'with type D (date)' do
|
107
|
+
context 'with valid date' do
|
108
|
+
it "should cast to Date" do
|
109
|
+
value = "20050712"
|
110
|
+
column = DBF::Column.new "ColumnName", "D", 8, 0
|
111
|
+
column.type_cast(value).should == Date.new(2005,7,12)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'with invalid date' do
|
116
|
+
it "should cast to Date" do
|
117
|
+
value = "0"
|
118
|
+
column = DBF::Column.new "ColumnName", "D", 8, 0
|
119
|
+
column.type_cast(value).should be_nil
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context 'with type M (memo)' do
|
125
|
+
it "should typecast memo columns to String" do
|
126
|
+
value = 'abc'
|
127
|
+
column = DBF::Column.new "ColumnName", "M", 3, 0
|
128
|
+
column.type_cast(value).should be_a String
|
129
|
+
end
|
95
130
|
end
|
96
131
|
end
|
97
132
|
|
98
133
|
context "#schema_definition" do
|
99
|
-
|
100
|
-
|
101
|
-
|
134
|
+
context 'with type N (number)' do
|
135
|
+
it "should output an integer column" do
|
136
|
+
column = DBF::Column.new "ColumnName", "N", 1, 0
|
137
|
+
column.schema_definition.should == "\"column_name\", :integer\n"
|
138
|
+
end
|
102
139
|
end
|
103
140
|
|
104
141
|
it "should define a float colmn if type is (N)umber with more than 0 decimals" do
|
data/spec/unit/record_spec.rb
CHANGED
@@ -20,34 +20,6 @@ describe DBF::Record do
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
context "when initialized" do
|
24
|
-
it "should typecast number columns no decimal places to Integer" do
|
25
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
26
|
-
table.column("ID").type.should == "N"
|
27
|
-
table.column("ID").decimal.should == 0
|
28
|
-
table.record(1).attributes['id'].should be_kind_of(Integer)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should typecast number columns with decimals > 0 to Float" do
|
32
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
33
|
-
table.column("ID").type.should == "N"
|
34
|
-
table.column("COST").decimal.should == 2
|
35
|
-
table.record(1).attributes['cost'].should be_kind_of(Float)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should typecast memo columns to String" do
|
39
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_83.dbf"
|
40
|
-
table.column("DESC").type.should == "M"
|
41
|
-
table.record(1).attributes['desc'].should be_kind_of(String)
|
42
|
-
end
|
43
|
-
|
44
|
-
it "should typecast logical columns to True or False" do
|
45
|
-
table = DBF::Table.new "#{DB_PATH}/dbase_30.dbf"
|
46
|
-
table.column("WEBINCLUDE").type.should == "L"
|
47
|
-
table.record(1).attributes["webinclude"].should satisfy {|v| v == true || v == false}
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
23
|
describe '#memo_block_content_size' do
|
52
24
|
it "should equal the difference between the table's memo_block_size and 8" do
|
53
25
|
table = mock_table
|
@@ -68,20 +40,35 @@ describe DBF::Record do
|
|
68
40
|
end
|
69
41
|
|
70
42
|
describe '#read_memo' do
|
71
|
-
|
72
|
-
table = mock_table
|
73
|
-
record = DBF::Record.new(table)
|
74
|
-
|
75
|
-
record.send(:read_memo, 0).should be_nil
|
76
|
-
record.send(:read_memo, -1).should be_nil
|
43
|
+
before do
|
44
|
+
@table = mock_table
|
45
|
+
@record = DBF::Record.new(@table)
|
77
46
|
end
|
78
47
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
48
|
+
context 'with start_block of 0' do
|
49
|
+
specify { @record.send(:read_memo, 0).should be_nil }
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'with start_block less than 0' do
|
53
|
+
specify { @record.send(:read_memo, -1).should be_nil }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with valid start_block' do
|
57
|
+
before do
|
58
|
+
@table.stub!(:memo_file_format).and_return(:fpt)
|
59
|
+
end
|
83
60
|
|
84
|
-
|
61
|
+
it 'should build the fpt memo' do
|
62
|
+
@record.should_receive(:build_fpt_memo)
|
63
|
+
@record.send(:read_memo, 1)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with no memo file' do
|
68
|
+
specify do
|
69
|
+
@table.should_receive(:has_memo_file?).and_return(false)
|
70
|
+
@record.send(:read_memo, 5).should be_nil
|
71
|
+
end
|
85
72
|
end
|
86
73
|
end
|
87
74
|
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 2
|
8
|
-
-
|
9
|
-
version: 1.2.
|
8
|
+
- 2
|
9
|
+
version: 1.2.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Keith Morrison
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-04-01 00:00:00 -07:00
|
18
18
|
default_executable: dbf
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|