lib/dbf/table.rb in dbf-1.2.9 vs lib/dbf/table.rb in dbf-1.3.0

- old
+ new

@@ -1,10 +1,28 @@ module DBF # DBF::Table is the primary interface to a single DBF file and provides # methods for enumerating and searching the records. class Table + DBF_HEADER_SIZE = 32 + FPT_HEADER_SIZE = 512 + + VERSION_DESCRIPTIONS = { + "02" => "FoxBase", + "03" => "dBase III without memo file", + "04" => "dBase IV without memo file", + "05" => "dBase V without memo file", + "30" => "Visual FoxPro", + "31" => "Visual FoxPro with AutoIncrement field", + "7b" => "dBase IV with memo file", + "83" => "dBase III 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" + } + attr_reader :column_count # The total number of columns attr_reader :columns # An array of DBF::Column attr_reader :version # Internal dBase version number attr_reader :last_updated # Last updated datetime attr_reader :memo_file_format # :fpt or :dpt @@ -33,11 +51,11 @@ # Reloads the database and memo files def reload! @records = nil get_header_info - get_memo_header_info if @memo + get_memo_header_info get_column_descriptors end # Checks if there is a memo file # @@ -57,14 +75,11 @@ # Calls block once for each record in the table. The record may be nil # if the record has been marked as deleted. # # @yield [nil, DBF::Record] def each - 0.upto(@record_count - 1) do |n| - seek_to_record(n) - yield current_record - end + 0.upto(@record_count - 1) {|index| yield record(index)} end # Retrieve a record by index number. # The record will be nil if it has been deleted, but not yet pruned from # the database. @@ -187,13 +202,13 @@ # @yield [optional DBF::Record] # @return [Array] def find_all(options, &block) results = [] each do |record| - if record && all_values_match?(record, options) + if record.try(:match?, options) if block_given? - yield(record) + yield record else results << record end end end @@ -204,24 +219,15 @@ # # @param [Hash] options # @return [DBF::Record, nil] def find_first(options) each do |record| - return record if record && all_values_match?(record, options) + return record if record.try(:match?, options) end nil end - # Do all search parameters match? - # - # @param [DBF::Record] record - # @param [Hash] options - # @return [Boolean] - def all_values_match?(record, options) - options.all? {|key, value| record.attributes[key.to_s.underscore] == value} - end - # Open memo file # # @params [String] path # @return [File] def open_memo(path) @@ -277,16 +283,18 @@ @columns end # Determines the memo block size and next available block def get_memo_header_info - @memo.rewind - if @memo_file_format == :fpt - @memo_next_available_block, @memo_block_size = @memo.read(FPT_HEADER_SIZE).unpack('N x2 n') - @memo_block_size = 0 if @memo_block_size.nil? - else - @memo_block_size = 512 - @memo_next_available_block = File.size(@memo.path) / @memo_block_size + if has_memo_file? + @memo.rewind + if @memo_file_format == :fpt + @memo_next_available_block, @memo_block_size = @memo.read(FPT_HEADER_SIZE).unpack('N x2 n') + @memo_block_size = 0 if @memo_block_size.nil? + else + @memo_block_size = 512 + @memo_next_available_block = File.size(@memo.path) / @memo_block_size + end end end # Seek to a byte offset # \ No newline at end of file