Skip to content

Commit

Permalink
Merge pull request #383 from tigrisdata/main
Browse files Browse the repository at this point in the history
Merged by Reviewpad
  • Loading branch information
reviewpad[bot] authored Jun 23, 2023
2 parents 2ccb59b + aa6ffc2 commit a6439df
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/__tests__/fixtures/json-schema/search/orders.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,8 @@
}
}
}
},
"options": {
"token_separators": ["/"]
}
}
2 changes: 1 addition & 1 deletion src/__tests__/fixtures/schema/search/orders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class OrderStatus {
createdAt: Date;
}

@TigrisSearchIndex(ORDERS_INDEX_NAME)
@TigrisSearchIndex(ORDERS_INDEX_NAME, { tokenSeparators: ["/"] })
export class Order {
@SearchField(TigrisDataTypes.UUID, { sort: true })
orderId: string;
Expand Down
8 changes: 6 additions & 2 deletions src/__tests__/search/schema.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import { DecoratedSchemaProcessor, IndexSchema } from "../../schema/decorated-sc
import { MATRICES_INDEX_NAME, Matrix, MatrixSchema } from "../fixtures/schema/search/matrices";
import { TigrisCollection } from "../../decorators/tigris-collection";
import { Field } from "../../decorators/tigris-field";
import { TigrisDataTypes } from "../../types";
import { SearchIndexOptions, TigrisDataTypes } from "../../types";
import { IncorrectVectorDefError } from "../../error";

type SchemaTestCase<T extends TigrisIndexType> = {
schemaClass: T;
expectedSchema: TigrisIndexSchema<any>;
name: string;
expectedJSON: string;
expectedOptions?: SearchIndexOptions;
};

const schemas: Array<SchemaTestCase<any>> = [
Expand All @@ -22,12 +23,14 @@ const schemas: Array<SchemaTestCase<any>> = [
expectedSchema: OrderSchema,
name: ORDERS_INDEX_NAME,
expectedJSON: "orders.json",
expectedOptions: { tokenSeparators: ["/"] },
},
{
schemaClass: Matrix,
expectedSchema: MatrixSchema,
name: MATRICES_INDEX_NAME,
expectedJSON: "matrices.json",
expectedOptions: undefined,
},
];

Expand All @@ -37,10 +40,11 @@ describe.each(schemas)("Schema conversion for: '$name'", (tc) => {
test("Convert decorated class to TigrisSchema", () => {
const generated: IndexSchema<unknown> = processor.processIndex(tc.schemaClass);
expect(generated.schema).toStrictEqual(tc.expectedSchema);
expect(generated.options).toStrictEqual(tc.expectedOptions);
});

test("Convert TigrisIndexSchema to JSON spec", () => {
expect(Utility._indexSchematoJSON(tc.name, tc.expectedSchema)).toBe(
expect(Utility._indexSchematoJSON(tc.name, tc.expectedSchema, tc.expectedOptions)).toBe(
readJSONFileAsObj("src/__tests__/fixtures/json-schema/search/" + tc.expectedJSON)
);
});
Expand Down
8 changes: 8 additions & 0 deletions src/__tests__/tigris.rpc.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,7 @@ describe("rpc tests", () => {

describe("DB branching", () => {
const tigris = new Tigris(testConfig);
const mockedUtil = spy(Utility);

it("creates a new branch", async () => {
expect.hasAssertions();
Expand All @@ -1033,6 +1034,13 @@ describe("rpc tests", () => {
return expect(createResp).rejects.toBeDefined();
});

it("fails to create branch if project does not exist", async () => {
when(mockedUtil.branchNameFromEnv(anything())).thenReturn(Branch.NotFound);
const db = tigris.getDatabase();

return expect(db.createBranch(Branch.NotFound)).rejects.toThrow(Error);
});

it("deletes a branch successfully", async () => {
expect.hasAssertions();
const db = tigris.getDatabase();
Expand Down
4 changes: 4 additions & 0 deletions src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ export class DB {
const req = new ProtoCreateBranchRequest().setProject(this.name).setBranch(name);
this.grpcClient.createBranch(req, (error, response) => {
if (error) {
if (error.code === Status.NOT_FOUND) {
const error_message = `The project ${this.name} could not be found. Please ensure ${this.name} exists in your Tigris deployment or target Tigris region.`;
Log.error(error_message);
}
reject(error);
return;
}
Expand Down
3 changes: 3 additions & 0 deletions src/decorators/metadata/search-index-metadata.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { SearchIndexOptions } from "../../types";

/**@internal*/
export interface SearchIndexMetadata {
readonly indexName: string;
readonly target: Function;
readonly options: SearchIndexOptions;
}
5 changes: 4 additions & 1 deletion src/decorators/tigris-search-index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { getDecoratorMetaStorage } from "../globals";
import { SearchIndexOptions } from "../types";

/**
* TigrisSearchIndex decorator is used to mark a class as a schema/data model for Search Index.
*
* @param name - Name of Index
* @param options - Search index options
*/
export function TigrisSearchIndex(name: string): ClassDecorator {
export function TigrisSearchIndex(name: string, options?: SearchIndexOptions): ClassDecorator {
return function (target) {
getDecoratorMetaStorage().indexes.push({
indexName: name,
target: target,
options: options,
});
};
}
3 changes: 3 additions & 0 deletions src/schema/decorated-schema-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { DecoratorMetaStorage } from "../decorators/metadata/decorator-meta-stor
import { getDecoratorMetaStorage } from "../globals";
import {
CollectionFieldOptions,
SearchIndexOptions,
TigrisCollectionType,
TigrisDataTypes,
TigrisSchema,
Expand All @@ -20,6 +21,7 @@ export type CollectionSchema<T extends TigrisCollectionType> = {
export type IndexSchema<T extends TigrisIndexType> = {
name: string;
schema: TigrisIndexSchema<T>;
options?: SearchIndexOptions;
};

/** @internal */
Expand Down Expand Up @@ -47,6 +49,7 @@ export class DecoratedSchemaProcessor {
return {
name: index.indexName,
schema: schema as TigrisIndexSchema<typeof cls>,
options: index.options,
};
}

Expand Down
5 changes: 4 additions & 1 deletion src/search/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ListIndexesRequest as ProtoListIndexesRequest,
} from "../proto/server/v1/search_pb";
import { DecoratedSchemaProcessor } from "../schema/decorated-schema-processor";
import { SearchIndexOptions } from "../types";

export class Search {
private readonly client: SearchClient;
Expand Down Expand Up @@ -37,6 +38,7 @@ export class Search {
let indexName: string;
let mayBeClass: new () => TigrisIndexType;
let schema: TigrisIndexSchema<T>;
let schemaOptions: SearchIndexOptions;

if (typeof nameOrClass === "string") {
indexName = nameOrClass as string;
Expand Down Expand Up @@ -65,9 +67,10 @@ export class Search {
schema = generatedIndex.schema as TigrisIndexSchema<T>;
// if indexName is not provided, use the one from model class
indexName = indexName ?? generatedIndex.name;
schemaOptions = generatedIndex.options;
}

const rawJSONSchema: string = Utility._indexSchematoJSON(indexName, schema);
const rawJSONSchema: string = Utility._indexSchematoJSON(indexName, schema, schemaOptions);
const createOrUpdateIndexRequest = new ProtoCreateIndexRequest()
.setProject(this.projectName)
.setName(indexName)
Expand Down
4 changes: 4 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,10 @@ export type PrimaryKeyOptions = {
autoGenerate?: boolean;
};

export type SearchIndexOptions = {
tokenSeparators?: Array<string>;
};

/**
* Generates all possible paths for type parameter T. By recursively iterating over its keys. While
* iterating the keys it makes the keys available in string form and in non string form both. For
Expand Down
12 changes: 11 additions & 1 deletion src/utility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
FindQueryOptions,
GroupByField,
ReadFields,
SearchIndexOptions,
SortOrder,
TigrisDataTypes,
TigrisSchema,
Expand Down Expand Up @@ -211,9 +212,18 @@ export const Utility = {
return toReturn;
},

_indexSchematoJSON<T>(indexName: string, schema: TigrisIndexSchema<T>): string {
_indexSchematoJSON<T>(
indexName: string,
schema: TigrisIndexSchema<T>,
options?: SearchIndexOptions
): string {
const root = { title: indexName, type: "object" };
root["properties"] = this._getSchemaProperties(schema, {}, {});
if (options && Array.isArray(options.tokenSeparators) && options.tokenSeparators.length > 0) {
root["options"] = {
token_separators: options.tokenSeparators,
};
}
return Utility.objToJsonString(root);
},

Expand Down

0 comments on commit a6439df

Please sign in to comment.