From ccd0b172c336705691be9153867a38453503efcc Mon Sep 17 00:00:00 2001 From: Gwynn DP Date: Sun, 17 Oct 2021 17:31:09 -0700 Subject: [PATCH 1/5] refactor: create mixin to share helper functions across repos --- src/controllers/organization.controller.ts | 10 +- src/controllers/planter.controller.ts | 2 + .../planterOrganization.controller.ts | 12 +- src/controllers/trees.controller.ts | 2 + .../treesOrganization.controller.ts | 2 + src/mixins/utils.repository-mixin.ts | 122 ++++++++++++++++++ src/repositories/organization.repository.ts | 44 ++----- src/repositories/planter.repository.ts | 89 ++----------- src/repositories/trees.repository.ts | 75 ++--------- 9 files changed, 173 insertions(+), 185 deletions(-) create mode 100644 src/mixins/utils.repository-mixin.ts diff --git a/src/controllers/organization.controller.ts b/src/controllers/organization.controller.ts index bbd62fa0..714363de 100644 --- a/src/controllers/organization.controller.ts +++ b/src/controllers/organization.controller.ts @@ -83,10 +83,12 @@ export class OrganizationController { // create query to get all orgs and their planters if (filter?.where) { - filter.where = await this.organizationRepository.applyOrganizationWhereClause( - filter.where, - organizationId.valueOf(), - ); + filter.where = + await this.organizationRepository.applyOrganizationWhereClause( + filter.where, + organizationId.valueOf(), + 'orgs', + ); } const childOrgs = await this.organizationRepository.find(filter); diff --git a/src/controllers/planter.controller.ts b/src/controllers/planter.controller.ts index 942c8f4f..324f5b81 100644 --- a/src/controllers/planter.controller.ts +++ b/src/controllers/planter.controller.ts @@ -54,6 +54,7 @@ export class PlanterController { where = await this.planterRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, organizationId, + 'planter', ); } // console.log('get /planter/count where -->', where); @@ -85,6 +86,7 @@ export class PlanterController { filter.where = await this.planterRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, organizationId, + 'planter', ); } diff --git a/src/controllers/planterOrganization.controller.ts b/src/controllers/planterOrganization.controller.ts index 40f4eb58..d2205c89 100644 --- a/src/controllers/planterOrganization.controller.ts +++ b/src/controllers/planterOrganization.controller.ts @@ -62,9 +62,8 @@ export class PlanterOrganizationController { const filterOrgId = organizationId; if (filterOrgId && filterOrgId !== orgId) { - const entityIds = await this.planterRepository.getEntityIdsByOrganizationId( - orgId, - ); + const entityIds = + await this.planterRepository.getEntityIdsByOrganizationId(orgId); orgId = entityIds.includes(filterOrgId) ? filterOrgId : orgId; } @@ -72,6 +71,7 @@ export class PlanterOrganizationController { where = await this.planterRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, orgId, + 'planter', ); } @@ -103,9 +103,8 @@ export class PlanterOrganizationController { const filterOrgId = organizationId; if (filterOrgId && filterOrgId !== orgId) { - const entityIds = await this.planterRepository.getEntityIdsByOrganizationId( - orgId, - ); + const entityIds = + await this.planterRepository.getEntityIdsByOrganizationId(orgId); orgId = entityIds.includes(filterOrgId) ? filterOrgId : orgId; } @@ -113,6 +112,7 @@ export class PlanterOrganizationController { filter.where = await this.planterRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, orgId, + 'planter', ); } diff --git a/src/controllers/trees.controller.ts b/src/controllers/trees.controller.ts index 888bef75..b2019266 100644 --- a/src/controllers/trees.controller.ts +++ b/src/controllers/trees.controller.ts @@ -57,6 +57,7 @@ export class TreesController { where = await this.treesRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, organizationId, + 'trees', ); } @@ -90,6 +91,7 @@ export class TreesController { filter.where = await this.treesRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, organizationId, + 'trees', ); } diff --git a/src/controllers/treesOrganization.controller.ts b/src/controllers/treesOrganization.controller.ts index 5a0575fd..3226aa3b 100644 --- a/src/controllers/treesOrganization.controller.ts +++ b/src/controllers/treesOrganization.controller.ts @@ -61,6 +61,7 @@ export class TreesOrganizationController { where = await this.treesRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, orgId, + 'trees', ); } @@ -100,6 +101,7 @@ export class TreesOrganizationController { filter.where = await this.treesRepository.applyOrganizationWhereClause( whereWithoutOrganizationId, orgId, + 'trees', ); } diff --git a/src/mixins/utils.repository-mixin.ts b/src/mixins/utils.repository-mixin.ts new file mode 100644 index 00000000..33ef8305 --- /dev/null +++ b/src/mixins/utils.repository-mixin.ts @@ -0,0 +1,122 @@ +import { MixinTarget } from '@loopback/core'; +import { CrudRepository, Model } from '@loopback/repository'; +import expect from 'expect-runtime'; +import { buildFilterQuery } from '../js/buildFilterQuery'; +import { utils } from '../js/utils'; + +export function UtilsRepositoryMixin< + M extends Model, + R extends MixinTarget>, +>(superClass: R) { + return class extends superClass { + [x: string]: any; + // put the shared code here + async getEntityIdsByOrganizationId( + organizationId: number, + ): Promise> { + expect(organizationId).number(); + expect(this).property('execute').defined(); + const result = await this.execute( + `select * from getEntityRelationshipChildren(${organizationId})`, + [], + ); + return result.map((e) => e.entity_id); + } + + async applyOrganizationWhereClause( + where: Object | undefined, + organizationId: number | undefined, + model: string, + ): Promise { + if (!where || organizationId === undefined) { + return Promise.resolve(where); + } + + // if planter or tree repository request + if (model === 'trees' || model === 'planter') { + const organizationWhereClause = await this.getOrganizationWhereClause( + organizationId, + model, + ); + return { + and: [where, organizationWhereClause], + }; + } else { + const entityIds = await this.getEntityIdsByOrganizationId( + organizationId, + ); + return { + and: [where, { id: { inq: entityIds } }], + }; + } + } + + async getPlanterIdsByOrganizationId( + organizationId: number, + ): Promise> { + expect(organizationId).number(); + const result = await this.execute( + `select * from planter where organization_id in (select entity_id from getEntityRelationshipChildren(${organizationId}))`, + [], + ); + expect(result).match([{ id: expect.any(Number) }]); + return result.map((e) => e.id); + } + + async getNonOrganizationPlanterIds(): Promise> { + const result = await this.execute( + `select * from planter where organization_id isnull`, + [], + ); + expect(result).match([{ id: expect.any(Number) }]); + return result.map((e) => e.id); + } + + async getOrganizationWhereClause( + organizationId: number, + model: string, + ): Promise { + if (organizationId === null) { + const planterIds = await this.getNonOrganizationPlanterIds(); + // if planter repository request + if (model === 'planter') { + return { + or: [{ organizationId: null }, { id: { inq: planterIds } }], + }; + } else { + // if trees or other repository request + return { + or: [ + { plantingOrganizationId: null }, + { planterId: { inq: planterIds } }, + ], + }; + } + } else { + const planterIds = await this.getPlanterIdsByOrganizationId( + organizationId, + ); + const entityIds = await this.getEntityIdsByOrganizationId( + organizationId, + ); + // if planter repository request + if (model === 'planter') { + return { + or: [ + { organizationId: { inq: entityIds } }, + { id: { inq: planterIds } }, + ], + }; + } else { + // if trees or other repository request + return { + or: [ + { plantingOrganizationId: { inq: entityIds } }, + { planterId: { inq: planterIds } }, + ], + }; + } + } + } + }; +} diff --git a/src/repositories/organization.repository.ts b/src/repositories/organization.repository.ts index 423cc87e..e9742ef4 100644 --- a/src/repositories/organization.repository.ts +++ b/src/repositories/organization.repository.ts @@ -1,42 +1,22 @@ +import { Constructor, inject } from '@loopback/core'; import { DefaultCrudRepository } from '@loopback/repository'; -import { Organization, OrganizationRelations } from '../models'; import { TreetrackerDataSource } from '../datasources'; -import { inject } from '@loopback/core'; -import expect from 'expect-runtime'; +import { UtilsRepositoryMixin } from '../mixins/utils.repository-mixin'; +import { Organization, OrganizationRelations } from '../models'; -export class OrganizationRepository extends DefaultCrudRepository< +export class OrganizationRepository extends UtilsRepositoryMixin< Organization, - typeof Organization.prototype.id, - OrganizationRelations -> { + Constructor< + DefaultCrudRepository< + Organization, + typeof Organization.prototype.id, + OrganizationRelations + > + > +>(DefaultCrudRepository) { constructor( @inject('datasources.treetracker') dataSource: TreetrackerDataSource, ) { super(Organization, dataSource); } - - async getEntityIdsByOrganizationId( - organizationId: number, - ): Promise> { - expect(organizationId).number(); - expect(this).property('execute').defined(); - const result = await this.execute( - `select * from getEntityRelationshipChildren(${organizationId})`, - [], - ); - return result.map((e) => e.entity_id); - } - - async applyOrganizationWhereClause( - where: Object | undefined, - organizationId: number | undefined, - ): Promise { - if (!where || organizationId === undefined) { - return Promise.resolve(where); - } - const entityIds = await this.getEntityIdsByOrganizationId(organizationId); - return { - and: [where, { id: { inq: entityIds } }], - }; - } } diff --git a/src/repositories/planter.repository.ts b/src/repositories/planter.repository.ts index 3f130ac2..e9332f43 100644 --- a/src/repositories/planter.repository.ts +++ b/src/repositories/planter.repository.ts @@ -1,3 +1,4 @@ +import { Constructor, inject, Getter } from '@loopback/core'; import { DefaultCrudRepository, repository, @@ -9,17 +10,22 @@ import { } from '@loopback/repository'; import { Planter, PlanterRelations, PlanterRegistration } from '../models'; import { TreetrackerDataSource } from '../datasources'; -import { inject, Getter } from '@loopback/core'; import { PlanterRegistrationRepository } from './planterRegistration.repository'; +import { UtilsRepositoryMixin } from '../mixins/utils.repository-mixin'; import expect from 'expect-runtime'; import { buildFilterQuery } from '../js/buildFilterQuery'; import { utils } from '../js/utils'; -export class PlanterRepository extends DefaultCrudRepository< +export class PlanterRepository extends UtilsRepositoryMixin< Planter, - typeof Planter.prototype.id, - PlanterRelations -> { + Constructor< + DefaultCrudRepository< + Planter, + typeof Planter.prototype.id, + PlanterRelations + > + > +>(DefaultCrudRepository) { public readonly planterRegs: HasManyRepositoryFactory< PlanterRegistration, typeof Planter.prototype.id @@ -40,75 +46,6 @@ export class PlanterRepository extends DefaultCrudRepository< ); } - async getEntityIdsByOrganizationId( - organizationId: number, - ): Promise> { - expect(organizationId).number(); - expect(this).property('execute').defined(); - const result = await this.execute( - `select * from getEntityRelationshipChildren(${organizationId})`, - [], - ); - return result.map((e) => e.entity_id); - } - - async getPlanterIdsByOrganizationId( - organizationId: number, - ): Promise> { - expect(organizationId).number(); - const result = await this.execute( - `select * from planter where organization_id in (select entity_id from getEntityRelationshipChildren(${organizationId}))`, - [], - ); - expect(result).match([{ id: expect.any(Number) }]); - return result.map((e) => e.id); - } - - async getNonOrganizationPlanterIds(): Promise> { - const result = await this.execute( - `select * from planter where organization_id isnull`, - [], - ); - expect(result).match([{ id: expect.any(Number) }]); - return result.map((e) => e.id); - } - - async getOrganizationWhereClause(organizationId: number): Promise { - if (organizationId === null) { - const planterIds = await this.getNonOrganizationPlanterIds(); - return { - and: [{ organizationId: null }, { 'planter.id': { inq: planterIds } }], - }; - } else { - const planterIds = await this.getPlanterIdsByOrganizationId( - organizationId, - ); - const entityIds = await this.getEntityIdsByOrganizationId(organizationId); - - return { - or: [ - { organizationId: { inq: entityIds } }, - { 'planter.id': { inq: planterIds } }, - ], - }; - } - } - - async applyOrganizationWhereClause( - where: Object | undefined, - organizationId: number | undefined, - ): Promise { - if (!where || organizationId === undefined) { - return Promise.resolve(where); - } - const organizationWhereClause = await this.getOrganizationWhereClause( - organizationId, - ); - return { - and: [where, organizationWhereClause], - }; - } - getPlanterRegistrationJoinClause(deviceIdentifier: string): string { if (deviceIdentifier === null) { return `LEFT JOIN planter_registrations @@ -120,7 +57,8 @@ export class PlanterRepository extends DefaultCrudRepository< WHERE (planter_registrations.device_identifier='${deviceIdentifier}')`; } - // loopback .find() wasn't applying the org filters + // default .find() wasn't applying the org filters + async findWithOrg( filter?: Filter, deviceIdentifier?: string, @@ -194,7 +132,6 @@ export class PlanterRepository extends DefaultCrudRepository< return >await this.execute(query.sql, query.params).then( (res) => { - // responds with count value as a string return (res && res[0]) || { count: 0 }; }, ); diff --git a/src/repositories/trees.repository.ts b/src/repositories/trees.repository.ts index 0a27c403..a778d536 100644 --- a/src/repositories/trees.repository.ts +++ b/src/repositories/trees.repository.ts @@ -1,3 +1,4 @@ +import { Constructor, inject, Getter } from '@loopback/core'; import { DefaultCrudRepository, repository, @@ -7,18 +8,19 @@ import { Where, Count, } from '@loopback/repository'; -import { Trees, TreesRelations, TreeTag } from '../models'; import { TreetrackerDataSource } from '../datasources'; -import { inject, Getter } from '@loopback/core'; +import { UtilsRepositoryMixin } from '../mixins/utils.repository-mixin'; import { TreeTagRepository } from './treeTag.repository'; +import { Trees, TreesRelations, TreeTag } from '../models'; import expect from 'expect-runtime'; import { buildFilterQuery } from '../js/buildFilterQuery'; -export class TreesRepository extends DefaultCrudRepository< +export class TreesRepository extends UtilsRepositoryMixin< Trees, - typeof Trees.prototype.id, - TreesRelations -> { + Constructor< + DefaultCrudRepository + > +>(DefaultCrudRepository) { public readonly treeTags: HasManyRepositoryFactory< TreeTag, typeof Trees.prototype.id @@ -49,67 +51,6 @@ export class TreesRepository extends DefaultCrudRepository< return result.map((e) => e.entity_id); } - async getPlanterIdsByOrganizationId( - organizationId: number, - ): Promise> { - expect(organizationId).number(); - const result = await this.execute( - `select * from planter where organization_id in (select entity_id from getEntityRelationshipChildren(${organizationId}))`, - [], - ); - expect(result).match([{ id: expect.any(Number) }]); - return result.map((e) => e.id); - } - - async getNonOrganizationPlanterIds(): Promise> { - const result = await this.execute( - `select * from planter where organization_id isnull`, - [], - ); - expect(result).match([{ id: expect.any(Number) }]); - return result.map((e) => e.id); - } - - async getOrganizationWhereClause(organizationId: number): Promise { - // console.log('getOrganizationWhereClause orgId ---', organizationId); - if (organizationId === null) { - const planterIds = await this.getNonOrganizationPlanterIds(); - return { - and: [ - { plantingOrganizationId: null }, - { planterId: { inq: planterIds } }, - ], - }; - } else { - const planterIds = await this.getPlanterIdsByOrganizationId( - organizationId, - ); - const entityIds = await this.getEntityIdsByOrganizationId(organizationId); - - return { - or: [ - { plantingOrganizationId: { inq: entityIds } }, - { planterId: { inq: planterIds } }, - ], - }; - } - } - - async applyOrganizationWhereClause( - where: Object | undefined, - organizationId: number | undefined, - ): Promise { - if (!where || organizationId === undefined) { - return Promise.resolve(where); - } - const organizationWhereClause = await this.getOrganizationWhereClause( - organizationId, - ); - return { - and: [where, organizationWhereClause], - }; - } - getTreeTagJoinClause(tagId: string): string { if (tagId === null) { return `LEFT JOIN tree_tag ON trees.id=tree_tag.tree_id WHERE (tree_tag.tag_id ISNULL)`; From a57a13ddcb591a7adacab907384dbc2b9ea5a29f Mon Sep 17 00:00:00 2001 From: Gwynn DP Date: Sat, 6 Nov 2021 16:29:01 -0700 Subject: [PATCH 2/5] fix: lint warnings and logic for querying planters by organization --- src/mixins/utils.repository-mixin.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/mixins/utils.repository-mixin.ts b/src/mixins/utils.repository-mixin.ts index 33ef8305..9bc70155 100644 --- a/src/mixins/utils.repository-mixin.ts +++ b/src/mixins/utils.repository-mixin.ts @@ -1,14 +1,14 @@ import { MixinTarget } from '@loopback/core'; import { CrudRepository, Model } from '@loopback/repository'; import expect from 'expect-runtime'; -import { buildFilterQuery } from '../js/buildFilterQuery'; -import { utils } from '../js/utils'; +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function UtilsRepositoryMixin< M extends Model, R extends MixinTarget>, >(superClass: R) { return class extends superClass { + // eslint-disable-next-line @typescript-eslint/no-explicit-any [x: string]: any; // put the shared code here async getEntityIdsByOrganizationId( @@ -80,13 +80,11 @@ export function UtilsRepositoryMixin< const planterIds = await this.getNonOrganizationPlanterIds(); // if planter repository request if (model === 'planter') { - return { - or: [{ organizationId: null }, { id: { inq: planterIds } }], - }; + return { id: { inq: planterIds } }; } else { // if trees or other repository request return { - or: [ + and: [ { plantingOrganizationId: null }, { planterId: { inq: planterIds } }, ], From b11c77e39f06336a524e7ee9f24c2c7a31b8599c Mon Sep 17 00:00:00 2001 From: Gwynn DP Date: Thu, 11 Nov 2021 21:55:37 -0800 Subject: [PATCH 3/5] fix: add modelName to query to avoid ambiguous fields --- src/js/buildFilterQuery.js | 14 ++++++++++++++ src/mixins/utils.repository-mixin.ts | 9 ++++++++- src/repositories/planter.repository.ts | 16 ++++++++++------ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/js/buildFilterQuery.js b/src/js/buildFilterQuery.js index a70e2579..067c0f49 100644 --- a/src/js/buildFilterQuery.js +++ b/src/js/buildFilterQuery.js @@ -28,6 +28,20 @@ export function buildFilterQuery(selectStmt, params) { const whereObjClause = connector._buildWhere(modelName, safeWhere); + //add the modelName to each requested field to avoid ambiguity in more complex queries + console.log('whereObjClause.sql -------> ', whereObjClause.sql); + + const tableName = + modelName.toLowerCase() === 'planterregistration' + ? 'planter_registrations' + : modelName.toLowerCase(); + const newQueryFields = whereObjClause.sql + .replace(/"/, `"${tableName}.`) + .replace(/AND "/gi, `AND "${tableName}.`) + .replace(/"/g, ''); + + whereObjClause.sql = newQueryFields; + if (whereObjClause.sql) { const hasWhere = /WHERE(?![^(]*\))/i.test(selectStmt); query.sql += ` ${hasWhere ? 'AND' : 'WHERE'} ${whereObjClause.sql}`; diff --git a/src/mixins/utils.repository-mixin.ts b/src/mixins/utils.repository-mixin.ts index 9bc70155..62997530 100644 --- a/src/mixins/utils.repository-mixin.ts +++ b/src/mixins/utils.repository-mixin.ts @@ -80,6 +80,13 @@ export function UtilsRepositoryMixin< const planterIds = await this.getNonOrganizationPlanterIds(); // if planter repository request if (model === 'planter') { + // return { + // and: [ + // { organizationId: null }, + // { 'planter.id': { inq: planterIds } }, + // ], + // }; + // could just do this if we didn't need to use 'planter.id' to avoid errors with adding other filters return { id: { inq: planterIds } }; } else { // if trees or other repository request @@ -102,7 +109,7 @@ export function UtilsRepositoryMixin< return { or: [ { organizationId: { inq: entityIds } }, - { id: { inq: planterIds } }, + { 'planter.id': { inq: planterIds } }, ], }; } else { diff --git a/src/repositories/planter.repository.ts b/src/repositories/planter.repository.ts index e9332f43..1e51a935 100644 --- a/src/repositories/planter.repository.ts +++ b/src/repositories/planter.repository.ts @@ -12,7 +12,7 @@ import { Planter, PlanterRelations, PlanterRegistration } from '../models'; import { TreetrackerDataSource } from '../datasources'; import { PlanterRegistrationRepository } from './planterRegistration.repository'; import { UtilsRepositoryMixin } from '../mixins/utils.repository-mixin'; -import expect from 'expect-runtime'; +// import expect from 'expect-runtime'; import { buildFilterQuery } from '../js/buildFilterQuery'; import { utils } from '../js/utils'; @@ -70,9 +70,14 @@ export class PlanterRepository extends UtilsRepositoryMixin< try { if (this.dataSource.connector) { - const columnNames = this.dataSource.connector - .buildColumnNames('Planter', filter) - .replace('"id"', 'planter.id as "id"'); + // const columnNames = this.dataSource.connector + // .buildColumnNames('Planter', filter) + // .replace('"id"', 'planter.id as "id"') + // .replace('"first_name"', 'planter.first_name as "first_name"') + // .replace('"last_name"', 'planter.last_name as "last_name"') + // .replace('"email"', 'planter.email as "email"') + // .replace('"organization"', 'planter.organization as "organization"') + // .replace('"phone"', 'planter.phone as "phone"'); let selectStmt; if (deviceIdentifier) { @@ -80,7 +85,7 @@ export class PlanterRepository extends UtilsRepositoryMixin< deviceIdentifier, )}`; } else { - selectStmt = `SELECT ${columnNames} FROM planter`; + selectStmt = `SELECT planter.* FROM planter`; } const params = { @@ -90,7 +95,6 @@ export class PlanterRepository extends UtilsRepositoryMixin< }; const query = buildFilterQuery(selectStmt, params); - // console.log('query ---------', query); const result = await this.execute(query.sql, query.params, options); return result.map((planter) => utils.convertCamel(planter)); From b1eeb08f314e863a2d8b615bff5b99d4dadda560 Mon Sep 17 00:00:00 2001 From: Gwynn DP Date: Sat, 13 Nov 2021 12:23:03 -0800 Subject: [PATCH 4/5] fix: add modelName to query to avoid ambiguous fields --- src/mixins/utils.repository-mixin.ts | 7 ------- src/repositories/planter.repository.ts | 10 ---------- 2 files changed, 17 deletions(-) diff --git a/src/mixins/utils.repository-mixin.ts b/src/mixins/utils.repository-mixin.ts index 62997530..71f71044 100644 --- a/src/mixins/utils.repository-mixin.ts +++ b/src/mixins/utils.repository-mixin.ts @@ -80,13 +80,6 @@ export function UtilsRepositoryMixin< const planterIds = await this.getNonOrganizationPlanterIds(); // if planter repository request if (model === 'planter') { - // return { - // and: [ - // { organizationId: null }, - // { 'planter.id': { inq: planterIds } }, - // ], - // }; - // could just do this if we didn't need to use 'planter.id' to avoid errors with adding other filters return { id: { inq: planterIds } }; } else { // if trees or other repository request diff --git a/src/repositories/planter.repository.ts b/src/repositories/planter.repository.ts index 1e51a935..af0bc93a 100644 --- a/src/repositories/planter.repository.ts +++ b/src/repositories/planter.repository.ts @@ -12,7 +12,6 @@ import { Planter, PlanterRelations, PlanterRegistration } from '../models'; import { TreetrackerDataSource } from '../datasources'; import { PlanterRegistrationRepository } from './planterRegistration.repository'; import { UtilsRepositoryMixin } from '../mixins/utils.repository-mixin'; -// import expect from 'expect-runtime'; import { buildFilterQuery } from '../js/buildFilterQuery'; import { utils } from '../js/utils'; @@ -70,15 +69,6 @@ export class PlanterRepository extends UtilsRepositoryMixin< try { if (this.dataSource.connector) { - // const columnNames = this.dataSource.connector - // .buildColumnNames('Planter', filter) - // .replace('"id"', 'planter.id as "id"') - // .replace('"first_name"', 'planter.first_name as "first_name"') - // .replace('"last_name"', 'planter.last_name as "last_name"') - // .replace('"email"', 'planter.email as "email"') - // .replace('"organization"', 'planter.organization as "organization"') - // .replace('"phone"', 'planter.phone as "phone"'); - let selectStmt; if (deviceIdentifier) { selectStmt = `SELECT planter.* FROM planter ${this.getPlanterRegistrationJoinClause( From b016d7290f980f6bfb48351e5f78823991a6d225 Mon Sep 17 00:00:00 2001 From: Gwynn DP Date: Sun, 9 Jan 2022 01:09:09 -0800 Subject: [PATCH 5/5] feat: add device manufacturer to planter registration data for org accounts --- src/controllers/planterOrganization.controller.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/controllers/planterOrganization.controller.ts b/src/controllers/planterOrganization.controller.ts index d2205c89..7088f13e 100644 --- a/src/controllers/planterOrganization.controller.ts +++ b/src/controllers/planterOrganization.controller.ts @@ -140,11 +140,16 @@ export class PlanterOrganizationController { ): Promise { // console.log('/organization/{organizationId}/planter-registration'); - const sql = `SELECT * FROM planter_registrations + const sql = `SELECT *, devices.manufacturer FROM planter_registrations + JOIN devices ON devices.android_id=planter_registrations.device_identifier LEFT JOIN ( - SELECT region.name AS country, region.geom FROM region, region_type - WHERE region_type.type='country' AND region.type_id=region_type.id - ) AS region ON ST_DWithin(region.geom, planter_registrations.geom, 0.01)`; + SELECT + region.name AS country, + region.geom FROM region, region_type + WHERE region_type.type='country' + AND region.type_id=region_type.id + ) AS region + ON ST_DWithin(region.geom, planter_registrations.geom, 0.01)`; const params = { filter,