Class: DBF::Table

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Find, Schema, Enumerable
Defined in:
lib/dbf/table.rb

Overview

DBF::Table is the primary interface to a single DBF file and provides methods for enumerating and searching the records.

Direct Known Subclasses

Database::Table

Constant Summary

Constants included from Schema

Schema::FORMATS, Schema::OTHER_DATA_TYPES, Schema::STRING_DATA_FORMATS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Find

#find

Methods included from Schema

#activerecord_schema, #activerecord_schema_definition, #json_schema, #number_data_type, #schema, #schema_data_type, #schema_name, #sequel_schema, #sequel_schema_definition, #string_data_format

Constructor Details

#initialize(data, memo = nil, encoding = nil, name: nil) {|_self| ... } ⇒ Table

Opens a DBF::Table Examples:

# working with a file stored on the filesystem
table = DBF::Table.new 'data.dbf'

# working with a misnamed memo file
table = DBF::Table.new 'data.dbf', 'memo.dbt'

# working with a dbf in memory
table = DBF::Table.new StringIO.new(dbf_data)

# working with a dbf and memo in memory
table = DBF::Table.new StringIO.new(dbf_data), StringIO.new(memo_data)

# working with a dbf overriding specified in the dbf encoding
table = DBF::Table.new 'data.dbf', nil, 'cp437'
table = DBF::Table.new 'data.dbf', 'memo.dbt', Encoding::US_ASCII

Parameters:

  • data (String, StringIO)

    data Path to the dbf file or a StringIO object

  • memo (optional String, StringIO) (defaults to: nil)

    memo Path to the memo file or a StringIO object

  • encoding (optional String, Encoding) (defaults to: nil)

    encoding Name of the encoding or an Encoding object

Yields:

  • (_self)

Yield Parameters:

  • _self (DBF::Table)

    the object that the method was called on



50
51
52
53
54
55
56
57
# File 'lib/dbf/table.rb', line 50

def initialize(data, memo = nil, encoding = nil, name: nil)
  @data = FileHandler.open_data(data)
  @user_encoding = encoding
  @encoding = determine_encoding
  @memo = FileHandler.open_memo(data, memo, version_config.memo_class, version)
  @name = name
  yield self if block_given?
end

Instance Attribute Details

#encodingObject (readonly)

Returns the value of attribute encoding.



22
23
24
# File 'lib/dbf/table.rb', line 22

def encoding
  @encoding
end

Instance Method Details

#closeTrueClass, FalseClass

Closes the table and memo file

Returns:

  • (TrueClass, FalseClass)


62
63
64
65
# File 'lib/dbf/table.rb', line 62

def close
  @data.close
  @memo&.close
end

#closed?TrueClass, FalseClass

Returns:

  • (TrueClass, FalseClass)


68
69
70
# File 'lib/dbf/table.rb', line 68

def closed?
  @data.closed? && (!@memo || @memo.closed?)
end

#column_namesString

Column names

Returns:

  • (String)


75
76
77
# File 'lib/dbf/table.rb', line 75

def column_names
  @column_names ||= columns.map(&:name)
end

#column_offsetsArray<Integer>

Cumulative byte offsets for each column within a record

Returns:

  • (Array<Integer>)


82
83
84
85
86
87
# File 'lib/dbf/table.rb', line 82

def column_offsets
  @column_offsets ||= begin
    sum = 0
    columns.map { |col| sum.tap { sum += col.length } }
  end
end

#columnsArray

All columns

Returns:

  • (Array)


96
97
98
# File 'lib/dbf/table.rb', line 96

def columns
  @columns ||= build_columns
end

#each {|nil, DBF::Record| ... } ⇒ Object

Calls block once for each record in the table. The record may be nil if the record has been marked as deleted.

Yields:



104
105
106
107
108
109
# File 'lib/dbf/table.rb', line 104

def each(&)
  return enum_for(:each) unless block_given?
  return if columns.empty?

  RecordIterator.new(@data, record_context, header_length, record_length, record_count).each(&)
end

#encode_string(string) ⇒ String

Encode string

Parameters:

  • string (String)

Returns:

  • (String)


174
175
176
# File 'lib/dbf/table.rb', line 174

def encode_string(string) # :nodoc:
  Encoder.encode(string, @encoding)
end

#filenameString

Returns:

  • (String)


112
113
114
# File 'lib/dbf/table.rb', line 112

def filename
  File.basename(@data.path) if @data.is_a?(File)
end

#has_memo_file?TrueClass, FalseClass

Returns:

  • (TrueClass, FalseClass)


117
118
119
# File 'lib/dbf/table.rb', line 117

def has_memo_file?
  !!@memo
end

#header_encodingEncoding

Encoding specified in the file header

Returns:

  • (Encoding)


181
182
183
# File 'lib/dbf/table.rb', line 181

def header_encoding
  header.encoding
end

#nameString

Returns:

  • (String)


122
123
124
# File 'lib/dbf/table.rb', line 122

def name
  @name ||= filename && File.basename(filename, '.*')
end

#record(index) ⇒ DBF::Record, NilClass Also known as: row

Retrieve a record by index number. The record will be nil if it has been deleted, but not yet pruned from the database.

Parameters:

  • index (Integer)

Returns:

Raises:



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/dbf/table.rb', line 132

def record(index)
  raise DBF::NoColumnsDefined, 'The DBF file has no columns defined' if columns.empty?

  seek_to_record(index)
  return nil if deleted_record?

  record_data = @data.read(record_length)
  # A file that ends immediately after the delete flag has no record body;
  # treat it as absent rather than building a Record over nil data.
  return nil unless record_data

  DBF::Record.new(record_data, record_context)
end

#record_contextObject



89
90
91
# File 'lib/dbf/table.rb', line 89

def record_context
  @record_context ||= RecordContext.new(columns:, version:, memo: @memo, column_offsets:)
end

#to_csv(path_or_io = nil) ⇒ Object

Dumps all records to a CSV file. If no filename is given then CSV is output to STDOUT.

Parameters:

  • path_or_io (optional String, IO) (defaults to: nil)

    String path, IO-like object, or nil for STDOUT



152
153
154
155
156
157
158
159
160
161
# File 'lib/dbf/table.rb', line 152

def to_csv(path_or_io = nil)
  io = case path_or_io
  when nil then $stdout
  when String then File.open(path_or_io, 'w')
  else path_or_io
  end
  csv = CSV.new(io, force_quotes: true)
  csv << column_names.map { |name| csv_safe_value(name) }
  each { |record| csv << record.to_a.map { |value| csv_safe_value(value) } }
end

#version_descriptionString

Human readable version description

Returns:

  • (String)


166
167
168
# File 'lib/dbf/table.rb', line 166

def version_description
  version_config.version_description
end