lib/dbf/table.rb in dbf-2.0.3 vs lib/dbf/table.rb in dbf-2.0.4

- old
+ new

@@ -13,19 +13,22 @@ "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", + "43" => "dBASE IV SQL table files, no memo", + "63" => "dBASE IV SQL system files, no memo", "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", + "cb" => "dBASE IV SQL table files, with memo", "f5" => "FoxPro with memo file", "fb" => "FoxPro without memo file" } - + FOXPRO_VERSIONS = { "30" => "Visual FoxPro", "31" => "Visual FoxPro with AutoIncrement field", "f5" => "FoxPro with memo file", "fb" => "FoxPro without memo file" @@ -56,15 +59,15 @@ # @param [String, StringIO] data Path to the dbf file or a StringIO object # @param [optional String, StringIO] memo Path to the memo file or a StringIO object # @param [optional String, Encoding] encoding Name of the encoding or an Encoding object def initialize(data, memo = nil, encoding = nil) @data = open_data(data) - get_header_info - @encoding = encoding || @encoding + @version, @record_count, @header_length, @record_length, @encoding_key, @encoding = get_header_info + @encoding = encoding if encoding @memo = open_memo(data, memo) end - + # @return [TrueClass, FalseClass] def has_memo_file? !!@memo end @@ -73,20 +76,20 @@ # @return [TrueClass, FalseClass] def close @data.close @memo && @memo.close end - + # @return [TrueClass, FalseClass] def closed? if @memo @data.closed? && @memo.closed? else @data.closed? end end - + # @return String def filename File.basename @data.path end @@ -211,36 +214,32 @@ end end columns end end - + def supports_encoding? String.new.respond_to?(:encoding) end - + def supports_iconv? require 'iconv' true rescue false end - + def foxpro? FOXPRO_VERSIONS.keys.include? @version end private - + def column_class #nodoc - @column_class ||= if foxpro? - Column::Foxpro - else - Column::Dbase - end + @column_class ||= foxpro? ? Column::Foxpro : Column::Dbase end - + def memo_class #nodoc @memo_class ||= if foxpro? Memo::Foxpro else if @version == "83" @@ -248,11 +247,11 @@ else Memo::Dbase4 end end end - + def column_count #nodoc @column_count ||= ((@header_length - DBF_HEADER_SIZE + 1) / DBF_HEADER_SIZE).to_i end def open_data(data) #nodoc @@ -263,19 +262,23 @@ if memo.is_a? StringIO memo_class.new(memo, version) elsif memo memo_class.open(memo, version) elsif !data.is_a? StringIO - dirname = File.dirname(data) - basename = File.basename(data, '.*') - files = Dir.glob("#{dirname}/#{basename}*.{fpt,FPT,dbt,DBT}") + files = Dir.glob(memo_search_path(data)) files.any? ? memo_class.open(files.first, version) : nil else nil end end + def memo_search_path(io) #nodoc + dirname = File.dirname(io) + basename = File.basename(io, '.*') + "#{dirname}/#{basename}*.{fpt,FPT,dbt,DBT}" + end + def find_all(options) #nodoc map do |record| if record && record.match?(options) yield record if block_given? record @@ -291,13 +294,14 @@ @data.read(1).unpack('a') == ['*'] end def get_header_info #nodoc @data.rewind - @version, @record_count, @header_length, @record_length, @encoding_key = read_header - @encoding = ENCODINGS[@encoding_key] if supports_encoding? || supports_iconv? + version, record_count, header_length, record_length, encoding_key = read_header + encoding = ENCODINGS[encoding_key] if supports_encoding? || supports_iconv? + [version, record_count, header_length, record_length, encoding_key, encoding] end - + def read_header #nodoc @data.read(DBF_HEADER_SIZE).unpack("H2 x3 V v2 x17H2") end def seek(offset) #nodoc