Skip to content

Commit ca79250

Browse files
authored
feature: project payment (#1)
* feat: add project, resource, payment schema * fix: use id_column, id_sequence from schema definition * feat: use @topcoder-framework/lib-client for rdb types * feat: switch to @topcoder-framework/lib-common and @topcoder-framwork/client-relational
1 parent 73f1663 commit ca79250

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+467
-6879
lines changed

bin/nosql-client.js

Lines changed: 0 additions & 35 deletions
This file was deleted.

bin/rdb-client.js

Lines changed: 0 additions & 33 deletions
This file was deleted.

bin/server.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable */
12
const path = require("path");
23
const rimraf = require("rimraf");
34

@@ -7,26 +8,31 @@ const PROTO_DIR = path.join(__dirname, "../node_modules/topcoder-interface");
78
const PROTO_REFLECTIONS = path.join(__dirname, "../reflections/reflection.bin");
89

910
const MODEL_DIR = path.join(__dirname, "../src/models/");
10-
1111
const PROTOC_PATH = "protoc";
1212
const PLUGIN_PATH = path.join(__dirname, "../node_modules/.bin/protoc-gen-ts_proto");
1313

1414
rimraf.sync(`${MODEL_DIR}/*`, {
15-
glob: { ignore: `${MODEL_DIR}/tsconfig.json` },
15+
glob: { ignore: `${MODEL_DIR}/*.json` },
1616
});
1717

1818
const protoConfig = [
1919
`--plugin=${PLUGIN_PATH}`,
2020
// https://github.com/stephenh/ts-proto/blob/main/README.markdown
2121
"--ts_proto_opt=outputServices=grpc-js,env=node,useOptionals=messages,exportCommonSymbols=false,esModuleInterop=true",
22-
`--ts_proto_out=${MODEL_DIR}`,
22+
`--ts_proto_opt=stringEnums=true`,
23+
`--ts_proto_opt=useDate=string`,
2324
`--ts_proto_opt=oneof=unions`,
2425
`--ts_proto_opt=addGrpcMetadata=true`,
2526
`--ts_proto_opt=outputClientImpl=false`,
26-
`--ts_proto_opt=useDate=string`,
27-
`--include_imports`,
2827
`--descriptor_set_out ${PROTO_REFLECTIONS}`,
29-
`--proto_path ${PROTO_DIR} ${PROTO_DIR}/domain-layer/legacy/**/*.proto`,
28+
`--include_imports`,
29+
`--ts_proto_opt=Mcommon/common.proto=@topcoder-framework/lib-common`,
30+
`--ts_proto_opt=Mgoogle/protobuf/struct.proto=@topcoder-framework/lib-common`,
31+
`--ts_proto_opt=Mgoogle/protobuf/timestamp.proto=@topcoder-framework/lib-common`,
32+
`--ts_proto_opt=Mgoogle/protobuf/empty.proto=@topcoder-framework/lib-common`,
33+
`--proto_path ${PROTO_DIR} ${PROTO_DIR}/domain-layer/legacy/*.proto`,
34+
`--proto_path ${PROTO_DIR} ${PROTO_DIR}/domain-layer/legacy/services/*.proto`,
35+
`--ts_proto_out=${MODEL_DIR}`,
3036
];
3137

3238
// https://github.com/stephenh/ts-proto#usage

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,20 @@
44
"description": "",
55
"main": "index.js",
66
"scripts": {
7-
"build:proto:client:nosql": "node bin/nosql-client",
8-
"build:proto:client:rdb": "node bin/rdb-client",
97
"build:proto:server": "node bin/server",
10-
"build:proto": "node bin/rdb-client && node bin/nosql-client && node bin/server",
8+
"build:proto": "node bin/server",
119
"build:app": "rimraf dist && tsc -b",
12-
"build": "node bin/rdb-client && node bin/nosql-client && node bin/server && rimraf dist && tsc -b",
10+
"build": "node bin/server && rimraf dist && tsc -b",
11+
"clean": "rimraf dist",
1312
"start": "ts-node-dev --respawn --transpile-only src/server.ts"
1413
},
1514
"keywords": [],
1615
"author": "Rakib Ansary <rakibansary@topcoder.com>",
1716
"license": "ISC",
1817
"dependencies": {
1918
"@grpc/grpc-js": "^1.7.1",
19+
"@topcoder-framework/client-relational": "^0.4.23-ci.0",
20+
"@topcoder-framework/lib-common": "^0.4.23-ci.0",
2021
"dayjs": "^1.11.5",
2122
"dotenv": "^16.0.3",
2223
"grpc-server-reflection": "^0.1.5",

src/common/QueryRunner.ts

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
/* TODO:
2-
1. Move this to @topcoder-framework
3-
2. Cleanup the exported interfaces
4-
3. Make "Client" a constructor parameter that implements a "Client" interface
5-
4 "ExecuteSqlQuery" should return a Promise<T> where T is the type of the result for "read" queries, but should return "number" for "write" queries indicating either
6-
a) the number of rows affected or
7-
b) the ID of the row insertede
8-
*/
9-
10-
import { ColumnType, Operator, Query, QueryRequest, Value } from "../grpc/models/rdb/relational";
11-
12-
import { relationalClient } from "../grpc/client/relational";
13-
import { TableColumns, TableColumn } from "./TableColumn";
1+
const { GRPC_RDB_SERVER_HOST, GRPC_RDB_SERVER_PORT } = process.env;
2+
3+
import {
4+
ColumnType,
5+
Operator,
6+
Query,
7+
QueryRequest,
8+
RelationalClient,
9+
Value,
10+
} from "@topcoder-framework/client-relational";
11+
import { TableColumn, TableColumns } from "./TableColumn";
1412

1513
export type Schema = {
1614
dbSchema: string;
@@ -26,21 +24,18 @@ interface ExecuteSqlQuery {
2624
}
2725

2826
type JoinAndWhereClause = JoinClause & WhereClause & ExecuteSqlQuery;
27+
type JoinWhereLimitAndOffset = JoinAndWhereClause & LimitClause & OffsetClause;
2928

3029
export interface SelectQuery {
31-
select(columns: TableColumn[]): JoinAndWhereClause & LimitClause & OffsetClause;
30+
select(columns: TableColumn[]): JoinWhereLimitAndOffset;
3231
}
3332

3433
export interface JoinClause {
3534
join(): JoinAndWhereClause;
3635
}
3736

3837
export interface WhereClause {
39-
where(whereCriteria: {
40-
key: string,
41-
operator: Operator,
42-
value: Value
43-
}): JoinAndWhereClause & LimitClause & OffsetClause;
38+
where(whereCriteria: { key: string; operator: Operator; value: Value }): JoinWhereLimitAndOffset;
4439
}
4540

4641
export interface LimitClause {
@@ -56,26 +51,37 @@ export interface InsertQuery<CreateInput> {
5651
}
5752

5853
export interface UpdateQuery<UpdateInput> {
59-
update(lookupCriteria: {[key: string]: unknown} ,input: UpdateInput): ExecuteSqlQuery;
54+
update(lookupCriteria: { [key: string]: unknown }, input: UpdateInput): ExecuteSqlQuery;
6055
}
6156

6257
export interface DeleteQuery {
6358
delete(): ExecuteSqlQuery;
6459
}
6560

66-
export class QueryRunner<T, CreateInput extends {[key: string]: unknown}, UpdateInput extends {[key: string]: unknown}>
67-
implements
68-
SelectQuery, JoinClause, WhereClause, LimitClause, OffsetClause,
61+
export class QueryRunner<
62+
T,
63+
CreateInput extends { [key: string]: unknown },
64+
UpdateInput extends { [key: string]: unknown }
65+
> implements
66+
SelectQuery,
67+
JoinClause,
68+
WhereClause,
69+
LimitClause,
70+
OffsetClause,
6971
InsertQuery<CreateInput>,
7072
UpdateQuery<UpdateInput>,
7173
DeleteQuery,
7274
ExecuteSqlQuery
7375
{
7476
#query: Query | null = null;
77+
#client: RelationalClient;
7578

76-
constructor(private schema: Schema) {}
79+
constructor(private schema: Schema) {
80+
console.log("Connecting to GRPC server at", GRPC_RDB_SERVER_HOST, GRPC_RDB_SERVER_PORT, "...");
81+
this.#client = new RelationalClient(GRPC_RDB_SERVER_HOST!, parseInt(GRPC_RDB_SERVER_PORT!));
82+
}
7783

78-
select(columns: TableColumn[]): JoinAndWhereClause & LimitClause & OffsetClause {
84+
select(columns: TableColumn[]): JoinWhereLimitAndOffset {
7985
this.#query = {
8086
query: {
8187
$case: "select",
@@ -85,7 +91,7 @@ export class QueryRunner<T, CreateInput extends {[key: string]: unknown}, Update
8591
column: columns.map((col) => ({
8692
tableName: this.schema.tableName,
8793
name: col.name,
88-
type: col.type
94+
type: col.type,
8995
})),
9096
where: [],
9197
join: [],
@@ -96,15 +102,13 @@ export class QueryRunner<T, CreateInput extends {[key: string]: unknown}, Update
96102
},
97103
},
98104
};
105+
106+
console.log("Query", JSON.stringify(this.#query, null, 2));
99107
return this;
100108
}
101109

102110
// TODO: use "convenience" methods from lib-util to build the clause
103-
where(whereCriteria: {
104-
key: string,
105-
operator: Operator,
106-
value: Value
107-
}): JoinAndWhereClause & LimitClause & OffsetClause {
111+
where(whereCriteria: { key: string; operator: Operator; value: Value }): JoinWhereLimitAndOffset {
108112
if (this.#query?.query?.$case != "select") {
109113
throw new Error("Cannot set where clause on a non-select query");
110114
}
@@ -119,15 +123,15 @@ export class QueryRunner<T, CreateInput extends {[key: string]: unknown}, Update
119123
}
120124

121125
limit(limit: number): OffsetClause & ExecuteSqlQuery {
122-
if (this.#query?.query?.$case != "select") {
126+
if (this.#query?.query?.$case != "select") {
123127
throw new Error("Cannot set limit on a non-select query");
124128
}
125129
this.#query.query.select.limit = limit;
126130
return this;
127131
}
128132

129133
offset(offset: number): ExecuteSqlQuery {
130-
if (this.#query?.query?.$case != "select") {
134+
if (this.#query?.query?.$case != "select") {
131135
throw new Error("Cannot set offset on a non-select query");
132136
}
133137
this.#query.query.select.offset = offset;
@@ -168,8 +172,8 @@ export class QueryRunner<T, CreateInput extends {[key: string]: unknown}, Update
168172
})),
169173
],
170174
idTable: this.schema.tableName,
171-
idColumn: "project_phase_id",
172-
idSequence: "project_phase_id_seq",
175+
idColumn: this.schema.idColumn ?? undefined,
176+
idSequence: this.schema.idSequence ?? undefined,
173177
},
174178
},
175179
};
@@ -194,7 +198,7 @@ export class QueryRunner<T, CreateInput extends {[key: string]: unknown}, Update
194198
query: this.#query,
195199
};
196200

197-
const queryResponse = await relationalClient.query(queryRequest);
201+
const queryResponse = await this.#client.query(queryRequest);
198202

199203
switch (this.#query.query?.$case) {
200204
case "select":

src/common/TableColumn.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ColumnType } from "../../dist/grpc/models/rdb/relational";
1+
import { ColumnType } from "@topcoder-framework/client-relational";
22

33
export type TableColumn = {
44
name: string;

src/domain/LegacyChallenge.ts

Lines changed: 4 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,10 @@
1-
import _ from "lodash";
1+
import { ColumnType, Operator, QueryRequest } from "@topcoder-framework/client-relational";
2+
import { Value } from "@topcoder-framework/lib-common";
23
import { QueryRunner } from "../common/QueryRunner";
3-
4-
import { relationalClient } from "../grpc/client/relational";
5-
import { ColumnType, Operator, QueryRequest, QueryResponse } from "../grpc/models/rdb/relational";
6-
import { CheckChallengeExistsResponse } from "../models/domain-layer/legacy/legacy_challenge";
7-
import { Value } from "../models/google/protobuf/struct";
8-
import { Project } from "../schema/Project";
4+
import { CheckChallengeExistsResponse } from "../models/domain-layer/legacy/challenge";
5+
import { Project } from "../schema/project/Project";
96

107
class LegacyChallengeDomain {
11-
constructor(private tableName: string = "project") {}
12-
13-
// public async lookup(lookupCriteria: LookupCriteria): Promise<LegacyChallenge[]> {
14-
// const queryRequest: QueryRequest = {
15-
// query: {
16-
// query: {
17-
// $case: "select",
18-
// select: {
19-
// table: this.tableName,
20-
// join: [],
21-
// column: [
22-
// {
23-
// name: "project_id",
24-
// type: ColumnType.COLUMN_TYPE_INT,
25-
// },
26-
// ],
27-
// where: [
28-
// {
29-
// key: "project_id",
30-
// operator: Operator.OPERATOR_EQUAL,
31-
// value: {
32-
// value: {
33-
// $case: "intValue",
34-
// intValue: 123,
35-
// },
36-
// },
37-
// },
38-
// ],
39-
// groupBy: [],
40-
// orderBy: [],
41-
// limit: 1,
42-
// offset: 0,
43-
// },
44-
// },
45-
// },
46-
// };
47-
48-
// const queryResponse: QueryResponse = await relationalClient.query(queryRequest);
49-
50-
// if (queryResponse.result?.$case == "selectResult") {
51-
// const rows = queryResponse.result.selectResult.rows;
52-
// return rows.map((row) => LegacyChallenge.fromJSON(row.values));
53-
// }
54-
55-
// return [];
56-
// }
57-
588
public async checkChallengeExists(
599
legacyChallengeId: number
6010
): Promise<CheckChallengeExistsResponse> {

0 commit comments

Comments
 (0)