Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
1c106bfd
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
1c106bfd
编写于
10月 09, 2022
作者:
S
Shengliang Guan
提交者:
GitHub
10月 09, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #17235 from taosdata/feat/TD-17777-V30
feat(shell): Supported the word completed by press Tab key for 3.0
上级
329b76ed
c3357340
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
888 addition
and
1047 deletion
+888
-1047
tools/shell/inc/shellAuto.h
tools/shell/inc/shellAuto.h
+1
-1
tools/shell/inc/shellTire.h
tools/shell/inc/shellTire.h
+29
-32
tools/shell/src/shellAuto.c
tools/shell/src/shellAuto.c
+539
-686
tools/shell/src/shellTire.c
tools/shell/src/shellTire.c
+319
-328
未找到文件。
tools/shell/inc/shellAuto.h
浏览文件 @
1c106bfd
...
...
@@ -24,7 +24,7 @@ void pressTabKey(SShellCmd* cmd);
// press othr key
void
pressOtherKey
(
char
c
);
// init shell auto funciton , shell start call once
// init shell auto funciton , shell start call once
bool
shellAutoInit
();
// set conn
...
...
tools/shell/inc/shellTire.h
浏览文件 @
1c106bfd
...
...
@@ -16,68 +16,65 @@
#ifndef __TRIE__
#define __TRIE__
//
//
// The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character
//
#define FIRST_ASCII 40 // first visiable char is '0'
#define LAST_ASCII 122 // last visilbe char is 'z'
// capacity save char is 95
#define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1)
#define MAX_WORD_LEN 256 // max insert word length
#define CHAR_CNT
(LAST_ASCII - FIRST_ASCII + 1)
#define MAX_WORD_LEN 256
// max insert word length
// define STire
#define TIRE_TREE
0
#define TIRE_LIST
1
#define TIRE_TREE 0
#define TIRE_LIST 1
typedef
struct
STireNode
{
struct
STireNode
**
d
;
bool
end
;
// record end flag
}
STireNode
;
struct
STireNode
**
d
;
bool
end
;
// record end flag
}
STireNode
;
typedef
struct
StrName
{
char
*
name
;
struct
StrName
*
next
;
}
StrName
;
char
*
name
;
struct
StrName
*
next
;
}
StrName
;
typedef
struct
STire
{
char
type
;
// see define TIRE_
STireNode
root
;
char
type
;
// see define TIRE_
STireNode
root
;
StrName
*
head
;
StrName
*
tail
;
StrName
*
head
;
StrName
*
tail
;
int
count
;
// all count
int
ref
;
}
STire
;
int
count
;
// all count
int
ref
;
}
STire
;
typedef
struct
SMatchNode
{
char
*
word
;
struct
SMatchNode
*
next
;
}
SMatchNode
;
char
*
word
;
struct
SMatchNode
*
next
;
}
SMatchNode
;
typedef
struct
SMatch
{
SMatchNode
*
head
;
SMatchNode
*
tail
;
// append node to tail
int
count
;
char
pre
[
MAX_WORD_LEN
];
}
SMatch
;
SMatchNode
*
head
;
SMatchNode
*
tail
;
// append node to tail
int
count
;
char
pre
[
MAX_WORD_LEN
];
}
SMatch
;
// ----------- interface -------------
// create prefix search tree, return value call freeTire to free
// create prefix search tree, return value call freeTire to free
STire
*
createTire
(
char
type
);
// destroy prefix search tree
void
freeTire
(
STire
*
tire
);
// add a new word
// add a new word
bool
insertWord
(
STire
*
tire
,
char
*
word
);
// add a new word
// add a new word
bool
deleteWord
(
STire
*
tire
,
char
*
word
);
// match prefix words, if match is not NULL , put all item to match and return match
...
...
tools/shell/src/shellAuto.c
浏览文件 @
1c106bfd
...
...
@@ -25,441 +25,326 @@
//
#define UNION_ALL " union all "
// extern function
void
shellClearScreen
(
int32_t
ecmd_pos
,
int32_t
cursor_pos
);
void
shellGetPrevCharSize
(
const
char
*
str
,
int32_t
pos
,
int32_t
*
size
,
int32_t
*
width
);
void
shellShowOnScreen
(
SShellCmd
*
cmd
);
void
shellInsertChar
(
SShellCmd
*
cmd
,
char
*
c
,
int
size
);
bool
appendAfterSelect
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
p
,
int32_t
len
);
void
shellClearScreen
(
int32_t
ecmd_pos
,
int32_t
cursor_pos
);
void
shellGetPrevCharSize
(
const
char
*
str
,
int32_t
pos
,
int32_t
*
size
,
int32_t
*
width
);
void
shellShowOnScreen
(
SShellCmd
*
cmd
);
void
shellInsertChar
(
SShellCmd
*
cmd
,
char
*
c
,
int
size
);
bool
appendAfterSelect
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
p
,
int32_t
len
);
typedef
struct
SAutoPtr
{
STire
*
p
;
int
ref
;
}
SAutoPtr
;
int
ref
;
}
SAutoPtr
;
typedef
struct
SWord
{
int
type
;
// word type , see WT_ define
char
*
word
;
int32_t
len
;
struct
SWord
*
next
;
bool
free
;
// if true need free
}
SWord
;
typedef
struct
SWord
{
int
type
;
// word type , see WT_ define
char
*
word
;
int32_t
len
;
struct
SWord
*
next
;
bool
free
;
// if true need free
}
SWord
;
typedef
struct
{
char
*
source
;
int32_t
source_len
;
// valid data length in source
char
*
source
;
int32_t
source_len
;
// valid data length in source
int32_t
count
;
SWord
*
head
;
// matched information
int32_t
matchIndex
;
// matched word index in words
int32_t
matchLen
;
// matched length at matched word
}
SWords
;
int32_t
matchIndex
;
// matched word index in words
int32_t
matchLen
;
// matched length at matched word
}
SWords
;
SWords
shellCommands
[]
=
{
{
"alter database <db_name> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> ;"
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> balance "
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> resetlog;"
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> debugFlag 141;"
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> monitor 1;"
,
0
,
0
,
NULL
},
{
"alter all dnodes monitor "
,
0
,
0
,
NULL
},
{
"alter alldnodes balance "
,
0
,
0
,
NULL
},
{
"alter alldnodes resetlog;"
,
0
,
0
,
NULL
},
{
"alter alldnodes debugFlag 141;"
,
0
,
0
,
NULL
},
{
"alter alldnodes monitor 1;"
,
0
,
0
,
NULL
},
{
"alter table <tb_name> <tb_actions> <anyword> ;"
,
0
,
0
,
NULL
},
{
"alter table modify column"
,
0
,
0
,
NULL
},
{
"alter local resetlog;"
,
0
,
0
,
NULL
},
{
"alter local DebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local cDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local uDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local rpcDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local tmrDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter topic"
,
0
,
0
,
NULL
},
{
"alter user <user_name> <user_actions> <anyword> ;"
,
0
,
0
,
NULL
},
// 20
{
"create table <anyword> using <stb_name> tags("
,
0
,
0
,
NULL
},
{
"create database <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> ;"
,
0
,
0
,
NULL
},
{
"create dnode "
,
0
,
0
,
NULL
},
{
"create index "
,
0
,
0
,
NULL
},
{
"create mnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"create qnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"create stream <anyword> into <anyword> as select"
,
0
,
0
,
NULL
},
// 26 append sub sql
{
"create topic <anyword> as select"
,
0
,
0
,
NULL
},
// 27 append sub sql
{
"create function "
,
0
,
0
,
NULL
},
{
"create user <anyword> pass <anyword> sysinfo 0;"
,
0
,
0
,
NULL
},
{
"create user <anyword> pass <anyword> sysinfo 1;"
,
0
,
0
,
NULL
},
{
"describe <all_table>"
,
0
,
0
,
NULL
},
{
"delete from <all_table> where "
,
0
,
0
,
NULL
},
{
"drop database <db_name>"
,
0
,
0
,
NULL
},
{
"drop table <all_table>"
,
0
,
0
,
NULL
},
{
"drop dnode <dnode_id>"
,
0
,
0
,
NULL
},
{
"drop mnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"drop qnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"drop user <user_name> ;"
,
0
,
0
,
NULL
},
// 40
{
"drop function"
,
0
,
0
,
NULL
},
{
"drop consumer group <anyword> on "
,
0
,
0
,
NULL
},
{
"drop topic <topic_name> ;"
,
0
,
0
,
NULL
},
{
"drop stream <stream_name> ;"
,
0
,
0
,
NULL
},
{
"explain select"
,
0
,
0
,
NULL
},
// 44 append sub sql
{
"grant all on <anyword> to <user_name> ;"
,
0
,
0
,
NULL
},
{
"grant read on <anyword> to <user_name> ;"
,
0
,
0
,
NULL
},
{
"grant write on <anyword> to <user_name> ;"
,
0
,
0
,
NULL
},
{
"kill connection <anyword> ;"
,
0
,
0
,
NULL
},
{
"kill query "
,
0
,
0
,
NULL
},
{
"kill transaction "
,
0
,
0
,
NULL
},
{
"merge vgroup "
,
0
,
0
,
NULL
},
{
"reset query cache;"
,
0
,
0
,
NULL
},
{
"revoke all on <anyword> from <user_name> ;"
,
0
,
0
,
NULL
},
{
"revoke read on <anyword> from <user_name> ;"
,
0
,
0
,
NULL
},
{
"revoke write on <anyword> from <user_name> ;"
,
0
,
0
,
NULL
},
{
"select * from <all_table>"
,
0
,
0
,
NULL
},
{
"select _block_dist() from <all_table>
\\
G;"
,
0
,
0
,
NULL
},
{
"select client_version();"
,
0
,
0
,
NULL
},
// 60
{
"select current_user();"
,
0
,
0
,
NULL
},
{
"select database();"
,
0
,
0
,
NULL
},
{
"select server_version();"
,
0
,
0
,
NULL
},
{
"select server_status();"
,
0
,
0
,
NULL
},
{
"select now();"
,
0
,
0
,
NULL
},
{
"select today();"
,
0
,
0
,
NULL
},
{
"select timezone();"
,
0
,
0
,
NULL
},
{
"set max_binary_display_width "
,
0
,
0
,
NULL
},
{
"show apps;"
,
0
,
0
,
NULL
},
{
"show create database <db_name>
\\
G;"
,
0
,
0
,
NULL
},
{
"show create stable <stb_name>
\\
G;"
,
0
,
0
,
NULL
},
{
"show create table <tb_name>
\\
G;"
,
0
,
0
,
NULL
},
{
"show connections;"
,
0
,
0
,
NULL
},
{
"show cluster;"
,
0
,
0
,
NULL
},
{
"show databases;"
,
0
,
0
,
NULL
},
{
"show dnodes;"
,
0
,
0
,
NULL
},
{
"show dnode <dnode_id> variables;"
,
0
,
0
,
NULL
},
{
"show functions;"
,
0
,
0
,
NULL
},
{
"show mnodes;"
,
0
,
0
,
NULL
},
{
"show queries;"
,
0
,
0
,
NULL
},
// 80
{
"show query <anyword> ;"
,
0
,
0
,
NULL
},
{
"show qnodes;"
,
0
,
0
,
NULL
},
{
"show snodes;"
,
0
,
0
,
NULL
},
{
"show stables;"
,
0
,
0
,
NULL
},
{
"show stables like "
,
0
,
0
,
NULL
},
{
"show streams;"
,
0
,
0
,
NULL
},
{
"show scores;"
,
0
,
0
,
NULL
},
{
"show subscriptions;"
,
0
,
0
,
NULL
},
{
"show tables;"
,
0
,
0
,
NULL
},
{
"show tables like"
,
0
,
0
,
NULL
},
{
"show table distributed <all_table>"
,
0
,
0
,
NULL
},
{
"show tags from <tb_name>"
,
0
,
0
,
NULL
},
{
"show tags from <db_name>"
,
0
,
0
,
NULL
},
{
"show topics;"
,
0
,
0
,
NULL
},
{
"show transactions;"
,
0
,
0
,
NULL
},
{
"show users;"
,
0
,
0
,
NULL
},
{
"show variables;"
,
0
,
0
,
NULL
},
{
"show local variables;"
,
0
,
0
,
NULL
},
{
"show vnodes <dnode_id>"
,
0
,
0
,
NULL
},
{
"show vgroups;"
,
0
,
0
,
NULL
},
{
"show consumers;"
,
0
,
0
,
NULL
},
{
"show grants;"
,
0
,
0
,
NULL
},
{
"split vgroup "
,
0
,
0
,
NULL
},
{
"insert into <tb_name> values("
,
0
,
0
,
NULL
},
{
"insert into <tb_name> using <stb_name> tags("
,
0
,
0
,
NULL
},
{
"insert into <tb_name> using <stb_name> <anyword> values("
,
0
,
0
,
NULL
},
{
"insert into <tb_name> file "
,
0
,
0
,
NULL
},
{
"trim database <db_name>"
,
0
,
0
,
NULL
},
{
"use <db_name>"
,
0
,
0
,
NULL
},
{
"quit"
,
0
,
0
,
NULL
}
};
char
*
keywords
[]
=
{
"and "
,
"asc "
,
"desc "
,
"from "
,
"fill("
,
"limit "
,
"where "
,
"interval("
,
"order by "
,
"order by "
,
"offset "
,
"or "
,
"group by "
,
"now()"
,
"session("
,
"sliding "
,
"slimit "
,
"soffset "
,
"state_window("
,
"today() "
,
"union all select "
,
"partition by "
};
char
*
functions
[]
=
{
"count("
,
"sum("
,
"avg("
,
"last("
,
"last_row("
,
"top("
,
"interp("
,
"max("
,
"min("
,
"now()"
,
"today()"
,
"percentile("
,
"tail("
,
"pow("
,
"abs("
,
"atan("
,
"acos("
,
"asin("
,
"apercentile("
,
"bottom("
,
"cast("
,
"ceil("
,
"char_length("
,
"cos("
,
"concat("
,
"concat_ws("
,
"csum("
,
"diff("
,
"derivative("
,
"elapsed("
,
"first("
,
"floor("
,
"hyperloglog("
,
"histogram("
,
"irate("
,
"leastsquares("
,
"length("
,
"log("
,
"lower("
,
"ltrim("
,
"mavg("
,
"mode("
,
"tan("
,
"round("
,
"rtrim("
,
"sample("
,
"sin("
,
"spread("
,
"substr("
,
"statecount("
,
"stateduration("
,
"stddev("
,
"sqrt("
,
"timediff("
,
"timezone("
,
"timetruncate("
,
"twa("
,
"to_unixtimestamp("
,
"unique("
,
"upper("
,
};
char
*
tb_actions
[]
=
{
"add column "
,
"modify column "
,
"drop column "
,
"rename column "
,
"add tag "
,
"modify tag "
,
"drop tag "
,
"rename tag "
,
"set tag "
,
};
char
*
user_actions
[]
=
{
"pass "
,
"enable "
,
"sysinfo "
};
char
*
tb_options
[]
=
{
"comment "
,
"watermark "
,
"max_delay "
,
"ttl "
,
"rollup("
,
"sma("
};
char
*
db_options
[]
=
{
"keep "
,
"replica "
,
"precision "
,
"strict "
,
"buffer "
,
"cachemodel "
,
"cachesize "
,
"comp "
,
"duration "
,
"wal_fsync_period"
,
"maxrows "
,
"minrows "
,
"pages "
,
"pagesize "
,
"retentions "
,
"wal_level "
,
"vgroups "
,
"single_stable "
,
"wal_retention_period "
,
"wal_roll_period "
,
"wal_retention_size "
,
"wal_segment_size "
};
char
*
alter_db_options
[]
=
{
"keep "
,
"cachemodel "
,
"cachesize "
,
"wal_fsync_period "
,
"wal_level "
};
char
*
data_types
[]
=
{
"timestamp"
,
"int"
,
"int unsigned"
,
"varchar(16)"
,
"float"
,
"double"
,
"binary(16)"
,
"nchar(16)"
,
"bigint"
,
"bigint unsigned"
,
"smallint"
,
"smallint unsigned"
,
"tinyint"
,
"tinyint unsigned"
,
"bool"
,
"json"
{
"alter database <db_name> <alter_db_options> <anyword> <alter_db_options> <anyword> <alter_db_options> <anyword> "
"<alter_db_options> <anyword> <alter_db_options> <anyword> ;"
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> balance "
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> resetlog;"
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> debugFlag 141;"
,
0
,
0
,
NULL
},
{
"alter dnode <dnode_id> monitor 1;"
,
0
,
0
,
NULL
},
{
"alter all dnodes monitor "
,
0
,
0
,
NULL
},
{
"alter alldnodes balance "
,
0
,
0
,
NULL
},
{
"alter alldnodes resetlog;"
,
0
,
0
,
NULL
},
{
"alter alldnodes debugFlag 141;"
,
0
,
0
,
NULL
},
{
"alter alldnodes monitor 1;"
,
0
,
0
,
NULL
},
{
"alter table <tb_name> <tb_actions> <anyword> ;"
,
0
,
0
,
NULL
},
{
"alter table modify column"
,
0
,
0
,
NULL
},
{
"alter local resetlog;"
,
0
,
0
,
NULL
},
{
"alter local DebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local cDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local uDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local rpcDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter local tmrDebugFlag 143;"
,
0
,
0
,
NULL
},
{
"alter topic"
,
0
,
0
,
NULL
},
{
"alter user <user_name> <user_actions> <anyword> ;"
,
0
,
0
,
NULL
},
// 20
{
"create table <anyword> using <stb_name> tags("
,
0
,
0
,
NULL
},
{
"create database <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> "
"<anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> <db_options> <anyword> "
"<db_options> <anyword> <db_options> <anyword> ;"
,
0
,
0
,
NULL
},
{
"create dnode "
,
0
,
0
,
NULL
},
{
"create index "
,
0
,
0
,
NULL
},
{
"create mnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"create qnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"create stream <anyword> into <anyword> as select"
,
0
,
0
,
NULL
},
// 26 append sub sql
{
"create topic <anyword> as select"
,
0
,
0
,
NULL
},
// 27 append sub sql
{
"create function "
,
0
,
0
,
NULL
},
{
"create user <anyword> pass <anyword> sysinfo 0;"
,
0
,
0
,
NULL
},
{
"create user <anyword> pass <anyword> sysinfo 1;"
,
0
,
0
,
NULL
},
{
"describe <all_table>"
,
0
,
0
,
NULL
},
{
"delete from <all_table> where "
,
0
,
0
,
NULL
},
{
"drop database <db_name>"
,
0
,
0
,
NULL
},
{
"drop table <all_table>"
,
0
,
0
,
NULL
},
{
"drop dnode <dnode_id>"
,
0
,
0
,
NULL
},
{
"drop mnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"drop qnode on dnode <dnode_id> ;"
,
0
,
0
,
NULL
},
{
"drop user <user_name> ;"
,
0
,
0
,
NULL
},
// 40
{
"drop function"
,
0
,
0
,
NULL
},
{
"drop consumer group <anyword> on "
,
0
,
0
,
NULL
},
{
"drop topic <topic_name> ;"
,
0
,
0
,
NULL
},
{
"drop stream <stream_name> ;"
,
0
,
0
,
NULL
},
{
"explain select"
,
0
,
0
,
NULL
},
// 44 append sub sql
{
"grant all on <anyword> to <user_name> ;"
,
0
,
0
,
NULL
},
{
"grant read on <anyword> to <user_name> ;"
,
0
,
0
,
NULL
},
{
"grant write on <anyword> to <user_name> ;"
,
0
,
0
,
NULL
},
{
"kill connection <anyword> ;"
,
0
,
0
,
NULL
},
{
"kill query "
,
0
,
0
,
NULL
},
{
"kill transaction "
,
0
,
0
,
NULL
},
{
"merge vgroup "
,
0
,
0
,
NULL
},
{
"reset query cache;"
,
0
,
0
,
NULL
},
{
"revoke all on <anyword> from <user_name> ;"
,
0
,
0
,
NULL
},
{
"revoke read on <anyword> from <user_name> ;"
,
0
,
0
,
NULL
},
{
"revoke write on <anyword> from <user_name> ;"
,
0
,
0
,
NULL
},
{
"select * from <all_table>"
,
0
,
0
,
NULL
},
{
"select _block_dist() from <all_table>
\\
G;"
,
0
,
0
,
NULL
},
{
"select client_version();"
,
0
,
0
,
NULL
},
// 60
{
"select current_user();"
,
0
,
0
,
NULL
},
{
"select database();"
,
0
,
0
,
NULL
},
{
"select server_version();"
,
0
,
0
,
NULL
},
{
"select server_status();"
,
0
,
0
,
NULL
},
{
"select now();"
,
0
,
0
,
NULL
},
{
"select today();"
,
0
,
0
,
NULL
},
{
"select timezone();"
,
0
,
0
,
NULL
},
{
"set max_binary_display_width "
,
0
,
0
,
NULL
},
{
"show apps;"
,
0
,
0
,
NULL
},
{
"show create database <db_name>
\\
G;"
,
0
,
0
,
NULL
},
{
"show create stable <stb_name>
\\
G;"
,
0
,
0
,
NULL
},
{
"show create table <tb_name>
\\
G;"
,
0
,
0
,
NULL
},
{
"show connections;"
,
0
,
0
,
NULL
},
{
"show cluster;"
,
0
,
0
,
NULL
},
{
"show databases;"
,
0
,
0
,
NULL
},
{
"show dnodes;"
,
0
,
0
,
NULL
},
{
"show dnode <dnode_id> variables;"
,
0
,
0
,
NULL
},
{
"show functions;"
,
0
,
0
,
NULL
},
{
"show mnodes;"
,
0
,
0
,
NULL
},
{
"show queries;"
,
0
,
0
,
NULL
},
// 80
{
"show query <anyword> ;"
,
0
,
0
,
NULL
},
{
"show qnodes;"
,
0
,
0
,
NULL
},
{
"show stables;"
,
0
,
0
,
NULL
},
{
"show stables like "
,
0
,
0
,
NULL
},
{
"show streams;"
,
0
,
0
,
NULL
},
{
"show scores;"
,
0
,
0
,
NULL
},
{
"show snodes;"
,
0
,
0
,
NULL
},
{
"show subscriptions;"
,
0
,
0
,
NULL
},
{
"show tables;"
,
0
,
0
,
NULL
},
{
"show tables like"
,
0
,
0
,
NULL
},
{
"show table distributed <all_table>"
,
0
,
0
,
NULL
},
{
"show tags from <tb_name>"
,
0
,
0
,
NULL
},
{
"show tags from <db_name>"
,
0
,
0
,
NULL
},
{
"show topics;"
,
0
,
0
,
NULL
},
{
"show transactions;"
,
0
,
0
,
NULL
},
{
"show users;"
,
0
,
0
,
NULL
},
{
"show variables;"
,
0
,
0
,
NULL
},
{
"show local variables;"
,
0
,
0
,
NULL
},
{
"show vnodes <dnode_id>"
,
0
,
0
,
NULL
},
{
"show vgroups;"
,
0
,
0
,
NULL
},
{
"show consumers;"
,
0
,
0
,
NULL
},
{
"show grants;"
,
0
,
0
,
NULL
},
{
"split vgroup "
,
0
,
0
,
NULL
},
{
"insert into <tb_name> values("
,
0
,
0
,
NULL
},
{
"insert into <tb_name> using <stb_name> tags("
,
0
,
0
,
NULL
},
{
"insert into <tb_name> using <stb_name> <anyword> values("
,
0
,
0
,
NULL
},
{
"insert into <tb_name> file "
,
0
,
0
,
NULL
},
{
"trim database <db_name>"
,
0
,
0
,
NULL
},
{
"use <db_name>"
,
0
,
0
,
NULL
},
{
"quit"
,
0
,
0
,
NULL
}};
char
*
keywords
[]
=
{
"and "
,
"asc "
,
"desc "
,
"from "
,
"fill("
,
"limit "
,
"where "
,
"interval("
,
"order by "
,
"order by "
,
"offset "
,
"or "
,
"group by "
,
"now()"
,
"session("
,
"sliding "
,
"slimit "
,
"soffset "
,
"state_window("
,
"today() "
,
"union all select "
,
"partition by "
};
char
*
functions
[]
=
{
"count("
,
"sum("
,
"avg("
,
"last("
,
"last_row("
,
"top("
,
"interp("
,
"max("
,
"min("
,
"now()"
,
"today()"
,
"percentile("
,
"tail("
,
"pow("
,
"abs("
,
"atan("
,
"acos("
,
"asin("
,
"apercentile("
,
"bottom("
,
"cast("
,
"ceil("
,
"char_length("
,
"cos("
,
"concat("
,
"concat_ws("
,
"csum("
,
"diff("
,
"derivative("
,
"elapsed("
,
"first("
,
"floor("
,
"hyperloglog("
,
"histogram("
,
"irate("
,
"leastsquares("
,
"length("
,
"log("
,
"lower("
,
"ltrim("
,
"mavg("
,
"mode("
,
"tan("
,
"round("
,
"rtrim("
,
"sample("
,
"sin("
,
"spread("
,
"substr("
,
"statecount("
,
"stateduration("
,
"stddev("
,
"sqrt("
,
"timediff("
,
"timezone("
,
"timetruncate("
,
"twa("
,
"to_unixtimestamp("
,
"unique("
,
"upper("
,
};
char
*
key_tags
[]
=
{
"tags("
char
*
tb_actions
[]
=
{
"add column "
,
"modify column "
,
"drop column "
,
"rename column "
,
"add tag "
,
"modify tag "
,
"drop tag "
,
"rename tag "
,
"set tag "
,
};
char
*
key_select
[]
=
{
"select "
};
char
*
user_actions
[]
=
{
"pass "
,
"enable "
,
"sysinfo "
};
char
*
tb_options
[]
=
{
"comment "
,
"watermark "
,
"max_delay "
,
"ttl "
,
"rollup("
,
"sma("
};
char
*
db_options
[]
=
{
"keep "
,
"replica "
,
"precision "
,
"strict "
,
"buffer "
,
"cachemodel "
,
"cachesize "
,
"comp "
,
"duration "
,
"wal_fsync_period"
,
"maxrows "
,
"minrows "
,
"pages "
,
"pagesize "
,
"retentions "
,
"wal_level "
,
"vgroups "
,
"single_stable "
,
"wal_retention_period "
,
"wal_roll_period "
,
"wal_retention_size "
,
"wal_segment_size "
};
char
*
alter_db_options
[]
=
{
"keep "
,
"cachemodel "
,
"cachesize "
,
"wal_fsync_period "
,
"wal_level "
};
char
*
data_types
[]
=
{
"timestamp"
,
"int"
,
"int unsigned"
,
"varchar(16)"
,
"float"
,
"double"
,
"binary(16)"
,
"nchar(16)"
,
"bigint"
,
"bigint unsigned"
,
"smallint"
,
"smallint unsigned"
,
"tinyint"
,
"tinyint unsigned"
,
"bool"
,
"json"
};
char
*
key_tags
[]
=
{
"tags("
};
char
*
key_select
[]
=
{
"select "
};
//
// ------- gobal variant define ---------
//
int32_t
firstMatchIndex
=
-
1
;
// first match shellCommands index
int32_t
lastMatchIndex
=
-
1
;
// last match shellCommands index
int32_t
curMatchIndex
=
-
1
;
// current match shellCommands index
int32_t
lastWordBytes
=
-
1
;
// printShow last word length
bool
waitAutoFill
=
false
;
int32_t
firstMatchIndex
=
-
1
;
// first match shellCommands index
int32_t
lastMatchIndex
=
-
1
;
// last match shellCommands index
int32_t
curMatchIndex
=
-
1
;
// current match shellCommands index
int32_t
lastWordBytes
=
-
1
;
// printShow last word length
bool
waitAutoFill
=
false
;
//
// ----------- global var array define -----------
//
#define WT_VAR_DBNAME 0
#define WT_VAR_STABLE 1
#define WT_VAR_TABLE 2
#define WT_VAR_DNODEID 3
#define WT_VAR_USERNAME 4
#define WT_VAR_TOPIC 5
#define WT_VAR_STREAM 6
#define WT_VAR_ALLTABLE 7
#define WT_VAR_FUNC 8
#define WT_VAR_KEYWORD 9
#define WT_VAR_TBACTION 10
#define WT_VAR_DBOPTION 11
#define WT_VAR_DBNAME
0
#define WT_VAR_STABLE
1
#define WT_VAR_TABLE
2
#define WT_VAR_DNODEID
3
#define WT_VAR_USERNAME
4
#define WT_VAR_TOPIC
5
#define WT_VAR_STREAM
6
#define WT_VAR_ALLTABLE
7
#define WT_VAR_FUNC
8
#define WT_VAR_KEYWORD
9
#define WT_VAR_TBACTION
10
#define WT_VAR_DBOPTION
11
#define WT_VAR_ALTER_DBOPTION 12
#define WT_VAR_DATATYPE 13
#define WT_VAR_KEYTAGS 14
#define WT_VAR_ANYWORD 15
#define WT_VAR_TBOPTION 16
#define WT_VAR_USERACTION 17
#define WT_VAR_KEYSELECT 18
#define WT_VAR_DATATYPE 13
#define WT_VAR_KEYTAGS 14
#define WT_VAR_ANYWORD 15
#define WT_VAR_TBOPTION 16
#define WT_VAR_USERACTION 17
#define WT_VAR_KEYSELECT 18
#define WT_VAR_CNT
19
#define WT_VAR_CNT 19
#define WT_FROM_DB_MAX
6 // max get content from db
#define WT_FROM_DB_CNT
(WT_FROM_DB_MAX + 1)
#define WT_FROM_DB_MAX 6 // max get content from db
#define WT_FROM_DB_CNT (WT_FROM_DB_MAX + 1)
#define WT_TEXT
0xFF
#define WT_TEXT 0xFF
char
dbName
[
256
]
=
""
;
// save use database name;
char
dbName
[
256
]
=
""
;
// save use database name;
// tire array
STire
*
tires
[
WT_VAR_CNT
];
STire
*
tires
[
WT_VAR_CNT
];
TdThreadMutex
tiresMutex
;
//save thread handle obtain var name from db server
//
save thread handle obtain var name from db server
TdThread
*
threads
[
WT_FROM_DB_CNT
];
// obtain var name with sql from server
char
varTypes
[
WT_VAR_CNT
][
64
]
=
{
"<db_name>"
,
"<stb_name>"
,
"<tb_name>"
,
"<dnode_id>"
,
"<user_name>"
,
"<topic_name>"
,
"<stream_name>"
,
"<all_table>"
,
"<function>"
,
"<keyword>"
,
"<tb_actions>"
,
"<db_options>"
,
"<alter_db_options>"
,
"<data_types>"
,
"<key_tags>"
,
"<anyword>"
,
"<tb_options>"
,
"<user_actions>"
,
"<key_select>"
};
char
varSqls
[
WT_FROM_DB_CNT
][
64
]
=
{
"show databases;"
,
"show stables;"
,
"show tables;"
,
"show dnodes;"
,
"show users;"
,
"show topics;"
,
"show streams;"
};
char
varTypes
[
WT_VAR_CNT
][
64
]
=
{
"<db_name>"
,
"<stb_name>"
,
"<tb_name>"
,
"<dnode_id>"
,
"<user_name>"
,
"<topic_name>"
,
"<stream_name>"
,
"<all_table>"
,
"<function>"
,
"<keyword>"
,
"<tb_actions>"
,
"<db_options>"
,
"<alter_db_options>"
,
"<data_types>"
,
"<key_tags>"
,
"<anyword>"
,
"<tb_options>"
,
"<user_actions>"
,
"<key_select>"
};
char
varSqls
[
WT_FROM_DB_CNT
][
64
]
=
{
"show databases;"
,
"show stables;"
,
"show tables;"
,
"show dnodes;"
,
"show users;"
,
"show topics;"
,
"show streams;"
};
// var words current cursor, if user press any one key except tab, cursorVar can be reset to -1
int
cursorVar
=
-
1
;
bool
varMode
=
false
;
// enter var names list mode
TAOS
*
varCon
=
NULL
;
SShellCmd
*
varCmd
=
NULL
;
SMatch
*
lastMatch
=
NULL
;
// save last match result
int
cntDel
=
0
;
// delete byte count after next press tab
int
cursorVar
=
-
1
;
bool
varMode
=
false
;
// enter var names list mode
TAOS
*
varCon
=
NULL
;
SShellCmd
*
varCmd
=
NULL
;
SMatch
*
lastMatch
=
NULL
;
// save last match result
int
cntDel
=
0
;
// delete byte count after next press tab
// show auto tab introduction
void
printfIntroduction
()
{
printf
(
" **************************** How To Use TAB Key ********************************
\n
"
);
printf
(
" * TDengine Command Line supports pressing TAB key to complete word, *
\n
"
);
printf
(
" **************************** How To Use TAB Key ********************************
\n
"
);
printf
(
" * TDengine Command Line supports pressing TAB key to complete word, *
\n
"
);
printf
(
" * including database name, table name, function name and keywords. *
\n
"
);
printf
(
" * Press TAB key anywhere, you'll get surprise. *
\n
"
);
printf
(
" * KEYBOARD SHORTCUT: *
\n
"
);
printf
(
" * [ TAB ] ...... Complete the word or show help if no input *
\n
"
);
printf
(
" * [ Ctrl + A ] ...... move cursor to [A]head of line *
\n
"
);
printf
(
" * [ Ctrl + E ] ...... move cursor to [E]nd of line *
\n
"
);
printf
(
" * [ Ctrl + W ] ...... move cursor to line of middle *
\n
"
);
printf
(
" * [ Ctrl + W ] ...... move cursor to line of middle *
\n
"
);
printf
(
" * [ Ctrl + L ] ...... clean screen *
\n
"
);
printf
(
" * [ Ctrl + K ] ...... clean after cursor *
\n
"
);
printf
(
" * [ Ctrl + U ] ...... clean before cursor *
\n
"
);
printf
(
" * *
\n
"
);
printf
(
" **********************************************************************************
\n\n
"
);
printf
(
" **********************************************************************************
\n\n
"
);
}
void
showHelp
()
{
printf
(
"
\n
The following are supported commands for TDengine Command Line:"
);
printf
(
"
\n
\
printf
(
"
\n
\
----- A -----
\n
\
alter database <db_name> <db_options>
\n
\
alter dnode <dnode_id> balance
\n
\
...
...
@@ -572,9 +457,10 @@ void showHelp() {
use <db_name>;"
);
printf
(
"
\n\n
"
);
//define in getDuration() function
printf
(
"\
// define in getDuration() function
printf
(
"\
Timestamp expression Format:
\n
\
b - nanosecond
\n
\
u - microsecond
\n
\
...
...
@@ -597,11 +483,10 @@ void showHelp() {
#define SHELL_COMMAND_COUNT() (sizeof(shellCommands) / sizeof(SWords))
// get at
SWord
*
atWord
(
SWords
*
command
,
int32_t
index
)
{
SWord
*
word
=
command
->
head
;
SWord
*
atWord
(
SWords
*
command
,
int32_t
index
)
{
SWord
*
word
=
command
->
head
;
for
(
int32_t
i
=
0
;
i
<
index
;
i
++
)
{
if
(
word
==
NULL
)
return
NULL
;
if
(
word
==
NULL
)
return
NULL
;
word
=
word
->
next
;
}
...
...
@@ -612,18 +497,17 @@ SWord * atWord(SWords * command, int32_t index) {
int
wordType
(
const
char
*
p
,
int32_t
len
)
{
for
(
int
i
=
0
;
i
<
WT_VAR_CNT
;
i
++
)
{
if
(
strncmp
(
p
,
varTypes
[
i
],
len
)
==
0
)
return
i
;
if
(
strncmp
(
p
,
varTypes
[
i
],
len
)
==
0
)
return
i
;
}
return
WT_TEXT
;
}
// add word
SWord
*
addWord
(
const
char
*
p
,
int32_t
len
,
bool
pattern
)
{
SWord
*
word
=
(
SWord
*
)
taosMemoryMalloc
(
sizeof
(
SWord
));
SWord
*
addWord
(
const
char
*
p
,
int32_t
len
,
bool
pattern
)
{
SWord
*
word
=
(
SWord
*
)
taosMemoryMalloc
(
sizeof
(
SWord
));
memset
(
word
,
0
,
sizeof
(
SWord
));
word
->
word
=
(
char
*
)
p
;
word
->
len
=
len
;
word
->
word
=
(
char
*
)
p
;
word
->
len
=
len
;
// check format
if
(
pattern
)
{
...
...
@@ -636,10 +520,10 @@ SWord * addWord(const char* p, int32_t len, bool pattern) {
}
// parse one command
void
parseCommand
(
SWords
*
command
,
bool
pattern
)
{
char
*
p
=
command
->
source
;
void
parseCommand
(
SWords
*
command
,
bool
pattern
)
{
char
*
p
=
command
->
source
;
int32_t
start
=
0
;
int32_t
size
=
command
->
source_len
>
0
?
command
->
source_len
:
strlen
(
p
);
int32_t
size
=
command
->
source_len
>
0
?
command
->
source_len
:
strlen
(
p
);
bool
lastBlank
=
false
;
for
(
int
i
=
0
;
i
<=
size
;
i
++
)
{
...
...
@@ -647,28 +531,28 @@ void parseCommand(SWords * command, bool pattern) {
// check continue blank like ' '
if
(
p
[
i
]
==
' '
)
{
if
(
lastBlank
)
{
start
++
;
start
++
;
continue
;
}
if
(
i
==
0
)
{
// first blank
if
(
i
==
0
)
{
// first blank
lastBlank
=
true
;
start
++
;
start
++
;
continue
;
}
lastBlank
=
true
;
}
}
// found split or string end , append word
if
(
command
->
head
==
NULL
)
{
command
->
head
=
addWord
(
p
+
start
,
i
-
start
,
pattern
);
command
->
count
=
1
;
}
else
{
SWord
*
word
=
command
->
head
;
SWord
*
word
=
command
->
head
;
while
(
word
->
next
)
{
word
=
word
->
next
;
}
word
->
next
=
addWord
(
p
+
start
,
i
-
start
,
pattern
);
command
->
count
++
;
command
->
count
++
;
}
start
=
i
+
1
;
}
else
{
...
...
@@ -678,25 +562,23 @@ void parseCommand(SWords * command, bool pattern) {
}
// free SShellCmd
void
freeCommand
(
SWords
*
command
)
{
SWord
*
word
=
command
->
head
;
void
freeCommand
(
SWords
*
command
)
{
SWord
*
word
=
command
->
head
;
if
(
word
==
NULL
)
{
return
;
return
;
}
// loop
// loop
while
(
word
->
next
)
{
SWord
*
tmp
=
word
;
SWord
*
tmp
=
word
;
word
=
word
->
next
;
// if malloc need free
if
(
tmp
->
free
&&
tmp
->
word
)
taosMemoryFree
(
tmp
->
word
);
if
(
tmp
->
free
&&
tmp
->
word
)
taosMemoryFree
(
tmp
->
word
);
taosMemoryFree
(
tmp
);
}
// if malloc need free
if
(
word
->
free
&&
word
->
word
)
taosMemoryFree
(
word
->
word
);
if
(
word
->
free
&&
word
->
word
)
taosMemoryFree
(
word
->
word
);
taosMemoryFree
(
word
);
}
...
...
@@ -715,12 +597,11 @@ void GenerateVarType(int type, char** p, int count) {
// -------------------- shell auto ----------------
//
// init shell auto funciton , shell start call once
// init shell auto funciton , shell start call once
bool
shellAutoInit
()
{
// command
int32_t
count
=
SHELL_COMMAND_COUNT
();
for
(
int32_t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
int32_t
i
=
0
;
i
<
count
;
i
++
)
{
parseCommand
(
shellCommands
+
i
,
true
);
}
...
...
@@ -732,30 +613,28 @@ bool shellAutoInit() {
memset
(
threads
,
0
,
sizeof
(
TdThread
*
)
*
WT_FROM_DB_CNT
);
// generate varType
GenerateVarType
(
WT_VAR_FUNC
,
functions
,
sizeof
(
functions
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_KEYWORD
,
keywords
,
sizeof
(
keywords
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_DBOPTION
,
db_options
,
sizeof
(
db_options
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_ALTER_DBOPTION
,
alter_db_options
,
sizeof
(
alter_db_options
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_TBACTION
,
tb_actions
,
sizeof
(
tb_actions
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_DATATYPE
,
data_types
,
sizeof
(
data_types
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_KEYTAGS
,
key_tags
,
sizeof
(
key_tags
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_TBOPTION
,
tb_options
,
sizeof
(
tb_options
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_USERACTION
,
user_actions
,
sizeof
(
user_actions
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_KEYSELECT
,
key_select
,
sizeof
(
key_select
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_FUNC
,
functions
,
sizeof
(
functions
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_KEYWORD
,
keywords
,
sizeof
(
keywords
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_DBOPTION
,
db_options
,
sizeof
(
db_options
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_ALTER_DBOPTION
,
alter_db_options
,
sizeof
(
alter_db_options
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_TBACTION
,
tb_actions
,
sizeof
(
tb_actions
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_DATATYPE
,
data_types
,
sizeof
(
data_types
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_KEYTAGS
,
key_tags
,
sizeof
(
key_tags
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_TBOPTION
,
tb_options
,
sizeof
(
tb_options
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_USERACTION
,
user_actions
,
sizeof
(
user_actions
)
/
sizeof
(
char
*
));
GenerateVarType
(
WT_VAR_KEYSELECT
,
key_select
,
sizeof
(
key_select
)
/
sizeof
(
char
*
));
return
true
;
}
// set conn
void
shellSetConn
(
TAOS
*
conn
)
{
varCon
=
conn
;
}
void
shellSetConn
(
TAOS
*
conn
)
{
varCon
=
conn
;
}
// exit shell auto funciton, shell exit call once
void
shellAutoExit
()
{
// free command
int32_t
count
=
SHELL_COMMAND_COUNT
();
for
(
int32_t
i
=
0
;
i
<
count
;
i
++
)
{
for
(
int32_t
i
=
0
;
i
<
count
;
i
++
)
{
freeCommand
(
shellCommands
+
i
);
}
...
...
@@ -765,7 +644,7 @@ void shellAutoExit() {
if
(
tires
[
i
])
{
freeTire
(
tires
[
i
]);
tires
[
i
]
=
NULL
;
}
}
}
taosThreadMutexUnlock
(
&
tiresMutex
);
// destory
...
...
@@ -790,8 +669,7 @@ void shellAutoExit() {
// ------------------- auto ptr for tires --------------------------
//
bool
setNewAuotPtr
(
int
type
,
STire
*
pNew
)
{
if
(
pNew
==
NULL
)
return
false
;
if
(
pNew
==
NULL
)
return
false
;
taosThreadMutexLock
(
&
tiresMutex
);
STire
*
pOld
=
tires
[
type
];
...
...
@@ -826,63 +704,61 @@ STire* getAutoPtr(int type) {
// put back tire to tires[type], if tire not equal tires[type].p, need free tire
void
putBackAutoPtr
(
int
type
,
STire
*
tire
)
{
if
(
tire
==
NULL
)
{
return
;
return
;
}
taosThreadMutexLock
(
&
tiresMutex
);
if
(
tires
[
type
]
!=
tire
)
{
//update by out, can't put back , so free
//
update by out, can't put back , so free
if
(
--
tire
->
ref
==
1
)
{
// support multi thread getAuotPtr
freeTire
(
tire
);
}
}
else
{
tires
[
type
]
->
ref
--
;
assert
(
tires
[
type
]
->
ref
>
0
);
}
taosThreadMutexUnlock
(
&
tiresMutex
);
return
;
return
;
}
//
// ------------------- var Word --------------------------
//
#define MAX_CACHED_CNT 100000 // max cached rows 10w
#define MAX_CACHED_CNT 100000
// max cached rows 10w
// write sql result to var name, return write rows cnt
int
writeVarNames
(
int
type
,
TAOS_RES
*
tres
)
{
// fetch row
// fetch row
TAOS_ROW
row
=
taos_fetch_row
(
tres
);
if
(
row
==
NULL
)
{
return
0
;
}
TAOS_FIELD
*
fields
=
taos_fetch_fields
(
tres
);
TAOS_FIELD
*
fields
=
taos_fetch_fields
(
tres
);
// create new tires
char
tireType
=
type
==
WT_VAR_TABLE
?
TIRE_TREE
:
TIRE_LIST
;
char
tireType
=
type
==
WT_VAR_TABLE
?
TIRE_TREE
:
TIRE_LIST
;
STire
*
tire
=
createTire
(
tireType
);
// enum rows
char
name
[
1024
];
int
numOfRows
=
0
;
int
numOfRows
=
0
;
do
{
int32_t
*
lengths
=
taos_fetch_lengths
(
tres
);
int32_t
bytes
=
lengths
[
0
];
if
(
fields
[
0
].
type
==
TSDB_DATA_TYPE_INT
)
{
sprintf
(
name
,
"%d"
,
*
(
int16_t
*
)
row
[
0
]);
int32_t
bytes
=
lengths
[
0
];
if
(
fields
[
0
].
type
==
TSDB_DATA_TYPE_INT
)
{
sprintf
(
name
,
"%d"
,
*
(
int16_t
*
)
row
[
0
]);
}
else
{
memcpy
(
name
,
row
[
0
],
bytes
);
}
name
[
bytes
]
=
0
;
//
set string end
name
[
bytes
]
=
0
;
//
set string end
// insert to tire
insertWord
(
tire
,
name
);
if
(
++
numOfRows
>
MAX_CACHED_CNT
)
{
if
(
++
numOfRows
>
MAX_CACHED_CNT
)
{
break
;
}
...
...
@@ -895,12 +771,12 @@ int writeVarNames(int type, TAOS_RES* tres) {
return
numOfRows
;
}
bool
firstMatchCommand
(
TAOS
*
con
,
SShellCmd
*
cmd
);
bool
firstMatchCommand
(
TAOS
*
con
,
SShellCmd
*
cmd
);
//
// thread obtain var thread from db server
// thread obtain var thread from db server
//
void
*
varObtainThread
(
void
*
param
)
{
int
type
=
*
(
int
*
)
param
;
int
type
=
*
(
int
*
)
param
;
taosMemoryFree
(
param
);
if
(
varCon
==
NULL
||
type
>
WT_FROM_DB_MAX
)
{
...
...
@@ -919,7 +795,7 @@ void* varObtainThread(void* param) {
// free sql
taos_free_result
(
pSql
);
// check need call auto tab
// check need call auto tab
if
(
cnt
>
0
&&
waitAutoFill
)
{
// press tab key by program
firstMatchCommand
(
varCon
,
varCmd
);
...
...
@@ -949,11 +825,10 @@ char* matchNextPrefix(STire* tire, char* pre) {
// NOT EMPTY
match
=
matchPrefix
(
tire
,
pre
,
NULL
);
}
// save to lastMatch
if
(
match
)
{
if
(
lastMatch
)
freeMatch
(
lastMatch
);
if
(
lastMatch
)
freeMatch
(
lastMatch
);
lastMatch
=
match
;
}
}
...
...
@@ -967,11 +842,11 @@ char* matchNextPrefix(STire* tire, char* pre) {
if
(
cursorVar
==
-
1
)
{
// first
cursorVar
=
0
;
return
strdup
(
match
->
head
->
word
);
return
strdup
(
match
->
head
->
word
);
}
// according to cursorVar , calculate next one
int
i
=
0
;
int
i
=
0
;
SMatchNode
*
item
=
match
->
head
;
while
(
item
)
{
if
(
i
==
cursorVar
+
1
)
{
...
...
@@ -1008,12 +883,11 @@ char* tireSearchWord(int type, char* pre) {
return
NULL
;
}
if
(
type
>
WT_FROM_DB_MAX
)
{
if
(
type
>
WT_FROM_DB_MAX
)
{
// NOT FROM DB , tires[type] alwary not null
STire
*
tire
=
tires
[
type
];
if
(
tire
==
NULL
)
return
NULL
;
return
matchNextPrefix
(
tire
,
pre
);
if
(
tire
==
NULL
)
return
NULL
;
return
matchNextPrefix
(
tire
,
pre
);
}
// TYPE CONTEXT GET FROM DB
...
...
@@ -1025,7 +899,7 @@ char* tireSearchWord(int type, char* pre) {
// need async obtain var names from db sever
if
(
threads
[
type
]
!=
NULL
)
{
if
(
taosThreadRunning
(
threads
[
type
]))
{
// thread running , need not obtain again, return
// thread running , need not obtain again, return
taosThreadMutexUnlock
(
&
tiresMutex
);
return
NULL
;
}
...
...
@@ -1033,10 +907,10 @@ char* tireSearchWord(int type, char* pre) {
taosDestroyThread
(
threads
[
type
]);
threads
[
type
]
=
NULL
;
}
// create new
void
*
param
=
taosMemoryMalloc
(
sizeof
(
int
));
*
((
int
*
)
param
)
=
type
;
void
*
param
=
taosMemoryMalloc
(
sizeof
(
int
));
*
((
int
*
)
param
)
=
type
;
threads
[
type
]
=
taosCreateThread
(
varObtainThread
,
param
);
taosThreadMutexUnlock
(
&
tiresMutex
);
return
NULL
;
...
...
@@ -1056,9 +930,9 @@ char* tireSearchWord(int type, char* pre) {
return
str
;
}
// match var word, word1 is pattern , word2 is input from shell
// match var word, word1 is pattern , word2 is input from shell
bool
matchVarWord
(
SWord
*
word1
,
SWord
*
word2
)
{
// search input word from tire tree
// search input word from tire tree
char
pre
[
512
];
memcpy
(
pre
,
word2
->
word
,
word2
->
len
);
pre
[
word2
->
len
]
=
0
;
...
...
@@ -1069,8 +943,7 @@ bool matchVarWord(SWord* word1, SWord* word2) {
str
=
tireSearchWord
(
WT_VAR_STABLE
,
pre
);
if
(
str
==
NULL
)
{
str
=
tireSearchWord
(
WT_VAR_TABLE
,
pre
);
if
(
str
==
NULL
)
return
false
;
if
(
str
==
NULL
)
return
false
;
}
}
else
{
// OTHER
...
...
@@ -1082,15 +955,15 @@ bool matchVarWord(SWord* word1, SWord* word2) {
}
// free previous malloc
if
(
word1
->
free
&&
word1
->
word
)
{
if
(
word1
->
free
&&
word1
->
word
)
{
taosMemoryFree
(
word1
->
word
);
}
// save
word1
->
word
=
str
;
word1
->
len
=
strlen
(
str
);
word1
->
free
=
true
;
// need free
word1
->
len
=
strlen
(
str
);
word1
->
free
=
true
;
// need free
return
true
;
}
...
...
@@ -1098,11 +971,10 @@ bool matchVarWord(SWord* word1, SWord* word2) {
// ------------------- match words --------------------------
//
// compare command cmd1 come from shellCommands , cmd2 come from user input
int32_t
compareCommand
(
SWords
*
cmd1
,
SWords
*
cmd2
)
{
SWord
*
word1
=
cmd1
->
head
;
SWord
*
word2
=
cmd2
->
head
;
int32_t
compareCommand
(
SWords
*
cmd1
,
SWords
*
cmd2
)
{
SWord
*
word1
=
cmd1
->
head
;
SWord
*
word2
=
cmd2
->
head
;
if
(
word1
==
NULL
||
word2
==
NULL
)
{
return
-
1
;
...
...
@@ -1112,8 +984,7 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) {
if
(
word1
->
type
==
WT_TEXT
)
{
// WT_TEXT match
if
(
word1
->
len
==
word2
->
len
)
{
if
(
strncasecmp
(
word1
->
word
,
word2
->
word
,
word1
->
len
)
!=
0
)
return
-
1
;
if
(
strncasecmp
(
word1
->
word
,
word2
->
word
,
word1
->
len
)
!=
0
)
return
-
1
;
}
else
if
(
word1
->
len
<
word2
->
len
)
{
return
-
1
;
}
else
{
...
...
@@ -1128,7 +999,7 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) {
}
}
else
{
// WT_VAR auto match any one word
if
(
word2
->
next
==
NULL
)
{
// input words last one
if
(
word2
->
next
==
NULL
)
{
// input words last one
if
(
matchVarWord
(
word1
,
word2
))
{
cmd1
->
matchIndex
=
i
;
cmd1
->
matchLen
=
word2
->
len
;
...
...
@@ -1151,10 +1022,10 @@ int32_t compareCommand(SWords * cmd1, SWords * cmd2) {
}
// match command
SWords
*
matchCommand
(
SWords
*
input
,
bool
continueSearch
)
{
SWords
*
matchCommand
(
SWords
*
input
,
bool
continueSearch
)
{
int32_t
count
=
SHELL_COMMAND_COUNT
();
for
(
int32_t
i
=
0
;
i
<
count
;
i
++
)
{
SWords
*
shellCommand
=
shellCommands
+
i
;
for
(
int32_t
i
=
0
;
i
<
count
;
i
++
)
{
SWords
*
shellCommand
=
shellCommands
+
i
;
if
(
continueSearch
&&
lastMatchIndex
!=
-
1
&&
i
<=
lastMatchIndex
)
{
// new match must greate than lastMatchIndex
if
(
varMode
&&
i
==
lastMatchIndex
)
{
...
...
@@ -1165,15 +1036,14 @@ SWords * matchCommand(SWords * input, bool continueSearch) {
}
// command is large
if
(
input
->
count
>
shellCommand
->
count
)
{
if
(
input
->
count
>
shellCommand
->
count
)
{
continue
;
}
// compare
int32_t
index
=
compareCommand
(
shellCommand
,
input
);
if
(
index
!=
-
1
)
{
if
(
firstMatchIndex
==
-
1
)
firstMatchIndex
=
i
;
if
(
firstMatchIndex
==
-
1
)
firstMatchIndex
=
i
;
curMatchIndex
=
i
;
return
&
shellCommands
[
i
];
}
...
...
@@ -1188,7 +1058,7 @@ SWords * matchCommand(SWords * input, bool continueSearch) {
//
// delete char count
void
deleteCount
(
SShellCmd
*
cmd
,
int
count
)
{
void
deleteCount
(
SShellCmd
*
cmd
,
int
count
)
{
int
size
=
0
;
int
width
=
0
;
int
prompt_size
=
6
;
...
...
@@ -1207,55 +1077,53 @@ void deleteCount(SShellCmd * cmd, int count) {
}
// show screen
void
printScreen
(
TAOS
*
con
,
SShellCmd
*
cmd
,
SWords
*
match
)
{
void
printScreen
(
TAOS
*
con
,
SShellCmd
*
cmd
,
SWords
*
match
)
{
// modify SShellCmd
if
(
firstMatchIndex
==
-
1
||
curMatchIndex
==
-
1
)
{
// no match
return
;
return
;
}
// first tab press
const
char
*
str
=
NULL
;
int
strLen
=
0
;
// first tab press
const
char
*
str
=
NULL
;
int
strLen
=
0
;
if
(
firstMatchIndex
==
curMatchIndex
&&
lastWordBytes
==
-
1
)
{
// first press tab
SWord
*
word
=
MATCH_WORD
(
match
);
SWord
*
word
=
MATCH_WORD
(
match
);
str
=
word
->
word
+
match
->
matchLen
;
strLen
=
word
->
len
-
match
->
matchLen
;
lastMatchIndex
=
firstMatchIndex
;
lastWordBytes
=
word
->
len
;
}
else
{
if
(
lastWordBytes
==
-
1
)
return
;
if
(
lastWordBytes
==
-
1
)
return
;
deleteCount
(
cmd
,
lastWordBytes
);
SWord
*
word
=
MATCH_WORD
(
match
);
SWord
*
word
=
MATCH_WORD
(
match
);
str
=
word
->
word
;
strLen
=
word
->
len
;
// set current to last
lastMatchIndex
=
curMatchIndex
;
lastWordBytes
=
word
->
len
;
}
// insert new
shellInsertChar
(
cmd
,
(
char
*
)
str
,
strLen
);
shellInsertChar
(
cmd
,
(
char
*
)
str
,
strLen
);
}
// main key press tab , matched return true else false
bool
firstMatchCommand
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
bool
firstMatchCommand
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
// parse command
SWords
*
input
=
(
SWords
*
)
taosMemoryMalloc
(
sizeof
(
SWords
));
SWords
*
input
=
(
SWords
*
)
taosMemoryMalloc
(
sizeof
(
SWords
));
memset
(
input
,
0
,
sizeof
(
SWords
));
input
->
source
=
cmd
->
command
;
input
->
source_len
=
cmd
->
commandSize
;
parseCommand
(
input
,
false
);
// if have many , default match first, if press tab again , switch to next
curMatchIndex
=
-
1
;
curMatchIndex
=
-
1
;
lastMatchIndex
=
-
1
;
SWords
*
match
=
matchCommand
(
input
,
true
);
SWords
*
match
=
matchCommand
(
input
,
true
);
if
(
match
==
NULL
)
{
// not match , nothing to do
freeCommand
(
input
);
...
...
@@ -1271,21 +1139,21 @@ bool firstMatchCommand(TAOS * con, SShellCmd * cmd) {
}
// create input source
void
createInputFromFirst
(
SWords
*
input
,
SWords
*
firstMatch
)
{
void
createInputFromFirst
(
SWords
*
input
,
SWords
*
firstMatch
)
{
//
// if next pressTabKey , input context come from firstMatch, set matched length with source_len
//
input
->
source
=
(
char
*
)
taosMemoryMalloc
(
1024
);
memset
((
void
*
)
input
->
source
,
0
,
1024
);
memset
((
void
*
)
input
->
source
,
0
,
1024
);
SWord
*
word
=
firstMatch
->
head
;
SWord
*
word
=
firstMatch
->
head
;
// source_len = full match word->len + half match with firstMatch->matchLen
// source_len = full match word->len + half match with firstMatch->matchLen
for
(
int
i
=
0
;
i
<
firstMatch
->
matchIndex
&&
word
;
i
++
)
{
// combine source from each word
strncpy
(
input
->
source
+
input
->
source_len
,
word
->
word
,
word
->
len
);
strcat
(
input
->
source
,
" "
);
// append blank splite
input
->
source_len
+=
word
->
len
+
1
;
// 1 is blank length
strcat
(
input
->
source
,
" "
);
// append blank splite
input
->
source_len
+=
word
->
len
+
1
;
// 1 is blank length
// move next
word
=
word
->
next
;
}
...
...
@@ -1297,11 +1165,11 @@ void createInputFromFirst(SWords* input, SWords * firstMatch) {
}
// user press Tabkey again is named next , matched return true else false
bool
nextMatchCommand
(
TAOS
*
con
,
SShellCmd
*
cmd
,
SWords
*
firstMatch
)
{
bool
nextMatchCommand
(
TAOS
*
con
,
SShellCmd
*
cmd
,
SWords
*
firstMatch
)
{
if
(
firstMatch
==
NULL
||
firstMatch
->
head
==
NULL
)
{
return
false
;
}
SWords
*
input
=
(
SWords
*
)
taosMemoryMalloc
(
sizeof
(
SWords
));
SWords
*
input
=
(
SWords
*
)
taosMemoryMalloc
(
sizeof
(
SWords
));
memset
(
input
,
0
,
sizeof
(
SWords
));
// create input from firstMatch
...
...
@@ -1311,16 +1179,15 @@ bool nextMatchCommand(TAOS * con, SShellCmd * cmd, SWords * firstMatch) {
parseCommand
(
input
,
false
);
// if have many , default match first, if press tab again , switch to next
SWords
*
match
=
matchCommand
(
input
,
true
);
SWords
*
match
=
matchCommand
(
input
,
true
);
if
(
match
==
NULL
)
{
// if not match , reset all index
firstMatchIndex
=
-
1
;
curMatchIndex
=
-
1
;
curMatchIndex
=
-
1
;
match
=
matchCommand
(
input
,
false
);
if
(
match
==
NULL
)
{
freeCommand
(
input
);
if
(
input
->
source
)
taosMemoryFree
(
input
->
source
);
if
(
input
->
source
)
taosMemoryFree
(
input
->
source
);
taosMemoryFree
(
input
);
return
false
;
}
...
...
@@ -1341,41 +1208,40 @@ bool nextMatchCommand(TAOS * con, SShellCmd * cmd, SWords * firstMatch) {
}
// fill with type
bool
fillWithType
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
pre
,
int
type
)
{
bool
fillWithType
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
pre
,
int
type
)
{
// get type
STire
*
tire
=
tires
[
type
];
char
*
str
=
matchNextPrefix
(
tire
,
pre
);
char
*
str
=
matchNextPrefix
(
tire
,
pre
);
if
(
str
==
NULL
)
{
return
false
;
}
// need insert part string
char
*
part
=
str
+
strlen
(
pre
);
char
*
part
=
str
+
strlen
(
pre
);
// show
int
count
=
strlen
(
part
);
shellInsertChar
(
cmd
,
part
,
count
);
cntDel
=
count
;
// next press tab delete current append count
cntDel
=
count
;
// next press tab delete current append count
taosMemoryFree
(
str
);
return
true
;
}
// fill with type
bool
fillTableName
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
pre
)
{
bool
fillTableName
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
pre
)
{
// search stable and table
char
*
str
=
tireSearchWord
(
WT_VAR_STABLE
,
pre
);
char
*
str
=
tireSearchWord
(
WT_VAR_STABLE
,
pre
);
if
(
str
==
NULL
)
{
str
=
tireSearchWord
(
WT_VAR_TABLE
,
pre
);
if
(
str
==
NULL
)
return
false
;
if
(
str
==
NULL
)
return
false
;
}
// need insert part string
char
*
part
=
str
+
strlen
(
pre
);
char
*
part
=
str
+
strlen
(
pre
);
// delete autofill count last append
if
(
cntDel
>
0
)
{
if
(
cntDel
>
0
)
{
deleteCount
(
cmd
,
cntDel
);
cntDel
=
0
;
}
...
...
@@ -1383,8 +1249,8 @@ bool fillTableName(TAOS * con, SShellCmd * cmd, char* pre) {
// show
int
count
=
strlen
(
part
);
shellInsertChar
(
cmd
,
part
,
count
);
cntDel
=
count
;
// next press tab delete current append count
cntDel
=
count
;
// next press tab delete current append count
taosMemoryFree
(
str
);
return
true
;
}
...
...
@@ -1396,20 +1262,20 @@ bool fillTableName(TAOS * con, SShellCmd * cmd, char* pre) {
// 2 select count(*),su -> select count(*), sum(
// 3 select count(*), su -> select count(*), sum(
//
char
*
lastWord
(
char
*
p
)
{
// get near from end revert find ' ' and ','
char
*
p1
=
strrchr
(
p
,
' '
);
char
*
p2
=
strrchr
(
p
,
','
);
char
*
lastWord
(
char
*
p
)
{
// get near from end revert find ' ' and ','
char
*
p1
=
strrchr
(
p
,
' '
);
char
*
p2
=
strrchr
(
p
,
','
);
if
(
p1
&&
p2
)
{
return
p1
>
p2
?
p1
:
p2
+
1
;
}
else
if
(
p1
)
{
return
p1
+
1
;
}
else
if
(
p2
)
{
}
else
if
(
p2
)
{
return
p2
+
1
;
}
else
{
return
p
;
}
}
}
bool
fieldsInputEnd
(
char
*
sql
)
{
...
...
@@ -1425,18 +1291,18 @@ bool fieldsInputEnd(char* sql) {
}
// not in ','
char
*
p3
=
strrchr
(
sql
,
','
);
char
*
p
=
p3
;
// like select ts, age,' '
char
*
p3
=
strrchr
(
sql
,
','
);
char
*
p
=
p3
;
// like select ts, age,' '
if
(
p
)
{
++
p
;
bool
allBlank
=
true
;
// after last ',' all char is blank
int
cnt
=
0
;
// blank count , like ' ' as one blank
char
*
plast
=
NULL
;
// last blank position
while
(
*
p
)
{
bool
allBlank
=
true
;
// after last ',' all char is blank
int
cnt
=
0
;
// blank count , like ' ' as one blank
char
*
plast
=
NULL
;
// last blank position
while
(
*
p
)
{
if
(
*
p
==
' '
)
{
plast
=
p
;
cnt
++
;
cnt
++
;
}
else
{
allBlank
=
false
;
}
...
...
@@ -1444,7 +1310,7 @@ bool fieldsInputEnd(char* sql) {
}
// any one word is not blank
if
(
allBlank
)
{
if
(
allBlank
)
{
return
false
;
}
...
...
@@ -1454,13 +1320,13 @@ bool fieldsInputEnd(char* sql) {
}
// if last char not ' ', then not end field, like 'select count(*), su' can fill sum(
if
(
sql
[
strlen
(
sql
)
-
1
]
!=
' '
&&
cnt
<=
1
)
{
if
(
sql
[
strlen
(
sql
)
-
1
]
!=
' '
&&
cnt
<=
1
)
{
return
false
;
}
}
char
*
p4
=
strrchr
(
sql
,
' '
);
if
(
p4
==
NULL
)
{
char
*
p4
=
strrchr
(
sql
,
' '
);
if
(
p4
==
NULL
)
{
// only one word
return
false
;
}
...
...
@@ -1469,9 +1335,9 @@ bool fieldsInputEnd(char* sql) {
}
// need insert from
bool
needInsertFrom
(
char
*
sql
,
int
len
)
{
// last is blank
if
(
sql
[
len
-
1
]
!=
' '
)
{
bool
needInsertFrom
(
char
*
sql
,
int
len
)
{
// last is blank
if
(
sql
[
len
-
1
]
!=
' '
)
{
// insert from keyword
return
false
;
}
...
...
@@ -1486,45 +1352,45 @@ bool needInsertFrom(char * sql, int len) {
}
// p is string following select keyword
bool
appendAfterSelect
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
sql
,
int32_t
len
)
{
bool
appendAfterSelect
(
TAOS
*
con
,
SShellCmd
*
cmd
,
char
*
sql
,
int32_t
len
)
{
char
*
p
=
strndup
(
sql
,
len
);
// union all
char
*
p1
;
char
*
p1
;
do
{
p1
=
strstr
(
p
,
UNION_ALL
);
if
(
p1
)
{
if
(
p1
)
{
p
=
p1
+
strlen
(
UNION_ALL
);
}
}
while
(
p1
);
char
*
from
=
strstr
(
p
,
" from "
);
//last word , maybe empty string or some letters of a string
char
*
last
=
lastWord
(
p
);
bool
ret
=
false
;
char
*
from
=
strstr
(
p
,
" from "
);
//
last word , maybe empty string or some letters of a string
char
*
last
=
lastWord
(
p
);
bool
ret
=
false
;
if
(
from
==
NULL
)
{
bool
fieldEnd
=
fieldsInputEnd
(
p
);
// cheeck fields input end then insert from keyword
if
(
fieldEnd
&&
p
[
len
-
1
]
==
' '
)
{
if
(
fieldEnd
&&
p
[
len
-
1
]
==
' '
)
{
shellInsertChar
(
cmd
,
"from"
,
4
);
taosMemoryFree
(
p
);
return
true
;
}
// fill funciton
if
(
fieldEnd
)
{
if
(
fieldEnd
)
{
// fields is end , need match keyword
ret
=
fillWithType
(
con
,
cmd
,
last
,
WT_VAR_KEYWORD
);
}
else
{
ret
=
fillWithType
(
con
,
cmd
,
last
,
WT_VAR_FUNC
);
}
taosMemoryFree
(
p
);
return
ret
;
}
// have from
char
*
blank
=
strstr
(
from
+
6
,
" "
);
char
*
blank
=
strstr
(
from
+
6
,
" "
);
if
(
blank
==
NULL
)
{
// no table name, need fill
ret
=
fillTableName
(
con
,
cmd
,
last
);
...
...
@@ -1538,13 +1404,12 @@ bool appendAfterSelect(TAOS * con, SShellCmd * cmd, char* sql, int32_t len) {
int32_t
searchAfterSelect
(
char
*
p
,
int32_t
len
)
{
// select * from st;
if
(
strncasecmp
(
p
,
"select "
,
7
)
==
0
)
{
if
(
strncasecmp
(
p
,
"select "
,
7
)
==
0
)
{
// check nest query
char
*
p1
=
p
+
7
;
while
(
1
)
{
char
*
p2
=
strstr
(
p1
,
"select "
);
if
(
p2
==
NULL
)
break
;
char
*
p1
=
p
+
7
;
while
(
1
)
{
char
*
p2
=
strstr
(
p1
,
"select "
);
if
(
p2
==
NULL
)
break
;
p1
=
p2
+
7
;
}
...
...
@@ -1552,29 +1417,29 @@ int32_t searchAfterSelect(char* p, int32_t len) {
}
// explain as select * from st;
if
(
strncasecmp
(
p
,
"explain select "
,
15
)
==
0
)
{
if
(
strncasecmp
(
p
,
"explain select "
,
15
)
==
0
)
{
return
15
;
}
char
*
as_pos_end
=
strstr
(
p
,
" as select "
);
if
(
as_pos_end
==
NULL
)
return
-
1
;
if
(
as_pos_end
==
NULL
)
return
-
1
;
as_pos_end
+=
11
;
// create stream <stream_name> as select
if
(
strncasecmp
(
p
,
"create stream "
,
14
)
==
0
)
{
return
as_pos_end
-
p
;;
if
(
strncasecmp
(
p
,
"create stream "
,
14
)
==
0
)
{
return
as_pos_end
-
p
;
;
}
// create topic <topic_name> as select
if
(
strncasecmp
(
p
,
"create topic "
,
13
)
==
0
)
{
if
(
strncasecmp
(
p
,
"create topic "
,
13
)
==
0
)
{
return
as_pos_end
-
p
;
}
return
-
1
;
}
bool
matchSelectQuery
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
bool
matchSelectQuery
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
// if continue press Tab , delete bytes by previous autofill
if
(
cntDel
>
0
)
{
deleteCount
(
cmd
,
cntDel
);
...
...
@@ -1582,8 +1447,8 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) {
}
// match select ...
int
len
=
cmd
->
commandSize
;
char
*
p
=
cmd
->
command
;
int
len
=
cmd
->
commandSize
;
char
*
p
=
cmd
->
command
;
// remove prefix blank
while
(
p
[
0
]
==
' '
&&
len
>
0
)
{
...
...
@@ -1592,17 +1457,16 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) {
}
// special range
if
(
len
<
7
||
len
>
512
)
{
if
(
len
<
7
||
len
>
512
)
{
return
false
;
}
// search
char
*
sql_cp
=
strndup
(
p
,
len
);
char
*
sql_cp
=
strndup
(
p
,
len
);
int32_t
n
=
searchAfterSelect
(
sql_cp
,
len
);
taosMemoryFree
(
sql_cp
);
if
(
n
==
-
1
||
n
>
len
)
return
false
;
p
+=
n
;
if
(
n
==
-
1
||
n
>
len
)
return
false
;
p
+=
n
;
len
-=
n
;
// append
...
...
@@ -1610,15 +1474,15 @@ bool matchSelectQuery(TAOS * con, SShellCmd * cmd) {
}
// if is input create fields or tags area, return true
bool
isCreateFieldsArea
(
char
*
p
)
{
char
*
left
=
strrchr
(
p
,
'('
);
bool
isCreateFieldsArea
(
char
*
p
)
{
char
*
left
=
strrchr
(
p
,
'('
);
if
(
left
==
NULL
)
{
// like 'create table st'
return
false
;
}
char
*
right
=
strrchr
(
p
,
')'
);
if
(
right
==
NULL
)
{
char
*
right
=
strrchr
(
p
,
')'
);
if
(
right
==
NULL
)
{
// like 'create table st( '
return
true
;
}
...
...
@@ -1631,7 +1495,7 @@ bool isCreateFieldsArea(char * p) {
return
false
;
}
bool
matchCreateTable
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
bool
matchCreateTable
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
// if continue press Tab , delete bytes by previous autofill
if
(
cntDel
>
0
)
{
deleteCount
(
cmd
,
cntDel
);
...
...
@@ -1639,8 +1503,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
}
// match select ...
int
len
=
cmd
->
commandSize
;
char
*
p
=
cmd
->
command
;
int
len
=
cmd
->
commandSize
;
char
*
p
=
cmd
->
command
;
// remove prefix blank
while
(
p
[
0
]
==
' '
&&
len
>
0
)
{
...
...
@@ -1649,12 +1513,12 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
}
// special range
if
(
len
<
7
||
len
>
1024
)
{
if
(
len
<
7
||
len
>
1024
)
{
return
false
;
}
// select and from
if
(
strncasecmp
(
p
,
"create table "
,
13
)
!=
0
)
{
// select and from
if
(
strncasecmp
(
p
,
"create table "
,
13
)
!=
0
)
{
// not select query clause
return
false
;
}
...
...
@@ -1662,8 +1526,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
len
-=
13
;
char
*
ps
=
strndup
(
p
,
len
);
bool
ret
=
false
;
char
*
last
=
lastWord
(
ps
);
bool
ret
=
false
;
char
*
last
=
lastWord
(
ps
);
// check in create fields or tags input area
if
(
isCreateFieldsArea
(
ps
))
{
...
...
@@ -1673,9 +1537,9 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
// tags
if
(
!
ret
)
{
// find only one ')' , can insert tags
char
*
p1
=
strchr
(
ps
,
')'
);
char
*
p1
=
strchr
(
ps
,
')'
);
if
(
p1
)
{
if
(
strchr
(
p1
+
1
,
')'
)
==
NULL
&&
strstr
(
p1
+
1
,
"tags"
)
==
NULL
)
{
if
(
strchr
(
p1
+
1
,
')'
)
==
NULL
&&
strstr
(
p1
+
1
,
"tags"
)
==
NULL
)
{
// can insert tags keyword
ret
=
fillWithType
(
con
,
cmd
,
last
,
WT_VAR_KEYTAGS
);
}
...
...
@@ -1685,9 +1549,9 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
// tb options
if
(
!
ret
)
{
// find like create talbe st (...) tags(..) <here is fill tb option area>
char
*
p1
=
strchr
(
ps
,
')'
);
// first ')' end
char
*
p1
=
strchr
(
ps
,
')'
);
// first ')' end
if
(
p1
)
{
if
(
strchr
(
p1
+
1
,
')'
))
{
// second ')' end
if
(
strchr
(
p1
+
1
,
')'
))
{
// second ')' end
// here is tb options area, can insert option
ret
=
fillWithType
(
con
,
cmd
,
last
,
WT_VAR_TBOPTION
);
}
...
...
@@ -1698,8 +1562,8 @@ bool matchCreateTable(TAOS * con, SShellCmd * cmd) {
return
ret
;
}
bool
matchOther
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
int
len
=
cmd
->
commandSize
;
bool
matchOther
(
TAOS
*
con
,
SShellCmd
*
cmd
)
{
int
len
=
cmd
->
commandSize
;
char
*
p
=
cmd
->
command
;
// '\\'
...
...
@@ -1711,8 +1575,7 @@ bool matchOther(TAOS * con, SShellCmd * cmd) {
}
// too small
if
(
len
<
8
)
return
false
;
if
(
len
<
8
)
return
false
;
// like 'from ( '
char
*
sql
=
strndup
(
p
,
len
);
...
...
@@ -1721,36 +1584,35 @@ bool matchOther(TAOS * con, SShellCmd * cmd) {
if
(
strcmp
(
last
,
"from("
)
==
0
)
{
fillWithType
(
con
,
cmd
,
""
,
WT_VAR_KEYSELECT
);
taosMemoryFree
(
sql
);
return
true
;
return
true
;
}
if
(
strncmp
(
last
,
"("
,
1
)
==
0
)
{
last
+=
1
;
last
+=
1
;
}
char
*
from
=
strstr
(
sql
,
" from"
);
// find last ' from'
while
(
from
)
{
char
*
p1
=
strstr
(
from
+
5
,
" from"
);
if
(
p1
==
NULL
)
break
;
if
(
p1
==
NULL
)
break
;
from
=
p1
;
}
if
(
from
)
{
// find next is '('
char
*
p2
=
from
+
5
;
bool
found
=
false
;
// found 'from ... ( ...' ... is any count of blank
bool
found1
=
false
;
// found '('
char
*
p2
=
from
+
5
;
bool
found
=
false
;
// found 'from ... ( ...' ... is any count of blank
bool
found1
=
false
;
// found '('
while
(
1
)
{
if
(
p2
==
last
||
*
p2
==
'\0'
)
{
if
(
p2
==
last
||
*
p2
==
'\0'
)
{
// last word or string end
if
(
found1
)
{
found
=
true
;
}
break
;
}
else
if
(
*
p2
==
'('
)
{
}
else
if
(
*
p2
==
'('
)
{
found1
=
true
;
}
else
if
(
*
p2
==
' '
)
{
}
else
if
(
*
p2
==
' '
)
{
// do nothing
}
else
{
// have any other char
...
...
@@ -1768,24 +1630,22 @@ bool matchOther(TAOS * con, SShellCmd * cmd) {
}
}
// INSERT
// INSERT
taosMemoryFree
(
sql
);
return
false
;
}
// main key press tab
void
pressTabKey
(
SShellCmd
*
cmd
)
{
// check
if
(
cmd
->
commandSize
==
0
)
{
void
pressTabKey
(
SShellCmd
*
cmd
)
{
// check
if
(
cmd
->
commandSize
==
0
)
{
// empty
showHelp
();
shellShowOnScreen
(
cmd
);
return
;
}
return
;
}
// save connection to global
varCmd
=
cmd
;
...
...
@@ -1793,45 +1653,41 @@ void pressTabKey(SShellCmd * cmd) {
// manual match like create table st( ...
matched
=
matchCreateTable
(
varCon
,
cmd
);
if
(
matched
)
return
;
if
(
matched
)
return
;
// shellCommands match
// shellCommands match
if
(
firstMatchIndex
==
-
1
)
{
matched
=
firstMatchCommand
(
varCon
,
cmd
);
}
else
{
matched
=
nextMatchCommand
(
varCon
,
cmd
,
&
shellCommands
[
firstMatchIndex
]);
}
if
(
matched
)
return
;
if
(
matched
)
return
;
// NOT MATCHED ANYONE
// match other like '\G' ...
matched
=
matchOther
(
varCon
,
cmd
);
if
(
matched
)
return
;
if
(
matched
)
return
;
// manual match like select * from ...
matched
=
matchSelectQuery
(
varCon
,
cmd
);
if
(
matched
)
return
;
if
(
matched
)
return
;
return
;
return
;
}
// press othr key
void
pressOtherKey
(
char
c
)
{
// reset global variant
firstMatchIndex
=
-
1
;
lastMatchIndex
=
-
1
;
curMatchIndex
=
-
1
;
lastWordBytes
=
-
1
;
lastMatchIndex
=
-
1
;
curMatchIndex
=
-
1
;
lastWordBytes
=
-
1
;
// var names
cursorVar
=
-
1
;
varMode
=
false
;
cursorVar
=
-
1
;
varMode
=
false
;
waitAutoFill
=
false
;
cntDel
=
0
;
cntDel
=
0
;
if
(
lastMatch
)
{
freeMatch
(
lastMatch
);
...
...
@@ -1840,18 +1696,18 @@ void pressOtherKey(char c) {
}
// put name into name, return name length
int
getWordName
(
char
*
p
,
char
*
name
,
int
nameLen
)
{
//remove prefix blank
int
getWordName
(
char
*
p
,
char
*
name
,
int
nameLen
)
{
//
remove prefix blank
while
(
*
p
==
' '
)
{
p
++
;
}
// get databases name;
int
i
=
0
;
while
(
p
[
i
]
!=
0
&&
i
<
nameLen
-
1
)
{
name
[
i
]
=
p
[
i
];
while
(
p
[
i
]
!=
0
&&
i
<
nameLen
-
1
)
{
name
[
i
]
=
p
[
i
];
i
++
;
if
(
p
[
i
]
==
' '
||
p
[
i
]
==
';'
||
p
[
i
]
==
'('
)
{
if
(
p
[
i
]
==
' '
||
p
[
i
]
==
';'
||
p
[
i
]
==
'('
)
{
// name end
break
;
}
...
...
@@ -1862,22 +1718,22 @@ int getWordName(char* p, char * name, int nameLen) {
}
// deal use db, if have 'use' return true
bool
dealUseDB
(
char
*
sql
)
{
// check use keyword
if
(
strncasecmp
(
sql
,
"use "
,
4
)
!=
0
)
{
bool
dealUseDB
(
char
*
sql
)
{
// check use keyword
if
(
strncasecmp
(
sql
,
"use "
,
4
)
!=
0
)
{
return
false
;
}
char
db
[
256
];
char
*
p
=
sql
+
4
;
char
db
[
256
];
char
*
p
=
sql
+
4
;
if
(
getWordName
(
p
,
db
,
sizeof
(
db
))
==
0
)
{
// no name , return
// no name , return
return
true
;
}
// dbName is previous use open db name
if
(
strcasecmp
(
db
,
dbName
)
==
0
)
{
// same , no need switch
// same , no need switch
return
true
;
}
...
...
@@ -1886,13 +1742,13 @@ bool dealUseDB(char * sql) {
// STABLE set null
STire
*
tire
=
tires
[
WT_VAR_STABLE
];
tires
[
WT_VAR_STABLE
]
=
NULL
;
if
(
tire
)
{
if
(
tire
)
{
freeTire
(
tire
);
}
// TABLE set null
tire
=
tires
[
WT_VAR_TABLE
];
tires
[
WT_VAR_TABLE
]
=
NULL
;
if
(
tire
)
{
if
(
tire
)
{
freeTire
(
tire
);
}
// save
...
...
@@ -1903,16 +1759,16 @@ bool dealUseDB(char * sql) {
}
// deal create, if have 'create' return true
bool
dealCreateCommand
(
char
*
sql
)
{
// check keyword
if
(
strncasecmp
(
sql
,
"create "
,
7
)
!=
0
)
{
bool
dealCreateCommand
(
char
*
sql
)
{
// check keyword
if
(
strncasecmp
(
sql
,
"create "
,
7
)
!=
0
)
{
return
false
;
}
char
name
[
1024
];
char
*
p
=
sql
+
7
;
char
name
[
1024
];
char
*
p
=
sql
+
7
;
if
(
getWordName
(
p
,
name
,
sizeof
(
name
))
==
0
)
{
// no name , return
// no name , return
return
true
;
}
...
...
@@ -1921,7 +1777,7 @@ bool dealCreateCommand(char * sql) {
if
(
strcasecmp
(
name
,
"database"
)
==
0
)
{
type
=
WT_VAR_DBNAME
;
}
else
if
(
strcasecmp
(
name
,
"table"
)
==
0
)
{
if
(
strstr
(
sql
,
" tags"
)
!=
NULL
&&
strstr
(
sql
,
" using "
)
==
NULL
)
if
(
strstr
(
sql
,
" tags"
)
!=
NULL
&&
strstr
(
sql
,
" using "
)
==
NULL
)
type
=
WT_VAR_STABLE
;
else
type
=
WT_VAR_TABLE
;
...
...
@@ -1932,7 +1788,7 @@ bool dealCreateCommand(char * sql) {
}
else
if
(
strcasecmp
(
name
,
"stream"
)
==
0
)
{
type
=
WT_VAR_STREAM
;
}
else
{
// no match , return
// no match , return
return
true
;
}
...
...
@@ -1941,7 +1797,7 @@ bool dealCreateCommand(char * sql) {
// get next word , that is table name
if
(
getWordName
(
p
,
name
,
sizeof
(
name
))
==
0
)
{
// no name , return
// no name , return
return
true
;
}
...
...
@@ -1949,7 +1805,7 @@ bool dealCreateCommand(char * sql) {
taosThreadMutexLock
(
&
tiresMutex
);
// STABLE set null
STire
*
tire
=
tires
[
type
];
if
(
tire
)
{
if
(
tire
)
{
insertWord
(
tire
,
name
);
}
taosThreadMutexUnlock
(
&
tiresMutex
);
...
...
@@ -1958,16 +1814,16 @@ bool dealCreateCommand(char * sql) {
}
// deal create, if have 'drop' return true
bool
dealDropCommand
(
char
*
sql
)
{
// check keyword
if
(
strncasecmp
(
sql
,
"drop "
,
5
)
!=
0
)
{
bool
dealDropCommand
(
char
*
sql
)
{
// check keyword
if
(
strncasecmp
(
sql
,
"drop "
,
5
)
!=
0
)
{
return
false
;
}
char
name
[
1024
];
char
*
p
=
sql
+
5
;
char
name
[
1024
];
char
*
p
=
sql
+
5
;
if
(
getWordName
(
p
,
name
,
sizeof
(
name
))
==
0
)
{
// no name , return
// no name , return
return
true
;
}
...
...
@@ -1986,7 +1842,7 @@ bool dealDropCommand(char * sql) {
}
else
if
(
strcasecmp
(
name
,
"stream"
)
==
0
)
{
type
=
WT_VAR_STREAM
;
}
else
{
// no match , return
// no match , return
return
true
;
}
...
...
@@ -1995,30 +1851,27 @@ bool dealDropCommand(char * sql) {
// get next word , that is table name
if
(
getWordName
(
p
,
name
,
sizeof
(
name
))
==
0
)
{
// no name , return
// no name , return
return
true
;
}
// switch new db
taosThreadMutexLock
(
&
tiresMutex
);
// STABLE set null
if
(
type
==
WT_VAR_ALLTABLE
)
{
if
(
type
==
WT_VAR_ALLTABLE
)
{
bool
del
=
false
;
// del in stable
STire
*
tire
=
tires
[
WT_VAR_STABLE
];
if
(
tire
)
del
=
deleteWord
(
tire
,
name
);
if
(
tire
)
del
=
deleteWord
(
tire
,
name
);
// del in table
if
(
!
del
)
{
if
(
!
del
)
{
tire
=
tires
[
WT_VAR_TABLE
];
if
(
tire
)
del
=
deleteWord
(
tire
,
name
);
if
(
tire
)
del
=
deleteWord
(
tire
,
name
);
}
}
else
{
// OTHER TYPE
STire
*
tire
=
tires
[
type
];
if
(
tire
)
deleteWord
(
tire
,
name
);
if
(
tire
)
deleteWord
(
tire
,
name
);
}
taosThreadMutexUnlock
(
&
tiresMutex
);
...
...
@@ -2027,26 +1880,26 @@ bool dealDropCommand(char * sql) {
// callback autotab module after shell sql execute
void
callbackAutoTab
(
char
*
sqlstr
,
TAOS
*
pSql
,
bool
usedb
)
{
char
*
sql
=
sqlstr
;
char
*
sql
=
sqlstr
;
// remove prefix blank
while
(
*
sql
==
' '
)
{
sql
++
;
}
if
(
dealUseDB
(
sql
))
{
if
(
dealUseDB
(
sql
))
{
// change to new db
return
;
return
;
}
// create command add name to autotab
if
(
dealCreateCommand
(
sql
))
{
return
;
if
(
dealCreateCommand
(
sql
))
{
return
;
}
// drop command remove name from autotab
if
(
dealDropCommand
(
sql
))
{
return
;
if
(
dealDropCommand
(
sql
))
{
return
;
}
return
;
return
;
}
tools/shell/src/shellTire.c
浏览文件 @
1c106bfd
...
...
@@ -22,414 +22,405 @@
// create prefix search tree
STire
*
createTire
(
char
type
)
{
STire
*
tire
=
taosMemoryMalloc
(
sizeof
(
STire
));
memset
(
tire
,
0
,
sizeof
(
STire
));
tire
->
ref
=
1
;
// init is 1
tire
->
type
=
type
;
tire
->
root
.
d
=
(
STireNode
**
)
taosMemoryCalloc
(
CHAR_CNT
,
sizeof
(
STireNode
*
));
return
tire
;
STire
*
tire
=
taosMemoryMalloc
(
sizeof
(
STire
));
memset
(
tire
,
0
,
sizeof
(
STire
));
tire
->
ref
=
1
;
// init is 1
tire
->
type
=
type
;
tire
->
root
.
d
=
(
STireNode
**
)
taosMemoryCalloc
(
CHAR_CNT
,
sizeof
(
STireNode
*
));
return
tire
;
}
// free tire node
void
freeTireNode
(
STireNode
*
node
)
{
if
(
node
==
NULL
)
return
;
// nest free sub node on array d
if
(
node
->
d
)
{
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
freeTireNode
(
node
->
d
[
i
]);
}
taosMemoryFree
(
node
->
d
);
if
(
node
==
NULL
)
return
;
// nest free sub node on array d
if
(
node
->
d
)
{
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
freeTireNode
(
node
->
d
[
i
]);
}
taosMemoryFree
(
node
->
d
);
}
// free self
taosMemoryFree
(
node
);
// free self
taosMemoryFree
(
node
);
}
// destroy prefix search tree
void
freeTire
(
STire
*
tire
)
{
// free nodes
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
freeTireNode
(
tire
->
root
.
d
[
i
]);
}
taosMemoryFree
(
tire
->
root
.
d
);
// free from list
StrName
*
item
=
tire
->
head
;
while
(
item
)
{
StrName
*
next
=
item
->
next
;
// free string
taosMemoryFree
(
item
->
name
);
// free node
taosMemoryFree
(
item
);
// move next
item
=
next
;
}
tire
->
head
=
tire
->
tail
=
NULL
;
// free tire
taosMemoryFree
(
tire
);
// free nodes
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
freeTireNode
(
tire
->
root
.
d
[
i
]);
}
taosMemoryFree
(
tire
->
root
.
d
);
// free from list
StrName
*
item
=
tire
->
head
;
while
(
item
)
{
StrName
*
next
=
item
->
next
;
// free string
taosMemoryFree
(
item
->
name
);
// free node
taosMemoryFree
(
item
);
// move next
item
=
next
;
}
tire
->
head
=
tire
->
tail
=
NULL
;
// free tire
taosMemoryFree
(
tire
);
}
// insert a new word to list
bool
insertToList
(
STire
*
tire
,
char
*
word
)
{
StrName
*
p
=
(
StrName
*
)
taosMemoryMalloc
(
sizeof
(
StrName
));
p
->
name
=
strdup
(
word
);
p
->
next
=
NULL
;
if
(
tire
->
head
==
NULL
)
{
tire
->
head
=
p
;
tire
->
tail
=
p
;
}
else
{
tire
->
tail
->
next
=
p
;
tire
->
tail
=
p
;
}
return
true
;
StrName
*
p
=
(
StrName
*
)
taosMemoryMalloc
(
sizeof
(
StrName
));
p
->
name
=
strdup
(
word
);
p
->
next
=
NULL
;
if
(
tire
->
head
==
NULL
)
{
tire
->
head
=
p
;
tire
->
tail
=
p
;
}
else
{
tire
->
tail
->
next
=
p
;
tire
->
tail
=
p
;
}
return
true
;
}
// insert a new word to tree
bool
insertToTree
(
STire
*
tire
,
char
*
word
,
int
len
)
{
int
m
=
0
;
STireNode
**
nodes
=
tire
->
root
.
d
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
m
=
word
[
i
]
-
FIRST_ASCII
;
if
(
m
<
0
||
m
>
CHAR_CNT
)
{
return
false
;
}
if
(
nodes
[
m
]
==
NULL
)
{
// no pointer
STireNode
*
p
=
(
STireNode
*
)
taosMemoryMalloc
(
sizeof
(
STireNode
));
memset
(
p
,
0
,
sizeof
(
STireNode
));
nodes
[
m
]
=
p
;
if
(
i
==
len
-
1
)
{
// is end
p
->
end
=
true
;
break
;
}
}
if
(
nodes
[
m
]
->
d
==
NULL
)
{
// malloc d
nodes
[
m
]
->
d
=
(
STireNode
**
)
taosMemoryCalloc
(
CHAR_CNT
,
sizeof
(
STireNode
*
));
}
// move to next node
nodes
=
nodes
[
m
]
->
d
;
int
m
=
0
;
STireNode
**
nodes
=
tire
->
root
.
d
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
m
=
word
[
i
]
-
FIRST_ASCII
;
if
(
m
<
0
||
m
>
CHAR_CNT
)
{
return
false
;
}
// add count
tire
->
count
+=
1
;
return
true
;
if
(
nodes
[
m
]
==
NULL
)
{
// no pointer
STireNode
*
p
=
(
STireNode
*
)
taosMemoryMalloc
(
sizeof
(
STireNode
));
memset
(
p
,
0
,
sizeof
(
STireNode
));
nodes
[
m
]
=
p
;
if
(
i
==
len
-
1
)
{
// is end
p
->
end
=
true
;
break
;
}
}
if
(
nodes
[
m
]
->
d
==
NULL
)
{
// malloc d
nodes
[
m
]
->
d
=
(
STireNode
**
)
taosMemoryCalloc
(
CHAR_CNT
,
sizeof
(
STireNode
*
));
}
// move to next node
nodes
=
nodes
[
m
]
->
d
;
}
// add count
tire
->
count
+=
1
;
return
true
;
}
// insert a new word
// insert a new word
bool
insertWord
(
STire
*
tire
,
char
*
word
)
{
int
len
=
strlen
(
word
);
if
(
len
>=
MAX_WORD_LEN
)
{
return
false
;
}
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
return
insertToTree
(
tire
,
word
,
len
);
case
TIRE_LIST
:
return
insertToList
(
tire
,
word
);
default:
break
;
}
int
len
=
strlen
(
word
);
if
(
len
>=
MAX_WORD_LEN
)
{
return
false
;
}
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
return
insertToTree
(
tire
,
word
,
len
);
case
TIRE_LIST
:
return
insertToList
(
tire
,
word
);
default:
break
;
}
return
false
;
}
// delete one word from list
bool
deleteFromList
(
STire
*
tire
,
char
*
word
)
{
StrName
*
item
=
tire
->
head
;
while
(
item
)
{
if
(
strcmp
(
item
->
name
,
word
)
==
0
)
{
// found, reset empty to delete
item
->
name
[
0
]
=
0
;
}
// move next
item
=
item
->
next
;
StrName
*
item
=
tire
->
head
;
while
(
item
)
{
if
(
strcmp
(
item
->
name
,
word
)
==
0
)
{
// found, reset empty to delete
item
->
name
[
0
]
=
0
;
}
return
true
;
// move next
item
=
item
->
next
;
}
return
true
;
}
// delete one word from tree
// delete one word from tree
bool
deleteFromTree
(
STire
*
tire
,
char
*
word
,
int
len
)
{
int
m
=
0
;
bool
del
=
false
;
STireNode
**
nodes
=
tire
->
root
.
d
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
m
=
word
[
i
]
-
FIRST_ASCII
;
if
(
m
<
0
||
m
>=
CHAR_CNT
)
{
return
false
;
}
if
(
nodes
[
m
]
==
NULL
)
{
// no found
return
false
;
}
else
{
// not null
if
(
i
==
len
-
1
)
{
// this is last, only set end false , not free node
nodes
[
m
]
->
end
=
false
;
del
=
true
;
break
;
}
}
if
(
nodes
[
m
]
->
d
==
NULL
)
break
;
// move to next node
nodes
=
nodes
[
m
]
->
d
;
int
m
=
0
;
bool
del
=
false
;
STireNode
**
nodes
=
tire
->
root
.
d
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
m
=
word
[
i
]
-
FIRST_ASCII
;
if
(
m
<
0
||
m
>=
CHAR_CNT
)
{
return
false
;
}
// reduce count
if
(
del
)
{
tire
->
count
-=
1
;
if
(
nodes
[
m
]
==
NULL
)
{
// no found
return
false
;
}
else
{
// not null
if
(
i
==
len
-
1
)
{
// this is last, only set end false , not free node
nodes
[
m
]
->
end
=
false
;
del
=
true
;
break
;
}
}
return
del
;
if
(
nodes
[
m
]
->
d
==
NULL
)
break
;
// move to next node
nodes
=
nodes
[
m
]
->
d
;
}
// reduce count
if
(
del
)
{
tire
->
count
-=
1
;
}
return
del
;
}
// insert a new word
// insert a new word
bool
deleteWord
(
STire
*
tire
,
char
*
word
)
{
int
len
=
strlen
(
word
);
if
(
len
>=
MAX_WORD_LEN
)
{
return
false
;
}
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
return
deleteFromTree
(
tire
,
word
,
len
);
case
TIRE_LIST
:
return
deleteFromList
(
tire
,
word
);
default:
break
;
}
int
len
=
strlen
(
word
);
if
(
len
>=
MAX_WORD_LEN
)
{
return
false
;
}
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
return
deleteFromTree
(
tire
,
word
,
len
);
case
TIRE_LIST
:
return
deleteFromList
(
tire
,
word
);
default:
break
;
}
return
false
;
}
void
addWordToMatch
(
SMatch
*
match
,
char
*
word
){
// malloc new
SMatchNode
*
node
=
(
SMatchNode
*
)
taosMemoryMalloc
(
sizeof
(
SMatchNode
));
memset
(
node
,
0
,
sizeof
(
SMatchNode
));
node
->
word
=
strdup
(
word
);
// append to match
if
(
match
->
head
==
NULL
)
{
match
->
head
=
match
->
tail
=
node
;
}
else
{
match
->
tail
->
next
=
node
;
match
->
tail
=
node
;
}
match
->
count
+=
1
;
void
addWordToMatch
(
SMatch
*
match
,
char
*
word
)
{
// malloc new
SMatchNode
*
node
=
(
SMatchNode
*
)
taosMemoryMalloc
(
sizeof
(
SMatchNode
));
memset
(
node
,
0
,
sizeof
(
SMatchNode
));
node
->
word
=
strdup
(
word
);
// append to match
if
(
match
->
head
==
NULL
)
{
match
->
head
=
match
->
tail
=
node
;
}
else
{
match
->
tail
->
next
=
node
;
match
->
tail
=
node
;
}
match
->
count
+=
1
;
}
// enum all words from node
void
enumAllWords
(
STireNode
**
nodes
,
char
*
prefix
,
SMatch
*
match
)
{
STireNode
*
c
;
char
word
[
MAX_WORD_LEN
];
int
len
=
strlen
(
prefix
);
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
c
=
nodes
[
i
];
if
(
c
==
NULL
)
{
// chain end node
continue
;
}
else
{
// combine word string
memset
(
word
,
0
,
sizeof
(
word
));
strcpy
(
word
,
prefix
);
word
[
len
]
=
FIRST_ASCII
+
i
;
// append current char
// chain middle node
if
(
c
->
end
)
{
// have end flag
addWordToMatch
(
match
,
word
);
}
// nested call next layer
if
(
c
->
d
)
enumAllWords
(
c
->
d
,
word
,
match
);
}
void
enumAllWords
(
STireNode
**
nodes
,
char
*
prefix
,
SMatch
*
match
)
{
STireNode
*
c
;
char
word
[
MAX_WORD_LEN
];
int
len
=
strlen
(
prefix
);
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
c
=
nodes
[
i
];
if
(
c
==
NULL
)
{
// chain end node
continue
;
}
else
{
// combine word string
memset
(
word
,
0
,
sizeof
(
word
));
strcpy
(
word
,
prefix
);
word
[
len
]
=
FIRST_ASCII
+
i
;
// append current char
// chain middle node
if
(
c
->
end
)
{
// have end flag
addWordToMatch
(
match
,
word
);
}
// nested call next layer
if
(
c
->
d
)
enumAllWords
(
c
->
d
,
word
,
match
);
}
}
}
// match prefix from list
void
matchPrefixFromList
(
STire
*
tire
,
char
*
prefix
,
SMatch
*
match
)
{
StrName
*
item
=
tire
->
head
;
int
len
=
strlen
(
prefix
);
while
(
item
)
{
if
(
strncmp
(
item
->
name
,
prefix
,
len
)
==
0
)
{
// prefix matched
addWordToMatch
(
match
,
item
->
name
);
}
// move next
item
=
item
->
next
;
StrName
*
item
=
tire
->
head
;
int
len
=
strlen
(
prefix
);
while
(
item
)
{
if
(
strncmp
(
item
->
name
,
prefix
,
len
)
==
0
)
{
// prefix matched
addWordToMatch
(
match
,
item
->
name
);
}
// move next
item
=
item
->
next
;
}
}
// match prefix words, if match is not NULL , put all item to match and return match
void
matchPrefixFromTree
(
STire
*
tire
,
char
*
prefix
,
SMatch
*
match
)
{
SMatch
*
root
=
match
;
int
m
=
0
;
STireNode
*
c
=
0
;
int
len
=
strlen
(
prefix
);
if
(
len
>=
MAX_WORD_LEN
)
{
return
;
SMatch
*
root
=
match
;
int
m
=
0
;
STireNode
*
c
=
0
;
int
len
=
strlen
(
prefix
);
if
(
len
>=
MAX_WORD_LEN
)
{
return
;
}
STireNode
**
nodes
=
tire
->
root
.
d
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
m
=
prefix
[
i
]
-
FIRST_ASCII
;
if
(
m
<
0
||
m
>
CHAR_CNT
)
{
return
;
}
STireNode
**
nodes
=
tire
->
root
.
d
;
for
(
int
i
=
0
;
i
<
len
;
i
++
)
{
m
=
prefix
[
i
]
-
FIRST_ASCII
;
if
(
m
<
0
||
m
>
CHAR_CNT
)
{
return
;
}
// match
c
=
nodes
[
m
];
if
(
c
==
NULL
)
{
// arrive end
break
;
}
// previous items already matched
if
(
i
==
len
-
1
)
{
// malloc match if not pass by param match
if
(
root
==
NULL
)
{
root
=
(
SMatch
*
)
taosMemoryMalloc
(
sizeof
(
SMatch
));
memset
(
root
,
0
,
sizeof
(
SMatch
));
strcpy
(
root
->
pre
,
prefix
);
}
// prefix is match to end char
if
(
c
->
d
)
enumAllWords
(
c
->
d
,
prefix
,
root
);
}
else
{
// move to next node continue match
if
(
c
->
d
==
NULL
)
break
;
nodes
=
c
->
d
;
}
}
// return
return
;
}
SMatch
*
matchPrefix
(
STire
*
tire
,
char
*
prefix
,
SMatch
*
match
)
{
if
(
match
==
NULL
)
{
match
=
(
SMatch
*
)
taosMemoryMalloc
(
sizeof
(
SMatch
));
memset
(
match
,
0
,
sizeof
(
SMatch
));
// match
c
=
nodes
[
m
];
if
(
c
==
NULL
)
{
// arrive end
break
;
}
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
matchPrefixFromTree
(
tire
,
prefix
,
match
);
case
TIRE_LIST
:
matchPrefixFromList
(
tire
,
prefix
,
match
);
default:
break
;
// previous items already matched
if
(
i
==
len
-
1
)
{
// malloc match if not pass by param match
if
(
root
==
NULL
)
{
root
=
(
SMatch
*
)
taosMemoryMalloc
(
sizeof
(
SMatch
));
memset
(
root
,
0
,
sizeof
(
SMatch
));
strcpy
(
root
->
pre
,
prefix
);
}
// prefix is match to end char
if
(
c
->
d
)
enumAllWords
(
c
->
d
,
prefix
,
root
);
}
else
{
// move to next node continue match
if
(
c
->
d
==
NULL
)
break
;
nodes
=
c
->
d
;
}
}
// return if need
if
(
match
->
count
==
0
)
{
freeMatch
(
match
);
match
=
NULL
;
}
return
match
;
// return
return
;
}
SMatch
*
matchPrefix
(
STire
*
tire
,
char
*
prefix
,
SMatch
*
match
)
{
if
(
match
==
NULL
)
{
match
=
(
SMatch
*
)
taosMemoryMalloc
(
sizeof
(
SMatch
));
memset
(
match
,
0
,
sizeof
(
SMatch
));
}
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
matchPrefixFromTree
(
tire
,
prefix
,
match
);
case
TIRE_LIST
:
matchPrefixFromList
(
tire
,
prefix
,
match
);
default:
break
;
}
// return if need
if
(
match
->
count
==
0
)
{
freeMatch
(
match
);
match
=
NULL
;
}
return
match
;
}
// get all items from tires tree
void
enumFromList
(
STire
*
tire
,
SMatch
*
match
)
{
StrName
*
item
=
tire
->
head
;
while
(
item
)
{
if
(
item
->
name
[
0
]
!=
0
)
{
// not delete
addWordToMatch
(
match
,
item
->
name
);
}
// move next
item
=
item
->
next
;
StrName
*
item
=
tire
->
head
;
while
(
item
)
{
if
(
item
->
name
[
0
]
!=
0
)
{
// not delete
addWordToMatch
(
match
,
item
->
name
);
}
// move next
item
=
item
->
next
;
}
}
// get all items from tires tree
void
enumFromTree
(
STire
*
tire
,
SMatch
*
match
)
{
char
pre
[
2
]
=
{
0
,
0
};
STireNode
*
c
;
// enum first layer
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
pre
[
0
]
=
FIRST_ASCII
+
i
;
// each node
c
=
tire
->
root
.
d
[
i
];
if
(
c
==
NULL
)
{
// this branch no data
continue
;
}
// this branch have data
if
(
c
->
end
)
addWordToMatch
(
match
,
pre
);
else
matchPrefix
(
tire
,
pre
,
match
);
char
pre
[
2
]
=
{
0
,
0
};
STireNode
*
c
;
// enum first layer
for
(
int
i
=
0
;
i
<
CHAR_CNT
;
i
++
)
{
pre
[
0
]
=
FIRST_ASCII
+
i
;
// each node
c
=
tire
->
root
.
d
[
i
];
if
(
c
==
NULL
)
{
// this branch no data
continue
;
}
// this branch have data
if
(
c
->
end
)
addWordToMatch
(
match
,
pre
);
else
matchPrefix
(
tire
,
pre
,
match
);
}
}
// get all items from tires tree
SMatch
*
enumAll
(
STire
*
tire
)
{
SMatch
*
match
=
(
SMatch
*
)
taosMemoryMalloc
(
sizeof
(
SMatch
));
memset
(
match
,
0
,
sizeof
(
SMatch
));
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
enumFromTree
(
tire
,
match
);
case
TIRE_LIST
:
enumFromList
(
tire
,
match
);
default:
break
;
}
// return if need
if
(
match
->
count
==
0
)
{
freeMatch
(
match
);
match
=
NULL
;
}
return
match
;
SMatch
*
match
=
(
SMatch
*
)
taosMemoryMalloc
(
sizeof
(
SMatch
));
memset
(
match
,
0
,
sizeof
(
SMatch
));
switch
(
tire
->
type
)
{
case
TIRE_TREE
:
enumFromTree
(
tire
,
match
);
case
TIRE_LIST
:
enumFromList
(
tire
,
match
);
default:
break
;
}
// return if need
if
(
match
->
count
==
0
)
{
freeMatch
(
match
);
match
=
NULL
;
}
return
match
;
}
// free match result
void
freeMatchNode
(
SMatchNode
*
node
)
{
// first free next
if
(
node
->
next
)
freeMatchNode
(
node
->
next
);
// second free self
if
(
node
->
word
)
taosMemoryFree
(
node
->
word
);
taosMemoryFree
(
node
);
// first free next
if
(
node
->
next
)
freeMatchNode
(
node
->
next
);
// second free self
if
(
node
->
word
)
taosMemoryFree
(
node
->
word
);
taosMemoryFree
(
node
);
}
// free match result
void
freeMatch
(
SMatch
*
match
)
{
// first free next
if
(
match
->
head
)
{
freeMatchNode
(
match
->
head
);
}
// second free self
taosMemoryFree
(
match
);
}
// first free next
if
(
match
->
head
)
{
freeMatchNode
(
match
->
head
);
}
// second free self
taosMemoryFree
(
match
);
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录