Skip to content

Commit

Permalink
Merge pull request #80 from dolthub/taylor/graphql-refactor
Browse files Browse the repository at this point in the history
Refactor graphql server in preparation of postgres support
  • Loading branch information
tbantle22 authored Dec 13, 2023
2 parents c7f39a9 + 918e214 commit 7809ca4
Show file tree
Hide file tree
Showing 69 changed files with 1,488 additions and 1,072 deletions.
4 changes: 2 additions & 2 deletions graphql-server/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,15 @@ enum DiffRowType {
}

type Mutation {
createBranch(databaseName: String!, newBranchName: String!, fromRefName: String!): Branch!
createBranch(databaseName: String!, newBranchName: String!, fromRefName: String!): String!
deleteBranch(databaseName: String!, branchName: String!): Boolean!
addDatabaseConnection(connectionUrl: String!, name: String!, hideDoltFeatures: Boolean, useSSL: Boolean): String
removeDatabaseConnection(name: String!): Boolean!
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!
createTag(tagName: String!, databaseName: String!, message: String, fromRefName: String!): String!
deleteTag(databaseName: String!, tagName: String!): Boolean!
}

Expand Down
2 changes: 0 additions & 2 deletions graphql-server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { ApolloDriver, ApolloDriverConfig } from "@nestjs/apollo";
import { Module } from "@nestjs/common";
import { GraphQLModule } from "@nestjs/graphql";
import { TerminusModule } from "@nestjs/terminus";
import { DataSourceModule } from "./dataSources/dataSource.module";
import { FileStoreModule } from "./fileStore/fileStore.module";
import resolvers from "./resolvers";

Expand All @@ -13,7 +12,6 @@ import resolvers from "./resolvers";
context: ctx => ctx,
driver: ApolloDriver,
}),
DataSourceModule,
FileStoreModule,
TerminusModule,
],
Expand Down
2 changes: 1 addition & 1 deletion graphql-server/src/branches/branch.model.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Field, GraphQLTimestamp, ID, ObjectType } from "@nestjs/graphql";
import { RawRow } from "../queryFactory/types";
import * as table from "../tables/table.model";
import { convertToUTCDate } from "../utils";
import { RawRow } from "../utils/commonTypes";

@ObjectType()
export class Branch {
Expand Down
19 changes: 0 additions & 19 deletions graphql-server/src/branches/branch.queries.ts

This file was deleted.

65 changes: 20 additions & 45 deletions graphql-server/src/branches/branch.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,12 @@ import {
ResolveField,
Resolver,
} from "@nestjs/graphql";
import { DataSourceService } from "../dataSources/dataSource.service";
import { ConnectionResolver } from "../connections/connection.resolver";
import { Table } from "../tables/table.model";
import { TableResolver } from "../tables/table.resolver";
import { BranchArgs, DBArgs } from "../utils/commonTypes";
import { SortBranchesBy } from "./branch.enum";
import {
Branch,
BranchNamesList,
branchForNonDoltDB,
fromDoltBranchesRow,
} from "./branch.model";
import {
branchQuery,
callDeleteBranch,
callNewBranch,
getBranchesQuery,
} from "./branch.queries";
import { Branch, BranchNamesList, fromDoltBranchesRow } from "./branch.model";

@ArgsType()
export class GetBranchOrDefaultArgs extends DBArgs {
Expand Down Expand Up @@ -62,20 +51,16 @@ class ListBranchesArgs extends DBArgs {
@Resolver(_of => Branch)
export class BranchResolver {
constructor(
private readonly dss: DataSourceService,
private readonly conn: ConnectionResolver,
private readonly tableResolver: TableResolver,
) {}

@Query(_returns => Branch, { nullable: true })
async branch(@Args() args: BranchArgs): Promise<Branch | undefined> {
return this.dss.queryMaybeDolt(async (query, isDolt) => {
if (!isDolt) {
return branchForNonDoltDB(args.databaseName);
}
const branch = await query(branchQuery, [args.branchName]);
if (!branch.length) return undefined;
return fromDoltBranchesRow(args.databaseName, branch[0]);
}, args.databaseName);
const conn = this.conn.connection();
const res = await conn.getBranch(args);
if (!res.length) return undefined;
return fromDoltBranchesRow(args.databaseName, res[0]);
}

@Query(_returns => Branch, { nullable: true })
Expand All @@ -92,17 +77,11 @@ export class BranchResolver {

@Query(_returns => BranchNamesList)
async branches(@Args() args: ListBranchesArgs): Promise<BranchNamesList> {
return this.dss.queryMaybeDolt(async (query, isDolt) => {
if (!isDolt) {
return {
list: [branchForNonDoltDB(args.databaseName)],
};
}
const branches = await query(getBranchesQuery(args.sortBy));
return {
list: branches.map(b => fromDoltBranchesRow(args.databaseName, b)),
};
}, args.databaseName);
const conn = this.conn.connection();
const res = await conn.getBranches(args);
return {
list: res.map(b => fromDoltBranchesRow(args.databaseName, b)),
};
}

@Query(_returns => Branch, { nullable: true })
Expand All @@ -111,22 +90,18 @@ export class BranchResolver {
return getDefaultBranchFromBranchesList(branchNames.list);
}

@Mutation(_returns => Branch)
async createBranch(@Args() args: CreateBranchArgs): Promise<Branch> {
return this.dss.query(async query => {
await query(callNewBranch, [args.newBranchName, args.fromRefName]);
const branch = await query(branchQuery, [args.newBranchName]);
if (!branch.length) throw new Error("Created branch not found");
return fromDoltBranchesRow(args.databaseName, branch[0]);
}, args.databaseName);
@Mutation(_returns => String)
async createBranch(@Args() args: CreateBranchArgs): Promise<string> {
const conn = this.conn.connection();
await conn.createNewBranch({ ...args, branchName: args.newBranchName });
return args.newBranchName;
}

@Mutation(_returns => Boolean)
async deleteBranch(@Args() args: BranchArgs): Promise<boolean> {
return this.dss.query(async query => {
await query(callDeleteBranch, [args.branchName]);
return true;
}, args.databaseName);
const conn = this.conn.connection();
await conn.callDeleteBranch(args);
return true;
}

@ResolveField(_returns => Table, { nullable: true })
Expand Down
2 changes: 1 addition & 1 deletion graphql-server/src/columns/column.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Field, ObjectType } from "@nestjs/graphql";
import { RawRow } from "../utils/commonTypes";
import { RawRow } from "../queryFactory/types";

@ObjectType()
export class ColConstraint {
Expand Down
3 changes: 2 additions & 1 deletion graphql-server/src/commits/commit.model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Field, GraphQLTimestamp, ID, ObjectType } from "@nestjs/graphql";
import { RawRow } from "../queryFactory/types";
import { convertToUTCDate } from "../utils";
import { ListOffsetRes, RawRow } from "../utils/commonTypes";
import { ListOffsetRes } from "../utils/commonTypes";
import * as doltWriter from "./doltWriter.model";

@ObjectType()
Expand Down
3 changes: 0 additions & 3 deletions graphql-server/src/commits/commit.queries.ts

This file was deleted.

28 changes: 15 additions & 13 deletions graphql-server/src/commits/commit.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Args, ArgsType, Field, Query, Resolver } from "@nestjs/graphql";
import { DataSourceService } from "../dataSources/dataSource.service";
import { ConnectionResolver } from "../connections/connection.resolver";
import { RawRow } from "../queryFactory/types";
import { ROW_LIMIT, getNextOffset } from "../utils";
import { DBArgsWithOffset, RawRow } from "../utils/commonTypes";
import { DBArgsWithOffset } from "../utils/commonTypes";
import { Commit, CommitList, fromDoltLogRow } from "./commit.model";
import { doltLogsQuery, twoDotDoltLogsQuery } from "./commit.queries";

@ArgsType()
export class ListCommitsArgs extends DBArgsWithOffset {
Expand All @@ -23,7 +23,7 @@ export class ListCommitsArgs extends DBArgsWithOffset {

@Resolver(_of => Commit)
export class CommitResolver {
constructor(private readonly dss: DataSourceService) {}
constructor(private readonly conn: ConnectionResolver) {}

@Query(_returns => CommitList)
async commits(
Expand All @@ -34,16 +34,18 @@ export class CommitResolver {
if (err) throw err;
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]);
const conn = this.conn.connection();

if (args.twoDot && args.excludingCommitsFromRefName) {
const logs = await conn.getTwoDotLogs({
toRefName: args.excludingCommitsFromRefName,
fromRefName: refName,
databaseName: args.databaseName,
});
return getCommitListRes(logs, args);
}, args.databaseName);
}
const logs = await conn.getLogs({ ...args, refName }, offset);
return getCommitListRes(logs, args);
}
}

Expand Down
2 changes: 1 addition & 1 deletion graphql-server/src/commits/doltWriter.model.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Field, ID, ObjectType } from "@nestjs/graphql";
import { RawRow } from "../utils/commonTypes";
import { RawRow } from "../queryFactory/types";

@ObjectType()
export class DoltWriter {
Expand Down
109 changes: 109 additions & 0 deletions graphql-server/src/connections/connection.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import { Resolver } from "@nestjs/graphql";
import * as mysql from "mysql2/promise";
import { DataSource } from "typeorm";
import { DoltQueryFactory } from "../queryFactory/dolt";
import { MySQLQueryFactory } from "../queryFactory/mysql";
import { QueryFactory } from "../queryFactory/types";

export class WorkbenchConfig {
hideDoltFeatures: boolean;

connectionUrl: string;

useSSL: boolean;
}

@Resolver()
export class ConnectionResolver {
private ds: DataSource | undefined;

private qf: QueryFactory | undefined;

private workbenchConfig: WorkbenchConfig | undefined;

connection(): QueryFactory {
if (!this.qf) {
throw new Error("Data source service not initialized");
}
return this.qf;
}

// Used for file upload only, must destroy after using
async mysqlConnection(): Promise<mysql.Connection> {
const { workbenchConfig } = this;
if (!workbenchConfig) {
throw new Error("Workbench config not found for MySQL connection");
}

const options: mysql.ConnectionOptions = {
uri: workbenchConfig.connectionUrl,
ssl: {
rejectUnauthorized: false,
},
connectionLimit: 1,
dateStrings: ["DATE"],

// Allows file upload via LOAD DATA
flags: ["+LOCAL_FILES"],
};

return mysql.createConnection(options);
}

async addConnection(config: WorkbenchConfig): Promise<void> {
if (this.ds?.isInitialized) {
await this.ds.destroy();
}

this.workbenchConfig = config;

this.ds = new DataSource({
type: "mysql",
connectorPackage: "mysql2",
url: config.connectionUrl,
ssl: config.useSSL
? {
rejectUnauthorized: false,
}
: undefined,
synchronize: false,
logging: "all",

extra: {
connectionLimit: 6,
dateStrings: ["DATE"],
namedPlaceholders: true,
},
});

await this.ds.initialize();

const qf = await this.newQueryFactory();
this.qf = qf;
}

getWorkbenchConfig(): WorkbenchConfig | undefined {
return this.workbenchConfig;
}

async newQueryFactory(): Promise<QueryFactory> {
try {
const res = await this.ds?.query("SELECT dolt_version()");
if (res) {
return new DoltQueryFactory(this.ds);
}
return new MySQLQueryFactory(this.ds);
} catch (_) {
return new MySQLQueryFactory(this.ds);
}
}

async resetDS(): Promise<void> {
if (!this.workbenchConfig) {
throw new Error(
"Workbench config not found. Please add connectivity information.",
);
}
await this.addConnection(this.workbenchConfig);
}
}
13 changes: 0 additions & 13 deletions graphql-server/src/dataSources/dataSource.module.ts

This file was deleted.

Loading

0 comments on commit 7809ca4

Please sign in to comment.