Files
flipper/desktop/plugins/databases/UpdateQueryUtil.tsx
Chaiwat Ekkaewnumchai 525d0e9925 Add Test Case for Single Quote and Fix Logic
Summary: Single quotes need to be double to be correctly recognized in queries. #thanks mweststrate for reminding me

Reviewed By: mweststrate

Differential Revision: D21908315

fbshipit-source-id: 6c13f9ddb527d1144cc3df90ba48bdb5f2ed4952
2020-06-08 09:00:04 -07:00

93 lines
2.6 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 (types.hasOwnProperty(key)) {
const {type, nullable} = types[key];
value = value === null ? '' : value;
if (value.length <= 0 && nullable) {
return {type: 'null', value: null};
}
if (INT_DATA_TYPE.indexOf(type) >= 0) {
const converted = parseInt(value, 10);
return {type: 'integer', value: isNaN(converted) ? 0 : converted};
} else if (FLOAT_DATA_TYPE.indexOf(type) >= 0) {
const converted = parseFloat(value);
return {type: 'float', value: isNaN(converted) ? 0 : converted};
} else if (BLOB_DATA_TYPE.indexOf(type) >= 0) {
return {type: 'blob', value};
} else {
return {type: 'string', value};
}
}
// if no type found assume type is nullable string
if (value === null || value.length <= 0) {
return {type: 'null', value: null};
} else {
return {type: 'string', value};
}
}
export function constructQueryClause(
values: {[key: string]: Value},
connector: string,
): string {
return Object.entries(values).reduce(
(clauses, [key, val]: [string, Value], idx) => {
const valueString =
val.type === 'null'
? 'NULL'
: val.type === 'string' || val.type === 'blob'
? `'${val.value.replace(/'/g, "''")}'`
: `${val.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)
);
}