core: copy all note relations when duplicating

This commit is contained in:
Abdullah Atta
2024-05-15 14:18:20 +05:00
committed by Abdullah Atta
parent 1e6f6ab477
commit a0595a7d23
2 changed files with 60 additions and 34 deletions

View File

@@ -318,17 +318,9 @@ export class Notes implements ICollection {
const content = note.contentId
? await this.db.content.get(note.contentId)
: undefined;
if (content && (isDeleted(content) || content.locked))
throw new Error("Cannot duplicate a locked or deleted note.");
const duplicateId = await this.db.notes.add({
...clone(note),
id: undefined,
content: content
? {
type: content.type,
data: content.data
}
: undefined,
readonly: false,
favorite: false,
pinned: false,
@@ -338,19 +330,38 @@ export class Notes implements ICollection {
dateCreated: undefined,
dateModified: undefined
});
if (!duplicateId) continue;
for (const relation of await this.db.relations
.to(note, "notebook")
.get()) {
const contentId = await this.db.content.add({
...clone(content),
id: undefined,
noteId: duplicateId,
dateResolved: undefined,
dateEdited: undefined,
dateCreated: undefined,
dateModified: undefined
});
await this.db.notes.add({ id: duplicateId, contentId });
for (const relation of await this.db.relations.to(note).get()) {
await this.db.relations.add(
{ type: "notebook", id: relation.fromId },
{ type: relation.fromType, id: relation.fromId },
{
id: duplicateId,
type: "note"
}
);
}
for (const relation of await this.db.relations.from(note).get()) {
await this.db.relations.add(
{
id: duplicateId,
type: "note"
},
{ type: relation.toType, id: relation.toId }
);
}
}
}

View File

@@ -63,6 +63,9 @@ export class Relations implements ICollection {
});
}
from(
reference: ItemReference | ItemReferences
): RelationsArray<keyof RelatableTable>;
from(
reference: ItemReference | ItemReferences,
types: (keyof RelatableTable)[]
@@ -73,16 +76,19 @@ export class Relations implements ICollection {
): RelationsArray<TType>;
from<TType extends keyof RelatableTable = keyof RelatableTable>(
reference: ItemReference | ItemReferences,
type: TType | keyof RelatableTable[]
type?: TType | keyof RelatableTable[]
) {
return new RelationsArray(
this.db,
reference,
Array.isArray(type) ? type : [type],
type ? (Array.isArray(type) ? type : ([type] as TType[])) : undefined,
"from"
);
}
to(
reference: ItemReference | ItemReferences
): RelationsArray<keyof RelatableTable>;
to(
reference: ItemReference | ItemReferences,
types: (keyof RelatableTable)[]
@@ -93,12 +99,12 @@ export class Relations implements ICollection {
): RelationsArray<TType>;
to<TType extends keyof RelatableTable = keyof RelatableTable>(
reference: ItemReference | ItemReferences,
type: TType | keyof RelatableTable[]
type?: TType | keyof RelatableTable[]
) {
return new RelationsArray(
this.db,
reference,
Array.isArray(type) ? type : [type],
type ? (Array.isArray(type) ? type : ([type] as TType[])) : undefined,
"to"
);
}
@@ -224,21 +230,26 @@ const TABLE_MAP = {
type RelatableTable = typeof TABLE_MAP;
class RelationsArray<TType extends keyof RelatableTable> {
private table: ValueOf<RelatableTable> = TABLE_MAP[this.types[0]];
constructor(
private readonly db: Database,
private readonly reference: ItemReference | ItemReferences,
private readonly types: TType[],
private readonly types: TType[] | undefined,
private readonly direction: "from" | "to"
) {}
get selector() {
if (!this.types)
throw new Error("Cannot use selector when no tables are specified.");
if (this.types.length > 1)
throw new Error(
"Cannot use selector when more than 1 tables are specified."
);
const table: ValueOf<RelatableTable> = TABLE_MAP[this.types[0]];
return new FilteredSelector<ItemMap[TType]>(
this.table,
table,
this.db
.sql()
.selectFrom<keyof DatabaseSchema>(this.table)
.selectFrom<keyof DatabaseSchema>(table)
.where("id", "in", (b) =>
b
.selectFrom("relations")
@@ -356,10 +367,12 @@ class RelationsArray<TType extends keyof RelatableTable> {
) => {
if (this.direction === "to") {
return builder
.where(
"fromType",
this.types.length > 1 ? "in" : "==",
this.types.length > 1 ? this.types : this.types[0]
.$if(!!this.types, (eb) =>
eb.where(
"fromType",
this.types!.length > 1 ? "in" : "==",
this.types!.length > 1 ? this.types : this.types![0]
)
)
.where("toType", "==", this.reference.type)
.where(
@@ -370,12 +383,12 @@ class RelationsArray<TType extends keyof RelatableTable> {
: this.reference.id
)
.$if(
this.types.includes("note" as TType) &&
!!this.types?.includes("note" as TType) &&
this.db.trash.cache.notes.length > 0,
(b) => b.where("fromId", "not in", this.db.trash.cache.notes)
)
.$if(
this.types.includes("notebook" as TType) &&
!!this.types?.includes("notebook" as TType) &&
this.db.trash.cache.notebooks.length > 0,
(b) => b.where("fromId", "not in", this.db.trash.cache.notebooks)
)
@@ -383,10 +396,12 @@ class RelationsArray<TType extends keyof RelatableTable> {
.$narrowType<{ id: string }>();
} else {
return builder
.where(
"toType",
this.types.length > 1 ? "in" : "==",
this.types.length > 1 ? this.types : this.types[0]
.$if(!!this.types, (eb) =>
eb.where(
"toType",
this.types!.length > 1 ? "in" : "==",
this.types!.length > 1 ? this.types : this.types![0]
)
)
.where("fromType", "==", this.reference.type)
.where(
@@ -397,12 +412,12 @@ class RelationsArray<TType extends keyof RelatableTable> {
: this.reference.id
)
.$if(
this.types.includes("note" as TType) &&
!!this.types?.includes("note" as TType) &&
this.db.trash.cache.notes.length > 0,
(b) => b.where("toId", "not in", this.db.trash.cache.notes)
)
.$if(
this.types.includes("notebook" as TType) &&
!!this.types?.includes("notebook" as TType) &&
this.db.trash.cache.notebooks.length > 0,
(b) => b.where("toId", "not in", this.db.trash.cache.notebooks)
)