photoprism/internal/entity
Michael Mayer 39695dd7b1 Develop: Use the mariadb client in Makefile database recipes #5753
The development database runs MariaDB, where the mysql command is a deprecated
symlink to mariadb that upstream intends to remove. Recipes reach it through
$(MARIADB) so the name is accurate today and can be overridden where a
different client is installed.

The mysql string stays where it names the SQL driver and in the MySQL 8
compatibility tooling, which is a separate lane from the MariaDB runs.
2026-07-26 09:57:41 +00:00
..
legacy Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
migrate Index: Widen instance_id and clip XMP identifiers to fit columns 2026-07-21 16:46:42 +02:00
query Tests: Fix the Go unit test suite on MariaDB #5753 2026-07-25 18:06:04 +00:00
schema Cleanup: Fix formatting of Markdown files 2026-02-14 12:10:43 +01:00
search Tests: Fix the Go unit test suite on MariaDB #5753 2026-07-25 18:06:04 +00:00
sortby Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
testdata/album Auth: Add CLI command to create access tokens for apps #782 #808 #3943 2024-01-05 16:31:07 +01:00
album.go Events: Refactor entity change notifications for sharing features #1307 2026-06-11 15:40:57 +00:00
album_cache.go Docs: Improve code comments in internal/entity/album*.go 2025-10-02 15:59:38 +02:00
album_cache_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
album_fixtures.go Tests: Adapt fixtures to have valid slugs 2025-08-19 19:44:23 +02:00
album_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
album_test.go Events: Refactor entity change notifications for sharing features #1307 2026-06-11 15:40:57 +00:00
album_user.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
album_yaml.go Entity: Clip album, photo, and folder paths via shared ClipPath #5615 2026-06-03 09:34:40 +00:00
album_yaml_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
auth_client.go Cluster: Add a per-instance node DisplayName field 2026-06-09 07:23:05 +00:00
auth_client_add.go OAuth2: Remove client soft delete and fix client add command #213 #3943 2024-01-29 21:08:01 +01:00
auth_client_add_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
auth_client_data.go Cluster: Declare per-node group config via instance env/flags 2026-06-12 18:52:54 +00:00
auth_client_fixtures.go Backend: Move unix package to /pkg/time/unix 2024-07-03 09:31:27 +02:00
auth_client_fixtures_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
auth_client_test.go Cluster: Add a per-instance node DisplayName field 2026-06-09 07:23:05 +00:00
auth_session.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_session_cache.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_session_cache_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
auth_session_client.go Account: Generate app password from the UI #808 #4114 2024-04-08 10:44:43 +02:00
auth_session_client_test.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_session_data.go Cluster: Collect OIDC groups at login for group-based admission 2026-06-12 16:08:38 +00:00
auth_session_data_test.go Cluster: Collect OIDC groups at login for group-based admission 2026-06-12 16:08:38 +00:00
auth_session_delete.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_session_delete_test.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_session_fixtures.go Tests: Fix the Go unit test suite on MariaDB #5753 2026-07-25 18:06:04 +00:00
auth_session_fixtures_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
auth_session_jwt.go Cluster: Improve usage of canonical terms in code/docs based on glossary 2026-02-23 16:16:29 +01:00
auth_session_jwt_test.go Lint: Resolve gosec findings and add embedding dist benchmark 2026-03-03 17:17:49 +01:00
auth_session_login.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
auth_session_login_test.go Lint: Resolve gosec findings and add embedding dist benchmark 2026-03-03 17:17:49 +01:00
auth_session_report.go Auth: Refactor user management API and CLI commands #98 2023-03-08 23:30:39 +01:00
auth_session_report_test.go Tests: Add unit tests 2023-08-09 15:56:16 +02:00
auth_session_test.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_tokens.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_tokens_test.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_user.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_user_add.go OIDC: Improve CLI commands and add AuthIssuer to users and sessions #782 2024-07-09 11:01:59 +02:00
auth_user_cli.go Auth: Revoke derived sessions & gate app passwords by login state #5647 2026-06-15 23:41:01 +00:00
auth_user_default.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
auth_user_details.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
auth_user_details_test.go Lint: Resolve gosec findings and add embedding dist benchmark 2026-03-03 17:17:49 +01:00
auth_user_fixtures.go Tests: Add unit tests #4973 2025-05-02 18:39:40 +02:00
auth_user_fixtures_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
auth_user_legacy.go Auth: Improve legacy user search command and add tests #98 2022-10-14 02:48:23 +02:00
auth_user_legacy_test.go Auth: Improve legacy user search command and add tests #98 2022-10-14 02:48:23 +02:00
auth_user_report.go Auth: Refactor user management API and CLI commands #98 2023-03-08 23:30:39 +01:00
auth_user_report_test.go Tests: Add unit tests 2023-08-11 14:48:28 +02:00
auth_user_settings.go Users: Set the user UID when creating user settings 2026-05-31 00:23:18 +00:00
auth_user_settings_test.go Users: Set the user UID when creating user settings 2026-05-31 00:23:18 +00:00
auth_user_share.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
auth_user_share_fixtures.go Search: Change time_format to RFC3339 and add "edited" filter #4300 2024-05-27 09:16:21 +02:00
auth_user_share_fixtures_test.go Auth: Refactor cluster configuration and provisioning API endpoints #98 2025-09-24 08:28:38 +02:00
auth_user_share_test.go Tests: Use valid fixture IDs so entity tests pass on MariaDB 2026-05-31 00:23:23 +00:00
auth_user_test.go Downloads: Add signed tokens and file-level album selection #5733 #5743 2026-07-24 15:55:39 +00:00
camera.go Events: UID-only camera/lens/country payloads & people refetch #5663 #1307 2026-06-15 11:37:26 +00:00
camera_cache.go Metadata: Add Camera Make and Model updates via CLI & API #5663 #5656 2026-06-15 09:25:44 +00:00
camera_fixtures.go Search: Change time_format to RFC3339 and add "edited" filter #4300 2024-05-27 09:16:21 +02:00
camera_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
camera_makes.go Metadata: Add Camera Make and Model updates via CLI & API #5663 #5656 2026-06-15 09:25:44 +00:00
camera_models.go Metadata: Add Camera Make and Model updates via CLI & API #5663 #5656 2026-06-15 09:25:44 +00:00
camera_test.go Events: UID-only camera/lens/country payloads & people refetch #5663 #1307 2026-06-15 11:37:26 +00:00
camera_types.go Scans: Add scan detection for epson scanner #5703 2025-06-26 11:42:22 +02:00
camera_types_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
category.go Docs: Update code comments in internal/entity/category.go and details.go 2025-10-02 16:19:57 +02:00
category_fixtures.go Backend: Update label photo count and refactor entity fixtures 2020-05-10 19:43:49 +02:00
category_test.go Code clean-up (make fmt) 2019-12-21 17:24:29 +01:00
cell.go Entity: Fix cell lookups 2026-03-07 11:48:20 +01:00
cell_fixtures.go Tests: Refactor unit tests after uid change #4560 2024-10-21 13:16:06 +02:00
cell_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
cell_test.go Entity: Fix cell lookups 2026-03-07 11:48:20 +01:00
clip.go Entity: Rename Sanitize* to Clip* and string.go to clip.go 2026-06-03 09:50:56 +00:00
clip_test.go Entity: Rename Sanitize* to Clip* and string.go to clip.go 2026-06-03 09:50:56 +00:00
country.go Events: UID-only camera/lens/country payloads & people refetch #5663 #1307 2026-06-15 11:37:26 +00:00
country_cache.go Index: Improve save / update functions, remove orphans 2021-02-06 16:30:30 +01:00
country_fixtures.go Backend: Refactor test fixtures 2020-05-11 14:49:53 +02:00
country_test.go Events: UID-only camera/lens/country payloads & people refetch #5663 #1307 2026-06-15 11:37:26 +00:00
db.go Entity: Store created and updated timestamps with second precision 2026-05-31 01:13:27 +00:00
db_conn.go Config: Centralize SQL driver identifiers in pkg/dsn #5588 2026-05-17 14:47:43 +00:00
db_conn_test.go Auth: Open album share links in the regular user interface #98 #782 2022-10-02 11:38:30 +02:00
deprecated.go Routing: Prefix frontend UI routes with /library #840 #2466 2022-10-15 21:54:11 +02:00
details.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
details_fixtures.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
details_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
details_test.go Tests: Use valid fixture IDs so entity tests pass on MariaDB 2026-05-31 00:23:23 +00:00
duplicate.go Auth: Session and ACL enhancements #98 #1746 2022-09-28 09:01:17 +02:00
duplicate_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
entity.go Links: Use canonical trailing-slash form for website URLs 2026-06-24 17:20:30 +02:00
entity_const.go Assets: Rename example fixtures directory to "samples" 2026-03-06 18:47:33 +01:00
entity_count.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
entity_count_test.go Download: Add Disabled, Originals, MediaRaw & MediaSidecar Flags #2234 2022-04-15 09:42:07 +02:00
entity_counts.go Config: Bound async job drain when closing the database 2026-07-24 11:02:29 +00:00
entity_counts_test.go Config: Bound async job drain when closing the database 2026-07-24 11:02:29 +00:00
entity_errors.go API: Ensure slugs are not empty before saving/creating labels #4761 2025-02-04 03:35:01 +01:00
entity_fixtures.go API: Rename /batch/photos endpoint to /batch/photos/edit #271 2025-05-04 14:09:23 +02:00
entity_init.go Tests: Give each package its own MariaDB test database #5753 2026-07-25 18:48:54 +00:00
entity_save.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
entity_save_test.go Lint: Resolve gosec findings and add embedding dist benchmark 2026-03-03 17:17:49 +01:00
entity_tables.go Tests: Fix the Go unit test suite on MariaDB #5753 2026-07-25 18:06:04 +00:00
entity_tables_test.go Tests: Fix the Go unit test suite on MariaDB #5753 2026-07-25 18:06:04 +00:00
entity_test.go Tests: Improve isolation and add fixes #5263 2026-07-12 05:47:21 +02:00
entity_time.go Auth: Store session login_at as NULL when no client IP is set #5707 2026-06-29 23:28:12 +00:00
entity_time_test.go Auth: Store session login_at as NULL when no client IP is set #5707 2026-06-29 23:28:12 +00:00
entity_update.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
entity_update_test.go Entity: Store created and updated timestamps with second precision 2026-05-31 01:13:27 +00:00
entity_values.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
entity_values_test.go CLI: Add "photoprism vision reset" command to reset metadata #5233 2025-09-29 18:59:52 +02:00
error.go Backend: Call clip.Bytes directly and drop the txt.ClipBytes facade #5638 2026-06-03 09:50:56 +00:00
face.go Config: Centralize SQL driver identifiers in pkg/dsn #5588 2026-05-17 14:47:43 +00:00
face_fixtures.go Search: Change time_format to RFC3339 and add "edited" filter #4300 2024-05-27 09:16:21 +02:00
face_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
face_test.go AI: Rename SampleRadius to ClusterRadius and increase cap to 0.42 #5167 2025-10-26 10:08:59 +01:00
faces.go Backend: Rename /internal/tensorflow to /internal/ai 2024-07-02 08:08:14 +02:00
faces_test.go Security: Use individual preview tokens for each user account #98 2022-10-13 22:11:02 +02:00
file.go Files: Redact InstanceID for shared sessions and drop unused search field 2026-07-22 13:34:18 +02:00
file_fixtures.go Services: Hold back DNG on WebDAV upload when raw sync is off #5744 2026-07-25 15:17:25 +00:00
file_fixtures_test.go Services: Hold back DNG on WebDAV upload when raw sync is off #5744 2026-07-25 15:17:25 +00:00
file_json.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
file_json_test.go People: Add SubjectNames() to file entity #22 2021-09-02 11:12:42 +02:00
file_metadata.go Videos: Refactor File.UpdateVideoInfos() method #926 #3588 #3559 2023-08-18 09:12:38 +02:00
file_scope_test.go Files: Redact InstanceID for shared sessions and drop unused search field 2026-07-22 13:34:18 +02:00
file_share.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
file_share_fixtures.go Routing: Prefix frontend UI routes with /library #840 #2466 2022-10-15 21:54:11 +02:00
file_share_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
file_share_test.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
file_sync.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
file_sync_fixtures.go Routing: Prefix frontend UI routes with /library #840 #2466 2022-10-15 21:54:11 +02:00
file_sync_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
file_sync_test.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
file_test.go Index: Widen instance_id and clip XMP identifiers to fit columns 2026-07-21 16:46:42 +02:00
fixtures.go API: Rename /batch/photos endpoint to /batch/photos/edit #271 2025-05-04 14:09:23 +02:00
folder.go Entity: Clip album, photo, and folder paths via shared ClipPath #5615 2026-06-03 09:34:40 +00:00
folder_album_slug.go Folders: Fix slug collision on long ASCII paths #5614 #5615 2026-05-26 02:34:48 +00:00
folder_album_slug_test.go Folders: Fix slug collision on long ASCII paths #5614 #5615 2026-05-26 02:34:48 +00:00
folder_fixtures.go People: Improve face clustering and indexing #22 2021-08-19 21:12:38 +02:00
folder_test.go Folders: Improve slug collision handling for Unicode paths #5366 2026-03-07 11:16:21 +01:00
keyword.go Go: Apply go fix modernizations across backend packages 2026-02-20 03:54:33 +01:00
keyword_cache.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
keyword_cache_test.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
keyword_fixtures.go Tests: Add fixtures 2022-03-30 18:21:14 +02:00
keyword_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
keyword_test.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
label.go Events: Refactor entity change notifications for sharing features #1307 2026-06-11 15:40:57 +00:00
label_cache.go Entity: Fix label homophone lookups and photo-label caching #5227 #5238 2026-03-07 11:43:25 +01:00
label_cache_test.go Entity: Fix label homophone lookups and photo-label caching #5227 #5238 2026-03-07 11:43:25 +01:00
label_fixtures.go Tests: Adapt fixtures to have valid slugs 2025-08-19 19:44:23 +02:00
label_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
label_search.go Labels: Reuse renamed label when re-added by previous name #5531 2026-05-04 21:13:57 +00:00
label_search_test.go Labels: Reuse renamed label when re-added by previous name #5531 2026-05-04 21:13:57 +00:00
label_slug.go Backend: Compact verbose comments in entity and photoprism workers 2026-05-15 17:50:08 +00:00
label_slug_test.go Labels: Reuse renamed label when re-added by previous name #5531 2026-05-04 21:13:57 +00:00
label_test.go Events: Refactor entity change notifications for sharing features #1307 2026-06-11 15:40:57 +00:00
lens.go Events: UID-only camera/lens/country payloads & people refetch #5663 #1307 2026-06-15 11:37:26 +00:00
lens_cache.go Metadata: Add Camera Make and Model updates via CLI & API #5663 #5656 2026-06-15 09:25:44 +00:00
lens_fixtures.go Metadata: Add Lens Make and Model updates via CLI & API #5644 #5656 2026-06-15 09:37:32 +02:00
lens_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
lens_models.go Cards View: Improve camera and lens information #2040 #3077 #3816 2023-10-13 11:35:43 +02:00
lens_test.go Events: UID-only camera/lens/country payloads & people refetch #5663 #1307 2026-06-15 11:37:26 +00:00
link.go Logs: Improve log messages in API and share audit paths 2026-03-08 12:53:20 +01:00
link_fixtures.go Sharing: Fix single-item access for shared smart albums #5727 2026-07-16 12:10:44 +00:00
link_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
marker.go Faces: Import XMP regions from HEIC and RAW sources #5712 #5751 2026-07-25 21:38:39 +02:00
marker_fixtures.go Backend: Move crop package to /internal/thumb/crop 2024-07-02 07:45:16 +02:00
marker_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
marker_json.go People: Add face dist to marker API JSON #22 2021-09-23 14:03:35 +02:00
marker_json_test.go People: Add SubjectNames() to file entity #22 2021-09-02 11:12:42 +02:00
marker_test.go Faces: Import XMP regions from HEIC and RAW sources #5712 #5751 2026-07-25 21:38:39 +02:00
markers.go XMP: Read face markers and names sidecar files #554 #1570 #747 #5712 #5713 2026-07-22 10:32:24 +02:00
markers_test.go AI: Improve the generation, sorting, and filtering of labels #5232 2025-10-02 13:08:52 +02:00
markers_xmp_test.go XMP: Read face markers and names sidecar files #554 #1570 #747 #5712 #5713 2026-07-22 10:32:24 +02:00
mysql8_test.go Config: Centralize SQL driver identifiers in pkg/dsn #5588 2026-05-17 14:47:43 +00:00
passcode.go Auth: Refine passcode recovery code comparison 2026-06-11 09:37:40 +00:00
passcode_fixtures.go Tests: Add unit tests 2024-07-17 16:38:34 +02:00
passcode_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
passcode_json.go Security: Add gosec fixes with shared URL and fs validation helpers 2026-03-03 16:38:41 +01:00
passcode_json_test.go Tests: Add unit tests #808 #3943 2024-03-27 17:01:17 +01:00
passcode_test.go Auth: Refine passcode recovery code comparison 2026-06-11 09:37:40 +00:00
password.go Entities: Improve Stringer interface implementations for logging #4490 2024-08-29 10:35:18 +02:00
password_fixtures.go Tests: Add unit tests #4973 2025-05-02 18:39:40 +02:00
password_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
password_test.go Tests: Use valid fixture IDs so entity tests pass on MariaDB 2026-05-31 00:23:23 +00:00
photo.go Sharing: Align photo search results and details on metadata fields 2026-07-25 10:04:25 +00:00
photo_album.go Docs: Improve code comments in internal/entity/photo*.go 2025-10-02 15:52:05 +02:00
photo_album_fixtures.go Tests: Fix typo in test fixtures 2025-12-02 11:02:05 +01:00
photo_album_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
photo_album_test.go Tests: Use valid fixture IDs so entity tests pass on MariaDB 2026-05-31 00:23:23 +00:00
photo_caption.go Docs: Improve code comments in internal/entity/photo*.go 2025-10-02 15:52:05 +02:00
photo_caption_test.go Tests: Add unit tests 2025-07-22 13:01:22 +02:00
photo_datetime.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
photo_datetime_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
photo_estimate.go Config: Centralize SQL driver identifiers in pkg/dsn #5588 2026-05-17 14:47:43 +00:00
photo_estimate_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
photo_fixtures.go Tests: Fix typo in test fixtures 2025-12-02 11:02:05 +01:00
photo_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
photo_interface.go Albums: Remove photo from review when adding it to an album #4229 2024-05-09 16:00:53 +02:00
photo_keyword.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
photo_keyword_fixtures.go Correct KeywordID's with extra Zero 2024-10-27 11:13:03 +01:00
photo_keyword_test.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
photo_label.go Entity: Fix photo-label caching #5227 #5238 2026-03-07 11:48:07 +01:00
photo_label_test.go Tests: Use valid fixture IDs so entity tests pass on MariaDB 2026-05-31 00:23:23 +00:00
photo_location.go Index: Resolve S2 cell in XMP branch, downgrade geocoding warn 2026-07-10 10:14:02 +02:00
photo_location_test.go Places: Update entity/photo_location_test.go #5445 2026-02-10 17:36:47 +01:00
photo_merge.go Config: Centralize SQL driver identifiers in pkg/dsn #5588 2026-05-17 14:47:43 +00:00
photo_merge_test.go Lint: Resolve gosec findings and add embedding dist benchmark 2026-03-03 17:17:49 +01:00
photo_optimize.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
photo_optimize_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
photo_quality.go Media: Improve layered TIFF & PSD preview support #5383 2026-03-06 18:14:48 +01:00
photo_quality_test.go Media: Improve layered TIFF & PSD preview support #5383 2026-03-06 18:14:48 +01:00
photo_reset.go CLI: Add "photoprism vision reset" command to reset metadata #5233 2025-09-29 18:59:52 +02:00
photo_reset_test.go CLI: Add "photoprism vision reset" command to reset metadata #5233 2025-09-29 18:59:52 +02:00
photo_scope_test.go Sharing: Align photo search results and details on metadata fields 2026-07-25 10:04:25 +00:00
photo_test.go Index: Widen instance_id and clip XMP identifiers to fit columns 2026-07-21 16:46:42 +02:00
photo_title.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
photo_title_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
photo_user.go Logs: Add package pkg/log/status to provide generic outcome constants 2025-10-21 14:42:05 +02:00
photo_vision.go AI: Add IndexedAt time to indicate when a photo was fully indexed #5167 2025-10-07 13:57:01 +02:00
photo_yaml.go Security: Add gosec fixes with shared URL and fs validation helpers 2026-03-03 16:38:41 +01:00
photo_yaml_test.go Tests: Add unit tests #4294 2024-05-28 12:48:24 +02:00
photos.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
photos_test.go API: Add /batch/photos endpoint to get metadata of selected photos #271 2025-05-03 12:43:01 +02:00
place.go Backend: Rename /internal/remote package to /internal/service 2024-07-02 08:00:27 +02:00
place_fixtures.go Tests: Refactor unit tests after uid change #4560 2024-10-21 13:16:06 +02:00
place_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
place_test.go UX: Add batch edit dialog and API endpoints #271 #5324 2025-11-19 11:20:34 +01:00
reaction.go CLI: Add "photoprism vision reset" command to reset metadata #5233 2025-09-29 18:59:52 +02:00
reaction_fixtures.go Search: Change time_format to RFC3339 and add "edited" filter #4300 2024-05-27 09:16:21 +02:00
reaction_test.go Auth: Rename database tables and delete temporary tables #98 #782 2022-10-02 22:09:02 +02:00
README.md Develop: Use the mariadb client in Makefile database recipes #5753 2026-07-26 09:57:41 +00:00
service.go Backend: Clip VARBINARY text columns by bytes to avoid write errors #5638 2026-06-03 08:04:40 +00:00
service_fixtures.go Search: Change time_format to RFC3339 and add "edited" filter #4300 2024-05-27 09:16:21 +02:00
service_test.go Tests: Add release-review regression tests #5647 #5638 #5666 #5699 #5733 2026-07-21 14:00:36 +00:00
src.go Faces: Change search to return all face markers, regardless of src #5167 2025-10-07 20:01:43 +02:00
src_test.go Faces: Change search to return all face markers, regardless of src #5167 2025-10-07 20:01:43 +02:00
string_keyvalue.go People: Show real name instead of uid in logs #1438 #2182 2022-04-04 14:21:43 +02:00
string_map.go Auth: Release preview and download tokens from cache when sessions end #5733 2026-07-19 11:24:43 +00:00
string_map_test.go Auth: Release preview and download tokens from cache when sessions end #5733 2026-07-19 11:24:43 +00:00
subject.go Events: Refactor entity change notifications for sharing features #1307 2026-06-11 15:40:57 +00:00
subject_fixtures.go API: Update Thumb/ThumbSrc for subjects and labels #4151 2025-10-03 23:17:07 +02:00
subject_fixtures_test.go Test: Use PascalCase names for all Go subtests in /internal 2025-10-02 14:50:02 +02:00
subject_names.go People: Show real name instead of uid in logs #1438 #2182 2022-04-04 14:21:43 +02:00
subject_person.go People: Show real name instead of uid in logs #1438 #2182 2022-04-04 14:21:43 +02:00
subject_person_test.go People: Improve face thumbnails on overview page #22 2021-09-17 18:51:24 +02:00
subject_test.go Events: Refactor entity change notifications for sharing features #1307 2026-06-11 15:40:57 +00:00
subjects.go Revert "People: Add subject cache and show real name in logs #1438 #2182" 2022-04-04 08:54:03 +02:00
subjects_test.go Security: Use individual preview tokens for each user account #98 2022-10-13 22:11:02 +02:00
test_db.go Tests: Isolate the XMP face test databases from the MariaDB run #5753 2026-07-26 09:57:34 +00:00
test_db_test.go Tests: Give each package its own MariaDB test database #5753 2026-07-25 18:48:54 +00:00

PhotoPrism — Database Entities

Last Updated: July 25, 2026

Overview

internal/entity holds the GORM models (Photo, File, Album, Label, Face, User, Client, Session, Service, Marker, …), their query and create/update helpers, the test fixtures (*_fixtures.go), and the migration helpers under migrate/. Models map to the database via GORM v1 (github.com/jinzhu/gorm) and are shared by the API, workers, and CLI.

Timestamps

Created and updated timestamps are stored as SQL DATETIME without fractional seconds (DATETIME_PRECISION = 0). To keep in-memory and persisted values in sync, the package sets GORM's timestamp source to second precision in db.go:

gorm.NowFunc = Now // entity.Now() == UTC().Truncate(time.Second)

Time helpers in entity_time.go:

  • UTC() — current time in UTC, full sub-second precision. Use for elapsed-time measurements, not for values that get persisted.
  • Now() — UTC truncated to whole seconds. This is what GORM writes to created_at / updated_at.
  • TimeStamp() — pointer to Now(), for nullable *time.Time columns.
  • Time(s) — parses an RFC 3339 string to a second-precision UTC time, or nil.

Implications:

  • Do not rely on sub-second ordering of persisted timestamps. Two rows created and updated within the same wall-clock second compare equal, so created_at / updated_at cannot disambiguate them. There is no monotonic auto-increment ID on UID-keyed models (e.g. Client), so there is no reliable intra-second tiebreaker — give rows distinct times when ordering must be deterministic.
  • Because both SQLite and MariaDB now receive second-precision values, timestamp behavior is identical across drivers. A timestamp assertion that passes on SQLite will pass on MariaDB.

When a test needs to prove a write advanced a timestamp, prefer one of:

  • Seed the starting value clearly in the past (e.g. Now().Add(-time.Hour)) and assert the new value is greater. This stays meaningful and distinguishes a real bump from a no-op.

  • Compare with Time.Sub() and assert the difference falls in a sane range, rather than a strict Before/After. A same-second save legitimately yields a zero delta:

    elapsed := after.Sub(before)
    assert.GreaterOrEqual(t, elapsed, time.Duration(0))
    assert.Less(t, elapsed, time.Minute)
    

Testing

Tests default to SQLite. To exercise the models against MariaDB (which is stricter and is the production database for some subsystems such as the cluster registry):

mariadb < scripts/sql/reset-acceptance.sql
PHOTOPRISM_TEST_DRIVER="mysql" \
PHOTOPRISM_TEST_DSN="root:photoprism@tcp(mariadb:4001)/acceptance?charset=utf8mb4,utf8&collation=utf8mb4_unicode_ci&parseTime=true" \
go test ./internal/entity/... -count=1 -tags="slow,develop"

make test-mariadb runs the whole backend suite this way. Each package gets a database of its own, named after its source directory (acceptance_query_…) and created on demand by entity.TestDbDSN, which mirrors the file-per-package isolation SQLite gets for free. Without it the packages would share one schema, and since every TestMain truncates the tables and re-seeds the fixtures, they would pull the database out from under each other as soon as go test runs them in parallel. make reset-acceptance drops these databases along with acceptance itself. The configured account needs CREATE privileges for this; without them the packages fall back to sharing acceptance (logged as a warning) and must not run in parallel. A test that needs a database of its own within a package must set PHOTOPRISM_TEST_DRIVER as well as PHOTOPRISM_TEST_DSN, as a SQLite path alone is parsed as a MySQL DSN and aborts the package.

MariaDB strict mode rejects inserts that SQLite quietly accepts, so a test that only ran on SQLite can fail here:

  • Primary keys must be set. An empty PK ("" UID, zero ID) triggers Error 1364: Field '<col>' doesn't have a default value. Use a valid ID/UID, not a placeholder like "1234".
  • Values must fit the column. Oversized strings give Error 1406: Data too long; out-of-range integers give Error 1264: Out of range value (e.g. photo_id is INT UNSIGNED, max 4294967295).
  • UID format (see pkg/rnd/uid.go): a one-byte prefix + 6 base36 time chars + 9 base36 random, 16 chars total (p… photo, a… album, c… client, u… user, l… label). Reuse existing fixtures for foreign-key safety; use a throwaway but in-range value only where a real reference would overwrite seeded data (e.g. a synthetic photo_id so a Details row does not attach to a real photo).
  • Fixtures live in *_fixtures.go, but some join rows are created indirectly from a parent fixture's embedded slice (e.g. a photos_labels row from a Photo fixture's Labels). Verify a combination is free against the seeded database, not just the fixtures file.
  • List-style global queries (WHERE … <> '' with no per-test scope) see everything the package has written: rows from other tests in the same package leak in, so a len(list) == N assertion that holds against a per-test SQLite file can fail on MariaDB, where the whole package shares one database.
  • Sort order is collation-dependent. utf8mb4_unicode_ci sorts case-insensitively and weights punctuation by Unicode rules, while SQLite compares byte values, so ORDER BY on a text column yields a different sequence. Give rows a deterministic tiebreaker, or assert per dialect (entity.Db().Dialect().GetName()).
  • Generated IDs restart at 1. Tables.Truncate issues TRUNCATE where supported, which resets AUTO_INCREMENT, so a fixture without an explicit ID gets the same value it would in a fresh database. Plain DELETE would not, and IDs would drift with every reset.

Collation & Emoji

MariaDB's utf8mb4_unicode_ci assigns most emoji the same collation weight, so an SQL =, <>, or LIKE on a utf8mb4 column treats distinct emoji as equal (e.g. test/🪞 matches test/🎃). SQLite compares text byte-exact, so this only reproduces on MariaDB.

  • utf8mb4 columns that collapse: albums.album_title, display/name text (*_name, *_title).
  • VARBINARY columns that stay byte-exact: albums.album_slug, albums.album_filter, albums.album_path, photos.photo_path, and every *_uid. A utf8mb4 column compared against a VARBINARY column is byte-exact (the binary operand wins).

Byte-exact also means case-sensitive, which is the one place VARBINARY bites on a search path: SQLite's LIKE folds ASCII case, so album_slug LIKE 'Forrest%' finds the forrest slug there but nothing on MariaDB. Slugs are always generated lowercase, so fold the pattern before comparing (strings.ToLower), as the album filter in search.searchPhotos does.

The durable fix for an identity/path column is to make it VARBINARYalbum_path is VARBINARY(1024) so it matches photos.photo_path and album_path = ? lookups are byte-exact at the database. Where a utf8mb4 column must stay, keep the SQL but re-verify the match byte-exact in Go before accepting it (see FindFolderAlbum / findFolderAlbumByPath, whose Go re-check is retained as defense-in-depth even now that album_path is VARBINARY). For self-join SQL where a Go re-check is awkward, HEX(col) = HEX(col) compares byte-exact on both MariaDB and SQLite. Legacy folder slugs drop emoji entirely (slug.Make("ins/🪞") == "ins") and long paths truncate to ClipSlug runes, so distinct folders can still collide on album_slug; folder albums are therefore deduplicated by album_filter (the byte-exact serialized path), not by slug (see query.RemoveDuplicateMoments).

VARBINARY Index Prefix Limit

InnoDB caps an index key prefix at 767 bytes on the COMPACT/REDUNDANT row formats, and only allows up to 3072 bytes on DYNAMIC/COMPRESSED. On a VARBINARY column the prefix is counted in bytes (on utf8mb4 it is counted in characters, i.e. up to 4 bytes each), so converting a long text column to VARBINARY can push an existing prefix index over the limit on older or non-DYNAMIC installs. Keep prefix indexes on long VARBINARY path/filter columns at ≤ 767 bytes; the project convention is 512 (albums.album_filter(512), albums.album_path(512)). A prefix index only narrows candidate rows — the full-column comparison stays exact — so a shorter prefix costs nothing for correctness.