fix query to fetch list of postgres types, change filter (close #2314) (#2339)

This commit is contained in:
Karthik Venkateswaran 2019-06-07 19:58:02 +05:30 committed by Rikin Kachhia
parent de09c29003
commit 0b3defd314
9 changed files with 89 additions and 60 deletions

View File

@ -1,5 +1,5 @@
import React from 'react';
import Select, { components } from 'react-select';
import Select, { components, createFilter } from 'react-select';
import PropTypes from 'prop-types';
/*
@ -16,6 +16,14 @@ const CustomOption = props => {
);
};
const getPrefixFilter = () => {
const prefixFilterOptions = {
matchFrom: 'start',
};
return createFilter(prefixFilterOptions);
};
/*
* Searchable select box component
* 1) options: Accepts options
@ -30,6 +38,7 @@ const SearchableSelectBox = ({
value,
bsClass,
styleOverrides,
filterOption,
}) => {
/* Select element style customization */
@ -45,6 +54,15 @@ const SearchableSelectBox = ({
});
}
let customFilter;
switch (filterOption) {
case 'prefix':
customFilter = getPrefixFilter();
break;
default:
customFilter = {};
}
return (
<Select
isSearchable
@ -55,6 +73,7 @@ const SearchableSelectBox = ({
onChange={onChange}
value={value}
styles={customStyles}
filterOption={customFilter}
/>
);
};
@ -65,6 +84,7 @@ SearchableSelectBox.propTypes = {
options: PropTypes.array.isRequired,
bsClass: PropTypes.string,
customStyle: PropTypes.object,
filterOption: PropTypes.object,
};
export default SearchableSelectBox;

View File

@ -91,6 +91,7 @@ const TableColumn = props => {
value={column.type && columnTypeValueMap[column.type]}
bsClass={`col-type-${i} add_table_column_selector`}
styleOverrides={customSelectBoxStyles}
filterOption={'prefix'}
/>
</span>
<input

View File

@ -34,23 +34,27 @@ const getAllDataTypeMap = allDataTypes => {
return dTIndex;
};
const getDataTypeInfo = (row, categoryInfo, colId) => {
const getDataTypeInfo = (row, categoryInfo, colId, cached = {}) => {
const columnTypeValueMap = {};
const { typInfo, typDisplayName, typDescription } = splitDbRow(row);
// Create option object for every valid type
const currTypeObj = typInfo.map((t, i) => {
const optObj = {
value: t,
label: typDisplayName[i],
key: `${categoryInfo}_${i}`,
colIdentifier: colId,
description: typDescription[i],
};
// Memoizing option for later use
columnTypeValueMap[t] = optObj;
return optObj;
const currTypeObj = [];
typInfo.forEach((t, i) => {
/* Don't add types which are part of frequently used types */
if (!(t in cached)) {
const optObj = {
value: t,
label: typDisplayName[i],
key: `${categoryInfo}_${i}`,
colIdentifier: colId,
description: typDescription[i],
};
// Memoizing option for later use
columnTypeValueMap[t] = optObj;
currTypeObj.push(optObj);
}
});
return { typInfo: currTypeObj, typValueMap: columnTypeValueMap };
};
@ -99,7 +103,8 @@ const getDataOptions = (commonDataTypes, restTypes, identifier) => {
const { typInfo, typValueMap } = getDataTypeInfo(
categoryRow[0],
pgCategoryCode[category],
identifier
identifier,
columnTypeValueMap
);
columnTypeValueMap = { ...columnTypeValueMap, ...typValueMap };
columnDataTypes.push({

View File

@ -697,7 +697,7 @@ const dataReducer = (state = defaultState, action) => {
return {
...state,
columnDataTypes: action.data,
columnDataTypeFetchErr: 'Error fetching data',
columnDataTypeFetchErr: defaultState.columnDataTypeFetchErr,
};
case FETCH_COLUMN_TYPE_LIST_FAIL:
@ -710,7 +710,7 @@ const dataReducer = (state = defaultState, action) => {
return {
...state,
columnDataTypes: [...defaultState.columnDataTypes],
columnDataTypeFetchErr: defaultState.columnDataTypes,
columnDataTypeFetchErr: defaultState.columnDataTypeFetchErr,
};
default:
return state;

View File

@ -152,6 +152,7 @@ const ColumnCreator = ({ dispatch, tableName, dataTypes: restTypes = [] }) => {
value={colType.value && columnTypeValueMap[colType.value]}
bsClass={`col-type-${0} modify_select`}
styleOverrides={customSelectBoxStyles}
filterOption={'prefix'}
/>
</span>
<input

View File

@ -2,20 +2,6 @@ import React, { useEffect } from 'react';
import SearchableSelectBox from '../../../Common/SearchableSelect/SearchableSelect';
/*
import {
INTEGER,
SERIAL,
BIGINT,
BIGSERIAL,
UUID,
JSONDTYPE,
JSONB,
TIMESTAMP,
TIME,
} from '../../../../constants';
*/
import { getValidAlterOptions } from './utils';
const ColumnEditor = ({
@ -113,6 +99,7 @@ const ColumnEditor = ({
value={columnTypePG && alterOptionsValueMap[columnTypePG]}
bsClass={`col-type-${0} modify_select`}
styleOverrides={customSelectBoxStyles}
filterOption={'prefix'}
/>
</div>
</div>

View File

@ -34,10 +34,10 @@ const getValidAlterOptions = (alterTypeOptions, colName) => {
const fetchColumnCastsQuery = `
SELECT ts.typname AS "Source Type",
pg_catalog.format_type(castsource, NULL) AS "Source Info",
pg_catalog.obj_description(castsource, 'pg_type') as "Source Descriptions",
coalesce(pg_catalog.obj_description(castsource, 'pg_type'), '') as "Source Descriptions",
string_agg(tt.typname, ',') AS "Target Type",
string_agg(pg_catalog.format_type(casttarget, NULL), ',') AS "Target Info",
string_agg(pg_catalog.obj_description(casttarget, 'pg_type'), ':') as "Target Descriptions",
string_agg(coalesce(pg_catalog.obj_description(casttarget, 'pg_type'), ''), ':') as "Target Descriptions",
string_agg(CASE WHEN castfunc = 0 THEN '(binary coercible)'
ELSE p.proname
END, ',') as "Function"
@ -59,15 +59,26 @@ ORDER BY 1, 2;
`;
const getCreatePkSql = ({ schemaName, tableName, selectedPkColumns, constraintName }) => {
const getCreatePkSql = ({
schemaName,
tableName,
selectedPkColumns,
constraintName,
}) => {
return `alter table "${schemaName}"."${tableName}"
add constraint "${constraintName}" primary key ( ${selectedPkColumns
.map(pkc => `"${pkc}"`)
.join(', ')} );`;
.map(pkc => `"${pkc}"`)
.join(', ')} );`;
};
const getDropPkSql = ({ schemaName, tableName, constraintName }) => {
return `alter table "${schemaName}"."${tableName}" drop constraint "${constraintName}";`;
};
export { convertArrayToJson, getValidAlterOptions, fetchColumnCastsQuery, getCreatePkSql, getDropPkSql };
export {
convertArrayToJson,
getValidAlterOptions,
fetchColumnCastsQuery,
getCreatePkSql,
getDropPkSql,
};

View File

@ -569,16 +569,20 @@ export const commonDataTypes = [
},
];
/*
* Fetch non-composite types, primitive types like text, varchar etc,
* Filter types whose typename is unknown and type category is not 'Pseudo' and it is valid and available to be used
* */
export const fetchColumnTypesQuery = `
SELECT
string_agg(t.typname, ',') as "Type Name",
string_agg(pg_catalog.format_type(t.oid, NULL), ',') as "Display Name",
string_agg(pg_catalog.obj_description(t.oid, 'pg_type'), ':') as "Descriptions",
string_agg(coalesce(pg_catalog.obj_description(t.oid, 'pg_type'), ''), ':') as "Descriptions",
t.typcategory
FROM pg_catalog.pg_type t
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
WHERE (t.typrelid = 0 OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid))
AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)
AND pg_catalog.pg_type_is_visible(t.oid)
AND t.typname != 'unknown'
AND t.typcategory != 'P'

View File

@ -225,7 +225,7 @@ const ViewRows = ({
};
const successIcon = (
<i className={styles.invocationSuccess + 'fa fa-check'} />
<i className={styles.invocationSuccess + ' fa fa-check'} />
);
const failureIcon = (
@ -437,26 +437,26 @@ const ViewRows = ({
>
{finalResponse.status_code
? [
'Status Code: ',
verifySuccessStatus(
finalResponse.status_code
)
? successIcon
: failureIcon,
finalResponse.status_code,
' ',
<OverlayTrigger
placement="top"
overlay={
tooltip.statusCodeDescription
}
>
<i
className="fa fa-question-circle"
aria-hidden="true"
/>
</OverlayTrigger>,
]
'Status Code: ',
verifySuccessStatus(
finalResponse.status_code
)
? successIcon
: failureIcon,
finalResponse.status_code,
' ',
<OverlayTrigger
placement="top"
overlay={
tooltip.statusCodeDescription
}
>
<i
className="fa fa-question-circle"
aria-hidden="true"
/>
</OverlayTrigger>,
]
: null}
</div>
<AceEditor