diff --git a/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoCodeFilesForDomainObjects.integration.test.ts.snap b/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoCodeFilesForDomainObjects.integration.test.ts.snap index 2958380..ef9d920 100644 --- a/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoCodeFilesForDomainObjects.integration.test.ts.snap +++ b/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoCodeFilesForDomainObjects.integration.test.ts.snap @@ -1849,13 +1849,14 @@ export const findById = async ( "relpath": "trainStationDao/findById.ts", }, GeneratedCodeFile { - "content": "import { HasId, HasMetadata } from 'type-fns'; + "content": "import { HasMetadata } from 'type-fns'; import { DatabaseConnection } from '$PATH_TO_DATABASE_CONNECTION'; import { log } from '$PATH_TO_LOG_OBJECT'; import { Geocode, TrainStation } from '$PATH_TO_DOMAIN_OBJECT'; import { sqlQueryFindTrainStationByUnique } from '$PATH_TO_GENERATED_SQL_QUERY_FUNCTIONS'; import { castFromDatabaseObject } from './castFromDatabaseObject'; +import { geocodeDao } from '../geocodeDao'; export const sql = \` -- query_name = find_train_station_by_unique @@ -1880,7 +1881,7 @@ export const findByUnique = async ( { geocode, }: { - geocode: HasId; + geocode: Geocode; }, context: { dbConnection: DatabaseConnection }, ): Promise | null> => { @@ -1888,7 +1889,7 @@ export const findByUnique = async ( dbExecute: context.dbConnection.query, logDebug: log.debug, input: { - geocodeId: geocode.id, + geocodeId: geocode.id ? geocode.id : ((await geocodeDao.findByUnique(geocode, context))?.id ?? -1), }, }); const [dbObject, ...moreDbObjects] = results; @@ -2227,13 +2228,14 @@ export const findById = async ( "relpath": "invoiceLineItemDao/findById.ts", }, GeneratedCodeFile { - "content": "import { HasId, HasMetadata } from 'type-fns'; + "content": "import { HasMetadata } from 'type-fns'; import { DatabaseConnection } from '$PATH_TO_DATABASE_CONNECTION'; import { log } from '$PATH_TO_LOG_OBJECT'; import { InvoiceLineItem, Price } from '$PATH_TO_DOMAIN_OBJECT'; import { sqlQueryFindInvoiceLineItemByUnique } from '$PATH_TO_GENERATED_SQL_QUERY_FUNCTIONS'; import { castFromDatabaseObject } from './castFromDatabaseObject'; +import { priceDao } from '../priceDao'; export const sql = \` -- query_name = find_invoice_line_item_by_unique @@ -2262,7 +2264,7 @@ export const findByUnique = async ( title, explanation, }: { - price: HasId; + price: Price; title: string; explanation: string; }, @@ -2272,7 +2274,7 @@ export const findByUnique = async ( dbExecute: context.dbConnection.query, logDebug: log.debug, input: { - priceId: price.id, + priceId: price.id ? price.id : ((await priceDao.findByUnique(price, context))?.id ?? -1), title, explanation, }, diff --git a/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoFindByMethodCodeForDomainObject.test.ts.snap b/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoFindByMethodCodeForDomainObject.test.ts.snap index c623406..a4841dc 100644 --- a/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoFindByMethodCodeForDomainObject.test.ts.snap +++ b/src/logic/define/databaseAccessObjects/__snapshots__/defineDaoFindByMethodCodeForDomainObject.test.ts.snap @@ -284,13 +284,15 @@ export const findByUnique = async ( `; exports[`defineDaoFindByMethodCodeForDomainObject findByUnique should look correct for domain entity that is unique on references, solo and array, implicit and nested 1`] = ` -"import { HasId, HasMetadata } from 'type-fns'; +"import { HasMetadata } from 'type-fns'; import { DatabaseConnection } from '$PATH_TO_DATABASE_CONNECTION'; import { log } from '$PATH_TO_LOG_OBJECT'; import { Geocode, Train, TrainBadge } from '$PATH_TO_DOMAIN_OBJECT'; import { sqlQueryFindTrainByUnique } from '$PATH_TO_GENERATED_SQL_QUERY_FUNCTIONS'; import { castFromDatabaseObject } from './castFromDatabaseObject'; +import { geocodeDao } from '../geocodeDao'; +import { trainBadgeDao } from '../trainBadgeDao'; export const sql = \` -- query_name = find_train_by_unique @@ -357,8 +359,8 @@ export const findByUnique = async ( locomotiveUuids, leadEngineerUuid, }: { - homeStationGeocode: HasId; - badges: HasId[]; + homeStationGeocode: Geocode; + badges: TrainBadge[]; locomotiveUuids: string[]; leadEngineerUuid: string; }, @@ -368,8 +370,8 @@ export const findByUnique = async ( dbExecute: context.dbConnection.query, logDebug: log.debug, input: { - homeStationGeocodeId: homeStationGeocode.id, - badgeIds: badges.map((trainBadge) => trainBadge.id), + homeStationGeocodeId: homeStationGeocode.id ? homeStationGeocode.id : ((await geocodeDao.findByUnique(homeStationGeocode, context))?.id ?? -1), + badgeIds: await Promise.all(badges.map(async (trainBadge) => trainBadge.id ? trainBadge.id : ((await trainBadgeDao.findByUnique(trainBadge, context))?.id ?? -1) )), locomotiveUuids, leadEngineerUuid, }, @@ -592,13 +594,14 @@ export const findByUnique = async ( `; exports[`defineDaoFindByMethodCodeForDomainObject findByUnique should look correct for simple literal that references another literal 1`] = ` -"import { HasId, HasMetadata } from 'type-fns'; +"import { HasMetadata } from 'type-fns'; import { DatabaseConnection } from '$PATH_TO_DATABASE_CONNECTION'; import { log } from '$PATH_TO_LOG_OBJECT'; import { InvoiceLineItem, Price } from '$PATH_TO_DOMAIN_OBJECT'; import { sqlQueryFindInvoiceLineItemByUnique } from '$PATH_TO_GENERATED_SQL_QUERY_FUNCTIONS'; import { castFromDatabaseObject } from './castFromDatabaseObject'; +import { priceDao } from '../priceDao'; export const sql = \` -- query_name = find_invoice_line_item_by_unique @@ -622,7 +625,7 @@ export const findByUnique = async ( { price, }: { - price: HasId; + price: Price; }, context: { dbConnection: DatabaseConnection }, ): Promise | null> => { @@ -630,7 +633,7 @@ export const findByUnique = async ( dbExecute: context.dbConnection.query, logDebug: log.debug, input: { - priceId: price.id, + priceId: price.id ? price.id : ((await priceDao.findByUnique(price, context))?.id ?? -1), }, }); const [dbObject, ...moreDbObjects] = results; @@ -641,13 +644,14 @@ export const findByUnique = async ( `; exports[`defineDaoFindByMethodCodeForDomainObject findByUnique should look for a domain entity unique on a nested domain object 1`] = ` -"import { HasId, HasMetadata } from 'type-fns'; +"import { HasMetadata } from 'type-fns'; import { DatabaseConnection } from '$PATH_TO_DATABASE_CONNECTION'; import { log } from '$PATH_TO_LOG_OBJECT'; import { Geocode, Station } from '$PATH_TO_DOMAIN_OBJECT'; import { sqlQueryFindStationByUnique } from '$PATH_TO_GENERATED_SQL_QUERY_FUNCTIONS'; import { castFromDatabaseObject } from './castFromDatabaseObject'; +import { geocodeDao } from '../geocodeDao'; export const sql = \` -- query_name = find_station_by_unique @@ -671,7 +675,7 @@ export const findByUnique = async ( { geocode, }: { - geocode: HasId; + geocode: Geocode; }, context: { dbConnection: DatabaseConnection }, ): Promise | null> => { @@ -679,7 +683,7 @@ export const findByUnique = async ( dbExecute: context.dbConnection.query, logDebug: log.debug, input: { - geocodeId: geocode.id, + geocodeId: geocode.id ? geocode.id : ((await geocodeDao.findByUnique(geocode, context))?.id ?? -1), }, }); const [dbObject, ...moreDbObjects] = results; diff --git a/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.test.ts b/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.test.ts index fec3f72..a9914c7 100644 --- a/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.test.ts +++ b/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.test.ts @@ -1190,7 +1190,7 @@ async ( { geocode, }: { - geocode: HasId; + geocode: Geocode; }, context `.trim(), @@ -1721,8 +1721,8 @@ async ( locomotiveUuids, leadEngineerUuid, }: { - homeStationGeocode: HasId; - badges: HasId[]; + homeStationGeocode: Geocode; + badges: TrainBadge[]; locomotiveUuids: string[]; leadEngineerUuid: string; }, diff --git a/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.ts b/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.ts index e239fd1..8f3d7d3 100644 --- a/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.ts +++ b/src/logic/define/databaseAccessObjects/defineDaoFindByMethodCodeForDomainObject.ts @@ -13,6 +13,7 @@ import { SqlSchemaPropertyMetadata } from '../../../domain/objects/SqlSchemaProp import { SqlSchemaReferenceMethod } from '../../../domain/objects/SqlSchemaReferenceMetadata'; import { SqlSchemaToDomainObjectRelationship } from '../../../domain/objects/SqlSchemaToDomainObjectRelationship'; import { UnexpectedCodePathDetectedError } from '../../UnexpectedCodePathDetectedError'; +import { castDomainObjectNameToDaoName } from './castDomainObjectNameToDaoName'; import { defineOutputTypeOfFoundDomainObject } from './defineOutputTypeOfFoundDomainObject'; import { defineQueryFunctionInputExpressionForDomainObjectProperty, @@ -48,7 +49,7 @@ const getTypescriptTypeForDomainObjectProperty = ({ return `${domainObjectName}['${domainObjectProperty.name}']`; if (domainObjectProperty.type === DomainObjectPropertyType.REFERENCE) { const referencedDomainObjectName = sqlSchemaProperty.reference!.of.name; - return `HasId<${referencedDomainObjectName}>`; + return referencedDomainObjectName; } if (domainObjectProperty.type === DomainObjectPropertyType.ARRAY) { if ( @@ -57,7 +58,7 @@ const getTypescriptTypeForDomainObjectProperty = ({ ) return 'string[]'; const referencedDomainObjectName = sqlSchemaProperty.reference!.of.name; - return `HasId<${referencedDomainObjectName}>[]`; + return `${referencedDomainObjectName}[]`; } throw new UnexpectedCodePathDetectedError({ reason: @@ -141,9 +142,7 @@ export const defineDaoFindByMethodCodeForDomainObject = ({ const imports = [ ...new Set([ // always present imports - `import { ${ - referencedDomainObjectNames.length > 1 ? 'HasId, ' : '' - }HasMetadata } from 'type-fns';`, + `import { HasMetadata } from 'type-fns';`, '', // split module from relative imports "import { DatabaseConnection } from '$PATH_TO_DATABASE_CONNECTION';", "import { log } from '$PATH_TO_LOG_OBJECT';", @@ -152,6 +151,24 @@ export const defineDaoFindByMethodCodeForDomainObject = ({ .join(', ')} } from '$PATH_TO_DOMAIN_OBJECT';`, `import { sqlQueryFind${domainObject.name}By${findByQueryType} } from '$PATH_TO_GENERATED_SQL_QUERY_FUNCTIONS';`, "import { castFromDatabaseObject } from './castFromDatabaseObject';", + ...sqlSchemaRelationship.properties + .map((property) => + property.sqlSchema.reference?.method === + SqlSchemaReferenceMethod.DIRECT_BY_NESTING + ? property.sqlSchema.reference.of.name + : null, + ) + .filter(isPresent) + .filter((nestedDomainObjectName) => + referencedDomainObjectNames.includes(nestedDomainObjectName), + ) + .map((referencedDomainObjectName) => { + const nameOfDaoToImport = castDomainObjectNameToDaoName( + referencedDomainObjectName, + ); + return `import { ${nameOfDaoToImport} } from '../${nameOfDaoToImport}';`; + }) + .sort(), ]), ]; diff --git a/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.test.ts b/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.test.ts index 099034a..8ee27b4 100644 --- a/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.test.ts +++ b/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.test.ts @@ -449,7 +449,9 @@ describe('defineQueryFunctionInputExpressionForDomainObjectProperty', () => { ], context: GetTypescriptCodeForPropertyContext.FOR_FIND_BY_QUERY, }); - expect(expression).toEqual('geocodeId: geocode.id'); + expect(expression).toEqual( + 'geocodeId: geocode.id ? geocode.id : ((await geocodeDao.findByUnique(geocode, context))?.id ?? -1)', + ); }); it('should define the input expression correctly for a solo, nullable, DIRECT_BY_NESTING reference', () => { const expression = @@ -517,7 +519,7 @@ describe('defineQueryFunctionInputExpressionForDomainObjectProperty', () => { context: GetTypescriptCodeForPropertyContext.FOR_FIND_BY_QUERY, }); expect(expression).toEqual( - 'geocodeId: geocode === null ? null : geocode.id', + 'geocodeId: geocode === null ? null : geocode.id ? geocode.id : ((await geocodeDao.findByUnique(geocode, context))?.id ?? -1)', ); }); it('should define the input expression correctly for an array of IMPLICIT_BY_UUID references', () => { @@ -629,7 +631,7 @@ describe('defineQueryFunctionInputExpressionForDomainObjectProperty', () => { context: GetTypescriptCodeForPropertyContext.FOR_FIND_BY_QUERY, }); expect(expression).toEqual( - 'geocodeIds: geocodes.map((geocode) => geocode.id)', + 'geocodeIds: await Promise.all(geocodes.map(async (geocode) => geocode.id ? geocode.id : ((await geocodeDao.findByUnique(geocode, context))?.id ?? -1) ))', ); }); }); diff --git a/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.ts b/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.ts index 5658b37..f52b955 100644 --- a/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.ts +++ b/src/logic/define/databaseAccessObjects/defineQueryFunctionInputExpressionForDomainObjectProperty.ts @@ -89,7 +89,9 @@ export const defineQueryFunctionInputExpressionForDomainObjectProperty = ({ // e.g., `geocodeId: geocode.id` return `${camelCase(sqlSchemaProperty.name)}: ${nullabilityPrefix}${ domainObjectProperty.name - }.id`; + }.id ? ${domainObjectPropertyVariableName}.id : ((await ${castDomainObjectNameToDaoName( + referencedDomainObjectName, + )}.findByUnique(${domainObjectPropertyVariableName}, context))?.id ?? -1)`; } // handle array of references @@ -109,11 +111,17 @@ export const defineQueryFunctionInputExpressionForDomainObjectProperty = ({ )}.upsert({ ${camelCase(referencedSqlSchemaName)} }, context)).id))`; // e.g., `geocodeIds: geocodes.map(geocode => geocode.id)` - return `${camelCase(sqlSchemaProperty.name)}: ${ + return `${camelCase(sqlSchemaProperty.name)}: await Promise.all(${ domainObjectProperty.name - }.map((${camelCase(referencedSqlSchemaName)}) => ${camelCase( + }.map(async (${camelCase(referencedSqlSchemaName)}) => ${camelCase( referencedSqlSchemaName, - )}.id)`; + )}.id ? ${camelCase( + referencedSqlSchemaName, + )}.id : ((await ${castDomainObjectNameToDaoName( + referencedDomainObjectName, + )}.findByUnique(${camelCase( + referencedSqlSchemaName, + )}, context))?.id ?? -1) ))`; } }