{ "version": 3, "sources": ["../../../src/dialects/mariadb/query.js"], "sourcesContent": ["'use strict';\n\nconst AbstractQuery = require('../abstract/query');\nconst sequelizeErrors = require('../../errors');\nconst _ = require('lodash');\nconst DataTypes = require('../../data-types');\nconst { logger } = require('../../utils/logger');\n\nconst ER_DUP_ENTRY = 1062;\nconst ER_DEADLOCK = 1213;\nconst ER_ROW_IS_REFERENCED = 1451;\nconst ER_NO_REFERENCED_ROW = 1452;\n\nconst debug = logger.debugContext('sql:mariadb');\n\nclass Query extends AbstractQuery {\n constructor(connection, sequelize, options) {\n super(connection, sequelize, { showWarnings: false, ...options });\n }\n\n static formatBindParameters(sql, values, dialect) {\n const bindParam = [];\n const replacementFunc = (match, key, values_) => {\n if (values_[key] !== undefined) {\n bindParam.push(values_[key]);\n return '?';\n }\n return undefined;\n };\n sql = AbstractQuery.formatBindParameters(sql, values, dialect, replacementFunc)[0];\n return [sql, bindParam.length > 0 ? bindParam : undefined];\n }\n\n async run(sql, parameters) {\n this.sql = sql;\n const { connection, options } = this;\n\n const showWarnings = this.sequelize.options.showWarnings || options.showWarnings;\n\n const complete = this._logQuery(sql, debug, parameters);\n\n if (parameters) {\n debug('parameters(%j)', parameters);\n }\n\n let results;\n const errForStack = new Error();\n\n try {\n results = await connection.query(this.sql, parameters);\n } catch (error) {\n if (options.transaction && error.errno === ER_DEADLOCK) {\n // MariaDB automatically rolls-back transactions in the event of a deadlock.\n // However, we still initiate a manual rollback to ensure the connection gets released - see #13102.\n try {\n await options.transaction.rollback();\n } catch (error_) {\n // Ignore errors - since MariaDB automatically rolled back, we're\n // not that worried about this redundant rollback failing.\n }\n\n options.transaction.finished = 'rollback';\n }\n\n error.sql = sql;\n error.parameters = parameters;\n throw this.formatError(error, errForStack.stack);\n } finally {\n complete();\n }\n\n if (showWarnings && results && results.warningStatus > 0) {\n await this.logWarnings(results);\n }\n return this.formatResults(results);\n }\n\n /**\n * High level function that handles the results of a query execution.\n *\n *\n * Example:\n * query.formatResults([\n * {\n * id: 1, // this is from the main table\n * attr2: 'snafu', // this is from the main table\n * Tasks.id: 1, // this is from the associated table\n * Tasks.title: 'task' // this is from the associated table\n * }\n * ])\n *\n * @param {Array} data - The result of the query execution.\n * @private\n */\n formatResults(data) {\n let result = this.instance;\n\n if (this.isBulkUpdateQuery() || this.isBulkDeleteQuery()) {\n return data.affectedRows;\n }\n if (this.isUpsertQuery()) {\n return [result, data.affectedRows === 1];\n }\n if (this.isInsertQuery(data)) {\n this.handleInsertQuery(data);\n\n if (!this.instance) {\n // handle bulkCreate AI primary key\n if (\n this.model\n && this.model.autoIncrementAttribute\n && this.model.autoIncrementAttribute === this.model.primaryKeyAttribute\n && this.model.rawAttributes[this.model.primaryKeyAttribute]\n ) {\n // ONLY TRUE IF @auto_increment_increment is set to 1 !!\n // Doesn't work with GALERA => each node will reserve increment (x for first server, x+1 for next node...)\n const startId = data[this.getInsertIdField()];\n result = new Array(data.affectedRows);\n const pkField = this.model.rawAttributes[this.model.primaryKeyAttribute].field;\n for (let i = 0; i < data.affectedRows; i++) {\n result[i] = { [pkField]: startId + i };\n }\n return [result, data.affectedRows];\n }\n\n return [data[this.getInsertIdField()], data.affectedRows];\n }\n }\n\n if (this.isSelectQuery()) {\n this.handleJsonSelectQuery(data);\n return this.handleSelectQuery(data);\n }\n if (this.isInsertQuery() || this.isUpdateQuery()) {\n return [result, data.affectedRows];\n }\n if (this.isCallQuery()) {\n return data[0];\n }\n if (this.isRawQuery()) {\n const meta = data.meta;\n delete data.meta;\n return [data, meta];\n }\n if (this.isShowIndexesQuery()) {\n return this.handleShowIndexesQuery(data);\n }\n if (this.isForeignKeysQuery() || this.isShowConstraintsQuery()) {\n return data;\n }\n if (this.isShowTablesQuery()) {\n return this.handleShowTablesQuery(data);\n }\n if (this.isDescribeQuery()) {\n result = {};\n\n for (const _result of data) {\n result[_result.Field] = {\n type: _result.Type.toLowerCase().startsWith('enum') ? _result.Type.replace(/^enum/i,\n 'ENUM') : _result.Type.toUpperCase(),\n allowNull: _result.Null === 'YES',\n defaultValue: _result.Default,\n primaryKey: _result.Key === 'PRI',\n autoIncrement: Object.prototype.hasOwnProperty.call(_result, 'Extra')\n && _result.Extra.toLowerCase() === 'auto_increment',\n comment: _result.Comment ? _result.Comment : null\n };\n }\n return result;\n }\n if (this.isVersionQuery()) {\n return data[0].version;\n }\n\n return result;\n }\n\n handleJsonSelectQuery(rows) {\n if (!this.model || !this.model.fieldRawAttributesMap) {\n return;\n }\n for (const _field of Object.keys(this.model.fieldRawAttributesMap)) {\n const modelField = this.model.fieldRawAttributesMap[_field];\n if (modelField.type instanceof DataTypes.JSON) {\n // Value is returned as String, not JSON\n rows = rows.map(row => {\n if (row[modelField.fieldName] && typeof row[modelField.fieldName] === 'string') {\n row[modelField.fieldName] = JSON.parse(row[modelField.fieldName]);\n }\n if (DataTypes.JSON.parse) {\n return DataTypes.JSON.parse(modelField, this.sequelize.options,\n row[modelField.fieldName]);\n }\n return row;\n });\n }\n }\n }\n\n async logWarnings(results) {\n const warningResults = await this.run('SHOW WARNINGS');\n const warningMessage = `MariaDB Warnings (${this.connection.uuid || 'default'}): `;\n const messages = [];\n for (const _warningRow of warningResults) {\n if (_warningRow === undefined || typeof _warningRow[Symbol.iterator] !== 'function') {\n continue;\n }\n for (const _warningResult of _warningRow) {\n if (Object.prototype.hasOwnProperty.call(_warningResult, 'Message')) {\n messages.push(_warningResult.Message);\n } else {\n for (const _objectKey of _warningResult.keys()) {\n messages.push([_objectKey, _warningResult[_objectKey]].join(': '));\n }\n }\n }\n }\n\n this.sequelize.log(warningMessage + messages.join('; '), this.options);\n\n return results;\n }\n\n formatError(err, errStack) {\n switch (err.errno) {\n case ER_DUP_ENTRY: {\n const match = err.message.match(\n /Duplicate entry '([\\s\\S]*)' for key '?((.|\\s)*?)'?\\s.*$/);\n\n let fields = {};\n let message = 'Validation error';\n const values = match ? match[1].split('-') : undefined;\n const fieldKey = match ? match[2] : undefined;\n const fieldVal = match ? match[1] : undefined;\n const uniqueKey = this.model && this.model.uniqueKeys[fieldKey];\n\n if (uniqueKey) {\n if (uniqueKey.msg) message = uniqueKey.msg;\n fields = _.zipObject(uniqueKey.fields, values);\n } else {\n fields[fieldKey] = fieldVal;\n }\n\n const errors = [];\n _.forOwn(fields, (value, field) => {\n errors.push(new sequelizeErrors.ValidationErrorItem(\n this.getUniqueConstraintErrorMessage(field),\n 'unique violation', // sequelizeErrors.ValidationErrorItem.Origins.DB,\n field,\n value,\n this.instance,\n 'not_unique'\n ));\n });\n\n return new sequelizeErrors.UniqueConstraintError({ message, errors, parent: err, fields, stack: errStack });\n }\n\n case ER_ROW_IS_REFERENCED:\n case ER_NO_REFERENCED_ROW: {\n // e.g. CONSTRAINT `example_constraint_name` FOREIGN KEY (`example_id`) REFERENCES `examples` (`id`)\n const match = err.message.match(\n /CONSTRAINT ([`\"])(.*)\\1 FOREIGN KEY \\(\\1(.*)\\1\\) REFERENCES \\1(.*)\\1 \\(\\1(.*)\\1\\)/\n );\n const quoteChar = match ? match[1] : '`';\n const fields = match ? match[3].split(new RegExp(`${quoteChar}, *${quoteChar}`)) : undefined;\n\n return new sequelizeErrors.ForeignKeyConstraintError({\n reltype: err.errno === ER_ROW_IS_REFERENCED ? 'parent' : 'child',\n table: match ? match[4] : undefined,\n fields,\n value: fields && fields.length && this.instance && this.instance[fields[0]] || undefined,\n index: match ? match[2] : undefined,\n parent: err,\n stack: errStack\n });\n }\n\n default:\n return new sequelizeErrors.DatabaseError(err, { stack: errStack });\n }\n }\n\n handleShowTablesQuery(results) {\n return results.map(resultSet => ({\n tableName: resultSet.TABLE_NAME,\n schema: resultSet.TABLE_SCHEMA\n }));\n }\n\n handleShowIndexesQuery(data) {\n\n let currItem;\n const result = [];\n\n data.forEach(item => {\n if (!currItem || currItem.name !== item.Key_name) {\n currItem = {\n primary: item.Key_name === 'PRIMARY',\n fields: [],\n name: item.Key_name,\n tableName: item.Table,\n unique: item.Non_unique !== 1,\n type: item.Index_type\n };\n result.push(currItem);\n }\n\n currItem.fields[item.Seq_in_index - 1] = {\n attribute: item.Column_name,\n length: item.Sub_part || undefined,\n order: item.Collation === 'A' ? 'ASC' : undefined\n };\n });\n\n return result;\n }\n}\n\nmodule.exports = Query;\n"], "mappings": "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", "names": [] }