perf(db): index every foreign-key column

86 foreign-key columns had no index. SQLite does not add one by itself,
so every cascading delete of a trip or a user scanned each such child
table in full, inside the transaction, while every other request waited
on the one connection. One migration adds them all, and the entities are
regenerated to match.
This commit is contained in:
Maurice
2026-10-07 16:56:58 +02:00
parent 1a4df59bf3
commit 48f9e7d132
62 changed files with 276 additions and 170 deletions
@@ -20,7 +20,7 @@ export const AssignmentParticipantsSchema = defineEntity({
id: p.integer().primary(),
assignment: () => p.manyToOne(DayAssignments).ref().deleteRule('cascade').hidden().index('idx_assignment_participants_assignment'),
assignment_id: p.integer().persist(false).index('idx_assignment_participants_assignment'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_assignment_participants_user_id'),
user_id: p.integer().persist(false).index('idx_assignment_participants_user_id'),
},
});
+2 -2
View File
@@ -21,8 +21,8 @@ export const AuditLogSchema = defineEntity({
properties: {
id: p.integer().primary(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`).index('idx_audit_log_created'),
user: () => p.manyToOne(Users).ref().nullable().hidden(),
user_id: p.integer().nullable().persist(false),
user: () => p.manyToOne(Users).ref().nullable().hidden().index('idx_audit_log_user_id'),
user_id: p.integer().nullable().persist(false).index('idx_audit_log_user_id'),
action: p.text(),
resource: p.text().nullable(),
details: p.text().nullable(),
+2 -2
View File
@@ -28,8 +28,8 @@ export const BucketListSchema = defineEntity({
repository: () => BucketListRepository,
properties: {
id: p.integer().primary(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_bucket_list_user_id'),
user_id: p.integer().persist(false).index('idx_bucket_list_user_id'),
name: p.text(),
lat: p.double().nullable(),
lng: p.double().nullable(),
@@ -21,8 +21,8 @@ export const BudgetItemPayersSchema = defineEntity({
id: p.integer().primary(),
budgetItem: () => p.manyToOne(BudgetItems).ref().deleteRule('cascade').hidden().index('idx_budget_item_payers_item'),
budget_item_id: p.integer().persist(false).index('idx_budget_item_payers_item'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_budget_item_payers_user_id'),
user_id: p.integer().persist(false).index('idx_budget_item_payers_user_id'),
amount: p.double().defaultRaw(`0`),
},
});
+6 -6
View File
@@ -52,16 +52,16 @@ export const BudgetItemsSchema = defineEntity({
note: p.text().nullable(),
sort_order: p.integer().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
paidByUser: () => p.manyToOne(Users).ref().deleteRule('no action').nullable().hidden(),
paid_by_user_id: p.integer().nullable().persist(false),
paidByUser: () => p.manyToOne(Users).ref().deleteRule('no action').nullable().hidden().index('idx_budget_items_paid_by_user_id'),
paid_by_user_id: p.integer().nullable().persist(false).index('idx_budget_items_paid_by_user_id'),
expense_date: p.text().nullable().defaultRaw(`NULL`),
reservation: () => p.manyToOne(Reservations).ref().nullable().hidden().defaultRaw(`NULL`),
reservation_id: p.integer().nullable().persist(false).defaultRaw(`NULL`),
reservation: () => p.manyToOne(Reservations).ref().nullable().hidden().defaultRaw(`NULL`).index('idx_budget_items_reservation_id'),
reservation_id: p.integer().nullable().persist(false).defaultRaw(`NULL`).index('idx_budget_items_reservation_id'),
currency: p.text().nullable(),
exchange_rate: p.double().defaultRaw(`1`),
ticket_json: p.text().nullable(),
place: () => p.manyToOne(Places).ref().nullable().hidden().defaultRaw(`NULL`),
place_id: p.integer().nullable().persist(false).defaultRaw(`NULL`),
place: () => p.manyToOne(Places).ref().nullable().hidden().defaultRaw(`NULL`).index('idx_budget_items_place_id'),
place_id: p.integer().nullable().persist(false).defaultRaw(`NULL`).index('idx_budget_items_place_id'),
budget_item_members_collection: () => p.oneToMany(BudgetItemMembers).mappedBy('budgetItem').hidden(),
budget_item_payers_collection: () => p.oneToMany(BudgetItemPayers).mappedBy('budgetItem').hidden(),
file_links_collection: () => p.oneToMany(FileLinks).mappedBy('budgetItem').hidden(),
@@ -30,14 +30,14 @@ export const BudgetSettlementsSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_budget_settlements_trip'),
trip_id: p.integer().persist(false).index('idx_budget_settlements_trip'),
fromUser: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
from_user_id: p.integer().persist(false),
toUser: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
to_user_id: p.integer().persist(false),
fromUser: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_budget_settlements_from_user_id'),
from_user_id: p.integer().persist(false).index('idx_budget_settlements_from_user_id'),
toUser: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_budget_settlements_to_user_id'),
to_user_id: p.integer().persist(false).index('idx_budget_settlements_to_user_id'),
amount: p.double().defaultRaw(`0`),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
createdByUser: () => p.manyToOne(Users).ref().deleteRule('no action').nullable().hidden(),
created_by_user_id: p.integer().nullable().persist(false),
createdByUser: () => p.manyToOne(Users).ref().deleteRule('no action').nullable().hidden().index('idx_budget_settlements_created_by_user_id'),
created_by_user_id: p.integer().nullable().persist(false).index('idx_budget_settlements_created_by_user_id'),
currency: p.text().nullable(),
exchange_rate: p.double().defaultRaw(`1`),
settled_at: p.text().nullable(),
+2 -2
View File
@@ -26,8 +26,8 @@ export const CategoriesSchema = defineEntity({
name: p.text(),
color: p.text().nullable(),
icon: p.text().nullable(),
user: () => p.manyToOne(Users).ref().nullable().hidden(),
user_id: p.integer().nullable().persist(false),
user: () => p.manyToOne(Users).ref().nullable().hidden().index('idx_categories_user_id'),
user_id: p.integer().nullable().persist(false).index('idx_categories_user_id'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
collection_places_collection: () => p.oneToMany(CollectionPlaces).mappedBy('category').hidden(),
places_collection: () => p.oneToMany(Places).mappedBy('category').hidden(),
+2 -2
View File
@@ -25,8 +25,8 @@ export const CollabLinksSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_collab_links_trip'),
trip_id: p.integer().persist(false).index('idx_collab_links_trip'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collab_links_user_id'),
user_id: p.integer().persist(false).index('idx_collab_links_user_id'),
title: p.text(),
url: p.text(),
pinned: p.integer().nullable(),
@@ -23,8 +23,8 @@ export const CollabMessageReactionsSchema = defineEntity({
id: p.integer().primary(),
message: () => p.manyToOne(CollabMessages).ref().deleteRule('cascade').hidden().index('idx_collab_reactions_msg'),
message_id: p.integer().persist(false).index('idx_collab_reactions_msg'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collab_message_reactions_user_id'),
user_id: p.integer().persist(false).index('idx_collab_message_reactions_user_id'),
emoji: p.text(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
@@ -30,13 +30,13 @@ export const CollabMessagesSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_collab_messages_trip'),
trip_id: p.integer().persist(false).index('idx_collab_messages_trip'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collab_messages_user_id'),
user_id: p.integer().persist(false).index('idx_collab_messages_user_id'),
text: p.text(),
reply_to: p.integer().nullable().persist(false),
reply_to: p.integer().nullable().persist(false).index('idx_collab_messages_reply_to'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
deleted: p.integer().nullable(),
replyToRef: () => p.manyToOne(CollabMessages).ref().joinColumn('reply_to').nullable().hidden(),
replyToRef: () => p.manyToOne(CollabMessages).ref().joinColumn('reply_to').nullable().hidden().index('idx_collab_messages_reply_to'),
collab_message_reactions_collection: () => p.oneToMany(CollabMessageReactions).mappedBy('message').hidden(),
collab_messages_collection: () => p.oneToMany(CollabMessages).mappedBy('replyToRef').hidden(),
trip_files_collection: () => p.oneToMany(TripFiles).mappedBy('message').hidden(),
+2 -2
View File
@@ -30,8 +30,8 @@ export const CollabNotesSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_collab_notes_trip'),
trip_id: p.integer().persist(false).index('idx_collab_notes_trip'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collab_notes_user_id'),
user_id: p.integer().persist(false).index('idx_collab_notes_user_id'),
category: p.text().nullable(),
title: p.text(),
content: p.text().nullable(),
@@ -23,8 +23,8 @@ export const CollabPollVotesSchema = defineEntity({
id: p.integer().primary(),
poll: () => p.manyToOne(CollabPolls).ref().deleteRule('cascade').hidden(),
poll_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collab_poll_votes_user_id'),
user_id: p.integer().persist(false).index('idx_collab_poll_votes_user_id'),
option_index: p.integer(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
+2 -2
View File
@@ -28,8 +28,8 @@ export const CollabPollsSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_collab_polls_trip'),
trip_id: p.integer().persist(false).index('idx_collab_polls_trip'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collab_polls_user_id'),
user_id: p.integer().persist(false).index('idx_collab_polls_user_id'),
question: p.text(),
options: p.text(),
multiple: p.integer().nullable(),
@@ -23,8 +23,8 @@ export const CollectionPlaceRatingsSchema = defineEntity({
id: p.integer().primary(),
collectionPlace: () => p.manyToOne(CollectionPlaces).ref().deleteRule('cascade').hidden().index('idx_collection_place_ratings_place'),
collection_place_id: p.integer().persist(false).index('idx_collection_place_ratings_place'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collection_place_ratings_user_id'),
user_id: p.integer().persist(false).index('idx_collection_place_ratings_user_id'),
rating: p.integer(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
@@ -52,16 +52,16 @@ export const CollectionPlacesSchema = defineEntity({
id: p.integer().primary(),
collection: () => p.manyToOne(Collections).ref().deleteRule('cascade').hidden().index('idx_collection_places_collection'),
collection_id: p.integer().persist(false).index('idx_collection_places_collection'),
owner: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
owner_id: p.integer().persist(false),
saved_by: p.integer().nullable().persist(false),
owner: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collection_places_owner_id'),
owner_id: p.integer().persist(false).index('idx_collection_places_owner_id'),
saved_by: p.integer().nullable().persist(false).index('idx_collection_places_saved_by'),
name: p.text(),
description: p.text().nullable(),
lat: p.double().nullable(),
lng: p.double().nullable(),
address: p.text().nullable(),
category: () => p.manyToOne(Categories).ref().nullable().hidden(),
category_id: p.integer().nullable().persist(false),
category: () => p.manyToOne(Categories).ref().nullable().hidden().index('idx_collection_places_category_id'),
category_id: p.integer().nullable().persist(false).index('idx_collection_places_category_id'),
price: p.double().nullable(),
currency: p.text().nullable(),
notes: p.text().nullable(),
@@ -78,7 +78,7 @@ export const CollectionPlacesSchema = defineEntity({
sort_order: p.integer().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
updated_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
savedByRef: () => p.manyToOne(Users).ref().joinColumn('saved_by').nullable().hidden(),
savedByRef: () => p.manyToOne(Users).ref().joinColumn('saved_by').nullable().hidden().index('idx_collection_places_saved_by'),
collection_place_labels: () => p.manyToMany(CollectionLabels).pivotTable('collection_place_labels').joinColumn('collection_place_id').inverseJoinColumn('label_id').hidden(),
collection_place_tags: () => p.manyToMany(Tags).pivotTable('collection_place_tags').joinColumn('collection_place_id').inverseJoinColumn('tag_id').hidden(),
collection_place_ratings_collection: () => p.oneToMany(CollectionPlaceRatings).mappedBy('collectionPlace').hidden(),
+2 -2
View File
@@ -30,8 +30,8 @@ export const CollectionsSchema = defineEntity({
repository: () => CollectionsRepository,
properties: {
id: p.integer().primary(),
owner: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
owner_id: p.integer().persist(false),
owner: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_collections_owner_id'),
owner_id: p.integer().persist(false).index('idx_collections_owner_id'),
name: p.text(),
description: p.text().nullable(),
color: p.text().nullable(),
@@ -70,13 +70,13 @@ export const DawarichVisitSuggestionsSchema = defineEntity({
country_code: p.text().nullable(),
state: p.text().default('new'),
target: p.text().nullable(),
acceptedPlace: () => p.manyToOne(Places).ref().nullable().hidden(),
accepted_place_id: p.integer().nullable().persist(false),
acceptedPlace: () => p.manyToOne(Places).ref().nullable().hidden().index('idx_dawarich_visit_suggestions_accepted_place_id'),
accepted_place_id: p.integer().nullable().persist(false).index('idx_dawarich_visit_suggestions_accepted_place_id'),
accepted_journal_entry_id: p.integer().nullable(),
acceptedBucketListItem: () => p.manyToOne(BucketList).ref().nullable().hidden(),
accepted_bucket_list_item_id: p.integer().nullable().persist(false),
matchedBucketListItem: () => p.manyToOne(BucketList).ref().nullable().hidden(),
matched_bucket_list_item_id: p.integer().nullable().persist(false),
acceptedBucketListItem: () => p.manyToOne(BucketList).ref().nullable().hidden().index('idx_dawarich_visit_suggestions_accepted_bucket_list_item_id'),
accepted_bucket_list_item_id: p.integer().nullable().persist(false).index('idx_dawarich_visit_suggestions_accepted_bucket_list_item_id'),
matchedBucketListItem: () => p.manyToOne(BucketList).ref().nullable().hidden().index('idx_dawarich_visit_suggestions_matched_bucket_list_item_id'),
matched_bucket_list_item_id: p.integer().nullable().persist(false).index('idx_dawarich_visit_suggestions_matched_bucket_list_item_id'),
source_hash: p.text(),
accepted_hash: p.text().nullable(),
source_missing_at: p.text().nullable(),
@@ -31,8 +31,8 @@ export const DayAccommodationsSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_day_accommodations_trip_id'),
trip_id: p.integer().persist(false).index('idx_day_accommodations_trip_id'),
place: () => p.manyToOne(Places).ref().nullable().hidden(),
place_id: p.integer().nullable().persist(false),
place: () => p.manyToOne(Places).ref().nullable().hidden().index('idx_day_accommodations_place_id'),
place_id: p.integer().nullable().persist(false).index('idx_day_accommodations_place_id'),
startDay: () => p.manyToOne(Days).ref().deleteRule('cascade').hidden().index('idx_day_accommodations_start_day_id'),
start_day_id: p.integer().persist(false).index('idx_day_accommodations_start_day_id'),
endDay: () => p.manyToOne(Days).ref().deleteRule('cascade').hidden().index('idx_day_accommodations_end_day_id'),
+2 -2
View File
@@ -26,8 +26,8 @@ export const DayNotesSchema = defineEntity({
id: p.integer().primary(),
day: () => p.manyToOne(Days).ref().deleteRule('cascade').hidden().index('idx_day_notes_day_id'),
day_id: p.integer().persist(false).index('idx_day_notes_day_id'),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_day_notes_trip_id'),
trip_id: p.integer().persist(false).index('idx_day_notes_trip_id'),
text: p.text(),
time: p.text().nullable(),
icon: p.text().nullable(),
@@ -36,8 +36,8 @@ export const DocumentConnectionsSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_document_connections_trip'),
trip_id: p.integer().persist(false).index('idx_document_connections_trip'),
provider: () => p.manyToOne(DocumentProviders).ref().deleteRule('cascade').hidden(),
provider_id: p.text().persist(false),
provider: () => p.manyToOne(DocumentProviders).ref().deleteRule('cascade').hidden().index('idx_document_connections_provider_id'),
provider_id: p.text().persist(false).index('idx_document_connections_provider_id'),
ownerUser: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_document_connections_owner'),
owner_user_id: p.integer().persist(false).index('idx_document_connections_owner'),
base_url: p.text(),
@@ -71,8 +71,8 @@ export const DocumentSyncItemsSchema = defineEntity({
link_id: p.integer().persist(false),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
file: () => p.manyToOne(TripFiles).ref().nullable().hidden(),
file_id: p.integer().nullable().persist(false),
file: () => p.manyToOne(TripFiles).ref().nullable().hidden().index('idx_document_sync_items_file_id'),
file_id: p.integer().nullable().persist(false).index('idx_document_sync_items_file_id'),
trek_doc_uid: p.text(),
remote_id: p.text().nullable(),
remote_name: p.text().nullable(),
+6 -6
View File
@@ -39,12 +39,12 @@ export const FileLinksSchema = defineEntity({
id: p.integer().primary(),
file: () => p.manyToOne(TripFiles).ref().deleteRule('cascade').hidden(),
file_id: p.integer().persist(false),
reservation: () => p.manyToOne(Reservations).ref().deleteRule('cascade').nullable().hidden(),
reservation_id: p.integer().nullable().persist(false),
assignment: () => p.manyToOne(DayAssignments).ref().deleteRule('cascade').nullable().hidden(),
assignment_id: p.integer().nullable().persist(false),
place: () => p.manyToOne(Places).ref().deleteRule('cascade').nullable().hidden(),
place_id: p.integer().nullable().persist(false),
reservation: () => p.manyToOne(Reservations).ref().deleteRule('cascade').nullable().hidden().index('idx_file_links_reservation_id'),
reservation_id: p.integer().nullable().persist(false).index('idx_file_links_reservation_id'),
assignment: () => p.manyToOne(DayAssignments).ref().deleteRule('cascade').nullable().hidden().index('idx_file_links_assignment_id'),
assignment_id: p.integer().nullable().persist(false).index('idx_file_links_assignment_id'),
place: () => p.manyToOne(Places).ref().deleteRule('cascade').nullable().hidden().index('idx_file_links_place_id'),
place_id: p.integer().nullable().persist(false).index('idx_file_links_place_id'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
budgetItem: () => p.manyToOne(BudgetItems).ref().nullable().hidden().index('idx_file_links_budget_item_id'),
budget_item_id: p.integer().nullable().persist(false).index('idx_file_links_budget_item_id'),
@@ -21,8 +21,8 @@ export const IdempotencyKeysSchema = defineEntity({
uniques: [{ properties: ['key', 'user', 'method', 'path'] }],
properties: {
key: p.text().primary(),
user: () => p.manyToOne(Users).primary().ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).primary().ref().deleteRule('cascade').hidden().index('idx_idempotency_keys_user_id'),
user_id: p.integer().persist(false).index('idx_idempotency_keys_user_id'),
method: p.text().primary(),
path: p.text().primary(),
status_code: p.integer(),
@@ -28,10 +28,10 @@ export const InviteTokensSchema = defineEntity({
max_uses: p.integer().default(1),
used_count: p.integer().default(0),
expires_at: p.text().nullable(),
created_by: p.integer().persist(false),
created_by: p.integer().persist(false).index('idx_invite_tokens_created_by'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
trip: () => p.manyToOne(Trips).ref().nullable().hidden(),
trip_id: p.integer().nullable().persist(false),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').deleteRule('cascade').hidden(),
trip: () => p.manyToOne(Trips).ref().nullable().hidden().index('idx_invite_tokens_trip_id'),
trip_id: p.integer().nullable().persist(false).index('idx_invite_tokens_trip_id'),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').deleteRule('cascade').hidden().index('idx_invite_tokens_created_by'),
},
});
@@ -30,11 +30,11 @@ export const JourneyBooksSchema = defineEntity({
title: p.text().default(''),
document: p.text(),
version: p.integer().default(1),
created_by: p.integer().nullable().persist(false),
updated_by: p.integer().nullable().persist(false),
created_by: p.integer().nullable().persist(false).index('idx_journey_books_created_by'),
updated_by: p.integer().nullable().persist(false).index('idx_journey_books_updated_by'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
updated_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
updatedByRef: () => p.manyToOne(Users).ref().joinColumn('updated_by').nullable().hidden(),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').nullable().hidden(),
updatedByRef: () => p.manyToOne(Users).ref().joinColumn('updated_by').nullable().hidden().index('idx_journey_books_updated_by'),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').nullable().hidden().index('idx_journey_books_created_by'),
},
});
@@ -62,12 +62,12 @@ export const JourneyEntriesSchema = defineEntity({
id: p.integer().primary(),
journey: () => p.manyToOne(Journeys).ref().deleteRule('cascade').hidden(),
journey_id: p.integer().persist(false),
sourceTrip: () => p.manyToOne(Trips).ref().nullable().hidden(),
source_trip_id: p.integer().nullable().persist(false),
sourceTrip: () => p.manyToOne(Trips).ref().nullable().hidden().index('idx_journey_entries_source_trip_id'),
source_trip_id: p.integer().nullable().persist(false).index('idx_journey_entries_source_trip_id'),
sourcePlace: () => p.manyToOne(Places).ref().nullable().hidden().index('idx_journey_entries_source'),
source_place_id: p.integer().nullable().persist(false).index('idx_journey_entries_source'),
author: () => p.manyToOne(Users).ref().hidden(),
author_id: p.integer().persist(false),
author: () => p.manyToOne(Users).ref().hidden().index('idx_journey_entries_author_id'),
author_id: p.integer().persist(false).index('idx_journey_entries_author_id'),
type: p.text(),
title: p.text().nullable(),
story: p.text().nullable(),
@@ -29,8 +29,8 @@ export const JourneyPhotosSchema = defineEntity({
id: p.integer().primary(),
journey: () => p.manyToOne(Journeys).ref().deleteRule('cascade').hidden().index('idx_journey_photos_journey'),
journey_id: p.integer().persist(false).index('idx_journey_photos_journey'),
photo: () => p.manyToOne(TrekPhotos).ref().deleteRule('cascade').hidden(),
photo_id: p.integer().persist(false),
photo: () => p.manyToOne(TrekPhotos).ref().deleteRule('cascade').hidden().index('idx_journey_photos_photo_id'),
photo_id: p.integer().persist(false).index('idx_journey_photos_photo_id'),
caption: p.text().nullable(),
shared: p.integer().nullable(),
sort_order: p.integer().nullable(),
@@ -28,12 +28,12 @@ export const JourneyShareTokensSchema = defineEntity({
journey: () => p.oneToOne(Journeys).ref().deleteRule('cascade').hidden().unique('idx_journey_share_journey'),
journey_id: p.integer().persist(false).unique('idx_journey_share_journey'),
token: p.text(),
created_by: p.integer().persist(false),
created_by: p.integer().persist(false).index('idx_journey_share_tokens_created_by'),
share_timeline: p.integer().nullable(),
share_gallery: p.integer().nullable(),
share_map: p.integer().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
newest_first: p.integer().default(0),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').hidden(),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').hidden().index('idx_journey_share_tokens_created_by'),
},
});
@@ -20,8 +20,8 @@ export const JourneyTripsSchema = defineEntity({
properties: {
journey: () => p.manyToOne(Journeys).primary().ref().hidden().index('idx_journey_trips_journey'),
journey_id: p.integer().persist(false).index('idx_journey_trips_journey'),
trip: () => p.manyToOne(Trips).primary().ref().hidden(),
trip_id: p.integer().persist(false),
trip: () => p.manyToOne(Trips).primary().ref().hidden().index('idx_journey_trips_trip_id'),
trip_id: p.integer().persist(false).index('idx_journey_trips_trip_id'),
added_at: p.integer(),
},
});
+2 -2
View File
@@ -23,8 +23,8 @@ export const McpTokensSchema = defineEntity({
repository: () => McpTokensRepository,
properties: {
id: p.integer().primary(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_mcp_tokens_user_id'),
user_id: p.integer().persist(false).index('idx_mcp_tokens_user_id'),
name: p.text(),
token_hash: p.text().unique('idx_mcp_tokens_hash'),
token_prefix: p.text(),
@@ -47,8 +47,8 @@ export const NotificationsSchema = defineEntity({
type: p.text(),
scope: p.text(),
target: p.integer(),
sender: () => p.manyToOne(Users).ref().nullable().hidden(),
sender_id: p.integer().nullable().persist(false),
sender: () => p.manyToOne(Users).ref().nullable().hidden().index('idx_notifications_sender_id'),
sender_id: p.integer().nullable().persist(false).index('idx_notifications_sender_id'),
recipient: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
recipient_id: p.integer().persist(false),
title_key: p.text(),
@@ -23,8 +23,8 @@ export const OauthConsentsSchema = defineEntity({
id: p.integer().primary(),
client: () => p.manyToOne(OauthClients).ref().name('client_id').deleteRule('cascade').hidden().referencedColumnNames('client_id'),
client_id: p.text().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_oauth_consents_user_id'),
user_id: p.integer().persist(false).index('idx_oauth_consents_user_id'),
scopes: p.text().default('[]'),
updated_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
+2 -2
View File
@@ -33,8 +33,8 @@ export const OauthTokensSchema = defineEntity({
],
properties: {
id: p.integer().primary(),
client: () => p.manyToOne(OauthClients).ref().name('client_id').deleteRule('cascade').hidden().referencedColumnNames('client_id'),
client_id: p.text().persist(false),
client: () => p.manyToOne(OauthClients).ref().name('client_id').deleteRule('cascade').hidden().index('idx_oauth_tokens_client_id').referencedColumnNames('client_id'),
client_id: p.text().persist(false).index('idx_oauth_tokens_client_id'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_oauth_tokens_user'),
user_id: p.integer().persist(false).index('idx_oauth_tokens_user'),
access_token_hash: p.text().unique('idx_oauth_tokens_access'),
+4 -4
View File
@@ -26,15 +26,15 @@ export const PackingBagsSchema = defineEntity({
repository: () => PackingBagsRepository,
properties: {
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_packing_bags_trip_id'),
trip_id: p.integer().persist(false).index('idx_packing_bags_trip_id'),
name: p.text(),
color: p.text().default('#6366f1'),
weight_limit_grams: p.integer().nullable(),
sort_order: p.integer().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
user: () => p.manyToOne(Users).ref().nullable().hidden().defaultRaw(`NULL`),
user_id: p.integer().nullable().persist(false).defaultRaw(`NULL`),
user: () => p.manyToOne(Users).ref().nullable().hidden().defaultRaw(`NULL`).index('idx_packing_bags_user_id'),
user_id: p.integer().nullable().persist(false).defaultRaw(`NULL`).index('idx_packing_bags_user_id'),
packing_bag_members: () => p.manyToMany(Users).pivotTable('packing_bag_members').joinColumn('bag_id').inverseJoinColumn('user_id').hidden(),
packing_items_collection: () => p.oneToMany(PackingItems).mappedBy('bag').hidden(),
},
@@ -22,7 +22,7 @@ export const PackingCategoryAssigneesSchema = defineEntity({
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
category_name: p.text(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_packing_category_assignees_user_id'),
user_id: p.integer().persist(false).index('idx_packing_category_assignees_user_id'),
},
});
@@ -22,8 +22,8 @@ export const PackingItemContributorsSchema = defineEntity({
properties: {
item: () => p.manyToOne(PackingItems).primary().ref().hidden(),
item_id: p.integer().persist(false),
user: () => p.manyToOne(Users).primary().ref().hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).primary().ref().hidden().index('idx_packing_item_contributors_user_id'),
user_id: p.integer().persist(false).index('idx_packing_item_contributors_user_id'),
status: p.text().default('accepted'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
@@ -43,13 +43,13 @@ export const PackingItemsSchema = defineEntity({
sort_order: p.integer().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
weight_grams: p.integer().nullable(),
bag: () => p.manyToOne(PackingBags).ref().nullable().hidden(),
bag_id: p.integer().nullable().persist(false),
bag: () => p.manyToOne(PackingBags).ref().nullable().hidden().index('idx_packing_items_bag_id'),
bag_id: p.integer().nullable().persist(false).index('idx_packing_items_bag_id'),
quantity: p.integer().default(1),
updated_at: p.type(DbTimestampType).nullable(),
is_private: p.integer().default(0),
owner: () => p.manyToOne(Users).ref().nullable().hidden(),
owner_id: p.integer().nullable().persist(false),
owner: () => p.manyToOne(Users).ref().nullable().hidden().index('idx_packing_items_owner_id'),
owner_id: p.integer().nullable().persist(false).index('idx_packing_items_owner_id'),
packed_quantity: p.integer().nullable(),
packing_item_contributors: () => p.manyToMany(Users).pivotTable('packing_item_contributors').pivotEntity(() => PackingItemContributors).joinColumn('item_id').inverseJoinColumn('user_id').hidden(),
packing_item_recipients: () => p.manyToMany(Users).pivotTable('packing_item_recipients').joinColumn('item_id').inverseJoinColumn('user_id').hidden(),
@@ -18,8 +18,8 @@ export const PackingTemplateCategoriesSchema = defineEntity({
repository: () => PackingTemplateCategoriesRepository,
properties: {
id: p.integer().primary(),
template: () => p.manyToOne(PackingTemplates).ref().deleteRule('cascade').hidden(),
template_id: p.integer().persist(false),
template: () => p.manyToOne(PackingTemplates).ref().deleteRule('cascade').hidden().index('idx_packing_template_categories_template_id'),
template_id: p.integer().persist(false).index('idx_packing_template_categories_template_id'),
name: p.text(),
sort_order: p.integer().default(0),
packing_template_items_collection: () => p.oneToMany(PackingTemplateItems).mappedBy('category').hidden(),
@@ -19,8 +19,8 @@ export const PackingTemplateItemsSchema = defineEntity({
repository: () => PackingTemplateItemsRepository,
properties: {
id: p.integer().primary(),
category: () => p.manyToOne(PackingTemplateCategories).ref().deleteRule('cascade').hidden(),
category_id: p.integer().persist(false),
category: () => p.manyToOne(PackingTemplateCategories).ref().deleteRule('cascade').hidden().index('idx_packing_template_items_category_id'),
category_id: p.integer().persist(false).index('idx_packing_template_items_category_id'),
name: p.text(),
sort_order: p.integer().default(0),
weight_grams: p.integer().nullable(),
@@ -20,9 +20,9 @@ export const PackingTemplatesSchema = defineEntity({
properties: {
id: p.integer().primary(),
name: p.text(),
created_by: p.integer().persist(false),
created_by: p.integer().persist(false).index('idx_packing_templates_created_by'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').deleteRule('cascade').hidden(),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').deleteRule('cascade').hidden().index('idx_packing_templates_created_by'),
packing_template_categories_collection: () => p.oneToMany(PackingTemplateCategories).mappedBy('template').hidden(),
},
});
@@ -23,8 +23,8 @@ export const PlaceRatingsSchema = defineEntity({
id: p.integer().primary(),
place: () => p.manyToOne(Places).ref().deleteRule('cascade').hidden().index('idx_place_ratings_place'),
place_id: p.integer().persist(false).index('idx_place_ratings_place'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_place_ratings_user_id'),
user_id: p.integer().persist(false).index('idx_place_ratings_user_id'),
rating: p.integer(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
@@ -20,8 +20,8 @@ export const ReservationDayPositionsSchema = defineEntity({
properties: {
reservation: () => p.manyToOne(Reservations).primary().ref().hidden(),
reservation_id: p.integer().persist(false),
day: () => p.manyToOne(Days).primary().ref().hidden(),
day_id: p.integer().persist(false),
day: () => p.manyToOne(Days).primary().ref().hidden().index('idx_reservation_day_positions_day_id'),
day_id: p.integer().persist(false).index('idx_reservation_day_positions_day_id'),
position: p.double(),
},
});
@@ -69,12 +69,12 @@ export const ReservationsSchema = defineEntity({
trip_id: p.integer().persist(false).index('idx_reservations_trip_id'),
day: () => p.manyToOne(Days).ref().nullable().hidden().index('idx_reservations_day_id'),
day_id: p.integer().nullable().persist(false).index('idx_reservations_day_id'),
endDay: () => p.manyToOne(Days).ref().nullable().hidden(),
end_day_id: p.integer().nullable().persist(false),
place: () => p.manyToOne(Places).ref().nullable().hidden(),
place_id: p.integer().nullable().persist(false),
assignment: () => p.manyToOne(DayAssignments).ref().nullable().hidden(),
assignment_id: p.integer().nullable().persist(false),
endDay: () => p.manyToOne(Days).ref().nullable().hidden().index('idx_reservations_end_day_id'),
end_day_id: p.integer().nullable().persist(false).index('idx_reservations_end_day_id'),
place: () => p.manyToOne(Places).ref().nullable().hidden().index('idx_reservations_place_id'),
place_id: p.integer().nullable().persist(false).index('idx_reservations_place_id'),
assignment: () => p.manyToOne(DayAssignments).ref().nullable().hidden().index('idx_reservations_assignment_id'),
assignment_id: p.integer().nullable().persist(false).index('idx_reservations_assignment_id'),
title: p.text(),
accommodation_id: p.text().nullable(),
reservation_time: p.text().nullable(),
@@ -34,10 +34,10 @@ export const RoadtripDayBoundariesSchema = defineEntity({
trip: () => p.manyToOne(Trips).primary().ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
day_number: p.integer().primary(),
fromAssignment: () => p.manyToOne(DayAssignments).ref().deleteRule('cascade').hidden(),
from_assignment_id: p.integer().persist(false),
toAssignment: () => p.manyToOne(DayAssignments).ref().deleteRule('cascade').nullable().hidden(),
to_assignment_id: p.integer().nullable().persist(false),
fromAssignment: () => p.manyToOne(DayAssignments).ref().deleteRule('cascade').hidden().index('idx_roadtrip_day_boundaries_from_assignment_id'),
from_assignment_id: p.integer().persist(false).index('idx_roadtrip_day_boundaries_from_assignment_id'),
toAssignment: () => p.manyToOne(DayAssignments).ref().deleteRule('cascade').nullable().hidden().index('idx_roadtrip_day_boundaries_to_assignment_id'),
to_assignment_id: p.integer().nullable().persist(false).index('idx_roadtrip_day_boundaries_to_assignment_id'),
fraction: p.double(),
},
});
+4 -4
View File
@@ -29,10 +29,10 @@ export const ShareTokensSchema = defineEntity({
uniques: [{ properties: ['token'] }],
properties: {
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_share_tokens_trip_id'),
trip_id: p.integer().persist(false).index('idx_share_tokens_trip_id'),
token: p.text().index('idx_share_tokens_token'),
created_by: p.integer().persist(false),
created_by: p.integer().persist(false).index('idx_share_tokens_created_by'),
share_map: p.integer().nullable(),
share_bookings: p.integer().nullable(),
share_packing: p.integer().nullable(),
@@ -42,6 +42,6 @@ export const ShareTokensSchema = defineEntity({
expires_at: p.text().nullable(),
share_travel_only: p.integer().default(0),
share_hide_images: p.integer().default(0),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').hidden(),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').hidden().index('idx_share_tokens_created_by'),
},
});
+2 -2
View File
@@ -22,8 +22,8 @@ export const TagsSchema = defineEntity({
repository: () => TagsRepository,
properties: {
id: p.integer().primary(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_tags_user_id'),
user_id: p.integer().persist(false).index('idx_tags_user_id'),
name: p.text(),
color: p.text().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
@@ -22,7 +22,7 @@ export const TodoCategoryAssigneesSchema = defineEntity({
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
category_name: p.text(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_todo_category_assignees_user_id'),
user_id: p.integer().persist(false).index('idx_todo_category_assignees_user_id'),
},
});
+2 -2
View File
@@ -35,8 +35,8 @@ export const TodoItemsSchema = defineEntity({
sort_order: p.integer().nullable(),
due_date: p.text().nullable(),
description: p.text().nullable(),
assignedUser: () => p.manyToOne(Users).ref().nullable().hidden(),
assigned_user_id: p.integer().nullable().persist(false),
assignedUser: () => p.manyToOne(Users).ref().nullable().hidden().index('idx_todo_items_assigned_user_id'),
assigned_user_id: p.integer().nullable().persist(false).index('idx_todo_items_assigned_user_id'),
priority: p.integer().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
reminded_at: p.type(DbTimestampType).nullable(),
@@ -30,8 +30,8 @@ export const TripAlbumLinksSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_trip_album_links_trip'),
trip_id: p.integer().persist(false).index('idx_trip_album_links_trip'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_trip_album_links_user_id'),
user_id: p.integer().persist(false).index('idx_trip_album_links_user_id'),
provider: p.text(),
album_id: p.text(),
album_name: p.text().default(''),
@@ -59,8 +59,8 @@ export const TripDocumentLinksSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_trip_document_links_trip'),
trip_id: p.integer().persist(false).index('idx_trip_document_links_trip'),
connection: () => p.manyToOne(DocumentConnections).ref().deleteRule('cascade').hidden(),
connection_id: p.integer().persist(false),
connection: () => p.manyToOne(DocumentConnections).ref().deleteRule('cascade').hidden().index('idx_trip_document_links_connection_id'),
connection_id: p.integer().persist(false).index('idx_trip_document_links_connection_id'),
provider_id: p.text(),
remote_scope_key: p.text(),
remote_root_id: p.text().nullable(),
@@ -79,10 +79,10 @@ export const TripDocumentLinksSchema = defineEntity({
last_sync_error: p.text().nullable(),
failure_count: p.integer().default(0),
next_attempt_at: p.text().nullable(),
created_by: p.integer().nullable().persist(false),
created_by: p.integer().nullable().persist(false).index('idx_trip_document_links_created_by'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
updated_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').nullable().hidden(),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').nullable().hidden().index('idx_trip_document_links_created_by'),
document_sync_items_collection: () => p.oneToMany(DocumentSyncItems).mappedBy('link').hidden(),
},
});
+8 -8
View File
@@ -44,24 +44,24 @@ export const TripFilesSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_trip_files_trip_id'),
trip_id: p.integer().persist(false).index('idx_trip_files_trip_id'),
place: () => p.manyToOne(Places).ref().nullable().hidden(),
place_id: p.integer().nullable().persist(false),
reservation: () => p.manyToOne(Reservations).ref().nullable().hidden(),
reservation_id: p.integer().nullable().persist(false),
place: () => p.manyToOne(Places).ref().nullable().hidden().index('idx_trip_files_place_id'),
place_id: p.integer().nullable().persist(false).index('idx_trip_files_place_id'),
reservation: () => p.manyToOne(Reservations).ref().nullable().hidden().index('idx_trip_files_reservation_id'),
reservation_id: p.integer().nullable().persist(false).index('idx_trip_files_reservation_id'),
filename: p.text(),
original_name: p.text(),
file_size: p.integer().nullable(),
mime_type: p.text().nullable(),
description: p.text().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
note: () => p.manyToOne(CollabNotes).ref().nullable().hidden(),
note_id: p.integer().nullable().persist(false),
uploaded_by: p.integer().nullable().persist(false),
note: () => p.manyToOne(CollabNotes).ref().nullable().hidden().index('idx_trip_files_note_id'),
note_id: p.integer().nullable().persist(false).index('idx_trip_files_note_id'),
uploaded_by: p.integer().nullable().persist(false).index('idx_trip_files_uploaded_by'),
starred: p.integer().nullable(),
deleted_at: p.text().nullable(),
message: () => p.manyToOne(CollabMessages).ref().deleteRule('cascade').nullable().hidden().index('idx_trip_files_message_id'),
message_id: p.integer().nullable().persist(false).index('idx_trip_files_message_id'),
uploadedByRef: () => p.manyToOne(Users).ref().joinColumn('uploaded_by').nullable().hidden(),
uploadedByRef: () => p.manyToOne(Users).ref().joinColumn('uploaded_by').nullable().hidden().index('idx_trip_files_uploaded_by'),
document_sync_items_collection: () => p.oneToMany(DocumentSyncItems).mappedBy('file').hidden(),
file_links_collection: () => p.oneToMany(FileLinks).mappedBy('file').hidden(),
},
@@ -25,9 +25,9 @@ export const TripInviteTokensSchema = defineEntity({
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden(),
trip_id: p.integer().persist(false),
token: p.text().index('idx_trip_invite_tokens_token'),
created_by: p.integer().nullable().persist(false),
created_by: p.integer().nullable().persist(false).index('idx_trip_invite_tokens_created_by'),
expires_at: p.text().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').nullable().hidden(),
createdByRef: () => p.manyToOne(Users).ref().joinColumn('created_by').nullable().hidden().index('idx_trip_invite_tokens_created_by'),
},
});
+2 -2
View File
@@ -26,8 +26,8 @@ export const TripMembersSchema = defineEntity({
trip_id: p.integer().persist(false).index('idx_trip_members_trip_id'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_trip_members_user_id'),
user_id: p.integer().persist(false).index('idx_trip_members_user_id'),
invited_by: p.integer().nullable().persist(false),
invited_by: p.integer().nullable().persist(false).index('idx_trip_members_invited_by'),
added_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
invitedByRef: () => p.manyToOne(Users).ref().joinColumn('invited_by').deleteRule('no action').nullable().hidden(),
invitedByRef: () => p.manyToOne(Users).ref().joinColumn('invited_by').deleteRule('no action').nullable().hidden().index('idx_trip_members_invited_by'),
},
});
+4 -4
View File
@@ -29,13 +29,13 @@ export const TripPhotosSchema = defineEntity({
id: p.integer().primary(),
trip: () => p.manyToOne(Trips).ref().deleteRule('cascade').hidden().index('idx_trip_photos_trip'),
trip_id: p.integer().persist(false).index('idx_trip_photos_trip'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_trip_photos_user_id'),
user_id: p.integer().persist(false).index('idx_trip_photos_user_id'),
photo: () => p.manyToOne(TrekPhotos).ref().deleteRule('cascade').hidden().index('idx_trip_photos_photo'),
photo_id: p.integer().persist(false).index('idx_trip_photos_photo'),
shared: p.integer().default(1),
albumLink: () => p.manyToOne(TripAlbumLinks).ref().nullable().hidden(),
album_link_id: p.integer().nullable().persist(false),
albumLink: () => p.manyToOne(TripAlbumLinks).ref().nullable().hidden().index('idx_trip_photos_album_link_id'),
album_link_id: p.integer().nullable().persist(false).index('idx_trip_photos_album_link_id'),
added_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
});
@@ -22,8 +22,8 @@ export const VacayEntriesSchema = defineEntity({
uniques: [{ properties: ['user', 'plan', 'date'] }],
properties: {
id: p.integer().primary(),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden(),
plan_id: p.integer().persist(false),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden().index('idx_vacay_entries_plan_id'),
plan_id: p.integer().persist(false).index('idx_vacay_entries_plan_id'),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
date: p.text(),
@@ -19,8 +19,8 @@ export const VacayHolidayCalendarsSchema = defineEntity({
repository: () => VacayHolidayCalendarsRepository,
properties: {
id: p.integer().primary(),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden(),
plan_id: p.integer().persist(false),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden().index('idx_vacay_holiday_calendars_plan_id'),
plan_id: p.integer().persist(false).index('idx_vacay_holiday_calendars_plan_id'),
type: p.text().default('public_holiday'),
region: p.text(),
label: p.text().nullable(),
@@ -23,8 +23,8 @@ export const VacayPlanMembersSchema = defineEntity({
id: p.integer().primary(),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden(),
plan_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden().index('idx_vacay_plan_members_user_id'),
user_id: p.integer().persist(false).index('idx_vacay_plan_members_user_id'),
status: p.text().nullable(),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
},
@@ -21,8 +21,8 @@ export const VacayUserColorsSchema = defineEntity({
id: p.integer().primary(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden(),
plan_id: p.integer().persist(false),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden().index('idx_vacay_user_colors_plan_id'),
plan_id: p.integer().persist(false).index('idx_vacay_user_colors_plan_id'),
color: p.text().nullable(),
},
});
@@ -23,8 +23,8 @@ export const VacayUserYearsSchema = defineEntity({
id: p.integer().primary(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').hidden(),
user_id: p.integer().persist(false),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden(),
plan_id: p.integer().persist(false),
plan: () => p.manyToOne(VacayPlans).ref().deleteRule('cascade').hidden().index('idx_vacay_user_years_plan_id'),
plan_id: p.integer().persist(false).index('idx_vacay_user_years_plan_id'),
year: p.integer(),
vacation_days: p.integer().nullable(),
carried_over: p.integer().nullable(),
@@ -21,8 +21,8 @@ export const WebauthnChallengesSchema = defineEntity({
properties: {
id: p.integer().primary(),
challenge: p.text(),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').nullable().hidden(),
user_id: p.integer().nullable().persist(false),
user: () => p.manyToOne(Users).ref().deleteRule('cascade').nullable().hidden().index('idx_webauthn_challenges_user_id'),
user_id: p.integer().nullable().persist(false).index('idx_webauthn_challenges_user_id'),
type: p.text(),
expires_at: p.integer().index('idx_webauthn_challenges_expires'),
created_at: p.type(DbTimestampType).nullable().defaultRaw(`CURRENT_TIMESTAMP`),
@@ -0,0 +1,105 @@
import { Migration } from '@mikro-orm/migrations';
/**
* An index on every foreign-key column that had none (86 of them).
*
* SQLite does not index a foreign key by itself, and every ON DELETE CASCADE
* or SET NULL has to find the child rows: deleting a trip or a user scanned
* each unindexed child table in full, once per parent row, inside the delete's
* transaction, while every other request waited on the one connection. The
* lookups by these columns (a trip's files, a user's tokens) get faster too.
*
* `IF NOT EXISTS`, so an install that added one by hand keeps it.
*/
export class Migration20200101042200_an_index_on_every_foreign_key extends Migration {
override name = 'Migration20200101042200_an_index_on_every_foreign_key';
override up(): void {
this.addSql('CREATE INDEX IF NOT EXISTS idx_webauthn_challenges_user_id ON webauthn_challenges(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_categories_user_id ON categories(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_tags_user_id ON tags(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_place_ratings_user_id ON place_ratings(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_items_owner_id ON packing_items(owner_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_items_bag_id ON packing_items(bag_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_files_uploaded_by ON trip_files(uploaded_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_files_note_id ON trip_files(note_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_files_reservation_id ON trip_files(reservation_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_files_place_id ON trip_files(place_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_reservations_assignment_id ON reservations(assignment_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_reservations_place_id ON reservations(place_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_reservations_end_day_id ON reservations(end_day_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_members_invited_by ON trip_members(invited_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_day_notes_trip_id ON day_notes(trip_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_budget_items_place_id ON budget_items(place_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_budget_items_reservation_id ON budget_items(reservation_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_budget_items_paid_by_user_id ON budget_items(paid_by_user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_vacay_plan_members_user_id ON vacay_plan_members(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_vacay_user_colors_plan_id ON vacay_user_colors(plan_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_vacay_user_years_plan_id ON vacay_user_years(plan_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_vacay_entries_plan_id ON vacay_entries(plan_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_vacay_holiday_calendars_plan_id ON vacay_holiday_calendars(plan_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collections_owner_id ON collections(owner_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collection_places_category_id ON collection_places(category_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collection_places_saved_by ON collection_places(saved_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collection_places_owner_id ON collection_places(owner_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collection_place_ratings_user_id ON collection_place_ratings(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collab_notes_user_id ON collab_notes(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collab_polls_user_id ON collab_polls(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collab_poll_votes_user_id ON collab_poll_votes(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collab_messages_reply_to ON collab_messages(reply_to)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collab_messages_user_id ON collab_messages(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_assignment_participants_user_id ON assignment_participants(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_audit_log_user_id ON audit_log(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_notifications_sender_id ON notifications(sender_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collab_message_reactions_user_id ON collab_message_reactions(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_invite_tokens_trip_id ON invite_tokens(trip_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_invite_tokens_created_by ON invite_tokens(created_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_category_assignees_user_id ON packing_category_assignees(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_templates_created_by ON packing_templates(created_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_template_categories_template_id ON packing_template_categories(template_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_template_items_category_id ON packing_template_items(category_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_bags_user_id ON packing_bags(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_bags_trip_id ON packing_bags(trip_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_bucket_list_user_id ON bucket_list(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_file_links_place_id ON file_links(place_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_file_links_assignment_id ON file_links(assignment_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_file_links_reservation_id ON file_links(reservation_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_share_tokens_created_by ON share_tokens(created_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_share_tokens_trip_id ON share_tokens(trip_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_mcp_tokens_user_id ON mcp_tokens(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_album_links_user_id ON trip_album_links(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_todo_items_assigned_user_id ON todo_items(assigned_user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_todo_category_assignees_user_id ON todo_category_assignees(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_bag_members_user_id ON packing_bag_members(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_reservation_day_positions_day_id ON reservation_day_positions(day_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_oauth_consents_user_id ON oauth_consents(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_oauth_tokens_client_id ON oauth_tokens(client_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_journey_trips_trip_id ON journey_trips(trip_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_journey_entries_author_id ON journey_entries(author_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_journey_entries_source_trip_id ON journey_entries(source_trip_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_journey_share_tokens_created_by ON journey_share_tokens(created_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_photos_album_link_id ON trip_photos(album_link_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_photos_user_id ON trip_photos(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_idempotency_keys_user_id ON idempotency_keys(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_day_accommodations_place_id ON day_accommodations(place_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_journey_photos_photo_id ON journey_photos(photo_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_budget_item_payers_user_id ON budget_item_payers(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_budget_settlements_created_by_user_id ON budget_settlements(created_by_user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_budget_settlements_to_user_id ON budget_settlements(to_user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_budget_settlements_from_user_id ON budget_settlements(from_user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_packing_item_contributors_user_id ON packing_item_contributors(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_invite_tokens_created_by ON trip_invite_tokens(created_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_journey_books_updated_by ON journey_books(updated_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_journey_books_created_by ON journey_books(created_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_collab_links_user_id ON collab_links(user_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_dawarich_visit_suggestions_matched_bucket_list_item_id ON dawarich_visit_suggestions(matched_bucket_list_item_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_dawarich_visit_suggestions_accepted_bucket_list_item_id ON dawarich_visit_suggestions(accepted_bucket_list_item_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_dawarich_visit_suggestions_accepted_place_id ON dawarich_visit_suggestions(accepted_place_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_document_connections_provider_id ON document_connections(provider_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_document_links_created_by ON trip_document_links(created_by)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_trip_document_links_connection_id ON trip_document_links(connection_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_document_sync_items_file_id ON document_sync_items(file_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_roadtrip_day_boundaries_to_assignment_id ON roadtrip_day_boundaries(to_assignment_id)');
this.addSql('CREATE INDEX IF NOT EXISTS idx_roadtrip_day_boundaries_from_assignment_id ON roadtrip_day_boundaries(from_assignment_id)');
}
}
@@ -33,6 +33,7 @@ const UNNUMBERED = [
'Migration20200101040200_trek_photo_cache_meta_cache_key_not_null',
'Migration20200101042000_tours',
'Migration20200101042100_a_trip_reminder_remembers_it_was_sent',
'Migration20200101042200_an_index_on_every_foreign_key',
];
// The last step the positional runner ever had; planLegacyBaseline refuses a
// schema_version past it.