Merge pull request #2256 from appwrite/fix-deletions

fix: bulk delete and sample data on tables with relationships
This commit is contained in:
Jake Barnby
2025-08-27 16:57:06 +12:00
committed by GitHub
4 changed files with 90 additions and 25 deletions
+8
View File
@@ -102,3 +102,11 @@ export function total(set: Array<number>): number {
if (!set) return 0;
return set.reduce((prev, curr) => prev + curr, 0);
}
export function chunks<T>(array: T[], size: number = 10): T[][] {
const output: T[][] = [];
for (let i = 0; i < array.length; i += size) {
output.push(array.slice(i, i + size));
}
return output;
}
@@ -60,6 +60,8 @@
import CreateIndex from './indexes/createIndex.svelte';
import { hash } from '$lib/helpers/string';
import { preferences } from '$lib/stores/preferences';
import { isRelationship } from './rows/store';
import { chunks } from '$lib/helpers/array';
let editRow: EditRow;
let editRelatedRow: EditRelatedRow;
@@ -249,6 +251,8 @@
$randomDataModalState.show = false;
let columns = $table.columns;
const hasAnyRelationships = columns.some((column) => isRelationship(column));
if (!columns.length) {
try {
columns = await generateColumns($project, page.params.database, page.params.table);
@@ -272,12 +276,32 @@
const { rows, ids } = generateFakeRecords(columns, $randomDataModalState.value);
rowIds = ids;
const tablesSDK = sdk.forProject(page.params.region, page.params.project).tablesDB;
await sdk.forProject(page.params.region, page.params.project).tablesDB.createRows({
databaseId: page.params.database,
tableId: page.params.table,
rows
});
if (hasAnyRelationships) {
for (const batch of chunks(rows)) {
try {
await Promise.all(
batch.map((row) =>
tablesSDK.createRow({
databaseId: page.params.database,
tableId: page.params.table,
rowId: row.$id,
data: row
})
)
);
} catch (error) {
// ignore, its sample data.
}
}
} else {
await tablesSDK.createRows({
databaseId: page.params.database,
tableId: page.params.table,
rows
});
}
addNotification({
type: 'success',
@@ -58,7 +58,7 @@
key: '$id',
type: 'string',
required: true,
name: 'ID',
name: '$id',
selectable: false,
system: true
} as Models.ColumnString & {
@@ -80,6 +80,7 @@
import { debounce } from '$lib/helpers/debounce';
import { hash } from '$lib/helpers/string';
import { abbreviateNumber } from '$lib/helpers/numbers';
import { chunks } from '$lib/helpers/array';
export let data: PageData;
export let showRowCreateSheet: {
@@ -337,6 +338,8 @@
async function handleDelete() {
showDelete = false;
let hadErrors = false;
try {
if (selectedRowForDelete) {
await sdk.forProject(page.params.region, page.params.project).tablesDB.deleteRow({
@@ -346,31 +349,61 @@
});
} else {
if (selectedRows.length) {
const batches: string[][] = [];
for (let i = 0; i < selectedRows.length; i += 100) {
batches.push(selectedRows.slice(i, i + 100));
}
await Promise.all(
batches.map((batch) =>
sdk
.forProject(page.params.region, page.params.project)
.tablesDB.deleteRows({
databaseId,
tableId,
queries: [Query.equal('$id', batch)]
})
)
const hasAnyRelationships = $table.columns.some((column) =>
isRelationship(column)
);
const tablesSDK = sdk.forProject(
page.params.region,
page.params.project
).tablesDB;
if (hasAnyRelationships) {
for (const batch of chunks(selectedRows)) {
try {
await Promise.all(
batch.map((rowId) =>
tablesSDK.deleteRow({
databaseId,
tableId,
rowId
})
)
);
} catch (e) {
hadErrors = true;
// ignore but keep proceeding!
}
}
if (hadErrors) {
addNotification({
type: 'error',
message: 'Some rows could not be deleted'
});
}
} else {
for (const batch of chunks(selectedRows, 100)) {
await tablesSDK.deleteRows({
databaseId,
tableId,
queries: [Query.equal('$id', batch)]
});
}
}
}
}
await invalidate(Dependencies.ROWS);
trackEvent(Submit.RowDelete);
addNotification({
type: 'success',
message: `${selectedRows.length ? selectedRows.length : 1} row${selectedRows.length > 1 ? 's' : ''} deleted`
});
if (!hadErrors) {
// error is already shown above!
addNotification({
type: 'success',
message: `${selectedRows.length ? selectedRows.length : 1} row${selectedRows.length > 1 ? 's' : ''} deleted`
});
}
spreadsheetRenderKey.set(
hash([