dbf 1.0.3 → 1.0.5
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 +9 -0
- data/Rakefile +1 -1
- data/lib/dbf/column.rb +41 -1
- data/lib/dbf/globals.rb +2 -0
- data/lib/dbf/record.rb +10 -11
- data/lib/dbf/table.rb +11 -28
- data/spec/fixtures/dbase_83_schema.txt +15 -15
- data/spec/unit/column_spec.rb +2 -2
- metadata +2 -2
data/History.txt
CHANGED
data/Rakefile
CHANGED
data/lib/dbf/column.rb
CHANGED
@@ -6,7 +6,47 @@ module DBF
|
|
6
6
|
|
7
7
|
def initialize(name, type, length, decimal)
|
8
8
|
raise ColumnLengthError, "field length must be greater than 0" unless length > 0
|
9
|
-
@name, @type, @length, @decimal = name
|
9
|
+
@name, @type, @length, @decimal = strip_non_ascii_chars(name), type, length, decimal
|
10
|
+
end
|
11
|
+
|
12
|
+
def schema_definition
|
13
|
+
"\"#{underscore(name)}\", " +
|
14
|
+
case type
|
15
|
+
when "N" # number
|
16
|
+
if decimal > 0
|
17
|
+
":float"
|
18
|
+
else
|
19
|
+
":integer"
|
20
|
+
end
|
21
|
+
when "D" # date
|
22
|
+
":datetime"
|
23
|
+
when "L" # boolean
|
24
|
+
":boolean"
|
25
|
+
when "M" # memo
|
26
|
+
":text"
|
27
|
+
else
|
28
|
+
":string, :limit => #{length}"
|
29
|
+
end +
|
30
|
+
"\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def underscore(camel_cased_word)
|
36
|
+
camel_cased_word.to_s.gsub(/::/, '/').
|
37
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
38
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
39
|
+
tr("-", "_").
|
40
|
+
downcase
|
41
|
+
end
|
42
|
+
|
43
|
+
def strip_non_ascii_chars(s)
|
44
|
+
clean = ''
|
45
|
+
s.each_byte do |char|
|
46
|
+
clean << char if char > 31 && char < 128
|
47
|
+
end
|
48
|
+
clean
|
10
49
|
end
|
11
50
|
end
|
51
|
+
|
12
52
|
end
|
data/lib/dbf/globals.rb
CHANGED
data/lib/dbf/record.rb
CHANGED
@@ -29,31 +29,30 @@ module DBF
|
|
29
29
|
|
30
30
|
def initialize_values(columns)
|
31
31
|
columns.each do |column|
|
32
|
-
case column.type
|
32
|
+
@attributes[column.name] = case column.type
|
33
33
|
when 'N' # number
|
34
|
-
|
34
|
+
column.decimal.zero? ? unpack_string(column).to_i : unpack_string(column).to_f
|
35
35
|
when 'D' # date
|
36
36
|
raw = unpack_string(column).strip
|
37
37
|
unless raw.empty?
|
38
|
+
parts = raw.match(DATE_REGEXP).captures.map {|n| n.to_i}
|
38
39
|
begin
|
39
|
-
|
40
|
-
@attributes[column.name] = Time.gm(*parts)
|
40
|
+
Time.gm(*parts)
|
41
41
|
rescue
|
42
|
-
|
43
|
-
@attributes[column.name] = Date.new(*parts)
|
42
|
+
Date.new(*parts)
|
44
43
|
end
|
45
44
|
end
|
46
45
|
when 'M' # memo
|
47
46
|
starting_block = unpack_string(column).to_i
|
48
|
-
|
47
|
+
read_memo(starting_block)
|
49
48
|
when 'L' # logical
|
50
|
-
|
49
|
+
unpack_string(column) =~ /^(y|t)$/i ? true : false
|
51
50
|
when 'I' # integer
|
52
|
-
|
51
|
+
unpack_integer(column)
|
53
52
|
when 'T' # datetime
|
54
|
-
|
53
|
+
unpack_datetime(column)
|
55
54
|
else
|
56
|
-
|
55
|
+
unpack_string(column).strip
|
57
56
|
end
|
58
57
|
end
|
59
58
|
end
|
data/lib/dbf/table.rb
CHANGED
@@ -105,19 +105,15 @@ module DBF
|
|
105
105
|
# for the record to be returned. The equivalent SQL would be "WHERE key1 = 'value1'
|
106
106
|
# AND key2 = 'value2'".
|
107
107
|
def find(command, options = {})
|
108
|
+
results = options.empty? ? records : records.select {|record| all_values_match?(record, options)}
|
109
|
+
|
108
110
|
case command
|
109
111
|
when Fixnum
|
110
112
|
record(command)
|
111
113
|
when :all
|
112
|
-
|
113
|
-
records.select do |record|
|
114
|
-
options.map {|key, value| record.attributes[key.to_s] == value}.all?
|
115
|
-
end
|
114
|
+
results
|
116
115
|
when :first
|
117
|
-
|
118
|
-
records.detect do |record|
|
119
|
-
options.map {|key, value| record.attributes[key.to_s] == value}.all?
|
120
|
-
end
|
116
|
+
results.first
|
121
117
|
end
|
122
118
|
end
|
123
119
|
|
@@ -151,24 +147,7 @@ module DBF
|
|
151
147
|
s = "ActiveRecord::Schema.define do\n"
|
152
148
|
s << " create_table \"#{File.basename(@data.path, ".*")}\" do |t|\n"
|
153
149
|
columns.each do |column|
|
154
|
-
s << " t.column
|
155
|
-
case column.type
|
156
|
-
when "N" # number
|
157
|
-
if column.decimal > 0
|
158
|
-
s << ", :float"
|
159
|
-
else
|
160
|
-
s << ", :integer"
|
161
|
-
end
|
162
|
-
when "D" # date
|
163
|
-
s << ", :datetime"
|
164
|
-
when "L" # boolean
|
165
|
-
s << ", :boolean"
|
166
|
-
when "M" # memo
|
167
|
-
s << ", :text"
|
168
|
-
else
|
169
|
-
s << ", :string, :limit => #{column.length}"
|
170
|
-
end
|
171
|
-
s << "\n"
|
150
|
+
s << " t.column #{column.schema_definition}"
|
172
151
|
end
|
173
152
|
s << " end\nend"
|
174
153
|
|
@@ -206,8 +185,8 @@ module DBF
|
|
206
185
|
@columns = []
|
207
186
|
@column_count.times do
|
208
187
|
name, type, length, decimal = @data.read(32).unpack('a10 x a x4 C2')
|
209
|
-
if length > 0
|
210
|
-
@columns << Column.new(name, type, length, decimal)
|
188
|
+
if length > 0
|
189
|
+
@columns << Column.new(name.strip, type, length, decimal)
|
211
190
|
end
|
212
191
|
end
|
213
192
|
# Reset the column count
|
@@ -263,6 +242,10 @@ module DBF
|
|
263
242
|
end
|
264
243
|
end
|
265
244
|
end
|
245
|
+
|
246
|
+
def all_values_match?(record, options)
|
247
|
+
options.map {|key, value| record.attributes[key.to_s] == value}.all?
|
248
|
+
end
|
266
249
|
end
|
267
250
|
|
268
251
|
end
|
@@ -1,19 +1,19 @@
|
|
1
1
|
ActiveRecord::Schema.define do
|
2
2
|
create_table "dbase_83" do |t|
|
3
|
-
t.column "
|
4
|
-
t.column "
|
5
|
-
t.column "
|
6
|
-
t.column "
|
7
|
-
t.column "
|
8
|
-
t.column "
|
9
|
-
t.column "
|
10
|
-
t.column "
|
11
|
-
t.column "
|
12
|
-
t.column "
|
13
|
-
t.column "
|
14
|
-
t.column "
|
15
|
-
t.column "
|
16
|
-
t.column "
|
17
|
-
t.column "
|
3
|
+
t.column "id", :integer
|
4
|
+
t.column "catcount", :integer
|
5
|
+
t.column "agrpcount", :integer
|
6
|
+
t.column "pgrpcount", :integer
|
7
|
+
t.column "order", :integer
|
8
|
+
t.column "code", :string, :limit => 50
|
9
|
+
t.column "name", :string, :limit => 100
|
10
|
+
t.column "thumbnail", :string, :limit => 254
|
11
|
+
t.column "image", :string, :limit => 254
|
12
|
+
t.column "price", :float
|
13
|
+
t.column "cost", :float
|
14
|
+
t.column "desc", :text
|
15
|
+
t.column "weight", :float
|
16
|
+
t.column "taxable", :boolean
|
17
|
+
t.column "active", :boolean
|
18
18
|
end
|
19
19
|
end
|
data/spec/unit/column_spec.rb
CHANGED
@@ -26,8 +26,8 @@ describe DBF::Column, "when initialized" do
|
|
26
26
|
lambda { column = DBF::Column.new "ColumnName", "N", -1, 0 }.should raise_error(DBF::ColumnLengthError)
|
27
27
|
end
|
28
28
|
|
29
|
-
it "should strip
|
30
|
-
column = DBF::Column.new "
|
29
|
+
it "should strip non-ascii characters from the name" do
|
30
|
+
column = DBF::Column.new "Col\200umn\0Name\037", "N", 1, 0
|
31
31
|
column.name.should == "ColumnName"
|
32
32
|
end
|
33
33
|
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4
|
|
3
3
|
specification_version: 1
|
4
4
|
name: dbf
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.0.
|
7
|
-
date: 2007-
|
6
|
+
version: 1.0.5
|
7
|
+
date: 2007-11-27 00:00:00 -08:00
|
8
8
|
summary: A small fast library for reading dBase, xBase, Clipper and FoxPro database files.
|
9
9
|
require_paths:
|
10
10
|
- lib
|