11<script setup lang="ts">
22import { ref , watch } from ' vue'
33import { API } from ' ./net'
4+ import type { Store } from ' ./store'
5+ import type { Pair } from ' ./types'
46import { ElMessage } from ' element-plus'
7+ import { Codemirror } from ' vue-codemirror'
8+ import HistoryInput from ' ../components/HistoryInput.vue'
59
6- const stores = ref ([])
10+ const stores = ref ([] as Store [] )
711const kind = ref (' ' )
812const store = ref (' ' )
913const sqlQuery = ref (' ' )
10- const queryResult = ref ([])
11- const columns = ref ([])
14+ const queryResult = ref ([] as any [])
15+ const queryResultAsJSON = ref (' ' )
16+ const columns = ref ([] as string [])
1217const queryTip = ref (' ' )
13- const databases = ref ([])
14- const tables = ref ([])
15- const currentDatabase = ref (' ' )
1618const loadingStores = ref (true )
19+ const dataFormat = ref (' table' )
20+ const dataFormatOptions = [' table' , ' json' ]
21+ const queryDataMeta = ref ({} as QueryDataMeta )
1722
18- const tablesTree = ref ([])
23+ interface TreeItem {
24+ label: string
25+ }
26+ const tablesTree = ref ([] as TreeItem [])
1927watch (store , (s ) => {
2028 kind .value = ' '
2129 stores .value .forEach ((e : Store ) => {
@@ -24,12 +32,28 @@ watch(store, (s) => {
2432 return
2533 }
2634 })
27- currentDatabase .value = ' '
35+ queryDataMeta .value . currentDatabase = ' '
2836 sqlQuery .value = ' '
2937 executeQuery ()
3038})
31- const queryDataFromTable = (data ) => {
32- sqlQuery .value = ` select * from ${data .label } limit 10 `
39+
40+ interface QueryDataMeta {
41+ databases: string []
42+ tables: string []
43+ currentDatabase: string
44+ duration: string
45+ labels: Pair []
46+ }
47+
48+ interface QueryData {
49+ items: any []
50+ data: any []
51+ label: string
52+ meta: QueryDataMeta
53+ }
54+
55+ const queryDataFromTable = (data : QueryData ) => {
56+ sqlQuery .value = ` @selectTableLImit100_${data .label } `
3357 executeQuery ()
3458}
3559const queryTables = () => {
@@ -61,43 +85,50 @@ API.GetStores((data) => {
6185 loadingStores .value = false
6286})
6387
64- const ormDataHandler = (data ) => {
65- const result = []
66- const cols = new Set ()
88+ const ormDataHandler = (data : QueryData ) => {
89+ const result = [] as any []
90+ const cols = new Set < string > ()
6791
6892 data .items .forEach (e => {
6993 const obj = {}
70- e .data .forEach (item => {
94+ e .data .forEach (( item : Pair ) => {
7195 obj [item .key ] = item .value
7296 cols .add (item .key )
7397 })
7498 result .push (obj )
7599 })
76100
77- databases .value = data .meta .databases
78- tables .value = data .meta .tables
79- currentDatabase .value = data .meta .currentDatabase
101+ data .meta .labels = data .meta .labels .filter ((item ) => {
102+ if (item .key === ' _native_sql' ) {
103+ sqlQuery .value = item .value
104+ return false
105+ }
106+ return ! item .key .startsWith (' _' )
107+ })
108+
109+ queryDataMeta .value = data .meta
80110 queryResult .value = result
111+ queryResultAsJSON .value = JSON .stringify (result , null , 2 )
81112 columns .value = Array .from (cols ).sort ((a , b ) => {
82113 if (a === ' id' ) return - 1 ;
83114 if (b === ' id' ) return 1 ;
84115 return a .localeCompare (b );
85116 })
86117
87118 tablesTree .value = []
88- tables .value .forEach ((i ) => {
119+ queryDataMeta .value . tables .forEach ((i ) => {
89120 tablesTree .value .push ({
90121 label: i ,
91122 })
92123 })
93124}
94125
95- const keyValueDataHandler = (data ) => {
126+ const keyValueDataHandler = (data : QueryData ) => {
96127 queryResult .value = []
97128 data .data .forEach (e => {
98- const obj = {}
99- obj [ ' key' ] = e .key
100- obj [ ' value' ] = e .value
129+ const obj = new Map < string , string >();
130+ obj . set ( ' key' , e .key )
131+ obj . set ( ' value' , e .value )
101132 queryResult .value .push (obj )
102133
103134 columns .value = [' key' , ' value' ]
@@ -111,13 +142,14 @@ const executeQuery = async () => {
111142 break ;
112143 }
113144
114- API .DataQuery (store .value , kind .value , currentDatabase .value , sqlQuery .value , (data ) => {
145+ let success = false
146+ try {
147+ const data = await API .DataQueryAsync (store .value , kind .value , queryDataMeta .value .currentDatabase , sqlQuery .value );
115148 switch (kind .value ) {
116149 case ' atest-store-orm' :
117- ormDataHandler (data )
118- break ;
119150 case ' atest-store-iotdb' :
120151 ormDataHandler (data )
152+ success = true
121153 break ;
122154 case ' atest-store-etcd' :
123155 keyValueDataHandler (data )
@@ -132,23 +164,26 @@ const executeQuery = async () => {
132164 type: ' error'
133165 });
134166 }
135- }, ( e ) => {
167+ } catch ( e : any ) {
136168 ElMessage ({
137169 showClose: true ,
138170 message: e .message ,
139171 type: ' error'
140172 });
141- })
173+ }
174+ return success
142175}
143176 </script >
144177
145178<template >
146179 <div >
147- <el-container style =" height : calc (100vh - 45 px );" >
148- <el-aside v-if =" kind === 'atest-store-orm' || kind === 'atest-store-iotdb' " >
180+ <el-container style =" height : calc (100vh - 50 px );" >
181+ <el-aside v-if =" kind === 'atest-store-orm'" >
149182 <el-scrollbar >
150- <el-select v-model =" currentDatabase" placeholder =" Select database" @change =" queryTables" filterable >
151- <el-option v-for =" item in databases" :key =" item" :label =" item" :value =" item" ></el-option >
183+ <el-select v-model =" queryDataMeta.currentDatabase" placeholder =" Select database"
184+ @change =" queryTables" filterable >
185+ <el-option v-for =" item in queryDataMeta.databases" :key =" item" :label =" item"
186+ :value =" item" ></el-option >
152187 </el-select >
153188 <el-tree :data =" tablesTree" node-key =" label" @node-click =" queryDataFromTable" highlight-current
154189 draggable />
@@ -168,24 +203,35 @@ const executeQuery = async () => {
168203 </el-select >
169204 </el-form-item >
170205 </el-col >
171- <el-col :span =" 17 " >
206+ <el-col :span =" 16 " >
172207 <el-form-item >
173- <el-input v-model =" sqlQuery" :placeholder =" queryTip"
174- @keyup.enter =" executeQuery" ></el-input >
208+ <HistoryInput :placeholder =" queryTip" :callback =" executeQuery" v-model =" sqlQuery" />
175209 </el-form-item >
176210 </el-col >
177211 <el-col :span =" 2" >
178212 <el-form-item >
179213 <el-button type =" primary" @click =" executeQuery" >Execute</el-button >
180214 </el-form-item >
181215 </el-col >
216+ <el-col :span =" 2" >
217+ <el-select v-model =" dataFormat" placeholder =" Select data format" >
218+ <el-option v-for =" item in dataFormatOptions" :key =" item" :label =" item"
219+ :value =" item" ></el-option >
220+ </el-select >
221+ </el-col >
182222 </el-row >
183223 </el-form >
184224 </el-header >
185225 <el-main >
186- <el-table :data =" queryResult" >
187- <el-table-column v-for =" col in columns" :key =" col" :prop =" col" :label =" col" ></el-table-column >
226+ <div style =" display : flex ; gap : 8px ;" >
227+ <el-tag type =" primary" v-if =" queryResult.length > 0" >{{ queryResult.length }} rows</el-tag >
228+ <el-tag type =" primary" v-if =" queryDataMeta.duration" >{{ queryDataMeta.duration }}</el-tag >
229+ <el-tag type =" primary" v-for =" label in queryDataMeta.labels" >{{ label.value }}</el-tag >
230+ </div >
231+ <el-table :data =" queryResult" stripe v-if =" dataFormat === 'table'" >
232+ <el-table-column v-for =" col in columns" :key =" col" :prop =" col" :label =" col" sortable />
188233 </el-table >
234+ <Codemirror v-else-if =" dataFormat === 'json'" v-model =" queryResultAsJSON" />
189235 </el-main >
190236 </el-container >
191237 </el-container >
0 commit comments