Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more to schemas tab #23

Merged
merged 5 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/graphql-server/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Column {
name: String!
isPrimaryKey: Boolean!
type: String!
sourceTable: String
constraints: [ColConstraint!]
}

Expand Down Expand Up @@ -226,7 +227,9 @@ type Query {
docOrDefaultDoc(refName: String!, databaseName: String!, docType: DocType): Doc
rowDiffs(offset: Int, databaseName: String!, fromCommitId: String!, toCommitId: String!, refName: String, tableName: String!, filterByRowType: DiffRowType): RowDiffList!
rows(refName: String!, databaseName: String!, tableName: String!, offset: Int): RowList!
doltSchemas(databaseName: String!, refName: String!): RowList!
views(databaseName: String!, refName: String!): RowList!
doltProcedures(databaseName: String!, refName: String!): RowList
schemaDiff(databaseName: String!, fromCommitId: String!, toCommitId: String!, refName: String, tableName: String!): SchemaDiff
sqlSelect(refName: String!, databaseName: String!, queryString: String!): SqlSelect!
sqlSelectForCsvDownload(refName: String!, databaseName: String!, queryString: String!): String!
Expand Down
6 changes: 5 additions & 1 deletion packages/graphql-server/src/columns/column.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,19 @@ export class Column {
@Field()
type: string;

@Field({ nullable: true })
sourceTable?: string;

@Field(_type => [ColConstraint], { nullable: true })
constraints?: ColConstraint[];
}

export function fromDoltRowRes(col: RawRow): Column {
export function fromDoltRowRes(col: RawRow, tableName: string): Column {
return {
name: col.Field,
isPrimaryKey: col.Key === "PRI",
type: col.Type,
constraints: [{ notNull: col.Null === "NO" }],
sourceTable: tableName,
};
}
3 changes: 2 additions & 1 deletion packages/graphql-server/src/rowDiffs/rowDiff.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,12 @@ export function fromDoltListRowWithColsRes(
rows: RawRow[],
cols: RawRow[],
offset: number,
tableName: string,
): RowListWithCols {
return {
list: rows.slice(0, ROW_LIMIT).map(row.fromDoltRowRes),
nextOffset: getNextOffset(rows.length, offset),
columns: cols.map(columns.fromDoltRowRes),
columns: cols.map(c => columns.fromDoltRowRes(c, tableName)),
};
}

Expand Down
6 changes: 3 additions & 3 deletions packages/graphql-server/src/rowDiffs/rowDiff.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ export class RowDiffResolver {
]);

const colsUnion = unionCols(
oldCols.map(column.fromDoltRowRes),
newCols.map(column.fromDoltRowRes),
oldCols.map(c => column.fromDoltRowRes(c, fromTableName)),
newCols.map(c => column.fromDoltRowRes(c, toTableName)),
);

const diffType = convertToStringForQuery(args.filterByRowType);
Expand Down Expand Up @@ -129,5 +129,5 @@ async function getRowsForDiff(query: ParQuery, args: ListRowsArgs) {
ROW_LIMIT + 1,
offset,
]);
return fromDoltListRowWithColsRes(rows, columns, offset);
return fromDoltListRowWithColsRes(rows, columns, offset, args.tableName);
}
5 changes: 4 additions & 1 deletion packages/graphql-server/src/rows/row.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ import { RawRows } from "../utils/commonTypes";

export const getRowsQuery = (
columns: RawRows,
hasWhereCause = false,
): { q: string; cols: string[] } => {
const cols = getPKColsForRowsQuery(columns);
return {
q: `SELECT * FROM ?? ${getOrderByFromCols(cols.length)}LIMIT ? OFFSET ?`,
q: `SELECT * FROM ?? ${
hasWhereCause ? "WHERE type = ? " : ""
}${getOrderByFromCols(cols.length)}LIMIT ? OFFSET ?`,
cols,
};
};
Expand Down
38 changes: 35 additions & 3 deletions packages/graphql-server/src/rows/row.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Args, ArgsType, Field, Int, Query, Resolver } from "@nestjs/graphql";
import { handleTableNotFound } from "src/tables/table.resolver";
import { DataSourceService } from "../dataSources/dataSource.service";
import { DoltSystemTable } from "../systemTables/systemTable.enums";
import { listTablesQuery } from "../tables/table.queries";
Expand Down Expand Up @@ -40,11 +41,42 @@ export class RowResolver {
);
}

@Query(_returns => RowList)
async doltSchemas(
@Args() args: RefArgs,
type?: string,
): Promise<RowList | undefined> {
return this.dss.queryMaybeDolt(
async query => {
const tableName = DoltSystemTable.SCHEMAS;
const columns = await query(listTablesQuery, [tableName]);

const page = { columns, offset: 0 };
const { q, cols } = getRowsQuery(columns, !!type);

const params = [...cols, ROW_LIMIT + 1, page.offset];
const rows = await query(
q,
type ? [tableName, type, ...params] : [tableName, ...params],
);
return fromDoltListRowRes(rows, page.offset);
},
args.databaseName,
args.refName,
);
}

@Query(_returns => RowList)
async views(@Args() args: RefArgs): Promise<RowList | undefined> {
return this.rows({
return this.doltSchemas(args, "view");
}

@Query(_returns => RowList, { nullable: true })
async doltProcedures(@Args() args: RefArgs): Promise<RowList | undefined> {
const tableArgs = {
...args,
tableName: DoltSystemTable.SCHEMAS,
});
tableName: DoltSystemTable.PROCEDURES,
};
return handleTableNotFound(async () => this.rows(tableArgs));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export enum DoltSystemTable {
DOCS = "dolt_docs",
QUERY_CATALOG = "dolt_query_catalog",
SCHEMAS = "dolt_schemas",
PROCEDURES = "dolt_procedures",
}

export const systemTableValues = Object.values(DoltSystemTable);
2 changes: 1 addition & 1 deletion packages/graphql-server/src/tables/table.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function fromDoltRowRes(
databaseName,
refName,
tableName,
columns: columns.map(column.fromDoltRowRes),
columns: columns.map(c => column.fromDoltRowRes(c, tableName)),
foreignKeys: foreignKey.fromDoltRowsRes(fkRows),
indexes: index.fromDoltRowsRes(idxRows),
};
Expand Down
6 changes: 4 additions & 2 deletions packages/web/components/CellButtons/DropColumnButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ export default function DropColumnButton({ col, refName }: Props) {
const { params } = useDataTableContext();
const { tableName } = params;

if (!tableName || isDoltSystemTable(tableName)) return null;
if (!tableName || !col.sourceTable || isDoltSystemTable(tableName)) {
return null;
}

const onClick = async () => {
const query = dropColumnQuery(tableName, col.name);
const query = dropColumnQuery(col.sourceTable ?? tableName, col.name);
setEditorString(query);
await executeQuery({
...params,
Expand Down
3 changes: 1 addition & 2 deletions packages/web/components/CellButtons/HideColumnButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,9 @@ export default function HideColumnButton({ col, columns }: Props) {
const { executeQuery } = useSqlEditorContext();
const { params } = useDataTableContext();
const q = params.q ?? `SELECT * FROM \`${params.tableName}\``;
const colNames = columns.map(c => c.name);

const onClick = async () => {
const query = removeColumnFromQuery(q, col.name, colNames);
const query = removeColumnFromQuery(q, col.name, columns);
await executeQuery({ ...params, query });
};

Expand Down
12 changes: 5 additions & 7 deletions packages/web/components/DataTable/ShowAllColumns.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,19 @@ import css from "./index.module.css";

export default function ShowAllColumns() {
const { executeQuery } = useSqlEditorContext();
const { params } = useDataTableContext();
const { tableName } = params;
const { params, tableNames } = useDataTableContext();

if (!tableName) return null;
if (!params.tableName || tableNames.length > 1) return null;

const q = params.q ?? `SELECT * FROM \`${params.tableName}\``;
const cols = getColumns(q);
const col = getColumns(q);

if (!cols?.length || cols[0].expr.column === "*") return null;
if (!col?.length || col[0].expr.column === "*") return null;

const onClick = async () => {
const query = convertToSqlWithNewCols(q, "*", tableName);
const query = convertToSqlWithNewCols(q, "*", tableNames);
await executeQuery({ ...params, query });
};

return (
<Button.Underlined className={css.colsButton} onClick={onClick}>
Show all columns
Expand Down
2 changes: 1 addition & 1 deletion packages/web/components/DataTable/Table/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export default function Cell(props: Props): JSX.Element {
}}
/>
) : (
<span>{displayCellVal}</span>
<span onDoubleClick={() => setEditing(true)}>{displayCellVal}</span>
)}
{!editing && (
<CellDropdown
Expand Down
22 changes: 11 additions & 11 deletions packages/web/components/DatabaseTableNav/NavLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function NavLinks({ className, params }: Props) {
const router = useRouter();
const initialActiveIndex = getActiveIndexFromRouterQuery(router.query.active);
const { hideDoltFeature, loading } = useIsDolt();
const tabs = ["Tables", "Schemas", "Views"];
const tabs = ["Tables", "Views", "Schemas"];

return (
<div data-cy="db-page-table-nav" className={className}>
Expand Down Expand Up @@ -56,21 +56,21 @@ export default function NavLinks({ className, params }: Props) {
</CustomTabPanel>
<CustomTabPanel index={1}>
{params.refName ? (
<SchemaList params={{ ...params, refName: params.refName }} />
<NotDoltWrapper showNotDoltMsg feature="Listing views">
<Views params={{ ...params, refName: params.refName }} />
</NotDoltWrapper>
) : (
<p className={css.empty} data-cy="db-schemas-empty">
No schemas to show
<p className={css.empty} data-cy="db-views-empty">
No views to show
</p>
)}
</CustomTabPanel>
<CustomTabPanel index={2}>
{params.refName ? (
<NotDoltWrapper showNotDoltMsg feature="Listing views">
<Views params={{ ...params, refName: params.refName }} />
</NotDoltWrapper>
<SchemaList params={{ ...params, refName: params.refName }} />
) : (
<p className={css.empty} data-cy="db-views-empty">
No views to show
<p className={css.empty} data-cy="db-schemas-empty">
No schemas to show
</p>
)}
</CustomTabPanel>
Expand All @@ -93,9 +93,9 @@ function getActiveIndexFromRouterQuery(
switch (activeQuery) {
case "Tables":
return 0;
case "Schemas":
return 1;
case "Views":
return 1;
case "Schemas":
return 2;
default:
return 0;
Expand Down
2 changes: 1 addition & 1 deletion packages/web/components/DatabaseTableNav/index.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}

.openContainer {
@apply transition-width w-96 min-w-[22rem] duration-75;
@apply transition-width w-96 min-w-[24rem] duration-75;
flex-basis: 24rem;
}

Expand Down
4 changes: 2 additions & 2 deletions packages/web/components/HistoryTable/queryHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { removeClauses } from "@lib/doltSystemTables";
import {
convertToSqlWithNewCols,
convertToSqlWithNewColNames,
getColumns,
getTableName,
} from "@lib/parseSqlQuery";
Expand All @@ -26,7 +26,7 @@ export function getDoltHistoryQuery(q: string): string {

// SELECT [cols] FROM dolt_history_[tableName] WHERE [conditions];
const query = formatQuery(q);
return convertToSqlWithNewCols(query, cols, historyTableName);
return convertToSqlWithNewColNames(query, cols, historyTableName);
}

function formatQuery(q: string): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { SqlQueryParams } from "@lib/params";
import { MdPlayCircleOutline } from "@react-icons/all-files/md/MdPlayCircleOutline";
import dynamic from "next/dynamic";
import css from "./index.module.css";
import { getSchemaInfo } from "./util";

const AceEditor = dynamic(async () => import("@components/AceEditor"), {
ssr: false,
Expand All @@ -26,6 +27,7 @@ type InnerProps = Props & {
};

function Inner({ rows, params }: InnerProps) {
const { isView, fragIdx } = getSchemaInfo(params.q);
const { queryClickHandler } = useSqlEditorContext("Views");
const { isMobile } = useReactiveWidth(null, 1024);

Expand All @@ -40,7 +42,7 @@ function Inner({ rows, params }: InnerProps) {
}

const name = rows[0].columnValues[0].displayValue;
const fragment = rows[0].columnValues[1].displayValue;
const fragment = rows[0].columnValues[fragIdx].displayValue;

return (
<div className={css.top}>
Expand All @@ -56,16 +58,18 @@ function Inner({ rows, params }: InnerProps) {
height={isMobile ? "calc(100vh - 38rem)" : "calc(100vh - 28rem)"}
/>
<div className={css.buttons}>
<Btn className={css.play} onClick={async () => executeView(name)}>
<MdPlayCircleOutline />
</Btn>
{isView && (
<Btn className={css.play} onClick={async () => executeView(name)}>
<MdPlayCircleOutline />
</Btn>
)}
<CopyButton text={fragment} />
</div>
</div>
);
}

export default function ViewFragment(props: Props) {
export default function SchemaFragment(props: Props) {
const res = useSqlSelectForSqlDataTableQuery({
variables: { ...props.params, queryString: props.params.q },
});
Expand Down
16 changes: 16 additions & 0 deletions packages/web/components/SchemaFragment/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export function getSchemaInfo(q: string): { isView: boolean; fragIdx: number } {
const lower = q.toLowerCase();
if (lower.startsWith("show create view")) {
return { isView: true, fragIdx: 1 };
}
if (
lower.startsWith("show create trigger") ||
lower.startsWith("show create procedure")
) {
return { isView: false, fragIdx: 2 };
}
if (lower.startsWith("show create event")) {
return { isView: false, fragIdx: 3 };
}
return { isView: false, fragIdx: 0 };
}
Loading