mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-02-25 18:55:31 -06:00
Ensure that when pasting a row in query tool grid, default value is used for autogenerated/serial columns. #5922
This commit is contained in:
parent
1d7d6561f6
commit
861c66d180
Binary file not shown.
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 17 KiB |
@ -178,7 +178,12 @@ Data Editing Options
|
||||
| | | |
|
||||
| | * Click *Copy with headers* to copy the highlighted content along with the header. | |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Paste* | Click the *Paste* icon to paste a previously copied row into a new row. | Accesskey + P |
|
||||
| *Paste* | Click the *Paste* icon to paste a previously copied row with or without serial/identity values: | Accesskey + P |
|
||||
| | | |
|
||||
| | * Click the *Paste* icon to paste a previously copied row into a new row. | |
|
||||
| | | |
|
||||
| | * Click the *Paste with SERIAL/IDENTITY values?* if you want to paste the copied column values | |
|
||||
| | in the serial/identity columns. | |
|
||||
+----------------------+---------------------------------------------------------------------------------------------------+----------------+
|
||||
| *Delete* | Click the *Delete* icon to mark the selected rows for deletion. These marked rows get deleted | Accesskey + D |
|
||||
| | when you click the *Save Data Changes* icon. | |
|
||||
|
@ -1,5 +1,5 @@
|
||||
SELECT DISTINCT att.attname as name, att.attnum as OID, pg_catalog.format_type(ty.oid,NULL) AS datatype,
|
||||
att.attnotnull as not_null, att.atthasdef as has_default_val, des.description
|
||||
att.attnotnull as not_null, att.atthasdef as has_default_val, des.description, seq.seqtypid
|
||||
FROM pg_catalog.pg_attribute att
|
||||
JOIN pg_catalog.pg_type ty ON ty.oid=atttypid
|
||||
JOIN pg_catalog.pg_namespace tn ON tn.oid=ty.typnamespace
|
||||
@ -11,6 +11,7 @@ FROM pg_catalog.pg_attribute att
|
||||
LEFT OUTER JOIN pg_catalog.pg_namespace ns ON ns.oid=cs.relnamespace
|
||||
LEFT OUTER JOIN pg_catalog.pg_index pi ON pi.indrelid=att.attrelid AND indisprimary
|
||||
LEFT OUTER JOIN pg_catalog.pg_description des ON (des.objoid=att.attrelid AND des.objsubid=att.attnum AND des.classoid='pg_class'::regclass)
|
||||
LEFT OUTER JOIN pg_catalog.pg_sequence seq ON cs.oid=seq.seqrelid
|
||||
WHERE
|
||||
att.attrelid = {{ tid|qtLiteral(conn) }}::oid
|
||||
{% if clid %}
|
||||
|
@ -530,6 +530,8 @@ export class ResultSetUtils {
|
||||
'not_null': c.not_null,
|
||||
'has_default_val': c.has_default_val,
|
||||
'is_array': arrayBracketIdx > -1 && arrayBracketIdx + 2 == columnTypeInternal.length,
|
||||
'seqtypid': c.seqtypid,
|
||||
'isPK': isPK
|
||||
};
|
||||
}
|
||||
|
||||
@ -559,14 +561,19 @@ export class ResultSetUtils {
|
||||
return columns;
|
||||
}
|
||||
|
||||
processClipboardVal(columnVal, col, rawCopiedVal) {
|
||||
processClipboardVal(columnVal, col, rawCopiedVal, pasteSerials) {
|
||||
if(columnVal === '' ) {
|
||||
if(col.has_default_val) {
|
||||
// if column has default value
|
||||
columnVal = undefined;
|
||||
} else if(rawCopiedVal === null) {
|
||||
columnVal = null;
|
||||
}
|
||||
} else if (col.has_default_val && col.seqtypid && !pasteSerials) {
|
||||
// if column has default value and is serial type
|
||||
columnVal = undefined;
|
||||
}
|
||||
|
||||
if(col.cell === 'boolean') {
|
||||
if(columnVal == 'true') {
|
||||
columnVal = true;
|
||||
@ -581,7 +588,7 @@ export class ResultSetUtils {
|
||||
return columnVal;
|
||||
}
|
||||
|
||||
processRows(result, columns, fromClipboard=false) {
|
||||
processRows(result, columns, fromClipboard=false, pasteSerials=false) {
|
||||
let retVal = [];
|
||||
if(!_.isArray(result) || !_.size(result)) {
|
||||
return retVal;
|
||||
@ -598,7 +605,7 @@ export class ResultSetUtils {
|
||||
let columnVal = rec[col.pos];
|
||||
/* If the source is clipboard, then it needs some extra handling */
|
||||
if(fromClipboard) {
|
||||
columnVal = this.processClipboardVal(columnVal, col, copiedRowsObjects[recIdx]?.[col.key]);
|
||||
columnVal = this.processClipboardVal(columnVal, col, copiedRowsObjects[recIdx]?.[col.key], pasteSerials);
|
||||
}
|
||||
rowObj[col.key] = columnVal;
|
||||
}
|
||||
@ -1207,14 +1214,14 @@ export function ResultSet() {
|
||||
}, [selectedRows, queryData, dataChangeStore, rows]);
|
||||
|
||||
useEffect(()=>{
|
||||
const triggerAddRows = (_rows, fromClipboard)=>{
|
||||
const triggerAddRows = (_rows, fromClipboard, pasteSerials)=>{
|
||||
let insPosn = 0;
|
||||
if(selectedRows.size > 0) {
|
||||
let selectedRowsSorted = Array.from(selectedRows);
|
||||
selectedRowsSorted.sort();
|
||||
insPosn = _.findIndex(rows, (r)=>rowKeyGetter(r)==selectedRowsSorted[selectedRowsSorted.length-1])+1;
|
||||
}
|
||||
let newRows = rsu.current.processRows(_rows, columns, fromClipboard);
|
||||
let newRows = rsu.current.processRows(_rows, columns, fromClipboard, pasteSerials);
|
||||
setRows((prev)=>[
|
||||
...prev.slice(0, insPosn),
|
||||
...newRows,
|
||||
|
@ -53,6 +53,7 @@ export function ResultSetToolbar({containerRef, canEdit, totalRowCount}) {
|
||||
const [checkedMenuItems, setCheckedMenuItems] = React.useState({});
|
||||
/* Menu button refs */
|
||||
const copyMenuRef = React.useRef(null);
|
||||
const pasetMenuRef = React.useRef(null);
|
||||
|
||||
const queryToolPref = queryToolCtx.preferences.sqleditor;
|
||||
|
||||
@ -72,8 +73,8 @@ export function ResultSetToolbar({containerRef, canEdit, totalRowCount}) {
|
||||
field_separator: queryToolPref.results_grid_field_separator,
|
||||
});
|
||||
let copiedRows = copyUtils.getCopiedRows();
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, copiedRows, true);
|
||||
}, [queryToolPref]);
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, copiedRows, true, checkedMenuItems['paste_with_serials']);
|
||||
}, [queryToolPref, checkedMenuItems['paste_with_serials']]);
|
||||
const copyData = ()=>{
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.COPY_DATA, checkedMenuItems['copy_with_headers']);
|
||||
};
|
||||
@ -163,6 +164,8 @@ export function ResultSetToolbar({containerRef, canEdit, totalRowCount}) {
|
||||
name="menu-copyheader" ref={copyMenuRef} onClick={openMenu} />
|
||||
<PgIconButton title={gettext('Paste')} icon={<PasteIcon />}
|
||||
accesskey={shortcut_key(queryToolPref.btn_paste_row)} disabled={!canEdit} onClick={pasteRows} />
|
||||
<PgIconButton title={gettext('Paste options')} icon={<KeyboardArrowDownIcon />} splitButton
|
||||
name="menu-pasteoptions" ref={pasetMenuRef} onClick={openMenu} />
|
||||
<PgIconButton title={gettext('Delete')} icon={<DeleteRoundedIcon />}
|
||||
accesskey={shortcut_key(queryToolPref.btn_delete_row)} disabled={buttonsDisabled['delete-rows'] || !canEdit} onClick={deleteRows} />
|
||||
</PgButtonGroup>
|
||||
@ -188,6 +191,14 @@ export function ResultSetToolbar({containerRef, canEdit, totalRowCount}) {
|
||||
>
|
||||
<PgMenuItem hasCheck value="copy_with_headers" checked={checkedMenuItems['copy_with_headers']} onClick={checkMenuClick}>{gettext('Copy with headers')}</PgMenuItem>
|
||||
</PgMenu>
|
||||
<PgMenu
|
||||
anchorRef={pasetMenuRef}
|
||||
open={menuOpenId=='menu-pasteoptions'}
|
||||
onClose={handleMenuClose}
|
||||
label={gettext('Paste Options Menu')}
|
||||
>
|
||||
<PgMenuItem hasCheck value="paste_with_serials" checked={checkedMenuItems['paste_with_serials']} onClick={checkMenuClick}>{gettext('Paste with SERIAL/IDENTITY values?')}</PgMenuItem>
|
||||
</PgMenu>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -49,6 +49,9 @@ def get_columns_types(is_query_tool, columns_info, table_oid, conn, has_oids):
|
||||
col['has_default_val'] = \
|
||||
rset['rows'][key]['has_default_val']
|
||||
|
||||
col_type['seqtypid'] = col['seqtypid'] = \
|
||||
rset['rows'][key]['seqtypid']
|
||||
|
||||
else:
|
||||
for row in rset['rows']:
|
||||
if row['oid'] == col['table_column']:
|
||||
@ -56,10 +59,14 @@ def get_columns_types(is_query_tool, columns_info, table_oid, conn, has_oids):
|
||||
|
||||
col_type['has_default_val'] = \
|
||||
col['has_default_val'] = row['has_default_val']
|
||||
|
||||
col_type['seqtypid'] = col['seqtypid'] = \
|
||||
rset['rows'][key]['seqtypid']
|
||||
break
|
||||
|
||||
else:
|
||||
col_type['not_null'] = col['not_null'] = None
|
||||
col_type['has_default_val'] = col['has_default_val'] = None
|
||||
col_type['seqtypid'] = col['seqtypid'] = None
|
||||
|
||||
return column_types
|
||||
|
Loading…
Reference in New Issue
Block a user