Creé un método en Typescript que utiliza el encadenamiento de métodos para crear un generador de consultas sql simple. Implementa los métodos básicos de consulta. Lo que me gustaría hacer es no permitir que alguien llame al método de compensación, por ejemplo, si no ha llamado al límite anteriormente o ha llamado a donde dos veces. Sé que puedo implementar algo a través de un mapa que almacena los métodos llamados anteriormente, pero me preguntaba si existe una solución limpia para este problema. Mi método de generación de consultas actual es
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; };¿Hay alguna forma agradable de forzar el flujo del encadenamiento de métodos?
La solución con la que terminé es crear múltiples objetos que tienen diferentes métodos dentro de ellos. La solución no es la más limpia pero no pude encontrar una mejor
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; };