mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 04:56:00 +00:00
236 lines
6.7 KiB
TypeScript
236 lines
6.7 KiB
TypeScript
import _isString from 'lodash/isString';
|
|
import _isArray from 'lodash/isArray';
|
|
import _isNumber from 'lodash/isNumber';
|
|
import _isPlainObject from 'lodash/isPlainObject';
|
|
import { DataEditorTypesBehaviour } from 'dbgate-types';
|
|
|
|
export function arrayToHexString(byteArray) {
|
|
return byteArray.reduce((output, elem) => output + ('0' + elem.toString(16)).slice(-2), '').toUpperCase();
|
|
}
|
|
|
|
export function hexStringToArray(inputString) {
|
|
var hex = inputString.toString();
|
|
var res = [];
|
|
for (var n = 0; n < hex.length; n += 2) {
|
|
res.push(parseInt(hex.substr(n, 2), 16));
|
|
}
|
|
return res;
|
|
}
|
|
|
|
export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
|
|
if (!_isString(value)) return value;
|
|
|
|
if (editorTypes?.parseSqlNull) {
|
|
if (value == '(NULL)') return null;
|
|
}
|
|
|
|
if (editorTypes?.parseHexAsBuffer) {
|
|
const mHex = value.match(/^0x([0-9a-fA-F][0-9a-fA-F])+$/);
|
|
if (mHex) {
|
|
return {
|
|
type: 'Buffer',
|
|
data: hexStringToArray(value.substring(2)),
|
|
};
|
|
}
|
|
}
|
|
|
|
if (editorTypes?.parseObjectIdAsDollar) {
|
|
const mOid = value.match(/^ObjectId\("([0-9a-f]{24})"\)$/);
|
|
if (mOid) {
|
|
return { $oid: mOid[1] };
|
|
}
|
|
}
|
|
|
|
if (editorTypes?.parseJsonNull) {
|
|
if (value == 'null') return null;
|
|
}
|
|
|
|
if (editorTypes?.parseJsonBoolean) {
|
|
if (value == 'true') return true;
|
|
if (value == 'false') return false;
|
|
}
|
|
|
|
if (editorTypes?.parseNumber) {
|
|
if (/^-?[0-9]+(?:\.[0-9]+)?$/.test(value)) {
|
|
return parseFloat(value);
|
|
}
|
|
}
|
|
|
|
if (editorTypes?.parseJsonArray || editorTypes?.parseJsonObject) {
|
|
const jsonValue = safeJsonParse(value);
|
|
if (_isPlainObject(jsonValue) && editorTypes?.parseJsonObject) return jsonValue;
|
|
if (_isArray(jsonValue) && editorTypes?.parseJsonArray) return jsonValue;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
function parseObjectIdAsDollar(value) {
|
|
if (value?.$oid) return value;
|
|
if (_isString(value)) {
|
|
if (value.match(/^[0-9a-f]{24}$/)) return { $oid: value };
|
|
const mOid = value.match(/^ObjectId\("([0-9a-f]{24})"\)$/);
|
|
if (mOid) {
|
|
return { $oid: mOid[1] };
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
export function stringifyCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
|
|
if (editorTypes?.parseSqlNull) {
|
|
if (value === null) return '(NULL)';
|
|
}
|
|
if (value === undefined) return '(NoField)';
|
|
if (editorTypes?.parseJsonNull) {
|
|
if (value === null) return 'null';
|
|
}
|
|
if (editorTypes?.parseJsonBoolean) {
|
|
if (value === true) return 'true';
|
|
if (value === false) return 'false';
|
|
}
|
|
if (editorTypes?.parseHexAsBuffer) {
|
|
if (value?.type == 'Buffer' && _isArray(value.data)) return '0x' + arrayToHexString(value.data);
|
|
}
|
|
if (editorTypes?.parseObjectIdAsDollar) {
|
|
if (value?.$oid) return `ObjectId("${value?.$oid}")`;
|
|
}
|
|
if (editorTypes?.parseJsonArray) {
|
|
if (_isArray(value)) return JSON.stringify(value);
|
|
}
|
|
if (editorTypes?.parseJsonObject) {
|
|
if (_isPlainObject(value)) return JSON.stringify(value);
|
|
}
|
|
if (editorTypes?.parseNumber) {
|
|
if (_isNumber(value)) return value.toString();
|
|
}
|
|
|
|
if (_isString(value)) return value;
|
|
|
|
// fallback
|
|
if (_isNumber(value)) return value.toString();
|
|
if (value === null || value === undefined) return '';
|
|
|
|
return '';
|
|
}
|
|
|
|
export function safeJsonParse(json, defaultValue?, logError = false) {
|
|
if (_isArray(json) || _isPlainObject(json)) {
|
|
return json;
|
|
}
|
|
try {
|
|
return JSON.parse(json);
|
|
} catch (err) {
|
|
if (logError) {
|
|
console.error(`Error parsing JSON value "${json}"`, err);
|
|
}
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
export function isJsonLikeLongString(value) {
|
|
return _isString(value) && value.length > 100 && value.match(/^\s*\{.*\}\s*$|^\s*\[.*\]\s*$/);
|
|
}
|
|
|
|
export function getIconForRedisType(type) {
|
|
switch (type) {
|
|
case 'dir':
|
|
return 'img folder';
|
|
case 'string':
|
|
return 'img type-string';
|
|
case 'hash':
|
|
return 'img type-hash';
|
|
case 'set':
|
|
return 'img type-set';
|
|
case 'list':
|
|
return 'img type-list';
|
|
case 'zset':
|
|
return 'img type-zset';
|
|
case 'stream':
|
|
return 'img type-stream';
|
|
case 'binary':
|
|
return 'img type-binary';
|
|
case 'ReJSON-RL':
|
|
return 'img type-rejson';
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
export function isWktGeometry(s) {
|
|
if (!_isString(s)) return false;
|
|
|
|
// return !!s.match(/^POINT\s*\(|/)
|
|
return !!s.match(
|
|
/^POINT\s*\(|^LINESTRING\s*\(|^POLYGON\s*\(|^MULTIPOINT\s*\(|^MULTILINESTRING\s*\(|^MULTIPOLYGON\s*\(|^GEOMCOLLECTION\s*\(|^GEOMETRYCOLLECTION\s*\(/
|
|
);
|
|
}
|
|
|
|
export function arrayBufferToBase64(buffer) {
|
|
var binary = '';
|
|
var bytes = [].slice.call(new Uint8Array(buffer));
|
|
bytes.forEach(b => (binary += String.fromCharCode(b)));
|
|
return btoa(binary);
|
|
}
|
|
|
|
export function getAsImageSrc(obj) {
|
|
if (obj?.type == 'Buffer' && _isArray(obj?.data)) {
|
|
return `data:image/png;base64, ${arrayBufferToBase64(obj?.data)}`;
|
|
}
|
|
|
|
if (_isString(obj) && (obj.startsWith('http://') || obj.startsWith('https://'))) {
|
|
return obj;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export function parseSqlDefaultValue(value: string) {
|
|
if (!value) return undefined;
|
|
if (!_isString(value)) return undefined;
|
|
if (value.startsWith("'") && value.endsWith("'")) {
|
|
return value.slice(1, -1);
|
|
}
|
|
if (!isNaN(value as any) && !isNaN(parseFloat(value))) {
|
|
return parseFloat(value);
|
|
}
|
|
return undefined;
|
|
}
|
|
|
|
export function detectTypeIcon(value) {
|
|
if (value === null) return 'icon type-null';
|
|
if (value?.$oid) return 'icon type-objectid';
|
|
if (_isString(value)) return 'icon type-string';
|
|
if (_isNumber(value)) return 'icon type-number';
|
|
if (_isPlainObject(value)) return 'icon type-object';
|
|
if (_isArray(value)) return 'icon type-array';
|
|
if (value === true || value === false) return 'icon type-boolean';
|
|
return 'icon type-unknown';
|
|
}
|
|
|
|
export function getConvertValueMenu(value, onSetValue, editorTypes?: DataEditorTypesBehaviour) {
|
|
return [
|
|
editorTypes?.supportStringType && {
|
|
text: 'String',
|
|
onClick: () => onSetValue(stringifyCellValue(value, editorTypes)),
|
|
},
|
|
editorTypes?.supportNumberType && { text: 'Number', onClick: () => onSetValue(parseFloat(value)) },
|
|
editorTypes?.supportNullType && { text: 'Null', onClick: () => onSetValue(null) },
|
|
editorTypes?.supportBooleanType && {
|
|
text: 'Boolean',
|
|
onClick: () => onSetValue(value?.toString()?.toLowerCase() == 'true' || value == '1'),
|
|
},
|
|
editorTypes?.supportObjectIdType && { text: 'ObjectId', onClick: () => onSetValue(parseObjectIdAsDollar(value)) },
|
|
editorTypes?.supportJsonType && {
|
|
text: 'JSON',
|
|
onClick: () => {
|
|
const jsonValue = safeJsonParse(value);
|
|
if (jsonValue != null) {
|
|
console.log('**** ON SET VALUE', jsonValue);
|
|
onSetValue(jsonValue);
|
|
}
|
|
},
|
|
},
|
|
];
|
|
}
|