Skip to content

Commit

Permalink
Merge pull request #211 from tigrisdata/main
Browse files Browse the repository at this point in the history
feat: Database branching
  • Loading branch information
adilansari authored Jan 17, 2023
2 parents b0fcc64 + 8d05ecb commit 45db10a
Show file tree
Hide file tree
Showing 15 changed files with 823 additions and 180 deletions.
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
"google-protobuf": "^3.21.0",
"json-bigint": "^1.0.0",
"reflect-metadata": "^0.1.13",
"typescript": "^4.7.2"
"typescript": "^4.7.2",
"app-root-path": "^3.1.0"
}
}
15 changes: 10 additions & 5 deletions src/__tests__/consumables/cursor.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ import { ObservabilityService } from "../../proto/server/v1/observability_grpc_p
import TestObservabilityService from "../test-observability-service";
import { DB } from "../../db";

describe("class FindCursor", () => {
describe("FindCursor", () => {
let server: Server;
const SERVER_PORT = 5003;
let db: DB;

beforeAll((done) => {
beforeAll(async () => {
server = new Server();
TestTigrisService.reset();
server.addService(TigrisService, TestService.handler.impl);
Expand All @@ -30,9 +30,14 @@ describe("class FindCursor", () => {
}
}
);
const tigris = new Tigris({ serverUrl: "localhost:" + SERVER_PORT, projectName: "db3" });
db = tigris.getDatabase();
done();
const tigris = new Tigris({
serverUrl: "localhost:" + SERVER_PORT,
projectName: "db3",
branch: TestTigrisService.ExpectedBranch,
});
const dbPromise = tigris.getDatabase();
db = await dbPromise;
return dbPromise;
});

beforeEach(() => {
Expand Down
128 changes: 97 additions & 31 deletions src/__tests__/test-service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ITigrisServer, TigrisService } from "../proto/server/v1/api_grpc_pb";
import { TigrisService } from "../proto/server/v1/api_grpc_pb";
import * as grpc from "@grpc/grpc-js";
import { sendUnaryData, ServerUnaryCall, ServerWritableStream } from "@grpc/grpc-js";
import { v4 as uuidv4 } from "uuid";
import {
Expand All @@ -9,20 +10,25 @@ import {
CollectionMetadata,
CommitTransactionRequest,
CommitTransactionResponse,
CreateProjectRequest,
CreateProjectResponse,
CreateBranchRequest,
CreateBranchResponse,
CreateOrUpdateCollectionRequest,
CreateOrUpdateCollectionResponse,
ProjectInfo,
CreateProjectRequest,
CreateProjectResponse,
DatabaseMetadata,
DeleteBranchRequest,
DeleteBranchResponse,
DeleteProjectRequest,
DeleteProjectResponse,
DeleteRequest,
DeleteResponse,
DescribeCollectionRequest,
DescribeCollectionResponse,
DescribeDatabaseRequest,
DescribeDatabaseResponse,
DropCollectionRequest,
DropCollectionResponse,
DeleteProjectRequest,
DeleteProjectResponse,
FacetCount,
InsertRequest,
InsertResponse,
Expand All @@ -31,6 +37,7 @@ import {
ListProjectsRequest,
ListProjectsResponse,
Page,
ProjectInfo,
ReadRequest,
ReadResponse,
ReplaceRequest,
Expand All @@ -47,17 +54,14 @@ import {
TransactionCtx,
UpdateRequest,
UpdateResponse,
DescribeDatabaseRequest,
DescribeDatabaseResponse,
CreateBranchRequest,
CreateBranchResponse,
DeleteBranchRequest,
DeleteBranchResponse,
} from "../proto/server/v1/api_pb";
import * as google_protobuf_timestamp_pb from "google-protobuf/google/protobuf/timestamp_pb";
import { Utility } from "../utility";
import { Status } from "@grpc/grpc-js/build/src/constants";
import assert from "assert";

export class TestTigrisService {
public static readonly ExpectedBranch = "unit-tests";
private static PROJECTS: string[] = [];
private static COLLECTION_MAP = new Map<string, Array<string>>();
private static txId: string;
Expand Down Expand Up @@ -179,18 +183,62 @@ export class TestTigrisService {
call: ServerUnaryCall<CreateBranchRequest, CreateBranchResponse>,
callback: sendUnaryData<CreateBranchResponse>
): void {
// TODO implement
let err: Partial<grpc.StatusObject>;
const reply = new CreateBranchResponse();

switch (call.request.getBranch()) {
case Branch.Existing:
err = {
code: Status.ALREADY_EXISTS,
details: `branch already exists '${Branch.Existing}'`,
};
break;
case Branch.NotFound:
err = {
code: Status.NOT_FOUND,
details: `project not found`,
};
break;
default:
reply.setStatus("created");
reply.setMessage("branch successfully created");
}

if (err) {
return callback(err, undefined);
} else {
return callback(undefined, reply);
}
},
deleteBranch(
call: ServerUnaryCall<DeleteBranchRequest, DeleteBranchResponse>,
callback: sendUnaryData<DeleteBranchResponse>
): void {
// TODO implement
let err: Partial<grpc.StatusObject>;
const reply = new DeleteBranchResponse();
switch (call.request.getBranch()) {
case Branch.NotFound:
err = {
code: Status.NOT_FOUND,
details: `Branch doesn't exist`,
};
break;
default:
reply.setStatus("deleted");
reply.setMessage("branch deleted successfully");
}
if (err) {
return callback(err, undefined);
} else {
return callback(undefined, reply);
}
},
beginTransaction(
call: ServerUnaryCall<BeginTransactionRequest, BeginTransactionResponse>,
callback: sendUnaryData<BeginTransactionResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

const reply: BeginTransactionResponse = new BeginTransactionResponse();
if (call.request.getProject() === "test-tx") {
TestTigrisService.txId = uuidv4();
Expand All @@ -204,11 +252,12 @@ export class TestTigrisService {
reply.setTxCtx(new TransactionCtx().setId("id-test").setOrigin("origin-test"));
callback(undefined, reply);
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
commitTransaction(
call: ServerUnaryCall<CommitTransactionRequest, CommitTransactionResponse>,
callback: sendUnaryData<CommitTransactionResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

const reply: CommitTransactionResponse = new CommitTransactionResponse();
reply.setStatus("committed-test");
callback(undefined, reply);
Expand All @@ -223,23 +272,23 @@ export class TestTigrisService {
reply.setStatus("created");
callback(undefined, reply);
},
/* eslint-disable @typescript-eslint/no-empty-function */
createOrUpdateCollection(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
call: ServerUnaryCall<CreateOrUpdateCollectionRequest, CreateOrUpdateCollectionResponse>,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
callback: sendUnaryData<CreateOrUpdateCollectionResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

const reply: CreateOrUpdateCollectionResponse = new CreateOrUpdateCollectionResponse();
reply.setStatus("Collections created successfully");
reply.setStatus(call.request.getCollection());
callback(undefined, reply);
},
/* eslint-enable @typescript-eslint/no-empty-function */
delete(
call: ServerUnaryCall<DeleteRequest, DeleteResponse>,
callback: sendUnaryData<DeleteResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

if (call.request.getProject() === "test-tx") {
const txIdHeader = call.metadata.get("Tigris-Tx-Id").toString();
const txOriginHeader = call.metadata.get("Tigris-Tx-Origin").toString();
Expand All @@ -259,13 +308,12 @@ export class TestTigrisService {
},
/* eslint-disable @typescript-eslint/no-empty-function */
describeCollection(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_call: ServerUnaryCall<DescribeCollectionRequest, DescribeCollectionResponse>,
call: ServerUnaryCall<DescribeCollectionRequest, DescribeCollectionResponse>,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
_callback: sendUnaryData<DescribeCollectionResponse>
): void {},

/* eslint-enable @typescript-eslint/no-empty-function */
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);
},
describeDatabase(
call: ServerUnaryCall<DescribeDatabaseRequest, DescribeDatabaseResponse>,
callback: sendUnaryData<DescribeDatabaseResponse>
Expand All @@ -284,14 +332,19 @@ export class TestTigrisService {
.setSchema("schema" + index)
);
}
result.setMetadata(new DatabaseMetadata()).setCollectionsList(collectionsDescription);
result
.setMetadata(new DatabaseMetadata())
.setCollectionsList(collectionsDescription)
.setBranchesList(["main", "staging", TestTigrisService.ExpectedBranch]);
callback(undefined, result);
},

dropCollection(
call: ServerUnaryCall<DropCollectionRequest, DropCollectionResponse>,
callback: sendUnaryData<DropCollectionResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

const newCollections = TestTigrisService.COLLECTION_MAP.get(call.request.getProject()).filter(
(coll) => coll !== call.request.getCollection()
);
Expand All @@ -317,6 +370,8 @@ export class TestTigrisService {
call: ServerUnaryCall<InsertRequest, InsertResponse>,
callback: sendUnaryData<InsertResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

if (call.request.getProject() === "test-tx") {
const txIdHeader = call.metadata.get("Tigris-Tx-Id").toString();
const txOriginHeader = call.metadata.get("Tigris-Tx-Origin").toString();
Expand Down Expand Up @@ -356,6 +411,8 @@ export class TestTigrisService {
call: ServerUnaryCall<ListCollectionsRequest, ListCollectionsResponse>,
callback: sendUnaryData<ListCollectionsResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

const reply: ListCollectionsResponse = new ListCollectionsResponse();
const collectionInfos: CollectionInfo[] = [];
for (
Expand Down Expand Up @@ -389,8 +446,9 @@ export class TestTigrisService {
reply.setProjectsList(databaseInfos);
callback(undefined, reply);
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
read(call: ServerWritableStream<ReadRequest, ReadResponse>): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

if (call.request.getProject() === "test-tx") {
const txIdHeader = call.metadata.get("Tigris-Tx-Id").toString();
const txOriginHeader = call.metadata.get("Tigris-Tx-Origin").toString();
Expand Down Expand Up @@ -453,8 +511,9 @@ export class TestTigrisService {
call.end();
}
},
// eslint-disable-next-line @typescript-eslint/no-empty-function
search(call: ServerWritableStream<SearchRequest, SearchResponse>): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

const searchMeta = new SearchMetadata().setFound(5).setTotalPages(5);

// paginated search impl
Expand Down Expand Up @@ -500,13 +559,12 @@ export class TestTigrisService {
call.end();
}
},
/* eslint-disable @typescript-eslint/no-empty-function */
replace(
// eslint-disable-next-line @typescript-eslint/no-unused-vars
call: ServerUnaryCall<ReplaceRequest, ReplaceResponse>,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
callback: sendUnaryData<ReplaceResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

if (call.request.getProject() === "test-tx") {
const txIdHeader = call.metadata.get("Tigris-Tx-Id").toString();
const txOriginHeader = call.metadata.get("Tigris-Tx-Origin").toString();
Expand Down Expand Up @@ -543,15 +601,18 @@ export class TestTigrisService {
call: ServerUnaryCall<RollbackTransactionRequest, RollbackTransactionResponse>,
callback: sendUnaryData<RollbackTransactionResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

const reply: RollbackTransactionResponse = new RollbackTransactionResponse();
reply.setStatus("rollback-test");
callback(undefined, reply);
},
/* eslint-enable @typescript-eslint/no-empty-function */
update(
call: ServerUnaryCall<UpdateRequest, UpdateResponse>,
callback: sendUnaryData<UpdateResponse>
): void {
assert(call.request.getBranch() === TestTigrisService.ExpectedBranch);

if (call.request.getProject() === "test-tx") {
const txIdHeader = call.metadata.get("Tigris-Tx-Id").toString();
const txOriginHeader = call.metadata.get("Tigris-Tx-Origin").toString();
Expand Down Expand Up @@ -582,3 +643,8 @@ export default {
service: TigrisService,
handler: new TestTigrisService(),
};

export enum Branch {
Existing = "existing",
NotFound = "no-project",
}
Loading

0 comments on commit 45db10a

Please sign in to comment.