mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 23:45:59 +00:00
Use changeset in DbKeyTableControl, update values
This commit is contained in:
@@ -9,6 +9,8 @@
|
|||||||
export let database;
|
export let database;
|
||||||
export let keyInfo;
|
export let keyInfo;
|
||||||
export let onChangeSelected;
|
export let onChangeSelected;
|
||||||
|
export let modifyRow = null;
|
||||||
|
export let changeSetRedis = null;
|
||||||
|
|
||||||
let rows = [];
|
let rows = [];
|
||||||
let cursor = 0;
|
let cursor = 0;
|
||||||
@@ -73,6 +75,12 @@
|
|||||||
onMount(() => {
|
onMount(() => {
|
||||||
loadNextRows();
|
loadNextRows();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$: displayRows = modifyRow ? rows.map(row => modifyRow(row)) : rows;
|
||||||
|
$: {
|
||||||
|
changeSetRedis;
|
||||||
|
displayRows = modifyRow ? rows.map(row => modifyRow(row)) : rows;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ScrollableTableControl
|
<ScrollableTableControl
|
||||||
@@ -87,7 +95,7 @@
|
|||||||
header: column.name,
|
header: column.name,
|
||||||
})),
|
})),
|
||||||
]}
|
]}
|
||||||
{rows}
|
rows={displayRows}
|
||||||
onLoadNext={isLoadedAll ? null : loadNextRows}
|
onLoadNext={isLoadedAll ? null : loadNextRows}
|
||||||
selectable
|
selectable
|
||||||
singleLineRow
|
singleLineRow
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
import { _t } from '../translations';
|
import { _t } from '../translations';
|
||||||
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
|
import ToolStripContainer from '../buttons/ToolStripContainer.svelte';
|
||||||
import ToolStripButton from '../buttons/ToolStripButton.svelte';
|
import ToolStripButton from '../buttons/ToolStripButton.svelte';
|
||||||
|
import type { ChangeSetRedis, ChangeSetRedisType } from 'dbgate-datalib';
|
||||||
|
|
||||||
export let tabid;
|
export let tabid;
|
||||||
export let conid;
|
export let conid;
|
||||||
@@ -46,12 +47,25 @@
|
|||||||
export let isDefaultBrowser = false;
|
export let isDefaultBrowser = false;
|
||||||
|
|
||||||
export const activator = createActivator('DbKeyDetailTab', true);
|
export const activator = createActivator('DbKeyDetailTab', true);
|
||||||
|
|
||||||
|
export function getChangeSetRedis(): ChangeSetRedis {
|
||||||
|
return changeSetRedis;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hasChanges(): boolean {
|
||||||
|
return changeSetRedis.changes.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function resetChangeSet() {
|
||||||
|
changeSetRedis = { changes: [] };
|
||||||
|
}
|
||||||
|
|
||||||
let currentRow;
|
let currentRow;
|
||||||
|
|
||||||
$: key = $activeDbKeysStore[`${conid}:${database}`];
|
$: key = $activeDbKeysStore[`${conid}:${database}`];
|
||||||
let refreshToken = 0;
|
let refreshToken = 0;
|
||||||
let editedValue = null;
|
let editedValue = null;
|
||||||
|
let changeSetRedis: ChangeSetRedis = { changes: [] };
|
||||||
|
|
||||||
$: changeTab(tabid, tab => ({
|
$: changeTab(tabid, tab => ({
|
||||||
...tab,
|
...tab,
|
||||||
@@ -113,11 +127,86 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addOrUpdateChange(change: ChangeSetRedisType) {
|
||||||
|
const existingIndex = changeSetRedis.changes.findIndex(
|
||||||
|
c => c.key === change.key && c.type === change.type
|
||||||
|
);
|
||||||
|
|
||||||
|
if (existingIndex >= 0) {
|
||||||
|
changeSetRedis.changes = changeSetRedis.changes.map((c, idx) =>
|
||||||
|
idx === existingIndex ? change : c
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
changeSetRedis.changes = [...changeSetRedis.changes, change];
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('ChangeSetRedis updated:', JSON.stringify(changeSetRedis, null, 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDisplayRow(row, keyInfo) {
|
||||||
|
if (!row) return row;
|
||||||
|
|
||||||
|
const existingChange = changeSetRedis.changes.find(
|
||||||
|
c => c.key === keyInfo.key && c.type === keyInfo.type
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!existingChange) return row;
|
||||||
|
|
||||||
|
// Pre hash - skontroluj či existuje update pre tento key
|
||||||
|
if (keyInfo.type === 'hash') {
|
||||||
|
// @ts-ignore
|
||||||
|
const update = existingChange.updates?.find(u => u.key === row.key);
|
||||||
|
if (update) {
|
||||||
|
return { ...row, value: update.value };
|
||||||
|
}
|
||||||
|
} else if (keyInfo.type === 'list') {
|
||||||
|
// @ts-ignore
|
||||||
|
const update = existingChange.updates?.find(u => u.index === row.rowNumber);
|
||||||
|
if (update) {
|
||||||
|
return { ...row, value: update.value };
|
||||||
|
}
|
||||||
|
} else if (keyInfo.type === 'zset') {
|
||||||
|
// @ts-ignore
|
||||||
|
const update = existingChange.updates?.find(u => u.member === row.member);
|
||||||
|
if (update) {
|
||||||
|
return { ...row, score: update.score };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDisplayValue(keyInfo) {
|
||||||
|
if (editedValue !== null) return editedValue;
|
||||||
|
|
||||||
|
const existingChange = changeSetRedis.changes.find(
|
||||||
|
c => c.key === keyInfo.key && c.type === keyInfo.type
|
||||||
|
);
|
||||||
|
|
||||||
|
if (existingChange && (keyInfo.type === 'string' || keyInfo.type === 'json')) {
|
||||||
|
// @ts-ignore
|
||||||
|
return existingChange.value || keyInfo.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return keyInfo.value;
|
||||||
|
}
|
||||||
|
|
||||||
function refresh() {
|
function refresh() {
|
||||||
editedValue = null;
|
editedValue = null;
|
||||||
refreshToken += 1;
|
refreshToken += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function saveAll() {
|
||||||
|
console.log('Saving all changes:', changeSetRedis);
|
||||||
|
await apiCall('database-connections/apply-redis-change-set', {
|
||||||
|
conid,
|
||||||
|
database,
|
||||||
|
changeSet: changeSetRedis,
|
||||||
|
});
|
||||||
|
changeSetRedis = { changes: [] };
|
||||||
|
refreshToken += 1;
|
||||||
|
}
|
||||||
|
|
||||||
async function saveString() {
|
async function saveString() {
|
||||||
await apiCall('database-connections/call-method', {
|
await apiCall('database-connections/call-method', {
|
||||||
conid,
|
conid,
|
||||||
@@ -125,13 +214,45 @@
|
|||||||
method: 'set',
|
method: 'set',
|
||||||
args: [key, editedValue],
|
args: [key, editedValue],
|
||||||
});
|
});
|
||||||
refresh();
|
|
||||||
|
editedValue = null;
|
||||||
|
refreshToken += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addItem(keyInfo) {
|
async function addItem(keyInfo) {
|
||||||
showModal(DbKeyAddItemModal, {
|
showModal(DbKeyAddItemModal, {
|
||||||
keyInfo,
|
keyInfo,
|
||||||
onConfirm: async row => {
|
onConfirm: async row => {
|
||||||
|
const existingChange = changeSetRedis.changes.find(
|
||||||
|
c => c.key === keyInfo.key && c.type === keyInfo.type
|
||||||
|
);
|
||||||
|
|
||||||
|
if (keyInfo.type === 'hash') {
|
||||||
|
// @ts-ignore
|
||||||
|
const hashChange = existingChange || { key: keyInfo.key, type: 'hash', inserts: [], updates: [], deletes: [] };
|
||||||
|
// @ts-ignore
|
||||||
|
hashChange.inserts = [...(hashChange.inserts || []), { key: row.key, value: row.value, ttl: keyInfo.ttl }];
|
||||||
|
addOrUpdateChange(hashChange);
|
||||||
|
} else if (keyInfo.type === 'list') {
|
||||||
|
// @ts-ignore
|
||||||
|
const listChange = existingChange || { key: keyInfo.key, type: 'list', inserts: [], updates: [], deletes: [] };
|
||||||
|
// @ts-ignore
|
||||||
|
listChange.inserts = [...(listChange.inserts || []), { index: row.rowNumber, value: row.value }];
|
||||||
|
addOrUpdateChange(listChange);
|
||||||
|
} else if (keyInfo.type === 'set') {
|
||||||
|
// @ts-ignore
|
||||||
|
const setChange = existingChange || { key: keyInfo.key, type: 'set', inserts: [], deletes: [] };
|
||||||
|
// @ts-ignore
|
||||||
|
setChange.inserts = [...(setChange.inserts || []), row.member];
|
||||||
|
addOrUpdateChange(setChange);
|
||||||
|
} else if (keyInfo.type === 'zset') {
|
||||||
|
// @ts-ignore
|
||||||
|
const zsetChange = existingChange || { key: keyInfo.key, type: 'zset', inserts: [], updates: [], deletes: [] };
|
||||||
|
// @ts-ignore
|
||||||
|
zsetChange.inserts = [...(zsetChange.inserts || []), { member: row.member, score: row.score }];
|
||||||
|
addOrUpdateChange(zsetChange);
|
||||||
|
}
|
||||||
|
|
||||||
const res = await apiCall('database-connections/call-method', {
|
const res = await apiCall('database-connections/call-method', {
|
||||||
conid,
|
conid,
|
||||||
database,
|
database,
|
||||||
@@ -142,7 +263,8 @@
|
|||||||
showModal(ErrorMessageModal, { message: res.errorMessage });
|
showModal(ErrorMessageModal, { message: res.errorMessage });
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
refresh();
|
|
||||||
|
refreshToken += 1;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -174,9 +296,11 @@
|
|||||||
{conid}
|
{conid}
|
||||||
{database}
|
{database}
|
||||||
{keyInfo}
|
{keyInfo}
|
||||||
|
{changeSetRedis}
|
||||||
onChangeSelected={row => {
|
onChangeSelected={row => {
|
||||||
currentRow = row;
|
currentRow = row;
|
||||||
}}
|
}}
|
||||||
|
modifyRow={row => getDisplayRow(row, keyInfo)}
|
||||||
/>
|
/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
<svelte:fragment slot="2">
|
<svelte:fragment slot="2">
|
||||||
@@ -184,7 +308,53 @@
|
|||||||
dbKeyFields={keyInfo.type === 'hash'
|
dbKeyFields={keyInfo.type === 'hash'
|
||||||
? keyInfo.keyType.dbKeyFields.filter(f => f.name === 'value')
|
? keyInfo.keyType.dbKeyFields.filter(f => f.name === 'value')
|
||||||
: keyInfo.keyType.dbKeyFields}
|
: keyInfo.keyType.dbKeyFields}
|
||||||
item={currentRow}
|
item={getDisplayRow(currentRow, keyInfo)}
|
||||||
|
onChangeItem={item => {
|
||||||
|
const existingChange = changeSetRedis.changes.find(
|
||||||
|
c => c.key === keyInfo.key && c.type === keyInfo.type
|
||||||
|
);
|
||||||
|
|
||||||
|
if (keyInfo.type === 'hash') {
|
||||||
|
// @ts-ignore
|
||||||
|
const hashChange = existingChange || { key: keyInfo.key, type: 'hash', inserts: [], updates: [], deletes: [] };
|
||||||
|
// @ts-ignore
|
||||||
|
const updateIndex = hashChange.updates?.findIndex(u => u.key === item.key) ?? -1;
|
||||||
|
if (updateIndex >= 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
hashChange.updates[updateIndex] = { key: item.key, value: item.value, ttl: keyInfo.ttl };
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
hashChange.updates = [...(hashChange.updates || []), { key: item.key, value: item.value, ttl: keyInfo.ttl }];
|
||||||
|
}
|
||||||
|
addOrUpdateChange(hashChange);
|
||||||
|
} else if (keyInfo.type === 'list') {
|
||||||
|
// @ts-ignore
|
||||||
|
const listChange = existingChange || { key: keyInfo.key, type: 'list', inserts: [], updates: [], deletes: [] };
|
||||||
|
// @ts-ignore
|
||||||
|
const updateIndex = listChange.updates?.findIndex(u => u.index === item.rowNumber) ?? -1;
|
||||||
|
if (updateIndex >= 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
listChange.updates[updateIndex] = { index: item.rowNumber, value: item.value };
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
listChange.updates = [...(listChange.updates || []), { index: item.rowNumber, value: item.value }];
|
||||||
|
}
|
||||||
|
addOrUpdateChange(listChange);
|
||||||
|
} else if (keyInfo.type === 'zset') {
|
||||||
|
// @ts-ignore
|
||||||
|
const zsetChange = existingChange || { key: keyInfo.key, type: 'zset', inserts: [], updates: [], deletes: [] };
|
||||||
|
// @ts-ignore
|
||||||
|
const updateIndex = zsetChange.updates?.findIndex(u => u.member === item.member) ?? -1;
|
||||||
|
if (updateIndex >= 0) {
|
||||||
|
// @ts-ignore
|
||||||
|
zsetChange.updates[updateIndex] = { member: item.member, score: item.score };
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
zsetChange.updates = [...(zsetChange.updates || []), { member: item.member, score: item.score }];
|
||||||
|
}
|
||||||
|
addOrUpdateChange(zsetChange);
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</svelte:fragment>
|
</svelte:fragment>
|
||||||
</VerticalSplitter>
|
</VerticalSplitter>
|
||||||
@@ -192,10 +362,24 @@
|
|||||||
<div class="value-holder">
|
<div class="value-holder">
|
||||||
<DbKeyValueDetail
|
<DbKeyValueDetail
|
||||||
columnTitle="Value"
|
columnTitle="Value"
|
||||||
value={editedValue || keyInfo.value}
|
value={getDisplayValue(keyInfo)}
|
||||||
keyType={keyInfo.type}
|
keyType={keyInfo.type}
|
||||||
onChangeValue={value => {
|
onChangeValue={value => {
|
||||||
editedValue = value;
|
editedValue = value;
|
||||||
|
|
||||||
|
if (keyInfo.type === 'string') {
|
||||||
|
addOrUpdateChange({
|
||||||
|
key: key,
|
||||||
|
type: 'string',
|
||||||
|
value: value,
|
||||||
|
});
|
||||||
|
} else if (keyInfo.type === 'json') {
|
||||||
|
addOrUpdateChange({
|
||||||
|
key: key,
|
||||||
|
type: 'json',
|
||||||
|
value: value,
|
||||||
|
});
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -204,6 +388,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<svelte:fragment slot="toolstrip">
|
<svelte:fragment slot="toolstrip">
|
||||||
|
<ToolStripButton
|
||||||
|
icon="icon save"
|
||||||
|
on:click={saveAll}
|
||||||
|
disabled={!hasChanges()}
|
||||||
|
>Save All Changes</ToolStripButton>
|
||||||
{#if keyInfo.type == 'string'}
|
{#if keyInfo.type == 'string'}
|
||||||
<ToolStripButton
|
<ToolStripButton
|
||||||
icon="icon save"
|
icon="icon save"
|
||||||
|
|||||||
Reference in New Issue
Block a user