* Upsert * * @param {string} tableName table to upsert on * @param {object} insertValues values to be inserted, mapped to field name * @param {object} updateValues values to be updated, mapped to field name * @param {object} where where conditions, which can be used for UPDA
(tableName, insertValues, updateValues, where, options)
| 810 | * @returns {Promise<boolean,?number>} Resolves an array with <created, primaryKey> |
| 811 | */ |
| 812 | async upsert(tableName, insertValues, updateValues, where, options) { |
| 813 | options = { ...options }; |
| 814 | |
| 815 | const model = options.model; |
| 816 | |
| 817 | options.type = QueryTypes.UPSERT; |
| 818 | options.updateOnDuplicate = Object.keys(updateValues); |
| 819 | options.upsertKeys = options.conflictFields || []; |
| 820 | |
| 821 | if (options.upsertKeys.length === 0) { |
| 822 | const primaryKeys = Object.values(model.primaryKeys).map(item => item.field); |
| 823 | const uniqueKeys = Object.values(model.uniqueKeys).filter(c => c.fields.length > 0).map(c => c.fields); |
| 824 | const indexKeys = Object.values(model._indexes).filter(c => c.unique && c.fields.length > 0).map(c => c.fields); |
| 825 | // For fields in updateValues, try to find a constraint or unique index |
| 826 | // that includes given field. Only first matching upsert key is used. |
| 827 | for (const field of options.updateOnDuplicate) { |
| 828 | const uniqueKey = uniqueKeys.find(fields => fields.includes(field)); |
| 829 | if (uniqueKey) { |
| 830 | options.upsertKeys = uniqueKey; |
| 831 | break; |
| 832 | } |
| 833 | |
| 834 | const indexKey = indexKeys.find(fields => fields.includes(field)); |
| 835 | if (indexKey) { |
| 836 | options.upsertKeys = indexKey; |
| 837 | break; |
| 838 | } |
| 839 | } |
| 840 | |
| 841 | // Always use PK, if no constraint available OR update data contains PK |
| 842 | if ( |
| 843 | options.upsertKeys.length === 0 |
| 844 | || _.intersection(options.updateOnDuplicate, primaryKeys).length |
| 845 | ) { |
| 846 | options.upsertKeys = primaryKeys; |
| 847 | } |
| 848 | |
| 849 | options.upsertKeys = _.uniq(options.upsertKeys); |
| 850 | } |
| 851 | |
| 852 | const sql = this.queryGenerator.insertQuery(tableName, insertValues, model.rawAttributes, options); |
| 853 | return await this.sequelize.query(sql, options); |
| 854 | } |
| 855 | |
| 856 | /** |
| 857 | * Insert multiple records into a table |
nothing calls this directly
no test coverage detected