generated from azures04/Base-REST-API
Add transport DDL, repos and transport service
Add database DDL and server-side data access/service layers for transport domain. New SQL DDL files create transport_types, lines, stations, platforms and platform_lines tables (with FKs, indexes, spatial POINT column, CHECK constraints, and triggers to populate location). New repositories implement queries and CRUD for lines, stations, platforms and platform_lines (including distance/nearest-platform and accessibility queries). A transportService aggregates repo functions and exposes high-level operations (CRUD, station/line lookups, platform-line management and nearest-platform validation).
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findAllLines() {
|
||||
try {
|
||||
const sql = "SELECT * FROM \`lines\`"
|
||||
const rows = await pool.query(sql)
|
||||
return rows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findLineById(lineId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM \`lines\` WHERE id = ?"
|
||||
const rows = await pool.query(sql, [lineId])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findLinesByTransportType(transportTypeId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM \`lines\` WHERE transportTypeId = ?"
|
||||
const rows = await pool.query(sql, [transportTypeId])
|
||||
return rows
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function createLine(code, name, textColorHex, backColorHex, transportTypeId) {
|
||||
try {
|
||||
const sql = "INSERT INTO \`lines\` (code, name, textColorHex, backColorHex, transportTypeId) VALUES (?, ?, ?, ?, ?)"
|
||||
const rows = await pool.query(sql, [code, name, textColorHex, backColorHex, transportTypeId])
|
||||
return rows.insertId
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function updateLine(lineId, updateData) {
|
||||
try {
|
||||
const fields = Object.keys(updateData)
|
||||
const values = Object.values(updateData)
|
||||
const setClause = fields.map(f => `${f} = ?`).join(", ")
|
||||
const sql = `UPDATE \`lines\` SET ${setClause} WHERE id = ?`
|
||||
const rows = await pool.query(sql, [...values, lineId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteLine(lineId) {
|
||||
try {
|
||||
const sql = "DELETE FROM \`lines\` WHERE id = ?"
|
||||
const rows = await pool.query(sql, [lineId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findAllLines,
|
||||
findLineById,
|
||||
findLinesByTransportType,
|
||||
createLine,
|
||||
updateLine,
|
||||
deleteLine
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
// lignes d'une station (dédupliquées, tous quais confondus)
|
||||
async function findLinesByStation(stationId) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT DISTINCT l.*
|
||||
FROM \`lines\` l
|
||||
JOIN platform_lines pl ON pl.lineId = l.id
|
||||
JOIN platforms p ON p.id = pl.platformId
|
||||
WHERE p.stationId = ?
|
||||
`
|
||||
return await pool.query(sql, [stationId])
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findLinesByPlatform(platformId) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT l.*, pl.directionId, pl.orderInLine
|
||||
FROM \`lines\` l
|
||||
JOIN platform_lines pl ON pl.lineId = l.id
|
||||
WHERE pl.platformId = ?
|
||||
`
|
||||
return await pool.query(sql, [platformId])
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
// parcours ordonné d'une ligne dans un sens donné
|
||||
async function findStationsByLine(lineId, directionId = 0) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT s.*, p.id AS platformId, p.name AS platformName, pl.orderInLine
|
||||
FROM stations s
|
||||
JOIN platforms p ON p.stationId = s.id
|
||||
JOIN platform_lines pl ON pl.platformId = p.id
|
||||
WHERE pl.lineId = ? AND pl.directionId = ?
|
||||
ORDER BY pl.orderInLine
|
||||
`
|
||||
return await pool.query(sql, [lineId, directionId])
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function addLineToPlatform(platformId, lineId, directionId, orderInLine) {
|
||||
try {
|
||||
const sql = "INSERT INTO platform_lines (platformId, lineId, directionId, orderInLine) VALUES (?, ?, ?, ?)"
|
||||
const rows = await pool.query(sql, [platformId, lineId, directionId, orderInLine])
|
||||
return rows.insertId
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function removeLineFromPlatform(platformId, lineId, directionId) {
|
||||
try {
|
||||
const sql = "DELETE FROM platform_lines WHERE platformId = ? AND lineId = ? AND directionId = ?"
|
||||
const rows = await pool.query(sql, [platformId, lineId, directionId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function updateOrder(platformLineId, orderInLine) {
|
||||
try {
|
||||
const sql = "UPDATE platform_lines SET orderInLine = ? WHERE id = ?"
|
||||
const rows = await pool.query(sql, [orderInLine, platformLineId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findLinesByStation,
|
||||
findLinesByPlatform,
|
||||
findStationsByLine,
|
||||
addLineToPlatform,
|
||||
removeLineFromPlatform,
|
||||
updateOrder
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findPlatformsByStation(stationId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM platforms WHERE stationId = ?"
|
||||
return await pool.query(sql, [stationId])
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findPlatformById(platformId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM platforms WHERE id = ?"
|
||||
const rows = await pool.query(sql, [platformId])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
// cœur de la validation : quai le plus proche desservant CETTE ligne
|
||||
async function findNearestPlatformForLine(lineId, latitude, longitude, radiusM) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT p.*, ST_Distance_Sphere(p.location, ST_SRID(POINT(?, ?), 4326)) AS distance
|
||||
FROM platforms p
|
||||
JOIN platform_lines pl ON pl.platformId = p.id
|
||||
WHERE pl.lineId = ?
|
||||
HAVING distance <= ?
|
||||
ORDER BY distance
|
||||
LIMIT 1
|
||||
`
|
||||
const rows = await pool.query(sql, [longitude, latitude, lineId, radiusM])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function createPlatform(stationId, name, direction, latitude, longitude, isPRM, hasElevator) {
|
||||
try {
|
||||
const sql = `
|
||||
INSERT INTO platforms (stationId, name, direction, latitude, longitude, isPRM, hasElevator)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
`
|
||||
const rows = await pool.query(sql, [
|
||||
stationId, name, direction, latitude, longitude,
|
||||
longitude, latitude, isPRM, hasElevator
|
||||
])
|
||||
return rows.insertId
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function updatePlatformAccessibility(platformId, isPRM, hasElevator) {
|
||||
try {
|
||||
const sql = "UPDATE platforms SET isPRM = ?, hasElevator = ? WHERE id = ?"
|
||||
const rows = await pool.query(sql, [isPRM, hasElevator, platformId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function deletePlatform(platformId) {
|
||||
try {
|
||||
const sql = "DELETE FROM platforms WHERE id = ?"
|
||||
const rows = await pool.query(sql, [platformId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findPlatformsByStation,
|
||||
findPlatformById,
|
||||
findNearestPlatformForLine,
|
||||
createPlatform,
|
||||
updatePlatformAccessibility,
|
||||
deletePlatform
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
const { pool } = require("../modules/database")
|
||||
const { DefaultError } = require("../errors/errors")
|
||||
|
||||
async function findAllStations() {
|
||||
try {
|
||||
const sql = "SELECT * FROM stations"
|
||||
return await pool.query(sql)
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function findStationById(stationId) {
|
||||
try {
|
||||
const sql = "SELECT * FROM stations WHERE id = ?"
|
||||
const rows = await pool.query(sql, [stationId])
|
||||
return rows[0] || null
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
// distance = celle du quai le plus proche
|
||||
async function findStationsByDistance(latitude, longitude, radiusKm) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT s.*, MIN(ST_Distance_Sphere(p.location, ST_SRID(POINT(?, ?), 4326))) / 1000 AS distance
|
||||
FROM stations s
|
||||
JOIN platforms p ON p.stationId = s.id
|
||||
GROUP BY s.id
|
||||
HAVING distance <= ?
|
||||
ORDER BY distance
|
||||
`
|
||||
return await pool.query(sql, [longitude, latitude, radiusKm])
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
// une station est "accessible" si AU MOINS un quai l'est
|
||||
async function findAccessibleStations(latitude, longitude, radiusKm) {
|
||||
try {
|
||||
const sql = `
|
||||
SELECT s.*, MIN(ST_Distance_Sphere(p.location, ST_SRID(POINT(?, ?), 4326))) / 1000 AS distance
|
||||
FROM stations s
|
||||
JOIN platforms p ON p.stationId = s.id
|
||||
WHERE p.isPRM = TRUE AND p.hasElevator = TRUE
|
||||
GROUP BY s.id
|
||||
HAVING distance <= ?
|
||||
ORDER BY distance
|
||||
`
|
||||
return await pool.query(sql, [longitude, latitude, radiusKm])
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function createStation(name, description) {
|
||||
try {
|
||||
const sql = "INSERT INTO stations (name, description) VALUES (?, ?)"
|
||||
const rows = await pool.query(sql, [name, description])
|
||||
return rows.insertId
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function updateStation(stationId, updateData) {
|
||||
try {
|
||||
const fields = Object.keys(updateData)
|
||||
const values = Object.values(updateData)
|
||||
const setClause = fields.map(f => `${f} = ?`).join(", ")
|
||||
const sql = `UPDATE stations SET ${setClause} WHERE id = ?`
|
||||
const rows = await pool.query(sql, [...values, stationId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteStation(stationId) {
|
||||
try {
|
||||
const sql = "DELETE FROM stations WHERE id = ?"
|
||||
const rows = await pool.query(sql, [stationId])
|
||||
return rows.affectedRows > 0
|
||||
} catch (error) {
|
||||
throw new DefaultError(500, "Internal Server Error", error)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
findAllStations,
|
||||
findStationById,
|
||||
findStationsByDistance,
|
||||
findAccessibleStations,
|
||||
createStation,
|
||||
updateStation,
|
||||
deleteStation
|
||||
}
|
||||
Reference in New Issue
Block a user