Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modified patch update to separetely process the meta field #319

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 22 additions & 18 deletions lib/api/address/models.js
Original file line number Diff line number Diff line change
@@ -1,42 +1,46 @@
import {Op} from 'sequelize'
import {Address} from '../../util/sequelize.js'

export async function getAddress(addressID) {
return Address.findByPk(addressID, {raw: true})
}
export const getAddress = addressID => Address.findByPk(addressID, {raw: true})

export async function getAddresses(addressIDs) {
return Address.findAll({where: {id: addressIDs}, raw: true})
}
export const getAddresses = addressIDs => Address.findAll({where: {id: addressIDs}, raw: true})

export async function getAllAddressIDsFromDistrict(districtID) {
export const getAllAddressIDsFromDistrict = async districtID => {
const addresses = await Address.findAll({where: {districtID}, attributes: ['id'], raw: true})
return addresses.map(address => address.id)
}

export async function getAllAddressIDsOutsideDistrict(addressIDs, districtID) {
export const getAllAddressIDsOutsideDistrict = async (addressIDs, districtID) => {
const addresses = await Address.findAll({where: {id: addressIDs, districtID: {[Op.ne]: districtID}}, attributes: ['id'], raw: true})
return addresses.map(address => address.id)
}

export async function setAddresses(addresses) {
return Address.bulkCreate(addresses)
}
export const setAddresses = addresses => Address.bulkCreate(addresses)

export async function updateAddresses(addresses) {
export const updateAddresses = async addresses => {
const bulkOperations = addresses.map(address => Address.update(address, {where: {id: address.id}}))
return Promise.all(bulkOperations)
}

export async function deleteAddress(addressID) {
return Address.destroy({where: {id: addressID}})
}
export const patchAddresses = async addresses => {
const bulkOperations = addresses.map(async address => {
// Separate meta from the rest of the object to process the update separately
const {meta, ...addressRest} = address
const addressID = address.id
const addressDB = await Address.findByPk(addressID)
addressDB.set(addressRest)
addressDB.meta = {...addressDB.meta, ...meta}
return addressDB.save()
})

export async function deleteAddresses(addressIDs) {
return Address.destroy({where: {id: addressIDs}})
return Promise.all(bulkOperations)
}

export async function getAllDistrictIDsFromAddresses(addressIDs) {
export const deleteAddress = addressID => Address.destroy({where: {id: addressID}})

export const deleteAddresses = addressIDs => Address.destroy({where: {id: addressIDs}})

export const getAllDistrictIDsFromAddresses = async addressIDs => {
const addresses = await Address.findAll({where: {id: addressIDs}, attributes: ['districtID'], raw: true})
return addresses.map(address => address.districtID)
}
47 changes: 27 additions & 20 deletions lib/api/address/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,36 @@ const metaSchema = object({

export const banAddressSchema = object({
id: banID.required(),
mainCommonToponymID: banID.required(),
mainCommonToponymID: banID.when('$isPatch', {
is: true,
otherwise: schema => schema.required(),
}),
secondaryCommonToponymIDs: array().of(banID),
districtID: banID.required(),
number: number().positive().integer().required(),
districtID: banID.when('$isPatch', {
is: true,
otherwise: schema => schema.required(),
}),
number: number().positive().integer().when('$isPatch', {
is: true,
otherwise: schema => schema.required(),
}),
suffix: string().trim(),
labels: array().of(labelSchema),
labels: array().of(labelSchema).when('$isPatch', {
is: true,
// eslint-disable-next-line unicorn/no-thenable
then: schema => schema.default(null).nullable(),
}),
certified: boolean(),
positions: array().of(positionSchema).required(),
updateDate: date().required(),
meta: metaSchema
}).noUnknown()

export const banAddressSchemaForPatch = object({
id: banID.required(),
mainCommonToponymID: banID,
secondaryCommonToponymIDs: array().of(banID),
districtID: banID,
number: number().positive().integer(),
suffix: string().trim(),
labels: array().of(labelSchema).default(null).nullable(),
certified: boolean().default(false),
positions: array().of(positionSchema).default(null).nullable(),
updateDate: date(),
positions: array().of(positionSchema).when('$isPatch', {
is: true,
// eslint-disable-next-line unicorn/no-thenable
then: schema => schema.default(null).nullable(),
otherwise: schema => schema.required(),
}),
updateDate: date().when('$isPatch', {
is: true,
otherwise: schema => schema.required(),
}),
meta: metaSchema
}).noUnknown()

Expand Down
22 changes: 2 additions & 20 deletions lib/api/address/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {checkDataFormat, dataValidationReportFrom, checkIdsIsUniq, checkIdsIsVacant, checkIdsIsAvailable, checkDataShema, checkIdsShema, checkIfCommonToponymsExist, checkIfDistrictsExist} from '../helper.js'
import {banID} from '../schema.js'
import {getAddresses, getAllAddressIDsFromDistrict, getAllAddressIDsOutsideDistrict} from './models.js'
import {banAddressSchema, banAddressSchemaForPatch} from './schema.js'
import {banAddressSchema} from './schema.js'

const getExistingAddressIDs = async addressIDs => {
const existingAddresses = await getAddresses(addressIDs)
Expand Down Expand Up @@ -50,32 +50,14 @@ export const checkAddressesRequest = async (addresses, actionType) => {
switch (actionType) {
case 'insert':
case 'update':
report = checkDataFormat(
`The request require an Array of address but receive ${typeof addresses}`,
'No address send to job',
addresses
)
|| await checkAddressesIDsRequest(addresses.map(address => address.id), actionType, false)
|| await checkDataShema('Invalid format', addresses, banAddressSchema)
|| await checkIfCommonToponymsExist(addresses.reduce((acc, {mainCommonToponymID, secondaryCommonToponymIDs}) => {
const ids = [mainCommonToponymID]
if (secondaryCommonToponymIDs) {
ids.push(...secondaryCommonToponymIDs)
}

return [...acc, ...ids]
}, []))
|| await checkIfDistrictsExist(addresses.map(({districtID}) => districtID))
|| dataValidationReportFrom(true)
break
case 'patch':
report = checkDataFormat(
`The request require an Array of address but receive ${typeof addresses}`,
'No address send to job',
addresses
)
|| await checkAddressesIDsRequest(addresses.map(address => address.id), actionType, false)
|| await checkDataShema('Invalid format', addresses, banAddressSchemaForPatch)
|| await checkDataShema('Invalid format', addresses, banAddressSchema, {isPatch: actionType === 'patch'})
|| await checkIfCommonToponymsExist(addresses.reduce((acc, {mainCommonToponymID, secondaryCommonToponymIDs}) => {
const ids = mainCommonToponymID ? [mainCommonToponymID] : []
if (secondaryCommonToponymIDs) {
Expand Down
40 changes: 22 additions & 18 deletions lib/api/common-toponym/models.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,52 @@
import {Op} from 'sequelize'
import {CommonToponym} from '../../util/sequelize.js'

export async function getCommonToponym(commonToponymID) {
return CommonToponym.findByPk(commonToponymID, {raw: true})
}
export const getCommonToponym = commonToponymID => CommonToponym.findByPk(commonToponymID, {raw: true})

export async function getCommonToponyms(commonToponymIDs) {
return CommonToponym.findAll({where: {id: commonToponymIDs}, raw: true})
}
export const getCommonToponyms = commonToponymIDs => CommonToponym.findAll({where: {id: commonToponymIDs}, raw: true})

export async function getAllCommonToponymIDsFromDistrict(districtID) {
export const getAllCommonToponymIDsFromDistrict = async districtID => {
const commonToponyms = await CommonToponym.findAll(
{where: {districtID}, attributes: ['id'], raw: true}
)
return commonToponyms.map(commonToponym => commonToponym.id)
}

export async function getAllCommonToponymIDsOutsideDistrict(commonToponymIDs, districtID) {
export const getAllCommonToponymIDsOutsideDistrict = async (commonToponymIDs, districtID) => {
const commonToponyms = await CommonToponym.findAll(
{where: {id: commonToponymIDs, districtID: {[Op.ne]: districtID}}, attributes: ['id'], raw: true}
)
return commonToponyms.map(commonToponym => commonToponym.id)
}

export async function setCommonToponyms(commonToponyms) {
return CommonToponym.bulkCreate(commonToponyms)
}
export const setCommonToponyms = commonToponyms => CommonToponym.bulkCreate(commonToponyms)

export async function updateCommonToponyms(commonToponyms) {
export const updateCommonToponyms = commonToponyms => {
const bulkOperations = commonToponyms.map(commonToponym =>
CommonToponym.update(commonToponym, {where: {id: commonToponym.id}})
)
return Promise.all(bulkOperations)
}

export async function deleteCommonToponym(commonToponymID) {
return CommonToponym.destroy({where: {id: commonToponymID}})
}
export const patchCommonToponyms = async commonToponyms => {
const bulkOperations = commonToponyms.map(async commonToponym => {
// Separate meta from the rest of the object to process the update separately
const {meta, ...commonToponymRest} = commonToponym
const commonToponymID = commonToponym.id
const commonToponymDB = await CommonToponym.findByPk(commonToponymID)
commonToponymDB.set(commonToponymRest)
commonToponymDB.meta = {...commonToponymDB.meta, ...meta}
return commonToponymDB.save()
})

export async function deleteCommonToponyms(commonToponymIDs) {
return CommonToponym.destroy({where: {id: commonToponymIDs}})
return Promise.all(bulkOperations)
}

export async function getAllDistrictIDsFromCommonToponyms(commonToponymIDs) {
export const deleteCommonToponym = commonToponymID => CommonToponym.destroy({where: {id: commonToponymID}})

export const deleteCommonToponyms = commonToponymIDs => CommonToponym.destroy({where: {id: commonToponymIDs}})

export const getAllDistrictIDsFromCommonToponyms = async commonToponymIDs => {
const commonToponyms = await CommonToponym.findAll({where: {id: commonToponymIDs}, attributes: ['districtID'], raw: true})
return commonToponyms.map(commonToponym => commonToponym.districtID)
}
26 changes: 14 additions & 12 deletions lib/api/common-toponym/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ const metaSchema = object({

export const banCommonToponymSchema = object({
id: banID.required(),
districtID: banID.required(),
labels: array().of(labelSchema).required(),
districtID: banID.when('$isPatch', {
is: true,
otherwise: schema => schema.required(),
}),
labels: array().of(labelSchema).when('$isPatch', {
is: true,
// eslint-disable-next-line unicorn/no-thenable
then: schema => schema.default(null).nullable(),
otherwise: schema => schema.required(),
}),
geometry: geometrySchema.default(null).nullable(),
updateDate: date().required(),
meta: metaSchema
}).noUnknown()

export const banCommonToponymSchemaForPatch = object({
id: banID.required(),
districtID: banID,
labels: array().of(labelSchema).default(null).nullable(),
geometry: geometrySchema.default(null).nullable(),
updateDate: date(),
updateDate: date().when('$isPatch', {
is: true,
otherwise: schema => schema.required(),
}),
meta: metaSchema
}).noUnknown()

Expand Down
14 changes: 2 additions & 12 deletions lib/api/common-toponym/utils.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {checkDataFormat, dataValidationReportFrom, checkIdsIsUniq, checkIdsIsVacant, checkIdsIsAvailable, checkDataShema, checkIdsShema, checkIfDistrictsExist} from '../helper.js'
import {banID} from '../schema.js'
import {getCommonToponyms, getAllCommonToponymIDsFromDistrict, getAllCommonToponymIDsOutsideDistrict} from './models.js'
import {banCommonToponymSchema, banCommonToponymSchemaForPatch} from './schema.js'
import {banCommonToponymSchema} from './schema.js'

const getExistingCommonToponymIDs = async commonToponymIDs => {
const existingCommonToponyms = await getCommonToponyms(commonToponymIDs)
Expand Down Expand Up @@ -50,24 +50,14 @@ export const checkCommonToponymsRequest = async (commonToponyms, actionType) =>
switch (actionType) {
case 'insert':
case 'update':
report = checkDataFormat(
`The request require an Array of common toponym but receive ${typeof commonToponyms}`,
'No common toponym send to job',
commonToponyms
)
|| await checkCommonToponymsIDsRequest(commonToponyms.map(commonToponym => commonToponym.id), actionType, false)
|| await checkDataShema('Invalid common toponym format', commonToponyms, banCommonToponymSchema)
|| await checkIfDistrictsExist(commonToponyms.map(({districtID}) => districtID))
|| dataValidationReportFrom(true)
break
case 'patch':
report = checkDataFormat(
`The request require an Array of common toponym but receive ${typeof commonToponyms}`,
'No common toponym send to job',
commonToponyms
)
|| await checkCommonToponymsIDsRequest(commonToponyms.map(commonToponym => commonToponym.id), actionType, false)
|| await checkDataShema('Invalid common toponym format', commonToponyms, banCommonToponymSchemaForPatch)
|| await checkDataShema('Invalid common toponym format', commonToponyms, banCommonToponymSchema, {isPatch: actionType === 'patch'})
|| await checkIfDistrictsExist(commonToponyms.reduce((acc, {districtID}) => {
if (districtID) {
return [...acc, districtID]
Expand Down
12 changes: 6 additions & 6 deletions lib/api/consumers/api-consumer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import queue from '../../util/queue.cjs'
import {getJobStatus, setJobStatus} from '../job-status/models.js'
import {setAddresses, updateAddresses, deleteAddresses, getAllDistrictIDsFromAddresses} from '../address/models.js'
import {setAddresses, updateAddresses, patchAddresses, deleteAddresses, getAllDistrictIDsFromAddresses} from '../address/models.js'
import {checkAddressesRequest, checkAddressesIDsRequest} from '../address/utils.js'
import {setCommonToponyms, updateCommonToponyms, deleteCommonToponyms, getAllDistrictIDsFromCommonToponyms} from '../common-toponym/models.js'
import {setCommonToponyms, updateCommonToponyms, patchCommonToponyms, deleteCommonToponyms, getAllDistrictIDsFromCommonToponyms} from '../common-toponym/models.js'
import {checkCommonToponymsRequest, checkCommonToponymsIDsRequest} from '../common-toponym/utils.js'
import {setDistricts, updateDistricts, deleteDistricts} from '../district/models.js'
import {setDistricts, updateDistricts, patchDistricts, deleteDistricts} from '../district/models.js'
import {checkDistrictsRequest, checkDistrictsIDsRequest} from '../district/utils.js'
import {dataValidationReportFrom, formatObjectWithDefaults, addOrUpdateJob} from '../helper.js'
import {addressDefaultOptionalValues} from '../address/schema.js'
Expand Down Expand Up @@ -93,7 +93,7 @@ const addressConsumer = async (jobType, payload, statusID) => {
}

case 'patch':
await updateAddresses(payload)
await patchAddresses(payload)
break
case 'delete':
await deleteAddresses(payload)
Expand Down Expand Up @@ -155,7 +155,7 @@ const commonToponymConsumer = async (jobType, payload, statusID) => {
}

case 'patch':
await updateCommonToponyms(payload)
await patchCommonToponyms(payload)
break
case 'delete':
await deleteCommonToponyms(payload)
Expand Down Expand Up @@ -217,7 +217,7 @@ const districtConsumer = async (jobType, payload, statusID) => {
}

case 'patch':
await updateDistricts(payload)
await patchDistricts(payload)
break
case 'delete':
await deleteDistricts(payload)
Expand Down
38 changes: 20 additions & 18 deletions lib/api/district/models.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
import {District} from '../../util/sequelize.js'

export async function getDistrict(districtID) {
return District.findByPk(districtID, {raw: true})
}
export const getDistrict = districtID => District.findByPk(districtID, {raw: true})

export async function getDistricts(districtIDs) {
return District.findAll({where: {id: districtIDs}, raw: true})
}
export const getDistricts = districtIDs => District.findAll({where: {id: districtIDs}, raw: true})

export async function getDistrictsFromCog(cog) {
return District.findAll({where: {meta: {insee: {cog}}}, raw: true})
}
export const getDistrictsFromCog = cog => District.findAll({where: {meta: {insee: {cog}}}, raw: true})

export async function setDistricts(districts) {
return District.bulkCreate(districts)
}
export const setDistricts = districts => District.bulkCreate(districts)

export async function updateDistricts(districts) {
export const updateDistricts = districts => {
const promises = districts.map(district => District.update(district, {where: {id: district.id}}))
return Promise.all(promises)
}

export async function deleteDistrict(districtID) {
return District.destroy({where: {id: districtID}})
}
export const patchDistricts = async districts => {
const bulkOperations = districts.map(async district => {
// Separate meta from the rest of the object to process the update separately
const {meta, ...districtRest} = district
const districtID = district.id
const districtDB = await District.findByPk(districtID)
districtDB.set(districtRest)
districtDB.meta = {...districtDB.meta, ...meta}
return districtDB.save()
})

export async function deleteDistricts(districtIDs) {
return District.destroy({where: {id: districtIDs}})
return Promise.all(bulkOperations)
}

export const deleteDistrict = districtID => District.destroy({where: {id: districtID}})

export const deleteDistricts = districtIDs => District.destroy({where: {id: districtIDs}})
Loading
Loading