Class: MiqSqlite3DB::MiqSqlite3Page

Inherits:
Object
  • Object
show all
Defined in:
lib/db/MiqSqlite/MiqSqlite3Page.rb

Constant Summary collapse

HEADER =

Page Header.

BinaryStruct.new([              # All integers are in Big-Endian (or Network) Order
  #    OFFSET   SIZE     DESCRIPTION
  'C',  'flags',                      #       0       1      Flags. 1: intkey, 2: zerodata, 4: leafdata, 8: leaf
  'n',  'offset2freeblock',           #       1       2      byte offset to the first freeblock
  'n',  'num_cells',                  #       3       2      number of cells on this page
  'n',  'offset2cell',                #       5       2      first byte of the cell content area
  'C',  'num_fragmented_free_bytes',  #       7       1      number of fragmented free bytes
  'N',  'right_child',                #       8       4      Right child (the Ptr(N) value).  Omitted on leaves.
])
SIZEOF_HEADER =
HEADER.size

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(buf, db, pagenum) ⇒ MiqSqlite3Page

Returns a new instance of MiqSqlite3Page.



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 51

def initialize(buf, db, pagenum)
  raise "Nil buffer" if buf.nil?
  @pagenum    = pagenum
  @db         = db
  @buf        = buf
  @pagesize   = buf.size
  skip        = (pagenum == 1) ? SIZEOF_DBHEADER : 0
  @header     = OpenStruct.new(HEADER.decode(@buf[skip, SIZEOF_HEADER]))
  decodeFlags
  headerSize  = SIZEOF_HEADER - @childPtrSize
  @data       = buf[skip + headerSize..-1]
  @cells = @cellPointers = nil
end

Instance Attribute Details

#bufObject

Instance Methods



49
50
51
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 49

def buf
  @buf
end

#hasDataObject

Instance Methods



49
50
51
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 49

def hasData
  @hasData
end

#intKeyObject

Instance Methods



49
50
51
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 49

def intKey
  @intKey
end

#leafObject

Instance Methods



49
50
51
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 49

def leaf
  @leaf
end

#maxLocalObject

Instance Methods



49
50
51
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 49

def maxLocal
  @maxLocal
end

#minLocalObject

Instance Methods



49
50
51
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 49

def minLocal
  @minLocal
end

#pagenumObject

Instance Methods



49
50
51
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 49

def pagenum
  @pagenum
end

Class Method Details

.getPage(db, pagenum) ⇒ Object

Class Methods



25
26
27
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 25

def self.getPage(db, pagenum)
  MiqSqlite3Page.new(db.readPage(pagenum), db, pagenum)
end

.intKey?(f) ⇒ Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 29

def self.intKey?(f)
  f & 0x01 == 0x01
end

.leaf?(f) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 41

def self.leaf?(f)
  f & 0x08 == 0x08
end

.leafData?(f) ⇒ Boolean

Returns:

  • (Boolean)


37
38
39
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 37

def self.leafData?(f)
  f & 0x04 == 0x04
end

.zeroData?(f) ⇒ Boolean

Returns:

  • (Boolean)


33
34
35
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 33

def self.zeroData?(f)
  f & 0x02 == 0x02
end

Instance Method Details

#cellPointers2StringObject



128
129
130
131
132
133
134
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 128

def cellPointers2String
  initCellPointers if @cellPointers.nil?
  str = ""
  @cellPointers.each { |p| str << "#{p} " }
  return nil if str == ""
  str.chomp
end

#decodeFlagsObject



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 65

def decodeFlags
  @leafData = MiqSqlite3Page.leafData?(@header.flags)
  @zeroData = MiqSqlite3Page.zeroData?(@header.flags)
  @leaf     = MiqSqlite3Page.leaf?(@header.flags)
  @childPtrSize = @leaf ? 4 : 0
  if MiqSqlite3Page.leafData?(@header.flags)
    @intKey   = MiqSqlite3Page.intKey?(@header.flags)
    @maxLocal = @db.maxLeaf
    @minLocal = @db.minLeaf
  else
    @intKey   = false
    @maxLocal = @db.maxLocal
    @minLocal = @db.minLocal
  end
  @hasData = !(@zeroData || (!@leaf && @leafData))
end

#dumpObject



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 101

def dump
  puts "================="
  puts "Page:                            #{@pagenum}"
  #     puts "Page Size:                       #{@pagesize}"
  #     puts "Data Size:                       #{@data.size}"
  #     puts "Flags (Raw):                     #{@header.flags}"
  puts "Flags:                           #{flags2str}"
  puts "Offset to First Freeblock:       #{@header.offset2freeblock}"
  puts "Offset to Cell Content Area:     #{@header.offset2cell}"
  puts "Number of Cells:                 #{@header.num_cells}"
  puts "Number of Fragmented Free Bytes: #{@header.num_fragmented_free_bytes}"
  puts "Right Child:                     #{@header.right_child}"   unless @leaf
  puts "Cell Pointers:                   #{cellPointers2String}"

  #     each_cell { |cell| p cell }
  #     each_child { |kid| puts "Child: #{kid}"}
end

#each_cellObject



89
90
91
92
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 89

def each_cell
  initCells if @cells.nil?
  @cells.each { |c| yield c }
end

#each_child {|@header.right_child| ... } ⇒ Object

Yields:

  • (@header.right_child)


82
83
84
85
86
87
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 82

def each_child
  each_cell do |cell|
    yield cell.left_child if cell.left_child
  end
  yield @header.right_child unless @leaf
end

#flags2strObject



119
120
121
122
123
124
125
126
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 119

def flags2str
  str = ""
  str << "IntKey "   if @intKey
  str << "ZeroData " if @zeroData
  str << "LeafData " if @leafData
  str << "Leaf "     if @leaf
  str.chomp
end

#initCellPointersObject



136
137
138
139
140
141
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 136

def initCellPointers
  @cellPointers = []
  for i in 1..@header.num_cells
    @cellPointers << @data[(i - 1) * 2, 2].unpack('n')[0]
  end
end

#initCellsObject



143
144
145
146
147
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 143

def initCells
  @cells = []
  initCellPointers if @cellPointers.nil?
  @cellPointers.each { |p| @cells << MiqSqlite3Cell.new(self, p) }
end

#leaves {|_self| ... } ⇒ Object

Yields:

  • (_self)

Yield Parameters:



94
95
96
97
98
99
# File 'lib/db/MiqSqlite/MiqSqlite3Page.rb', line 94

def leaves
  each_child do |child|
    MiqSqlite3Page.getPage(@db, child).leaves { |p| yield p }
  end
  yield self if @leaf
end