
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;

module.exports = function(Self) {
    Self.ParameterizedSQL = ParameterizedSQL;

    Object.assign(Self, {
        setup() {
            Self.super_.setup.call(this);
        },

        rewriteDbError(replaceErrFunc) {
            function replaceErr(err, replaceErrFunc) {
                if (Array.isArray(err)) {
                    let errs = [];
                    for (let e of err)
                        errs.push(replaceErrFunc(e));
                    return errs;
                }
                return replaceErrFunc(err);
            }

            function rewriteMethod(methodName) {
                const realMethod = this[methodName];
                return async(data, options, cb) => {
                    if (options instanceof Function) {
                        cb = options;
                        options = null;
                    }

                    try {
                        const result = await realMethod.call(this, data, options);

                        if (cb) cb(null, result);
                        else return result;
                    } catch (err) {
                        let myErr = replaceErr(err, replaceErrFunc);
                        if (cb) cb(myErr);
                        else
                            throw myErr;
                    }
                };
            }

            this.once('attached', () => {
                this.remove =
                this.deleteAll =
                this.destroyAll = rewriteMethod.call(this, 'remove');
                this.upsert = rewriteMethod.call(this, 'upsert');
                this.create = rewriteMethod.call(this, 'create');
            });
        },

        rawSql(query, params, options, cb) {
            return this.dataSource.connector.executeP(query, params, options, cb);
        }
    });
};
