"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MySqlService = void 0;
// 不依赖框架
var moment = require("moment");
var mysql2_1 = require("mysql2");
var fs = require("fs");
var path = require("path");
var uid_1 = require("uid");
var axios = require('axios');
var sqlite3 = require("sqlite3");
var pg_1 = require("pg");
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
function dbQueryList(hdb, sql) {
    // console.log('sql', sql)
    return new Promise(function (resolve, reject) {
        var list = [];
        hdb.all(sql, function (err, rows) {
            // console.log('row', err, rows)
            if (err) {
                return reject(err);
            }
            // console.log(row.id + ": " + row.info);
            // list.push(row)
            resolve(rows);
        });
        // const cb = ((st, err) => {
        //     // console.log('row', err, rows)
        //     if (err) {
        //         reject(err)
        //     }
        //     // console.log(row.id + ": " + row.info);
        //     // list.push(row)
        //     resolve(st)
        // }) as any
        // hdb.run(sql, [], cb)
        // resolve(list)
    });
}
function _createMssqlConnect(params) {
    var host = params.host, password = params.password, port = params.port, user = params.user, test = params.test;
    return new Promise(function (resolve, reject) {
        var config = {
            server: host,
            options: {
                database: 'MidDB',
                port: port,
                // trustServerCertificate: true,
                // encrypted: false,
                encrypt: false
            },
            authentication: {
                type: "default",
                options: {
                    userName: user,
                    password: password,
                }
            }
        };
        var connection = new Connection(config);
        // Setup event handler when the connection is established. 
        connection.on('connect', function (err) {
            if (err) {
                console.log('Error: ', err);
            }
            console.log('success');
            // If no error, then good to go...
            resolve(connection);
        });
        // Initialize the connection.
        connection.connect();
    });
}
function _mssqlExec(connection, sql) {
    return new Promise(function (resolve, reject) {
        var rows = [];
        var request = new Request(sql, function (err, rowCount) {
            if (err) {
                console.log(err);
                reject(err);
                return;
            }
            else {
                resolve(rows);
                return;
                // console.log(rowCount + ' rows');
            }
        });
        request.on('row', function (columns) {
            console.log('columns', columns);
            var obj = {};
            for (var _i = 0, columns_1 = columns; _i < columns_1.length; _i++) {
                var col = columns_1[_i];
                obj[col.metadata.colName] = col.value;
            }
            rows.push(obj);
            // columns [
            //     {
            //       value: 7,
            //       metadata: {
            //         userType: 0,
            //         flags: 8,
            //         type: [Object],
            //         collation: undefined,
            //         precision: undefined,
            //         scale: undefined,
            //         udtInfo: undefined,
            //         dataLength: undefined,
            //         schema: undefined,
            //         colName: 'FactoryId',
            //         tableName: undefined
            //       }
            //     },
            //     {
            //       value: 'bst',
            //       metadata: {
            //         userType: 0,
            //         flags: 8,
            //         type: [Object],
            //         collation: [Collation],
            //         precision: undefined,
            //         scale: undefined,
            //         udtInfo: undefined,
            //         dataLength: 40,
            //         schema: undefined,
            //         colName: 'FactoryName',
            //         tableName: undefined
            //       }
            //     },
            //   ]
            // columns.forEach(function (column) {
            //     console.log(column.value);
            // });
        });
        connection.execSql(request);
    });
}
function _mssqlExecArr(connection, sql) {
    return new Promise(function (resolve, reject) {
        var rows = [];
        var fields = [];
        var request = new Request(sql, function (err, rowCount) {
            if (err) {
                console.log(err);
                reject(err);
                return;
            }
            else {
                resolve({
                    results: rows,
                    fields: fields,
                });
                return;
                // console.log(rowCount + ' rows');
            }
        });
        request.on('row', function (columns) {
            console.log('columns', columns);
            if (rows.length == 0) {
                for (var _i = 0, columns_2 = columns; _i < columns_2.length; _i++) {
                    var col = columns_2[_i];
                    fields.push({
                        name: col.metadata.colName,
                    });
                }
            }
            var obj = [];
            for (var _a = 0, columns_3 = columns; _a < columns_3.length; _a++) {
                var col = columns_3[_a];
                obj.push(col.value);
            }
            rows.push(obj);
            // columns [
            //     {
            //       value: 7,
            //       metadata: {
            //         userType: 0,
            //         flags: 8,
            //         type: [Object],
            //         collation: undefined,
            //         precision: undefined,
            //         scale: undefined,
            //         udtInfo: undefined,
            //         dataLength: undefined,
            //         schema: undefined,
            //         colName: 'FactoryId',
            //         tableName: undefined
            //       }
            //     },
            //     {
            //       value: 'bst',
            //       metadata: {
            //         userType: 0,
            //         flags: 8,
            //         type: [Object],
            //         collation: [Collation],
            //         precision: undefined,
            //         scale: undefined,
            //         udtInfo: undefined,
            //         dataLength: 40,
            //         schema: undefined,
            //         colName: 'FactoryName',
            //         tableName: undefined
            //       }
            //     },
            //   ]
            // columns.forEach(function (column) {
            //     console.log(column.value);
            // });
        });
        connection.execSql(request);
    });
}
// const chalk = require('chalk')
// import('chalk').then(m => [
//     console.log('chalk', chalk)
// ])
// console.log(chalk.green('green'))
var ParamException = /** @class */ (function (_super) {
    __extends(ParamException, _super);
    function ParamException() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    return ParamException;
}(Error));
function hasValue(value) {
    return !!value || value === 0;
}
var g_connections = {};
var g_sqls = [];
var USER_HOME = process.env.HOME || process.env.USERPROFILE;
var yunserFolder = path.resolve(USER_HOME, '.yunser'); // TODO package，npm install cmd-core
if (!fs.existsSync(yunserFolder)) {
    // console.log('创建目录')
    fs.mkdirSync(yunserFolder);
}
var appFolder = path.resolve(yunserFolder, 'dms-cli'); // TODO package，npm install cmd-core
if (!fs.existsSync(appFolder)) {
    fs.mkdirSync(appFolder);
}
var sqlDbFilePath = path.resolve(appFolder, 'sqls.json');
if (!fs.existsSync(sqlDbFilePath)) {
    // console.log('创建目录')
    // fs.mkdirSync(yunserFolder)
    fs.writeFileSync(sqlDbFilePath, '', 'utf8');
}
var sqlContentText = fs.readFileSync(sqlDbFilePath, 'utf-8');
if (sqlContentText) {
    g_sqls = JSON.parse(sqlContentText);
}
var historyDbFilePath = path.resolve(appFolder, 'history.json');
if (!fs.existsSync(historyDbFilePath)) {
    // console.log('创建目录')
    // fs.mkdirSync(yunserFolder)
    fs.writeFileSync(historyDbFilePath, '', 'utf8');
}
var sshConnectionFilePath = path.resolve(appFolder, 'mysql.connection.json');
if (!fs.existsSync(sshConnectionFilePath)) {
    // console.log('创建目录')
    // fs.mkdirSync(yunserFolder)
    fs.writeFileSync(sshConnectionFilePath, '[]', 'utf8');
}
var g_hostories = [
// {
//     sql: '122',
// }
];
var historyContentText = fs.readFileSync(historyDbFilePath, 'utf-8');
if (historyContentText) {
    g_hostories = JSON.parse(historyContentText);
}
function saveSqlData() {
    fs.writeFileSync(sqlDbFilePath, JSON.stringify(g_sqls, null, 4), 'utf-8');
}
function saveHistorylData() {
    fs.writeFileSync(historyDbFilePath, JSON.stringify(g_hostories, null, 4), 'utf-8');
}
// query.error.code undefined
// query.error Error: Can't add new command when connection is in closed state
// query.error.code EADDRNOTAVAIL
// query.error Error: read EADDRNOTAVAIL
//     at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
//   errno: -49,
//   code: 'EADDRNOTAVAIL',
//   syscall: 'read',
//   fatal: true
// }
var MySqlService = /** @class */ (function () {
    function MySqlService() {
    }
    MySqlService.prototype.index = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/, 'mysql index'];
            });
        });
    };
    MySqlService.prototype._httpConnect = function (options, agentUrl) {
        return __awaiter(this, void 0, void 0, function () {
            var res;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, axios.post("".concat(agentUrl, "/mysql/connect"), options)];
                    case 1:
                        res = _a.sent();
                        console.log('res', res.data);
                        return [2 /*return*/, {
                                rawConnectionId: res.data.id,
                            }];
                }
            });
        });
    };
    MySqlService.prototype._mssqlConnect = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                // const { host, password, port, user, test } = params
                return [2 /*return*/, _createMssqlConnect(params)];
            });
        });
    };
    MySqlService.prototype._sqliteConnect = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var databasePath, password, port, user, test, hdb;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        databasePath = params.databasePath, password = params.password, port = params.port, user = params.user, test = params.test;
                        hdb = new sqlite3.Database(databasePath);
                        return [4 /*yield*/, dbQueryList(hdb, 'SELECT 1 + 1')];
                    case 1:
                        _a.sent();
                        return [2 /*return*/, hdb];
                }
            });
        });
    };
    MySqlService.prototype._postgresConnect = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var host, password, port, user, test, client;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        host = params.host, password = params.password, port = params.port, user = params.user, test = params.test;
                        client = new pg_1.Client({
                            user: user,
                            // database?: string | undefined;
                            password: password,
                            port: port,
                            host: host,
                            // keepAlive?: boolean | undefined;
                            // statement_timeout?: false | number | undefined;
                            // query_timeout?: number | undefined;
                        });
                        return [4 /*yield*/, client.connect()];
                    case 1:
                        _a.sent();
                        return [2 /*return*/, client];
                }
            });
        });
    };
    MySqlService.prototype._connect2 = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                // console.log('connect2', params)
                return [2 /*return*/, new Promise(function (resolve, reject) {
                        var connection = (0, mysql2_1.createConnection)(params);
                        connection.on('error', function (err) {
                            console.error('db on error', err);
                            // 这种错误还可以正常请求的，不清楚为什么
                            // db on error Error: read ETIMEDOUT
                            //     at TCP.onStreamRead (internal/stream_base_commons.js:209:20) {
                            // errno: -60,
                            // code: 'ETIMEDOUT',
                            // syscall: 'read',
                            // fatal: true
                            // }
                            // if(err.code === 'PROTOCOL_CONNECTION_LOST') {
                            //     logger.error('db error执行重连:'+err.message)
                            //     handleDisconnection()
                            // } else {
                            //     throw err
                            // }
                        });
                        connection.connect(function (err) {
                            if (err) {
                                console.error('error connecting: ' + err.stack);
                                reject(err);
                                return;
                            }
                            // console.log('nonnect ok', connection)
                            resolve(connection);
                        });
                    })];
            });
        });
    };
    MySqlService.prototype.connectionDatabases = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var connection, sql, id;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this._connect2(body)];
                    case 1:
                        connection = _a.sent();
                        sql = "SELECT * FROM `information_schema`.`SCHEMATA` LIMIT 20";
                        id = (0, uid_1.uid)(32);
                        g_connections[id] = {
                            id: id,
                            options: {},
                            connection: connection,
                            createTime: new Date().getTime(),
                            updateTime: new Date().getTime(),
                        };
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: id,
                            })];
                    case 2: return [2 /*return*/, _a.sent()];
                }
            });
        });
    };
    MySqlService.prototype.connectionCompareData = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var db1Data, db2Data, connections, getSchemaData;
            var _a;
            var _this = this;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        db1Data = body.db1Data, db2Data = body.db2Data;
                        return [4 /*yield*/, this.connectionList()];
                    case 1:
                        connections = (_b.sent()).list;
                        getSchemaData = function (dbData) { return __awaiter(_this, void 0, void 0, function () {
                            var connectionId, schemaName, _connection, connection, id, tableSql, tables, colSql, columns;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        connectionId = dbData.connectionId, schemaName = dbData.schemaName;
                                        _connection = connections.find(function (item) { return item.id == connectionId; });
                                        console.log('_connection', _connection);
                                        return [4 /*yield*/, this._connect2(_connection)];
                                    case 1:
                                        connection = _a.sent();
                                        id = (0, uid_1.uid)(32);
                                        g_connections[id] = {
                                            id: id,
                                            options: {},
                                            connection: connection,
                                            createTime: new Date().getTime(),
                                            updateTime: new Date().getTime(),
                                        };
                                        tableSql = "SELECT * FROM `information_schema`.`TABLES` where TABLE_SCHEMA = '".concat(schemaName, "' and TABLE_TYPE = 'BASE TABLE'");
                                        return [4 /*yield*/, this.query(tableSql, {
                                                connectionId: id,
                                            })];
                                    case 2:
                                        tables = _a.sent();
                                        colSql = "SELECT * FROM `information_schema`.`COLUMNS` where TABLE_SCHEMA = '".concat(schemaName, "'");
                                        return [4 /*yield*/, this.query(colSql, {
                                                connectionId: id,
                                            })];
                                    case 3:
                                        columns = _a.sent();
                                        return [2 /*return*/, {
                                                tables: tables,
                                                columns: columns,
                                            }];
                                }
                            });
                        }); };
                        _a = {};
                        return [4 /*yield*/, getSchemaData(db1Data)];
                    case 2:
                        _a.db1Result = _b.sent();
                        return [4 /*yield*/, getSchemaData(db2Data)];
                    case 3: return [2 /*return*/, (_a.db2Result = _b.sent(),
                            _a)];
                }
            });
        });
    };
    MySqlService.prototype.connect = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var test, _a, type, httpProxyUrl, options, httpAgent, agentUrl, connection, id;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        test = body.test, _a = body.type, type = _a === void 0 ? 'mysql' : _a, httpProxyUrl = body.httpProxyUrl, options = __rest(body, ["test", "type", "httpProxyUrl"]);
                        httpAgent = !!httpProxyUrl;
                        agentUrl = httpProxyUrl;
                        if (!(type == 'postgresql')) return [3 /*break*/, 2];
                        return [4 /*yield*/, this._postgresConnect(options)];
                    case 1:
                        connection = _b.sent();
                        return [3 /*break*/, 10];
                    case 2:
                        if (!(type == 'sqlite')) return [3 /*break*/, 4];
                        return [4 /*yield*/, this._sqliteConnect(options)];
                    case 3:
                        connection = _b.sent();
                        return [3 /*break*/, 10];
                    case 4:
                        if (!(type == 'mssql')) return [3 /*break*/, 6];
                        return [4 /*yield*/, this._mssqlConnect(options)];
                    case 5:
                        connection = _b.sent();
                        return [3 /*break*/, 10];
                    case 6:
                        if (!httpAgent) return [3 /*break*/, 8];
                        return [4 /*yield*/, this._httpConnect(options, agentUrl)];
                    case 7:
                        connection = _b.sent();
                        return [3 /*break*/, 10];
                    case 8: return [4 /*yield*/, this._connect2(options)];
                    case 9:
                        connection = _b.sent();
                        _b.label = 10;
                    case 10:
                        if (test) {
                            return [2 /*return*/, {}];
                        }
                        id = (0, uid_1.uid)(32);
                        g_connections[id] = {
                            type: type,
                            id: id,
                            httpAgent: httpAgent,
                            agentUrl: agentUrl,
                            options: options,
                            connection: connection,
                            createTime: new Date().getTime(),
                            updateTime: new Date().getTime(),
                        };
                        return [2 /*return*/, {
                                id: id,
                            }];
                }
            });
        });
    };
    MySqlService.prototype.reconnect = function (_a) {
        var connectionId = _a.connectionId;
        return __awaiter(this, void 0, void 0, function () {
            var options, connection;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!connectionId) {
                            throw new Error('No connection');
                        }
                        if (!g_connections[connectionId]) {
                            throw new Error('ConnectionId not exits');
                        }
                        options = g_connections[connectionId].options;
                        return [4 /*yield*/, this._connect2(options)];
                    case 1:
                        connection = _b.sent();
                        g_connections[connectionId].connection = connection;
                        g_connections[connectionId].updateTime = new Date().getTime();
                        return [2 /*return*/, {}];
                }
            });
        });
    };
    MySqlService.prototype.query = function (sql, _a) {
        var connectionId = _a.connectionId;
        return __awaiter(this, void 0, void 0, function () {
            var conn, client, res, hdb, result, res;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!g_connections[connectionId]) {
                            console.log('g_connections', g_connections);
                            throw new ParamException("ConnectionId ".concat(connectionId, " not exits"));
                        }
                        conn = g_connections[connectionId];
                        if (!(conn.type == 'postgresql')) return [3 /*break*/, 2];
                        client = conn.connection;
                        return [4 /*yield*/, client.query(sql, [])];
                    case 1:
                        res = _b.sent();
                        console.log('res', res);
                        console.log('res.rows', res.rows);
                        // console.log(res.rows[0].message) // Hello world!
                        return [2 /*return*/, res.rows];
                    case 2:
                        if (!(conn.type == 'sqlite')) return [3 /*break*/, 4];
                        hdb = conn.connection;
                        return [4 /*yield*/, dbQueryList(hdb, sql)
                            // console.log('res.rows', res.rows)
                            // console.log(res.rows[0].message) // Hello world!
                        ];
                    case 3:
                        result = _b.sent();
                        // console.log('res.rows', res.rows)
                        // console.log(res.rows[0].message) // Hello world!
                        return [2 /*return*/, result];
                    case 4:
                        if (!conn.httpAgent) return [3 /*break*/, 6];
                        return [4 /*yield*/, axios.post("".concat(conn.agentUrl, "/mysql/execSqlSimple"), {
                                connectionId: conn.connection.rawConnectionId,
                                sql: sql,
                            })
                            // console.log('res', res.data)
                        ];
                    case 5:
                        res = _b.sent();
                        // console.log('res', res.data)
                        return [2 /*return*/, res.data];
                    case 6: return [2 /*return*/, new Promise(function (resolve, reject) {
                            conn.connection.query({
                                sql: sql,
                                // rowsAsArray: true,
                            }, function (error, results, fields) {
                                if (error) {
                                    console.log('query.error.code', error.code);
                                    console.log('query.error', error);
                                    reject(error);
                                }
                                // console.log('results', results)
                                resolve(results);
                            });
                        })];
                }
            });
        });
    };
    MySqlService.prototype.queryArr = function (sql, _a) {
        var connectionId = _a.connectionId;
        return __awaiter(this, void 0, void 0, function () {
            var conn, client, res, connection, hdb, result, fields_1, results, item0, fieldName, res;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        conn = g_connections[connectionId];
                        if (!conn) {
                            throw new ParamException('ConnectionId not exits');
                        }
                        if (!(conn.type == 'postgresql')) return [3 /*break*/, 2];
                        client = conn.connection;
                        return [4 /*yield*/, client.query({
                                text: sql,
                                rowMode: 'array'
                            })];
                    case 1:
                        res = _b.sent();
                        return [2 /*return*/, {
                                results: res.rows,
                                fields: res.fields,
                            }];
                    case 2:
                        if (!(conn.type == 'mssql')) return [3 /*break*/, 4];
                        connection = conn.connection;
                        return [4 /*yield*/, _mssqlExecArr(connection, sql)];
                    case 3: return [2 /*return*/, _b.sent()];
                    case 4:
                        if (!(conn.type == 'sqlite')) return [3 /*break*/, 6];
                        hdb = conn.connection;
                        return [4 /*yield*/, dbQueryList(hdb, sql)];
                    case 5:
                        result = _b.sent();
                        console.log('result', result);
                        fields_1 = [];
                        results = [];
                        if (result && result.length) {
                            item0 = result[0];
                            for (fieldName in item0) {
                                fields_1.push({
                                    name: fieldName,
                                });
                            }
                            results = result.map(function (obj) {
                                var arr = [];
                                for (var _i = 0, fields_2 = fields_1; _i < fields_2.length; _i++) {
                                    var field = fields_2[_i];
                                    arr.push(obj[field.name]);
                                }
                                return arr;
                            });
                        }
                        return [2 /*return*/, {
                                results: results,
                                fields: fields_1,
                            }];
                    case 6:
                        if (!conn.httpAgent) return [3 /*break*/, 8];
                        return [4 /*yield*/, axios.post("".concat(conn.agentUrl, "/mysql/execSql"), {
                                connectionId: conn.connection.rawConnectionId,
                                sql: sql,
                            })
                            // console.log('res', res.data)
                        ];
                    case 7:
                        res = _b.sent();
                        // console.log('res', res.data)
                        return [2 /*return*/, res.data];
                    case 8: return [2 /*return*/, new Promise(function (resolve, reject) {
                            conn.connection.query({
                                sql: sql,
                                rowsAsArray: true,
                            }, function (error, results, fields, c) {
                                // console.log('query.c', c)
                                if (error) {
                                    console.log('query.error', error);
                                    reject(error);
                                }
                                // console.log('results', results)
                                resolve({ results: results, fields: fields });
                            });
                        })];
                }
            });
        });
    };
    MySqlService.prototype.databases = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var conn, sql, connection, sql_1, results, result;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        conn = g_connections[params.connectionId];
                        if (!(conn.type == 'sqlite')) return [3 /*break*/, 1];
                        return [2 /*return*/, [
                                {
                                    $_name: 'main',
                                }
                            ]];
                    case 1:
                        if (!(conn.type == 'mssql')) return [3 /*break*/, 3];
                        connection = conn.connection;
                        sql_1 = "SELECT Name from Master..SysDatabases ORDER BY Name";
                        return [4 /*yield*/, _mssqlExec(connection, sql_1)];
                    case 2:
                        results = _a.sent();
                        return [2 /*return*/, results.map(function (item) {
                                return __assign(__assign({}, item), { $_name: item.Name });
                            })];
                    case 3:
                        if (conn.type == 'postgresql') {
                            sql = 'select * from information_schema.schemata';
                            // throw new ParamException('postgres not support')
                        }
                        else {
                            sql = 'SELECT * FROM `information_schema`.`SCHEMATA`';
                        }
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: params.connectionId,
                            })];
                    case 4:
                        result = _a.sent();
                        return [2 /*return*/, result.map(function (item) {
                                return __assign(__assign({}, item), { $_name: item.SCHEMA_NAME || item.schema_name });
                            })];
                }
            });
        });
    };
    MySqlService.prototype.execSqlSimple = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        return [4 /*yield*/, this.query(params.sql, {
                                connectionId: params.connectionId,
                            })];
                    case 1: 
                    // const { dbName } = params
                    return [2 /*return*/, _a.sent()];
                }
            });
        });
    };
    MySqlService.prototype.schemas = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var conn, connection, dbName_1, sql, results;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        conn = g_connections[params.connectionId];
                        if (!(conn.type == 'mssql')) return [3 /*break*/, 2];
                        connection = conn.connection;
                        dbName_1 = params.dbName;
                        sql = "select * from sys.schemas";
                        return [4 /*yield*/, _mssqlExec(connection, sql)];
                    case 1:
                        results = _a.sent();
                        return [2 /*return*/, results.map(function (item) {
                                return __assign(__assign({}, item), { $_schema_db: dbName_1, $_schema_name: item.name });
                            })];
                    case 2: return [2 /*return*/];
                }
            });
        });
    };
    MySqlService.prototype.tables = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var schemaName, conn, hdb, sql_2, result, connection, dbName_2, sql_3, results_1, dbName, sql, results;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        schemaName = params.schemaName;
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        conn = g_connections[params.connectionId];
                        if (!(conn.type == 'sqlite')) return [3 /*break*/, 2];
                        hdb = conn.connection;
                        sql_2 = "SELECT * from sqlite_master WHERE type = 'table'";
                        return [4 /*yield*/, dbQueryList(hdb, sql_2)
                            // console.log('res.rows', res.rows)
                            // console.log(res.rows[0].message) // Hello world!
                        ];
                    case 1:
                        result = _a.sent();
                        // console.log('res.rows', res.rows)
                        // console.log(res.rows[0].message) // Hello world!
                        return [2 /*return*/, result.map(function (item) {
                                return {
                                    $table_schema: 'main',
                                    $_table_name: item.name,
                                };
                            })];
                    case 2:
                        if (!(conn.type == 'mssql')) return [3 /*break*/, 4];
                        connection = conn.connection;
                        dbName_2 = params.dbName;
                        sql_3 = "SELECT Name from ".concat(dbName_2, "..SysObjects Where XType='U' ORDER BY Name");
                        return [4 /*yield*/, _mssqlExec(connection, sql_3)];
                    case 3:
                        results_1 = _a.sent();
                        return [2 /*return*/, results_1.map(function (item) {
                                return __assign(__assign({}, item), { $table_schema: dbName_2, $_table_name: item.Name, $__schemaName: schemaName });
                            })];
                    case 4:
                        dbName = params.dbName;
                        sql = "SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA = '".concat(dbName, "'");
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: params.connectionId,
                            })];
                    case 5:
                        results = _a.sent();
                        return [2 /*return*/, results.map(function (item) {
                                return __assign(__assign({}, item), { $table_schema: item.TABLE_SCHEMA || item.table_schema, $_table_name: item.TABLE_NAME || item.table_name });
                            })];
                }
            });
        });
    };
    // async tableNames() {
    //     const { ctx } = this
    //     const { name } = ctx.params
    //     let sql = `SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA = '${name}'`
    //     ctx.body = (await this.query(sql)).map(item => item.TABLE_NAME)
    // }
    MySqlService.prototype.tableDetailOld = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var dbName, tableName, sql;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        dbName = params.dbName, tableName = params.tableName;
                        sql = "describe ".concat(dbName, ".").concat(tableName, ";");
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: params.connectionId,
                            })];
                    case 1: return [2 /*return*/, _a.sent()];
                }
            });
        });
    };
    MySqlService.prototype.historyList = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var _a, page, _b, pageSize, keyword, list;
            return __generator(this, function (_c) {
                _a = body.page, page = _a === void 0 ? 1 : _a, _b = body.pageSize, pageSize = _b === void 0 ? 10 : _b, keyword = body.keyword;
                list = g_hostories;
                if (keyword) {
                    // list = g_sqls.filter(item => item.name.toLowerCase().includes(keyword.toLowerCase()))
                }
                return [2 /*return*/, {
                        total: list.length,
                        list: list.slice((page - 1) * pageSize, page * pageSize),
                    }];
            });
        });
    };
    MySqlService.prototype.historyClear = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                g_hostories = [];
                saveHistorylData();
                return [2 /*return*/];
            });
        });
    };
    MySqlService.prototype.sqlList = function (body) {
        if (body === void 0) { body = {}; }
        return __awaiter(this, void 0, void 0, function () {
            var _a, page, _b, pageSize, keyword, list;
            return __generator(this, function (_c) {
                _a = body.page, page = _a === void 0 ? 1 : _a, _b = body.pageSize, pageSize = _b === void 0 ? 10 : _b, keyword = body.keyword;
                list = g_sqls;
                if (keyword) {
                    list = g_sqls.filter(function (item) { return item.name.toLowerCase().includes(keyword.toLowerCase()); });
                }
                return [2 /*return*/, {
                        total: list.length,
                        list: list.slice((page - 1) * pageSize, page * pageSize),
                    }];
            });
        });
    };
    MySqlService.prototype.sqlCreate = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                g_sqls.unshift(__assign(__assign({}, body), { id: (0, uid_1.uid)(32) }));
                saveSqlData();
                return [2 /*return*/];
            });
        });
    };
    MySqlService.prototype.sqlRemove = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var idx;
            return __generator(this, function (_a) {
                idx = g_sqls.findIndex(function (item) { return item.id == body.id; });
                if (idx != -1) {
                    g_sqls.splice(idx, 1);
                }
                saveSqlData();
                return [2 /*return*/];
            });
        });
    };
    MySqlService.prototype.tableDetail = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var dbName, tableName, indexSql, tables;
            var _a;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        dbName = params.dbName, tableName = params.tableName;
                        indexSql = "SELECT *\nFROM information_schema.STATISTICS\nWHERE TABLE_SCHEMA = '".concat(dbName, "'\n\tand TABLE_NAME = '").concat(tableName, "'");
                        return [4 /*yield*/, this.query("SELECT * FROM information_schema.tables \nWHERE TABLE_SCHEMA = '".concat(dbName, "'\nAND TABLE_NAME = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 1:
                        tables = _b.sent();
                        _a = {
                            table: tables[0]
                        };
                        return [4 /*yield*/, this.query("SELECT *\nFROM information_schema.COLUMNS\nWHERE TABLE_SCHEMA = '".concat(dbName, "'\n\tand TABLE_NAME = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 2:
                        _a.columns = _b.sent();
                        return [4 /*yield*/, this.query(indexSql, {
                                connectionId: params.connectionId,
                            })];
                    case 3:
                        _a.indexes = _b.sent();
                        return [4 /*yield*/, this.query("SELECT *\nFROM information_schema.PARTITIONS\nWHERE TABLE_SCHEMA = '".concat(dbName, "'\n\tand TABLE_NAME = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 4:
                        _a.partitions = _b.sent();
                        return [4 /*yield*/, this.query("SELECT *\nFROM information_schema.TRIGGERS\nWHERE EVENT_OBJECT_SCHEMA = '".concat(dbName, "'\n    and EVENT_OBJECT_TABLE = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 5: return [2 /*return*/, (_a.triggers = _b.sent(),
                            _a)];
                }
            });
        });
    };
    MySqlService.prototype.execSql = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var sql, tableName, dbName, _a, logger, results, fields, time, startTime, ret_1, err_1, newResults, result, rows, ret, _b, err_2;
            return __generator(this, function (_c) {
                switch (_c.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        sql = params.sql, tableName = params.tableName, dbName = params.dbName, _a = params.logger, logger = _a === void 0 ? false : _a;
                        time = null;
                        _c.label = 1;
                    case 1:
                        _c.trys.push([1, 3, , 4]);
                        startTime = new Date();
                        return [4 /*yield*/, this.queryArr(sql, {
                                connectionId: params.connectionId,
                            })];
                    case 2:
                        ret_1 = _c.sent();
                        time = new Date().getTime() - startTime.getTime();
                        results = ret_1.results;
                        fields = ret_1.fields;
                        return [3 /*break*/, 4];
                    case 3:
                        err_1 = _c.sent();
                        if (logger) {
                            g_hostories.unshift({
                                id: (0, uid_1.uid)(32),
                                sql: sql,
                                schema: dbName,
                                time: new Date().toISOString(),
                                status: 'fail',
                                rows: 0,
                                execTime: time,
                                message: err_1.message || 'Unknown Error',
                            });
                            saveHistorylData();
                        }
                        throw new Error(err_1.message);
                    case 4:
                        newResults = [];
                        result = null;
                        rows = null;
                        if (Array.isArray(results)) {
                            rows = results.length;
                            newResults = results.map(function (row) {
                                return row.map(function (cell) {
                                    if (typeof cell == 'string' || typeof cell == 'number' || cell == null) {
                                        return cell;
                                        // console.log('is-string')
                                    }
                                    else if (cell instanceof Date) {
                                        return moment(cell).format('YYYY-MM-DD HH:mm:ss');
                                        // console.log('is-string')
                                    }
                                    else if (typeof cell == 'object') {
                                        return JSON.stringify(cell);
                                    }
                                    else {
                                        // console.log('not-string')
                                        console.warn('typeof cell', typeof cell);
                                        // else if (typeof key == 'object') {
                                        return JSON.stringify(cell);
                                    }
                                });
                                // const newObj: any = {}
                                // for (let key of item) {
                                //     // console.log('key', key)
                                // }
                                // // console.log('newObj', newObj)
                                // return newObj
                            });
                        }
                        else {
                            // changedRows 返回更新了多少行(表中有几条数据中的字段值发生变化)
                            // affectedRows返回知足where条件影响的行
                            if (results && hasValue(results.changedRows)) {
                                rows = results.changedRows;
                            }
                            fields = [];
                            result = results;
                        }
                        ret = {
                            result: result,
                            results: newResults,
                            fields: fields,
                            time: time,
                            columns: [],
                        };
                        if (!(dbName && tableName)) return [3 /*break*/, 8];
                        _c.label = 5;
                    case 5:
                        _c.trys.push([5, 7, , 8]);
                        _b = ret;
                        return [4 /*yield*/, this.query("SELECT *\n    FROM information_schema.COLUMNS\n    WHERE TABLE_SCHEMA = '".concat(dbName, "'\n        and TABLE_NAME = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 6:
                        _b.columns = _c.sent();
                        return [3 /*break*/, 8];
                    case 7:
                        err_2 = _c.sent();
                        console.error(err_2);
                        return [3 /*break*/, 8];
                    case 8:
                        if (logger) {
                            g_hostories.unshift({
                                id: (0, uid_1.uid)(32),
                                sql: sql,
                                schema: dbName,
                                time: new Date().toISOString(),
                                status: 'success',
                                rows: rows,
                                execTime: time,
                                message: '',
                            });
                            saveHistorylData();
                        }
                        return [2 /*return*/, ret];
                }
            });
        });
    };
    MySqlService.prototype.users = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                return [2 /*return*/];
            });
        });
    };
    MySqlService.prototype.connectionList = function (body) {
        if (body === void 0) { body = {}; }
        return __awaiter(this, void 0, void 0, function () {
            var content;
            return __generator(this, function (_a) {
                content = fs.readFileSync(sshConnectionFilePath, 'utf-8');
                return [2 /*return*/, {
                        list: JSON.parse(content)
                    }];
            });
        });
    };
    MySqlService.prototype.connectionEdit = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var id, data, content, list, idx;
            return __generator(this, function (_a) {
                id = body.id, data = body.data;
                content = fs.readFileSync(sshConnectionFilePath, 'utf-8');
                list = JSON.parse(content);
                idx = list.findIndex(function (_item) { return _item.id == id; });
                list[idx] = __assign(__assign({}, list[idx]), data);
                console.log('list', list);
                fs.writeFileSync(sshConnectionFilePath, JSON.stringify(list, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    MySqlService.prototype.connectionCreate = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var content, list;
            return __generator(this, function (_a) {
                content = fs.readFileSync(sshConnectionFilePath, 'utf-8');
                list = JSON.parse(content);
                list.unshift(__assign(__assign({}, body), { id: (0, uid_1.uid)(32) }));
                fs.writeFileSync(sshConnectionFilePath, JSON.stringify(list, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    MySqlService.prototype.connectionDelete = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var id, content, list, newList;
            return __generator(this, function (_a) {
                id = body.id;
                content = fs.readFileSync(sshConnectionFilePath, 'utf-8');
                list = JSON.parse(content);
                newList = list.filter(function (item) { return item.id != id; });
                console.log('id', id);
                console.log('newList', newList);
                fs.writeFileSync(sshConnectionFilePath, JSON.stringify(newList, null, 4), 'utf-8');
                return [2 /*return*/, {}];
            });
        });
    };
    MySqlService.prototype.compare = function (body) {
        return __awaiter(this, void 0, void 0, function () {
            var content;
            return __generator(this, function (_a) {
                content = fs.readFileSync('/Users/yunser/app/dms-projects/dms-cli/_mysql_compare.json', 'utf-8');
                return [2 /*return*/, JSON.parse(content)];
            });
        });
    };
    return MySqlService;
}());
exports.MySqlService = MySqlService;
//# sourceMappingURL=mysql.service.js.map