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 pull requests tab #42

Merged
merged 13 commits into from
Nov 9, 2023
Merged
1 change: 1 addition & 0 deletions packages/graphql-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"mysql2": "^3.1.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.5.4",
"timeago.js": "^4.0.2",
"typeorm": "^0.3.12"
},
"devDependencies": {
Expand Down
44 changes: 41 additions & 3 deletions packages/graphql-server/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,42 @@ type DocList {
list: [Doc!]!
}

type PullSummary {
_id: ID!
commits: CommitList!
}

type PullWithDetails {
_id: ID!
state: PullState!
summary: PullSummary
details: [PullDetails!]
}

enum PullState {
Open
Merged
Unspecified
}

union PullDetails = PullDetailSummary | PullDetailCommit

type PullDetailSummary {
_id: ID!
username: String!
createdAt: Timestamp!
numCommits: Float!
}

type PullDetailCommit {
_id: ID!
username: String!
message: String!
createdAt: Timestamp!
commitId: String!
parentCommitId: String
}

type RowDiff {
added: Row
deleted: Row
Expand Down Expand Up @@ -229,7 +265,7 @@ type Query {
branchOrDefault(databaseName: String!, branchName: String): Branch
branches(databaseName: String!, sortBy: SortBranchesBy): BranchNamesList!
defaultBranch(databaseName: String!): Branch
commits(offset: Int, databaseName: String!, refName: String, afterCommitId: String): CommitList!
commits(offset: Int, databaseName: String!, refName: String, afterCommitId: String, twoDot: Boolean, excludingCommitsFromRefName: String): CommitList!
currentDatabase: String
hasDatabaseEnv: Boolean!
databases: [String!]!
Expand All @@ -238,9 +274,10 @@ type Query {
diffSummaries(databaseName: String!, fromRefName: String!, toRefName: String!, refName: String, type: CommitDiffType, tableName: String): [DiffSummary!]!
docs(databaseName: String!, refName: String!): DocList!
docOrDefaultDoc(refName: String!, databaseName: String!, docType: DocType): Doc
rowDiffs(offset: Int, databaseName: String!, fromCommitId: String!, toCommitId: String!, refName: String, tableName: String!, filterByRowType: DiffRowType): RowDiffList!
pullWithDetails(databaseName: String!, fromBranchName: String!, toBranchName: String!): PullWithDetails!
rowDiffs(offset: Int, databaseName: String!, fromRefName: String!, toRefName: String!, refName: String, tableName: String!, filterByRowType: DiffRowType, type: CommitDiffType): RowDiffList!
rows(refName: String!, databaseName: String!, tableName: String!, offset: Int): RowList!
schemaDiff(databaseName: String!, fromCommitId: String!, toCommitId: String!, refName: String, tableName: String!): SchemaDiff
schemaDiff(databaseName: String!, fromRefName: String!, toRefName: String!, refName: String, tableName: String!, type: CommitDiffType): SchemaDiff
doltSchemas(databaseName: String!, refName: String!): [SchemaItem!]!
views(databaseName: String!, refName: String!): [SchemaItem!]!
doltProcedures(databaseName: String!, refName: String!): [SchemaItem!]!
Expand Down Expand Up @@ -285,6 +322,7 @@ type Mutation {
createDatabase(databaseName: String!): Boolean!
resetDatabase: Boolean!
loadDataFile(tableName: String!, refName: String!, databaseName: String!, importOp: ImportOperation!, fileType: FileType!, file: Upload!, modifier: LoadDataModifier): Boolean!
mergePull(databaseName: String!, fromBranchName: String!, toBranchName: String!): Boolean!
createTag(tagName: String!, databaseName: String!, message: String, fromRefName: String!): Tag!
deleteTag(databaseName: String!, tagName: String!): Boolean!
}
Expand Down
2 changes: 2 additions & 0 deletions packages/graphql-server/src/commits/commit.queries.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export const doltLogsQuery = `SELECT * FROM DOLT_LOG(?, '--parents') LIMIT ? OFFSET ?`;

export const twoDotDoltLogsQuery = `SELECT * FROM DOLT_LOG(?, '--parents')`;
39 changes: 21 additions & 18 deletions packages/graphql-server/src/commits/commit.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { DataSourceService } from "../dataSources/dataSource.service";
import { ROW_LIMIT, getNextOffset } from "../utils";
import { DBArgsWithOffset, RawRow } from "../utils/commonTypes";
import { Commit, CommitList, fromDoltLogRow } from "./commit.model";
import { doltLogsQuery } from "./commit.queries";
import { doltLogsQuery, twoDotDoltLogsQuery } from "./commit.queries";

@ArgsType()
export class ListCommitsArgs extends DBArgsWithOffset {
Expand All @@ -14,14 +14,11 @@ export class ListCommitsArgs extends DBArgsWithOffset {
@Field({ nullable: true })
afterCommitId?: string;

// @Field(_type => Boolean, { nullable: true })
// twoDot?: boolean;
@Field(_type => Boolean, { nullable: true })
twoDot?: boolean;

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

// @Field(_type => Boolean, { nullable: true })
// resolveBranchNames?: boolean;
@Field({ nullable: true })
excludingCommitsFromRefName?: string;
}

@Resolver(_of => Commit)
Expand All @@ -38,6 +35,12 @@ export class CommitResolver {
const refName = args.refName ?? args.afterCommitId ?? "";
const offset = args.offset ?? 0;
return this.dss.query(async query => {
if (args.twoDot && args.excludingCommitsFromRefName) {
const logs = await query(twoDotDoltLogsQuery, [
`${args.excludingCommitsFromRefName}..${refName}`,
]);
return getCommitListRes(logs, args);
}
const logs = await query(doltLogsQuery, [refName, ROW_LIMIT + 1, offset]);
return getCommitListRes(logs, args);
}, args.databaseName);
Expand All @@ -64,15 +67,15 @@ function handleArgsErr(args: ListCommitsArgs): Error | undefined {
"cannot supply both `refName` and `afterCommitId` when listing commits",
);
}
// if (args.twoDot && !args.excludingCommitsFromRefName) {
// return new Error(
// "must supply `excludingCommitsFromRefName` if twoDot is true",
// );
// }
// if (!args.twoDot && args.excludingCommitsFromRefName) {
// return new Error(
// "cannot supply `excludingCommitsFromRefName` if twoDot is not provided or false",
// );
// }
if (args.twoDot && !args.excludingCommitsFromRefName) {
return new Error(
"must supply `excludingCommitsFromRefName` if twoDot is true",
);
}
if (!args.twoDot && args.excludingCommitsFromRefName) {
return new Error(
"cannot supply `excludingCommitsFromRefName` if twoDot is not provided or false",
);
}
return undefined;
}
90 changes: 90 additions & 0 deletions packages/graphql-server/src/pullDetails/getPullDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import { format } from "timeago.js";
import { Commit } from "../commits/commit.model";
import { PullSummary } from "../pullSummaries/pullSummary.model";
import {
PullDetailCommit,
PullDetails,
PullDetailSummary,
PullDetailUnion,
} from "./pullDetail.model";

type PullDetail = typeof PullDetailUnion;

export default function getPullDetails(summary?: PullSummary): PullDetails {
const details: PullDetails = [];
if (!summary) {
return details;
}
// Add commits to details
summary.commits.list.forEach(c => details.push(getCommit(c)));
// Get commit summaries from sorted commits
const sorted = details.sort(sortByTimestampDesc);
const summaries = getSummaries(sorted);
return sorted.concat(summaries).sort(sortByTimestampDesc) as PullDetails;
}

function sortByTimestampDesc(a: PullDetail, b: PullDetail) {
return a.createdAt.valueOf() - b.createdAt.valueOf();
}

function getCommit(c: Commit): PullDetailCommit {
const parentCommitId = c.parents.length ? c.parents[0] : undefined;
return {
...c,
username: c.committer.username ?? c.committer.displayName,
createdAt: c.committedAt,
parentCommitId,
};
}

const initialSummary: PullDetailSummary = {
_id: "",
username: "",
createdAt: new Date(0),
numCommits: 0,
};

function getSummaries(sorted: PullDetail[]): PullDetailSummary[] {
const summaries: PullDetailSummary[] = [];
let summary = { ...initialSummary };

sorted.forEach(d => {
// Only update summary for commits
if ("commitId" in d) {
const timeagosEqual = format(d.createdAt) === format(summary.createdAt);
const needToUpdate = d.username !== summary.username || !timeagosEqual;

if (needToUpdate) {
// Push last summary if it has commit info
if (summary.numCommits > 0) {
summaries.push({ ...summary });
}
// Update summary with changed information
summary = {
...summary,
_id: `${d.username}/${d.createdAt.valueOf()}`,
username: d.username,
numCommits: 0,
// Ensure that the summary shows up before first commit
createdAt: new Date(d.createdAt.valueOf() - 1),
};
}
// Update number of commits every time
summary.numCommits += 1;
} else {
// If not commit, push last summary
if (summary.numCommits > 0) {
summaries.push({ ...summary });
}
// And start fresh
summary = { ...initialSummary };
}
});

// If last summary not pushed yet, push
if (summary.numCommits > 0) {
summaries.push({ ...summary });
}

return summaries;
}
60 changes: 60 additions & 0 deletions packages/graphql-server/src/pullDetails/pullDetail.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
Field,
GraphQLTimestamp,
ID,
ObjectType,
createUnionType,
} from "@nestjs/graphql";

@ObjectType()
export class PullDetailCommit {
@Field(_type => ID)
_id: string;

@Field()
username: string;

@Field()
message: string;

@Field(_type => GraphQLTimestamp)
createdAt: Date;

@Field()
commitId: string;

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

@ObjectType()
export class PullDetailSummary {
@Field(_type => ID)
_id: string;

@Field()
username: string;

@Field(_type => GraphQLTimestamp)
createdAt: Date;

@Field()
numCommits: number;
}

export const PullDetailUnion = createUnionType({
name: "PullDetails",
types: () => [PullDetailSummary, PullDetailCommit],
resolveType: value => {
if ("commitId" in value) {
return PullDetailCommit;
}
if ("numCommits" in value) {
return PullDetailSummary;
}
return undefined;
},
});

export type PullDetail = typeof PullDetailUnion;
export type PullDetails = PullDetail[];
21 changes: 21 additions & 0 deletions packages/graphql-server/src/pullSummaries/pullSummary.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Field, ID, ObjectType } from "@nestjs/graphql";
import * as commit from "../commits/commit.model";

@ObjectType()
export class PullSummary {
@Field(_type => ID)
_id: string;

@Field(_type => commit.CommitList)
commits: commit.CommitList;
}

export function fromAPISummary(
_pullId: string,
commits: commit.Commit[],
): PullSummary {
return {
_id: `${_pullId}/summary`,
commits: { list: commits },
};
}
9 changes: 9 additions & 0 deletions packages/graphql-server/src/pulls/pull.enums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { registerEnumType } from "@nestjs/graphql";

export enum PullState {
Open,
Merged,
Unspecified,
}

registerEnumType(PullState, { name: "PullState" });
37 changes: 37 additions & 0 deletions packages/graphql-server/src/pulls/pull.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Field, ID, ObjectType } from "@nestjs/graphql";
import { Commit } from "../commits/commit.model";
import getPullDetails from "../pullDetails/getPullDetails";
import { PullDetailUnion, PullDetails } from "../pullDetails/pullDetail.model";
import {
PullSummary,
fromAPISummary,
} from "../pullSummaries/pullSummary.model";
import { PullState } from "./pull.enums";

@ObjectType()
export class PullWithDetails {
@Field(_type => ID)
_id: string;

@Field(_type => PullState)
state: PullState;

@Field(_type => PullSummary, { nullable: true })
summary?: PullSummary;

@Field(_type => [PullDetailUnion], { nullable: true })
details?: PullDetails;
}

export function fromAPIModelPullWithDetails(
pullId: string,
commits: Commit[] = [],
): PullWithDetails {
const summary = fromAPISummary(pullId, commits);
return {
_id: `${pullId}/pullWithDetails`,
state: commits.length ? PullState.Open : PullState.Merged,
summary,
details: getPullDetails(summary),
};
}
1 change: 1 addition & 0 deletions packages/graphql-server/src/pulls/pull.queries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const callMerge = `CALL DOLT_MERGE(?, "--no-ff", "-m", ?)`;
Loading
Loading