JS 方法链接控制流程
JS Method Chaining Controlling Flow
我在 Typescript 中创建了一个方法,它利用方法链来创建一个简单的 sql 查询生成器。它实现了基本的查询方法。我想做的是不允许有人调用偏移方法,例如,如果他们之前没有调用 limit 或调用 where 两次。我知道我可以通过一个存储以前调用的方法的映射来实现一些东西,但我想知道是否有一个干净的解决方案来解决这个问题。我当前的查询生成器方法是
public qb = () =>
{
let query = this.SELECT;
const api = {
where: (key: string, value: number|string) =>
{
query = sql`${query} WHERE ${sql.identifier([key])} = ${value}`;
return api;
},
and: (key: string, value: number|string) =>
{
query = sql`${query} AND ${sql.identifier([key])} = ${value}`;
return api;
},
orderBy: (key: string, order: 'ASC'|'DESC') =>
{
query = sql`${query} ORDER BY ${sql.identifier([key])} ${order}`;
return api;
},
limit: (limit: number) =>
{
query = sql`${query} LIMIT ${limit}`;
return api;
},
offset: (offset: number) =>
{
query = sql`${query} OFFSET ${offset}`;
return api;
},
get: async () => this.rowMapper(await this.database.query(query)),
};
return api;
};
是否有强制方法链流动的好方法?
我最终采用的解决方案是创建多个内部具有不同方法的对象。该解决方案不是最干净的,但我找不到更好的解决方案
public qb = () =>
{
let query = this.SELECT;
const get = async () => this.rowMapper(await this.database.query(query));
const limit = (_limit: number) =>
{
query = sql`${query} LIMIT ${_limit}`;
return {
offset: (offset: number) =>
{
query = sql`${query} OFFSET ${offset}`;
return { get };
},
get,
};
};
const api2 = {
and: (key: string, value: number|string) =>
{
query = sql`${query} AND ${sql.identifier([key])} = ${value}`;
return api2;
},
orderBy: (key: string, order: 'ASC'|'DESC') =>
{
query = sql`${query} ORDER BY ${sql.identifier([key])} ${order}`;
return {
limit,
get,
};
},
limit,
get,
};
const api = {
where: (key: string, value: number|string) =>
{
query = sql`${query} WHERE ${sql.identifier([key])} = ${value}`;
return api2;
},
};
return api;
};
我在 Typescript 中创建了一个方法,它利用方法链来创建一个简单的 sql 查询生成器。它实现了基本的查询方法。我想做的是不允许有人调用偏移方法,例如,如果他们之前没有调用 limit 或调用 where 两次。我知道我可以通过一个存储以前调用的方法的映射来实现一些东西,但我想知道是否有一个干净的解决方案来解决这个问题。我当前的查询生成器方法是
public qb = () =>
{
let query = this.SELECT;
const api = {
where: (key: string, value: number|string) =>
{
query = sql`${query} WHERE ${sql.identifier([key])} = ${value}`;
return api;
},
and: (key: string, value: number|string) =>
{
query = sql`${query} AND ${sql.identifier([key])} = ${value}`;
return api;
},
orderBy: (key: string, order: 'ASC'|'DESC') =>
{
query = sql`${query} ORDER BY ${sql.identifier([key])} ${order}`;
return api;
},
limit: (limit: number) =>
{
query = sql`${query} LIMIT ${limit}`;
return api;
},
offset: (offset: number) =>
{
query = sql`${query} OFFSET ${offset}`;
return api;
},
get: async () => this.rowMapper(await this.database.query(query)),
};
return api;
};
是否有强制方法链流动的好方法?
我最终采用的解决方案是创建多个内部具有不同方法的对象。该解决方案不是最干净的,但我找不到更好的解决方案
public qb = () =>
{
let query = this.SELECT;
const get = async () => this.rowMapper(await this.database.query(query));
const limit = (_limit: number) =>
{
query = sql`${query} LIMIT ${_limit}`;
return {
offset: (offset: number) =>
{
query = sql`${query} OFFSET ${offset}`;
return { get };
},
get,
};
};
const api2 = {
and: (key: string, value: number|string) =>
{
query = sql`${query} AND ${sql.identifier([key])} = ${value}`;
return api2;
},
orderBy: (key: string, order: 'ASC'|'DESC') =>
{
query = sql`${query} ORDER BY ${sql.identifier([key])} ${order}`;
return {
limit,
get,
};
},
limit,
get,
};
const api = {
where: (key: string, value: number|string) =>
{
query = sql`${query} WHERE ${sql.identifier([key])} = ${value}`;
return api2;
},
};
return api;
};