Skip to content

Commit

Permalink
web,graphql: Refactor schemas and procedures
Browse files Browse the repository at this point in the history
  • Loading branch information
tbantle22 committed Oct 31, 2023
1 parent 907a327 commit 69606f0
Show file tree
Hide file tree
Showing 18 changed files with 153 additions and 168 deletions.
11 changes: 8 additions & 3 deletions packages/graphql-server/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ type SchemaDiff {
numChangedSchemas: Int
}

type SchemaItem {
name: String!
type: String!
}

type SqlSelect {
_id: ID!
databaseName: String!
Expand Down Expand Up @@ -227,10 +232,10 @@ 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
doltSchemas(databaseName: String!, refName: String!): [SchemaItem!]!
views(databaseName: String!, refName: String!): [SchemaItem!]!
doltProcedures(databaseName: String!, refName: String!): [SchemaItem!]!
sqlSelect(refName: String!, databaseName: String!, queryString: String!): SqlSelect!
sqlSelectForCsvDownload(refName: String!, databaseName: String!, queryString: String!): String!
status(databaseName: String!, refName: String!): [Status!]!
Expand Down
2 changes: 2 additions & 0 deletions packages/graphql-server/src/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DocsResolver } from "./docs/doc.resolver";
import { RowDiffResolver } from "./rowDiffs/rowDiff.resolver";
import { RowResolver } from "./rows/row.resolver";
import { SchemaDiffResolver } from "./schemaDiffs/schemaDiff.resolver";
import { SchemaResolver } from "./schemas/schema.resolver";
import { SqlSelectResolver } from "./sqlSelects/sqlSelect.resolver";
import { StatusResolver } from "./status/status.resolver";
import { TableResolver } from "./tables/table.resolver";
Expand All @@ -24,6 +25,7 @@ const resolvers = [
RowDiffResolver,
RowResolver,
SchemaDiffResolver,
SchemaResolver,
SqlSelectResolver,
StatusResolver,
TableResolver,
Expand Down
5 changes: 1 addition & 4 deletions packages/graphql-server/src/rows/row.queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import { RawRows } from "../utils/commonTypes";

export const getRowsQuery = (
columns: RawRows,
hasWhereCause = false,
): { q: string; cols: string[] } => {
const cols = getPKColsForRowsQuery(columns);
return {
q: `SELECT * FROM ?? ${
hasWhereCause ? "WHERE type = ? " : ""
}${getOrderByFromCols(cols.length)}LIMIT ? OFFSET ?`,
q: `SELECT * FROM ?? ${getOrderByFromCols(cols.length)}LIMIT ? OFFSET ?`,
cols,
};
};
Expand Down
41 changes: 0 additions & 41 deletions packages/graphql-server/src/rows/row.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,7 +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";
import { ROW_LIMIT } from "../utils";
import { RefArgs } from "../utils/commonTypes";
Expand Down Expand Up @@ -40,43 +38,4 @@ export class RowResolver {
args.refName,
);
}

@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.doltSchemas(args, "view");
}

@Query(_returns => RowList, { nullable: true })
async doltProcedures(@Args() args: RefArgs): Promise<RowList | undefined> {
const tableArgs = {
...args,
tableName: DoltSystemTable.PROCEDURES,
};
return handleTableNotFound(async () => this.rows(tableArgs));
}
}
10 changes: 10 additions & 0 deletions packages/graphql-server/src/schemas/schema.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Field, ObjectType } from "@nestjs/graphql";

@ObjectType()
export class SchemaItem {
@Field()
name: string;

@Field()
type: string;
}
8 changes: 8 additions & 0 deletions packages/graphql-server/src/schemas/schema.queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { DoltSystemTable } from "../systemTables/systemTable.enums";

export const getDoltSchemasQuery = (hasWhereCause = false): string =>
`SELECT * FROM ${DoltSystemTable.SCHEMAS}${
hasWhereCause ? " WHERE type = ?" : ""
}`;

export const doltProceduresQuery = `SELECT * FROM ${DoltSystemTable.PROCEDURES}`;
53 changes: 53 additions & 0 deletions packages/graphql-server/src/schemas/schema.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Args, Query, Resolver } from "@nestjs/graphql";
import { handleTableNotFound } from "src/tables/table.resolver";
import { DataSourceService } from "../dataSources/dataSource.service";
import { RefArgs } from "../utils/commonTypes";
import { SchemaItem } from "./schema.model";
import { doltProceduresQuery, getDoltSchemasQuery } from "./schema.queries";

@Resolver(_of => SchemaItem)
export class SchemaResolver {
constructor(private readonly dss: DataSourceService) {}

@Query(_returns => [SchemaItem])
async doltSchemas(
@Args() args: RefArgs,
type?: string,
): Promise<SchemaItem[]> {
return this.dss.queryMaybeDolt(
async (query, isDolt) => {
const res = await handleTableNotFound(async () =>
query(getDoltSchemasQuery(!!type), [type]),
);
if (!res) return [];
return res.map(r => {
return { name: r.name, type: r.type };
});
},
args.databaseName,
args.refName,
);
}

@Query(_returns => [SchemaItem])
async views(@Args() args: RefArgs): Promise<SchemaItem[]> {
return this.doltSchemas(args, "view");
}

@Query(_returns => [SchemaItem])
async doltProcedures(@Args() args: RefArgs): Promise<[SchemaItem]> {
return this.dss.queryMaybeDolt(
async (query, isDolt) => {
const res = await handleTableNotFound(async () =>
query(doltProceduresQuery),
);
if (!res) return [];
return res.map(r => {
return { name: r.name, type: "procedure" };
});
},
args.databaseName,
args.refName,
);
}
}
8 changes: 3 additions & 5 deletions packages/web/components/CellButtons/HistoryButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useSqlEditorContext } from "@contexts/sqleditor";
import {
ColumnForDataTableFragment,
RowForDataTableFragment,
SchemaItemFragment,
} from "@gen/graphql-types";
import { isDoltSystemTable } from "@lib/doltSystemTables";
import { TableParams } from "@lib/params";
Expand Down Expand Up @@ -117,12 +118,9 @@ export default function HistoryButton(props: Props): JSX.Element | null {
);
}

function getIsView(
tableName: string,
views?: RowForDataTableFragment[],
): boolean {
function getIsView(tableName: string, views?: SchemaItemFragment[]): boolean {
if (!views) return false;
return views.some(v => v.columnValues[1].displayValue === tableName);
return views.some(v => v.name === tableName);
}

function queryHasMultipleTables(q?: string): boolean {
Expand Down
27 changes: 8 additions & 19 deletions packages/web/components/DatabaseTableNav/NavLinks.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import Loader from "@components/Loader";
import SchemaList from "@components/SchemaList";
import TableList from "@components/TableList";
import { Tab, TabList, TabPanel } from "@components/Tabs";
import { TabsProvider } from "@components/Tabs/context";
import Views from "@components/Views";
import NotDoltWrapper from "@components/util/NotDoltWrapper";
import useIsDolt from "@hooks/useIsDolt";
import { OptionalRefParams } from "@lib/params";
import { useRouter } from "next/router";
import { ReactNode } from "react";
Expand All @@ -22,24 +19,18 @@ type Props = {
export default function NavLinks({ className, params }: Props) {
const router = useRouter();
const initialActiveIndex = getActiveIndexFromRouterQuery(router.query.active);
const { hideDoltFeature, loading } = useIsDolt();
const tabs = ["Tables", "Views", "Schemas"];

return (
<div data-cy="db-page-table-nav" className={className}>
<TabsProvider initialActiveIndex={initialActiveIndex}>
<Loader loaded={!loading}>
<TabList className={css.tabList}>
{tabs.map((tab, i) => {
if (hideDoltFeature && tab === "Views") return null;
return (
<Tab key={tab} data-cy={`tab-${tab.toLowerCase()}`} index={i}>
{tab}
</Tab>
);
})}
</TabList>
</Loader>
<TabList className={css.tabList}>
{tabs.map((tab, i) => (
<Tab key={tab} data-cy={`tab-${tab.toLowerCase()}`} index={i}>
{tab}
</Tab>
))}
</TabList>
<CustomTabPanel index={0}>
{params.refName ? (
<TableList
Expand All @@ -56,9 +47,7 @@ export default function NavLinks({ className, params }: Props) {
</CustomTabPanel>
<CustomTabPanel index={1}>
{params.refName ? (
<NotDoltWrapper showNotDoltMsg feature="Listing views">
<Views params={{ ...params, refName: params.refName }} />
</NotDoltWrapper>
<Views params={{ ...params, refName: params.refName }} />
) : (
<p className={css.empty} data-cy="db-views-empty">
No views to show
Expand Down
6 changes: 1 addition & 5 deletions packages/web/components/SchemaList/Procedures.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,7 @@ export default function Procedures(props: Props) {
render={data => (
<List
{...props}
items={
data.doltProcedures?.list.map(
e => e.columnValues[0].displayValue,
) ?? []
}
items={data.doltProcedures?.map(e => e.name) ?? []}
kind="procedure"
/>
)}
Expand Down
29 changes: 7 additions & 22 deletions packages/web/components/SchemaList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import Section from "@components/DatabaseTableNav/Section";
import NotDoltWrapper from "@components/util/NotDoltWrapper";
import { useRowsForDoltSchemasQuery } from "@gen/graphql-types";
import { RefParams } from "@lib/params";
import List from "./List";
Expand All @@ -12,49 +11,35 @@ type Props = {
params: RefParams & { q?: string };
};

function DoltFeatures(props: Props) {
function Inner(props: Props) {
const res = useRowsForDoltSchemasQuery({ variables: props.params });
return (
<>
<div className={css.container}>
<h4>Tables</h4>
<Tables params={props.params} />
<h4>Views</h4>
<List
params={props.params}
kind="view"
items={getSchemaItemsFromRows("view", res.data?.doltSchemas.list)}
items={getSchemaItemsFromRows("view", res.data?.doltSchemas)}
loading={res.loading}
/>
<h4>Triggers</h4>
<List
params={props.params}
kind="trigger"
items={getSchemaItemsFromRows("trigger", res.data?.doltSchemas.list)}
items={getSchemaItemsFromRows("trigger", res.data?.doltSchemas)}
loading={res.loading}
/>
<h4>Events</h4>
<List
params={props.params}
kind="event"
items={getSchemaItemsFromRows("event", res.data?.doltSchemas.list)}
items={getSchemaItemsFromRows("event", res.data?.doltSchemas)}
loading={res.loading}
/>
<h4>Procedures</h4>
<Procedures params={props.params} />
</>
);
}

function Inner(props: Props) {
return (
<div className={css.container}>
<h4>Tables</h4>
<Tables params={props.params} />
{/* TODO: Make this work for non-Dolt */}
<NotDoltWrapper
showNotDoltMsg
feature="Viewing schemas for views, triggers, events, and procedures"
>
<DoltFeatures {...props} />
</NotDoltWrapper>
</div>
);
}
Expand Down
12 changes: 6 additions & 6 deletions packages/web/components/SchemaList/queries.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import { gql } from "@apollo/client";

export const ROWS_FOR_SCHEMAS = gql`
fragment SchemaItem on SchemaItem {
name
type
}
query RowsForDoltSchemas($databaseName: String!, $refName: String!) {
doltSchemas(databaseName: $databaseName, refName: $refName) {
list {
...RowForSchemas
}
...SchemaItem
}
}
`;

export const ROWS_FOR_PROCEDURES = gql`
query RowsForDoltProcedures($databaseName: String!, $refName: String!) {
doltProcedures(databaseName: $databaseName, refName: $refName) {
list {
...RowForSchemas
}
...SchemaItem
}
}
`;
10 changes: 4 additions & 6 deletions packages/web/components/SchemaList/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { RowForSchemasFragment } from "@gen/graphql-types";
import { SchemaItemFragment } from "@gen/graphql-types";

export type SchemaKind = "table" | "view" | "trigger" | "event" | "procedure";

Expand All @@ -13,10 +13,8 @@ export function getActiveItem(

export function getSchemaItemsFromRows(
kind: SchemaKind,
rows?: RowForSchemasFragment[],
items?: SchemaItemFragment[],
): string[] {
if (!rows) return [];
return rows
.filter(v => v.columnValues[0].displayValue === kind)
.map(e => e.columnValues[1].displayValue);
if (!items) return [];
return items.filter(i => i.type === kind).map(i => i.name);
}
Loading

0 comments on commit 69606f0

Please sign in to comment.