Skip to content

Commit

Permalink
feat: add context menu on schemas dropdown, ui changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Ionov committed May 26, 2024
1 parent 8c5e5a8 commit 695934b
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 67 deletions.
11 changes: 11 additions & 0 deletions src-tauri/src/database/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::{self, Display, Formatter};

use serde::{Deserialize, Serialize};

pub mod init;
Expand All @@ -8,3 +10,12 @@ pub enum QueryType {
Select,
Other,
}

impl Display for QueryType {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
QueryType::Select => write!(f, "Select"),
QueryType::Other => write!(f, "Other"),
}
}
}
19 changes: 16 additions & 3 deletions src-tauri/src/handlers/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@ use tracing::info;

fn get_query_type(s: Statement) -> QueryType {
match s {
Statement::Query(_) => QueryType::Select,
Statement::Query(_)
| Statement::Explain { .. }
| Statement::Analyze { .. }
| Statement::ShowVariables { .. }
| Statement::ShowCreate { .. }
| Statement::ShowFunctions { .. }
| Statement::ShowCollation { .. }
| Statement::ShowVariable { .. }
| Statement::ShowColumns { .. }
| Statement::ShowStatus { .. }
| Statement::ShowTables { .. } => QueryType::Select,
//Statement::Insert { .. } => QueryType::Insert,
//Statement::Update { .. } => QueryType::Update,
//Statement::Delete { .. } => QueryType::Delete,
Expand Down Expand Up @@ -58,8 +68,10 @@ pub async fn enqueue_query(
let query_type = get_query_type(s.clone());
let mut statement = s.to_string();
if auto_limit
&& !statement.to_lowercase().contains("limit")
&& query_type == QueryType::Select
&& ["show", "analyze", "explain", "limit"]
.iter()
.all(|k| !statement.to_lowercase().contains(k))
{
statement = format!("{} LIMIT 1000", statement);
}
Expand Down Expand Up @@ -89,7 +101,7 @@ pub async fn enqueue_query(
if let Some(table) = task.table.clone() {
result_set.table = task.conn.get_table_metadata(&table).await.unwrap_or_default();
}
match write_query(&task.id, &result_set) {
match write_query(&task.id, &result_set, task.query_type) {
Ok(path) => {
handle
.emit_all(Events::QueryFinished.as_str(), QueryTaskResult::success(task, result_set, path))
Expand Down Expand Up @@ -155,6 +167,7 @@ pub async fn execute_query(
query: String,
) -> CommandResult<Value> {
let conn = app_handle.acquire_connection(conn_id);
info!(?query, "execute_query");
let statements = Parser::parse_sql(
dialect_from_str(conn.config.dialect.to_string())
.expect("Failed to get dialect")
Expand Down
5 changes: 3 additions & 2 deletions src-tauri/src/utils/fs.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::engine::types::result::ResultSet;
use crate::{database::QueryType, engine::types::result::ResultSet};
use anyhow::Result;
use fs::metadata;
use serde_json::json;
Expand Down Expand Up @@ -87,12 +87,13 @@ pub fn write_file(path: &PathBuf, content: &str) -> Result<()> {
Ok(())
}

pub fn write_query(id: &str, result_set: &ResultSet) -> Result<String> {
pub fn write_query(id: &str, result_set: &ResultSet, query_type: QueryType) -> Result<String> {
let mut rows = String::from("");
result_set.rows.iter().for_each(|row| {
rows += &(row.to_string() + "\n");
});
let metadata = json!({
"query_type": query_type.to_string(),
"start_time": result_set.start_time,
"end_time": result_set.end_time,
"count": result_set.rows.len(),
Expand Down
3 changes: 2 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ function App() {
<>
<Switch>
<Match when={loading()}>
<div class="flex justify-center items-center h-full bg-base-200 w-full">
<div class="flex justify-center flex-col gap-4 items-center h-full bg-base-200 w-full">
<Loader />
<div class="text-lg">{t('restoring_connections')}</div>
</div>
</Match>
<Match when={!loading()}>
Expand Down
17 changes: 12 additions & 5 deletions src/components/Screens/Console/Content/QueryTab/Results.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ export const Results = (props: {
count: result_set.count,
exhausted: rows.length < pageSizeVal,
path: result_set.path,
affectedRows: result_set.affected_rows,
queryType: result_set.query_type,
start_time,
end_time,
};
Expand Down Expand Up @@ -259,7 +261,7 @@ export const Results = (props: {
getConnection().idx
);
updateContentTab('data', {
result_sets: result_sets.map((id) => ({ id })),
result_sets: result_sets.map((id) => ({ id, loading: true })),
});
Object.keys(changes).forEach((key) => {
const count = Object.keys(changes[key as keyof typeof changes]).length;
Expand Down Expand Up @@ -377,20 +379,25 @@ export const Results = (props: {
onNextPage,
onPrevPage,
loading: data.loading,
hasResults: !!data()?.rows.length,
query: {
hasResults: !!data()?.rows.length,
executionTime:
(data()?.end_time ?? 0) - (data()?.start_time ?? 0),
count: data()?.count ?? 0,
affectedRows: data()?.affectedRows ?? 0,
queryType: data()?.queryType ?? 'Select',
},
onPageSizeChange,
onBtnExport,
count: data()?.count ?? 0,
openDrawerForm: props.editable ? openDrawerForm : undefined,
executionTime: (data()?.end_time ?? 0) - (data()?.start_time ?? 0),
}}
/>
<Search table={table.name} columns={table.columns} />
</div>
<div class={'ag-theme-' + props.gridTheme} style={{ height: '100%' }}>
<AgGridSolid
noRowsOverlayComponent={() =>
data()?.notReady ? (
data()?.notReady || data()?.queryType === 'Other' ? (
<Keymaps short />
) : (
<NoResults error={data()?.error} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createShortcut } from '@solid-primitives/keyboard';
import { Accessor, createEffect, For, Match, Show, Switch } from 'solid-js';
import { createStore } from 'solid-js/store';
import { ResultSet } from 'interfaces';
import { QueryType, ResultSet } from 'interfaces';
import { ChevronLeft, ChevronRight } from 'components/UI/Icons';
import { Alert } from 'components/UI';
import { useAppSelector } from 'services/Context';
Expand All @@ -12,16 +12,20 @@ type PaginationProps = {
page: Accessor<number>;
loading: boolean;
changesCount: number;
hasResults: boolean;
onPageSizeChange: () => void;
onPrevPage: () => void;
onNextPage: () => void;
onBtnExport: (t: 'csv' | 'json') => void;
applyChanges: () => void;
undoChanges: () => void;
count: number;
openDrawerForm?: (s: Pick<DrawerState, 'mode' | 'rowIndex' | 'data'>) => void;
executionTime?: number;
query: {
hasResults: boolean;
count: number;
executionTime?: number;
affectedRows?: number;
queryType: QueryType;
};
};

const PAGE_SIZE_OPTIONS = [10, 25, 50, 100];
Expand Down Expand Up @@ -95,9 +99,9 @@ export const Pagination = (props: PaginationProps) => {
</div>
</Show>

<Show when={props.count > 0}>
<Show when={props.query.count > 0}>
<span class="text-xs text-base-content">
{t('console.table.total_rows')} {props.count}
{t('console.table.total_rows')} {props.query.count}
</span>
</Show>
<Show when={props.openDrawerForm}>
Expand All @@ -117,9 +121,17 @@ export const Pagination = (props: PaginationProps) => {
</button>
</div>
</Show>
<Show when={props.executionTime}>
<Show when={props.query.executionTime}>
<span class="text-xs font-medium">
{t('console.table.ran', { duration: props.executionTime })}
{t('console.table.ran', { duration: props.query.executionTime })}
</span>
</Show>
<Show when={props.query.queryType === 'Other'}>
<span class="font-medium">|</span>
<span class="text-xs font-medium">
{t('console.table.affected_rows', {
rows: props.query.affectedRows,
})}
</span>
</Show>
</div>
Expand All @@ -144,7 +156,7 @@ export const Pagination = (props: PaginationProps) => {
</button>
</div>
</Show>
<Show when={props.hasResults}>
<Show when={props.query.hasResults}>
<button
class="btn btn-ghost btn-xs"
onClick={(_) => props.onBtnExport('csv')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ export const Search = (props: SearchProps) => {
tabIdx: conn.idx,
table: props.table,
});
const result_sets = res.map((id) => ({ id, columns: props.columns, table: props.table }));
const result_sets = res.map((id) => ({ id, loading: true, columns: props.columns, table: props.table }));
updateContentTab('data', { result_sets });
} catch (error) {
notify(error);
Expand Down
Loading

0 comments on commit 695934b

Please sign in to comment.