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
1823const tablesTree = ref ([])
1924watch (store , (s ) => {
@@ -24,12 +29,27 @@ watch(store, (s) => {
2429 return
2530 }
2631 })
27- currentDatabase . value = ' '
32+ queryDataMeta . currentDatabase = ' '
2833 sqlQuery .value = ' '
2934 executeQuery ()
3035})
31- const queryDataFromTable = (data ) => {
32- sqlQuery .value = ` select * from ${data .label } limit 10 `
36+
37+ interface QueryDataMeta {
38+ databases: string []
39+ tables: string []
40+ currentDatabase: string
41+ duration: string
42+ }
43+
44+ interface QueryData {
45+ items: any []
46+ data: any []
47+ label: string
48+ meta: QueryDataMeta
49+ }
50+
51+ const queryDataFromTable = (data : QueryData ) => {
52+ sqlQuery .value = ` select * from ${data .label } limit 100 `
3353 executeQuery ()
3454}
3555const queryTables = () => {
@@ -61,43 +81,42 @@ API.GetStores((data) => {
6181 loadingStores .value = false
6282})
6383
64- const ormDataHandler = (data ) => {
65- const result = []
84+ const ormDataHandler = (data : QueryData ) => {
85+ const result = [] as any []
6686 const cols = new Set ()
6787
6888 data .items .forEach (e => {
6989 const obj = {}
70- e .data .forEach (item => {
90+ e .data .forEach (( item : Pair ) => {
7191 obj [item .key ] = item .value
7292 cols .add (item .key )
7393 })
7494 result .push (obj )
7595 })
7696
77- databases .value = data .meta .databases
78- tables .value = data .meta .tables
79- currentDatabase .value = data .meta .currentDatabase
97+ queryDataMeta .value = data .meta
8098 queryResult .value = result
99+ queryResultAsJSON .value = JSON .stringify (result , null , 2 )
81100 columns .value = Array .from (cols ).sort ((a , b ) => {
82101 if (a === ' id' ) return - 1 ;
83102 if (b === ' id' ) return 1 ;
84103 return a .localeCompare (b );
85104 })
86105
87106 tablesTree .value = []
88- tables .value .forEach ((i ) => {
107+ queryDataMeta .value . tables .forEach ((i ) => {
89108 tablesTree .value .push ({
90109 label: i ,
91110 })
92111 })
93112}
94113
95- const keyValueDataHandler = (data ) => {
114+ const keyValueDataHandler = (data : QueryData ) => {
96115 queryResult .value = []
97116 data .data .forEach (e => {
98- const obj = {}
99- obj [ ' key' ] = e .key
100- obj [ ' value' ] = e .value
117+ const obj = new Map < string , string >();
118+ obj . set ( ' key' , e .key )
119+ obj . set ( ' value' , e .value )
101120 queryResult .value .push (obj )
102121
103122 columns .value = [' key' , ' value' ]
@@ -111,10 +130,13 @@ const executeQuery = async () => {
111130 break ;
112131 }
113132
114- API .DataQuery (store .value , kind .value , currentDatabase .value , sqlQuery .value , (data ) => {
133+ let success = false
134+ try {
135+ const data = await API .DataQueryAsync (store .value , kind .value , queryDataMeta .value .currentDatabase , sqlQuery .value );
115136 switch (kind .value ) {
116137 case ' atest-store-orm' :
117138 ormDataHandler (data )
139+ success = true
118140 break ;
119141 case ' atest-store-etcd' :
120142 keyValueDataHandler (data )
@@ -129,23 +151,24 @@ const executeQuery = async () => {
129151 type: ' error'
130152 });
131153 }
132- }, ( e ) => {
154+ } catch ( e : any ) {
133155 ElMessage ({
134156 showClose: true ,
135157 message: e .message ,
136158 type: ' error'
137159 });
138- })
160+ }
161+ return success
139162}
140163 </script >
141164
142165<template >
143166 <div >
144- <el-container style =" height : calc (100vh - 45 px );" >
167+ <el-container style =" height : calc (100vh - 50 px );" >
145168 <el-aside v-if =" kind === 'atest-store-orm'" >
146169 <el-scrollbar >
147- <el-select v-model =" currentDatabase" placeholder =" Select database" @change =" queryTables" filterable >
148- <el-option v-for =" item in databases" :key =" item" :label =" item"
170+ <el-select v-model =" queryDataMeta. currentDatabase" placeholder =" Select database" @change =" queryTables" filterable >
171+ <el-option v-for =" item in queryDataMeta. databases" :key =" item" :label =" item"
149172 :value =" item" ></el-option >
150173 </el-select >
151174 <el-tree :data =" tablesTree" node-key =" label" @node-click =" queryDataFromTable" highlight-current draggable />
@@ -163,23 +186,34 @@ const executeQuery = async () => {
163186 </el-select >
164187 </el-form-item >
165188 </el-col >
166- <el-col :span =" 17 " >
189+ <el-col :span =" 16 " >
167190 <el-form-item >
168- <el-input v-model = " sqlQuery " :placeholder = " queryTip " @keyup.enter = " executeQuery " ></ el-input >
191+ <HistoryInput :placeholder = " queryTip " :callback = " executeQuery " v-model = " sqlQuery " / >
169192 </el-form-item >
170193 </el-col >
171194 <el-col :span =" 2" >
172195 <el-form-item >
173196 <el-button type =" primary" @click =" executeQuery" >Execute</el-button >
174197 </el-form-item >
175198 </el-col >
199+ <el-col :span =" 2" >
200+ <el-select v-model =" dataFormat" placeholder =" Select data format" >
201+ <el-option v-for =" item in dataFormatOptions" :key =" item" :label =" item" :value =" item" ></el-option >
202+ </el-select >
203+ </el-col >
176204 </el-row >
177205 </el-form >
178206 </el-header >
179207 <el-main >
180- <el-table :data =" queryResult" >
181- <el-table-column v-for =" col in columns" :key =" col" :prop =" col" :label =" col" ></el-table-column >
208+ <div style =" display : flex ; gap : 8px ;" >
209+ <el-tag type =" primary" v-if =" queryResult.length > 0" >{{ queryResult.length }} rows</el-tag >
210+ <el-tag type =" primary" v-if =" queryDataMeta.duration" >{{ queryDataMeta.duration }}</el-tag >
211+ </div >
212+ <el-table :data =" queryResult" stripe v-if =" dataFormat === 'table'" >
213+ <el-table-column v-for =" col in columns" :key =" col" :prop =" col" :label =" col" sortable />
182214 </el-table >
215+ <Codemirror v-else-if =" dataFormat === 'json'"
216+ v-model =" queryResultAsJSON" />
183217 </el-main >
184218 </el-container >
185219 </el-container >
0 commit comments