Class: RBase::Table

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/rbase/table.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#columnsObject (readonly)

Returns the value of attribute columns.



113
114
115
# File 'lib/rbase/table.rb', line 113

def columns
  @columns
end

#countObject

Returns the value of attribute count.



113
114
115
# File 'lib/rbase/table.rb', line 113

def count
  @count
end

#languageObject (readonly)

Returns the value of attribute language.



113
114
115
# File 'lib/rbase/table.rb', line 113

def language
  @language
end

#last_modified_onObject

Returns the value of attribute last_modified_on.



113
114
115
# File 'lib/rbase/table.rb', line 113

def last_modified_on
  @last_modified_on
end

#nameObject (readonly)

Returns the value of attribute name.



113
114
115
# File 'lib/rbase/table.rb', line 113

def name
  @name
end

Class Method Details

.create(name, schema, options = {}) ⇒ Object

Create new XBase table file. Table file name will be equal to name with “.dbf” suffix.

Allowed options

* :language - language character set used in database. Can be one of LANGUAGE_* constants


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/rbase/table.rb', line 12

def self.create(name, schema, options = {})
  date = Date.today

  record_size = 1+schema.columns.inject(0) { |size, column| size + column.size }

  data = ''
  # data << [0xf5].pack('C') # version
  data << [0x3].pack('C') # version
  data << [date.year % 100, date.month, date.day].pack('CCC') # last modification date
  data << [0].pack('L') # number of records
  # data << [32+schema.columns.size*32+263+1].pack('v') # data size
  data << [32+schema.columns.size*32+1].pack('v') # data size
  data << [record_size].pack('v') # record size
  data << [].pack('x2') # reserved
  data << [].pack('x') # incomplete transaction
  data << [].pack('x') # encyption flag
  data << [].pack('x4') # reserved
  data << [].pack('x8') # reserved
  data << [0].pack('c') # mdx flag
  data << [options[:language]].pack('C') # language driver
  data << [].pack('x2') # reserved

  offset = 1 # take into account 1 byte for deleted flag
  data << schema.columns.collect do |column|
    s = ''
    s << [column.name.to_s[0..9]].pack('a11') # field name
    s << [column.type].pack('a') # field type
    s << [offset].pack('L') # field data offset
    s << [column.size].pack('C') # field size
    s << [column.decimal || 0].pack('C') # decimal count
    s << [].pack('x2') # reserved
    s << [].pack('x') # work area id
    s << [].pack('x2') # reserved
    s << [].pack('x') # flag for SET FIELDS
    s << [].pack('x7') # reserved
    s << [].pack('x') # index field flag
    offset += column.size
    s
  end.join

  data << [13].pack('C') # terminator

  data << [26].pack('C') # end of file

  File.open("#{name}.dbf", 'wb') do |f|
    f.write data
  end
end

.open(name, options = {}) ⇒ Object

Open table with given name. Table name should be like file name without “.dbf” suffix.



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/rbase/table.rb', line 63

def self.open(name, options = {})
  table = new
  table.instance_eval { open("#{name}.dbf", options) }
  if block_given?
    result = yield table
    table.close
    result
  else
    table
  end
end

Instance Method Details

#[]=(index, record) ⇒ Object



148
149
150
151
# File 'lib/rbase/table.rb', line 148

def []=(index, record)
  record.instance_eval { @index = index }
  save(record)
end

#build(attributes = {}) ⇒ Object

Create new record, populate it with given attributes



126
127
128
# File 'lib/rbase/table.rb', line 126

def build(attributes = {})
  Record.new(self, attributes)
end

#clearObject



99
100
101
102
103
104
105
106
107
# File 'lib/rbase/table.rb', line 99

def clear
  file_end = @record_offset
  @file.pos = file_end
  @file.write "\x1a"
  @file.truncate file_end+1

  self.count = 0
  update_header
end

#closeObject



109
110
111
# File 'lib/rbase/table.rb', line 109

def close
  @file.close
end

#column(name) ⇒ Object

Return instance of RBase::Column for given column name



116
117
118
# File 'lib/rbase/table.rb', line 116

def column(name)
  @name_to_columns[name]
end

#create(attributes = {}) ⇒ Object

Create new record, populate it with given attributes and save it



131
132
133
134
135
# File 'lib/rbase/table.rb', line 131

def create(attributes = {})
  record = build(attributes)
  record.save
  record
end

#eachObject

Iterate through all non-deleted records



163
164
165
166
167
168
169
# File 'lib/rbase/table.rb', line 163

def each
  return unless block_given?

  self.each_with_deleted do |record|
    yield record unless record.deleted?
  end
end

#each_with_deletedObject

Iterate through all (even deleted) records



154
155
156
157
158
159
160
# File 'lib/rbase/table.rb', line 154

def each_with_deleted
  return unless block_given?

  count.times do |i|
    yield load(i)
  end
end

#load(index) ⇒ Object Also known as: []

Load record stored in position ‘index’



138
139
140
141
142
143
144
# File 'lib/rbase/table.rb', line 138

def load(index)
  @file.pos = @record_offset + @record_size*index
  data = @file.read(@record_size)
  record = Record.new(self)
  record.instance_eval { load(index, data) }
  record
end

#memoObject

Returns instance of MemoFile that is associated with table



121
122
123
# File 'lib/rbase/table.rb', line 121

def memo
  return @memo_file
end

#packObject

Physically remove records that were marked as deleted from file.



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/rbase/table.rb', line 76

def pack
  packed_count = 0
  count.times do |i|
    @file.pos = @record_offset + @record_size*i
    data = @file.read(@record_size)
    unless data[0, 1]=='*'
      if i!=packed_count
        @file.pos = @record_offset + @record_size*packed_count
        @file.write data
      end
      packed_count += 1
    end
  end

  file_end = @record_offset + @record_size*packed_count
  @file.pos = file_end
  @file.write "\x1a"
  @file.truncate file_end+1

  self.count = packed_count
  update_header
end