lib/dbf/table.rb in dbf-1.7.2 vs lib/dbf/table.rb in dbf-1.7.3

- old
+ new

@@ -10,14 +10,16 @@ VERSIONS = { "02" => "FoxBase", "03" => "dBase III without memo file", "04" => "dBase IV without memo file", "05" => "dBase V without memo file", + "07" => "Visual Objects 1.x", "30" => "Visual FoxPro", "31" => "Visual FoxPro with AutoIncrement field", "7b" => "dBase IV with memo file", "83" => "dBase III with memo file", + "87" => "Visual Objects 1.x with memo file", "8b" => "dBase IV with memo file", "8e" => "dBase IV with SQL table", "f5" => "FoxPro with memo file", "fb" => "FoxPro without memo file" } @@ -184,22 +186,23 @@ # Retrieves column information from the database def columns @columns ||= begin @data.seek(DBF_HEADER_SIZE) columns = [] - column_count.times do - name, type, length, decimal = @data.read(32).unpack('a10 x a x4 C2') + while !["\0", "\r"].include?(first_byte = @data.read(1)) + column_data = first_byte + @data.read(31) + name, type, length, decimal = column_data.unpack('a10 x a x4 C2') if length > 0 columns << column_class.new(name.strip, type, length, decimal, version, @encoding) end end columns end end def supports_encoding? - "".respond_to? :encoding + String.new.respond_to? :encoding end def foxpro? FOXPRO_VERSIONS.keys.include? @version end @@ -249,37 +252,40 @@ end end def find_all(options) #nodoc map do |record| - if record.match? options + if record && record.match?(options) yield record if block_given? record end end.compact end def find_first(options) #nodoc - detect {|record| record.match? options} + detect {|record| record && record.match?(options)} end def deleted_record? #nodoc @data.read(1).unpack('a') == ['*'] end def get_header_info #nodoc @data.rewind - @version, @record_count, @header_length, @record_length, encoding_key = - @data.read(DBF_HEADER_SIZE).unpack("H2 x3 V v2 x17H2") - @encoding = self.class.encodings[encoding_key] if supports_encoding? + @version, @record_count, @header_length, @record_length, @encoding_key = read_header + @encoding = self.class.encodings[@encoding_key] if supports_encoding? end + + def read_header #nodoc + @data.read(DBF_HEADER_SIZE).unpack("H2 x3 V v2 x17H2") + end def seek(offset) #nodoc @data.seek @header_length + offset end def csv_class #nodoc - CSV.const_defined?(:Reader) ? FCSV : CSV + @csv_class ||= CSV.const_defined?(:Reader) ? FCSV : CSV end def self.encodings #nodoc @encodings ||= YAML.load_file File.expand_path("../encodings.yml", __FILE__) end