diff --git a/base/cli/daemon.go b/base/cli/daemon.go index 33d67560..1b55ccb0 100644 --- a/base/cli/daemon.go +++ b/base/cli/daemon.go @@ -116,7 +116,7 @@ func init() { m.Cmdy("", STOP).Sleep3s().Cmdy("", START) }}, STOP: {Hand: func(m *ice.Message, arg ...string) { - m.OptionFields(m.Config(mdb.FIELD)) + m.OptionFields(mdb.HashField(m)) h, pid := m.Option(mdb.HASH), m.Option(PID) mdb.HashSelect(m, m.Option(mdb.HASH)).Tables(func(value ice.Maps) { if h == "" && value[PID] != pid { diff --git a/base/ctx/config.go b/base/ctx/config.go index 128bf1f4..e83d748f 100644 --- a/base/ctx/config.go +++ b/base/ctx/config.go @@ -26,7 +26,7 @@ func _config_save(m *ice.Message, name string, arg ...string) { } if s, e := json.MarshalIndent(data, "", " "); !m.Warn(e) { if _, e := f.Write(s); !m.Warn(e) { - + } } } diff --git a/base/mdb/demo.go b/base/mdb/demo.go new file mode 100644 index 00000000..e9a28bad --- /dev/null +++ b/base/mdb/demo.go @@ -0,0 +1 @@ +package mdb diff --git a/base/mdb/hash.go b/base/mdb/hash.go index 610991fb..82dde2fc 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -14,44 +14,27 @@ func _hash_fields(m *ice.Message) []string { return kit.Split(kit.Select(HASH_FIELD, m.OptionFields())) } func _hash_inputs(m *ice.Message, prefix, chain string, field, value string) { - switch field { - case EXPIRE: - m.Push(field, "72h") - m.Push(field, "24h") - m.Push(field, "8h") - m.Push(field, "3h") - m.Push(field, "1h") - return - } - defer RLock(m, prefix, chain)() list := map[string]int{} - Richs(m, prefix, chain, FOREACH, func(key string, val Map) { - val = kit.GetMeta(val) - list[kit.Format(val[field])] += kit.Int(kit.Select("1", val[COUNT])) - }) - for k, i := range list { - if k != "" { + defer func() { + delete(list, "") + for k, i := range list { m.Push(field, k).Push(COUNT, i) } - } - m.SortIntR(COUNT) + m.SortIntR(COUNT) + }() + defer RLock(m, prefix, chain)() + Richs(m, prefix, chain, FOREACH, func(key string, value Map) { + value = kit.GetMeta(value) + list[kit.Format(value[field])] += kit.Int(kit.Select("1", value[COUNT])) + }) } func _hash_insert(m *ice.Message, prefix, chain string, arg ...string) string { - m.Logs(INSERT, KEY, path.Join(prefix, chain), arg[0], arg[1]) + m.Logs(INSERT, KEY, path.Join(prefix, chain), arg) defer Lock(m, prefix, chain)() - if value := kit.GetMeta(m.Confm(prefix, kit.Keys(HASH, arg[1]))); value != nil && arg[1] != "" { - kit.Fetch(arg[2:], func(k, v string) { kit.Value(value, k, v)}) - return arg[1] - } if expire := m.Conf(prefix, kit.Keys(chain, kit.Keym(EXPIRE))); expire != "" { arg = kit.Simple(TIME, m.Time(expire), arg) } - if m.Optionv(TARGET) != nil && m.Option(TARGET) != "" { - m.Echo(Rich(m, prefix, chain, kit.Data(arg, TARGET, m.Optionv(TARGET)))) - } else { - m.Echo(Rich(m, prefix, chain, kit.Data(arg))) - } - return m.Result() + return m.Echo(Rich(m, prefix, chain, kit.Data(arg, TARGET, m.Optionv(TARGET)))).Result() } func _hash_delete(m *ice.Message, prefix, chain, field, value string) { defer Lock(m, prefix, chain)() @@ -79,9 +62,9 @@ func _hash_select(m *ice.Message, prefix, chain, field, value string) { } func _hash_select_field(m *ice.Message, prefix, chain string, key string, field string) (value string) { defer RLock(m, prefix, chain)() - Richs(m, prefix, chain, key, func(h string, v Map) { + Richs(m, prefix, chain, key, func(k string, v Map) { if field == HASH { - value = h + value = k } else { value = kit.Format(v[field]) } @@ -110,13 +93,13 @@ func _hash_export(m *ice.Message, prefix, chain, file string) { f, p, e := miss.CreateFile(kit.Keys(file, JSON)) m.Assert(e) defer f.Close() + defer m.Echo(p) m.Logs(EXPORT, KEY, path.Join(prefix, chain), FILE, p) - defer m.Echo(p).StatusTime(LINK, "/share/local/"+p) en := json.NewEncoder(f) - en.SetIndent("", " ") defer Lock(m, prefix, chain)() - m.Warn(en.Encode(m.Confv(prefix, kit.Keys(chain, HASH))), EXPORT, p) - m.Conf(prefix, kit.Keys(chain, HASH), "") + if en.SetIndent("", " "); !m.Warn(en.Encode(m.Confv(prefix, kit.Keys(chain, HASH))), EXPORT, prefix) { + m.Conf(prefix, kit.Keys(chain, HASH), "") + } } func _hash_import(m *ice.Message, prefix, chain, file string) { f, e := miss.OpenFile(kit.Keys(file, JSON)) @@ -126,7 +109,7 @@ func _hash_import(m *ice.Message, prefix, chain, file string) { defer f.Close() list := Map{} m.Assert(json.NewDecoder(f).Decode(&list)) - m.Logs(IMPORT, KEY, path.Join(prefix, chain), COUNT, len(list)) + m.Logs(IMPORT, KEY, path.Join(prefix, chain), FILE, kit.Keys(file, JSON), COUNT, len(list)) defer m.Echo("%d", len(list)) defer Lock(m, prefix, chain)() for k, data := range list { @@ -144,12 +127,12 @@ const ( const HASH = "hash" func HashAction(arg ...Any) ice.Actions { - return ice.Actions{ice.CTX_INIT: AutoConfig(arg...), ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, + return ice.Actions{ice.CTX_INIT: AutoConfig(append(kit.List(FIELD, HASH_FIELD), arg...)...), ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, INPUTS: {Hand: func(m *ice.Message, arg ...string) { HashInputs(m, arg) }}, CREATE: {Hand: func(m *ice.Message, arg ...string) { HashCreate(m, arg) }}, REMOVE: {Hand: func(m *ice.Message, arg ...string) { HashRemove(m, arg) }}, MODIFY: {Hand: func(m *ice.Message, arg ...string) { HashModify(m, arg) }}, - SELECT: {Hand: func(m *ice.Message, arg ...string) { HashSelect(m, arg...) }}, + SELECT: {Name: "select hash auto create", Hand: func(m *ice.Message, arg ...string) { HashSelect(m, arg...) }}, PRUNES: {Name: "prunes before@date", Hand: func(m *ice.Message, arg ...string) { HashPrunes(m, nil) }}, EXPORT: {Hand: func(m *ice.Message, arg ...string) { HashExport(m, arg) }}, IMPORT: {Hand: func(m *ice.Message, arg ...string) { HashImport(m, arg) }}, @@ -158,21 +141,17 @@ func HashAction(arg ...Any) ice.Actions { func HashStatusAction(arg ...Any) ice.Actions { return ice.MergeActions(ice.Actions{ PRUNES: &ice.Action{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") - m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "stop") - m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "end") + m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, STATUS, "error", STATUS, "close", STATUS, "stop", STATUS, "end", ice.OptionFields(HashField(m))) }}, }, HashAction(arg...)) } -func HashCloseAction(args ...Any) ice.Actions { - return ice.MergeActions(HashAction(args...), ice.Actions{ +func HashStatusCloseAction(args ...Any) ice.Actions { + return ice.MergeActions(HashStatusAction(args...), ice.Actions{ ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, }) } -func HashStatusCloseAction(args ...Any) ice.Actions { - return ice.MergeActions(HashStatusAction(args...), ice.Actions{ +func HashCloseAction(args ...Any) ice.Actions { + return ice.MergeActions(HashAction(args...), ice.Actions{ ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) { HashSelectClose(m) }}, }) } @@ -187,35 +166,28 @@ func HashShort(m *ice.Message) string { return kit.Select(HASH, m.Config(SHORT), m.Config(SHORT) != UNIQ) } func HashField(m *ice.Message) string { return kit.Select(HASH_FIELD, m.Config(FIELD)) } -func HashArgs(m *ice.Message, arg ...Any) []string { - return _mdb_args(m, "", arg...) -} func HashInputs(m *ice.Message, arg ...Any) *ice.Message { - return m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, HashArgs(m, arg)) + return m.Cmdy(INPUTS, m.PrefixKey(), "", HASH, arg) } func HashCreate(m *ice.Message, arg ...Any) string { - msg := m.Spawn() - args := HashArgs(msg, arg...) - if len(args) == 0 { - args = m.OptionSimple(m.Config(FIELD)) + if len(arg) == 0 { + arg = append(arg, m.OptionSimple(HashField(m))) } - return m.Echo(msg.Cmdx(INSERT, m.PrefixKey(), "", HASH, args)).Result() + return m.Echo(m.Cmdx(INSERT, m.PrefixKey(), "", HASH, arg)).Result() } func HashRemove(m *ice.Message, arg ...Any) *ice.Message { - args := kit.Simple(arg) - if len(args) == 0 { - args = m.OptionSimple(HashKey(m)) + if args := kit.Simple(arg); len(args) == 0 { + arg = append(arg, m.OptionSimple(HashKey(m))) } else if len(args) == 1 { - args = []string{HashKey(m), args[0]} + arg = kit.List(HashKey(m), args[0]) } - return m.Cmdy(DELETE, m.PrefixKey(), "", HASH, args) + return m.Cmdy(DELETE, m.PrefixKey(), "", HASH, arg) } func HashModify(m *ice.Message, arg ...Any) *ice.Message { - args := HashArgs(m, arg...) - if args[0] != HashShort(m) && args[0] != HASH { - args = append(m.OptionSimple(HashKey(m)), args...) + if args := kit.Simple(arg...); args[0] != HASH && args[0] != HashShort(m) { + arg = append(kit.List(m.OptionSimple(HashKey(m))), arg...) } - return m.Cmd(MODIFY, m.PrefixKey(), "", HASH, args) + return m.Cmd(MODIFY, m.PrefixKey(), "", HASH, arg) } func HashSelect(m *ice.Message, arg ...string) *ice.Message { if len(arg) > 0 && arg[0] == FOREACH { @@ -229,18 +201,18 @@ func HashSelect(m *ice.Message, arg ...string) *ice.Message { } return m.StatusTime() } -func HashPrunes(m *ice.Message, cb func(Maps) bool) *ice.Message { +func HashPrunes(m *ice.Message, cb func(Map) bool) *ice.Message { expire := kit.Select(m.Time("-72h"), m.Option("before")) - m.Cmd("", func(value Maps) { - if value[TIME] > expire { - return + m.OptionCB(PRUNES, func(key string, value Map) bool { + if kit.Format(value[TIME]) > expire { + return false } if cb != nil && !cb(value) { - return + return false } - HashRemove(m, HashShort(m), value[HashShort(m)]) + return true }) - return m.StatusTimeCount() + return m.Cmdy(PRUNES, m.PrefixKey(), "", HASH).StatusTimeCount() } func HashExport(m *ice.Message, arg ...Any) *ice.Message { return m.Cmdy(EXPORT, m.PrefixKey(), "", HASH, arg) @@ -249,6 +221,54 @@ func HashImport(m *ice.Message, arg ...Any) *ice.Message { return m.Cmdy(IMPORT, m.PrefixKey(), "", HASH, arg) } +func HashSelects(m *ice.Message, arg ...string) *ice.Message { + m.OptionFields(HashField(m)) + return HashSelect(m, arg...) +} +func HashSelectValue(m *ice.Message, cb Any) *ice.Message { + defer RLock(m, m.PrefixKey(), "")() + Richs(m, m.PrefixKey(), nil, FOREACH, func(key string, value Map) { + _mdb_select(m, cb, key, value, nil, nil) + }) + return m +} +func HashPrunesValue(m *ice.Message, field, value string) { + m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, field, value, ice.OptionFields(HashField(m))) +} +func HashSelectClose(m *ice.Message) *ice.Message { + HashSelectValue(m, func(value ice.Map) { + if c, ok := value[TARGET].(io.Closer); ok { + c.Close() + } + delete(value, TARGET) + }) + return m +} +func HashSelectUpdate(m *ice.Message, key string, cb Any) *ice.Message { + defer Lock(m, m.PrefixKey(), "")() + Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) { + _mdb_select(m, cb, key, value, nil, nil) + }) + return m +} +func HashSelectDetail(m *ice.Message, key string, cb Any) (has bool) { + defer RLock(m, m.PrefixKey(), "")() + Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) { + _mdb_select(m, cb, key, value, nil, nil) + has = true + }) + return +} +func HashSelectField(m *ice.Message, key string, field string) (value string) { + HashSelectDetail(m, key, func(h string, val ice.Map) { + if field == HASH { + value = h + } else { + value = kit.Format(val[field]) + } + }) + return +} func HashTarget(m *ice.Message, h string, add Any) (p Any) { HashSelectUpdate(m, h, func(value ice.Map) { p = value[TARGET] @@ -270,56 +290,6 @@ func HashTarget(m *ice.Message, h string, add Any) (p Any) { }) return } -func HashPrunesValue(m *ice.Message, field, value string) { - m.OptionFields(m.Config(FIELD)) - m.Cmdy(PRUNES, m.PrefixKey(), "", HASH, field, value) -} -func HashSelectField(m *ice.Message, key string, field string) (value string) { - HashSelectDetail(m, key, func(h string, val ice.Map) { - if field == HASH { - value = h - } else { - value = kit.Format(val[field]) - } - }) - return -} -func HashSelectDetail(m *ice.Message, key string, cb Any) (has bool) { - defer RLock(m, m.PrefixKey(), "")() - Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) { - _mdb_select(m, cb, key, value, nil, nil) - has = true - }) - return -} -func HashSelectUpdate(m *ice.Message, key string, cb Any) *ice.Message { - defer Lock(m, m.PrefixKey(), "")() - Richs(m, m.PrefixKey(), nil, key, func(key string, value Map) { - _mdb_select(m, cb, key, value, nil, nil) - }) - return m -} -func HashSelectValue(m *ice.Message, cb Any) *ice.Message { - defer RLock(m, m.PrefixKey(), "")() - Richs(m, m.PrefixKey(), nil, FOREACH, func(key string, value Map) { - _mdb_select(m, cb, key, value, nil, nil) - }) - return m -} -func HashSelectClose(m *ice.Message) *ice.Message { - HashSelectValue(m, func(value ice.Map) { - target := value[TARGET] - if c, ok := target.(io.Closer); ok { - c.Close() - } - delete(value, TARGET) - }) - return m -} -func HashSelects(m *ice.Message, arg ...string) *ice.Message { - m.OptionFields(m.Config(FIELD)) - return HashSelect(m, arg...) -} func Richs(m *ice.Message, prefix string, chain Any, raw Any, cb Any) (res Map) { cache := m.Confm(prefix, chain) diff --git a/base/mdb/list.go b/base/mdb/list.go index 06efb0bc..84d62d42 100644 --- a/base/mdb/list.go +++ b/base/mdb/list.go @@ -14,23 +14,24 @@ func _list_fields(m *ice.Message) []string { return kit.Split(kit.Select(LIST_FIELD, m.OptionFields())) } func _list_inputs(m *ice.Message, prefix, chain string, field, value string) { - defer RLock(m, prefix, chain)() - list := map[string]int{} - Grows(m, prefix, chain, "", "", func(val ice.Map) { - val = kit.GetMeta(val) - list[kit.Format(val[field])] += kit.Int(kit.Select("1", val[COUNT])) + defer func() { + for k, i := range list { + if k != "" { + m.Push(field, k).Push(COUNT, i) + } + } + m.SortIntR(COUNT) + }() + defer RLock(m, prefix, chain)() + Grows(m, prefix, chain, "", "", func(value ice.Map) { + value = kit.GetMeta(value) + list[kit.Format(value[field])] += kit.Int(kit.Select("1", value[COUNT])) }) - for k, i := range list { - m.Push(field, k) - m.Push(COUNT, i) - } - m.SortIntR(COUNT) } func _list_insert(m *ice.Message, prefix, chain string, arg ...string) { - defer Lock(m, prefix, chain)() - m.Logs(INSERT, KEY, path.Join(prefix, chain), arg[0], arg[1]) + defer Lock(m, prefix, chain)() if m.Optionv(TARGET) != nil && m.Option(TARGET) != "" { m.Echo("%d", Grow(m, prefix, chain, kit.Dict(arg, TARGET, m.Optionv(TARGET)))) } else { @@ -38,74 +39,57 @@ func _list_insert(m *ice.Message, prefix, chain string, arg ...string) { } } func _list_modify(m *ice.Message, prefix, chain string, field, value string, arg ...string) { + m.Logs(MODIFY, KEY, path.Join(prefix, chain), field, value, arg) defer Lock(m, prefix, chain)() - - Grows(m, prefix, chain, field, value, func(index int, val ice.Map) { - m.Logs(MODIFY, KEY, path.Join(prefix, chain), field, value, arg) - _mdb_modify(m, val, field, arg...) - }) + Grows(m, prefix, chain, field, value, func(index int, val ice.Map) { _mdb_modify(m, val, field, arg...) }) } func _list_select(m *ice.Message, prefix, chain, field, value string) { defer RLock(m, prefix, chain)() - fields := _list_fields(m) Grows(m, prefix, chain, kit.Select(m.Option(CACHE_FIELD), field), kit.Select(m.Option(CACHE_VALUE), value), func(value ice.Map) { _mdb_select(m, m.OptionCB(""), "", value, fields, nil) }) } func _list_export(m *ice.Message, prefix, chain, file string) { - defer RLock(m, prefix, chain)() - f, p, e := miss.CreateFile(kit.Keys(file, CSV)) m.Assert(e) defer f.Close() - + defer m.Echo(p) w := csv.NewWriter(f) defer w.Flush() - - count := 0 - head := kit.Split(m.Config(FIELD)) - Grows(m, prefix, chain, "", "", func(index int, val ice.Map) { - if val = kit.GetMeta(val); index == 0 { - if len(head) == 0 || head[0] == ice.FIELDS_DETAIL { // 默认表头 - for k := range val { - head = append(head, k) - } - kit.Sort(head) + defer RLock(m, prefix, chain)() + count, head := 0, kit.Split(ListField(m)) + Grows(m, prefix, chain, "", "", func(index int, value ice.Map) { + if value = kit.GetMeta(value); index == 0 { + if len(head) == 0 || head[0] == ice.FIELDS_DETAIL { + head = kit.SortedKey(value) } - w.Write(head) // 输出表头 + w.Write(head) } - data := []string{} for _, k := range head { - data = append(data, kit.Format(val[k])) + data = append(data, kit.Format(value[k])) } - w.Write(data) // 输出数据 + w.Write(data) count++ }) - m.Logs(EXPORT, KEY, path.Join(prefix, chain), FILE, p, COUNT, count) m.Conf(prefix, kit.Keys(chain, kit.Keym(COUNT)), 0) m.Conf(prefix, kit.Keys(chain, LIST), "") - m.Echo(p) } func _list_import(m *ice.Message, prefix, chain, file string) { - defer RLock(m, prefix, chain)() - f, e := miss.OpenFile(kit.Keys(file, CSV)) m.Assert(e) defer f.Close() - r := csv.NewReader(f) head, _ := r.Read() count := 0 - + defer RLock(m, prefix, chain)() for { line, e := r.Read() if e != nil { break } - data := kit.Dict() for i, k := range head { if k == EXTRA { @@ -114,11 +98,9 @@ func _list_import(m *ice.Message, prefix, chain, file string) { kit.Value(data, k, line[i]) } } - Grow(m, prefix, chain, data) count++ } - m.Logs(IMPORT, KEY, kit.Keys(prefix, chain), COUNT, count) m.Echo("%d", count) } @@ -128,53 +110,28 @@ const ( ) const LIST = "list" -func ListAction(args ...ice.Any) ice.Actions { - return ice.Actions{ice.CTX_INIT: AutoConfig(args...), - INPUTS: {Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(INPUTS, m.PrefixKey(), "", LIST, ListArgs(m, arg)) - }}, - INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(INSERT, m.PrefixKey(), "", LIST, ListArgs(m, arg)) - }}, - DELETE: {Name: "delete", Help: "删除", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(DELETE, m.PrefixKey(), "", LIST, m.OptionSimple(ID), arg) - }}, - MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(MODIFY, m.PrefixKey(), "", LIST, m.OptionSimple(ID), ListArgs(m, arg)) - }}, - SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) { - ListSelect(m, arg...) - }}, - PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(PRUNES, m.PrefixKey(), "", LIST, arg) - }}, - EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(EXPORT, m.PrefixKey(), "", LIST, arg) - }}, - IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { - m.Cmdy(IMPORT, m.PrefixKey(), "", LIST, arg) - }}, - PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) { - PrevPage(m, m.Config(COUNT), kit.Slice(arg, 1)...) - }}, - NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) { - NextPageLimit(m, m.Config(COUNT), kit.Slice(arg, 1)...) - }}, +func ListAction(arg ...ice.Any) ice.Actions { + return ice.Actions{ice.CTX_INIT: AutoConfig(append(kit.List(FIELD, LIST_FIELD), arg...)...), + INPUTS: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INPUTS, m.PrefixKey(), "", LIST, arg) }}, + INSERT: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(INSERT, m.PrefixKey(), "", LIST, arg) }}, + DELETE: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(DELETE, m.PrefixKey(), "", LIST, m.OptionSimple(ID), arg) }}, + MODIFY: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(MODIFY, m.PrefixKey(), "", LIST, m.OptionSimple(ID), arg) }}, + SELECT: {Name: "select id auto insert", Hand: func(m *ice.Message, arg ...string) { ListSelect(m, arg...) }}, + PREV: {Hand: func(m *ice.Message, arg ...string) { PrevPage(m, m.Config(COUNT), kit.Slice(arg, 1)...) }}, + NEXT: {Hand: func(m *ice.Message, arg ...string) { NextPageLimit(m, m.Config(COUNT), kit.Slice(arg, 1)...) }}, + PRUNES: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(PRUNES, m.PrefixKey(), "", LIST, arg) }}, + EXPORT: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(EXPORT, m.PrefixKey(), "", LIST, arg) }}, + IMPORT: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy(IMPORT, m.PrefixKey(), "", LIST, arg) }}, } } func ListField(m *ice.Message) string { return kit.Select(LIST_FIELD, m.Config(FIELD)) } -func ListArgs(m *ice.Message, arg ...ice.Any) []string { - return _mdb_args(m, ListField(m), arg...) -} func ListSelect(m *ice.Message, arg ...string) *ice.Message { OptionPage(m, kit.Slice(arg, 1)...) m.Fields(len(kit.Slice(arg, 0, 1)), ListField(m)) if m.Cmdy(SELECT, m.PrefixKey(), "", LIST, ID, arg); !m.FieldsIsDetail() { - m.StatusTimeCountTotal(m.Config(COUNT)) - } else { - m.StatusTime() + return m.StatusTimeCountTotal(m.Config(COUNT)) } - return m + return m.StatusTime() } func PrevPageLimit(m *ice.Message, total string, arg ...string) { if kit.Int(kit.Select("0", arg, 1)) > 0 { @@ -185,17 +142,13 @@ func PrevPageLimit(m *ice.Message, total string, arg ...string) { } func PrevPage(m *ice.Message, total string, arg ...string) { limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1) - offends := kit.Int(offend) - kit.Int(limit) - if total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) { + if offends := kit.Int(offend) - kit.Int(limit); total != "0" && (offends <= -kit.Int(total) || offends >= kit.Int(total)) { m.ProcessHold("已经是最前一页啦!") - return - } - if offends == 0 { + } else if offends == 0 { m.ProcessRewrite("offend", "") } else { m.ProcessRewrite("offend", offends) } - } func NextPage(m *ice.Message, total string, arg ...string) { limit, offend := kit.Select("10", arg, 0), kit.Select("0", arg, 1) @@ -233,7 +186,7 @@ func OptionPage(m *ice.Message, arg ...string) int { return page } -const ( // CACHE +const ( CACHE_LIMIT = "cache.limit" CACHE_BEGIN = "cache.begin" CACHE_COUNT = "cache.count" @@ -256,7 +209,6 @@ func Grows(m *ice.Message, prefix string, chain Any, match string, value string, if cache == nil { return nil } - limit := kit.Int(m.Option(CACHE_LIMIT)) if begin := kit.Int(m.Option(CACHE_BEGIN)); begin != 0 && limit > 0 { count := kit.Int(m.Option(CACHE_COUNT, kit.Int(kit.Value(cache, kit.Keym("count"))))) diff --git a/base/mdb/mdb.go b/base/mdb/mdb.go index cb8649f0..9cae704e 100644 --- a/base/mdb/mdb.go +++ b/base/mdb/mdb.go @@ -19,37 +19,13 @@ func _file_name(m *ice.Message, arg ...string) string { } return path.Join(ice.USR_LOCAL_EXPORT, path.Join(arg[:2]...), arg[2]) } -func _mdb_args(m *ice.Message, field string, arg ...Any) []string { - res := []Any{} - for _, v := range arg { - switch v := v.(type) { - case Map: - for k, v := range v { - m.Option(k, v) - } - default: - res = append(res, v) +func _mdb_modify(m *ice.Message, value ice.Map, field string, arg ...string) { + value = kit.GetMeta(value) + kit.Fetch(arg, func(k, v string) { + if k != field { + kit.Value(value, k, v) } - } - args := kit.Simple(res...) - if field == "" { - return args - } - for i := 0; i < len(args); i += 2 { - if !strings.Contains(field, args[i]) && !strings.HasPrefix(args[i], EXTRA) { - // args[i] = kit.Keys(EXTRA, args[i]) - } - } - return args -} -func _mdb_modify(m *ice.Message, val ice.Map, field string, arg ...string) { - val = kit.GetMeta(val) - for i := 0; i < len(arg); i += 2 { - if arg[i] == field { - continue - } - kit.Value(val, arg[i], kit.Select("", arg, i+1)) - } + }) } func _mdb_select(m *ice.Message, cb Any, key string, value Map, fields []string, val Map) { switch value, val = kit.GetMeta(value), kit.GetMeta(val); cb := cb.(type) { @@ -91,23 +67,28 @@ const ( RANDOMS = kit.MDB_RANDOMS ) const ( - // 数据 ID = kit.MDB_ID KEY = kit.MDB_KEY TIME = kit.MDB_TIME TYPE = kit.MDB_TYPE NAME = kit.MDB_NAME TEXT = kit.MDB_TEXT + DATA = kit.MDB_DATA - // 文件 LINK = kit.MDB_LINK + FILE = kit.MDB_FILE SCAN = kit.MDB_SCAN SHOW = kit.MDB_SHOW HELP = kit.MDB_HELP - DATA = kit.MDB_DATA - FILE = kit.MDB_FILE - // 存储 + INDEX = kit.MDB_INDEX + VALUE = kit.MDB_VALUE + EXTRA = kit.MDB_EXTRA + ALIAS = kit.MDB_ALIAS + EXPIRE = kit.MDB_EXPIRE + STATUS = kit.MDB_STATUS + STREAM = kit.MDB_STREAM + SHORT = kit.MDB_SHORT FIELD = kit.MDB_FIELD TOTAL = kit.MDB_TOTAL @@ -116,15 +97,12 @@ const ( LEAST = kit.MDB_LEAST STORE = kit.MDB_STORE FSIZE = kit.MDB_FSIZE + TOOLS = "tools" - // 索引 - INDEX = kit.MDB_INDEX - VALUE = kit.MDB_VALUE - EXTRA = kit.MDB_EXTRA - ALIAS = kit.MDB_ALIAS - EXPIRE = kit.MDB_EXPIRE - STATUS = kit.MDB_STATUS - STREAM = kit.MDB_STREAM + SOURCE = "_source" + TARGET = "_target" + + CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit" ) const ( DETAIL = "detail" @@ -151,37 +129,35 @@ const ( PAGE = "page" OFFEND = "offend" - TOOLS = "tools" - JSON = "json" CSV = "csv" ) -const ( - CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit" - - SOURCE = "_source" - TARGET = "_target" -) +const () const MDB = "mdb" var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands{ ice.CTX_INIT: {Hand: func(m *ice.Message, arg ...string) {}}, ice.CTX_EXIT: {Hand: func(m *ice.Message, arg ...string) {}}, - INPUTS: {Name: "inputs key sub type field value", Help: "补全", Hand: func(m *ice.Message, arg ...string) { - switch arg[3] = strings.TrimPrefix(arg[3], "extra."); arg[3] { + INPUTS: {Name: "inputs key sub type field value", Hand: func(m *ice.Message, arg ...string) { + const ( + SPACE = "space" + CONTEXT = "context" + COMMAND = "command" + INDEX = "index" + ) + switch arg[3] = strings.TrimPrefix(arg[3], EXTRA+ice.PT); arg[3] { case ice.POD: - m.Cmdy("route") + m.Cmdy(SPACE) case ice.CTX: - m.Cmdy("context") + m.Cmdy(CONTEXT) case ice.CMD: - m.Cmdy("context", kit.Select(m.Option(ice.CTX), m.Option(kit.Keys(EXTRA, ice.CTX))), "command") - case "index": - m.OptionFields(arg[3]) - m.Cmdy("command", SEARCH, "command", kit.Select("", arg, 1)) + m.Cmdy(CONTEXT, kit.Select(m.Option(ice.CTX), m.Option(kit.Keys(EXTRA, ice.CTX))), COMMAND) + case INDEX: + m.Cmdy(COMMAND, SEARCH, COMMAND, kit.Select("", arg, 1), ice.OptionFields(arg[3])) default: switch arg[2] { - case ZONE: // inputs key sub type zone field value + case ZONE: _zone_inputs(m, arg[0], arg[1], arg[3], kit.Select(NAME, arg, 4), kit.Select("", arg, 5)) case HASH: _hash_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4)) @@ -190,10 +166,10 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands } } }}, - INSERT: {Name: "insert key sub type arg...", Help: "添加", Hand: func(m *ice.Message, arg ...string) { + INSERT: {Name: "insert key sub type arg...", Hand: func(m *ice.Message, arg ...string) { defer m.ProcessRefresh() switch arg[2] { - case ZONE: // insert key sub type zone arg... + case ZONE: _zone_insert(m, arg[0], arg[1], arg[3], arg[4:]...) case HASH: _hash_insert(m, arg[0], arg[1], arg[3:]...) @@ -201,10 +177,10 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands _list_insert(m, arg[0], arg[1], arg[3:]...) } }}, - DELETE: {Name: "delete key sub type field value", Help: "删除", Hand: func(m *ice.Message, arg ...string) { + DELETE: {Name: "delete key sub type field value", Hand: func(m *ice.Message, arg ...string) { defer m.ProcessRefresh() switch arg[2] { - case ZONE: // delete key sub type zone field value + case ZONE: // _list_delete(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4], arg[5]) case HASH: _hash_delete(m, arg[0], arg[1], arg[3], arg[4]) @@ -212,9 +188,9 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands // _list_delete(m, arg[0], arg[1], arg[3], arg[4]) } }}, - MODIFY: {Name: "modify key sub type field value arg...", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { + MODIFY: {Name: "modify key sub type field value arg...", Hand: func(m *ice.Message, arg ...string) { switch arg[2] { - case ZONE: // modify key sub type zone id field value + case ZONE: _zone_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) case HASH: _hash_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) @@ -222,7 +198,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands _list_modify(m, arg[0], arg[1], arg[3], arg[4], arg[5:]...) } }}, - SELECT: {Name: "select key sub type field value", Help: "查询", Hand: func(m *ice.Message, arg ...string) { + SELECT: {Name: "select key sub type field value", Hand: func(m *ice.Message, arg ...string) { switch arg[2] { case ZONE: _zone_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) @@ -232,9 +208,9 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands _list_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4)) } }}, - PRUNES: {Name: "prunes key sub type [field value]...", Help: "清理", Hand: func(m *ice.Message, arg ...string) { + PRUNES: {Name: "prunes key sub type [field value]...", Hand: func(m *ice.Message, arg ...string) { switch arg[2] { - case ZONE: // prunes key sub type zone field value + case ZONE: // _list_prunes(m, arg[0], _domain_chain(m, kit.Keys(arg[1], kit.KeyHash(arg[3]))), arg[4:]...) case HASH: _hash_prunes(m, arg[0], arg[1], arg[3:]...) @@ -243,10 +219,8 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands // _list_prunes(m, arg[0], arg[1], arg[3:]...) } }}, - EXPORT: {Name: "export key sub type file", Help: "导出", Hand: func(m *ice.Message, arg ...string) { - if m.Option(CACHE_LIMIT) == "" { - m.Option(CACHE_LIMIT, "-1") - } + EXPORT: {Name: "export key sub type file", Hand: func(m *ice.Message, arg ...string) { + m.OptionDefault(CACHE_LIMIT, "-1") switch file := _file_name(m, arg...); arg[2] { case ZONE: _zone_export(m, arg[0], arg[1], file) @@ -255,8 +229,9 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands case LIST: _list_export(m, arg[0], arg[1], file) } + m.StatusTime(LINK, "/share/local/"+m.Result()).Process("_clear") }}, - IMPORT: {Name: "import key sub type file", Help: "导入", Hand: func(m *ice.Message, arg ...string) { + IMPORT: {Name: "import key sub type file", Hand: func(m *ice.Message, arg ...string) { switch file := _file_name(m, arg...); arg[2] { case ZONE: _zone_import(m, arg[0], arg[1], file) @@ -269,11 +244,7 @@ var Index = &ice.Context{Name: MDB, Help: "数据模块", Commands: ice.Commands }} func init() { - ice.Index.Register(Index, nil, - INSERT, DELETE, MODIFY, SELECT, - INPUTS, PRUNES, EXPORT, IMPORT, - SEARCH, ENGINE, PLUGIN, RENDER, - ) + ice.Index.Register(Index, nil, INSERT, DELETE, MODIFY, SELECT, INPUTS, PRUNES, EXPORT, IMPORT, PLUGIN, ENGINE, RENDER, SEARCH) } func AutoConfig(args ...ice.Any) *ice.Action { return &ice.Action{Hand: func(m *ice.Message, arg ...string) { @@ -281,29 +252,15 @@ func AutoConfig(args ...ice.Any) *ice.Action { cs[m.CommandKey()] = &ice.Config{Value: kit.Data(args...)} ice.Info.Load(m, m.CommandKey()) } - - inputs := []ice.Any{} - kit.Fetch(kit.Split(m.Config(FIELD)), func(i int, k string) { - switch k { - case TIME, HASH, ID: - return - } - inputs = append(inputs, k) - }) - if len(inputs) == 0 { + if cs := m.Target().Commands; cs[m.CommandKey()] == nil { return - } - - cs := m.Target().Commands - if cs[m.CommandKey()] == nil { - return - } - - if cs[m.CommandKey()].Actions[INSERT] != nil { + } else if inputs := []ice.Any{}; cs[m.CommandKey()].Actions[INSERT] != nil { + kit.Fetch(kit.Filters(kit.Split(ListField(m)), TIME, ID), func(k string) { inputs = append(inputs, k) }) if cs[m.CommandKey()].Meta[INSERT] == nil { - m.Design(INSERT, "添加", append([]ice.Any{kit.Select(ZONE, m.Config(SHORT))}, inputs...)...) + m.Design(INSERT, "添加", append(kit.List(kit.Select(ZONE, m.Config(SHORT))), inputs...)...) } } else if cs[m.CommandKey()].Actions[CREATE] != nil { + kit.Fetch(kit.Filters(kit.Split(HashField(m)), TIME, HASH), func(k string) { inputs = append(inputs, k) }) if cs[m.CommandKey()].Meta[CREATE] == nil { m.Design(CREATE, "创建", inputs...) } @@ -311,14 +268,13 @@ func AutoConfig(args ...ice.Any) *ice.Action { }} } -var _locks = map[string]*task.Lock{} var _lock = task.Lock{} +var _locks = map[string]*task.Lock{} func getLock(m *ice.Message, key string) *task.Lock { if key == "" { key = m.PrefixKey() } - defer _lock.Lock()() l, ok := _locks[key] if !ok { @@ -327,9 +283,5 @@ func getLock(m *ice.Message, key string) *task.Lock { } return l } -func RLock(m *ice.Message, arg ...ice.Any) func() { - return getLock(m, kit.Keys(arg...)).RLock() -} -func Lock(m *ice.Message, arg ...ice.Any) func() { - return getLock(m, kit.Keys(arg...)).Lock() -} +func Lock(m *ice.Message, arg ...ice.Any) func() { return getLock(m, kit.Keys(arg...)).Lock() } +func RLock(m *ice.Message, arg ...ice.Any) func() { return getLock(m, kit.Keys(arg...)).RLock() } diff --git a/base/mdb/search.go b/base/mdb/search.go index a0d68bf7..e401c098 100644 --- a/base/mdb/search.go +++ b/base/mdb/search.go @@ -17,14 +17,18 @@ func init() { return nil, nil }) } -func SearchAction() ice.Actions { return ice.Actions{SEARCH: {Hand: func(m *ice.Message, arg ...string) { HashSelectSearch(m, arg) }}} } -func HashSearchAction(arg ...Any) ice.Actions { return ice.MergeActions(HashAction(arg...), SearchAction()) } +func SearchAction() ice.Actions { + return ice.Actions{SEARCH: {Hand: func(m *ice.Message, arg ...string) { HashSelectSearch(m, arg) }}} +} +func HashSearchAction(arg ...Any) ice.Actions { + return ice.MergeActions(HashAction(arg...), SearchAction()) +} func HashSelectSearch(m *ice.Message, args []string, keys ...string) *ice.Message { if args[0] != m.CommandKey() { return m } if len(keys) == 0 { - keys = kit.Filters(kit.Split(m.Config(FIELD)), TIME, HASH) + keys = kit.Filters(kit.Split(HashField(m)), TIME, HASH) } HashSelectValue(m, func(value ice.Map) { if args[1] == "" || args[1] == value[keys[1]] { diff --git a/base/mdb/zone.go b/base/mdb/zone.go index 35c07300..42f2b266 100644 --- a/base/mdb/zone.go +++ b/base/mdb/zone.go @@ -45,7 +45,6 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { if zone == RANDOM { zone = RANDOMS } - fields := _zone_fields(m) defer RLock(m, prefix, chain)() Richs(m, prefix, chain, kit.Select(FOREACH, zone), func(key string, val Map) { @@ -60,7 +59,6 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { f, p, e := miss.CreateFile(kit.Keys(file, CSV)) m.Assert(e) defer f.Close() - w := csv.NewWriter(f) defer w.Flush() fields := _zone_fields(m) @@ -68,22 +66,21 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { fields = append(fields, EXTRA) } w.Write(fields) - keys := []string{} - Richs(m, prefix, chain, FOREACH, func(key string, val ice.Map) { keys = append(keys, key) }) + func() { + defer RLock(m, prefix, chain)() + Richs(m, prefix, chain, FOREACH, func(key string, val ice.Map) { keys = append(keys, key) }) + }() kit.Sort(keys) - count := 0 defer Lock(m, prefix, chain)() for _, key := range keys { Richs(m, prefix, chain, key, func(key string, val ice.Map) { val = kit.GetMeta(val) - chain := kit.Keys(chain, HASH, key) defer RLock(m, prefix, chain)() Grows(m, prefix, chain, "", "", func(value ice.Map) { value = kit.GetMeta(value) - list := []string{} for _, k := range fields { list = append(list, kit.Select(kit.Format(kit.Value(val, k)), kit.Format(kit.Value(value, k)))) @@ -93,7 +90,6 @@ func _zone_export(m *ice.Message, prefix, chain, file string) { }) }) } - m.Logs(EXPORT, KEY, path.Join(prefix, chain), FILE, p, COUNT, count) m.Conf(prefix, kit.Keys(chain, HASH), "") m.Echo(p).StatusTime(LINK, "/share/local/"+p) @@ -102,21 +98,17 @@ func _zone_import(m *ice.Message, prefix, chain, file string) { f, e := miss.OpenFile(kit.Keys(file, CSV)) m.Assert(e) defer f.Close() - r := csv.NewReader(f) head, _ := r.Read() count := 0 - list := ice.Maps{} zkey := kit.Select(head[0], m.OptionFields()) - defer Lock(m, prefix, chain)() for { line, e := r.Read() if e != nil { break } - zone := "" data := kit.Dict() for i, k := range head { @@ -134,7 +126,6 @@ func _zone_import(m *ice.Message, prefix, chain, file string) { if list[zone] == "" { list[zone] = Rich(m, prefix, chain, kit.Data(zkey, zone)) } - func() { chain := kit.Keys(chain, HASH, list[zone]) defer Lock(m, prefix, chain)() @@ -142,7 +133,6 @@ func _zone_import(m *ice.Message, prefix, chain, file string) { }() count++ } - m.Logs(IMPORT, KEY, path.Join(prefix, chain), COUNT, count) m.Echo("%d", count) } @@ -154,66 +144,45 @@ const ZONE = "zone" func ZoneAction(args ...ice.Any) ice.Actions { return ice.Actions{ice.CTX_INIT: AutoConfig(append([]ice.Any{SHORT, ZONE}, args)...), - INPUTS: {Name: "inputs", Help: "补全", Hand: func(m *ice.Message, arg ...string) { ZoneInputs(m, arg) }}, - CREATE: {Name: "create zone", Help: "创建", Hand: func(m *ice.Message, arg ...string) { ZoneCreate(m, arg) }}, - REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) { ZoneRemove(m, arg) }}, - INSERT: {Name: "insert", Help: "添加", Hand: func(m *ice.Message, arg ...string) { ZoneInsert(m, arg) }}, - MODIFY: {Name: "modify", Help: "编辑", Hand: func(m *ice.Message, arg ...string) { ZoneModify(m, arg) }}, - SELECT: {Name: "select", Help: "列表", Hand: func(m *ice.Message, arg ...string) { ZoneSelect(m, arg...) }}, - EXPORT: {Name: "export", Help: "导出", Hand: func(m *ice.Message, arg ...string) { ZoneExport(m, arg) }}, - IMPORT: {Name: "import", Help: "导入", Hand: func(m *ice.Message, arg ...string) { ZoneImport(m, arg) }}, - PREV: {Name: "prev", Help: "上一页", Hand: func(m *ice.Message, arg ...string) { PrevPage(m, arg[0], arg[1:]...) }}, - NEXT: {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) { NextPageLimit(m, arg[0], arg[1:]...) }}, + INPUTS: {Hand: func(m *ice.Message, arg ...string) { ZoneInputs(m, arg) }}, + CREATE: {Name: "create zone", Hand: func(m *ice.Message, arg ...string) { ZoneCreate(m, arg) }}, + REMOVE: {Hand: func(m *ice.Message, arg ...string) { ZoneRemove(m, arg) }}, + INSERT: {Hand: func(m *ice.Message, arg ...string) { ZoneInsert(m, arg) }}, + MODIFY: {Hand: func(m *ice.Message, arg ...string) { ZoneModify(m, arg) }}, + SELECT: {Name: "select zone id auto insert", Hand: func(m *ice.Message, arg ...string) { ZoneSelect(m, arg...) }}, + EXPORT: {Hand: func(m *ice.Message, arg ...string) { ZoneExport(m, arg) }}, + IMPORT: {Hand: func(m *ice.Message, arg ...string) { ZoneImport(m, arg) }}, + PREV: {Hand: func(m *ice.Message, arg ...string) { PrevPage(m, arg[0], arg[1:]...) }}, + NEXT: {Hand: func(m *ice.Message, arg ...string) { NextPageLimit(m, arg[0], arg[1:]...) }}, } } func ZoneShort(m *ice.Message) string { return kit.Select(ZONE, m.Config(SHORT), m.Config(SHORT) != UNIQ) } -func ZoneField(m *ice.Message) string { - return kit.Select(ZONE_FIELD, m.Config(FIELD)) -} -func ZoneArgs(m *ice.Message, arg ...Any) []string { - return _mdb_args(m, ZoneField(m), arg...) -} - +func ZoneField(m *ice.Message) string { return kit.Select(ZONE_FIELD, m.Config(FIELD)) } func ZoneInputs(m *ice.Message, arg ...Any) { - m.Cmdy(INPUTS, m.PrefixKey(), "", ZONE, m.Option(ZoneShort(m)), ZoneArgs(m, arg...)) + m.Cmdy(INPUTS, m.PrefixKey(), "", ZONE, m.Option(ZoneShort(m)), arg) } func ZoneCreate(m *ice.Message, arg ...Any) { m.Cmdy(INSERT, m.PrefixKey(), "", HASH, arg) } func ZoneRemove(m *ice.Message, arg ...Any) { - args := kit.Simple(arg...) - if len(args) == 0 { - args = m.OptionSimple(ZoneShort(m), HASH) + if args := kit.Simple(arg...); len(args) == 0 { + arg = append(arg, m.OptionSimple(ZoneShort(m), HASH)) } else if len(args) == 1 { - args = []string{ZoneShort(m), args[0]} + arg = kit.List(ZoneShort(m), args[0]) } - m.Cmdy(DELETE, m.PrefixKey(), "", HASH, args) + m.Cmdy(DELETE, m.PrefixKey(), "", HASH, arg) } func ZoneInsert(m *ice.Message, arg ...Any) { - args := kit.Simple(arg...) - if len(args) == 0 { - args = m.OptionSimple(ZoneShort(m), m.Config(FIELD)) - } - if len(args)%2 == 1 { - args = args[:len(args)-1] - } - for i := len(args) - 2; i >= 0; i -= 2 { - if args[i+1] == "" { - args = args[:i] - } else { - break - } - } - m.Cmdy(INSERT, m.PrefixKey(), "", ZONE, args[1], ZoneArgs(m, args[2:])) + m.Cmdy(INSERT, m.PrefixKey(), "", ZONE, arg) } func ZoneModify(m *ice.Message, arg ...Any) { - m.Cmdy(MODIFY, m.PrefixKey(), "", ZONE, m.Option(ZoneShort(m)), m.Option(ID), ZoneArgs(m, arg...)) + m.Cmdy(MODIFY, m.PrefixKey(), "", ZONE, m.Option(ZoneShort(m)), m.Option(ID), arg) } func ZoneSelect(m *ice.Message, arg ...string) *ice.Message { arg = kit.Slice(arg, 0, 2) - m.Fields(len(arg), kit.Fields(TIME, m.Config(SHORT), COUNT), m.Config(FIELD)) + m.Fields(len(arg), kit.Fields(TIME, m.Config(SHORT), COUNT), ZoneField(m)) if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg, logs.FileLineMeta(logs.FileLine(-1))); len(arg) == 0 { if m.Config(SHORT) != "" { m.Sort(m.Config(SHORT)) @@ -227,7 +196,7 @@ func ZoneSelect(m *ice.Message, arg ...string) *ice.Message { } func ZoneExport(m *ice.Message, arg ...Any) { if m.OptionFields() == "" { - m.OptionFields(m.Config(SHORT), m.Config(FIELD)) + m.OptionFields(m.Config(SHORT), ZoneField(m)) } m.Cmdy(EXPORT, m.PrefixKey(), "", ZONE, arg) } @@ -239,7 +208,7 @@ func ZoneSelectPage(m *ice.Message, arg ...string) *ice.Message { return ZoneSelect(m, arg...) } func ZoneSelects(m *ice.Message, arg ...string) *ice.Message { - m.OptionFields(m.Config(FIELD)) + m.OptionFields(ZoneField(m)) return ZoneSelect(m, arg...) } func ZoneSelectAll(m *ice.Message, arg ...string) *ice.Message { diff --git a/base/nfs/tail.go b/base/nfs/tail.go index 2938c507..05f6d877 100644 --- a/base/nfs/tail.go +++ b/base/nfs/tail.go @@ -59,7 +59,7 @@ func init() { _tail_create(m, arg...) }}, }, mdb.ZoneAction(mdb.SHORT, mdb.NAME, mdb.FIELD, "time,id,file,text")), Hand: func(m *ice.Message, arg ...string) { - m.Fields(len(kit.Slice(arg, 0, 2)), "time,name,count,file", m.Config(mdb.FIELD)) + m.Fields(len(kit.Slice(arg, 0, 2)), "time,name,count,file", mdb.ZoneField(m)) mdb.OptionPage(m, kit.Slice(arg, 2)...) mdb.ZoneSelect(m.Spawn(), arg...).Table(func(index int, value ice.Maps, head []string) { diff --git a/base/nfs/trash.go b/base/nfs/trash.go index 91984bc3..828227e2 100644 --- a/base/nfs/trash.go +++ b/base/nfs/trash.go @@ -54,9 +54,10 @@ func init() { mdb.HashRemove(m, m.OptionSimple(mdb.HASH)) }}, mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - mdb.HashPrunes(m, func(value ice.Maps) bool { - Remove(m, value[FILE]) + mdb.HashPrunes(m, func(value ice.Map) bool { return true + }).Tables(func(value ice.Maps) { + Remove(m, value[FILE]) }) }}, }, mdb.HashAction(mdb.SHORT, FROM, mdb.FIELD, "time,hash,file,from")), Hand: func(m *ice.Message, arg ...string) { diff --git a/core/chat/demo.go b/core/chat/demo.go new file mode 100644 index 00000000..1374a353 --- /dev/null +++ b/core/chat/demo.go @@ -0,0 +1,15 @@ +package chat + +import ( + ice "shylinux.com/x/icebergs" + "shylinux.com/x/icebergs/base/ctx" + "shylinux.com/x/icebergs/base/mdb" +) + +func init() { + Index.MergeCommands(ice.Commands{ + "demo-hash": {Actions: ice.MergeActions(mdb.HashAction(), ctx.CmdAction())}, + "demo-list": {Actions: ice.MergeActions(mdb.ListAction(), ctx.CmdAction())}, + "demo-zone": {Actions: ice.MergeActions(mdb.ZoneAction(), ctx.CmdAction())}, + }) +} diff --git a/core/chat/favor.go b/core/chat/favor.go index 442f811f..cf625082 100644 --- a/core/chat/favor.go +++ b/core/chat/favor.go @@ -80,7 +80,7 @@ func init() { m.Option(mdb.TYPE, m.Cmd("", m.Option(mdb.HASH)).Append(mdb.TYPE)) ctx.Run(m, arg...) }}, - }, mdb.HashAction(mdb.FIELD, "time,hash,type,name,text"), ctx.CmdAction(), KeyboardAction()), Hand: func(m *ice.Message, arg ...string) { + }, mdb.HashAction(), ctx.CmdAction(), KeyboardAction()), Hand: func(m *ice.Message, arg ...string) { if len(arg) > 0 && arg[0] == ctx.ACTION { m.Option(mdb.TYPE, m.Cmd("", m.Option(mdb.HASH)).Append(mdb.TYPE)) gdb.Event(m, FAVOR_ACTION, arg) diff --git a/core/code/pprof.go b/core/code/pprof.go index ea1cca05..f6bcf9d0 100644 --- a/core/code/pprof.go +++ b/core/code/pprof.go @@ -62,7 +62,7 @@ func init() { m.Echo("http://%s/ui/top", p).ProcessInner() }}, }, mdb.ZoneAction(mdb.SHORT, mdb.ZONE, mdb.FIELD, "time,id,text,file", PPROF, kit.List(GO, "tool", PPROF))), Hand: func(m *ice.Message, arg ...string) { - m.Fields(len(arg), "time,zone,count,binnary,service,seconds", m.Config(mdb.FIELD)) + m.Fields(len(arg), "time,zone,count,binnary,service,seconds", mdb.ZoneField(m)) if mdb.ZoneSelect(m, arg...); len(arg) == 0 { m.EchoAnchor(web.MergeLink(m, "/code/pprof/")) m.PushAction(ice.RUN, mdb.REMOVE) diff --git a/core/mall/asset.go b/core/mall/asset.go index 5973a3c7..dd54f102 100644 --- a/core/mall/asset.go +++ b/core/mall/asset.go @@ -31,7 +31,7 @@ func _asset_check(m *ice.Message, account string) { m.OptionCB(mdb.SELECT, func(key string, value ice.Map) { amount += kit.Int(kit.Value(value, AMOUNT)) }) - m.Cmd(mdb.SELECT, m.PrefixKey(), "", mdb.ZONE, account, ice.OptionFields(m.Config(mdb.FIELD))) + m.Cmd(mdb.SELECT, m.PrefixKey(), "", mdb.ZONE, account, ice.OptionFields(mdb.ZoneField(m))) m.Cmdy(mdb.MODIFY, m.PrefixKey(), "", mdb.HASH, ACCOUNT, account, AMOUNT, amount) } @@ -93,7 +93,7 @@ func init() { web.Toast(m, "核算成功") }}, }, mdb.ZoneAction(), ctx.CmdAction()), Hand: func(m *ice.Message, arg ...string) { - m.Fields(len(arg), "time,account,amount,count", m.Config(mdb.FIELD)) + m.Fields(len(arg), "time,account,amount,count", mdb.ZoneField(m)) amount, count := 0, 0 if mdb.ZoneSelect(m, arg...); len(arg) == 0 { m.PushAction(CHECK) diff --git a/meta.go b/meta.go index 86c64b0e..a5c8b45e 100644 --- a/meta.go +++ b/meta.go @@ -187,6 +187,9 @@ func (m *Message) Copy(msg *Message, arg ...string) *Message { case MSG_CMDS, MSG_FIELDS, MSG_SESSID: continue } + if kit.IndexOf(m.meta[MSG_APPEND], k) > -1 { + continue + } if v, ok := msg.data[k]; ok { m.data[k] = v } else { @@ -396,7 +399,7 @@ func (m *Message) Options(arg ...Any) Any { for i := 0; i < len(arg); i += 2 { switch val := arg[i].(type) { case []string: - for i := 0; i < len(val) - 1; i += 2 { + for i := 0; i < len(val)-1; i += 2 { m.Optionv(val[i], val[i+1]) } i-- diff --git a/misc/bash/trash.go b/misc/bash/trash.go index 4c832d1a..c97ef3c9 100644 --- a/misc/bash/trash.go +++ b/misc/bash/trash.go @@ -35,9 +35,10 @@ func init() { } }}, mdb.PRUNES: {Name: "prunes before@date", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - mdb.HashPrunes(m, func(value ice.Maps) bool { - nfs.RemoveAll(m, value[TO]) + mdb.HashPrunes(m, func(value ice.Map) bool { return true + }).Tables(func(value ice.Maps) { + nfs.RemoveAll(m, value[TO]) }) }}, nfs.CAT: {Name: "cat", Help: "查看", Hand: func(m *ice.Message, arg ...string) { diff --git a/misc/vim/sess.go b/misc/vim/sess.go index 55f7a9c5..17afdfce 100644 --- a/misc/vim/sess.go +++ b/misc/vim/sess.go @@ -62,7 +62,7 @@ func init() { }}, SESS: {Name: "sess hash auto prunes", Help: "会话流", Actions: ice.MergeActions(ice.Actions{ mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) { - m.OptionFields(m.Config(mdb.FIELD)) + m.OptionFields(mdb.HashField(m)) m.Cmdy(mdb.PRUNES, m.PrefixKey(), "", mdb.HASH, mdb.STATUS, aaa.LOGOUT) }}, }, mdb.HashAction(mdb.FIELD, "time,hash,status,username,hostname,pid,pwd")), Hand: func(m *ice.Message, arg ...string) { diff --git a/option.go b/option.go index 50b37d4e..0149e393 100644 --- a/option.go +++ b/option.go @@ -34,7 +34,7 @@ func (m *Message) OptionDefault(arg ...string) string { } func (m *Message) OptionSimple(key ...string) (res []string) { if len(key) == 0 { - for _, k := range kit.Split(m.Config(FIELD)) { + for _, k := range kit.Split(kit.Select("type,name,text", m.Config(FIELD))) { switch k { case TIME, HASH: continue