A handful of fixes/enhancements for the "dbf" Rubygem.
1
2
3 require 'rubygems'
4 require 'dbf'
5 require 'dbf_fixes'
6
7 table = DBF::Table.new('/path/to/table.dbf', :in_memory => false)
8 table.each_record do |record|
9
10
11
12 end
1
2
3 module DBF
4 class Record
5 private
6
7
8 def initialize_values(columns)
9 columns.each do |column|
10 case column.type
11 when 'I'
12 @attributes[column.name] = @data.read(column.length).unpack("I").first
13 when 'N'
14 @attributes[column.name] = column.decimal.zero? ? unpack_string(column).to_i : unpack_string(column).to_f
15 when 'D'
16 raw = unpack_string(column).strip
17 unless raw.empty?
18 begin
19 parts = raw.match(DATE_REGEXP).to_a.slice(1,3).map {|n| n.to_i}
20 @attributes[column.name] = Time.gm(*parts)
21 rescue
22 parts = raw.match(DATE_REGEXP).to_a.slice(1,3).map {|n| n.to_i}
23 @attributes[column.name] = Date.new(*parts)
24 end
25 end
26 when 'M'
27 starting_block = unpack_string(column).to_i
28 @attributes[column.name] = read_memo(starting_block)
29 when 'L'
30 @attributes[column.name] = unpack_string(column) =~ /^(y|t)$/i ? true : false
31 else
32 @attributes[column.name] = unpack_string(column).strip
33 end
34 end
35 end
36
37
38 def define_accessors
39 @table.columns.each do |column|
40 underscored_column_name = underscore(column.name)
41 if @table.options[:accessors]
42 self.class.send :define_method, underscored_column_name do
43 @attributes[column.name]
44 end
45 @@accessors_defined = true
46 end
47 end
48 end
49 end
50
51 class Table
52
53 def each_record
54 if options[:in_memory] and @records
55 @records.each { |r| yield(r) }
56 else
57 0.upto(@record_count - 1) do |n|
58 seek_to_record(n)
59 yield(DBF::Record.new(self)) unless deleted_record?
60 end
61 end
62 end
63 end
64 end