"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const operators_1 = require("rxjs/operators");
const logger_1 = require("../../../logger/logger");
const mapper_1 = require("../../../mapper");
const request_expression_builder_1 = require("../../expression/request-expression-builder");
const request_model_1 = require("../request.model");
class QueryRequest extends request_model_1.Request {
    constructor(dynamoRx, modelClazz) {
        super(dynamoRx, modelClazz);
        this.mapFromDb = (queryResponse) => {
            const response = Object.assign({}, queryResponse);
            response.Items = (queryResponse.Items || []).map(item => mapper_1.fromDb(item, this.modelClazz));
            return response;
        };
        this.logger = logger_1.createLogger('dynamo.request.QueryRequest', modelClazz);
    }
    wherePartitionKey(partitionKeyValue) {
        let partitionKey;
        if (this.params.IndexName) {
            const index = this.metadata.getIndex(this.params.IndexName);
            if (index) {
                partitionKey = index.partitionKey;
                if (!partitionKey) {
                    throw new Error(`there is no parition key defined for index <${this.params.IndexName}>`);
                }
            }
            else {
                throw new Error(`the index <${this.params.IndexName}> does not exist on model ${this.modelClazz.name}`);
            }
        }
        else {
            partitionKey = this.metadata.getPartitionKey();
        }
        return request_expression_builder_1.addSortKeyCondition(partitionKey, this, this.metadata).equals(partitionKeyValue);
    }
    /**
     * used to define some condition for the sort key, use the secondary index to query based on a custom index
     * @returns {RequestConditionFunction<T>}
     */
    whereSortKey() {
        let sortKey;
        if (this.params.IndexName) {
            const index = this.metadata.getIndex(this.params.IndexName);
            if (index) {
                if (index.sortKey) {
                    sortKey = index.sortKey;
                }
                else {
                    throw new Error(`there is no sort key defined for index <${this.params.IndexName}>`);
                }
            }
            else {
                throw new Error(`the index <${this.params.IndexName}> does not exist on model ${this.modelClazz.name}`);
            }
        }
        else {
            sortKey = this.metadata.getSortKey();
        }
        if (!sortKey) {
            throw new Error('There was no sort key defined for current schema');
        }
        return request_expression_builder_1.addSortKeyCondition(sortKey, this, this.metadata);
    }
    ascending() {
        this.params.ScanIndexForward = true;
        return this;
    }
    descending() {
        this.params.ScanIndexForward = false;
        return this;
    }
    execNoMap() {
        this.logger.debug('request (noMap)', this.params);
        return this.dynamoRx.query(this.params).pipe(operators_1.tap(response => this.logger.debug('response', response)));
    }
    execFullResponse() {
        this.logger.debug('request', this.params);
        return this.dynamoRx.query(this.params).pipe(operators_1.tap(response => this.logger.debug('response', response)), operators_1.map(this.mapFromDb), operators_1.tap(response => this.logger.debug('mapped items', response.Items)));
    }
    exec() {
        this.logger.debug('request', this.params);
        return this.dynamoRx.query(this.params).pipe(operators_1.tap(response => this.logger.debug('response', response)), operators_1.map(this.mapFromDb), operators_1.map(r => r.Items), operators_1.tap(items => this.logger.debug('mapped items', items)));
    }
    execSingle() {
        const params = Object.assign({}, this.params, { Limit: 1 });
        this.logger.debug('single request', params);
        return this.dynamoRx.query(params)
            .pipe(operators_1.tap(response => this.logger.debug('response', response)), operators_1.map(this.mapFromDb), operators_1.map(r => r.Items && r.Items.length ? r.Items[0] : null), operators_1.tap(item => this.logger.debug('mapped item', item)));
    }
    execCount() {
        const params = Object.assign({}, this.params, { Select: 'COUNT' });
        this.logger.debug('count request', params);
        return this.dynamoRx.query(params).pipe(operators_1.tap(response => this.logger.debug('response', response)), operators_1.map(response => response.Count || 0), operators_1.tap(count => this.logger.debug('count', count)));
    }
}
exports.QueryRequest = QueryRequest;
//# sourceMappingURL=query.request.js.map