improve selector
This commit is contained in:
		
							parent
							
								
									f0440ed65f
								
							
						
					
					
						commit
						e0030aba73
					
				| 
						 | 
				
			
			@ -7,6 +7,7 @@ import { Inject } from '@nestjs/common';
 | 
			
		|||
import { AdRepositoryPort } from '@modules/ad/core/application/ports/ad.repository.port';
 | 
			
		||||
import {
 | 
			
		||||
  AD_REPOSITORY,
 | 
			
		||||
  AD_ROUTE_PROVIDER,
 | 
			
		||||
  INPUT_DATETIME_TRANSFORMER,
 | 
			
		||||
  PARAMS_PROVIDER,
 | 
			
		||||
} from '@modules/ad/ad.di-tokens';
 | 
			
		||||
| 
						 | 
				
			
			@ -14,6 +15,7 @@ import { MatchEntity } from '@modules/ad/core/domain/match.entity';
 | 
			
		|||
import { DefaultParamsProviderPort } from '../../ports/default-params-provider.port';
 | 
			
		||||
import { DefaultParams } from '../../ports/default-params.type';
 | 
			
		||||
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
 | 
			
		||||
import { RouteProviderPort } from '../../ports/route-provider.port';
 | 
			
		||||
 | 
			
		||||
@QueryHandler(MatchQuery)
 | 
			
		||||
export class MatchQueryHandler implements IQueryHandler {
 | 
			
		||||
| 
						 | 
				
			
			@ -25,6 +27,8 @@ export class MatchQueryHandler implements IQueryHandler {
 | 
			
		|||
    @Inject(AD_REPOSITORY) private readonly repository: AdRepositoryPort,
 | 
			
		||||
    @Inject(INPUT_DATETIME_TRANSFORMER)
 | 
			
		||||
    private readonly datetimeTransformer: DateTimeTransformerPort,
 | 
			
		||||
    @Inject(AD_ROUTE_PROVIDER)
 | 
			
		||||
    private readonly routeProvider: RouteProviderPort,
 | 
			
		||||
  ) {
 | 
			
		||||
    this._defaultParams = defaultParamsProvider.getParams();
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -50,6 +54,7 @@ export class MatchQueryHandler implements IQueryHandler {
 | 
			
		|||
        maxDetourDurationRatio: this._defaultParams.MAX_DETOUR_DURATION_RATIO,
 | 
			
		||||
      })
 | 
			
		||||
      .setDatesAndSchedule(this.datetimeTransformer);
 | 
			
		||||
    await query.setRoutes(this.routeProvider);
 | 
			
		||||
 | 
			
		||||
    let algorithm: Algorithm;
 | 
			
		||||
    switch (query.algorithmType) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,11 @@
 | 
			
		|||
import { QueryBase } from '@mobicoop/ddd-library';
 | 
			
		||||
import { AlgorithmType } from '../../types/algorithm.types';
 | 
			
		||||
import { Waypoint } from '../../types/waypoint.type';
 | 
			
		||||
import { Frequency } from '@modules/ad/core/domain/ad.types';
 | 
			
		||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
 | 
			
		||||
import { MatchRequestDto } from '@modules/ad/interface/grpc-controllers/dtos/match.request.dto';
 | 
			
		||||
import { DateTimeTransformerPort } from '../../ports/datetime-transformer.port';
 | 
			
		||||
import { Route } from '../../types/route.type';
 | 
			
		||||
import { RouteProviderPort } from '../../ports/route-provider.port';
 | 
			
		||||
 | 
			
		||||
export class MatchQuery extends QueryBase {
 | 
			
		||||
  driver?: boolean;
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +28,7 @@ export class MatchQuery extends QueryBase {
 | 
			
		|||
  maxDetourDurationRatio?: number;
 | 
			
		||||
  readonly page?: number;
 | 
			
		||||
  readonly perPage?: number;
 | 
			
		||||
  route?: Route;
 | 
			
		||||
 | 
			
		||||
  constructor(props: MatchRequestDto) {
 | 
			
		||||
    super();
 | 
			
		||||
| 
						 | 
				
			
			@ -160,6 +163,18 @@ export class MatchQuery extends QueryBase {
 | 
			
		|||
    }));
 | 
			
		||||
    return this;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  setRoutes = async (routeProvider: RouteProviderPort): Promise<MatchQuery> => {
 | 
			
		||||
    const roles: Role[] = [];
 | 
			
		||||
    if (this.driver) roles.push(Role.DRIVER);
 | 
			
		||||
    if (this.passenger) roles.push(Role.PASSENGER);
 | 
			
		||||
    try {
 | 
			
		||||
      this.route = await routeProvider.getBasic(roles, this.waypoints);
 | 
			
		||||
    } catch (e: any) {
 | 
			
		||||
      throw new Error('Unable to find a route for given waypoints');
 | 
			
		||||
    }
 | 
			
		||||
    return this;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ScheduleItem = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { Role } from '@modules/ad/core/domain/ad.types';
 | 
			
		||||
import { Frequency, Role } from '@modules/ad/core/domain/ad.types';
 | 
			
		||||
import { Candidate } from '../../../types/algorithm.types';
 | 
			
		||||
import { Selector } from '../algorithm.abstract';
 | 
			
		||||
import { AdReadModel } from '@modules/ad/infrastructure/ad.repository';
 | 
			
		||||
| 
						 | 
				
			
			@ -8,15 +8,16 @@ export class PassengerOrientedSelector extends Selector {
 | 
			
		|||
    const queryStringRoles: QueryStringRole[] = [];
 | 
			
		||||
    if (this.query.driver)
 | 
			
		||||
      queryStringRoles.push({
 | 
			
		||||
        query: this.asDriverQueryString(),
 | 
			
		||||
        query: this.createQueryString(Role.DRIVER),
 | 
			
		||||
        role: Role.DRIVER,
 | 
			
		||||
      });
 | 
			
		||||
    if (this.query.passenger)
 | 
			
		||||
      queryStringRoles.push({
 | 
			
		||||
        query: this.asPassengerQueryString(),
 | 
			
		||||
        query: this.createQueryString(Role.PASSENGER),
 | 
			
		||||
        role: Role.PASSENGER,
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
    console.log(queryStringRoles);
 | 
			
		||||
    return (
 | 
			
		||||
      await Promise.all(
 | 
			
		||||
        queryStringRoles.map<Promise<AdsRole>>(
 | 
			
		||||
| 
						 | 
				
			
			@ -42,29 +43,66 @@ export class PassengerOrientedSelector extends Selector {
 | 
			
		|||
      .flat();
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  private asPassengerQueryString = (): string => `SELECT
 | 
			
		||||
        ad.uuid,driver,passenger,frequency,public.st_astext(matcher.ad.waypoints) as waypoints,
 | 
			
		||||
        "fromDate","toDate",
 | 
			
		||||
        "seatsProposed","seatsRequested",
 | 
			
		||||
        strict,
 | 
			
		||||
        "driverDuration","driverDistance",
 | 
			
		||||
        "passengerDuration","passengerDistance",
 | 
			
		||||
        "fwdAzimuth","backAzimuth",
 | 
			
		||||
        si.day,si.time,si.margin
 | 
			
		||||
        FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"
 | 
			
		||||
        WHERE driver=True`;
 | 
			
		||||
  private createQueryString = (role: Role): string =>
 | 
			
		||||
    [
 | 
			
		||||
      this.createSelect(role),
 | 
			
		||||
      this.createFrom(),
 | 
			
		||||
      'WHERE',
 | 
			
		||||
      this.createWhere(role),
 | 
			
		||||
    ].join(' ');
 | 
			
		||||
 | 
			
		||||
  private asDriverQueryString = (): string => `SELECT
 | 
			
		||||
  private createSelect = (role: Role): string =>
 | 
			
		||||
    [
 | 
			
		||||
      `SELECT
 | 
			
		||||
        ad.uuid,driver,passenger,frequency,public.st_astext(matcher.ad.waypoints) as waypoints,
 | 
			
		||||
        "fromDate","toDate",
 | 
			
		||||
        "seatsProposed","seatsRequested",
 | 
			
		||||
        strict,
 | 
			
		||||
        "driverDuration","driverDistance",
 | 
			
		||||
        "passengerDuration","passengerDistance",
 | 
			
		||||
        "fwdAzimuth","backAzimuth",
 | 
			
		||||
        si.day,si.time,si.margin
 | 
			
		||||
        FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"
 | 
			
		||||
        WHERE passenger=True`;
 | 
			
		||||
        si.day,si.time,si.margin`,
 | 
			
		||||
      role == Role.DRIVER ? this.selectAsDriver() : this.selectAsPassenger(),
 | 
			
		||||
    ].join();
 | 
			
		||||
 | 
			
		||||
  private selectAsDriver = (): string =>
 | 
			
		||||
    `${this.query.route?.driverDuration} as duration,${this.query.route?.driverDistance} as distance`;
 | 
			
		||||
 | 
			
		||||
  private selectAsPassenger = (): string =>
 | 
			
		||||
    `"driverDuration" as duration,"driverDistance" as distance`;
 | 
			
		||||
 | 
			
		||||
  private createFrom = (): string =>
 | 
			
		||||
    'FROM ad LEFT JOIN schedule_item si ON ad.uuid = si."adUuid"';
 | 
			
		||||
 | 
			
		||||
  private createWhere = (role: Role): string =>
 | 
			
		||||
    [this.whereRole(role), this.whereStrict(), this.whereDate()].join(' AND ');
 | 
			
		||||
 | 
			
		||||
  private whereRole = (role: Role): string =>
 | 
			
		||||
    role == Role.PASSENGER ? 'driver=True' : 'passenger=True';
 | 
			
		||||
 | 
			
		||||
  private whereStrict = (): string =>
 | 
			
		||||
    this.query.strict
 | 
			
		||||
      ? this.query.frequency == Frequency.PUNCTUAL
 | 
			
		||||
        ? `frequency='${Frequency.PUNCTUAL}'`
 | 
			
		||||
        : `frequency='${Frequency.RECURRENT}'`
 | 
			
		||||
      : '';
 | 
			
		||||
 | 
			
		||||
  private whereDate = (): string => {
 | 
			
		||||
    const whereDate = `(
 | 
			
		||||
      (
 | 
			
		||||
        "fromDate" <= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
 | 
			
		||||
        "toDate" >= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
 | 
			
		||||
      ) OR (
 | 
			
		||||
        "fromDate" >= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
 | 
			
		||||
        "toDate" <= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
 | 
			
		||||
      ) OR (
 | 
			
		||||
        "fromDate" <= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
 | 
			
		||||
        "toDate" <= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
 | 
			
		||||
      ) OR (
 | 
			
		||||
        "fromDate" >= '${this.query.fromDate}' and "fromDate" <= '${this.query.toDate}' and
 | 
			
		||||
        "toDate" >= '${this.query.toDate}' and "toDate" >= '${this.query.fromDate}'
 | 
			
		||||
      )
 | 
			
		||||
    )`;
 | 
			
		||||
    return whereDate;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type QueryStringRole = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue