@@ -3,61 +3,123 @@ const tcUserId = require('./common/tcUserId')
3
3
const Sequelize = require ( 'sequelize' )
4
4
const _ = require ( 'lodash' )
5
5
const helper = require ( '../src/common/helper' )
6
+ const request = require ( 'superagent' )
7
+ const config = require ( 'config' )
6
8
7
- // read cli arguments, pass the table name
8
- const tableName = process . argv [ 2 ]
9
- // read cli arguments, pass the column names to update
10
- const columnNames = process . argv [ 3 ]
9
+ /**
10
+ *
11
+ * @param {string } handle - The member handle
12
+ * @returns {Promise<object> } The member details from the member API
13
+ */
14
+ async function getMemberDetailsByHandle ( handle ) {
15
+ const token = await helper . getM2MToken ( )
16
+ let res
17
+ try {
18
+ res = await request
19
+ . get ( `${ config . TOPCODER_MEMBERS_API } /${ handle } ` )
20
+ . query ( {
21
+ fields : 'userId,handle,handleLower,firstName,lastName,email'
22
+ } )
23
+ . set ( 'Authorization' , `Bearer ${ token } ` )
24
+ . set ( 'Accept' , 'application/json' )
25
+ return res . body
26
+ } catch ( error ) {
27
+ console . log ( `Unable to find member with handle ${ handle } ` )
28
+ return { }
29
+ }
30
+ }
11
31
12
32
const processRemainingUUIDs = async ( tableName , columnNames ) => {
13
33
const dbUrl = process . env . UBAHN_DB_URL
14
34
const MODE = process . env . MODE || 'test'
35
+ const handleToIDMap = { }
15
36
16
37
if ( _ . isUndefined ( dbUrl ) || _ . isNull ( dbUrl ) ) {
17
38
console . log ( 'Ubahn DB URL not set, exiting!' )
18
39
process . exit ( 0 )
19
40
}
20
41
42
+ // only for readability
43
+ console . log ( )
44
+ console . log ( '---------------------------------------------------------------------------------------------------------------' )
45
+ console . log ( )
46
+
21
47
for ( const columnName of _ . split ( columnNames , ',' ) ) {
22
- const query = `SELECT DISTINCT ${ columnName } FROM bookings.${ tableName } WHERE LENGTH(${ columnName } ) > 9 AND ${ columnName } <> '00000000-0000-0000-0000-000000000000';`
23
- let results = await models . sequelize . query ( query , { type : Sequelize . QueryTypes . SELECT } )
24
-
25
- if ( results . length > 0 ) {
26
- results = _ . uniq ( _ . map ( _ . filter ( results , val => toString ( val [ `${ columnName } ` ] ) . length > 9 ) , val => val [ `${ columnName } ` ] ) )
27
- console . log ( `result: ${ JSON . stringify ( results ) } ` )
28
-
29
- const ubahnConn = await tcUserId . getUbahnDatabaseConnection ( dbUrl )
30
- const uuidToHandleMap = await tcUserId . getUserUbahnUUIDToHandleMap ( ubahnConn , results )
31
-
32
- const handleToIDMap = { }
33
- const batches = _ . chunk ( Object . values ( uuidToHandleMap ) , 30 )
34
- for ( const batch of batches ) {
35
- const memberAPIRes = await helper . getMemberDetailsByHandles ( batch )
36
- _ . forEach ( memberAPIRes , member => {
37
- handleToIDMap [ member . handleLower ] = member . userId
38
- } )
39
- }
40
48
41
- let sql = ''
42
- for ( const [ key , value ] of Object . entries ( uuidToHandleMap ) ) {
43
- if ( ! _ . isUndefined ( handleToIDMap [ value . toLowerCase ( ) ] ) ) {
44
- sql += `UPDATE bookings.${ tableName } SET ${ columnName } = '${ handleToIDMap [ value . toLowerCase ( ) ] } ' WHERE ${ columnName } = '${ key } ';`
49
+ let transaction = await models . sequelize . transaction ( )
50
+
51
+ try {
52
+ // check each column to find distinct existing uuids which have not yet been converted to TC legacy user id
53
+ const query = `SELECT DISTINCT ${ columnName } FROM bookings.${ tableName } WHERE LENGTH(${ columnName } ) > 9 AND ${ columnName } <> '00000000-0000-0000-0000-000000000000';`
54
+ console . log ( `Executing query in table ${ tableName } against column ${ columnName } ` )
55
+ console . log ( `SQL query: ${ query } ` )
56
+ let results = await models . sequelize . query ( query , { type : Sequelize . QueryTypes . SELECT } )
57
+
58
+ if ( results . length > 0 ) {
59
+ results = _ . uniq ( _ . map ( _ . filter ( results , val => toString ( val [ `${ columnName } ` ] ) . length > 9 ) , val => val [ `${ columnName } ` ] ) )
60
+ console . log ( `SQL query result: ${ JSON . stringify ( results ) } ` )
61
+
62
+ // get the ubahn uuid to handle map
63
+ const ubahnConn = await tcUserId . getUbahnDatabaseConnection ( dbUrl )
64
+ const uuidToHandleMap = await tcUserId . getUserUbahnUUIDToHandleMap ( ubahnConn , results )
65
+
66
+ // get the handle to legacy topcoder id map
67
+ for ( const handle of Object . values ( uuidToHandleMap ) ) {
68
+ console . log ( `handle to search for ${ handle } ` )
69
+ if ( _ . isUndefined ( handleToIDMap [ handle ] ) ) {
70
+ const member = await getMemberDetailsByHandle ( handle )
71
+ handleToIDMap [ member . handleLower ] = member . userId
72
+ }
45
73
}
74
+
75
+ // build the update queries
76
+ let sql = ''
77
+ for ( const [ key , value ] of Object . entries ( uuidToHandleMap ) ) {
78
+ if ( ! _ . isUndefined ( handleToIDMap [ value . toLowerCase ( ) ] ) ) {
79
+ sql += `UPDATE bookings.${ tableName } SET ${ columnName } = '${ handleToIDMap [ value . toLowerCase ( ) ] } ' WHERE ${ columnName } = '${ key } ';`
80
+ }
81
+ }
82
+
83
+ // execute update queries if and only if it's not in test mode
84
+ if ( sql !== '' ) {
85
+ console . log ( `SQL UPDATE statements: ${ sql } ` )
86
+ if ( MODE !== 'test' ) {
87
+ console . log ( `Executing UPDATE statements` )
88
+ await models . sequelize . query ( sql , { type : Sequelize . QueryTypes . UPDATE , transaction : transaction } )
89
+ }
90
+ } else {
91
+ console . log ( `No UPDATE statements to execute against column ${ columnName } ` )
92
+ }
93
+ } else {
94
+ console . log ( `No data eligible to be updated for table: ${ tableName } against column ${ columnName } ` )
46
95
}
47
- console . log ( `UPDATE statements: ${ sql } ` )
48
- if ( MODE !== test ) {
49
- await models . sequelize . query ( sql , { type : Sequelize . QueryTypes . UPDATE } )
50
- }
51
- } else {
52
- console . log ( `No data eligible to be updated for table: ${ tableName } against column ${ columnName } ` )
96
+
97
+ // only for readability
98
+ console . log ( '---------------------------------------------------------------------------------------------------------------' )
99
+ console . log ( )
100
+
101
+ await transaction . commit ( )
102
+
103
+ } catch ( error ) {
104
+ console . log ( `Error encountered` )
105
+ console . error ( JSON . stringify ( error ) )
106
+ await transaction . rollback ( )
53
107
}
54
108
}
109
+
110
+ console . log ( `DONE processing table ${ tableName } ` )
55
111
}
56
112
113
+ // read cli arguments, pass the table name
114
+ const tableName = process . argv [ 2 ]
115
+ // read cli arguments, pass the column names to update
116
+ const columnNames = process . argv [ 3 ]
117
+
57
118
processRemainingUUIDs ( tableName , columnNames ) . then ( res => {
58
119
console . log ( `Processed remaining records for model '${ tableName } ' against columns: ${ columnNames } ` )
59
120
process . exit ( 0 )
60
121
} ) . catch ( err => {
122
+ console . log ( `Error encountered!` )
61
123
console . error ( `${ JSON . stringify ( err ) } ` )
62
124
process . exit ( 1 )
63
- } )
125
+ } )
0 commit comments