Skip to content

Commit

Permalink
feat(growers): filter growers by deviceIdentifier (#598)
Browse files Browse the repository at this point in the history
  • Loading branch information
gwynndp authored Nov 6, 2021
1 parent 46730b6 commit cea9d24
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 19 deletions.
14 changes: 10 additions & 4 deletions src/controllers/planter.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ import { Planter, Trees } from '../models';
import { TreesFilter } from './trees.controller';
import { PlanterRepository, TreesRepository } from '../repositories';

// Extend the LoopBack filter types for the Planter model to include organizationId
type PlanterWhere = (Where<Planter> & { organizationId?: number }) | undefined;
// Extend the LoopBack filter types for the Planter model to include organizationId and deviceIdentifier
type PlanterWhere =
| (Where<Planter> & { deviceIdentifier?: string; organizationId?: number })
| undefined;
export type PlanterFilter = Filter<Planter> & { where: PlanterWhere };

export class PlanterController {
Expand All @@ -44,6 +46,8 @@ export class PlanterController {
@param.query.object('where', getWhereSchemaFor(Planter))
where?: PlanterWhere,
): Promise<Count> {
const deviceIdentifier = where?.deviceIdentifier;

// Replace organizationId with full entity tree and planter
if (where) {
const { organizationId, ...whereWithoutOrganizationId } = where;
Expand All @@ -54,7 +58,7 @@ export class PlanterController {
}
// console.log('get /planter/count where -->', where);

return await this.planterRepository.countWithOrg(where);
return await this.planterRepository.countWithOrg(where, deviceIdentifier);
}

@get('/planter', {
Expand All @@ -73,6 +77,8 @@ export class PlanterController {
@param.query.object('filter', getFilterSchemaFor(Planter))
filter?: PlanterFilter,
): Promise<Planter[]> {
const deviceIdentifier = filter?.where?.deviceIdentifier;

// Replace organizationId with full entity tree and planter
if (filter?.where) {
const { organizationId, ...whereWithoutOrganizationId } = filter.where;
Expand All @@ -82,7 +88,7 @@ export class PlanterController {
);
}

return await this.planterRepository.findWithOrg(filter);
return await this.planterRepository.findWithOrg(filter, deviceIdentifier);
}

@get('/planter/{id}', {
Expand Down
10 changes: 7 additions & 3 deletions src/controllers/planterRegistration.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ export class PlanterRegistrationController {

const sql = `SELECT * FROM planter_registrations
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,
Expand Down
6 changes: 5 additions & 1 deletion src/models/planter.model.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Entity, model, property } from '@loopback/repository';
import { Entity, model, property, hasMany } from '@loopback/repository';
import { PlanterRegistration } from './planterRegistration.model';

/* eslint-disable @typescript-eslint/no-empty-interface */

Expand Down Expand Up @@ -183,6 +184,9 @@ export class Planter extends Entity {
})
imageRotation?: Number;

@hasMany(() => PlanterRegistration, { keyTo: 'planterId' })
planterRegs: PlanterRegistration[];

// Define well-known properties here

// Indexer property to allow additional data
Expand Down
74 changes: 63 additions & 11 deletions src/repositories/planter.repository.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import {
DefaultCrudRepository,
repository,
HasManyRepositoryFactory,
Filter,
Options,
Where,
Count,
} from '@loopback/repository';
import { Planter, PlanterRelations } from '../models';
import { Planter, PlanterRelations, PlanterRegistration } from '../models';
import { TreetrackerDataSource } from '../datasources';
import { inject } from '@loopback/core';
import { inject, Getter } from '@loopback/core';
import { PlanterRegistrationRepository } from './planterRegistration.repository';
import expect from 'expect-runtime';
import { buildFilterQuery } from '../js/buildFilterQuery';
import { utils } from '../js/utils';
Expand All @@ -16,10 +20,24 @@ export class PlanterRepository extends DefaultCrudRepository<
typeof Planter.prototype.id,
PlanterRelations
> {
public readonly planterRegs: HasManyRepositoryFactory<
PlanterRegistration,
typeof Planter.prototype.id
>;
constructor(
@inject('datasources.treetracker') dataSource: TreetrackerDataSource,
@repository.getter('PlanterRegistrationRepository')
protected planterRegistrationRepositoryGetter: Getter<PlanterRegistrationRepository>,
) {
super(Planter, dataSource);
this.planterRegs = this.createHasManyRepositoryFactoryFor(
'planterRegs',
planterRegistrationRepositoryGetter,
);
this.registerInclusionResolver(
'planterRegs',
this.planterRegs.inclusionResolver,
);
}

async getEntityIdsByOrganizationId(
Expand Down Expand Up @@ -91,12 +109,27 @@ export class PlanterRepository extends DefaultCrudRepository<
};
}

getPlanterRegistrationJoinClause(deviceIdentifier: string): string {
if (deviceIdentifier === null) {
return `LEFT JOIN planter_registrations
ON planter.id=planter_registrations.planter_id
WHERE (planter_registrations.device_identifier ISNULL)
GROUP BY planter.id`;
}
return `JOIN planter_registrations
ON planter.id=planter_registrations.planter_id
WHERE (planter_registrations.device_identifier='${deviceIdentifier}')
GROUP BY planter.id`;
}

// loopback .find() wasn't applying the org filters
async findWithOrg(
filter?: Filter<Planter>,
deviceIdentifier?: string,
options?: Options,
): Promise<(Planter & PlanterRelations)[]> {
if (!filter) {
return await this.find(filter);
if (!filter || deviceIdentifier === null) {
return await this.find(filter, options);
}

try {
Expand All @@ -106,7 +139,14 @@ export class PlanterRepository extends DefaultCrudRepository<
filter,
);

const selectStmt = `SELECT ${columnNames} FROM planter `;
let selectStmt;
if (deviceIdentifier) {
selectStmt = `SELECT planter.* FROM planter ${this.getPlanterRegistrationJoinClause(
deviceIdentifier,
)}`;
} else {
selectStmt = `SELECT ${columnNames} FROM planter`;
}

const params = {
filter,
Expand All @@ -115,25 +155,37 @@ export class PlanterRepository extends DefaultCrudRepository<
};

const query = buildFilterQuery(selectStmt, params);
// console.log('query ---------', query);

const result = await this.execute(query.sql, query.params);
const result = await this.execute(query.sql, query.params, options);
return <Planter[]>result.map((planter) => utils.convertCamel(planter));
} else {
throw 'Connector not defined';
}
} catch (e) {
console.log(e);
return await this.find(filter);
return await this.find(filter, options);
}
}

async countWithOrg(where?: Where<Planter>): Promise<Count> {
if (!where) {
return await this.count(where);
async countWithOrg(
where?: Where<Planter>,
deviceIdentifier?: string,
options?: Options,
): Promise<Count> {
if (!where || deviceIdentifier === null) {
return await this.count(where, options);
}

try {
const selectStmt = `SELECT COUNT(*) FROM planter `;
let selectStmt;
if (deviceIdentifier) {
selectStmt = `SELECT COUNT(*) FROM planter ${this.getPlanterRegistrationJoinClause(
deviceIdentifier,
)}`;
} else {
selectStmt = `SELECT COUNT(*) FROM planter`;
}

const params = {
filter: { where },
Expand Down

0 comments on commit cea9d24

Please sign in to comment.