Adding the challenge 0401
This commit is contained in:
+95
@@ -0,0 +1,95 @@
|
||||
package db0401
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"slices"
|
||||
)
|
||||
|
||||
type Schema struct {
|
||||
Table string
|
||||
Cols []Column
|
||||
PKey []int // indexes of primary key columns
|
||||
}
|
||||
|
||||
type Column struct {
|
||||
Name string
|
||||
Type CellType
|
||||
}
|
||||
|
||||
type Row []Cell
|
||||
|
||||
func (schema *Schema) NewRow() Row {
|
||||
return make(Row, len(schema.Cols))
|
||||
}
|
||||
|
||||
func (row Row) EncodeKey(schema *Schema) (key []byte) {
|
||||
key = append(key, []byte(schema.Table)...)
|
||||
key = append(key, 0x00)
|
||||
check(len(row) == len(schema.Cols))
|
||||
for idx, value := range row {
|
||||
if slices.Contains(schema.PKey, idx) {
|
||||
check(value.Type == schema.Cols[idx].Type)
|
||||
key = row[idx].Encode(key)
|
||||
}
|
||||
}
|
||||
return key
|
||||
}
|
||||
|
||||
func (row Row) EncodeVal(schema *Schema) (val []byte) {
|
||||
check(len(row) == len(schema.Cols))
|
||||
for idx, value := range row {
|
||||
if !slices.Contains(schema.PKey, idx) {
|
||||
check(value.Type == schema.Cols[idx].Type)
|
||||
val = row[idx].Encode(val)
|
||||
}
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (row Row) DecodeKey(schema *Schema, key []byte) (err error) {
|
||||
check(len(row) == len(schema.Cols))
|
||||
|
||||
if len(key) < len(schema.Table)+1 {
|
||||
return errors.New("bad key")
|
||||
}
|
||||
if string(key[:len(schema.Table)+1]) != schema.Table+"\x00" {
|
||||
return errors.New("bad key")
|
||||
}
|
||||
key = key[len(schema.Table)+1:]
|
||||
|
||||
for idx, col := range schema.Cols {
|
||||
if !slices.Contains(schema.PKey, idx) {
|
||||
continue
|
||||
}
|
||||
row[idx] = Cell{Type: col.Type}
|
||||
if key, err = row[idx].Decode(key); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(key) != 0 {
|
||||
return errors.New("trailing garbage")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (row Row) DecodeVal(schema *Schema, val []byte) (err error) {
|
||||
check(len(row) == len(schema.Cols))
|
||||
|
||||
for idx, col := range schema.Cols {
|
||||
if slices.Contains(schema.PKey, idx) {
|
||||
continue
|
||||
}
|
||||
row[idx] = Cell{Type: col.Type}
|
||||
if val, err = row[idx].Decode(val); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(val) != 0 {
|
||||
return errors.New("trailing garbage")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// QzBQWVJJOUhU https://trialofcode.org/
|
||||
Reference in New Issue
Block a user