package misc
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"encoding/json"
|
|
"errors"
|
|
"io"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type Record map[string]interface{}
|
|
|
|
const (
|
|
STRING uint8 = iota
|
|
INTEGER
|
|
FLOAT
|
|
DOUBLE
|
|
BOOL
|
|
DATE
|
|
TIME
|
|
DATETIME
|
|
)
|
|
|
|
type Key struct {
|
|
Name string
|
|
Type uint8
|
|
Extra string
|
|
}
|
|
|
|
func parse_key_type(s string) uint8 {
|
|
switch strings.ToLower(s) {
|
|
case "int", "integer":
|
|
return INTEGER
|
|
case "bool", "boolean":
|
|
return BOOL
|
|
case "float":
|
|
return FLOAT
|
|
case "double":
|
|
return DOUBLE
|
|
case "date":
|
|
return DATE
|
|
case "time":
|
|
return TIME
|
|
case "datetime":
|
|
return DATETIME
|
|
default:
|
|
return STRING
|
|
}
|
|
return STRING
|
|
}
|
|
|
|
func (k *Key) Parse(s string) error {
|
|
ss := strings.Split(s, ":")
|
|
switch len(ss) {
|
|
case 1:
|
|
k.Name = ss[0]
|
|
k.Type = STRING
|
|
case 2:
|
|
k.Name = ss[0]
|
|
k.Type = parse_key_type(ss[1])
|
|
case 3:
|
|
k.Name = ss[0]
|
|
k.Type = parse_key_type(ss[1])
|
|
k.Extra = ss[2]
|
|
default:
|
|
return errors.New("Wrong format of key!")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r Record) Assign(v interface{}) error {
|
|
if p, e := json.Marshal(r); nil != e {
|
|
return e
|
|
} else {
|
|
return json.Unmarshal(p, v)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (r Record) GetString(k string, defaults ...string) (string, bool) {
|
|
if v, ok := r[k]; ok {
|
|
if vv, ook := v.(string); ook {
|
|
return vv, true
|
|
}
|
|
}
|
|
d := ""
|
|
if len(defaults) > 0 {
|
|
d = defaults[0]
|
|
}
|
|
return d, false
|
|
}
|
|
|
|
func (r Record) GetInt(k string, defaults ...int) (int, bool) {
|
|
if v, ok := r[k]; ok {
|
|
if vv, ook := v.(int); ook {
|
|
return vv, true
|
|
}
|
|
}
|
|
d := 0
|
|
if len(defaults) > 0 {
|
|
d = defaults[0]
|
|
}
|
|
return d, false
|
|
}
|
|
|
|
func (r Record) GetBool(k string, defaults ...bool) (bool, bool) {
|
|
if v, ok := r[k]; ok {
|
|
if vv, ook := v.(bool); ook {
|
|
return vv, true
|
|
}
|
|
}
|
|
d := false
|
|
if len(defaults) > 0 {
|
|
d = defaults[0]
|
|
}
|
|
return d, false
|
|
}
|
|
|
|
func (r Record) GetFloat(k string, defaults ...float32) (float32, bool) {
|
|
if v, ok := r[k]; ok {
|
|
if vv, ook := v.(float32); ook {
|
|
return vv, true
|
|
}
|
|
}
|
|
var d float32 = 0.0
|
|
if len(defaults) > 0 {
|
|
d = defaults[0]
|
|
}
|
|
return d, false
|
|
}
|
|
|
|
func (r Record) GetDouble(k string, defaults ...float64) (float64, bool) {
|
|
if v, ok := r[k]; ok {
|
|
if vv, ook := v.(float64); ook {
|
|
return vv, true
|
|
}
|
|
}
|
|
var d float64 = 0
|
|
if len(defaults) > 0 {
|
|
d = defaults[0]
|
|
}
|
|
return d, false
|
|
}
|
|
|
|
func CSV2List(in io.Reader) (records []Record, err error) {
|
|
reader := csv.NewReader(in)
|
|
if recs, e := reader.ReadAll(); nil != e {
|
|
return records, e
|
|
} else {
|
|
var keys []*Key
|
|
for i, rec := range recs {
|
|
if i == 0 {
|
|
for _, k := range rec {
|
|
kk := &Key{}
|
|
if ee := kk.Parse(k); nil != ee {
|
|
return records, ee
|
|
} else {
|
|
keys = append(keys, kk)
|
|
}
|
|
}
|
|
continue
|
|
}
|
|
r := make(Record)
|
|
for j, k := range keys {
|
|
switch k.Type {
|
|
case INTEGER:
|
|
if n, e := strconv.ParseInt(rec[j], 10, 32); nil != e {
|
|
return records, e
|
|
} else {
|
|
r[k.Name] = n
|
|
}
|
|
case BOOL:
|
|
switch strings.ToLower(rec[j]) {
|
|
case "t", "y", "true", "yes":
|
|
r[k.Name] = true
|
|
default:
|
|
r[k.Name] = false
|
|
}
|
|
case FLOAT:
|
|
if f, e := strconv.ParseFloat(rec[j], 32); nil != e {
|
|
return records, e
|
|
} else {
|
|
r[k.Name] = float32(f)
|
|
}
|
|
case DOUBLE:
|
|
if f, e := strconv.ParseFloat(rec[j], 64); nil != e {
|
|
return records, e
|
|
} else {
|
|
r[k.Name] = f
|
|
}
|
|
case DATE:
|
|
case TIME:
|
|
case DATETIME:
|
|
default:
|
|
r[k.Name] = rec[j]
|
|
}
|
|
|
|
}
|
|
records = append(records, r)
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func CSV_File2List(filename string) (records []Record, err error) {
|
|
f, e := os.Open(filename)
|
|
if nil != e {
|
|
err = e
|
|
return
|
|
}
|
|
defer f.Close()
|
|
records, err = CSV2List(f)
|
|
return
|
|
}
|