Skip to content

Commit

Permalink
Feature: 数据库表展示
Browse files Browse the repository at this point in the history
  • Loading branch information
YuS1aN committed Mar 7, 2024
1 parent a1e8398 commit 3435a14
Show file tree
Hide file tree
Showing 23 changed files with 598 additions and 43 deletions.
16 changes: 16 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/api/ApiService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package me.kbai.zhenxunui.api

import me.kbai.zhenxunui.model.BotBaseInfo
import me.kbai.zhenxunui.model.BotMessageCount
import me.kbai.zhenxunui.model.ExecuteSql
import me.kbai.zhenxunui.model.FriendListItem
import me.kbai.zhenxunui.model.GroupInfo
import me.kbai.zhenxunui.model.GroupListItem
Expand All @@ -12,6 +13,9 @@ import me.kbai.zhenxunui.model.PluginInfo
import me.kbai.zhenxunui.model.PluginSwitch
import me.kbai.zhenxunui.model.RequestListResult
import me.kbai.zhenxunui.model.SendMessage
import me.kbai.zhenxunui.model.SqlLog
import me.kbai.zhenxunui.model.TableColumn
import me.kbai.zhenxunui.model.TableListItem
import me.kbai.zhenxunui.model.UpdateGroup
import me.kbai.zhenxunui.model.UpdatePlugin
import me.kbai.zhenxunui.model.UserDetail
Expand Down Expand Up @@ -103,4 +107,16 @@ interface ApiService {

@POST("manage/send_message")
suspend fun sendMessage(@Body message: SendMessage): ApiResponse<*>

@GET("database/get_table_list")
suspend fun getTableList(): ApiResponse<List<TableListItem>>

@GET("database/get_table_column")
suspend fun getTableColumn(@Query("table_name") table: String): ApiResponse<List<TableColumn>>

@GET("database/get_sql_log")
suspend fun getSqlLog(): ApiResponse<List<SqlLog>>

@POST("database/exec_sql")
suspend fun executeSql(@Body sql: ExecuteSql): RawApiResponse
}
5 changes: 5 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/model/ExecuteSql.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package me.kbai.zhenxunui.model

data class ExecuteSql(
val sql: String
)
17 changes: 17 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/model/SqlLog.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package me.kbai.zhenxunui.model

import com.google.gson.annotations.SerializedName

data class SqlLog(
val id: Int,
/**
* The time for executed sql. sample: `2024-03-06T06:54:48.829937+00:00`
*/
@SerializedName("create_time")
val createTime: String,
@SerializedName("is_suc")
val success: Boolean,
val ip: String,
val result: String,
val sql: String
)
14 changes: 14 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/model/TableColumn.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package me.kbai.zhenxunui.model

import com.google.gson.annotations.SerializedName

data class TableColumn(
@SerializedName("column_name")
val name: String,
@SerializedName("data_type")
val type: String,
@SerializedName("max_length")
val maxLength: Int?,
@SerializedName("is_nullable")
val nullable: String
)
6 changes: 6 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/model/TableListItem.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package me.kbai.zhenxunui.model

data class TableListItem(
val name: String,
val desc: String?
)
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ object ApiRepository {
}
}

fun getTableList() = networkFlow { BotApi.service.getTableList() }

fun getTableColumn(table: String) = networkFlow { BotApi.service.getTableColumn(table) }

private fun <T> networkFlow(
tempData: T? = null,
f: suspend () -> ApiResponse<T>
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/me/kbai/zhenxunui/ui/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
R.id.nav_plugin,
R.id.nav_friend_list,
R.id.nav_request,
R.id.nav_db_manage,
// R.id.nav_info
), viewBinding.drawerLayout
)
Expand Down
43 changes: 43 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/ui/db/DbManageFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package me.kbai.zhenxunui.ui.db

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.fragment.app.viewModels
import me.kbai.zhenxunui.base.BaseFragment
import me.kbai.zhenxunui.databinding.FragmentDbManageBinding
import me.kbai.zhenxunui.extends.setOnDebounceClickListener
import me.kbai.zhenxunui.extends.viewLifecycleScope
import me.kbai.zhenxunui.viewmodel.DbManageViewModel

/**
* @author Sean on 2023/5/30
*/
class DbManageFragment : BaseFragment<FragmentDbManageBinding>() {

private val mViewModel by viewModels<DbManageViewModel>()

override fun getViewBinding(
inflater: LayoutInflater,
container: ViewGroup?
): FragmentDbManageBinding = FragmentDbManageBinding.inflate(inflater, container, false)

override fun initView() = viewBinding.run {

srlRefresh.setOnRefreshListener {
mViewModel.requestTableList()
}

btnSql.setOnDebounceClickListener {
//TODO
}
}

override fun initData() {
mViewModel.tables.observe(viewLifecycleOwner) {
viewBinding.srlRefresh.isRefreshing = false
viewBinding.rvTables.adapter = DbTableAdapter(it, mViewModel, viewLifecycleScope)
}

mViewModel.requestTableList()
}
}
69 changes: 69 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/ui/db/DbTableAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package me.kbai.zhenxunui.ui.db

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.core.view.size
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import me.kbai.zhenxunui.databinding.ItemDbManageTableBinding
import me.kbai.zhenxunui.extends.setOnDebounceClickListener
import me.kbai.zhenxunui.model.TableListItem
import me.kbai.zhenxunui.viewmodel.DbManageViewModel

class DbTableAdapter(
private val data: List<TableListItem>,
private val viewModel: DbManageViewModel,
private val coroutineScope: CoroutineScope
) : RecyclerView.Adapter<DbTableAdapter.ItemViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
ItemDbManageTableBinding.inflate(LayoutInflater.from(parent.context), parent, false)
)

override fun getItemCount() = data.size

override fun onBindViewHolder(holder: ItemViewHolder, position: Int) {
val item = data[position]

holder.binding.run {
tvTableName.text = item.name
tvDescription.text = item.desc

root.setOnDebounceClickListener {
elFields.toggleExpand()

if (rvFields.adapter != null) {
return@setOnDebounceClickListener
}
coroutineScope.launch {
viewModel.getColumns(item.name)
.collect {
if (!holder.recycled) {
pbWaiting.isVisible = false
rvFields.adapter = TableFieldAdapter(it)
rvFields.post { elFields.expand() }
}
}
}
}

rvFields.adapter = null
elFields.collapse(false)
pbWaiting.isVisible = true
holder.recycled = false
}
}

override fun onViewRecycled(holder: ItemViewHolder) {
holder.recycled = true
}

class ItemViewHolder(val binding: ItemDbManageTableBinding) :
RecyclerView.ViewHolder(binding.root) {
var recycled: Boolean = false
}
}
37 changes: 37 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/ui/db/TableFieldAdapter.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package me.kbai.zhenxunui.ui.db

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import me.kbai.zhenxunui.R
import me.kbai.zhenxunui.databinding.ItemDbManageFieldBinding
import me.kbai.zhenxunui.model.TableColumn

class TableFieldAdapter(
private val data: List<TableColumn>
) : RecyclerView.Adapter<TableFieldAdapter.ItemViewHolder>() {

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = ItemViewHolder(
ItemDbManageFieldBinding.inflate(
LayoutInflater.from(parent.context), parent, false
)
)

override fun getItemCount() = data.size

override fun onBindViewHolder(holder: ItemViewHolder, position: Int) = holder.binding.run {
val item = data[position]

tvName.text = item.name
tvType.text = item.type
tvMaxLength.text =
tvMaxLength.context.getString(
R.string.max_length_format,
item.maxLength?.toString().orEmpty()
)
tvNullable.text = tvNullable.context.getString(R.string.nullable_format, item.nullable)
}

class ItemViewHolder(val binding: ItemDbManageFieldBinding) :
RecyclerView.ViewHolder(binding.root)
}
19 changes: 0 additions & 19 deletions app/src/main/java/me/kbai/zhenxunui/ui/home/HomeFragment.kt

This file was deleted.

43 changes: 43 additions & 0 deletions app/src/main/java/me/kbai/zhenxunui/viewmodel/DbManageViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package me.kbai.zhenxunui.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import androidx.webkit.internal.ApiFeature.M
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import me.kbai.zhenxunui.extends.apiCollect
import me.kbai.zhenxunui.model.TableColumn
import me.kbai.zhenxunui.model.TableListItem
import me.kbai.zhenxunui.repository.ApiRepository

class DbManageViewModel : ViewModel() {

private val _tables: MutableLiveData<List<TableListItem>> = MutableLiveData()
val tables: LiveData<List<TableListItem>> = _tables

private val _columnMap: MutableMap<String, List<TableColumn>> = HashMap()

fun requestTableList() = viewModelScope.launch {
ApiRepository.getTableList().apiCollect {
if (it.success()) {
_tables.value = it.data ?: return@apiCollect
_columnMap.clear()
}
}
}

fun getColumns(table: String) = flow {
val data = _columnMap[table]
if (data != null) {
emit(data)
return@flow
}
val res = ApiRepository.getTableColumn(table).apiCollect()
if (res.success() && res.data != null) {
_columnMap[table] = res.data
emit(res.data)
}
}
}
Loading

0 comments on commit 3435a14

Please sign in to comment.