Skip to content

Commit

Permalink
feat: add list data and truncate table actions
Browse files Browse the repository at this point in the history
  • Loading branch information
invm authored and Michael Ionov committed Oct 1, 2023
1 parent 69edec8 commit 6ee5c73
Show file tree
Hide file tree
Showing 13 changed files with 114 additions and 54 deletions.
2 changes: 1 addition & 1 deletion src-tauri/src/handlers/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use serde_json::Value;
use tauri::{command, AppHandle};

#[command]
pub async fn execute_query(app_handle: AppHandle, conn_id: String, query: String) -> CommandResult<Value> {
pub async fn execute_query(app_handle: AppHandle, conn_id: String, query: String, _auto_limit: bool) -> CommandResult<Value> {
let connection = app_handle.acquire_connection(conn_id);
let result = connection.execute_query(query).await?;
Ok(result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export const QueryTextArea = (props: {
const [code, setCode] = createSignal("");
const [schema, setSchema] = createStore({});
const [loading, setLoading] = createSignal(false);
const [autoLimit, setAutoLimit] = createSignal(false);

const updateQueryText = async (query: string) => {
updateContentTab("data", { query });
Expand Down Expand Up @@ -105,6 +106,7 @@ export const QueryTextArea = (props: {
const { result_sets } = await invoke<QueryResult>("execute_query", {
connId: activeConnection.id,
query: selectedText || code(),
autoLimit: autoLimit(),
});
updateContentTab("data", { query: code(), executed: true, result_sets });
// console.log({ result_sets });
Expand Down Expand Up @@ -157,6 +159,17 @@ export const QueryTextArea = (props: {
onClick={copyQueryToClipboard}
icon={<Copy />}
/>
<div class="form-control">
<label class="cursor-pointer label">
<span class="label-text font-semibold mr-2">{t("components.console.actions.limit")}</span>
<input
type="checkbox"
checked={autoLimit()}
onChange={e => setAutoLimit(e.target.checked)}
class="checkbox checkbox-sm"
/>
</label>
</div>

<div
class="tooltip tooltip-primary tooltip-bottom"
Expand All @@ -168,7 +181,7 @@ export const QueryTextArea = (props: {
</span>
<input
type="checkbox"
class="toggle"
class="toggle toggle-sm"
classList={{
"toggle-success": vimModeOn(),
}}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Screens/Console/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { columnsToSchema } from "utils/utils";

export const Sidebar = () => {
const {
errors: { addError },
messages: { notify },
connections: {
getConnection,
updateConnectionTab,
Expand Down Expand Up @@ -49,7 +49,7 @@ export const Sidebar = () => {
});
console.log({ procedures });
} catch (error) {
addError(String(error));
notify(String(error), 'info');
} finally {
setLoading(false);
}
Expand Down
43 changes: 40 additions & 3 deletions src/components/Screens/Console/Sidebar/TableColumnsCollapse.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "services/Connections";

import { invoke } from "@tauri-apps/api";
import { QueryResult } from "interfaces";

export const TableColumnsCollapse = (props: {
title: string;
Expand All @@ -17,7 +18,7 @@ export const TableColumnsCollapse = (props: {

const {
connections: { addContentTab, getConnection },
errors: { addError },
messages: { notify },
} = useAppSelector();

const menu_id = "sidebar-table-menu";
Expand All @@ -27,14 +28,44 @@ export const TableColumnsCollapse = (props: {
props: { table: props.title },
});

const addTableStructureTab = async (table: string) => { try {
const addTableStructureTab = async (table: string) => {
try {
const data = await invoke<TableStructureContentTabData>(
"get_table_structure",
{ connId: getConnection().id, table }
);
addContentTab(newContentTab(table, "TableStructure", data));
} catch (error) {
addError(error);
notify(error);
}
};

const listData = async (table: string) => {
try {
const query = "SELECT * from " + table + " LIMIT 1000";
const { result_sets } = await invoke<QueryResult>("execute_query", {
connId: getConnection().id,
query,
autoLimit: true,
});
const data = { query, executed: true, result_sets };
addContentTab(newContentTab(table, "Query", data));
} catch (error) {
notify(error);
}
};

const truncateTable = async (table: string) => {
try {
const query = "TRUNCATE TABLE " + table;
await invoke<QueryResult>("execute_query", {
connId: getConnection().id,
query,
autoLimit: false,
});
notify(t("components.sidebar.table_was_truncated", { table }), "success");
} catch (error) {
notify(error);
}
};

Expand All @@ -47,6 +78,12 @@ export const TableColumnsCollapse = (props: {
<Item onClick={({ props }) => addTableStructureTab(props.table)}>
{t("components.sidebar.show_table_structure")}
</Item>
<Item onClick={({ props }) => listData(props.table)}>
{t("components.sidebar.list_data")}
</Item>
<Item onClick={({ props }) => truncateTable(props.table)}>
{t("components.sidebar.truncate_table")}
</Item>
</Menu>
<span
onClick={() => setOpen(!open())}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Screens/Home/Connections/AddConnectionForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ const AddConnectionForm = (props: {
}) => Promise<void>;
}) => {
const {
errors: { addError },
messages: { notify },
} = useAppSelector();
const formHandler = useFormHandler(zodSchema(ConnectionFormSchema));
const { formData, setFieldDefaultValue, getFormErrors, setFieldValue } =
Expand All @@ -159,7 +159,7 @@ const AddConnectionForm = (props: {
const { name, scheme, color } = formToConnectionStruct(formData());
await props.addConnection({ name, scheme, color });
} catch (error) {
addError((error as any).message);
notify((error as any).message);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { columnsToSchema } from "utils/utils";

export const ActionsMenu = (props: { connection: ConnectionConfig }) => {
const {
errors: { addError },
messages: { notify },
connections: { addConnectionTab },
} = useAppSelector();

Expand All @@ -24,7 +24,7 @@ export const ActionsMenu = (props: { connection: ConnectionConfig }) => {
connection: config,
});
} catch (error) {
addError(String(error));
notify(String(error));
}
};

Expand Down
6 changes: 4 additions & 2 deletions src/components/UI/Alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ export const AlertColors = {
error: 'text-error-content bg-error',
}

const Alert = (props: { children: any, color: keyof typeof AlertColors }) => {
export type AlertTypes = keyof typeof AlertColors;

const Alert = (props: { children: any, color: AlertTypes }) => {
return (
<div class={`flex px-2 py-1 items-center text-sm rounded-lg ${AlertColors[props.color]}`} role="alert">
<div class={`flex px-2 py-1 items-center text-lg rounded-lg ${AlertColors[props.color]}`} role="alert">
<svg aria-hidden="true" class="flex-shrink-0 inline w-5 h-5 mr-3" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"></path></svg>
<span class="sr-only">{props.color}</span>
<div>
Expand Down
23 changes: 13 additions & 10 deletions src/components/UI/Alerts.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
import { For } from "solid-js"
import { useAppSelector } from "../../services/Context"
import { For } from "solid-js";
import { useAppSelector } from "../../services/Context";
import { Alert } from "./Alert";

export const Alerts = () => {
const { errors: { errors } } = useAppSelector()
const {
messages: { messages },
} = useAppSelector();
return (
<div class="absolute">
<div class="toast">
<For each={errors}>
{error => (
<div class="alert alert-error py-1 px-2 rounded-lg">
<span class="text-sm font-medium">{error.message}</span>
</div>
<For each={messages}>
{(msg) => (
<Alert color={msg.type}>
<span class="font-medium">{msg.message}</span>
</Alert>
)}
</For>
</div>
</div>
)
}
);
};
4 changes: 2 additions & 2 deletions src/services/Connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ConnectionConfig, ResultSet, Row, Table, TableEntity } from "../interfa
import { Store } from "tauri-plugin-store-api";
import { debounce } from "utils/utils";
import { invoke } from "@tauri-apps/api";
import { ErrorService } from "./Error";
import { MessageService } from "./Messages";

const store = new Store(".connections.dat");
const INTERVAL = 1000;
Expand Down Expand Up @@ -138,7 +138,7 @@ export const ConnectionsService = () => {
return Promise.resolve([...res, conn]);
} catch (e) {
conn_tabs.idx = 0;
ErrorService().addError(e);
MessageService().notify(e);
return Promise.resolve(res);
}
}, Promise.resolve([] as ConnectionTab[]));
Expand Down
6 changes: 3 additions & 3 deletions src/services/Context.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { createContext, ParentComponent, useContext } from "solid-js";
import { ErrorService } from "./Error";
import { MessageService } from "./Messages";
import { ConnectionsService } from "./Connections";
import { AppService } from "./App";

export type RootState = {
errors: ReturnType<typeof ErrorService>;
messages: ReturnType<typeof MessageService>;
connections: ReturnType<typeof ConnectionsService>;
app: ReturnType<typeof AppService>;
};

const rootState: RootState = {
errors: ErrorService(),
messages: MessageService(),
connections: ConnectionsService(),
app: AppService(),
};
Expand Down
24 changes: 0 additions & 24 deletions src/services/Error.ts

This file was deleted.

25 changes: 25 additions & 0 deletions src/services/Messages.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { AlertTypes } from "components/UI";
import { createStore } from "solid-js/store";
import { randomId } from "utils/utils";

type Error = {
message: string;
id: string;
type: AlertTypes;
};

export const MessageService = () => {
const errorStore = createStore<Error[]>([]);
const [messages, setMessages] = errorStore;

const notify = (message: string | unknown, type: AlertTypes = 'error') => {
const id = randomId();
setMessages(messages.concat({ message: String(message), id, type }));

setTimeout(() => {
setMessages(messages.filter((e) => e.id !== id));
}, 5000);
};

return { messages, notify };
};
8 changes: 6 additions & 2 deletions src/utils/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,15 +39,19 @@
"format": "Format",
"execute": "Execute",
"vim_mode_on": "Vim mode on",
"copy_query": "Copy query to clipboard"
"copy_query": "Copy query to clipboard",
"limit": "LIMIT 1000"
},
"zero_results": "0 rows retuned",
"result_set": "Result set ",
"out_of": " out of "
},
"sidebar": {
"show_table_structure": "Show table structure",
"tables": "Tables"
"list_data": "List data",
"truncate_table": "Truncate table",
"tables": "Tables",
"table_was_truncated": "Table {{table}} was truncated"
},
"theme_switch": {
"theme": "Theme"
Expand Down

0 comments on commit 6ee5c73

Please sign in to comment.