Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit d970922

Browse files
handling of adding/removing prizes
1 parent 0fb6673 commit d970922

File tree

3 files changed

+182
-7
lines changed

3 files changed

+182
-7
lines changed

src/common/idGenerator.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/**
2+
* The ID generator service
3+
*/
4+
const util = require('util')
5+
const Mutex = require('async-mutex').Mutex
6+
const logger = require('./logger')
7+
const helper = require('./helper')
8+
9+
/**
10+
* Main class of IDGenerator
11+
*/
12+
class IDGenerator {
13+
/**
14+
* Constructor
15+
* @param {Informix} db database
16+
* @param {String} seqName sequence name
17+
*/
18+
constructor (seqName) {
19+
this.seqName = seqName
20+
this._availableId = 0
21+
this.mutex = new Mutex()
22+
}
23+
24+
/**
25+
* Get next id
26+
* @returns {Number} next id
27+
*/
28+
async getNextId () {
29+
const release = await this.mutex.acquire()
30+
try {
31+
logger.debug('Getting nextId')
32+
--this._availableId
33+
logger.debug(`this._availableId = ${this._availableId}`)
34+
35+
if (this._availableId <= 0) {
36+
const connection = await helper.getInformixConnection()
37+
try {
38+
// begin transaction
39+
await connection.beginTransactionAsync()
40+
41+
const [nextId, availableId] = await this.getNextBlock(connection)
42+
await this.updateNextBlock(connection, nextId + availableId + 1)
43+
44+
// commit the transaction
45+
await connection.commitTransactionAsync()
46+
47+
// Only set to this's properties after successful commit
48+
this._nextId = nextId
49+
this._availableId = availableId
50+
} catch (e) {
51+
await connection.rollbackTransactionAsync()
52+
throw e
53+
} finally {
54+
await connection.closeAsync()
55+
}
56+
}
57+
58+
logger.debug(`this._availableId = ${this._availableId}`)
59+
return ++this._nextId
60+
} finally {
61+
release()
62+
}
63+
}
64+
65+
/**
66+
* Fetch next block from id_sequence
67+
* @param {Object} connection the Informix connection
68+
* @returns {Array} [nextId, availableId]
69+
* @private
70+
*/
71+
async getNextBlock (connection) {
72+
try {
73+
const result = await connection.queryAsync(`select next_block_start, block_size from id_sequences where name = '${this.seqName}'`)
74+
if (result.length > 0) {
75+
return [Number(result[0].next_block_start) - 1, Number(result[0].block_size)]
76+
} else {
77+
throw new Error(`null or empty result for ${this.seqName}`)
78+
}
79+
} catch (e) {
80+
logger.error(util.inspect(e))
81+
throw e
82+
}
83+
}
84+
85+
/**
86+
* Update id_sequence
87+
* @param {Object} connection the Informix connection
88+
* @param {Number} nextStart next start id
89+
* @private
90+
*/
91+
async updateNextBlock (connection, nextStart) {
92+
try {
93+
await connection.queryAsync(`update id_sequences set next_block_start = ${nextStart} where name = '${this.seqName}'`)
94+
} catch (e) {
95+
logger.error('Failed to update id sequence: ' + this.seqName)
96+
logger.error(util.inspect(e))
97+
throw e
98+
}
99+
}
100+
}
101+
102+
module.exports = IDGenerator

src/services/ProcessorService.js

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,17 @@ async function syncChallengePhases (legacyId, v5Phases) {
4444
}
4545
}
4646
}
47+
// TODO: What about iterative reviews? There can be many for the same challenge.
48+
// TODO: handle timeline template updates
4749
}
4850

4951
/**
5052
* Update the payments from v5 prize sets into legacy
51-
* @param {Array} v4Prizes the v4 prizes
52-
* @param {Number} v4NumOfCheckpointPrizes the number of checkpoints (v4)
53-
* @param {Number} v4CheckpointPrize the dollar ammount of each checkpoint prize (v4)
53+
* @param {Number} legacyId the legacy challenge ID
5454
* @param {Array} v5PrizeSets the v5 prize sets
55+
* @param {String} createdBy the created by
5556
*/
56-
async function updateMemberPayments (legacyId, v5PrizeSets) {
57+
async function updateMemberPayments (legacyId, v5PrizeSets, createdBy) {
5758
const prizesFromIfx = await paymentService.getChallengePrizes(legacyId, constants.prizeTypesIds.Contest)
5859
const [checkpointPrizesFromIfx] = await paymentService.getChallengePrizes(legacyId, constants.prizeTypesIds.Checkpoint)
5960
const v5Prizes = _.map(_.get(_.find(v5PrizeSets, p => p.type === constants.prizeSetTypes.ChallengePrizes), 'prizes', []), prize => prize.value)
@@ -67,6 +68,14 @@ async function updateMemberPayments (legacyId, v5PrizeSets) {
6768
if (_.toInteger(ifxPrize.prize_amount) !== v5Prizes[i]) {
6869
await paymentService.updatePrize(ifxPrize.prize_id, legacyId, v5Prizes[i], 1)
6970
}
71+
} else {
72+
await paymentService.createPrize(legacyId, i + 1, v5Prizes[i], constants.prizeTypesIds.Contest, 1, createdBy)
73+
}
74+
}
75+
if (prizesFromIfx.length > v5Prizes.length) {
76+
const prizesToDelete = _.filter(prizesFromIfx, p => p.place > v5Prizes.length)
77+
for (const prizeToDelete of prizesToDelete) {
78+
await paymentService.deletePrize(legacyId, prizeToDelete.prize_id)
7079
}
7180
}
7281
}
@@ -76,6 +85,8 @@ async function updateMemberPayments (legacyId, v5PrizeSets) {
7685
if (v5CheckPointPrizes.length !== checkpointPrizesFromIfx.number_of_submissions || v5CheckPointPrizes[0] !== _.toInteger(checkpointPrizesFromIfx.prize_amount)) {
7786
await paymentService.updatePrize(checkpointPrizesFromIfx.prize_id, legacyId, v5CheckPointPrizes[0], v5CheckPointPrizes.length)
7887
}
88+
} else if (checkpointPrizesFromIfx) {
89+
await paymentService.deletePrize(legacyId, checkpointPrizesFromIfx.prize_id)
7990
}
8091
}
8192

@@ -580,7 +591,7 @@ async function processUpdate (message) {
580591

581592
// Direct IFX modifications
582593
await syncChallengePhases(message.payload.legacyId, message.payload.phases)
583-
await updateMemberPayments(message.payload.legacyId, message.payload.prizeSets)
594+
await updateMemberPayments(message.payload.legacyId, message.payload.prizeSets, _.get(message, 'payload.updatedBy') || _.get(message, 'payload.createdBy'))
584595
await associateChallengeGroups(saveDraftContestDTO.groupsToBeAdded, saveDraftContestDTO.groupsToBeDeleted, message.payload.legacyId)
585596
await associateChallengeTerms(message.payload.terms, message.payload.legacyId)
586597
await setCopilotPayment(message.payload.legacyId, _.get(message, 'payload.prizeSets'), _.get(message, 'payload.createdBy'), _.get(message, 'payload.updatedBy'))

src/services/paymentService.js

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55
const logger = require('../common/logger')
66
const util = require('util')
77
const helper = require('../common/helper')
8+
const IDGenerator = require('../common/idGenerator')
9+
10+
const prizeIdGen = new IDGenerator('prize_id_seq')
811

912
const QUERY_GET_CHALLENGE_PRIZES = 'SELECT prize_id, place, prize_amount, number_of_submissions FROM prize WHERE prize_type_id = %d and project_id = %d'
1013
const QUERY_UPDATE_CHALLENGE_PRIZE = 'UPDATE prize SET prize_amount = ?, number_of_submissions = ? WHERE prize_id = %d and project_id = %d'
14+
const QUERY_CREATE_CHALLENGE_PRIZE = 'INSERT INTO prize (prize_id, project_id, place, prize_amount, prize_type_id, number_of_submissions, create_user, create_date, modify_user, modify_date) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'
15+
const QUERY_DELETE_CHALLENGE_PRIZE = 'DELETE FROM prize WHERE prize_id = %d and project_id = %d'
1116

1217
/**
1318
* Prepare Informix statement
@@ -60,13 +65,70 @@ async function updatePrize (prizeId, challengeLegacyId, prizeAmount, numberOfSub
6065
await connection.rollbackTransactionAsync()
6166
throw e
6267
} finally {
63-
logger.info(`Phase ${prizeId} has been updated`)
68+
logger.info(`Prize ${prizeId} has been updated`)
69+
await connection.closeAsync()
70+
}
71+
return result
72+
}
73+
74+
/**
75+
* Creates a new prize in IFX
76+
* @param {Number} challengeLegacyId the legacy challenge ID
77+
* @param {Number} place the placement
78+
* @param {Number} prizeAmount the prize amount
79+
* @param {Number} prizeTypeId the prize type ID
80+
* @param {Number} numberOfSubmissions the number of submissions that will receive the prize
81+
* @param {String} createdBy the creator user
82+
*/
83+
async function createPrize (challengeLegacyId, place, prizeAmount, prizeTypeId, numberOfSubmissions, createdBy) {
84+
const connection = await helper.getInformixConnection()
85+
let result = null
86+
let prizeId
87+
try {
88+
// await connection.beginTransactionAsync()
89+
prizeId = await prizeIdGen.getNextId()
90+
const currentDateIso = new Date().toISOString().replace('T', ' ').replace('Z', '').split('.')[0]
91+
const query = await prepare(connection, QUERY_CREATE_CHALLENGE_PRIZE)
92+
result = await query.executeAsync([prizeId, challengeLegacyId, place, prizeAmount, prizeTypeId, numberOfSubmissions, createdBy, currentDateIso, createdBy, currentDateIso])
93+
// await connection.commitTransactionAsync()
94+
} catch (e) {
95+
logger.error(`Error in 'createPrize' ${e}, rolling back transaction`)
96+
await connection.rollbackTransactionAsync()
97+
throw e
98+
} finally {
99+
logger.info(`Prize ${prizeId} has been updated`)
100+
await connection.closeAsync()
101+
}
102+
return result
103+
}
104+
105+
/**
106+
* Deletes a prize from IFX
107+
* @param {Number} challengeLegacyId the legacy challenge ID
108+
* @param {Number} prizeId the prize ID
109+
*/
110+
async function deletePrize (challengeLegacyId, prizeId) {
111+
const connection = await helper.getInformixConnection()
112+
let result = null
113+
try {
114+
// await connection.beginTransactionAsync()
115+
const query = await prepare(connection, QUERY_DELETE_CHALLENGE_PRIZE)
116+
result = await query.executeAsync([prizeId, challengeLegacyId])
117+
// await connection.commitTransactionAsync()
118+
} catch (e) {
119+
logger.error(`Error in 'deletePrize' ${e}, rolling back transaction`)
120+
await connection.rollbackTransactionAsync()
121+
throw e
122+
} finally {
123+
logger.info(`Prize ${prizeId} has been deleted`)
64124
await connection.closeAsync()
65125
}
66126
return result
67127
}
68128

69129
module.exports = {
70130
getChallengePrizes,
71-
updatePrize
131+
updatePrize,
132+
createPrize,
133+
deletePrize
72134
}

0 commit comments

Comments
 (0)