mirror of
https://github.com/wader/fq.git
synced 2024-12-02 12:45:53 +03:00
90 lines
2.0 KiB
Go
90 lines
2.0 KiB
Go
package postgres
|
|
|
|
import (
|
|
"github.com/wader/fq/format"
|
|
"github.com/wader/fq/pkg/decode"
|
|
"github.com/wader/fq/pkg/interp"
|
|
"github.com/wader/fq/pkg/scalar"
|
|
)
|
|
|
|
// TO DO
|
|
// actualize
|
|
|
|
const BLCKSZ = 8192
|
|
|
|
func init() {
|
|
interp.RegisterFormat(decode.Format{
|
|
Name: format.PG_MULTIXACTOFF,
|
|
Description: "PostgreSQL multixact offset file",
|
|
DecodeFn: mxOffsetDecode,
|
|
})
|
|
interp.RegisterFormat(decode.Format{
|
|
Name: format.PG_MULTIXACTMEM,
|
|
Description: "PostgreSQL multixact members file",
|
|
DecodeFn: mxMembersDecode,
|
|
})
|
|
}
|
|
|
|
func mxOffsetDecode(d *decode.D, in interface{}) interface{} {
|
|
d.Endian = decode.LittleEndian
|
|
|
|
d.FieldArray("offsets", func(d *decode.D) {
|
|
for {
|
|
if d.End() {
|
|
break
|
|
}
|
|
d.FieldU32("offset", scalar.ActualHex)
|
|
|
|
}
|
|
})
|
|
return nil
|
|
}
|
|
|
|
var flags = scalar.UToScalar{
|
|
0: {Sym: "ForKeyShare", Description: "For Key Share"},
|
|
1: {Sym: "ForShare", Description: "For Share"},
|
|
2: {Sym: "ForNoKeyUpdate", Description: "For No Key Update"},
|
|
3: {Sym: "ForUpdate", Description: "For Update"},
|
|
4: {Sym: "NoKeyUpdate", Description: "No Key Update"},
|
|
5: {Sym: "Update", Description: "Update"},
|
|
}
|
|
|
|
func mxMembersDecode(d *decode.D, in interface{}) interface{} {
|
|
var xidLen uint = 4
|
|
var groupLen uint = 4 * (1 + xidLen)
|
|
d.Endian = decode.LittleEndian
|
|
|
|
m := d.FieldArrayValue("members")
|
|
p := d.FieldArrayValue("paddings")
|
|
|
|
for {
|
|
var xacts []*decode.D = make([]*decode.D, 4)
|
|
|
|
for i := 0; i < 4; i++ {
|
|
xacts[i] = m.FieldStructValue("xact")
|
|
xacts[i].FieldU8("status", flags)
|
|
}
|
|
|
|
for i := 0; i < 4; i++ {
|
|
xacts[i].FieldU32("xid")
|
|
}
|
|
|
|
// Check if rest of bytes are padding before EOF
|
|
if d.BitsLeft() < int64(groupLen*8) && d.BitsLeft() > 0 {
|
|
p.FieldRawLen("padding", d.BitsLeft())
|
|
break
|
|
}
|
|
|
|
// Check on EOF
|
|
if d.End() {
|
|
break
|
|
}
|
|
|
|
// Not EOF, let's check on block boundary
|
|
if blkLeft := BLCKSZ - (uint(d.Pos())>>3)%BLCKSZ; blkLeft < groupLen {
|
|
p.FieldRawLen("padding", int64(blkLeft*8))
|
|
}
|
|
}
|
|
return nil
|
|
}
|