"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 (g && (g = 0, op[0] && (_ = 0)), _) 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 ssh_service_1 = require("./ssh.service");
// import * as alasql from 'alasql'
var nodePath = path;
var alasql = require('alasql');
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var g_taskMap = {};
function sleep(ms) {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(null);
        }, ms);
    });
}
function getValue(value) {
    if (typeof value == 'number') {
        return "".concat(value);
    }
    if (value === null) {
        return "NULL";
    }
    if (value instanceof Date) {
        return "'".concat(moment(value).format('YYYY-MM-DD HH:mm:ss'), "'");
    }
    return "'".concat(value.replace(/\n/g, '\\n').replace(/'/g, '\\\''), "'");
}
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 = {
    alasql: {
        type: 'alasql',
    }
};
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 jsonDBPath = path.resolve(appFolder, 'jsondb.json');
if (!fs.existsSync(jsonDBPath)) {
    // console.log('创建目录')
    // fs.mkdirSync(yunserFolder)
    fs.writeFileSync(jsonDBPath, '[]', '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, httpProxyToken) {
        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, {
                            headers: {
                                'Authorization': httpProxyToken || '',
                            }
                        })];
                    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._alasqlConnect = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var _a, tables, dataId, _i, tables_1, table, tableName;
            return __generator(this, function (_b) {
                _a = params.tables, tables = _a === void 0 ? [] : _a;
                dataId = moment().format('HHmmss');
                // const tableName = `t${dataId}`
                for (_i = 0, tables_1 = tables; _i < tables_1.length; _i++) {
                    table = tables_1[_i];
                    tableName = table.name;
                    alasql("CREATE TABLE IF NOT EXISTS `".concat(tableName, "`"));
                    alasql.tables[tableName].data = table.rows || [];
                }
                return [2 /*return*/, {
                        dataId: dataId,
                    }];
            });
        });
    };
    MySqlService.prototype._jsondbConnect = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var _a;
            return __generator(this, function (_b) {
                _a = params;
                // const dataId = uid(8)
                // const dataId = moment().format('HHmmss')
                // const tableName = `t${dataId}`
                // for (let table of tables) {
                //     const tableName = table.name
                //     alasql(`CREATE TABLE IF NOT EXISTS \`${tableName}\``)
                //     alasql.tables[tableName].data = table.rows || []
                // }
                return [2 /*return*/, {
                        isJsonDb: true,
                        // dataId,
                    }];
            });
        });
    };
    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._mysqlConnect = function (params, connectionId) {
        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)(__assign(__assign({}, params), { supportBigNumbers: true, bigNumberStrings: true }));
                        connection.on('error', function (err) {
                            console.error('db/on/error', err);
                            console.error('err.code', err.code);
                            // PROTOCOL_CONNECTION_LOST
                            console.error('connectionId', connectionId);
                            (0, ssh_service_1.closeWebSocketByDbConnectionId)(connectionId);
                            // 这种错误还可以正常请求的，不清楚为什么
                            // 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 connectionId, sql;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.connect(body)];
                    case 1:
                        connectionId = (_a.sent()).connectionId;
                        sql = "SELECT * FROM `information_schema`.`SCHEMATA` LIMIT 20";
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: connectionId,
                            })];
                    case 2: 
                    // let id = uid(32)
                    // g_connections[id] = {
                    //     id,
                    //     options: {},
                    //     connection,
                    //     createTime: new Date().getTime(),
                    //     updateTime: new Date().getTime(),
                    // }
                    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, connectionId, 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.connect(_connection)];
                                    case 1:
                                        connectionId = (_a.sent()).connectionId;
                                        tableSql = "SELECT * FROM `information_schema`.`TABLES` where TABLE_SCHEMA = '".concat(schemaName, "' and TABLE_TYPE = 'BASE TABLE'");
                                        return [4 /*yield*/, this.query(tableSql, {
                                                connectionId: connectionId,
                                            })];
                                    case 2:
                                        tables = _a.sent();
                                        colSql = "SELECT * FROM `information_schema`.`COLUMNS` where TABLE_SCHEMA = '".concat(schemaName, "'");
                                        return [4 /*yield*/, this.query(colSql, {
                                                connectionId: connectionId,
                                            })];
                                    case 3:
                                        columns = _a.sent();
                                        return [2 /*return*/, {
                                                tables: tables,
                                                columns: columns,
                                                ignoreTables: _connection.ignoreTables || [],
                                                connectionName: _connection.name,
                                                _connectionId: connectionId,
                                            }];
                                }
                            });
                        }); };
                        _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, httpProxyToken, options, httpAgent, agentUrl, connection, connectionId;
            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, httpProxyToken = body.httpProxyToken, options = __rest(body, ["test", "type", "httpProxyUrl", "httpProxyToken"]);
                        httpAgent = !!httpProxyUrl;
                        agentUrl = httpProxyUrl;
                        connectionId = (0, uid_1.uid)(32);
                        if (!(type == 'postgresql')) return [3 /*break*/, 2];
                        return [4 /*yield*/, this._postgresConnect(options)];
                    case 1:
                        connection = _b.sent();
                        return [3 /*break*/, 14];
                    case 2:
                        if (!(type == 'alasql')) return [3 /*break*/, 4];
                        return [4 /*yield*/, this._alasqlConnect(options)];
                    case 3:
                        connection = _b.sent();
                        return [3 /*break*/, 14];
                    case 4:
                        if (!(type == 'jsondb')) return [3 /*break*/, 6];
                        return [4 /*yield*/, this._jsondbConnect(options)];
                    case 5:
                        connection = _b.sent();
                        return [3 /*break*/, 14];
                    case 6:
                        if (!(type == 'sqlite')) return [3 /*break*/, 8];
                        return [4 /*yield*/, this._sqliteConnect(options)];
                    case 7:
                        connection = _b.sent();
                        return [3 /*break*/, 14];
                    case 8:
                        if (!(type == 'mssql')) return [3 /*break*/, 10];
                        return [4 /*yield*/, this._mssqlConnect(options)];
                    case 9:
                        connection = _b.sent();
                        return [3 /*break*/, 14];
                    case 10:
                        if (!httpAgent) return [3 /*break*/, 12];
                        return [4 /*yield*/, this._httpConnect(options, agentUrl, httpProxyToken)];
                    case 11:
                        connection = _b.sent();
                        return [3 /*break*/, 14];
                    case 12: return [4 /*yield*/, this._mysqlConnect(options, connectionId)];
                    case 13:
                        connection = _b.sent();
                        _b.label = 14;
                    case 14:
                        if (test) {
                            return [2 /*return*/, {}];
                        }
                        g_connections[connectionId] = {
                            type: type,
                            connectionId: connectionId,
                            httpAgent: httpAgent,
                            agentUrl: agentUrl,
                            httpProxyToken: httpProxyToken,
                            options: options,
                            connection: connection,
                            createTime: new Date().getTime(),
                            updateTime: new Date().getTime(),
                        };
                        return [2 /*return*/, {
                                connectionId: connectionId,
                            }];
                }
            });
        });
    };
    MySqlService.prototype.reconnect = function (_a) {
        var connectionId = _a.connectionId;
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_b) {
                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, result, fields_2, 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();
                        console.log('pg/res', res);
                        // fields
                        // [
                        //     {
                        //         name: 'id',
                        //         tableID: 16397,
                        //         columnID: 1,
                        //         dataTypeID: 1043,
                        //         dataTypeSize: -1,
                        //         dataTypeModifier: 36,
                        //         format: 'text'
                        //     }
                        // ]
                        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_3 = fields_1; _i < fields_3.length; _i++) {
                                    var field = fields_3[_i];
                                    arr.push(obj[field.name]);
                                }
                                return arr;
                            });
                        }
                        return [2 /*return*/, {
                                results: results,
                                fields: fields_1,
                            }];
                    case 6:
                        if (conn.type == 'alasql') {
                            result = alasql(sql);
                            console.log('alasql/result', result);
                            fields_2 = [];
                            results = [];
                            if (result && result.length) {
                                item0 = result[0];
                                for (fieldName in item0) {
                                    fields_2.push({
                                        name: fieldName,
                                    });
                                }
                                results = result.map(function (obj) {
                                    var arr = [];
                                    for (var _i = 0, fields_4 = fields_2; _i < fields_4.length; _i++) {
                                        var field = fields_4[_i];
                                        arr.push(obj[field.name]);
                                    }
                                    return arr;
                                });
                            }
                            return [2 /*return*/, {
                                    results: results,
                                    fields: fields_2,
                                }];
                        }
                        _b.label = 7;
                    case 7:
                        if (!conn.httpAgent) return [3 /*break*/, 9];
                        return [4 /*yield*/, axios.post("".concat(conn.agentUrl, "/mysql/execSql"), {
                                connectionId: conn.connection.rawConnectionId,
                                sql: sql,
                            })
                            // console.log('res', res.data)
                        ];
                    case 8:
                        res = _b.sent();
                        // console.log('res', res.data)
                        return [2 /*return*/, res.data];
                    case 9: 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, res, content, list, 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 == 'alasql')) return [3 /*break*/, 2];
                        res = alasql("show databases");
                        // res:
                        // [ { databaseid: 'alasql' }, { databaseid: 'dbo' } ]
                        return [2 /*return*/, res.map(function (item) {
                                return {
                                    $_name: item.databaseid,
                                };
                            })];
                    case 2:
                        if (!(conn.type == 'jsondb')) return [3 /*break*/, 3];
                        content = fs.readFileSync(jsonDBPath, 'utf-8');
                        list = JSON.parse(content);
                        return [2 /*return*/, list.map(function (item) {
                                return {
                                    $_name: item.name,
                                };
                            })];
                    case 3:
                        if (!(conn.type == 'mssql')) return [3 /*break*/, 5];
                        connection = conn.connection;
                        sql_1 = "SELECT Name from Master..SysDatabases ORDER BY Name";
                        return [4 /*yield*/, _mssqlExec(connection, sql_1)];
                    case 4:
                        results = _a.sent();
                        return [2 /*return*/, results.map(function (item) {
                                return __assign(__assign({}, item), { $_name: item.Name });
                            })];
                    case 5:
                        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 6:
                        result = _a.sent();
                        return [2 /*return*/, result.map(function (item) {
                                return __assign(__assign({}, item), { $_name: item.SCHEMA_NAME || item.schema_name });
                            })];
                }
            });
        });
    };
    MySqlService.prototype.taskDetail = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var id;
            return __generator(this, function (_a) {
                id = params.id;
                return [2 /*return*/, {
                        task: g_taskMap[id] || null,
                    }];
            });
        });
    };
    MySqlService.prototype.createFunction = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var sql;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        sql = params.sql;
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: params.connectionId,
                            })];
                    case 1:
                        _a.sent();
                        return [2 /*return*/, {}];
                }
            });
        });
    };
    MySqlService.prototype.runSqls = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var sqls, taskId;
            return __generator(this, function (_a) {
                if (!params.connectionId) {
                    throw new ParamException('Need connectionId');
                }
                sqls = params.sqls;
                taskId = (0, uid_1.uid)(32);
                g_taskMap[taskId] = {
                    total: sqls.length,
                    current: 0,
                    status: 'ing',
                    id: taskId,
                };
                this._runSqls({
                    connectionId: params.connectionId,
                    taskId: taskId,
                    sqls: sqls,
                });
                return [2 /*return*/, {
                        taskId: taskId,
                    }];
            });
        });
    };
    MySqlService.prototype._runSqls = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var connectionId, _a, sqls, taskId, task, isError, error, errorSql, idx, sql, err_1;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        connectionId = params.connectionId, _a = params.sqls, sqls = _a === void 0 ? [] : _a, taskId = params.taskId;
                        task = g_taskMap[taskId];
                        isError = false;
                        idx = 0;
                        _b.label = 1;
                    case 1:
                        if (!(idx < sqls.length)) return [3 /*break*/, 6];
                        task.current = idx;
                        sql = sqls[idx];
                        _b.label = 2;
                    case 2:
                        _b.trys.push([2, 4, , 5]);
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: connectionId,
                            })];
                    case 3:
                        _b.sent();
                        return [3 /*break*/, 5];
                    case 4:
                        err_1 = _b.sent();
                        console.error('err', err_1);
                        isError = true;
                        error = err_1.toString();
                        errorSql = sql;
                        return [3 /*break*/, 5];
                    case 5:
                        idx++;
                        return [3 /*break*/, 1];
                    case 6:
                        if (isError) {
                            task.status = 'fail';
                            task.error = error;
                            task.sql = errorSql;
                        }
                        else {
                            task.current = sqls.length - 1;
                            task.status = 'success';
                        }
                        console.log('_runSqls/finish');
                        return [2 /*return*/];
                }
            });
        });
    };
    MySqlService.prototype.exportDataDownload = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var taskId, task;
            return __generator(this, function (_a) {
                taskId = params.taskId;
                task = g_taskMap[taskId];
                return [2 /*return*/, fs.readFileSync(task.path)];
            });
        });
    };
    MySqlService.prototype.exportTableData = function (params) {
        return __awaiter(this, void 0, void 0, function () {
            var dbName, tableName, _a, pageSize, sql, countResult, total, taskId;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        dbName = params.dbName, tableName = params.tableName, _a = params.pageSize, pageSize = _a === void 0 ? 1000 : _a;
                        sql = "SELECT COUNT(*) FROM `".concat(dbName, "`.`").concat(tableName, "`");
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: params.connectionId,
                            })];
                    case 1:
                        countResult = _b.sent();
                        total = countResult[0]['COUNT(*)'];
                        taskId = (0, uid_1.uid)(32);
                        g_taskMap[taskId] = {
                            total: total,
                            current: 0,
                            status: 'ing',
                            id: taskId,
                            hasFile: true,
                        };
                        this._exportData({
                            connectionId: params.connectionId,
                            dbName: dbName,
                            tableName: tableName,
                            total: total,
                            taskId: taskId,
                            pageSize: pageSize,
                        });
                        return [2 /*return*/, {
                                taskId: taskId,
                            }];
                }
            });
        });
    };
    MySqlService.prototype._exportData = function (_a) {
        var connectionId = _a.connectionId, dbName = _a.dbName, tableName = _a.tableName, total = _a.total, taskId = _a.taskId, _b = _a.pageSize, pageSize = _b === void 0 ? 1000 : _b;
        return __awaiter(this, void 0, void 0, function () {
            var totalPage, task, colSql, columns, exportSqls, page, offset, dataSql, dataList, _i, dataList_1, data, fields, values, _c, columns_4, column, fields_sql, values_sql, exportSql, allSql, tmpPath;
            return __generator(this, function (_d) {
                switch (_d.label) {
                    case 0:
                        totalPage = Math.ceil(total / pageSize);
                        task = g_taskMap[taskId];
                        colSql = "select * from `information_schema`.`COLUMNS` where TABLE_SCHEMA = '".concat(dbName, "' AND TABLE_NAME = '").concat(tableName, "' ORDER BY ORDINAL_POSITION ASC");
                        return [4 /*yield*/, this.query(colSql, {
                                connectionId: connectionId,
                            })];
                    case 1:
                        columns = _d.sent();
                        exportSqls = [];
                        page = 0;
                        _d.label = 2;
                    case 2:
                        if (!(page < totalPage)) return [3 /*break*/, 5];
                        offset = page * pageSize;
                        dataSql = "SELECT * FROM `".concat(dbName, "`.`").concat(tableName, "` LIMIT ").concat(pageSize, " OFFSET ").concat(offset);
                        return [4 /*yield*/, this.query(dataSql, {
                                connectionId: connectionId,
                            })];
                    case 3:
                        dataList = _d.sent();
                        for (_i = 0, dataList_1 = dataList; _i < dataList_1.length; _i++) {
                            data = dataList_1[_i];
                            fields = [];
                            values = [];
                            for (_c = 0, columns_4 = columns; _c < columns_4.length; _c++) {
                                column = columns_4[_c];
                                fields.push(column.COLUMN_NAME);
                                values.push(data[column.COLUMN_NAME]);
                            }
                            fields_sql = fields.map(function (field) { return "`".concat(field, "`"); }).join(', ');
                            values_sql = values.map(function (value) { return getValue(value); }).join(', ');
                            exportSql = "INSERT INTO `".concat(dbName, "`.`").concat(tableName, "` (").concat(fields_sql, ") VALUES (").concat(values_sql, ");");
                            exportSqls.push(exportSql);
                        }
                        if (task) {
                            task.current += pageSize;
                        }
                        _d.label = 4;
                    case 4:
                        page++;
                        return [3 /*break*/, 2];
                    case 5:
                        allSql = exportSqls.join('\n') + '\n';
                        tmpPath = nodePath.join(appFolder, 'tmp.sql');
                        fs.writeFileSync(tmpPath, allSql, 'utf-8');
                        if (task) {
                            task.current = total - 1;
                            task.status = 'success';
                            task.path = tmpPath;
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    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 dbName, schemaName, conn, hdb, sql_2, result, res, content, list, db_1, connection, dbName_2, sql_3, results_1, sql, results;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        dbName = params.dbName, 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 == 'alasql')) return [3 /*break*/, 3];
                        res = alasql("show tables from ".concat(dbName));
                        // res:
                        // [ { tableid: 't2c477ea3' } ]
                        return [2 /*return*/, res.map(function (item) {
                                return {
                                    $table_schema: dbName,
                                    $_table_name: item.tableid,
                                };
                            })];
                    case 3:
                        if (!(conn.type == 'jsondb')) return [3 /*break*/, 4];
                        content = fs.readFileSync(jsonDBPath, 'utf-8');
                        list = JSON.parse(content);
                        db_1 = list.find(function (item) { return item.name == dbName; });
                        return [2 /*return*/, db_1.tables.map(function (item) {
                                return {
                                    $table_schema: db_1.name,
                                    $_table_name: item.name,
                                };
                            })];
                    case 4:
                        if (!(conn.type == 'mssql')) return [3 /*break*/, 6];
                        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 5:
                        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 6:
                        sql = "SELECT * FROM information_schema.tables WHERE TABLE_SCHEMA = '".concat(dbName, "'");
                        return [4 /*yield*/, this.query(sql, {
                                connectionId: params.connectionId,
                            })];
                    case 7:
                        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, conn, tableSql, table, tables, tables, result, cols, indexes, indexSql, columns, _a, _b, indexSql, _c, _d, _e;
            var _f, _g;
            return __generator(this, function (_h) {
                switch (_h.label) {
                    case 0:
                        if (!params.connectionId) {
                            throw new ParamException('Need connectionId');
                        }
                        dbName = params.dbName, tableName = params.tableName;
                        conn = g_connections[params.connectionId];
                        if (!(conn.type == 'sqlite')) return [3 /*break*/, 2];
                        tableSql = "SELECT * from sqlite_master\nWHERE type = 'table'\nAND name='".concat(tableName, "'\n");
                        return [4 /*yield*/, this.query(tableSql, {
                                connectionId: params.connectionId,
                            })];
                    case 1:
                        tables = _h.sent();
                        table = __assign({ TABLE_NAME: tables[0].name }, tables[0]);
                        return [3 /*break*/, 4];
                    case 2:
                        tableSql = "SELECT * FROM information_schema.tables \nWHERE TABLE_SCHEMA = '".concat(dbName, "'\nAND TABLE_NAME = '").concat(tableName, "'");
                        return [4 /*yield*/, this.query(tableSql, {
                                connectionId: params.connectionId,
                            })];
                    case 3:
                        tables = _h.sent();
                        table = tables[0];
                        _h.label = 4;
                    case 4:
                        result = {
                            table: table,
                            columns: [],
                            indexes: [],
                            partitions: [],
                            triggers: [],
                        };
                        if (!(conn.type == 'sqlite')) return [3 /*break*/, 7];
                        return [4 /*yield*/, this.query("PRAGMA table_info(".concat(tableName, ")"), {
                                connectionId: params.connectionId,
                            })
                            // [
                            //     "cid": 0,
                            //     "name": "id",
                            //     "type": "TEXT",
                            //     "notnull": 1,
                            //     "dflt_value": null,
                            //     "pk": 1
                            // ]
                        ];
                    case 5:
                        cols = _h.sent();
                        // [
                        //     "cid": 0,
                        //     "name": "id",
                        //     "type": "TEXT",
                        //     "notnull": 1,
                        //     "dflt_value": null,
                        //     "pk": 1
                        // ]
                        result.columns = cols.map(function (item) {
                            return {
                                // CHARACTER_MAXIMUM_LENGTH
                                // CHARACTER_OCTET_LENGTH
                                // CHARACTER_SET_NAME
                                // COLLATION_NAME
                                COLUMN_KEY: item.pk == 1 ? 'PRI' : 'NOT_PRI',
                                COLUMN_NAME: item.name,
                                COLUMN_TYPE: item.type,
                                COLUMN_COMMENT: '',
                                COLUMN_DEFAULT: item.dflt_value,
                                IS_NULLABLE: item.notnull == 1 ? 'NO' : 'YES',
                                'x-raw': item,
                                // DATA_TYPE
                                // DATETIME_PRECISION
                                // EXTRA
                                // GENERATION_EXPRESSION
                                // NUMERIC_PRECISION
                                // NUMERIC_SCALE
                                // ORDINAL_POSITION
                                // PRIVILEGES
                                // TABLE_CATALOG
                                // TABLE_NAME
                                // TABLE_SCHEMA
                            };
                        });
                        return [4 /*yield*/, this.query("select * from sqlite_master where type='index' AND tbl_name = '".concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 6:
                        indexes = _h.sent();
                        console.log('indexes', indexes);
                        // [
                        //     {
                        //         "type": "index",
                        //         "name": "idx_db_time",
                        //         "tbl_name": "redis_history",
                        //         "rootpage": 7,
                        //         "sql": "CREATE INDEX \"idx_db_time\"\nON \"redis_history\" (\n  \"db\",\n  \"create_time\"\n)"
                        //     }
                        // ]
                        result.indexes = indexes.map(function (item) {
                            return {
                                INDEX_NAME: item.name,
                                INDEX_COMMENT: '',
                                NON_UNIQUE: 1,
                                'x-raw': item,
                            };
                        });
                        return [3 /*break*/, 22];
                    case 7:
                        if (!(conn.type == 'postgresql')) return [3 /*break*/, 13];
                        indexSql = "SELECT *\nFROM information_schema.STATISTICS\nWHERE TABLE_SCHEMA = '".concat(dbName, "'\n\tand TABLE_NAME = '").concat(tableName, "'");
                        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 8:
                        columns = _h.sent();
                        _a = [__assign({}, result)];
                        _f = { columns: columns.map(function (item) {
                                return {
                                    // COLUMN_KEY: item.pk == 1 ? 'PRI' : 'NOT_PRI',
                                    COLUMN_NAME: item.column_name,
                                    COLUMN_TYPE: item.data_type,
                                    COLUMN_COMMENT: '',
                                    COLUMN_DEFAULT: item.column_default,
                                    IS_NULLABLE: item.is_nullable,
                                    positon: item.ordinal_position,
                                    'x-raw': item,
                                };
                            }) };
                        if (!(conn.type == 'postgresql')) return [3 /*break*/, 9];
                        _b = [];
                        return [3 /*break*/, 11];
                    case 9: return [4 /*yield*/, this.query(indexSql, {
                            connectionId: params.connectionId,
                        })];
                    case 10:
                        _b = _h.sent();
                        _h.label = 11;
                    case 11:
                        _f.indexes = _b;
                        return [4 /*yield*/, this.query("SELECT *\n    FROM information_schema.TRIGGERS\n    WHERE EVENT_OBJECT_SCHEMA = '".concat(dbName, "'\n        and EVENT_OBJECT_TABLE = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 12:
                        result = __assign.apply(void 0, _a.concat([(_f.triggers = _h.sent(), _f)]));
                        return [3 /*break*/, 22];
                    case 13:
                        indexSql = "SELECT *\nFROM information_schema.STATISTICS\nWHERE TABLE_SCHEMA = '".concat(dbName, "'\n\tand TABLE_NAME = '").concat(tableName, "'");
                        _c = [__assign({}, result)];
                        _g = {};
                        return [4 /*yield*/, this.query("SELECT *\nFROM information_schema.COLUMNS\nWHERE TABLE_SCHEMA = '".concat(dbName, "'\nand TABLE_NAME = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 14:
                        _g.columns = _h.sent();
                        if (!(conn.type == 'postgresql')) return [3 /*break*/, 15];
                        _d = [];
                        return [3 /*break*/, 17];
                    case 15: return [4 /*yield*/, this.query(indexSql, {
                            connectionId: params.connectionId,
                        })];
                    case 16:
                        _d = _h.sent();
                        _h.label = 17;
                    case 17:
                        _g.indexes = _d;
                        if (!(conn.type == 'postgresql')) return [3 /*break*/, 18];
                        _e = [];
                        return [3 /*break*/, 20];
                    case 18: return [4 /*yield*/, this.query("SELECT *\n    FROM information_schema.PARTITIONS\n    WHERE TABLE_SCHEMA = '".concat(dbName, "'\n        and TABLE_NAME = '").concat(tableName, "'"), {
                            connectionId: params.connectionId,
                        })];
                    case 19:
                        _e = _h.sent();
                        _h.label = 20;
                    case 20:
                        _g.partitions = _e;
                        return [4 /*yield*/, this.query("SELECT *\n    FROM information_schema.TRIGGERS\n    WHERE EVENT_OBJECT_SCHEMA = '".concat(dbName, "'\n        and EVENT_OBJECT_TABLE = '").concat(tableName, "'"), {
                                connectionId: params.connectionId,
                            })];
                    case 21:
                        result = __assign.apply(void 0, _c.concat([(_g.triggers = _h.sent(), _g)]));
                        _h.label = 22;
                    case 22: return [2 /*return*/, result];
                }
            });
        });
    };
    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_2, newResults, result, rows, ret, _b, err_3;
            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_2 = _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_2.message || 'Unknown Error',
                            });
                            saveHistorylData();
                        }
                        throw new Error(err_2.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_3 = _c.sent();
                        console.error(err_3);
                        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