Vue.component("vv-msql-queryresult", {
template: '<template>     <div>         <q-tabs v-model="current_tab" align="left" dense class="bg-white text-primary" no-caps>             <q-tab v-for="(table, table_idx) in table_list_computed" dense :name="table_idx" :label="\'#\'.concat(table_idx, \' (cols \', table.columns.length, \'; rows \', table.origin_rows.length, \')\')" >             </q-tab>         </q-tabs>         <div v-for="(table, table_idx) in table_list_computed" style=\'overflow: hidden\'>             <q-table dense flat square hide-bottom virtual-scroll style="margin: 10px 0px 0px 0px;"                 ref="main_table"                 v-show="table_idx === current_tab"                 v-bind:style=\'table_style\'                 :pagination.sync="pagination"                 :rows-per-page-options="[0]"                 :data="table.formatted_rows"                 :columns="table.columns"                 :sort-method="on_sort"                 >                 <template v-slot:header="props">                     <q-tr :props="props">                         <q-th v-for="col in props.cols"                             :key="col.name"                             :props="props"                             class="bg-primary text-white"                             @click="on_click_column">                             {{col.name}}                             <q-icon v-show="col.sort_state === \'(a>z)\'" name="icon-eo-up-dir"></q-icon>                             <q-icon v-show="col.sort_state === \'(z>a)\'" name="icon-eo-down-dir"></q-icon>                             <q-tooltip :delay="500" anchor="top middle" self="bottom middle" :offset="[10, 10]">                                 {{col.model.declare}}                             </q-tooltip>                         </q-th>                     </q-tr>                 </template>                  <template v-slot:body="props">                     <q-tr :props="props">                         <q-td v-for="col in props.cols" :key="col.name" :props="props">                             <div v-if = "col.value === undefined" class = "text-italic text-grey">                                 NULL                             </div>                             <div v-else>                                 {{col.value}}                             </div>                         </q-td>                     </q-tr>                 </template>             </q-table>         </div>                </div> </template>',
props :{
    table_height: String,
    external_table_list: Array
},
computed :{
    table_style: function () {
        return { height: this.table_height ? this.table_height : '100%' };
    },
    table_list_computed: function () {
        if (Array.isArray(this.external_table_list))
            return this.external_table_list;
        return this.table_list;
    }
},
data :function () {
    return {
        table_list: [],
        current_tab: 0,
        pagination: { rowsPerPage: 0 },
        mapping_types: [
            {
                type: 'bigint',
                precision: 19,
                scale: 0,
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:integer',
                bytes_on_char: undefined
            },
            {
                type: 'bit',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:boolean',
                bytes_on_char: undefined
            },
            {
                type: 'decimal',
                precision: 'allow',
                scale: 'allow',
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:decimal',
                bytes_on_char: undefined
            },
            {
                type: 'int',
                precision: 10,
                scale: 0,
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:integer',
                bytes_on_char: undefined
            },
            {
                type: 'money',
                precision: 19,
                scale: 4,
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:decimal',
                bytes_on_char: undefined
            },
            {
                type: 'numeric',
                precision: 'allow',
                scale: 'allow',
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:decimal',
                bytes_on_char: undefined
            },
            {
                type: 'smallint',
                precision: 5,
                scale: 0,
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:integer',
                bytes_on_char: undefined
            },
            {
                type: 'smallmoney',
                precision: 10,
                scale: 4,
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:integer',
                bytes_on_char: undefined
            },
            {
                type: 'tinyint',
                precision: 3,
                scale: 0,
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:integer',
                bytes_on_char: undefined
            },
            {
                type: 'float',
                precision: 53,
                scale: 'deny',
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:decimal',
                bytes_on_char: undefined
            },
            {
                type: 'real',
                precision: 24,
                scale: 'deny',
                len: 'deny',
                jstype: 'number',
                xsdtype: 'xs:decimal',
                bytes_on_char: undefined
            },
            {
                type: 'date',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'Date',
                xsdtype: 'xs:date',
                bytes_on_char: undefined
            },
            {
                type: 'datetime2',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'Date',
                xsdtype: 'xs:dateTime',
                bytes_on_char: undefined
            },
            {
                type: 'datetime',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'Date',
                xsdtype: 'xs:dateTime',
                bytes_on_char: undefined
            },
            {
                type: 'datetimeoffset',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'Date',
                xsdtype: 'xs:string',
                bytes_on_char: undefined
            },
            {
                type: 'smalldatetime',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'Date',
                xsdtype: 'xs:dateTime',
                bytes_on_char: undefined
            },
            {
                type: 'time',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'Date',
                xsdtype: 'xs:time',
                bytes_on_char: undefined
            },
            {
                type: 'char',
                precision: 'deny',
                scale: 'deny',
                len: 'deny_max',
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: 2
            },
            {
                type: 'text',
                precision: 'deny',
                scale: 'deny',
                len: 2147483647,
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: 1
            },
            {
                type: 'varchar',
                precision: 'deny',
                scale: 'deny',
                len: 'allow',
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: 1
            },
            {
                type: 'sysname',
                precision: 'deny',
                scale: 'deny',
                len: 128,
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: 1
            },
            {
                type: 'nchar',
                precision: 'deny',
                scale: 'deny',
                len: 'deny_max',
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: 2
            },
            {
                type: 'ntext',
                precision: 'deny',
                scale: 'deny',
                len: 1073741823,
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: 2
            },
            {
                type: 'nvarchar',
                precision: 'deny',
                scale: 'deny',
                len: 'allow',
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: 2
            },
            {
                type: 'binary',
                precision: 'deny',
                scale: 'deny',
                len: 'deny_max',
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'image',
                precision: 'deny',
                scale: 'deny',
                len: 2147483647,
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'varbinary',
                precision: 'deny',
                scale: 'deny',
                len: 'allow',
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'hierarchyid',
                precision: 'deny',
                scale: 'deny',
                len: 892,
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'sql_variant',
                precision: 'deny',
                scale: 'deny',
                len: 0,
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'xml',
                precision: 'deny',
                scale: 'deny',
                len: -1,
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'uniqueidentifier',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: 'string',
                xsdtype: 'xs:string',
                bytes_on_char: undefined
            },
            {
                type: 'timestamp',
                precision: 'deny',
                scale: 'deny',
                len: 'deny',
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'geometry',
                precision: 'deny',
                scale: 'deny',
                len: -1,
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            },
            {
                type: 'geography',
                precision: 'deny',
                scale: 'deny',
                len: -1,
                jstype: undefined,
                xsdtype: undefined,
                bytes_on_char: undefined
            }
        ]
    };
},
methods :{
    table_add(raw_columns) {
        let raw_columns_arr = typeof raw_columns === 'string' ? JSON.parse(raw_columns) : raw_columns;
        let table = {
            columns: [],
            _func_build_origin_row: new Function('raw_row', 'return {}'),
            _func_build_formatted_row: new Function('origin_row', 'return {}'),
            origin_rows: [],
            formatted_rows: []
        };
        let _func_build_origin_row = ['return {'];
        let _func_build_formatted_row = ['return {'];
        raw_columns_arr.forEach(item => {
            let model = {
                name: vvs.findPropertyValueInObject(item, 'name', ''),
                type: vvs.findPropertyValueInObject(item, 'type', '').toLowerCase(),
                len: vvs.toInt(vvs.findPropertyValueInObject(item, 'len')),
                precision: vvs.toInt(vvs.findPropertyValueInObject(item, 'precision')),
                scale: vvs.toInt(vvs.findPropertyValueInObject(item, 'scale')),
                pk_position: vvs.toInt(vvs.findPropertyValueInObject(item, 'pk_position')),
                nullable: vvs.findPropertyValueInObject(item, 'nullable', true),
                identity: vvs.findPropertyValueInObject(item, 'identity', false),
                readonly: vvs.findPropertyValueInObject(item, 'readonly', false),
                declare: '<unknown declare>'
            };
            model.declare = model.type.toUpperCase();
            if ([
                    'decimal',
                    'numeric'
                ].includes(model.type)) {
                if (model.precision && model.scale) {
                    model.declare = model.declare.concat('(', model.precision, ', ', model.scale, ')');
                }
            } else if ([
                    'varchar',
                    'varbinary'
                ].includes(model.type)) {
                if (model.len) {
                    if (model.len >= 0) {
                        model.declare = model.declare.concat('(', model.len, ')');
                    } else {
                        model.declare = model.declare.concat('(MAX)');
                    }
                }
            } else if (['nvarchar'].includes(model.type)) {
                if (model.len) {
                    if (model.len === 65535) {
                        model.declare = model.declare;
                    } else if (model.len >= 0) {
                        model.declare = model.declare.concat('(', model.len, ')');
                    } else {
                        model.declare = model.declare.concat('(MAX)');
                    }
                }
            } else if ([
                    'char',
                    'nchar',
                    'binary'
                ].includes(model.type)) {
                if (model.len) {
                    if (model.len >= 0) {
                        model.declare = model.declare.concat('(', model.len, ')');
                    }
                }
            }
            if ([
                    'bigint',
                    'int',
                    'smallint',
                    'tinyint'
                ].includes(model.type)) {
                _func_build_origin_row.push(vvs.format('{0}: vvs.nz(vvs.toInt(vvs.findPropertyValueInObject(raw_row, "{0}")),null),', model.name));
            } else if (model.type === 'bit') {
                _func_build_origin_row.push(vvs.format('{0}: vvs.nz(vvs.toBool(vvs.findPropertyValueInObject(raw_row, "{0}")),null),', model.name));
            } else if ([
                    'decimal',
                    'money',
                    'numeric',
                    'smallmoney',
                    'float',
                    'real'
                ].includes(model.type)) {
                _func_build_origin_row.push(vvs.format('{0}: vvs.nz(vvs.toFloat(vvs.findPropertyValueInObject(raw_row, "{0}")),null),', model.name));
            } else if ([
                    'date',
                    'datetime2',
                    'datetime',
                    'datetimeoffset',
                    'smalldatetime',
                    'time'
                ].includes(model.type)) {
                _func_build_origin_row.push(vvs.format('{0}: vvs.nz(vvs.toDate(vvs.findPropertyValueInObject(raw_row, "{0}")),null),', model.name));
            } else if ([
                    'char',
                    'varchar',
                    'sysname',
                    'nchar',
                    'nvarchar',
                    'uniqueidentifier'
                ].includes(model.type)) {
                _func_build_origin_row.push(vvs.format('{0}: vvs.nz(vvs.toString(vvs.findPropertyValueInObject(raw_row, "{0}")),null),', model.name));
            } else if ([
                    'text',
                    'ntext',
                    'binary',
                    'image',
                    'varbinary',
                    'hierarchyid',
                    'sql_variant',
                    'xml',
                    'timestamp',
                    'geometry',
                    'geography'
                ].includes(model.type)) {
                _func_build_origin_row.push(vvs.format('{0}: vvs.nz(vvs.findPropertyValueInObject(raw_row, "{0}"),null),', model.name));
            } else {
                _func_build_origin_row.push(vvs.format('{0}: vvs.nz(vvs.findPropertyValueInObject(raw_row, "{0}"),null),', model.name));
            }
            if (model.type === 'bit') {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : (origin_row.{0} === true ? "1" : "0"),', model.name));
            } else if ([
                    'decimal',
                    'numeric'
                ].includes(model.type)) {
                if (Number.isInteger(model.scale)) {
                    _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : origin_row.{0}.toFixed({1}),', [
                        model.name,
                        model.scale
                    ]));
                } else {
                    _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : origin_row', model.name));
                }
            } else if ([
                    'binary',
                    'image',
                    'varbinary',
                    'timestamp',
                    'hierarchyid',
                    'geometry',
                    'geography'
                ].includes(model.type)) {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : (!origin_row.{0}.type || !origin_row.{0}.data || origin_row.{0}.type !== "Buffer" ? origin_row.{0} : "0x".concat(Array.from(origin_row.{0}.data, function(byte) {return ("0" + (byte & 0xFF).toString(16)).slice(-2)}).join("").toUpperCase())),', model.name));
            } else if (model.type === 'date') {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : vvs.formatDate(origin_row.{0}, 23),', model.name));
            } else if ([
                    'datetime2',
                    'datetime',
                    'datetimeoffset'
                ].includes(model.type)) {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : vvs.formatDate(origin_row.{0}, 101262),', model.name));
            } else if (model.type === 'smalldatetime') {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : vvs.formatDate(origin_row.{0}, 101263),', model.name));
            } else if (model.type === 'time') {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : vvs.formatDate(origin_row.{0}, 1141),', model.name));
            } else if (model.type === 'uniqueidentifier') {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : origin_row.{0}.toUpperCase(),', model.name));
            } else if ([
                    'bigint',
                    'int',
                    'money',
                    'smallint',
                    'smallmoney',
                    'tinyint',
                    'float',
                    'real',
                    'char',
                    'text',
                    'sysname',
                    'nchar',
                    'ntext',
                    'nvarchar',
                    'sql_variant',
                    'xml'
                ].includes(model.type)) {
                _func_build_formatted_row.push(vvs.format('{0}: origin_row.{0} === undefined ? undefined : origin_row.{0},', model.name));
            }
            let column = {
                name: model.name,
                field: model.name,
                align: 'left',
                sortable: true,
                sort_state: '',
                model: model
            };
            table.columns.push(column);
        });
        _func_build_origin_row.push('}');
        _func_build_formatted_row.push('}');
        table._func_build_origin_row = new Function('raw_row', _func_build_origin_row.join('\n')), table._func_build_formatted_row = new Function('origin_row', _func_build_formatted_row.join('\n')), this.table_list.push(table);
    },
    rows_add(raw_rows) {
        let table = this.table_list.length <= 0 ? undefined : this.table_list[this.table_list.length - 1];
        if (!table) {
            throw new Error('table_list is empty');
        }
        let raw_arr = typeof raw_rows === 'string' ? JSON.parse(raw_rows) : raw_rows;
        raw_arr.forEach(item => {
            let origin_row = table._func_build_origin_row(item);
            let formatted_row = table._func_build_formatted_row(origin_row);
            table.origin_rows.push(origin_row);
            table.formatted_rows.push(formatted_row);
        });
    },
    clear() {
        this.table_list = [];
    },
    on_click_column() {
        let table = this.table_list_computed[this.current_tab];
        table.columns.forEach(column => {
            column.sort_state = '';
        });
    },
    on_sort(rows, column_name, descending) {
        let table = this.table_list_computed[this.current_tab];
        if (table) {
            let column = table.columns.find(f => f.name === column_name);
            if (column) {
                column.sort_state = descending === true ? '(z>a)' : '(a>z)';
            }
        }
        const data = [...rows];
        data.sort((a, b) => {
            const x = descending ? b : a;
            const y = descending ? a : b;
            return x[column_name] > y[column_name] ? 1 : x[column_name] < y[column_name] ? -1 : 0;
        });
        return data;
    }
},
mounted :function () {
}
})