Files
flipper/desktop/plugins/databases/UpdateQueryUtil.tsx
Chaiwat Ekkaewnumchai 54bf6440de Allow to Edit only When There Is Primary Key in Table
Summary: To be able to edit correct cell, identifiers are needed. Assume that the primary key is unique, this should be safe to allow the query to find exactly one row to edit

Reviewed By: jknoxville

Differential Revision: D21788239

fbshipit-source-id: b09d1b6da1b46cbc961f08010467e973546acbef
2020-06-02 01:47:06 -07:00

88 lines
2.4 KiB
TypeScript

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {Value} from 'flipper';
const INT_DATA_TYPE = ['INTEGER', 'LONG', 'INT', 'BIGINT'];
const FLOAT_DATA_TYPE = ['REAL', 'DOUBLE'];
const BLOB_DATA_TYPE = ['BLOB'];
export function convertStringToValue(
types: {[key: string]: {type: string; nullable: boolean}},
key: string,
value: string | null,
): Value {
if (value !== null && types.hasOwnProperty(key)) {
const {type, nullable} = types[key];
if (value.length <= 0 && nullable) {
return {type: 'null', value: null};
}
if (INT_DATA_TYPE.indexOf(type) >= 0) {
return {type: 'integer', value: parseInt(value, 10)};
} else if (FLOAT_DATA_TYPE.indexOf(type) >= 0) {
return {type: 'float', value: parseFloat(value)};
} else if (BLOB_DATA_TYPE.indexOf(type) >= 0) {
return {type: 'blob', value};
}
}
// if no type found assume type is nullable string
if (value === null) {
return {type: 'null', value: null};
} else {
return {type: 'string', value};
}
}
function constructQueryClause(
values: {[key: string]: Value},
connector: string,
): string {
return Object.entries(values).reduce(
(clauses, [key, val]: [string, Value], idx) => {
const {type, value} = val;
const valueString =
type === 'null'
? 'NULL'
: type === 'string' || type === 'blob'
? `'${value}'`
: `${value}`;
if (idx <= 0) {
return `${key}=${valueString}`;
} else {
return `${clauses} ${connector} ${key}=${valueString}`;
}
},
'',
);
}
export function constructUpdateQuery(
table: string,
where: {[key: string]: Value},
change: {[key: string]: Value},
): string {
return `UPDATE ${table}
SET ${constructQueryClause(change, ',')}
WHERE ${constructQueryClause(where, 'AND')}`;
}
export function isUpdatable(
columnMeta: Array<string>,
columnData: Array<Array<Value>>,
): boolean {
const primaryKeyIdx = columnMeta.indexOf('primary_key');
return (
primaryKeyIdx >= 0 &&
columnData.reduce((acc: boolean, column) => {
const primaryValue = column[primaryKeyIdx];
return acc || (primaryValue.type === 'boolean' && primaryValue.value);
}, false)
);
}