"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const sql_type_to_ts_type_1 = __importDefault(require("./lib/sql-type-to-ts-type"));
const mysql2_1 = require("mysql2");
const events_1 = require("events");
class Schema extends events_1.EventEmitter {
    constructor({ databaseName, databaseUri, logger }) {
        super();
        this.tables = [];
        this.logger = logger;
        if (!databaseUri) {
            return;
        }
        this.databaseName = databaseName;
        this.connection = mysql2_1.createConnection({ uri: databaseUri });
        this.start();
    }
    start() {
        this.logger.log('Started getting schema...');
        // do not block other plugin features while loading schema
        this.queryTables()
            .then(tables => {
            this.tables = tables;
            this.emit('schemaLoaded');
        })
            .catch(error => {
            if (error) {
                throw error;
            }
        });
    }
    async queryTables() {
        const results = await this.query(`SELECT table_name FROM information_schema.columns WHERE table_schema = '${this.databaseName}' GROUP BY table_name`);
        const names = results.map(result => result.table_name);
        const tables = names.map(async (name) => {
            return {
                name,
                columns: await this.queryColumns(name)
            };
        });
        return Promise.all(tables);
    }
    async queryColumns(name) {
        const columns = await this.query(`SELECT column_name, data_type, is_nullable
       FROM information_schema.columns
       WHERE table_name = '${name}' 
       AND table_schema = '${this.databaseName}'`);
        return columns.map(column => {
            return {
                name: column.column_name,
                tsType: sql_type_to_ts_type_1.default(column.data_type),
                sqlType: column.data_type,
                optional: column.is_nullable === 'YES'
            };
        });
    }
    query(sql) {
        return new Promise((resolve, reject) => {
            var _a;
            (_a = this.connection) === null || _a === void 0 ? void 0 : _a.query(sql, (error, results) => {
                if (error) {
                    return reject(error);
                }
                return resolve(results);
            });
        });
    }
    getTables() {
        return this.tables;
    }
}
exports.default = Schema;
//# sourceMappingURL=schema.js.map