Skip to content

Commit

Permalink
Merge pull request #314 from dolthub/liuliu/add-remote
Browse files Browse the repository at this point in the history
Graphql, Web: Add and delete remote
  • Loading branch information
liuliu-dev authored Dec 3, 2024
2 parents 4c6fd12 + 0ce40ff commit d567853
Show file tree
Hide file tree
Showing 27 changed files with 568 additions and 114 deletions.
2 changes: 2 additions & 0 deletions graphql-server/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ type Mutation {
resetDatabase(newDatabase: String): Boolean!
loadDataFile(schemaName: String, tableName: String!, refName: String!, databaseName: String!, importOp: ImportOperation!, fileType: FileType!, file: Upload!, modifier: LoadDataModifier): Boolean!
mergePull(fromBranchName: String!, toBranchName: String!, databaseName: String!, author: AuthorInfo): Boolean!
addRemote(databaseName: String!, remoteName: String!, remoteUrl: String!): String!
deleteRemote(databaseName: String!, remoteName: String!): Boolean!
restoreAllTables(databaseName: String!, refName: String!): Boolean!
createTag(tagName: String!, databaseName: String!, message: String, fromRefName: String!, author: AuthorInfo): String!
deleteTag(databaseName: String!, tagName: String!): Boolean!
Expand Down
16 changes: 16 additions & 0 deletions graphql-server/src/queryFactory/dolt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,22 @@ export class DoltQueryFactory
args.databaseName,
);
}

async addRemote(args: t.AddRemoteArgs): t.PR {
return this.query(
qh.callAddRemote,
[args.remoteName, args.remoteUrl],
args.databaseName,
);
}

async callDeleteRemote(args: t.RemoteArgs): t.PR {
return this.query(
qh.callDeleteRemote,
[args.remoteName],
args.databaseName,
);
}
}

async function getTableInfoWithQR(
Expand Down
6 changes: 6 additions & 0 deletions graphql-server/src/queryFactory/dolt/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ export const threeDotSchemaDiffQuery = `SELECT * FROM DOLT_SCHEMA_DIFF(?, ?)`;
export const getCallMerge = (hasAuthor = false) =>
`CALL DOLT_MERGE(?, "--no-ff", "-m", ?${getAuthorNameString(hasAuthor)})`;

// REMOTES

export const callAddRemote = `CALL DOLT_REMOTE("add", ?, ?)`;

export const callDeleteRemote = `CALL DOLT_REMOTE("remove", ?)`;

// TAGS

export const callDeleteTag = `CALL DOLT_TAG("-d", ?)`;
Expand Down
16 changes: 16 additions & 0 deletions graphql-server/src/queryFactory/doltgres/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,22 @@ export class DoltgresQueryFactory
args.databaseName,
);
}

async addRemote(args: t.AddRemoteArgs): t.PR {
return this.query(
qh.callAddRemote,
[args.remoteName, args.remoteUrl],
args.databaseName,
);
}

async callDeleteRemote(args: t.RemoteArgs): t.PR {
return this.query(
qh.callDeleteRemote,
[args.remoteName],
args.databaseName,
);
}
}

async function getTableInfoWithQR(
Expand Down
6 changes: 6 additions & 0 deletions graphql-server/src/queryFactory/doltgres/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,3 +160,9 @@ export function getOrderByFromDiffCols(cols: t.RawRows): string {
export const callResetHard = `SELECT DOLT_RESET('--hard')`;

export const callCheckoutTable = `SELECT DOLT_CHECKOUT($1::text)`;

// REMOTES

export const callAddRemote = `SELECT DOLT_REMOTE('add', $1::text, $2::text)`;

export const callDeleteRemote = `SELECT DOLT_REMOTE('remove', $1::text)`;
4 changes: 4 additions & 0 deletions graphql-server/src/queryFactory/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,4 +146,8 @@ export declare class QueryFactory {
restoreAllTables(args: t.RefArgs): t.PR;

getRemotes(args: t.DBArgs): t.PR;

addRemote(args: t.AddRemoteArgs): t.PR;

callDeleteRemote(args: t.RemoteArgs): t.PR;
}
8 changes: 8 additions & 0 deletions graphql-server/src/queryFactory/mysql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,4 +305,12 @@ export class MySQLQueryFactory
async getRemotes(_args: t.DBArgs): t.PR {
throw notDoltError("get remotes");
}

async addRemote(_: t.AddRemoteArgs): t.PR {
throw notDoltError("add remote");
}

async callDeleteRemote(_: t.RemoteArgs): t.PR {
throw notDoltError("delete remote");
}
}
2 changes: 2 additions & 0 deletions graphql-server/src/queryFactory/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export type RefArgs = DBArgs & { refName: string };
export type RefSchemaArgs = RefArgs & { schemaName: string };
export type RefMaybeSchemaArgs = RefArgs & { schemaName?: string };
export type BranchArgs = DBArgs & { branchName: string };
export type AddRemoteArgs = DBArgs & { remoteName: string; remoteUrl: string };
export type RemoteArgs = DBArgs & { remoteName: string };
export type TagArgs = DBArgs & { tagName: string };
export type TableArgs = RefArgs & { tableName: string };
export type TableMaybeSchemaArgs = TableArgs & { schemaName?: string };
Expand Down
4 changes: 2 additions & 2 deletions graphql-server/src/remotes/remote.model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Field, ID, ObjectType } from "@nestjs/graphql";
import { __Type } from "graphql";
import { RawRow } from "src/queryFactory/types";
import { ListOffsetRes } from "src/utils/commonTypes";
import { RawRow } from "../queryFactory/types";
import { ListOffsetRes } from "../utils/commonTypes";

@ObjectType()
export class Remote {
Expand Down
40 changes: 35 additions & 5 deletions graphql-server/src/remotes/remote.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,26 @@
import { Args, Query, Resolver } from "@nestjs/graphql";
import { ConnectionProvider } from "src/connections/connection.provider";
import { DBArgsWithOffset } from "src/utils/commonTypes";
import { RawRow } from "src/queryFactory/types";
import { getNextOffset, ROW_LIMIT } from "src/utils";
import {
Args,
ArgsType,
Field,
Mutation,
Query,
Resolver,
} from "@nestjs/graphql";
import { ConnectionProvider } from "../connections/connection.provider";
import { DBArgs, DBArgsWithOffset, RemoteArgs } from "../utils/commonTypes";
import { RawRow } from "../queryFactory/types";
import { getNextOffset, ROW_LIMIT } from "../utils";
import { fromDoltRemotesRow, Remote, RemoteList } from "./remote.model";

@ArgsType()
export class AddRemoteArgs extends DBArgs {
@Field()
remoteName: string;

@Field()
remoteUrl: string;
}

@Resolver(_of => Remote)
export class RemoteResolver {
constructor(private readonly conn: ConnectionProvider) {}
Expand All @@ -16,6 +32,20 @@ export class RemoteResolver {
const res = await conn.getRemotes(args);
return getRemoteListRes(res, args);
}

@Mutation(_returns => String)
async addRemote(@Args() args: AddRemoteArgs): Promise<string> {
const conn = this.conn.connection();
await conn.addRemote(args);
return args.remoteName;
}

@Mutation(_returns => Boolean)
async deleteRemote(@Args() args: RemoteArgs): Promise<boolean> {
const conn = this.conn.connection();
await conn.callDeleteRemote(args);
return true;
}
}

function getRemoteListRes(
Expand Down
6 changes: 6 additions & 0 deletions graphql-server/src/utils/commonTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export class TagArgs extends DBArgs {
tagName: string;
}

@ArgsType()
export class RemoteArgs extends DBArgs {
@Field()
remoteName: string;
}

@InputType()
export class AuthorInfo {
@Field()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {
Button,
ButtonsWithError,
FormInput,
Loader,
} from "@dolthub/react-components";
import { useReactiveWidth } from "@dolthub/react-hooks";
import { useAddRemoteMutation } from "@gen/graphql-types";
import useMutation from "@hooks/useMutation";
import { DatabaseParams } from "@lib/params";
import { refetchBranchQueries } from "@lib/refetchQueries";
import { remotes } from "@lib/urls";
import { useRouter } from "next/router";
import { SyntheticEvent, useState } from "react";
import css from "./index.module.css";

type Props = {
params: DatabaseParams;
};

export default function AddRemoteForm(props: Props): JSX.Element {
const router = useRouter();
const [remoteName, setRemoteName] = useState("");
const [remoteUrl, setRemoteUrl] = useState("");
const {
mutateFn: addRemote,
err,
loading,
} = useMutation({
hook: useAddRemoteMutation,
refetchQueries: refetchBranchQueries(props.params),
});
const { isMobile } = useReactiveWidth();

const goToRemotesPage = () => {
const { href, as } = remotes(props.params);
router.push(href, as).catch(() => {});
};

const onSubmit = async (e: SyntheticEvent) => {
e.preventDefault();
if (!remoteName || !remoteUrl) return;

const { data } = await addRemote({
variables: { ...props.params, remoteName, remoteUrl },
});
if (!data) return;
const { href, as } = remotes(props.params);
router.push(href, as).catch(console.error);
};

return (
<div>
<form onSubmit={onSubmit}>
<div className={css.remoteForm}>
<FormInput
value={remoteName}
onChangeString={setRemoteName}
label="Add remote name"
placeholder="i.e. origin"
className={css.input}
/>
<FormInput
value={remoteUrl}
onChangeString={setRemoteUrl}
label="Add remote url"
className={css.input}
/>
<ButtonsWithError
onCancel={goToRemotesPage}
left
stackedButton={isMobile}
error={err}
>
<Button type="submit" disabled={!remoteName || !remoteUrl}>
Add remote
</Button>
</ButtonsWithError>
</div>
<Loader loaded={!loading} />
</form>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.container {
@apply m-6;
}

.remoteForm {
@apply max-w-2xl mx-auto;
}

.input {
@apply mt-4 px-0;
input {
@apply text-sm rounded bg-stone-50 border border-stone-100;

&:focus {
@apply bg-white;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { DatabaseParams } from "@lib/params";
import AddRemoteForm from "./AddRemoteForm";
import css from "./index.module.css";

type Props = {
params: DatabaseParams;
};

export default function AddRemotePage(props: Props): JSX.Element {
return (
<div className={css.container}>
<h1>Add Remote</h1>
<AddRemoteForm {...props} />
</div>
);
}

This file was deleted.

Loading

0 comments on commit d567853

Please sign in to comment.