Improvements to query table

This commit is contained in:
Fabio 2020-06-18 19:01:09 +02:00
parent a597015f50
commit 0d10a93bf8
10 changed files with 194 additions and 22 deletions

7
CHANGELOG.md Normal file
View File

@ -0,0 +1,7 @@
# Changelog
## [0.0.1-alpha]() - Coming Soon
### Features
- **Initial release:**

BIN
build/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

5
package-lock.json generated
View File

@ -8475,6 +8475,11 @@
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.26.0",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz",
"integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw=="
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",

View File

@ -9,7 +9,8 @@
"dev": "cross-env NODE_ENV=development electron-webpack dev",
"compile": "electron-webpack",
"dist": "cross-env NODE_ENV=production npm run compile && electron-builder",
"dist:dir": "cross-env NODE_ENV=production npm run dist --dir -c.compression=store -c.mac.identity=null"
"dist:dir": "cross-env NODE_ENV=production npm run dist --dir -c.compression=store -c.mac.identity=null",
"publish": "build -p always"
},
"author": "Fabio Di Stasio <fabio286@gmail.com>",
"build": {
@ -33,6 +34,7 @@
"electron-updater": "^4.3.1",
"lodash": "^4.17.15",
"material-design-icons": "^3.0.1",
"moment": "^2.26.0",
"mssql": "^6.2.0",
"mysql": "^2.18.1",
"pg": "^8.2.1",

View File

@ -0,0 +1,40 @@
'use strict';
const lookup = {
0: '0000',
1: '0001',
2: '0010',
3: '0011',
4: '0100',
5: '0101',
6: '0110',
7: '0111',
8: '1000',
9: '1001',
a: '1010',
b: '1011',
c: '1100',
d: '1101',
e: '1110',
f: '1111',
A: '1010',
B: '1011',
C: '1100',
D: '1101',
E: '1110',
F: '1111'
};
/**
* Converts hexadecimal string to binary string
*
* @param {string} hex Hexadecimal string
* @returns {string} Binary string
*/
export default function hexToBinary (hex) {
let binary = '';
for (let i = 0, len = hex.length; i < len; i++)
binary += lookup[hex[i]];
return binary;
}

View File

@ -1,3 +1,59 @@
export function uidGen () {
return Math.random().toString(36).substr(2, 9).toUpperCase();
};
export function mimeFromHex (hex) {
switch (hex.substring(0, 4)) { // 2 bytes
case '424D':
return { ext: 'bmp', mime: 'image/bmp' };
case '1F8B':
return { ext: 'gz', mime: 'application/gzip' };
case '0B77':
return { ext: 'ac3', mime: 'audio/vnd.dolby.dd-raw' };
case '7801':
return { ext: 'dmg', mime: 'application/x-apple-diskimage' };
case '4D5A':
return { ext: 'exe', mime: 'application/x-msdownload' };
case '1FA0':
case '1F9D':
return { ext: 'Z', mime: 'application/x-compress' };
default:
switch (hex.substring(0, 6)) { // 3 bytes
case 'FFD8FF':
return { ext: 'jpj', mime: 'image/jpeg' };
case '4949BC':
return { ext: 'jxr', mime: 'image/vnd.ms-photo' };
case '425A68':
return { ext: 'bz2', mime: 'application/x-bzip2' };
default:
switch (hex) { // 4 bites
case '89504E47':
return { ext: 'png', mime: 'image/png' };
case '47494638':
return { ext: 'gif', mime: 'image/gif' };
case '25504446':
return { ext: 'pdf', mime: 'application/pdf' };
case '504B0304':
return { ext: 'zip', mime: 'application/zip' };
case '425047FB':
return { ext: 'bpg', mime: 'image/bpg' };
case '4D4D002A':
return { ext: 'tif', mime: 'image/tiff' };
default:
return { ext: '???', mime: 'unknown ' + hex };
}
}
}
};
export function formatBytes (bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

View File

@ -94,10 +94,19 @@ app.on('ready', () => {
});
// auto-updater events
autoUpdater.on('checking-for-update', () => {
});
autoUpdater.on('update-available', () => {
mainWindow.webContents.send('update_available');
});
autoUpdater.on('update-not-available', () => {
});
autoUpdater.on('download-progress', (progressObj) => {
});
autoUpdater.on('update-downloaded', () => {
mainWindow.webContents.send('update_downloaded');
});

View File

@ -151,6 +151,7 @@ export default {
background: $bg-color;
border: 1px solid;
border-left: none;
border-bottom-width: 2px;
border-color: $bg-color-light;
padding: .1rem .4rem;
font-weight: 700;

View File

@ -38,11 +38,11 @@
v-for="(col, cKey) in row"
:key="cKey"
class="td"
:class="fieldType(col)"
:style="{'display': cKey === '_id'? 'none' : ''}"
:class="`type-${fieldType(cKey)}${isNull(col)}`"
:style="{'display': cKey === '_id' ? 'none' : ''}"
tabindex="0"
>
{{ col }}
{{ col | typeFormat(fieldType(cKey)) }}
</div>
</div>
</div>
@ -52,7 +52,9 @@
</template>
<script>
import { uidGen } from 'common/libs/utilities';
import { uidGen, mimeFromHex, formatBytes } from 'common/libs/utilities';
import hexToBinary from 'common/libs/hexToBinary';
import moment from 'moment';
import BaseVirtualScroll from '@/components/BaseVirtualScroll';
export default {
@ -60,6 +62,37 @@ export default {
components: {
BaseVirtualScroll
},
filters: {
typeFormat (val, type) {
if (!val) return val;
switch (type) {
case 'char':
case 'varchar':
case 'text':
return val.substring(0, 128);
case 'date':
return moment(val).format('YYYY-MM-DD');
case 'datetime':
return moment(val).format('YYYY-MM-DD HH:mm:ss.SSS');
case 'blob':
case 'mediumblob':
case 'longblob': {
const buff = Buffer.from(val);
if (!buff.length) return '';
const hex = buff.toString('hex').substring(0, 8).toUpperCase();
return `${mimeFromHex(hex).mime} (${formatBytes(buff.length)})`;
}
case 'bit': {
const hex = Buffer.from(val).toString('hex');
return hexToBinary(hex);
}
default:
return val;
}
}
},
props: {
results: Object,
fields: Array
@ -88,14 +121,16 @@ export default {
window.removeEventListener('resize', this.resizeResults);
},
methods: {
fieldType (col) { // TODO: get from fields
let type = typeof col;
if (type === 'object')
if (col instanceof Date) type = 'date';
if (col instanceof Uint8Array) type = 'blob';
if (col === null) type = 'null';
fieldType (cKey) {
let type = 'unknown';
const field = this.fields.filter(field => field.name === cKey)[0];
if (field)
type = field.type;
return `type-${type}`;
return type;
},
isNull (col) {
return col === null ? ' is-null' : '';
},
keyName (key) {
switch (key) {

View File

@ -3,12 +3,6 @@
.type-#{$type} {
color: $color;
@if $type == 'null'{
&::after{
content: 'NULL';
}
}
@if $type == 'number'{
text-align: right;
}
@ -17,9 +11,32 @@
}
@include type-colors((
"string": seagreen,
"number": cornflowerblue,
"char": seagreen,
"varchar": seagreen,
"text": seagreen,
"int": cornflowerblue,
"tinyint": cornflowerblue,
"smallint": cornflowerblue,
"mediumint": cornflowerblue,
"datetime": coral,
"date": coral,
"time": coral,
"bit": lightskyblue,
"blob": darkorchid,
"null": gray,
))
"mediumblob": darkorchid,
"longblob": darkorchid,
"unknown": gray,
));
.is-null{
color: gray;
&::after{
content: 'NULL';
}
}