| 184 | |
| 185 | // Handle incoming vote requests and inserting them into the database. |
| 186 | const httpPost = async (req, res) => { |
| 187 | const {team} = req.body; |
| 188 | const timestamp = new Date(); |
| 189 | |
| 190 | if (!team || (team !== 'TABS' && team !== 'SPACES')) { |
| 191 | return res.status(400).send('Invalid team specified.').end(); |
| 192 | } |
| 193 | |
| 194 | // [START cloud_sql_sqlserver_mssql_connection] |
| 195 | try { |
| 196 | const stmt = |
| 197 | 'INSERT INTO votes (time_cast, candidate) VALUES (@timestamp, @team)'; |
| 198 | // Using a prepared statement protects against SQL injection attacks. |
| 199 | // When prepare is called, a single connection is acquired from the connection pool |
| 200 | // and all subsequent executions are executed exclusively on this connection. |
| 201 | const ps = new mssql.PreparedStatement(pool); |
| 202 | ps.input('timestamp', mssql.DateTime); |
| 203 | ps.input('team', mssql.VarChar(6)); |
| 204 | await ps.prepare(stmt); |
| 205 | await ps.execute({ |
| 206 | timestamp: timestamp, |
| 207 | team: team, |
| 208 | }); |
| 209 | await ps.unprepare(); |
| 210 | } catch (err) { |
| 211 | // If something goes wrong, handle the error in this section. This might |
| 212 | // involve retrying or adjusting parameters depending on the situation. |
| 213 | // [START_EXCLUDE] |
| 214 | |
| 215 | logger.error(err); |
| 216 | return res |
| 217 | .status(500) |
| 218 | .send( |
| 219 | 'Unable to successfully cast vote! Please check the application logs for more details.' |
| 220 | ) |
| 221 | .end(); |
| 222 | // [END_EXCLUDE] |
| 223 | } |
| 224 | // [END cloud_sql_sqlserver_mssql_connection] |
| 225 | |
| 226 | res.status(200).send(`Successfully voted for ${team} at ${timestamp}`).end(); |
| 227 | }; |
| 228 | |
| 229 | app.post('*', httpPost); |
| 230 | |