mirror of
https://shylinux.com/x/icebergs
synced 2025-04-26 01:24:05 +08:00
330 lines
8.5 KiB
Go
330 lines
8.5 KiB
Go
package mdb
|
|
|
|
import (
|
|
"path"
|
|
"strings"
|
|
|
|
ice "shylinux.com/x/icebergs"
|
|
kit "shylinux.com/x/toolkits"
|
|
"shylinux.com/x/toolkits/task"
|
|
)
|
|
|
|
type Any = interface{}
|
|
type Map = map[string]Any
|
|
type Maps = map[string]string
|
|
|
|
func _file_name(m *ice.Message, arg ...string) string {
|
|
if len(arg) > 3 && strings.Contains(arg[3], ice.PS) {
|
|
return arg[3]
|
|
}
|
|
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)
|
|
}
|
|
}
|
|
args := kit.Simple(res...)
|
|
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 = kit.GetMeta(value); cb := cb.(type) {
|
|
case func([]string, Map):
|
|
cb(fields, value)
|
|
case func(string, []string, Map, Map):
|
|
cb(key, fields, value, val)
|
|
case func(string, Map, Map):
|
|
cb(key, value, val)
|
|
case func(string, Map):
|
|
cb(key, value)
|
|
case func(Map):
|
|
cb(value)
|
|
case func(Any):
|
|
cb(value[TARGET])
|
|
case func(Maps):
|
|
res := Maps{}
|
|
for k, v := range value {
|
|
res[k] = kit.Format(v)
|
|
}
|
|
cb(res)
|
|
case nil:
|
|
if m.FieldsIsDetail() {
|
|
m.Push(ice.FIELDS_DETAIL, value)
|
|
} else {
|
|
m.Push(key, value, fields, val)
|
|
}
|
|
default:
|
|
m.ErrorNotImplement(cb)
|
|
}
|
|
}
|
|
|
|
const (
|
|
DICT = kit.MDB_DICT
|
|
META = kit.MDB_META
|
|
|
|
UNIQ = kit.MDB_UNIQ
|
|
FOREACH = kit.MDB_FOREACH
|
|
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
|
|
|
|
// 文件
|
|
LINK = kit.MDB_LINK
|
|
SCAN = kit.MDB_SCAN
|
|
SHOW = kit.MDB_SHOW
|
|
HELP = kit.MDB_HELP
|
|
DATA = kit.MDB_DATA
|
|
FILE = kit.MDB_FILE
|
|
|
|
// 存储
|
|
SHORT = kit.MDB_SHORT
|
|
FIELD = kit.MDB_FIELD
|
|
TOTAL = kit.MDB_TOTAL
|
|
COUNT = kit.MDB_COUNT
|
|
LIMIT = kit.MDB_LIMIT
|
|
LEAST = kit.MDB_LEAST
|
|
STORE = kit.MDB_STORE
|
|
FSIZE = kit.MDB_FSIZE
|
|
|
|
// 索引
|
|
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
|
|
)
|
|
const (
|
|
DETAIL = "detail"
|
|
RANDOM = "random"
|
|
ACTION = "action"
|
|
|
|
INPUTS = "inputs"
|
|
CREATE = "create"
|
|
REMOVE = "remove"
|
|
INSERT = "insert"
|
|
DELETE = "delete"
|
|
MODIFY = "modify"
|
|
SELECT = "select"
|
|
PRUNES = "prunes"
|
|
EXPORT = "export"
|
|
IMPORT = "import"
|
|
|
|
UPLOAD = "upload"
|
|
REVERT = "revert"
|
|
REPEAT = "repeat"
|
|
|
|
NEXT = "next"
|
|
PREV = "prev"
|
|
PAGE = "page"
|
|
OFFEND = "offend"
|
|
|
|
JSON = "json"
|
|
CSV = "csv"
|
|
)
|
|
const (
|
|
CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit"
|
|
|
|
SOURCE = "_source"
|
|
TARGET = "_target"
|
|
)
|
|
|
|
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] {
|
|
case ice.POD:
|
|
m.Cmdy("route")
|
|
case ice.CTX:
|
|
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[0])
|
|
m.Cmdy("command", SEARCH, "command", kit.Select("", arg, 1))
|
|
default:
|
|
switch arg[2] {
|
|
case ZONE: // inputs key sub type zone field value
|
|
_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))
|
|
case LIST:
|
|
_list_inputs(m, arg[0], arg[1], kit.Select(NAME, arg, 3), kit.Select("", arg, 4))
|
|
}
|
|
}
|
|
}},
|
|
INSERT: {Name: "insert key sub type arg...", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
|
defer m.ProcessRefresh3ms()
|
|
switch arg[2] {
|
|
case ZONE: // insert key sub type zone arg...
|
|
_zone_insert(m, arg[0], arg[1], arg[3], arg[4:]...)
|
|
case HASH:
|
|
_hash_insert(m, arg[0], arg[1], arg[3:]...)
|
|
case LIST:
|
|
_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) {
|
|
defer m.ProcessRefresh3ms()
|
|
switch arg[2] {
|
|
case ZONE: // delete key sub type zone field value
|
|
// _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])
|
|
case LIST:
|
|
// _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) {
|
|
switch arg[2] {
|
|
case ZONE: // modify key sub type zone id field value
|
|
_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:]...)
|
|
case LIST:
|
|
_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) {
|
|
switch arg[2] {
|
|
case ZONE:
|
|
_zone_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select("", arg, 4))
|
|
case HASH:
|
|
_hash_select(m, arg[0], arg[1], kit.Select("", arg, 3), kit.Select(FOREACH, arg, 4))
|
|
case LIST:
|
|
_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) {
|
|
switch arg[2] {
|
|
case ZONE: // prunes key sub type zone field value
|
|
// _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:]...)
|
|
m.Tables(func(value ice.Maps) { _hash_delete(m, arg[0], arg[1], HASH, value[HASH]) })
|
|
case LIST:
|
|
// _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")
|
|
}
|
|
switch file := _file_name(m, arg...); arg[2] {
|
|
case ZONE:
|
|
m.OptionFields(ZoneShort(m), m.Config(FIELD))
|
|
_zone_export(m, arg[0], arg[1], file)
|
|
case HASH:
|
|
_hash_export(m, arg[0], arg[1], file)
|
|
case LIST:
|
|
m.OptionFields(m.Config(FIELD))
|
|
_list_export(m, arg[0], arg[1], file)
|
|
}
|
|
}},
|
|
IMPORT: {Name: "import key sub type file", Help: "导入", 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)
|
|
case HASH:
|
|
_hash_import(m, arg[0], arg[1], file)
|
|
case LIST:
|
|
_list_import(m, arg[0], arg[1], file)
|
|
}
|
|
}},
|
|
}}
|
|
|
|
func init() {
|
|
ice.Index.Register(Index, nil,
|
|
INSERT, DELETE, MODIFY, SELECT,
|
|
INPUTS, PRUNES, EXPORT, IMPORT,
|
|
SEARCH, ENGINE, PLUGIN, RENDER,
|
|
)
|
|
}
|
|
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 && len(args) > 0 {
|
|
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)
|
|
})
|
|
|
|
cs := m.Target().Commands
|
|
if cs[m.CommandKey()] == nil {
|
|
return
|
|
}
|
|
|
|
if cs[m.CommandKey()].Actions[INSERT] != nil {
|
|
if cs[m.CommandKey()].Meta[INSERT] == nil {
|
|
m.Design(INSERT, "添加", append([]ice.Any{ZONE}, inputs...)...)
|
|
}
|
|
} else if cs[m.CommandKey()].Actions[CREATE] != nil {
|
|
if cs[m.CommandKey()].Meta[CREATE] == nil {
|
|
m.Design(CREATE, "创建", inputs...)
|
|
}
|
|
}
|
|
}}
|
|
}
|
|
|
|
var _locks = map[string]*task.Lock{}
|
|
var _lock = 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 {
|
|
l = &task.Lock{}
|
|
_locks[key] = l
|
|
}
|
|
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()
|
|
}
|