forked from x/icebergs
248 lines
7.3 KiB
Go
248 lines
7.3 KiB
Go
package mdb
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path"
|
|
|
|
ice "shylinux.com/x/icebergs"
|
|
kit "shylinux.com/x/toolkits"
|
|
)
|
|
|
|
func _hash_fields(m *ice.Message) []string {
|
|
return kit.Split(kit.Select("time,hash,type,name,text", m.OptionFields()))
|
|
}
|
|
func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) {
|
|
list := map[string]int{}
|
|
m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
|
|
if val = kit.GetMeta(val); kit.Format(val[COUNT]) != "" {
|
|
list[kit.Format(val[field])] = kit.Int(val[COUNT])
|
|
} else {
|
|
list[kit.Format(val[field])]++
|
|
}
|
|
})
|
|
for k, i := range list {
|
|
m.Push(field, k)
|
|
m.Push(COUNT, i)
|
|
}
|
|
m.SortIntR(COUNT)
|
|
}
|
|
func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) {
|
|
if m.Option(ice.MSG_DOMAIN) != "" {
|
|
m.Conf(prefix, kit.Keys(chain, kit.Keym(SHORT)), m.Conf(prefix, kit.Keym(SHORT)))
|
|
}
|
|
m.Log_INSERT(KEY, path.Join(prefix, chain), arg[0], arg[1])
|
|
if expire := m.Conf(prefix, kit.Keys(chain, kit.Keym(EXPIRE))); expire != "" {
|
|
arg = kit.Simple(TIME, m.Time(expire), arg)
|
|
}
|
|
|
|
m.Echo(m.Rich(prefix, chain, kit.Data(arg)))
|
|
}
|
|
func _hash_delete(m *ice.Message, prefix, chain, field, value string) {
|
|
if field != HASH {
|
|
field, value = HASH, kit.Select(kit.Hashs(value), m.Option(HASH))
|
|
}
|
|
m.Richs(prefix, chain, value, func(key string, val ice.Map) {
|
|
m.Log_DELETE(KEY, path.Join(prefix, chain), field, value, VALUE, kit.Format(val))
|
|
m.Conf(prefix, kit.Keys(chain, HASH, key), "")
|
|
})
|
|
}
|
|
func _hash_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) {
|
|
m.Richs(prefix, chain, value, func(key string, val ice.Map) {
|
|
val = kit.GetMeta(val)
|
|
m.Log_MODIFY(KEY, path.Join(prefix, chain), field, value, arg)
|
|
for i := 0; i < len(arg); i += 2 {
|
|
if arg[i] == field {
|
|
continue
|
|
}
|
|
kit.Value(val, arg[i], kit.Select("", arg, i+1))
|
|
}
|
|
})
|
|
}
|
|
func _hash_select(m *ice.Message, prefix, chain, field, value string) {
|
|
if field == HASH && value == RANDOM {
|
|
value = RANDOMS
|
|
}
|
|
fields := _hash_fields(m)
|
|
m.Richs(prefix, chain, value, func(key string, val ice.Map) {
|
|
switch val = kit.GetMeta(val); cb := m.OptionCB(SELECT).(type) {
|
|
case func(fields []string, value ice.Map):
|
|
cb(fields, val)
|
|
case func(value ice.Map):
|
|
cb(val)
|
|
default:
|
|
if m.OptionFields() == DETAIL {
|
|
m.Push(DETAIL, val)
|
|
} else {
|
|
m.Push(key, val, fields)
|
|
}
|
|
}
|
|
})
|
|
if !m.FieldsIsDetail() {
|
|
m.SortTimeR(TIME)
|
|
}
|
|
}
|
|
func _hash_export(m *ice.Message, prefix, chain, file string) {
|
|
f, p, e := kit.Create(kit.Keys(file, JSON))
|
|
m.Assert(e)
|
|
defer f.Close()
|
|
|
|
en := json.NewEncoder(f)
|
|
en.SetIndent("", " ")
|
|
m.Assert(en.Encode(m.Confv(prefix, kit.Keys(chain, HASH))))
|
|
|
|
m.Log_EXPORT(KEY, path.Join(prefix, chain), FILE, p)
|
|
m.Conf(prefix, kit.Keys(chain, HASH), "")
|
|
m.Echo(p)
|
|
}
|
|
func _hash_import(m *ice.Message, prefix, chain, file string) {
|
|
f, e := os.Open(kit.Keys(file, JSON))
|
|
if m.Warn(e) {
|
|
return
|
|
}
|
|
defer f.Close()
|
|
|
|
list := ice.Map{}
|
|
m.Assert(json.NewDecoder(f).Decode(&list))
|
|
|
|
count := 0
|
|
if m.Conf(prefix, kit.Keys(chain, META, SHORT)) == "" {
|
|
for k, data := range list {
|
|
m.Conf(prefix, kit.Keys(chain, HASH, k), data)
|
|
count++
|
|
}
|
|
} else {
|
|
for _, data := range list {
|
|
m.Rich(prefix, chain, data)
|
|
count++
|
|
}
|
|
}
|
|
|
|
m.Log_IMPORT(KEY, path.Join(prefix, chain), COUNT, count)
|
|
m.Echo("%d", count)
|
|
}
|
|
func _hash_prunes(m *ice.Message, prefix, chain string, arg ...string) {
|
|
fields := _hash_fields(m)
|
|
m.Richs(prefix, chain, FOREACH, func(key string, val ice.Map) {
|
|
switch val = kit.GetMeta(val); cb := m.OptionCB(PRUNES).(type) {
|
|
case func(string, ice.Map) bool:
|
|
if !cb(key, val) {
|
|
return
|
|
}
|
|
default:
|
|
for i := 0; i < len(arg)-1; i += 2 {
|
|
if val[arg[i]] != arg[i+1] && kit.Value(val, arg[i]) != arg[i+1] {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
m.Push(key, val, fields)
|
|
})
|
|
m.Table(func(index int, value map[string]string, head []string) {
|
|
_hash_delete(m, prefix, chain, HASH, value[HASH])
|
|
})
|
|
}
|
|
|
|
const HASH = "hash"
|
|
|
|
func AutoConfig(args ...ice.Any) *ice.Action {
|
|
return &ice.Action{Hand: func(m *ice.Message, arg ...string) {
|
|
if cs := m.Target().Configs; cs[m.CommandKey()] == nil {
|
|
cs[m.CommandKey()] = &ice.Config{Value: kit.Data(args...)}
|
|
m.Load(m.CommandKey())
|
|
}
|
|
if cs := m.Target().Commands; cs[m.CommandKey()].Meta[CREATE] != nil {
|
|
return
|
|
}
|
|
|
|
inputs := []ice.Any{}
|
|
kit.Fetch(kit.Split(m.Config(FIELD)), func(i int, k string) {
|
|
switch k {
|
|
case TIME, HASH:
|
|
return
|
|
}
|
|
inputs = append(inputs, k)
|
|
})
|
|
m.Design(CREATE, "创建", inputs...)
|
|
}}
|
|
}
|
|
func HashAction(args ...ice.Any) map[string]*ice.Action {
|
|
_key := func(m *ice.Message) string {
|
|
if m.Config(HASH) == UNIQ {
|
|
return HASH
|
|
}
|
|
if m.Config(SHORT) == UNIQ {
|
|
return HASH
|
|
}
|
|
return kit.Select(HASH, m.Config(SHORT))
|
|
}
|
|
return ice.SelectAction(map[string]*ice.Action{ice.CTX_INIT: AutoConfig(args...),
|
|
INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) {
|
|
m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, arg)
|
|
}},
|
|
CREATE: {Name: "create", Help: "创建", Hand: func(m *ice.Message, arg ...string) {
|
|
m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg)
|
|
}},
|
|
REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
|
m.OptionFields(m.Config(FIELD))
|
|
m.Cmdy(DELETE, m.PrefixKey(), "", HASH, m.OptionSimple(_key(m)), arg)
|
|
m.Event(kit.Keys(m.CommandKey(), REMOVE), m.CommandKey(), m.Option(m.Config(SHORT)))
|
|
}},
|
|
MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) {
|
|
m.Cmdy(MODIFY, m.PrefixKey(), "", HASH, m.OptionSimple(_key(m)), arg)
|
|
}},
|
|
EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) {
|
|
m.OptionFields(m.Config(FIELD))
|
|
m.Cmdy(EXPORT, m.PrefixKey(), "", HASH, arg)
|
|
}},
|
|
IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) {
|
|
m.Cmdy(IMPORT, m.PrefixKey(), "", HASH, arg)
|
|
}},
|
|
PRUNES: &ice.Action{Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
|
HashPrunes(m, nil)
|
|
}},
|
|
SELECT: &ice.Action{Name: "select hash auto", Help: "列表", Hand: func(m *ice.Message, arg ...string) {
|
|
HashSelect(m, arg...)
|
|
}},
|
|
})
|
|
}
|
|
func HashActionStatus(args ...ice.Any) map[string]*ice.Action {
|
|
list := HashAction(args...)
|
|
list[PRUNES] = &ice.Action{Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
|
m.OptionFields(m.Config(FIELD))
|
|
m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "error")
|
|
m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "close")
|
|
}}
|
|
return list
|
|
}
|
|
func HashCreate(m *ice.Message, arg ...ice.Any) *ice.Message {
|
|
return m.Cmd(INSERT, m.PrefixKey(), "", HASH, kit.Simple(arg...))
|
|
}
|
|
func HashSelect(m *ice.Message, arg ...string) *ice.Message {
|
|
m.Fields(len(arg), m.Config(FIELD))
|
|
m.Cmdy(SELECT, m.PrefixKey(), "", HASH, m.Config(SHORT), arg)
|
|
m.PushAction(m.Config("action"), REMOVE)
|
|
m.StatusTimeCount()
|
|
return m
|
|
}
|
|
func HashPrunes(m *ice.Message, cb func(map[string]string) bool) *ice.Message {
|
|
_key := func(m *ice.Message) string {
|
|
if m.Config(HASH) == UNIQ {
|
|
return HASH
|
|
}
|
|
return kit.Select(HASH, m.Config(SHORT))
|
|
}
|
|
expire := kit.Time(kit.Select(m.Time("-72h"), m.Option(EXPIRE)))
|
|
m.Cmd(m.CommandKey()).Table(func(index int, value map[string]string, head []string) {
|
|
if kit.Time(value[TIME]) > expire {
|
|
return
|
|
}
|
|
if cb != nil && cb(value) {
|
|
return
|
|
}
|
|
m.OptionFields(m.Config(FIELD))
|
|
m.Cmdy(DELETE, m.PrefixKey(), "", HASH, _key(m), value[_key(m)])
|
|
})
|
|
return m
|
|
}
|