* Gets the tables that should be used to execute the UPDATE query. * @param {Client} client * @param {ModelMappingInfo} info * @param {Array} propertiesInfo * @param {Array} when * @return {Promise >} A promise that resolves to an Array of tables.
(client, info, propertiesInfo, when)
| 187 | * @return {Promise<Array<TableMetadata>>} A promise that resolves to an Array of tables. |
| 188 | */ |
| 189 | static getForUpdate(client, info, propertiesInfo, when) { |
| 190 | return Promise.all(info.tables.filter(t => !t.isView).map(t => client.metadata.getTable(info.keyspace, t.name))) |
| 191 | .then(tables => { |
| 192 | const filteredTables = tables |
| 193 | .filter((table, i) => { |
| 194 | if (table === null) { |
| 195 | throw new Error(`Table "${info.tables[i].name}" could not be retrieved`); |
| 196 | } |
| 197 | |
| 198 | if (keysAreIncluded(table.partitionKeys, propertiesInfo) !== keyMatches.all) { |
| 199 | // Not all the partition keys are covered |
| 200 | return false; |
| 201 | } |
| 202 | |
| 203 | const clusteringKeyMatches = keysAreIncluded(table.clusteringKeys, propertiesInfo); |
| 204 | |
| 205 | // All clustering keys should be included or it can be updating a static column value |
| 206 | if (clusteringKeyMatches === keyMatches.some) { |
| 207 | return false; |
| 208 | } |
| 209 | |
| 210 | if (clusteringKeyMatches === keyMatches.none && !hasStaticColumn(table)) { |
| 211 | return false; |
| 212 | } |
| 213 | |
| 214 | const applicableColumns = propertiesInfo |
| 215 | .reduce((acc, p) => acc + (table.columnsByName[p.columnName] !== undefined ? 1 : 0), 0); |
| 216 | |
| 217 | if (applicableColumns <= table.partitionKeys.length + table.clusteringKeys.length) { |
| 218 | if (!hasStaticColumn(table) || applicableColumns <= table.partitionKeys.length) { |
| 219 | // UPDATE statement does not contain columns to SET |
| 220 | return false; |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | // "when" conditions should be contained in the table |
| 225 | return when.reduce((acc, p) => acc && table.columnsByName[p.columnName] !== undefined, true); |
| 226 | }); |
| 227 | |
| 228 | if (filteredTables.length === 0) { |
| 229 | let message = `No table matches (all PKs and columns to set have to be specified) fields: [${ |
| 230 | propertiesInfo.map(p => p.columnName)}]`; |
| 231 | |
| 232 | if (when.length > 0) { |
| 233 | message += `; condition: [${when.map(p => p.columnName)}]`; |
| 234 | } |
| 235 | |
| 236 | throw new Error(message); |
| 237 | } |
| 238 | |
| 239 | return filteredTables; |
| 240 | }); |
| 241 | } |
| 242 | |
| 243 | /** |
| 244 | * Gets the tables that should be used to execute the DELETE query. |
no test coverage detected