From 5e8520cd5d3042e41db7613a4a189c76f8574fb8 Mon Sep 17 00:00:00 2001 From: name5566 Date: Tue, 5 Aug 2014 23:27:07 +0800 Subject: [PATCH] implement simple recordfile --- recordfile/recordfile.go | 93 +++++++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 20 deletions(-) diff --git a/recordfile/recordfile.go b/recordfile/recordfile.go index 48b56673..406f41fc 100644 --- a/recordfile/recordfile.go +++ b/recordfile/recordfile.go @@ -6,18 +6,18 @@ import ( "fmt" "os" "reflect" + "strconv" ) -const ( - defComma = ',' - defComment = '#' -) +var Comma rune = ',' +var Comment rune = '#' type RecordFile struct { Comma rune Comment rune kindFields []reflect.Kind tagFields []reflect.StructTag + typeRecord reflect.Type records []interface{} indexes [](map[interface{}]interface{}) } @@ -31,11 +31,11 @@ func New(st interface{}) (*RecordFile, error) { rf := new(RecordFile) rf.kindFields = make([]reflect.Kind, t.NumField()) rf.tagFields = make([]reflect.StructTag, t.NumField()) + rf.typeRecord = t for i := 0; i < t.NumField(); i++ { f := t.Field(i) - // kind k := f.Type.Kind() if k == reflect.Bool || k == reflect.Int8 || @@ -43,6 +43,7 @@ func New(st interface{}) (*RecordFile, error) { k == reflect.Int32 || k == reflect.Int64 || k == reflect.Uint8 || + k == reflect.Uint16 || k == reflect.Uint32 || k == reflect.Uint64 || k == reflect.Float32 || @@ -53,7 +54,6 @@ func New(st interface{}) (*RecordFile, error) { return nil, errors.New("invalid type: " + k.String()) } - // tag tag := f.Tag if tag == "" || tag == "index" { @@ -74,10 +74,10 @@ func (rf *RecordFile) Read(name string) error { defer f.Close() if rf.Comma == 0 { - rf.Comma = defComma + rf.Comma = Comma } if rf.Comment == 0 { - rf.Comment = defComment + rf.Comment = Comment } reader := csv.NewReader(f) @@ -88,22 +88,75 @@ func (rf *RecordFile) Read(name string) error { return err } - for n, line := range lines { - // kind - if n == 0 { - for i, k := range rf.kindFields { - fmt.Println(i, k) - fmt.Println(line[i]) - } - } + records := make([]interface{}, len(lines)-1) + for n := 1; n < len(lines); n++ { + v := reflect.New(rf.typeRecord) + records[n-1] = v.Interface() + record := v.Elem() - // desc - if n == 1 { - continue + line := lines[n] + if len(line) != len(rf.kindFields) { + return errors.New(fmt.Sprintf("line %v, field count mismatch: %v %v", + n, len(line), len(rf.kindFields))) } - // data + for i, k := range rf.kindFields { + fieldStr := line[i] + field := record.Field(i) + + var err error + + if k == reflect.Bool { + var v bool + v, err = strconv.ParseBool(fieldStr) + if err == nil { + field.SetBool(v) + } + } else if k == reflect.Int8 || + k == reflect.Int16 || + k == reflect.Int32 || + k == reflect.Int64 { + var v int64 + v, err = strconv.ParseInt(fieldStr, 0, field.Type().Bits()) + if err == nil { + field.SetInt(v) + } + } else if k == reflect.Uint8 || + k == reflect.Uint16 || + k == reflect.Uint32 || + k == reflect.Uint64 { + var v uint64 + v, err = strconv.ParseUint(fieldStr, 0, field.Type().Bits()) + if err == nil { + field.SetUint(v) + } + } else if k == reflect.Float32 || + k == reflect.Float64 { + var v float64 + v, err = strconv.ParseFloat(fieldStr, field.Type().Bits()) + if err == nil { + field.SetFloat(v) + } + } else if k == reflect.String { + field.SetString(fieldStr) + } + + if err != nil { + return errors.New(fmt.Sprintf("parse field (row=%v, col=%v) error: %v", + n, i, err)) + } + } } + rf.records = records + return nil } + +func (rf *RecordFile) Record(i int) interface{} { + return rf.records[i] +} + +func (rf *RecordFile) NumRecord() int { + return len(rf.records) +}