From 5e55a17b2a5fa49236349729b3d9e85cdc0ee194 Mon Sep 17 00:00:00 2001 From: Jason Rasmussen Date: Thu, 30 Nov 2023 10:10:30 -0500 Subject: [PATCH] chore(server): sql versioning (#5346) * chore(server): sql versioning * chore: always add newline to end of file * refactor: generator * chore: pr feedback * chore: pr feedback --- .github/workflows/test.yml | 25 +- Makefile | 5 +- server/package-lock.json | 166 +++++ server/package.json | 4 +- server/src/infra/infra.module.ts | 4 +- server/src/infra/infra.util.ts | 20 + .../infra/repositories/activity.repository.ts | 3 + .../infra/repositories/album.repository.ts | 16 + .../infra/repositories/api-key.repository.ts | 6 +- .../infra/repositories/asset.repository.ts | 19 + .../infra/repositories/library.repository.ts | 12 + .../src/infra/repositories/move.repository.ts | 2 + .../infra/repositories/person.repository.ts | 13 + .../repositories/shared-link.repository.ts | 4 + .../repositories/system-config.repository.ts | 3 + .../repositories/user-token.repository.ts | 3 + .../src/infra/repositories/user.repository.ts | 7 + server/src/infra/sql-generator/index.ts | 168 +++++ server/src/infra/sql-generator/sql.logger.ts | 27 + server/src/infra/sql/access.repository.sql | 1 + server/src/infra/sql/album.repository.sql | 613 +++++++++++++++++ server/src/infra/sql/api.key.repository.sql | 69 ++ server/src/infra/sql/asset.repository.sql | 614 ++++++++++++++++++ server/src/infra/sql/audit.repository.sql | 1 + server/src/infra/sql/library.repository.sql | 299 +++++++++ server/src/infra/sql/move.repository.sql | 18 + server/src/infra/sql/partner.repository.sql | 1 + server/src/infra/sql/person.repository.sql | 367 +++++++++++ .../src/infra/sql/shared.link.repository.sql | 327 ++++++++++ .../infra/sql/system.config.repository.sql | 13 + .../infra/sql/system.metadata.repository.sql | 1 + server/src/infra/sql/tag.repository.sql | 1 + server/src/infra/sql/user.repository.sql | 143 ++++ .../src/infra/sql/user.token.repository.sql | 46 ++ 34 files changed, 3012 insertions(+), 9 deletions(-) create mode 100644 server/src/infra/infra.util.ts create mode 100644 server/src/infra/sql-generator/index.ts create mode 100644 server/src/infra/sql-generator/sql.logger.ts create mode 100644 server/src/infra/sql/access.repository.sql create mode 100644 server/src/infra/sql/album.repository.sql create mode 100644 server/src/infra/sql/api.key.repository.sql create mode 100644 server/src/infra/sql/asset.repository.sql create mode 100644 server/src/infra/sql/audit.repository.sql create mode 100644 server/src/infra/sql/library.repository.sql create mode 100644 server/src/infra/sql/move.repository.sql create mode 100644 server/src/infra/sql/partner.repository.sql create mode 100644 server/src/infra/sql/person.repository.sql create mode 100644 server/src/infra/sql/shared.link.repository.sql create mode 100644 server/src/infra/sql/system.config.repository.sql create mode 100644 server/src/infra/sql/system.metadata.repository.sql create mode 100644 server/src/infra/sql/tag.repository.sql create mode 100644 server/src/infra/sql/user.repository.sql create mode 100644 server/src/infra/sql/user.token.repository.sql diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a2f946f02..2505aa185 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -209,7 +209,7 @@ jobs: exit 1 generated-typeorm-migrations-up-to-date: - name: TypeORM Migrations + name: TypeORM Checks runs-on: ubuntu-latest services: postgres: @@ -236,7 +236,7 @@ jobs: - name: Install server dependencies run: npm ci - - name: Build the + - name: Build the app run: npm run build - name: Run existing migrations @@ -252,13 +252,30 @@ jobs: with: files: | server/src/infra/migrations/ - - name: Verify files have not changed + - name: Verify migration files have not changed if: steps.verify-changed-files.outputs.files_changed == 'true' run: | - echo "ERROR: Generated files not up to date!" + echo "ERROR: Generated migration files not up to date!" echo "Changed files: ${{ steps.verify-changed-files.outputs.changed_files }}" exit 1 + - name: Run SQL generation + run: npm run sql:generate + + - name: Find file changes + uses: tj-actions/verify-changed-files@v13.1 + id: verify-changed-sql-files + with: + files: | + server/src/infra/sql + + - name: Verify SQL files have not changed + if: steps.verify-changed-sql-files.outputs.files_changed == 'true' + run: | + echo "ERROR: Generated SQL files not up to date!" + echo "Changed files: ${{ steps.verify-changed-sql-files.outputs.changed_files }}" + exit 1 + # mobile-integration-tests: # name: Run mobile end-to-end integration tests # runs-on: macos-latest diff --git a/Makefile b/Makefile index 7668d4f60..73b922ee8 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,10 @@ prod-scale: docker compose -f ./docker/docker-compose.prod.yml up --build -V --scale immich-server=3 --scale immich-microservices=3 --remove-orphans api: - cd ./server && npm run api:generate + npm --prefix server run api:generate + +sql: + npm --prefix server run sql:generate attach-server: docker exec -it docker_immich-server_1 sh diff --git a/server/package-lock.json b/server/package-lock.json index 19a4851c8..77145427a 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -93,6 +93,7 @@ "prettier-plugin-organize-imports": "^3.2.3", "rimraf": "^5.0.1", "source-map-support": "^0.5.21", + "sql-formatter": "^14.0.0", "supertest": "^6.3.3", "testcontainers": "^10.2.1", "ts-jest": "^29.1.1", @@ -5504,6 +5505,12 @@ "node": ">=8" } }, + "node_modules/discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", + "dev": true + }, "node_modules/docker-compose": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.2.tgz", @@ -6740,6 +6747,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -8723,6 +8742,12 @@ "node": ">=12.0.0" } }, + "node_modules/moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8895,6 +8920,34 @@ "ncp": "bin/ncp" } }, + "node_modules/nearley": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", + "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", + "dev": true, + "dependencies": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6" + }, + "bin": { + "nearley-railroad": "bin/nearley-railroad.js", + "nearley-test": "bin/nearley-test.js", + "nearley-unparse": "bin/nearley-unparse.js", + "nearleyc": "bin/nearleyc.js" + }, + "funding": { + "type": "individual", + "url": "https://nearley.js.org/#give-to-nearley" + } + }, + "node_modules/nearley/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, "node_modules/negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -9964,6 +10017,25 @@ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, + "node_modules/railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", + "dev": true + }, + "node_modules/randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "dev": true, + "dependencies": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -10222,6 +10294,15 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -10806,6 +10887,20 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "node_modules/sql-formatter": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-14.0.0.tgz", + "integrity": "sha512-VcHYMRvZqg3RNjjxNB/puT9O1hR5QLXTvgTaBtxXcvmRQwSnH9M+oW2Ti+uFuVVU8HoNlOjU2uKHv8c0FQNsdQ==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "get-stdin": "=8.0.0", + "nearley": "^2.20.1" + }, + "bin": { + "sql-formatter": "bin/sql-formatter-cli.cjs" + } + }, "node_modules/ssh-remote-port-forward": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.4.tgz", @@ -16768,6 +16863,12 @@ "path-type": "^4.0.0" } }, + "discontinuous-range": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/discontinuous-range/-/discontinuous-range-1.0.0.tgz", + "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", + "dev": true + }, "docker-compose": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/docker-compose/-/docker-compose-0.24.2.tgz", @@ -17718,6 +17819,12 @@ "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", "dev": true }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -19188,6 +19295,12 @@ "integrity": "sha512-2dF2R6YMSZbpip1V1WHKGLNjr/k48uQClqMVb5H3MOvwc9qhYis3/IWbj02qIg/Y8MDXKFF4c5v0rxx2o6xTZw==", "dev": true }, + "moo": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz", + "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -19340,6 +19453,26 @@ "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==" }, + "nearley": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/nearley/-/nearley-2.20.1.tgz", + "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "moo": "^0.5.0", + "railroad-diagrams": "^1.0.0", + "randexp": "0.4.6" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, "negotiator": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", @@ -20107,6 +20240,22 @@ "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" }, + "railroad-diagrams": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", + "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", + "dev": true + }, + "randexp": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/randexp/-/randexp-0.4.6.tgz", + "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", + "dev": true, + "requires": { + "discontinuous-range": "1.0.0", + "ret": "~0.1.10" + } + }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", @@ -20313,6 +20462,12 @@ } } }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, "retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -20747,6 +20902,17 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, + "sql-formatter": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/sql-formatter/-/sql-formatter-14.0.0.tgz", + "integrity": "sha512-VcHYMRvZqg3RNjjxNB/puT9O1hR5QLXTvgTaBtxXcvmRQwSnH9M+oW2Ti+uFuVVU8HoNlOjU2uKHv8c0FQNsdQ==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "get-stdin": "=8.0.0", + "nearley": "^2.20.1" + } + }, "ssh-remote-port-forward": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/ssh-remote-port-forward/-/ssh-remote-port-forward-1.0.4.tgz", diff --git a/server/package.json b/server/package.json index 142cb92e1..bf424abe8 100644 --- a/server/package.json +++ b/server/package.json @@ -36,7 +36,8 @@ "typeorm:schema:reset": "npm run typeorm:schema:drop && npm run typeorm:migrations:run", "api:typescript": "bash ./bin/generate-open-api.sh web", "api:dart": "bash ./bin/generate-open-api.sh mobile", - "api:generate": "node ./bin/sync-spec-version.js && bash ./bin/generate-open-api.sh" + "api:generate": "node ./bin/sync-spec-version.js && bash ./bin/generate-open-api.sh", + "sql:generate": "node ./dist/infra/sql-generator/" }, "dependencies": { "@babel/runtime": "^7.22.11", @@ -119,6 +120,7 @@ "prettier-plugin-organize-imports": "^3.2.3", "rimraf": "^5.0.1", "source-map-support": "^0.5.21", + "sql-formatter": "^14.0.0", "supertest": "^6.3.3", "testcontainers": "^10.2.1", "ts-jest": "^29.1.1", diff --git a/server/src/infra/infra.module.ts b/server/src/infra/infra.module.ts index e0d5711d6..6cfaebefc 100644 --- a/server/src/infra/infra.module.ts +++ b/server/src/infra/infra.module.ts @@ -36,10 +36,10 @@ import { databaseConfig } from './database.config'; import { databaseEntities } from './entities'; import { bullConfig, bullQueues } from './infra.config'; import { - APIKeyRepository, AccessRepository, ActivityRepository, AlbumRepository, + ApiKeyRepository, AssetRepository, AuditRepository, CommunicationRepository, @@ -74,7 +74,7 @@ const providers: Provider[] = [ { provide: ICryptoRepository, useClass: CryptoRepository }, { provide: IJobRepository, useClass: JobRepository }, { provide: ILibraryRepository, useClass: LibraryRepository }, - { provide: IKeyRepository, useClass: APIKeyRepository }, + { provide: IKeyRepository, useClass: ApiKeyRepository }, { provide: IMachineLearningRepository, useClass: MachineLearningRepository }, { provide: IMetadataRepository, useClass: MetadataRepository }, { provide: IMoveRepository, useClass: MoveRepository }, diff --git a/server/src/infra/infra.util.ts b/server/src/infra/infra.util.ts new file mode 100644 index 000000000..8b2cd7efa --- /dev/null +++ b/server/src/infra/infra.util.ts @@ -0,0 +1,20 @@ +import { SetMetadata } from '@nestjs/common'; + +export const GENERATE_SQL_KEY = 'generate-sql-key'; + +export interface GenerateSqlQueries { + name?: string; + params?: any[]; +} + +/** Decorator to enable versioning/tracking of generated Sql */ +export const GenerateSql = (...options: GenerateSqlQueries[]) => SetMetadata(GENERATE_SQL_KEY, options); + +export const DummyValue = { + UUID: '00000000-0000-4000-a000-000000000000', + PAGINATION: { take: 10, skip: 0 }, + EMAIL: 'user@immich.app', + STRING: 'abcdefghi', + BUFFER: Buffer.from('abcdefghi'), + DATE: new Date(), +}; diff --git a/server/src/infra/repositories/activity.repository.ts b/server/src/infra/repositories/activity.repository.ts index 25fd5fa7a..319c9c647 100644 --- a/server/src/infra/repositories/activity.repository.ts +++ b/server/src/infra/repositories/activity.repository.ts @@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { IsNull, Repository } from 'typeorm'; import { ActivityEntity } from '../entities/activity.entity'; +import { DummyValue, GenerateSql } from '../infra.util'; export interface ActivitySearch { albumId?: string; @@ -15,6 +16,7 @@ export interface ActivitySearch { export class ActivityRepository implements IActivityRepository { constructor(@InjectRepository(ActivityEntity) private repository: Repository) {} + @GenerateSql({ params: [{ albumId: DummyValue.UUID }] }) search(options: ActivitySearch): Promise { const { userId, assetId, albumId, isLiked } = options; return this.repository.find({ @@ -41,6 +43,7 @@ export class ActivityRepository implements IActivityRepository { await this.repository.delete(id); } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] }) getStatistics(assetId: string, albumId: string): Promise { return this.repository.count({ where: { assetId, albumId, isLiked: false }, diff --git a/server/src/infra/repositories/album.repository.ts b/server/src/infra/repositories/album.repository.ts index e6c279726..8a63897ed 100644 --- a/server/src/infra/repositories/album.repository.ts +++ b/server/src/infra/repositories/album.repository.ts @@ -4,6 +4,7 @@ import { InjectDataSource, InjectRepository } from '@nestjs/typeorm'; import { DataSource, FindOptionsOrder, FindOptionsRelations, In, IsNull, Not, Repository } from 'typeorm'; import { dataSource } from '../database.config'; import { AlbumEntity, AssetEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; @Injectable() export class AlbumRepository implements IAlbumRepository { @@ -13,6 +14,7 @@ export class AlbumRepository implements IAlbumRepository { @InjectDataSource() private dataSource: DataSource, ) {} + @GenerateSql({ params: [DummyValue.UUID, {}] }) getById(id: string, options: AlbumInfoOptions): Promise { const relations: FindOptionsRelations = { owner: true, @@ -36,6 +38,7 @@ export class AlbumRepository implements IAlbumRepository { return this.repository.findOne({ where: { id }, relations, order }); } + @GenerateSql({ params: [[DummyValue.UUID]] }) getByIds(ids: string[]): Promise { return this.repository.find({ where: { @@ -48,6 +51,7 @@ export class AlbumRepository implements IAlbumRepository { }); } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] }) getByAssetId(ownerId: string, assetId: string): Promise { return this.repository.find({ where: [ @@ -59,6 +63,7 @@ export class AlbumRepository implements IAlbumRepository { }); } + @GenerateSql({ params: [[DummyValue.UUID]] }) async getMetadataForIds(ids: string[]): Promise { // Guard against running invalid query when ids list is empty. if (!ids.length) { @@ -91,6 +96,7 @@ export class AlbumRepository implements IAlbumRepository { * - Thumbnail references an asset outside the album * - Empty album still has a thumbnail set */ + @GenerateSql() async getInvalidThumbnail(): Promise { // Using dataSource, because there is no direct access to albums_assets_assets. const albumHasAssets = this.dataSource @@ -113,6 +119,7 @@ export class AlbumRepository implements IAlbumRepository { return albums.map((album) => album.id); } + @GenerateSql({ params: [DummyValue.UUID] }) getOwned(ownerId: string): Promise { return this.repository.find({ relations: { sharedUsers: true, sharedLinks: true, owner: true }, @@ -124,6 +131,7 @@ export class AlbumRepository implements IAlbumRepository { /** * Get albums shared with and shared by owner. */ + @GenerateSql({ params: [DummyValue.UUID] }) getShared(ownerId: string): Promise { return this.repository.find({ relations: { sharedUsers: true, sharedLinks: true, owner: true }, @@ -139,6 +147,7 @@ export class AlbumRepository implements IAlbumRepository { /** * Get albums of owner that are _not_ shared */ + @GenerateSql({ params: [DummyValue.UUID] }) getNotShared(ownerId: string): Promise { return this.repository.find({ relations: { sharedUsers: true, sharedLinks: true, owner: true }, @@ -159,6 +168,7 @@ export class AlbumRepository implements IAlbumRepository { await this.repository.delete({ ownerId: userId }); } + @GenerateSql() getAll(): Promise { return this.repository.find({ relations: { @@ -167,6 +177,7 @@ export class AlbumRepository implements IAlbumRepository { }); } + // @GenerateSql({ params: [DummyValue.UUID] }) async removeAsset(assetId: string): Promise { // Using dataSource, because there is no direct access to albums_assets_assets. await this.dataSource @@ -176,6 +187,7 @@ export class AlbumRepository implements IAlbumRepository { .where('"albums_assets_assets"."assetsId" = :assetId', { assetId }); } + @GenerateSql({ params: [{ albumId: DummyValue.UUID, assetIds: [DummyValue.UUID] }] }) async removeAssets(asset: AlbumAssets): Promise { await this.dataSource .createQueryBuilder() @@ -195,6 +207,7 @@ export class AlbumRepository implements IAlbumRepository { * @param assetIds Optional list of asset IDs to filter on. * @returns Set of Asset IDs for the given album ID. */ + @GenerateSql({ params: [DummyValue.UUID, [DummyValue.UUID]] }, { name: 'no assets', params: [DummyValue.UUID] }) async getAssetIds(albumId: string, assetIds?: string[]): Promise> { const query = this.dataSource .createQueryBuilder() @@ -210,6 +223,7 @@ export class AlbumRepository implements IAlbumRepository { return new Set(result.map((row) => row['assetId'])); } + @GenerateSql({ params: [{ albumId: DummyValue.UUID, assetId: DummyValue.UUID }] }) hasAsset(asset: AlbumAsset): Promise { return this.repository.exist({ where: { @@ -224,6 +238,7 @@ export class AlbumRepository implements IAlbumRepository { }); } + @GenerateSql({ params: [{ albumId: DummyValue.UUID, assetIds: [DummyValue.UUID] }] }) async addAssets({ albumId, assetIds }: AlbumAssets): Promise { await this.dataSource .createQueryBuilder() @@ -266,6 +281,7 @@ export class AlbumRepository implements IAlbumRepository { * * @returns Amount of updated album thumbnails or undefined when unknown */ + @GenerateSql() async updateThumbnails(): Promise { // Subquery for getting a new thumbnail. const newThumbnail = this.assetRepository diff --git a/server/src/infra/repositories/api-key.repository.ts b/server/src/infra/repositories/api-key.repository.ts index 2484b0d56..71226a537 100644 --- a/server/src/infra/repositories/api-key.repository.ts +++ b/server/src/infra/repositories/api-key.repository.ts @@ -3,9 +3,10 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { APIKeyEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; @Injectable() -export class APIKeyRepository implements IKeyRepository { +export class ApiKeyRepository implements IKeyRepository { constructor(@InjectRepository(APIKeyEntity) private repository: Repository) {} async create(dto: Partial): Promise { @@ -21,6 +22,7 @@ export class APIKeyRepository implements IKeyRepository { await this.repository.delete({ userId, id }); } + @GenerateSql({ params: [DummyValue.STRING] }) getKey(hashedToken: string): Promise { return this.repository.findOne({ select: { @@ -35,10 +37,12 @@ export class APIKeyRepository implements IKeyRepository { }); } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] }) getById(userId: string, id: string): Promise { return this.repository.findOne({ where: { userId, id } }); } + @GenerateSql({ params: [DummyValue.STRING] }) getByUserId(userId: string): Promise { return this.repository.find({ where: { userId }, order: { createdAt: 'DESC' } }); } diff --git a/server/src/infra/repositories/asset.repository.ts b/server/src/infra/repositories/asset.repository.ts index 59c29a9d2..09ecf6692 100644 --- a/server/src/infra/repositories/asset.repository.ts +++ b/server/src/infra/repositories/asset.repository.ts @@ -22,6 +22,7 @@ import _ from 'lodash'; import { DateTime } from 'luxon'; import { And, FindOptionsRelations, FindOptionsWhere, In, IsNull, LessThan, Not, Repository } from 'typeorm'; import { AssetEntity, AssetJobStatusEntity, AssetType, ExifEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; import OptionalBetween from '../utils/optional-between.util'; import { paginate } from '../utils/pagination.util'; @@ -185,6 +186,7 @@ export class AssetRepository implements IAssetRepository { return this.repository.save(asset); } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.DATE] }) getByDate(ownerId: string, date: Date): Promise { // For reference of a correct approach although slower @@ -219,6 +221,7 @@ export class AssetRepository implements IAssetRepository { }); } + @GenerateSql({ params: [DummyValue.UUID, { day: 1, month: 1 }] }) getByDayOfYear(ownerId: string, { day, month }: MonthDay): Promise { return this.repository .createQueryBuilder('entity') @@ -240,6 +243,7 @@ export class AssetRepository implements IAssetRepository { .getMany(); } + @GenerateSql({ params: [[DummyValue.UUID]] }) getByIds(ids: string[], relations?: FindOptionsRelations): Promise { if (!relations) { relations = { @@ -259,6 +263,7 @@ export class AssetRepository implements IAssetRepository { }); } + @GenerateSql({ params: [DummyValue.UUID] }) async deleteAll(ownerId: string): Promise { await this.repository.delete({ ownerId }); } @@ -291,12 +296,14 @@ export class AssetRepository implements IAssetRepository { }); } + @GenerateSql({ params: [[DummyValue.UUID]] }) getByLibraryId(libraryIds: string[]): Promise { return this.repository.find({ where: { library: { id: In(libraryIds) } }, }); } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] }) getByLibraryIdAndOriginalPath(libraryId: string, originalPath: string): Promise { return this.repository.findOne({ where: { library: { id: libraryId }, originalPath: originalPath }, @@ -333,6 +340,7 @@ export class AssetRepository implements IAssetRepository { * * @returns Promise - Array of assetIds belong to the device */ + @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] }) async getAllByDeviceId(ownerId: string, deviceId: string): Promise { const items = await this.repository.find({ select: { deviceAssetId: true }, @@ -347,6 +355,7 @@ export class AssetRepository implements IAssetRepository { return items.map((asset) => asset.deviceAssetId); } + @GenerateSql({ params: [DummyValue.UUID] }) getById(id: string): Promise { return this.repository.findOne({ where: { id }, @@ -362,6 +371,7 @@ export class AssetRepository implements IAssetRepository { }); } + @GenerateSql({ params: [[DummyValue.UUID], { deviceId: DummyValue.STRING }] }) async updateAll(ids: string[], options: Partial): Promise { await this.repository.update({ id: In(ids) }, options); } @@ -395,6 +405,7 @@ export class AssetRepository implements IAssetRepository { await this.repository.remove(asset); } + @GenerateSql({ params: [[DummyValue.UUID], DummyValue.BUFFER] }) getByChecksum(userId: string, checksum: Buffer): Promise { return this.repository.findOne({ where: { ownerId: userId, checksum } }); } @@ -417,6 +428,14 @@ export class AssetRepository implements IAssetRepository { }); } + @GenerateSql( + ...Object.values(WithProperty) + .filter((property) => property !== WithProperty.IS_OFFLINE) + .map((property) => ({ + name: property, + params: [DummyValue.PAGINATION, property], + })), + ) getWithout(pagination: PaginationOptions, property: WithoutProperty): Paginated { let relations: FindOptionsRelations = {}; let where: FindOptionsWhere | FindOptionsWhere[] = {}; diff --git a/server/src/infra/repositories/library.repository.ts b/server/src/infra/repositories/library.repository.ts index 2b42b3cb5..155c3d9be 100644 --- a/server/src/infra/repositories/library.repository.ts +++ b/server/src/infra/repositories/library.repository.ts @@ -4,11 +4,13 @@ import { InjectRepository } from '@nestjs/typeorm'; import { IsNull, Not } from 'typeorm'; import { Repository } from 'typeorm/repository/Repository'; import { LibraryEntity, LibraryType } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; @Injectable() export class LibraryRepository implements ILibraryRepository { constructor(@InjectRepository(LibraryEntity) private repository: Repository) {} + @GenerateSql({ params: [DummyValue.UUID] }) get(id: string, withDeleted = false): Promise { return this.repository.findOneOrFail({ where: { @@ -19,6 +21,7 @@ export class LibraryRepository implements ILibraryRepository { }); } + @GenerateSql({ params: [DummyValue.STRING] }) existsByName(name: string, withDeleted = false): Promise { return this.repository.exist({ where: { @@ -28,10 +31,12 @@ export class LibraryRepository implements ILibraryRepository { }); } + @GenerateSql({ params: [DummyValue.UUID] }) getCountForUser(ownerId: string): Promise { return this.repository.countBy({ ownerId }); } + @GenerateSql({ params: [DummyValue.UUID] }) getDefaultUploadLibrary(ownerId: string): Promise { return this.repository.findOne({ where: { @@ -44,6 +49,7 @@ export class LibraryRepository implements ILibraryRepository { }); } + @GenerateSql({ params: [DummyValue.UUID] }) getUploadLibraryCount(ownerId: string): Promise { return this.repository.count({ where: { @@ -53,6 +59,7 @@ export class LibraryRepository implements ILibraryRepository { }); } + @GenerateSql({ params: [DummyValue.UUID] }) getAllByUserId(ownerId: string, type?: LibraryType): Promise { return this.repository.find({ where: { @@ -69,6 +76,7 @@ export class LibraryRepository implements ILibraryRepository { }); } + @GenerateSql({ params: [] }) getAll(withDeleted = false, type?: LibraryType): Promise { return this.repository.find({ where: { type }, @@ -82,6 +90,7 @@ export class LibraryRepository implements ILibraryRepository { }); } + @GenerateSql() getAllDeleted(): Promise { return this.repository.find({ where: { @@ -114,6 +123,7 @@ export class LibraryRepository implements ILibraryRepository { return this.save(library); } + @GenerateSql({ params: [DummyValue.UUID] }) async getStatistics(id: string): Promise { const stats = await this.repository .createQueryBuilder('libraries') @@ -134,6 +144,7 @@ export class LibraryRepository implements ILibraryRepository { }; } + @GenerateSql({ params: [DummyValue.UUID] }) async getOnlineAssetPaths(libraryId: string): Promise { // Return all non-offline asset paths for a given library const rawResults = await this.repository @@ -153,6 +164,7 @@ export class LibraryRepository implements ILibraryRepository { return results; } + @GenerateSql({ params: [DummyValue.UUID] }) async getAssetIds(libraryId: string, withDeleted = false): Promise { let query = await this.repository .createQueryBuilder('library') diff --git a/server/src/infra/repositories/move.repository.ts b/server/src/infra/repositories/move.repository.ts index f909b0f20..f7995b54e 100644 --- a/server/src/infra/repositories/move.repository.ts +++ b/server/src/infra/repositories/move.repository.ts @@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { MoveEntity, PathType } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; @Injectable() export class MoveRepository implements IMoveRepository { @@ -12,6 +13,7 @@ export class MoveRepository implements IMoveRepository { return this.repository.save(entity); } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING] }) getByEntity(entityId: string, pathType: PathType): Promise { return this.repository.findOne({ where: { entityId, pathType } }); } diff --git a/server/src/infra/repositories/person.repository.ts b/server/src/infra/repositories/person.repository.ts index a986a0e0c..e3c0ac26a 100644 --- a/server/src/infra/repositories/person.repository.ts +++ b/server/src/infra/repositories/person.repository.ts @@ -9,6 +9,7 @@ import { import { InjectRepository } from '@nestjs/typeorm'; import { In, Repository } from 'typeorm'; import { AssetEntity, AssetFaceEntity, PersonEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; export class PersonRepository implements IPersonRepository { constructor( @@ -36,6 +37,7 @@ export class PersonRepository implements IPersonRepository { return assetIds; } + @GenerateSql({ params: [{ oldPersonId: DummyValue.UUID, newPersonId: DummyValue.UUID }] }) async reassignFaces({ oldPersonId, newPersonId }: UpdateFacesData): Promise { const result = await this.assetFaceRepository .createQueryBuilder() @@ -57,18 +59,22 @@ export class PersonRepository implements IPersonRepository { return people.length; } + @GenerateSql() getAllFaces(): Promise { return this.assetFaceRepository.find({ relations: { asset: true }, withDeleted: true }); } + @GenerateSql() getAll(): Promise { return this.personRepository.find(); } + @GenerateSql() getAllWithoutThumbnail(): Promise { return this.personRepository.findBy({ thumbnailPath: '' }); } + @GenerateSql({ params: [DummyValue.UUID] }) getAllForUser(userId: string, options?: PersonSearchOptions): Promise { const queryBuilder = this.personRepository .createQueryBuilder('person') @@ -89,6 +95,7 @@ export class PersonRepository implements IPersonRepository { return queryBuilder.getMany(); } + @GenerateSql() getAllWithoutFaces(): Promise { return this.personRepository .createQueryBuilder('person') @@ -99,10 +106,12 @@ export class PersonRepository implements IPersonRepository { .getMany(); } + @GenerateSql({ params: [DummyValue.UUID] }) getById(personId: string): Promise { return this.personRepository.findOne({ where: { id: personId } }); } + @GenerateSql({ params: [DummyValue.UUID, DummyValue.STRING, { withHidden: true }] }) getByName(userId: string, personName: string, { withHidden }: PersonNameSearchOptions): Promise { const queryBuilder = this.personRepository .createQueryBuilder('person') @@ -121,6 +130,7 @@ export class PersonRepository implements IPersonRepository { return queryBuilder.getMany(); } + @GenerateSql({ params: [DummyValue.UUID] }) async getStatistics(personId: string): Promise { return { assets: await this.assetFaceRepository @@ -135,6 +145,7 @@ export class PersonRepository implements IPersonRepository { }; } + @GenerateSql({ params: [DummyValue.UUID] }) getAssets(personId: string): Promise { return this.assetRepository.find({ where: { @@ -171,10 +182,12 @@ export class PersonRepository implements IPersonRepository { return this.personRepository.findOneByOrFail({ id }); } + @GenerateSql({ params: [[{ assetId: DummyValue.UUID, personId: DummyValue.UUID }]] }) async getFacesByIds(ids: AssetFaceId[]): Promise { return this.assetFaceRepository.find({ where: ids, relations: { asset: true }, withDeleted: true }); } + @GenerateSql({ params: [DummyValue.UUID] }) async getRandomFace(personId: string): Promise { return this.assetFaceRepository.findOneBy({ personId }); } diff --git a/server/src/infra/repositories/shared-link.repository.ts b/server/src/infra/repositories/shared-link.repository.ts index 127efee43..ae8826f79 100644 --- a/server/src/infra/repositories/shared-link.repository.ts +++ b/server/src/infra/repositories/shared-link.repository.ts @@ -3,11 +3,13 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { SharedLinkEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; @Injectable() export class SharedLinkRepository implements ISharedLinkRepository { constructor(@InjectRepository(SharedLinkEntity) private repository: Repository) {} + @GenerateSql({ params: [DummyValue.UUID, DummyValue.UUID] }) get(userId: string, id: string): Promise { return this.repository.findOne({ where: { @@ -39,6 +41,7 @@ export class SharedLinkRepository implements ISharedLinkRepository { }); } + @GenerateSql({ params: [DummyValue.UUID] }) getAll(userId: string): Promise { return this.repository.find({ where: { @@ -56,6 +59,7 @@ export class SharedLinkRepository implements ISharedLinkRepository { }); } + @GenerateSql({ params: [DummyValue.BUFFER] }) async getByKey(key: Buffer): Promise { return await this.repository.findOne({ where: { diff --git a/server/src/infra/repositories/system-config.repository.ts b/server/src/infra/repositories/system-config.repository.ts index 0a66c2f22..57eb6c1fd 100644 --- a/server/src/infra/repositories/system-config.repository.ts +++ b/server/src/infra/repositories/system-config.repository.ts @@ -4,6 +4,7 @@ import axios from 'axios'; import { readFile } from 'fs/promises'; import { In, Repository } from 'typeorm'; import { SystemConfigEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; export class SystemConfigRepository implements ISystemConfigRepository { constructor( @@ -14,6 +15,7 @@ export class SystemConfigRepository implements ISystemConfigRepository { return axios.get(url).then((response) => response.data); } + @GenerateSql() load(): Promise { return this.repository.find(); } @@ -26,6 +28,7 @@ export class SystemConfigRepository implements ISystemConfigRepository { return this.repository.save(items); } + @GenerateSql({ params: [DummyValue.STRING] }) async deleteKeys(keys: string[]): Promise { await this.repository.delete({ key: In(keys) }); } diff --git a/server/src/infra/repositories/user-token.repository.ts b/server/src/infra/repositories/user-token.repository.ts index cb83134a3..b5656d922 100644 --- a/server/src/infra/repositories/user-token.repository.ts +++ b/server/src/infra/repositories/user-token.repository.ts @@ -3,11 +3,13 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { UserTokenEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; @Injectable() export class UserTokenRepository implements IUserTokenRepository { constructor(@InjectRepository(UserTokenEntity) private repository: Repository) {} + @GenerateSql({ params: [DummyValue.STRING] }) getByToken(token: string): Promise { return this.repository.findOne({ where: { token }, relations: { user: true } }); } @@ -35,6 +37,7 @@ export class UserTokenRepository implements IUserTokenRepository { return this.repository.save(userToken); } + @GenerateSql({ params: [DummyValue.UUID] }) async delete(id: string): Promise { await this.repository.delete({ id }); } diff --git a/server/src/infra/repositories/user.repository.ts b/server/src/infra/repositories/user.repository.ts index b84adb2fd..d1b1c0d5e 100644 --- a/server/src/infra/repositories/user.repository.ts +++ b/server/src/infra/repositories/user.repository.ts @@ -3,6 +3,7 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { IsNull, Not, Repository } from 'typeorm'; import { UserEntity } from '../entities'; +import { DummyValue, GenerateSql } from '../infra.util'; @Injectable() export class UserRepository implements IUserRepository { @@ -16,14 +17,17 @@ export class UserRepository implements IUserRepository { }); } + @GenerateSql() async getAdmin(): Promise { return this.userRepository.findOne({ where: { isAdmin: true } }); } + @GenerateSql() async hasAdmin(): Promise { return this.userRepository.exist({ where: { isAdmin: true } }); } + @GenerateSql({ params: [DummyValue.EMAIL] }) async getByEmail(email: string, withPassword?: boolean): Promise { let builder = this.userRepository.createQueryBuilder('user').where({ email }); @@ -34,10 +38,12 @@ export class UserRepository implements IUserRepository { return builder.getOne(); } + @GenerateSql({ params: [DummyValue.STRING] }) async getByStorageLabel(storageLabel: string): Promise { return this.userRepository.findOne({ where: { storageLabel } }); } + @GenerateSql({ params: [DummyValue.STRING] }) async getByOAuthId(oauthId: string): Promise { return this.userRepository.findOne({ where: { oauthId } }); } @@ -76,6 +82,7 @@ export class UserRepository implements IUserRepository { return this.userRepository.recover(user); } + @GenerateSql() async getUserStats(): Promise { const stats = await this.userRepository .createQueryBuilder('users') diff --git a/server/src/infra/sql-generator/index.ts b/server/src/infra/sql-generator/index.ts new file mode 100644 index 000000000..78b412249 --- /dev/null +++ b/server/src/infra/sql-generator/index.ts @@ -0,0 +1,168 @@ +import { INestApplication } from '@nestjs/common'; +import { Reflector } from '@nestjs/core'; +import { Test } from '@nestjs/testing'; +import { TypeOrmModule } from '@nestjs/typeorm'; +import { mkdir, rm, writeFile } from 'fs/promises'; +import { join } from 'path'; +import { databaseConfig } from '../database.config'; +import { databaseEntities } from '../entities'; +import { GENERATE_SQL_KEY, GenerateSqlQueries } from '../infra.util'; +import { + AccessRepository, + AlbumRepository, + ApiKeyRepository, + AssetRepository, + AuditRepository, + LibraryRepository, + MoveRepository, + PartnerRepository, + PersonRepository, + SharedLinkRepository, + SystemConfigRepository, + SystemMetadataRepository, + TagRepository, + UserRepository, + UserTokenRepository, +} from '../repositories'; +import { SqlLogger } from './sql.logger'; + +const reflector = new Reflector(); +const repositories = [ + AccessRepository, + AlbumRepository, + ApiKeyRepository, + AssetRepository, + AuditRepository, + LibraryRepository, + MoveRepository, + PartnerRepository, + PersonRepository, + SharedLinkRepository, + SystemConfigRepository, + SystemMetadataRepository, + TagRepository, + UserTokenRepository, + UserRepository, +]; + +type Repository = (typeof repositories)[0]; +type SqlGeneratorOptions = { targetDir: string }; + +class SqlGenerator { + private app: INestApplication | null = null; + private sqlLogger = new SqlLogger(); + private results: Record = {}; + + constructor(private options: SqlGeneratorOptions) {} + + async run() { + try { + await this.setup(); + for (const Repository of repositories) { + await this.process(Repository); + } + await this.write(); + this.stats(); + } finally { + await this.close(); + } + } + + private async setup() { + await rm(this.options.targetDir, { force: true, recursive: true }); + await mkdir(this.options.targetDir); + + const moduleFixture = await Test.createTestingModule({ + imports: [ + TypeOrmModule.forRoot({ + ...databaseConfig, + entities: databaseEntities, + logging: ['query'], + logger: this.sqlLogger, + }), + TypeOrmModule.forFeature(databaseEntities), + ], + providers: repositories, + }).compile(); + + this.app = await moduleFixture.createNestApplication().init(); + } + + async process(Repository: Repository) { + if (!this.app) { + throw new Error('Not initialized'); + } + + const data: string[] = [`-- NOTE: This file is auto generated by ./sql-generator`]; + const instance = this.app.get(Repository); + const properties = Object.getOwnPropertyNames(Repository.prototype) as Array; + for (const key of properties) { + const target = instance[key]; + if (!(target instanceof Function)) { + continue; + } + + const queries = reflector.get(GENERATE_SQL_KEY, target); + if (!queries) { + continue; + } + + // empty decorator implies calling with no arguments + if (queries.length === 0) { + queries.push({ params: [] }); + } + + for (const { name, params } of queries) { + let queryLabel = `${Repository.name}.${key}`; + if (name) { + queryLabel += ` (${name})`; + } + + this.sqlLogger.clear(); + + // errors still generate sql, which is all we care about + await target.apply(instance, params).catch(() => null); + + if (this.sqlLogger.queries.length === 0) { + console.warn(`No queries recorded for ${queryLabel}`); + continue; + } + + data.push([`-- ${queryLabel}`, ...this.sqlLogger.queries].join('\n')); + } + } + + this.results[Repository.name] = data; + } + + private async write() { + for (const [repoName, data] of Object.entries(this.results)) { + const filename = repoName.replace(/[A-Z]/g, (letter) => `.${letter.toLowerCase()}`).replace('.', ''); + const file = join(this.options.targetDir, `${filename}.sql`); + await writeFile(file, data.join('\n\n') + '\n'); + } + } + + private stats() { + console.log(`Wrote ${Object.keys(this.results).length} files`); + console.log(`Generated ${Object.values(this.results).flat().length} queries`); + } + + private async close() { + if (this.app) { + await this.app.close(); + } + } +} + +new SqlGenerator({ targetDir: './src/infra/sql' }) + .run() + .then(() => { + console.log('Done'); + process.exit(0); + }) + .catch((error) => { + console.error(error); + console.log('Something went wrong'); + process.exit(1); + }); diff --git a/server/src/infra/sql-generator/sql.logger.ts b/server/src/infra/sql-generator/sql.logger.ts new file mode 100644 index 000000000..78c3df148 --- /dev/null +++ b/server/src/infra/sql-generator/sql.logger.ts @@ -0,0 +1,27 @@ +import { Logger } from 'typeorm'; + +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { format } = require('sql-formatter'); + +export class SqlLogger implements Logger { + queries: string[] = []; + errors: Array<{ error: string | Error; query: string }> = []; + + clear() { + this.queries = []; + this.errors = []; + } + + logQuery(query: string) { + this.queries.push(format(query, { language: 'postgresql' })); + } + + logQueryError(error: string | Error, query: string) { + this.errors.push({ error, query }); + } + + logQuerySlow() {} + logSchemaBuild() {} + logMigration() {} + log() {} +} diff --git a/server/src/infra/sql/access.repository.sql b/server/src/infra/sql/access.repository.sql new file mode 100644 index 000000000..21f9f116b --- /dev/null +++ b/server/src/infra/sql/access.repository.sql @@ -0,0 +1 @@ +-- NOTE: This file is auto generated by ./sql-generator diff --git a/server/src/infra/sql/album.repository.sql b/server/src/infra/sql/album.repository.sql new file mode 100644 index 000000000..777edb097 --- /dev/null +++ b/server/src/infra/sql/album.repository.sql @@ -0,0 +1,613 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- AlbumRepository.getById +SELECT DISTINCT + "distinctAlias"."AlbumEntity_id" AS "ids_AlbumEntity_id" +FROM + ( + SELECT + "AlbumEntity"."id" AS "AlbumEntity_id", + "AlbumEntity"."ownerId" AS "AlbumEntity_ownerId", + "AlbumEntity"."albumName" AS "AlbumEntity_albumName", + "AlbumEntity"."description" AS "AlbumEntity_description", + "AlbumEntity"."createdAt" AS "AlbumEntity_createdAt", + "AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt", + "AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt", + "AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId", + "AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled", + "AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id", + "AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name", + "AlbumEntity__AlbumEntity_owner"."avatarColor" AS "AlbumEntity__AlbumEntity_owner_avatarColor", + "AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin", + "AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email", + "AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel", + "AlbumEntity__AlbumEntity_owner"."externalPath" AS "AlbumEntity__AlbumEntity_owner_externalPath", + "AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId", + "AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath", + "AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword", + "AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt", + "AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt", + "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", + "AlbumEntity__AlbumEntity_owner"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_owner_memoriesEnabled", + "AlbumEntity__AlbumEntity_sharedUsers"."id" AS "AlbumEntity__AlbumEntity_sharedUsers_id", + "AlbumEntity__AlbumEntity_sharedUsers"."name" AS "AlbumEntity__AlbumEntity_sharedUsers_name", + "AlbumEntity__AlbumEntity_sharedUsers"."avatarColor" AS "AlbumEntity__AlbumEntity_sharedUsers_avatarColor", + "AlbumEntity__AlbumEntity_sharedUsers"."isAdmin" AS "AlbumEntity__AlbumEntity_sharedUsers_isAdmin", + "AlbumEntity__AlbumEntity_sharedUsers"."email" AS "AlbumEntity__AlbumEntity_sharedUsers_email", + "AlbumEntity__AlbumEntity_sharedUsers"."storageLabel" AS "AlbumEntity__AlbumEntity_sharedUsers_storageLabel", + "AlbumEntity__AlbumEntity_sharedUsers"."externalPath" AS "AlbumEntity__AlbumEntity_sharedUsers_externalPath", + "AlbumEntity__AlbumEntity_sharedUsers"."oauthId" AS "AlbumEntity__AlbumEntity_sharedUsers_oauthId", + "AlbumEntity__AlbumEntity_sharedUsers"."profileImagePath" AS "AlbumEntity__AlbumEntity_sharedUsers_profileImagePath", + "AlbumEntity__AlbumEntity_sharedUsers"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_sharedUsers_shouldChangePassword", + "AlbumEntity__AlbumEntity_sharedUsers"."createdAt" AS "AlbumEntity__AlbumEntity_sharedUsers_createdAt", + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_deletedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."updatedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_updatedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_sharedUsers_memoriesEnabled", + "AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id", + "AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description", + "AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password", + "AlbumEntity__AlbumEntity_sharedLinks"."userId" AS "AlbumEntity__AlbumEntity_sharedLinks_userId", + "AlbumEntity__AlbumEntity_sharedLinks"."key" AS "AlbumEntity__AlbumEntity_sharedLinks_key", + "AlbumEntity__AlbumEntity_sharedLinks"."type" AS "AlbumEntity__AlbumEntity_sharedLinks_type", + "AlbumEntity__AlbumEntity_sharedLinks"."createdAt" AS "AlbumEntity__AlbumEntity_sharedLinks_createdAt", + "AlbumEntity__AlbumEntity_sharedLinks"."expiresAt" AS "AlbumEntity__AlbumEntity_sharedLinks_expiresAt", + "AlbumEntity__AlbumEntity_sharedLinks"."allowUpload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowUpload", + "AlbumEntity__AlbumEntity_sharedLinks"."allowDownload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowDownload", + "AlbumEntity__AlbumEntity_sharedLinks"."showExif" AS "AlbumEntity__AlbumEntity_sharedLinks_showExif", + "AlbumEntity__AlbumEntity_sharedLinks"."albumId" AS "AlbumEntity__AlbumEntity_sharedLinks_albumId" + FROM + "albums" "AlbumEntity" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" + AND ( + "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL + ) + LEFT JOIN "albums_shared_users_users" "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity__AlbumEntity_sharedUsers"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."usersId" + AND ( + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL + ) + LEFT JOIN "shared_links" "AlbumEntity__AlbumEntity_sharedLinks" ON "AlbumEntity__AlbumEntity_sharedLinks"."albumId" = "AlbumEntity"."id" + WHERE + (("AlbumEntity"."id" = $1)) + AND ("AlbumEntity"."deletedAt" IS NULL) + ) "distinctAlias" +ORDER BY + "AlbumEntity_id" ASC +LIMIT + 1 + +-- AlbumRepository.getByIds +SELECT + "AlbumEntity"."id" AS "AlbumEntity_id", + "AlbumEntity"."ownerId" AS "AlbumEntity_ownerId", + "AlbumEntity"."albumName" AS "AlbumEntity_albumName", + "AlbumEntity"."description" AS "AlbumEntity_description", + "AlbumEntity"."createdAt" AS "AlbumEntity_createdAt", + "AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt", + "AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt", + "AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId", + "AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled", + "AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id", + "AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name", + "AlbumEntity__AlbumEntity_owner"."avatarColor" AS "AlbumEntity__AlbumEntity_owner_avatarColor", + "AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin", + "AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email", + "AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel", + "AlbumEntity__AlbumEntity_owner"."externalPath" AS "AlbumEntity__AlbumEntity_owner_externalPath", + "AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId", + "AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath", + "AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword", + "AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt", + "AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt", + "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", + "AlbumEntity__AlbumEntity_owner"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_owner_memoriesEnabled", + "AlbumEntity__AlbumEntity_sharedUsers"."id" AS "AlbumEntity__AlbumEntity_sharedUsers_id", + "AlbumEntity__AlbumEntity_sharedUsers"."name" AS "AlbumEntity__AlbumEntity_sharedUsers_name", + "AlbumEntity__AlbumEntity_sharedUsers"."avatarColor" AS "AlbumEntity__AlbumEntity_sharedUsers_avatarColor", + "AlbumEntity__AlbumEntity_sharedUsers"."isAdmin" AS "AlbumEntity__AlbumEntity_sharedUsers_isAdmin", + "AlbumEntity__AlbumEntity_sharedUsers"."email" AS "AlbumEntity__AlbumEntity_sharedUsers_email", + "AlbumEntity__AlbumEntity_sharedUsers"."storageLabel" AS "AlbumEntity__AlbumEntity_sharedUsers_storageLabel", + "AlbumEntity__AlbumEntity_sharedUsers"."externalPath" AS "AlbumEntity__AlbumEntity_sharedUsers_externalPath", + "AlbumEntity__AlbumEntity_sharedUsers"."oauthId" AS "AlbumEntity__AlbumEntity_sharedUsers_oauthId", + "AlbumEntity__AlbumEntity_sharedUsers"."profileImagePath" AS "AlbumEntity__AlbumEntity_sharedUsers_profileImagePath", + "AlbumEntity__AlbumEntity_sharedUsers"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_sharedUsers_shouldChangePassword", + "AlbumEntity__AlbumEntity_sharedUsers"."createdAt" AS "AlbumEntity__AlbumEntity_sharedUsers_createdAt", + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_deletedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."updatedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_updatedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_sharedUsers_memoriesEnabled" +FROM + "albums" "AlbumEntity" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" + AND ( + "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL + ) + LEFT JOIN "albums_shared_users_users" "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity__AlbumEntity_sharedUsers"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."usersId" + AND ( + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL + ) +WHERE + (("AlbumEntity"."id" IN ($1))) + AND ("AlbumEntity"."deletedAt" IS NULL) + +-- AlbumRepository.getByAssetId +SELECT + "AlbumEntity"."id" AS "AlbumEntity_id", + "AlbumEntity"."ownerId" AS "AlbumEntity_ownerId", + "AlbumEntity"."albumName" AS "AlbumEntity_albumName", + "AlbumEntity"."description" AS "AlbumEntity_description", + "AlbumEntity"."createdAt" AS "AlbumEntity_createdAt", + "AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt", + "AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt", + "AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId", + "AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled", + "AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id", + "AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name", + "AlbumEntity__AlbumEntity_owner"."avatarColor" AS "AlbumEntity__AlbumEntity_owner_avatarColor", + "AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin", + "AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email", + "AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel", + "AlbumEntity__AlbumEntity_owner"."externalPath" AS "AlbumEntity__AlbumEntity_owner_externalPath", + "AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId", + "AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath", + "AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword", + "AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt", + "AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt", + "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", + "AlbumEntity__AlbumEntity_owner"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_owner_memoriesEnabled", + "AlbumEntity__AlbumEntity_sharedUsers"."id" AS "AlbumEntity__AlbumEntity_sharedUsers_id", + "AlbumEntity__AlbumEntity_sharedUsers"."name" AS "AlbumEntity__AlbumEntity_sharedUsers_name", + "AlbumEntity__AlbumEntity_sharedUsers"."avatarColor" AS "AlbumEntity__AlbumEntity_sharedUsers_avatarColor", + "AlbumEntity__AlbumEntity_sharedUsers"."isAdmin" AS "AlbumEntity__AlbumEntity_sharedUsers_isAdmin", + "AlbumEntity__AlbumEntity_sharedUsers"."email" AS "AlbumEntity__AlbumEntity_sharedUsers_email", + "AlbumEntity__AlbumEntity_sharedUsers"."storageLabel" AS "AlbumEntity__AlbumEntity_sharedUsers_storageLabel", + "AlbumEntity__AlbumEntity_sharedUsers"."externalPath" AS "AlbumEntity__AlbumEntity_sharedUsers_externalPath", + "AlbumEntity__AlbumEntity_sharedUsers"."oauthId" AS "AlbumEntity__AlbumEntity_sharedUsers_oauthId", + "AlbumEntity__AlbumEntity_sharedUsers"."profileImagePath" AS "AlbumEntity__AlbumEntity_sharedUsers_profileImagePath", + "AlbumEntity__AlbumEntity_sharedUsers"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_sharedUsers_shouldChangePassword", + "AlbumEntity__AlbumEntity_sharedUsers"."createdAt" AS "AlbumEntity__AlbumEntity_sharedUsers_createdAt", + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_deletedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."updatedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_updatedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_sharedUsers_memoriesEnabled" +FROM + "albums" "AlbumEntity" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" + AND ( + "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL + ) + LEFT JOIN "albums_shared_users_users" "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity__AlbumEntity_sharedUsers"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."usersId" + AND ( + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL + ) + LEFT JOIN "albums_assets_assets" "AlbumEntity_AlbumEntity__AlbumEntity_assets" ON "AlbumEntity_AlbumEntity__AlbumEntity_assets"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "assets" "AlbumEntity__AlbumEntity_assets" ON "AlbumEntity__AlbumEntity_assets"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_assets"."assetsId" + AND ( + "AlbumEntity__AlbumEntity_assets"."deletedAt" IS NULL + ) +WHERE + ( + ( + ( + "AlbumEntity"."ownerId" = $1 + AND "AlbumEntity__AlbumEntity_assets"."id" = $2 + ) + OR ( + "AlbumEntity__AlbumEntity_sharedUsers"."id" = $3 + AND "AlbumEntity__AlbumEntity_assets"."id" = $4 + ) + ) + ) + AND ("AlbumEntity"."deletedAt" IS NULL) +ORDER BY + "AlbumEntity"."createdAt" DESC + +-- AlbumRepository.getMetadataForIds +SELECT + "album"."id" AS "album_id", + MIN("assets"."fileCreatedAt") AS "start_date", + MAX("assets"."fileCreatedAt") AS "end_date", + COUNT("album_assets"."assetsId") AS "asset_count" +FROM + "albums" "album" + LEFT JOIN "albums_assets_assets" "album_assets" ON "album_assets"."albumsId" = "album"."id" + LEFT JOIN "assets" "assets" ON "assets"."id" = "album_assets"."assetsId" + AND "assets"."deletedAt" IS NULL +WHERE + ("album"."id" IN ($1)) + AND ("album"."deletedAt" IS NULL) +GROUP BY + "album"."id" + +-- AlbumRepository.getInvalidThumbnail +SELECT + "albums"."id" AS "albums_id" +FROM + "albums" "albums" +WHERE + ( + "albums"."albumThumbnailAssetId" IS NULL + AND EXISTS ( + SELECT + 1 + FROM + "albums_assets_assets" "albums_assets" + WHERE + "albums"."id" = "albums_assets"."albumsId" + ) + OR "albums"."albumThumbnailAssetId" IS NOT NULL + AND NOT EXISTS ( + SELECT + 1 + FROM + "albums_assets_assets" "albums_assets" + WHERE + "albums"."id" = "albums_assets"."albumsId" + AND "albums"."albumThumbnailAssetId" = "albums_assets"."assetsId" + ) + ) + AND ("albums"."deletedAt" IS NULL) + +-- AlbumRepository.getOwned +SELECT + "AlbumEntity"."id" AS "AlbumEntity_id", + "AlbumEntity"."ownerId" AS "AlbumEntity_ownerId", + "AlbumEntity"."albumName" AS "AlbumEntity_albumName", + "AlbumEntity"."description" AS "AlbumEntity_description", + "AlbumEntity"."createdAt" AS "AlbumEntity_createdAt", + "AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt", + "AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt", + "AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId", + "AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled", + "AlbumEntity__AlbumEntity_sharedUsers"."id" AS "AlbumEntity__AlbumEntity_sharedUsers_id", + "AlbumEntity__AlbumEntity_sharedUsers"."name" AS "AlbumEntity__AlbumEntity_sharedUsers_name", + "AlbumEntity__AlbumEntity_sharedUsers"."avatarColor" AS "AlbumEntity__AlbumEntity_sharedUsers_avatarColor", + "AlbumEntity__AlbumEntity_sharedUsers"."isAdmin" AS "AlbumEntity__AlbumEntity_sharedUsers_isAdmin", + "AlbumEntity__AlbumEntity_sharedUsers"."email" AS "AlbumEntity__AlbumEntity_sharedUsers_email", + "AlbumEntity__AlbumEntity_sharedUsers"."storageLabel" AS "AlbumEntity__AlbumEntity_sharedUsers_storageLabel", + "AlbumEntity__AlbumEntity_sharedUsers"."externalPath" AS "AlbumEntity__AlbumEntity_sharedUsers_externalPath", + "AlbumEntity__AlbumEntity_sharedUsers"."oauthId" AS "AlbumEntity__AlbumEntity_sharedUsers_oauthId", + "AlbumEntity__AlbumEntity_sharedUsers"."profileImagePath" AS "AlbumEntity__AlbumEntity_sharedUsers_profileImagePath", + "AlbumEntity__AlbumEntity_sharedUsers"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_sharedUsers_shouldChangePassword", + "AlbumEntity__AlbumEntity_sharedUsers"."createdAt" AS "AlbumEntity__AlbumEntity_sharedUsers_createdAt", + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_deletedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."updatedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_updatedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_sharedUsers_memoriesEnabled", + "AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id", + "AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description", + "AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password", + "AlbumEntity__AlbumEntity_sharedLinks"."userId" AS "AlbumEntity__AlbumEntity_sharedLinks_userId", + "AlbumEntity__AlbumEntity_sharedLinks"."key" AS "AlbumEntity__AlbumEntity_sharedLinks_key", + "AlbumEntity__AlbumEntity_sharedLinks"."type" AS "AlbumEntity__AlbumEntity_sharedLinks_type", + "AlbumEntity__AlbumEntity_sharedLinks"."createdAt" AS "AlbumEntity__AlbumEntity_sharedLinks_createdAt", + "AlbumEntity__AlbumEntity_sharedLinks"."expiresAt" AS "AlbumEntity__AlbumEntity_sharedLinks_expiresAt", + "AlbumEntity__AlbumEntity_sharedLinks"."allowUpload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowUpload", + "AlbumEntity__AlbumEntity_sharedLinks"."allowDownload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowDownload", + "AlbumEntity__AlbumEntity_sharedLinks"."showExif" AS "AlbumEntity__AlbumEntity_sharedLinks_showExif", + "AlbumEntity__AlbumEntity_sharedLinks"."albumId" AS "AlbumEntity__AlbumEntity_sharedLinks_albumId", + "AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id", + "AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name", + "AlbumEntity__AlbumEntity_owner"."avatarColor" AS "AlbumEntity__AlbumEntity_owner_avatarColor", + "AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin", + "AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email", + "AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel", + "AlbumEntity__AlbumEntity_owner"."externalPath" AS "AlbumEntity__AlbumEntity_owner_externalPath", + "AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId", + "AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath", + "AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword", + "AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt", + "AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt", + "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", + "AlbumEntity__AlbumEntity_owner"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_owner_memoriesEnabled" +FROM + "albums" "AlbumEntity" + LEFT JOIN "albums_shared_users_users" "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity__AlbumEntity_sharedUsers"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."usersId" + AND ( + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL + ) + LEFT JOIN "shared_links" "AlbumEntity__AlbumEntity_sharedLinks" ON "AlbumEntity__AlbumEntity_sharedLinks"."albumId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" + AND ( + "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL + ) +WHERE + (("AlbumEntity"."ownerId" = $1)) + AND ("AlbumEntity"."deletedAt" IS NULL) +ORDER BY + "AlbumEntity"."createdAt" DESC + +-- AlbumRepository.getShared +SELECT + "AlbumEntity"."id" AS "AlbumEntity_id", + "AlbumEntity"."ownerId" AS "AlbumEntity_ownerId", + "AlbumEntity"."albumName" AS "AlbumEntity_albumName", + "AlbumEntity"."description" AS "AlbumEntity_description", + "AlbumEntity"."createdAt" AS "AlbumEntity_createdAt", + "AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt", + "AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt", + "AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId", + "AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled", + "AlbumEntity__AlbumEntity_sharedUsers"."id" AS "AlbumEntity__AlbumEntity_sharedUsers_id", + "AlbumEntity__AlbumEntity_sharedUsers"."name" AS "AlbumEntity__AlbumEntity_sharedUsers_name", + "AlbumEntity__AlbumEntity_sharedUsers"."avatarColor" AS "AlbumEntity__AlbumEntity_sharedUsers_avatarColor", + "AlbumEntity__AlbumEntity_sharedUsers"."isAdmin" AS "AlbumEntity__AlbumEntity_sharedUsers_isAdmin", + "AlbumEntity__AlbumEntity_sharedUsers"."email" AS "AlbumEntity__AlbumEntity_sharedUsers_email", + "AlbumEntity__AlbumEntity_sharedUsers"."storageLabel" AS "AlbumEntity__AlbumEntity_sharedUsers_storageLabel", + "AlbumEntity__AlbumEntity_sharedUsers"."externalPath" AS "AlbumEntity__AlbumEntity_sharedUsers_externalPath", + "AlbumEntity__AlbumEntity_sharedUsers"."oauthId" AS "AlbumEntity__AlbumEntity_sharedUsers_oauthId", + "AlbumEntity__AlbumEntity_sharedUsers"."profileImagePath" AS "AlbumEntity__AlbumEntity_sharedUsers_profileImagePath", + "AlbumEntity__AlbumEntity_sharedUsers"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_sharedUsers_shouldChangePassword", + "AlbumEntity__AlbumEntity_sharedUsers"."createdAt" AS "AlbumEntity__AlbumEntity_sharedUsers_createdAt", + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_deletedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."updatedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_updatedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_sharedUsers_memoriesEnabled", + "AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id", + "AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description", + "AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password", + "AlbumEntity__AlbumEntity_sharedLinks"."userId" AS "AlbumEntity__AlbumEntity_sharedLinks_userId", + "AlbumEntity__AlbumEntity_sharedLinks"."key" AS "AlbumEntity__AlbumEntity_sharedLinks_key", + "AlbumEntity__AlbumEntity_sharedLinks"."type" AS "AlbumEntity__AlbumEntity_sharedLinks_type", + "AlbumEntity__AlbumEntity_sharedLinks"."createdAt" AS "AlbumEntity__AlbumEntity_sharedLinks_createdAt", + "AlbumEntity__AlbumEntity_sharedLinks"."expiresAt" AS "AlbumEntity__AlbumEntity_sharedLinks_expiresAt", + "AlbumEntity__AlbumEntity_sharedLinks"."allowUpload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowUpload", + "AlbumEntity__AlbumEntity_sharedLinks"."allowDownload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowDownload", + "AlbumEntity__AlbumEntity_sharedLinks"."showExif" AS "AlbumEntity__AlbumEntity_sharedLinks_showExif", + "AlbumEntity__AlbumEntity_sharedLinks"."albumId" AS "AlbumEntity__AlbumEntity_sharedLinks_albumId", + "AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id", + "AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name", + "AlbumEntity__AlbumEntity_owner"."avatarColor" AS "AlbumEntity__AlbumEntity_owner_avatarColor", + "AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin", + "AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email", + "AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel", + "AlbumEntity__AlbumEntity_owner"."externalPath" AS "AlbumEntity__AlbumEntity_owner_externalPath", + "AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId", + "AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath", + "AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword", + "AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt", + "AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt", + "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", + "AlbumEntity__AlbumEntity_owner"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_owner_memoriesEnabled" +FROM + "albums" "AlbumEntity" + LEFT JOIN "albums_shared_users_users" "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity__AlbumEntity_sharedUsers"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."usersId" + AND ( + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL + ) + LEFT JOIN "shared_links" "AlbumEntity__AlbumEntity_sharedLinks" ON "AlbumEntity__AlbumEntity_sharedLinks"."albumId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" + AND ( + "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL + ) +WHERE + ( + ( + ("AlbumEntity__AlbumEntity_sharedUsers"."id" = $1) + OR ( + "AlbumEntity__AlbumEntity_sharedLinks"."userId" = $2 + ) + OR ( + "AlbumEntity"."ownerId" = $3 + AND NOT ( + "AlbumEntity__AlbumEntity_sharedUsers"."id" IS NULL + ) + ) + ) + ) + AND ("AlbumEntity"."deletedAt" IS NULL) +ORDER BY + "AlbumEntity"."createdAt" DESC + +-- AlbumRepository.getNotShared +SELECT + "AlbumEntity"."id" AS "AlbumEntity_id", + "AlbumEntity"."ownerId" AS "AlbumEntity_ownerId", + "AlbumEntity"."albumName" AS "AlbumEntity_albumName", + "AlbumEntity"."description" AS "AlbumEntity_description", + "AlbumEntity"."createdAt" AS "AlbumEntity_createdAt", + "AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt", + "AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt", + "AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId", + "AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled", + "AlbumEntity__AlbumEntity_sharedUsers"."id" AS "AlbumEntity__AlbumEntity_sharedUsers_id", + "AlbumEntity__AlbumEntity_sharedUsers"."name" AS "AlbumEntity__AlbumEntity_sharedUsers_name", + "AlbumEntity__AlbumEntity_sharedUsers"."avatarColor" AS "AlbumEntity__AlbumEntity_sharedUsers_avatarColor", + "AlbumEntity__AlbumEntity_sharedUsers"."isAdmin" AS "AlbumEntity__AlbumEntity_sharedUsers_isAdmin", + "AlbumEntity__AlbumEntity_sharedUsers"."email" AS "AlbumEntity__AlbumEntity_sharedUsers_email", + "AlbumEntity__AlbumEntity_sharedUsers"."storageLabel" AS "AlbumEntity__AlbumEntity_sharedUsers_storageLabel", + "AlbumEntity__AlbumEntity_sharedUsers"."externalPath" AS "AlbumEntity__AlbumEntity_sharedUsers_externalPath", + "AlbumEntity__AlbumEntity_sharedUsers"."oauthId" AS "AlbumEntity__AlbumEntity_sharedUsers_oauthId", + "AlbumEntity__AlbumEntity_sharedUsers"."profileImagePath" AS "AlbumEntity__AlbumEntity_sharedUsers_profileImagePath", + "AlbumEntity__AlbumEntity_sharedUsers"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_sharedUsers_shouldChangePassword", + "AlbumEntity__AlbumEntity_sharedUsers"."createdAt" AS "AlbumEntity__AlbumEntity_sharedUsers_createdAt", + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_deletedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."updatedAt" AS "AlbumEntity__AlbumEntity_sharedUsers_updatedAt", + "AlbumEntity__AlbumEntity_sharedUsers"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_sharedUsers_memoriesEnabled", + "AlbumEntity__AlbumEntity_sharedLinks"."id" AS "AlbumEntity__AlbumEntity_sharedLinks_id", + "AlbumEntity__AlbumEntity_sharedLinks"."description" AS "AlbumEntity__AlbumEntity_sharedLinks_description", + "AlbumEntity__AlbumEntity_sharedLinks"."password" AS "AlbumEntity__AlbumEntity_sharedLinks_password", + "AlbumEntity__AlbumEntity_sharedLinks"."userId" AS "AlbumEntity__AlbumEntity_sharedLinks_userId", + "AlbumEntity__AlbumEntity_sharedLinks"."key" AS "AlbumEntity__AlbumEntity_sharedLinks_key", + "AlbumEntity__AlbumEntity_sharedLinks"."type" AS "AlbumEntity__AlbumEntity_sharedLinks_type", + "AlbumEntity__AlbumEntity_sharedLinks"."createdAt" AS "AlbumEntity__AlbumEntity_sharedLinks_createdAt", + "AlbumEntity__AlbumEntity_sharedLinks"."expiresAt" AS "AlbumEntity__AlbumEntity_sharedLinks_expiresAt", + "AlbumEntity__AlbumEntity_sharedLinks"."allowUpload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowUpload", + "AlbumEntity__AlbumEntity_sharedLinks"."allowDownload" AS "AlbumEntity__AlbumEntity_sharedLinks_allowDownload", + "AlbumEntity__AlbumEntity_sharedLinks"."showExif" AS "AlbumEntity__AlbumEntity_sharedLinks_showExif", + "AlbumEntity__AlbumEntity_sharedLinks"."albumId" AS "AlbumEntity__AlbumEntity_sharedLinks_albumId", + "AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id", + "AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name", + "AlbumEntity__AlbumEntity_owner"."avatarColor" AS "AlbumEntity__AlbumEntity_owner_avatarColor", + "AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin", + "AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email", + "AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel", + "AlbumEntity__AlbumEntity_owner"."externalPath" AS "AlbumEntity__AlbumEntity_owner_externalPath", + "AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId", + "AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath", + "AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword", + "AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt", + "AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt", + "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", + "AlbumEntity__AlbumEntity_owner"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_owner_memoriesEnabled" +FROM + "albums" "AlbumEntity" + LEFT JOIN "albums_shared_users_users" "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_sharedUsers" ON "AlbumEntity__AlbumEntity_sharedUsers"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."usersId" + AND ( + "AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL + ) + LEFT JOIN "shared_links" "AlbumEntity__AlbumEntity_sharedLinks" ON "AlbumEntity__AlbumEntity_sharedLinks"."albumId" = "AlbumEntity"."id" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" + AND ( + "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL + ) +WHERE + ( + ( + "AlbumEntity"."ownerId" = $1 + AND "AlbumEntity__AlbumEntity_sharedUsers"."id" IS NULL + AND "AlbumEntity__AlbumEntity_sharedLinks"."id" IS NULL + ) + ) + AND ("AlbumEntity"."deletedAt" IS NULL) +ORDER BY + "AlbumEntity"."createdAt" DESC + +-- AlbumRepository.getAll +SELECT + "AlbumEntity"."id" AS "AlbumEntity_id", + "AlbumEntity"."ownerId" AS "AlbumEntity_ownerId", + "AlbumEntity"."albumName" AS "AlbumEntity_albumName", + "AlbumEntity"."description" AS "AlbumEntity_description", + "AlbumEntity"."createdAt" AS "AlbumEntity_createdAt", + "AlbumEntity"."updatedAt" AS "AlbumEntity_updatedAt", + "AlbumEntity"."deletedAt" AS "AlbumEntity_deletedAt", + "AlbumEntity"."albumThumbnailAssetId" AS "AlbumEntity_albumThumbnailAssetId", + "AlbumEntity"."isActivityEnabled" AS "AlbumEntity_isActivityEnabled", + "AlbumEntity__AlbumEntity_owner"."id" AS "AlbumEntity__AlbumEntity_owner_id", + "AlbumEntity__AlbumEntity_owner"."name" AS "AlbumEntity__AlbumEntity_owner_name", + "AlbumEntity__AlbumEntity_owner"."avatarColor" AS "AlbumEntity__AlbumEntity_owner_avatarColor", + "AlbumEntity__AlbumEntity_owner"."isAdmin" AS "AlbumEntity__AlbumEntity_owner_isAdmin", + "AlbumEntity__AlbumEntity_owner"."email" AS "AlbumEntity__AlbumEntity_owner_email", + "AlbumEntity__AlbumEntity_owner"."storageLabel" AS "AlbumEntity__AlbumEntity_owner_storageLabel", + "AlbumEntity__AlbumEntity_owner"."externalPath" AS "AlbumEntity__AlbumEntity_owner_externalPath", + "AlbumEntity__AlbumEntity_owner"."oauthId" AS "AlbumEntity__AlbumEntity_owner_oauthId", + "AlbumEntity__AlbumEntity_owner"."profileImagePath" AS "AlbumEntity__AlbumEntity_owner_profileImagePath", + "AlbumEntity__AlbumEntity_owner"."shouldChangePassword" AS "AlbumEntity__AlbumEntity_owner_shouldChangePassword", + "AlbumEntity__AlbumEntity_owner"."createdAt" AS "AlbumEntity__AlbumEntity_owner_createdAt", + "AlbumEntity__AlbumEntity_owner"."deletedAt" AS "AlbumEntity__AlbumEntity_owner_deletedAt", + "AlbumEntity__AlbumEntity_owner"."updatedAt" AS "AlbumEntity__AlbumEntity_owner_updatedAt", + "AlbumEntity__AlbumEntity_owner"."memoriesEnabled" AS "AlbumEntity__AlbumEntity_owner_memoriesEnabled" +FROM + "albums" "AlbumEntity" + LEFT JOIN "users" "AlbumEntity__AlbumEntity_owner" ON "AlbumEntity__AlbumEntity_owner"."id" = "AlbumEntity"."ownerId" + AND ( + "AlbumEntity__AlbumEntity_owner"."deletedAt" IS NULL + ) +WHERE + "AlbumEntity"."deletedAt" IS NULL + +-- AlbumRepository.removeAssets +DELETE FROM "albums_assets_assets" +WHERE + ( + "albumsId" = $1 + AND "assetsId" IN ($2) + ) + +-- AlbumRepository.getAssetIds +SELECT + "albums_assets"."assetsId" AS "assetId" +FROM + "albums_assets_assets" "albums_assets" +WHERE + "albums_assets"."albumsId" = $1 + AND "albums_assets"."assetsId" IN ($2) + +-- AlbumRepository.getAssetIds (no assets) +SELECT + "albums_assets"."assetsId" AS "assetId" +FROM + "albums_assets_assets" "albums_assets" +WHERE + "albums_assets"."albumsId" = $1 + +-- AlbumRepository.hasAsset +SELECT + 1 AS "row_exists" +FROM + ( + SELECT + 1 AS dummy_column + ) "dummy_table" +WHERE + EXISTS ( + SELECT + 1 + FROM + "albums" "AlbumEntity" + LEFT JOIN "albums_assets_assets" "AlbumEntity_AlbumEntity__AlbumEntity_assets" ON "AlbumEntity_AlbumEntity__AlbumEntity_assets"."albumsId" = "AlbumEntity"."id" + LEFT JOIN "assets" "AlbumEntity__AlbumEntity_assets" ON "AlbumEntity__AlbumEntity_assets"."id" = "AlbumEntity_AlbumEntity__AlbumEntity_assets"."assetsId" + AND ( + "AlbumEntity__AlbumEntity_assets"."deletedAt" IS NULL + ) + WHERE + ( + ( + "AlbumEntity"."id" = $1 + AND "AlbumEntity__AlbumEntity_assets"."id" = $2 + ) + ) + AND ("AlbumEntity"."deletedAt" IS NULL) + ) +LIMIT + 1 + +-- AlbumRepository.addAssets +INSERT INTO + "albums_assets_assets" ("albumsId", "assetsId") +VALUES + ($1, $2) + +-- AlbumRepository.updateThumbnails +UPDATE "albums" +SET + "albumThumbnailAssetId" = ( + SELECT + "albums_assets2"."assetsId" + FROM + "assets" "assets", + "albums_assets_assets" "albums_assets2" + WHERE + ( + "albums_assets2"."assetsId" = "assets"."id" + AND "albums_assets2"."albumsId" = "albums"."id" + ) + AND ("assets"."deletedAt" IS NULL) + ORDER BY + "assets"."fileCreatedAt" DESC + LIMIT + 1 + ), + "updatedAt" = CURRENT_TIMESTAMP +WHERE + "albums"."albumThumbnailAssetId" IS NULL + AND EXISTS ( + SELECT + 1 + FROM + "albums_assets_assets" "albums_assets" + WHERE + "albums"."id" = "albums_assets"."albumsId" + ) + OR "albums"."albumThumbnailAssetId" IS NOT NULL + AND NOT EXISTS ( + SELECT + 1 + FROM + "albums_assets_assets" "albums_assets" + WHERE + "albums"."id" = "albums_assets"."albumsId" + AND "albums"."albumThumbnailAssetId" = "albums_assets"."assetsId" + ) diff --git a/server/src/infra/sql/api.key.repository.sql b/server/src/infra/sql/api.key.repository.sql new file mode 100644 index 000000000..7f26d8575 --- /dev/null +++ b/server/src/infra/sql/api.key.repository.sql @@ -0,0 +1,69 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- ApiKeyRepository.getKey +SELECT DISTINCT + "distinctAlias"."APIKeyEntity_id" AS "ids_APIKeyEntity_id" +FROM + ( + SELECT + "APIKeyEntity"."id" AS "APIKeyEntity_id", + "APIKeyEntity"."key" AS "APIKeyEntity_key", + "APIKeyEntity"."userId" AS "APIKeyEntity_userId", + "APIKeyEntity__APIKeyEntity_user"."id" AS "APIKeyEntity__APIKeyEntity_user_id", + "APIKeyEntity__APIKeyEntity_user"."name" AS "APIKeyEntity__APIKeyEntity_user_name", + "APIKeyEntity__APIKeyEntity_user"."avatarColor" AS "APIKeyEntity__APIKeyEntity_user_avatarColor", + "APIKeyEntity__APIKeyEntity_user"."isAdmin" AS "APIKeyEntity__APIKeyEntity_user_isAdmin", + "APIKeyEntity__APIKeyEntity_user"."email" AS "APIKeyEntity__APIKeyEntity_user_email", + "APIKeyEntity__APIKeyEntity_user"."storageLabel" AS "APIKeyEntity__APIKeyEntity_user_storageLabel", + "APIKeyEntity__APIKeyEntity_user"."externalPath" AS "APIKeyEntity__APIKeyEntity_user_externalPath", + "APIKeyEntity__APIKeyEntity_user"."oauthId" AS "APIKeyEntity__APIKeyEntity_user_oauthId", + "APIKeyEntity__APIKeyEntity_user"."profileImagePath" AS "APIKeyEntity__APIKeyEntity_user_profileImagePath", + "APIKeyEntity__APIKeyEntity_user"."shouldChangePassword" AS "APIKeyEntity__APIKeyEntity_user_shouldChangePassword", + "APIKeyEntity__APIKeyEntity_user"."createdAt" AS "APIKeyEntity__APIKeyEntity_user_createdAt", + "APIKeyEntity__APIKeyEntity_user"."deletedAt" AS "APIKeyEntity__APIKeyEntity_user_deletedAt", + "APIKeyEntity__APIKeyEntity_user"."updatedAt" AS "APIKeyEntity__APIKeyEntity_user_updatedAt", + "APIKeyEntity__APIKeyEntity_user"."memoriesEnabled" AS "APIKeyEntity__APIKeyEntity_user_memoriesEnabled" + FROM + "api_keys" "APIKeyEntity" + LEFT JOIN "users" "APIKeyEntity__APIKeyEntity_user" ON "APIKeyEntity__APIKeyEntity_user"."id" = "APIKeyEntity"."userId" + AND ( + "APIKeyEntity__APIKeyEntity_user"."deletedAt" IS NULL + ) + WHERE + ("APIKeyEntity"."key" = $1) + ) "distinctAlias" +ORDER BY + "APIKeyEntity_id" ASC +LIMIT + 1 + +-- ApiKeyRepository.getById +SELECT + "APIKeyEntity"."id" AS "APIKeyEntity_id", + "APIKeyEntity"."name" AS "APIKeyEntity_name", + "APIKeyEntity"."userId" AS "APIKeyEntity_userId", + "APIKeyEntity"."createdAt" AS "APIKeyEntity_createdAt", + "APIKeyEntity"."updatedAt" AS "APIKeyEntity_updatedAt" +FROM + "api_keys" "APIKeyEntity" +WHERE + ( + "APIKeyEntity"."userId" = $1 + AND "APIKeyEntity"."id" = $2 + ) +LIMIT + 1 + +-- ApiKeyRepository.getByUserId +SELECT + "APIKeyEntity"."id" AS "APIKeyEntity_id", + "APIKeyEntity"."name" AS "APIKeyEntity_name", + "APIKeyEntity"."userId" AS "APIKeyEntity_userId", + "APIKeyEntity"."createdAt" AS "APIKeyEntity_createdAt", + "APIKeyEntity"."updatedAt" AS "APIKeyEntity_updatedAt" +FROM + "api_keys" "APIKeyEntity" +WHERE + ("APIKeyEntity"."userId" = $1) +ORDER BY + "APIKeyEntity"."createdAt" DESC diff --git a/server/src/infra/sql/asset.repository.sql b/server/src/infra/sql/asset.repository.sql new file mode 100644 index 000000000..c970c997b --- /dev/null +++ b/server/src/infra/sql/asset.repository.sql @@ -0,0 +1,614 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- AssetRepository.getByDate +SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId", + "AssetEntity__AssetEntity_exifInfo"."assetId" AS "AssetEntity__AssetEntity_exifInfo_assetId", + "AssetEntity__AssetEntity_exifInfo"."description" AS "AssetEntity__AssetEntity_exifInfo_description", + "AssetEntity__AssetEntity_exifInfo"."exifImageWidth" AS "AssetEntity__AssetEntity_exifInfo_exifImageWidth", + "AssetEntity__AssetEntity_exifInfo"."exifImageHeight" AS "AssetEntity__AssetEntity_exifInfo_exifImageHeight", + "AssetEntity__AssetEntity_exifInfo"."fileSizeInByte" AS "AssetEntity__AssetEntity_exifInfo_fileSizeInByte", + "AssetEntity__AssetEntity_exifInfo"."orientation" AS "AssetEntity__AssetEntity_exifInfo_orientation", + "AssetEntity__AssetEntity_exifInfo"."dateTimeOriginal" AS "AssetEntity__AssetEntity_exifInfo_dateTimeOriginal", + "AssetEntity__AssetEntity_exifInfo"."modifyDate" AS "AssetEntity__AssetEntity_exifInfo_modifyDate", + "AssetEntity__AssetEntity_exifInfo"."timeZone" AS "AssetEntity__AssetEntity_exifInfo_timeZone", + "AssetEntity__AssetEntity_exifInfo"."latitude" AS "AssetEntity__AssetEntity_exifInfo_latitude", + "AssetEntity__AssetEntity_exifInfo"."longitude" AS "AssetEntity__AssetEntity_exifInfo_longitude", + "AssetEntity__AssetEntity_exifInfo"."projectionType" AS "AssetEntity__AssetEntity_exifInfo_projectionType", + "AssetEntity__AssetEntity_exifInfo"."city" AS "AssetEntity__AssetEntity_exifInfo_city", + "AssetEntity__AssetEntity_exifInfo"."livePhotoCID" AS "AssetEntity__AssetEntity_exifInfo_livePhotoCID", + "AssetEntity__AssetEntity_exifInfo"."state" AS "AssetEntity__AssetEntity_exifInfo_state", + "AssetEntity__AssetEntity_exifInfo"."country" AS "AssetEntity__AssetEntity_exifInfo_country", + "AssetEntity__AssetEntity_exifInfo"."make" AS "AssetEntity__AssetEntity_exifInfo_make", + "AssetEntity__AssetEntity_exifInfo"."model" AS "AssetEntity__AssetEntity_exifInfo_model", + "AssetEntity__AssetEntity_exifInfo"."lensModel" AS "AssetEntity__AssetEntity_exifInfo_lensModel", + "AssetEntity__AssetEntity_exifInfo"."fNumber" AS "AssetEntity__AssetEntity_exifInfo_fNumber", + "AssetEntity__AssetEntity_exifInfo"."focalLength" AS "AssetEntity__AssetEntity_exifInfo_focalLength", + "AssetEntity__AssetEntity_exifInfo"."iso" AS "AssetEntity__AssetEntity_exifInfo_iso", + "AssetEntity__AssetEntity_exifInfo"."exposureTime" AS "AssetEntity__AssetEntity_exifInfo_exposureTime", + "AssetEntity__AssetEntity_exifInfo"."profileDescription" AS "AssetEntity__AssetEntity_exifInfo_profileDescription", + "AssetEntity__AssetEntity_exifInfo"."colorspace" AS "AssetEntity__AssetEntity_exifInfo_colorspace", + "AssetEntity__AssetEntity_exifInfo"."bitsPerSample" AS "AssetEntity__AssetEntity_exifInfo_bitsPerSample", + "AssetEntity__AssetEntity_exifInfo"."fps" AS "AssetEntity__AssetEntity_exifInfo_fps", + "AssetEntity__AssetEntity_exifInfo"."exifTextSearchableColumn" AS "AssetEntity__AssetEntity_exifInfo_exifTextSearchableColumn" +FROM + "assets" "AssetEntity" + LEFT JOIN "exif" "AssetEntity__AssetEntity_exifInfo" ON "AssetEntity__AssetEntity_exifInfo"."assetId" = "AssetEntity"."id" +WHERE + ( + ( + "AssetEntity"."ownerId" = $1 + AND "AssetEntity"."isVisible" = $2 + AND "AssetEntity"."isArchived" = $3 + AND NOT ("AssetEntity"."resizePath" IS NULL) + AND "AssetEntity"."fileCreatedAt" BETWEEN $4 AND $5 + ) + ) + AND ("AssetEntity"."deletedAt" IS NULL) +ORDER BY + "AssetEntity"."fileCreatedAt" DESC + +-- AssetRepository.getByDayOfYear +SELECT + "entity"."id" AS "entity_id", + "entity"."deviceAssetId" AS "entity_deviceAssetId", + "entity"."ownerId" AS "entity_ownerId", + "entity"."libraryId" AS "entity_libraryId", + "entity"."deviceId" AS "entity_deviceId", + "entity"."type" AS "entity_type", + "entity"."originalPath" AS "entity_originalPath", + "entity"."resizePath" AS "entity_resizePath", + "entity"."webpPath" AS "entity_webpPath", + "entity"."thumbhash" AS "entity_thumbhash", + "entity"."encodedVideoPath" AS "entity_encodedVideoPath", + "entity"."createdAt" AS "entity_createdAt", + "entity"."updatedAt" AS "entity_updatedAt", + "entity"."deletedAt" AS "entity_deletedAt", + "entity"."fileCreatedAt" AS "entity_fileCreatedAt", + "entity"."localDateTime" AS "entity_localDateTime", + "entity"."fileModifiedAt" AS "entity_fileModifiedAt", + "entity"."isFavorite" AS "entity_isFavorite", + "entity"."isArchived" AS "entity_isArchived", + "entity"."isExternal" AS "entity_isExternal", + "entity"."isReadOnly" AS "entity_isReadOnly", + "entity"."isOffline" AS "entity_isOffline", + "entity"."checksum" AS "entity_checksum", + "entity"."duration" AS "entity_duration", + "entity"."isVisible" AS "entity_isVisible", + "entity"."livePhotoVideoId" AS "entity_livePhotoVideoId", + "entity"."originalFileName" AS "entity_originalFileName", + "entity"."sidecarPath" AS "entity_sidecarPath", + "entity"."stackParentId" AS "entity_stackParentId", + "exifInfo"."assetId" AS "exifInfo_assetId", + "exifInfo"."description" AS "exifInfo_description", + "exifInfo"."exifImageWidth" AS "exifInfo_exifImageWidth", + "exifInfo"."exifImageHeight" AS "exifInfo_exifImageHeight", + "exifInfo"."fileSizeInByte" AS "exifInfo_fileSizeInByte", + "exifInfo"."orientation" AS "exifInfo_orientation", + "exifInfo"."dateTimeOriginal" AS "exifInfo_dateTimeOriginal", + "exifInfo"."modifyDate" AS "exifInfo_modifyDate", + "exifInfo"."timeZone" AS "exifInfo_timeZone", + "exifInfo"."latitude" AS "exifInfo_latitude", + "exifInfo"."longitude" AS "exifInfo_longitude", + "exifInfo"."projectionType" AS "exifInfo_projectionType", + "exifInfo"."city" AS "exifInfo_city", + "exifInfo"."livePhotoCID" AS "exifInfo_livePhotoCID", + "exifInfo"."state" AS "exifInfo_state", + "exifInfo"."country" AS "exifInfo_country", + "exifInfo"."make" AS "exifInfo_make", + "exifInfo"."model" AS "exifInfo_model", + "exifInfo"."lensModel" AS "exifInfo_lensModel", + "exifInfo"."fNumber" AS "exifInfo_fNumber", + "exifInfo"."focalLength" AS "exifInfo_focalLength", + "exifInfo"."iso" AS "exifInfo_iso", + "exifInfo"."exposureTime" AS "exifInfo_exposureTime", + "exifInfo"."profileDescription" AS "exifInfo_profileDescription", + "exifInfo"."colorspace" AS "exifInfo_colorspace", + "exifInfo"."bitsPerSample" AS "exifInfo_bitsPerSample", + "exifInfo"."fps" AS "exifInfo_fps", + "exifInfo"."exifTextSearchableColumn" AS "exifInfo_exifTextSearchableColumn" +FROM + "assets" "entity" + LEFT JOIN "exif" "exifInfo" ON "exifInfo"."assetId" = "entity"."id" +WHERE + ( + "entity"."ownerId" = $1 + AND "entity"."isVisible" = true + AND "entity"."isArchived" = false + AND "entity"."resizePath" IS NOT NULL + AND EXTRACT( + DAY + FROM + "entity"."localDateTime" AT TIME ZONE 'UTC' + ) = $2 + AND EXTRACT( + MONTH + FROM + "entity"."localDateTime" AT TIME ZONE 'UTC' + ) = $3 + ) + AND ("entity"."deletedAt" IS NULL) +ORDER BY + "entity"."localDateTime" DESC + +-- AssetRepository.getByIds +SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId", + "AssetEntity__AssetEntity_exifInfo"."assetId" AS "AssetEntity__AssetEntity_exifInfo_assetId", + "AssetEntity__AssetEntity_exifInfo"."description" AS "AssetEntity__AssetEntity_exifInfo_description", + "AssetEntity__AssetEntity_exifInfo"."exifImageWidth" AS "AssetEntity__AssetEntity_exifInfo_exifImageWidth", + "AssetEntity__AssetEntity_exifInfo"."exifImageHeight" AS "AssetEntity__AssetEntity_exifInfo_exifImageHeight", + "AssetEntity__AssetEntity_exifInfo"."fileSizeInByte" AS "AssetEntity__AssetEntity_exifInfo_fileSizeInByte", + "AssetEntity__AssetEntity_exifInfo"."orientation" AS "AssetEntity__AssetEntity_exifInfo_orientation", + "AssetEntity__AssetEntity_exifInfo"."dateTimeOriginal" AS "AssetEntity__AssetEntity_exifInfo_dateTimeOriginal", + "AssetEntity__AssetEntity_exifInfo"."modifyDate" AS "AssetEntity__AssetEntity_exifInfo_modifyDate", + "AssetEntity__AssetEntity_exifInfo"."timeZone" AS "AssetEntity__AssetEntity_exifInfo_timeZone", + "AssetEntity__AssetEntity_exifInfo"."latitude" AS "AssetEntity__AssetEntity_exifInfo_latitude", + "AssetEntity__AssetEntity_exifInfo"."longitude" AS "AssetEntity__AssetEntity_exifInfo_longitude", + "AssetEntity__AssetEntity_exifInfo"."projectionType" AS "AssetEntity__AssetEntity_exifInfo_projectionType", + "AssetEntity__AssetEntity_exifInfo"."city" AS "AssetEntity__AssetEntity_exifInfo_city", + "AssetEntity__AssetEntity_exifInfo"."livePhotoCID" AS "AssetEntity__AssetEntity_exifInfo_livePhotoCID", + "AssetEntity__AssetEntity_exifInfo"."state" AS "AssetEntity__AssetEntity_exifInfo_state", + "AssetEntity__AssetEntity_exifInfo"."country" AS "AssetEntity__AssetEntity_exifInfo_country", + "AssetEntity__AssetEntity_exifInfo"."make" AS "AssetEntity__AssetEntity_exifInfo_make", + "AssetEntity__AssetEntity_exifInfo"."model" AS "AssetEntity__AssetEntity_exifInfo_model", + "AssetEntity__AssetEntity_exifInfo"."lensModel" AS "AssetEntity__AssetEntity_exifInfo_lensModel", + "AssetEntity__AssetEntity_exifInfo"."fNumber" AS "AssetEntity__AssetEntity_exifInfo_fNumber", + "AssetEntity__AssetEntity_exifInfo"."focalLength" AS "AssetEntity__AssetEntity_exifInfo_focalLength", + "AssetEntity__AssetEntity_exifInfo"."iso" AS "AssetEntity__AssetEntity_exifInfo_iso", + "AssetEntity__AssetEntity_exifInfo"."exposureTime" AS "AssetEntity__AssetEntity_exifInfo_exposureTime", + "AssetEntity__AssetEntity_exifInfo"."profileDescription" AS "AssetEntity__AssetEntity_exifInfo_profileDescription", + "AssetEntity__AssetEntity_exifInfo"."colorspace" AS "AssetEntity__AssetEntity_exifInfo_colorspace", + "AssetEntity__AssetEntity_exifInfo"."bitsPerSample" AS "AssetEntity__AssetEntity_exifInfo_bitsPerSample", + "AssetEntity__AssetEntity_exifInfo"."fps" AS "AssetEntity__AssetEntity_exifInfo_fps", + "AssetEntity__AssetEntity_exifInfo"."exifTextSearchableColumn" AS "AssetEntity__AssetEntity_exifInfo_exifTextSearchableColumn", + "AssetEntity__AssetEntity_smartInfo"."assetId" AS "AssetEntity__AssetEntity_smartInfo_assetId", + "AssetEntity__AssetEntity_smartInfo"."tags" AS "AssetEntity__AssetEntity_smartInfo_tags", + "AssetEntity__AssetEntity_smartInfo"."objects" AS "AssetEntity__AssetEntity_smartInfo_objects", + "AssetEntity__AssetEntity_smartInfo"."clipEmbedding" AS "AssetEntity__AssetEntity_smartInfo_clipEmbedding", + "AssetEntity__AssetEntity_tags"."id" AS "AssetEntity__AssetEntity_tags_id", + "AssetEntity__AssetEntity_tags"."type" AS "AssetEntity__AssetEntity_tags_type", + "AssetEntity__AssetEntity_tags"."name" AS "AssetEntity__AssetEntity_tags_name", + "AssetEntity__AssetEntity_tags"."userId" AS "AssetEntity__AssetEntity_tags_userId", + "AssetEntity__AssetEntity_tags"."renameTagId" AS "AssetEntity__AssetEntity_tags_renameTagId", + "AssetEntity__AssetEntity_faces"."id" AS "AssetEntity__AssetEntity_faces_id", + "AssetEntity__AssetEntity_faces"."assetId" AS "AssetEntity__AssetEntity_faces_assetId", + "AssetEntity__AssetEntity_faces"."personId" AS "AssetEntity__AssetEntity_faces_personId", + "AssetEntity__AssetEntity_faces"."embedding" AS "AssetEntity__AssetEntity_faces_embedding", + "AssetEntity__AssetEntity_faces"."imageWidth" AS "AssetEntity__AssetEntity_faces_imageWidth", + "AssetEntity__AssetEntity_faces"."imageHeight" AS "AssetEntity__AssetEntity_faces_imageHeight", + "AssetEntity__AssetEntity_faces"."boundingBoxX1" AS "AssetEntity__AssetEntity_faces_boundingBoxX1", + "AssetEntity__AssetEntity_faces"."boundingBoxY1" AS "AssetEntity__AssetEntity_faces_boundingBoxY1", + "AssetEntity__AssetEntity_faces"."boundingBoxX2" AS "AssetEntity__AssetEntity_faces_boundingBoxX2", + "AssetEntity__AssetEntity_faces"."boundingBoxY2" AS "AssetEntity__AssetEntity_faces_boundingBoxY2", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."id" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_id", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."createdAt" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_createdAt", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."updatedAt" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_updatedAt", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."ownerId" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_ownerId", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."name" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_name", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."birthDate" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_birthDate", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."thumbnailPath" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_thumbnailPath", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."faceAssetId" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_faceAssetId", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."isHidden" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_isHidden", + "AssetEntity__AssetEntity_stack"."id" AS "AssetEntity__AssetEntity_stack_id", + "AssetEntity__AssetEntity_stack"."deviceAssetId" AS "AssetEntity__AssetEntity_stack_deviceAssetId", + "AssetEntity__AssetEntity_stack"."ownerId" AS "AssetEntity__AssetEntity_stack_ownerId", + "AssetEntity__AssetEntity_stack"."libraryId" AS "AssetEntity__AssetEntity_stack_libraryId", + "AssetEntity__AssetEntity_stack"."deviceId" AS "AssetEntity__AssetEntity_stack_deviceId", + "AssetEntity__AssetEntity_stack"."type" AS "AssetEntity__AssetEntity_stack_type", + "AssetEntity__AssetEntity_stack"."originalPath" AS "AssetEntity__AssetEntity_stack_originalPath", + "AssetEntity__AssetEntity_stack"."resizePath" AS "AssetEntity__AssetEntity_stack_resizePath", + "AssetEntity__AssetEntity_stack"."webpPath" AS "AssetEntity__AssetEntity_stack_webpPath", + "AssetEntity__AssetEntity_stack"."thumbhash" AS "AssetEntity__AssetEntity_stack_thumbhash", + "AssetEntity__AssetEntity_stack"."encodedVideoPath" AS "AssetEntity__AssetEntity_stack_encodedVideoPath", + "AssetEntity__AssetEntity_stack"."createdAt" AS "AssetEntity__AssetEntity_stack_createdAt", + "AssetEntity__AssetEntity_stack"."updatedAt" AS "AssetEntity__AssetEntity_stack_updatedAt", + "AssetEntity__AssetEntity_stack"."deletedAt" AS "AssetEntity__AssetEntity_stack_deletedAt", + "AssetEntity__AssetEntity_stack"."fileCreatedAt" AS "AssetEntity__AssetEntity_stack_fileCreatedAt", + "AssetEntity__AssetEntity_stack"."localDateTime" AS "AssetEntity__AssetEntity_stack_localDateTime", + "AssetEntity__AssetEntity_stack"."fileModifiedAt" AS "AssetEntity__AssetEntity_stack_fileModifiedAt", + "AssetEntity__AssetEntity_stack"."isFavorite" AS "AssetEntity__AssetEntity_stack_isFavorite", + "AssetEntity__AssetEntity_stack"."isArchived" AS "AssetEntity__AssetEntity_stack_isArchived", + "AssetEntity__AssetEntity_stack"."isExternal" AS "AssetEntity__AssetEntity_stack_isExternal", + "AssetEntity__AssetEntity_stack"."isReadOnly" AS "AssetEntity__AssetEntity_stack_isReadOnly", + "AssetEntity__AssetEntity_stack"."isOffline" AS "AssetEntity__AssetEntity_stack_isOffline", + "AssetEntity__AssetEntity_stack"."checksum" AS "AssetEntity__AssetEntity_stack_checksum", + "AssetEntity__AssetEntity_stack"."duration" AS "AssetEntity__AssetEntity_stack_duration", + "AssetEntity__AssetEntity_stack"."isVisible" AS "AssetEntity__AssetEntity_stack_isVisible", + "AssetEntity__AssetEntity_stack"."livePhotoVideoId" AS "AssetEntity__AssetEntity_stack_livePhotoVideoId", + "AssetEntity__AssetEntity_stack"."originalFileName" AS "AssetEntity__AssetEntity_stack_originalFileName", + "AssetEntity__AssetEntity_stack"."sidecarPath" AS "AssetEntity__AssetEntity_stack_sidecarPath", + "AssetEntity__AssetEntity_stack"."stackParentId" AS "AssetEntity__AssetEntity_stack_stackParentId" +FROM + "assets" "AssetEntity" + LEFT JOIN "exif" "AssetEntity__AssetEntity_exifInfo" ON "AssetEntity__AssetEntity_exifInfo"."assetId" = "AssetEntity"."id" + LEFT JOIN "smart_info" "AssetEntity__AssetEntity_smartInfo" ON "AssetEntity__AssetEntity_smartInfo"."assetId" = "AssetEntity"."id" + LEFT JOIN "tag_asset" "AssetEntity_AssetEntity__AssetEntity_tags" ON "AssetEntity_AssetEntity__AssetEntity_tags"."assetsId" = "AssetEntity"."id" + LEFT JOIN "tags" "AssetEntity__AssetEntity_tags" ON "AssetEntity__AssetEntity_tags"."id" = "AssetEntity_AssetEntity__AssetEntity_tags"."tagsId" + LEFT JOIN "asset_faces" "AssetEntity__AssetEntity_faces" ON "AssetEntity__AssetEntity_faces"."assetId" = "AssetEntity"."id" + LEFT JOIN "person" "8258e303a73a72cf6abb13d73fb592dde0d68280" ON "8258e303a73a72cf6abb13d73fb592dde0d68280"."id" = "AssetEntity__AssetEntity_faces"."personId" + LEFT JOIN "assets" "AssetEntity__AssetEntity_stack" ON "AssetEntity__AssetEntity_stack"."stackParentId" = "AssetEntity"."id" +WHERE + ("AssetEntity"."id" IN ($1)) + +-- AssetRepository.deleteAll +DELETE FROM "assets" +WHERE + "ownerId" = $1 + +-- AssetRepository.getByLibraryId +SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId" +FROM + "assets" "AssetEntity" + LEFT JOIN "libraries" "AssetEntity__AssetEntity_library" ON "AssetEntity__AssetEntity_library"."id" = "AssetEntity"."libraryId" + AND ( + "AssetEntity__AssetEntity_library"."deletedAt" IS NULL + ) +WHERE + (("AssetEntity__AssetEntity_library"."id" IN ($1))) + AND ("AssetEntity"."deletedAt" IS NULL) + +-- AssetRepository.getByLibraryIdAndOriginalPath +SELECT DISTINCT + "distinctAlias"."AssetEntity_id" AS "ids_AssetEntity_id" +FROM + ( + SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId" + FROM + "assets" "AssetEntity" + LEFT JOIN "libraries" "AssetEntity__AssetEntity_library" ON "AssetEntity__AssetEntity_library"."id" = "AssetEntity"."libraryId" + AND ( + "AssetEntity__AssetEntity_library"."deletedAt" IS NULL + ) + WHERE + ( + ( + "AssetEntity__AssetEntity_library"."id" = $1 + AND "AssetEntity"."originalPath" = $2 + ) + ) + AND ("AssetEntity"."deletedAt" IS NULL) + ) "distinctAlias" +ORDER BY + "AssetEntity_id" ASC +LIMIT + 1 + +-- AssetRepository.getAllByDeviceId +SELECT + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."id" AS "AssetEntity_id" +FROM + "assets" "AssetEntity" +WHERE + ( + "AssetEntity"."ownerId" = $1 + AND "AssetEntity"."deviceId" = $2 + AND "AssetEntity"."isVisible" = $3 + ) + +-- AssetRepository.getById +SELECT DISTINCT + "distinctAlias"."AssetEntity_id" AS "ids_AssetEntity_id" +FROM + ( + SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId", + "AssetEntity__AssetEntity_faces"."id" AS "AssetEntity__AssetEntity_faces_id", + "AssetEntity__AssetEntity_faces"."assetId" AS "AssetEntity__AssetEntity_faces_assetId", + "AssetEntity__AssetEntity_faces"."personId" AS "AssetEntity__AssetEntity_faces_personId", + "AssetEntity__AssetEntity_faces"."embedding" AS "AssetEntity__AssetEntity_faces_embedding", + "AssetEntity__AssetEntity_faces"."imageWidth" AS "AssetEntity__AssetEntity_faces_imageWidth", + "AssetEntity__AssetEntity_faces"."imageHeight" AS "AssetEntity__AssetEntity_faces_imageHeight", + "AssetEntity__AssetEntity_faces"."boundingBoxX1" AS "AssetEntity__AssetEntity_faces_boundingBoxX1", + "AssetEntity__AssetEntity_faces"."boundingBoxY1" AS "AssetEntity__AssetEntity_faces_boundingBoxY1", + "AssetEntity__AssetEntity_faces"."boundingBoxX2" AS "AssetEntity__AssetEntity_faces_boundingBoxX2", + "AssetEntity__AssetEntity_faces"."boundingBoxY2" AS "AssetEntity__AssetEntity_faces_boundingBoxY2", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."id" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_id", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."createdAt" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_createdAt", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."updatedAt" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_updatedAt", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."ownerId" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_ownerId", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."name" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_name", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."birthDate" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_birthDate", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."thumbnailPath" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_thumbnailPath", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."faceAssetId" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_faceAssetId", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."isHidden" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_isHidden", + "AssetEntity__AssetEntity_library"."id" AS "AssetEntity__AssetEntity_library_id", + "AssetEntity__AssetEntity_library"."name" AS "AssetEntity__AssetEntity_library_name", + "AssetEntity__AssetEntity_library"."ownerId" AS "AssetEntity__AssetEntity_library_ownerId", + "AssetEntity__AssetEntity_library"."type" AS "AssetEntity__AssetEntity_library_type", + "AssetEntity__AssetEntity_library"."importPaths" AS "AssetEntity__AssetEntity_library_importPaths", + "AssetEntity__AssetEntity_library"."exclusionPatterns" AS "AssetEntity__AssetEntity_library_exclusionPatterns", + "AssetEntity__AssetEntity_library"."createdAt" AS "AssetEntity__AssetEntity_library_createdAt", + "AssetEntity__AssetEntity_library"."updatedAt" AS "AssetEntity__AssetEntity_library_updatedAt", + "AssetEntity__AssetEntity_library"."deletedAt" AS "AssetEntity__AssetEntity_library_deletedAt", + "AssetEntity__AssetEntity_library"."refreshedAt" AS "AssetEntity__AssetEntity_library_refreshedAt", + "AssetEntity__AssetEntity_library"."isVisible" AS "AssetEntity__AssetEntity_library_isVisible", + "AssetEntity__AssetEntity_stack"."id" AS "AssetEntity__AssetEntity_stack_id", + "AssetEntity__AssetEntity_stack"."deviceAssetId" AS "AssetEntity__AssetEntity_stack_deviceAssetId", + "AssetEntity__AssetEntity_stack"."ownerId" AS "AssetEntity__AssetEntity_stack_ownerId", + "AssetEntity__AssetEntity_stack"."libraryId" AS "AssetEntity__AssetEntity_stack_libraryId", + "AssetEntity__AssetEntity_stack"."deviceId" AS "AssetEntity__AssetEntity_stack_deviceId", + "AssetEntity__AssetEntity_stack"."type" AS "AssetEntity__AssetEntity_stack_type", + "AssetEntity__AssetEntity_stack"."originalPath" AS "AssetEntity__AssetEntity_stack_originalPath", + "AssetEntity__AssetEntity_stack"."resizePath" AS "AssetEntity__AssetEntity_stack_resizePath", + "AssetEntity__AssetEntity_stack"."webpPath" AS "AssetEntity__AssetEntity_stack_webpPath", + "AssetEntity__AssetEntity_stack"."thumbhash" AS "AssetEntity__AssetEntity_stack_thumbhash", + "AssetEntity__AssetEntity_stack"."encodedVideoPath" AS "AssetEntity__AssetEntity_stack_encodedVideoPath", + "AssetEntity__AssetEntity_stack"."createdAt" AS "AssetEntity__AssetEntity_stack_createdAt", + "AssetEntity__AssetEntity_stack"."updatedAt" AS "AssetEntity__AssetEntity_stack_updatedAt", + "AssetEntity__AssetEntity_stack"."deletedAt" AS "AssetEntity__AssetEntity_stack_deletedAt", + "AssetEntity__AssetEntity_stack"."fileCreatedAt" AS "AssetEntity__AssetEntity_stack_fileCreatedAt", + "AssetEntity__AssetEntity_stack"."localDateTime" AS "AssetEntity__AssetEntity_stack_localDateTime", + "AssetEntity__AssetEntity_stack"."fileModifiedAt" AS "AssetEntity__AssetEntity_stack_fileModifiedAt", + "AssetEntity__AssetEntity_stack"."isFavorite" AS "AssetEntity__AssetEntity_stack_isFavorite", + "AssetEntity__AssetEntity_stack"."isArchived" AS "AssetEntity__AssetEntity_stack_isArchived", + "AssetEntity__AssetEntity_stack"."isExternal" AS "AssetEntity__AssetEntity_stack_isExternal", + "AssetEntity__AssetEntity_stack"."isReadOnly" AS "AssetEntity__AssetEntity_stack_isReadOnly", + "AssetEntity__AssetEntity_stack"."isOffline" AS "AssetEntity__AssetEntity_stack_isOffline", + "AssetEntity__AssetEntity_stack"."checksum" AS "AssetEntity__AssetEntity_stack_checksum", + "AssetEntity__AssetEntity_stack"."duration" AS "AssetEntity__AssetEntity_stack_duration", + "AssetEntity__AssetEntity_stack"."isVisible" AS "AssetEntity__AssetEntity_stack_isVisible", + "AssetEntity__AssetEntity_stack"."livePhotoVideoId" AS "AssetEntity__AssetEntity_stack_livePhotoVideoId", + "AssetEntity__AssetEntity_stack"."originalFileName" AS "AssetEntity__AssetEntity_stack_originalFileName", + "AssetEntity__AssetEntity_stack"."sidecarPath" AS "AssetEntity__AssetEntity_stack_sidecarPath", + "AssetEntity__AssetEntity_stack"."stackParentId" AS "AssetEntity__AssetEntity_stack_stackParentId" + FROM + "assets" "AssetEntity" + LEFT JOIN "asset_faces" "AssetEntity__AssetEntity_faces" ON "AssetEntity__AssetEntity_faces"."assetId" = "AssetEntity"."id" + LEFT JOIN "person" "8258e303a73a72cf6abb13d73fb592dde0d68280" ON "8258e303a73a72cf6abb13d73fb592dde0d68280"."id" = "AssetEntity__AssetEntity_faces"."personId" + LEFT JOIN "libraries" "AssetEntity__AssetEntity_library" ON "AssetEntity__AssetEntity_library"."id" = "AssetEntity"."libraryId" + LEFT JOIN "assets" "AssetEntity__AssetEntity_stack" ON "AssetEntity__AssetEntity_stack"."stackParentId" = "AssetEntity"."id" + WHERE + ("AssetEntity"."id" = $1) + ) "distinctAlias" +ORDER BY + "AssetEntity_id" ASC +LIMIT + 1 + +-- AssetRepository.updateAll +UPDATE "assets" +SET + "deviceId" = $1, + "updatedAt" = CURRENT_TIMESTAMP +WHERE + "id" IN ($2) + +-- AssetRepository.getByChecksum +SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId" +FROM + "assets" "AssetEntity" +WHERE + ( + ( + "AssetEntity"."ownerId" = $1 + AND "AssetEntity"."checksum" = $2 + ) + ) + AND ("AssetEntity"."deletedAt" IS NULL) +LIMIT + 1 + +-- AssetRepository.getWithout (sidecar) +SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId" +FROM + "assets" "AssetEntity" +WHERE + ( + ( + ( + "AssetEntity"."sidecarPath" IS NULL + AND "AssetEntity"."isVisible" = $1 + ) + OR ( + "AssetEntity"."sidecarPath" = $2 + AND "AssetEntity"."isVisible" = $3 + ) + ) + ) + AND ("AssetEntity"."deletedAt" IS NULL) +ORDER BY + "AssetEntity"."createdAt" ASC +LIMIT + 11 diff --git a/server/src/infra/sql/audit.repository.sql b/server/src/infra/sql/audit.repository.sql new file mode 100644 index 000000000..21f9f116b --- /dev/null +++ b/server/src/infra/sql/audit.repository.sql @@ -0,0 +1 @@ +-- NOTE: This file is auto generated by ./sql-generator diff --git a/server/src/infra/sql/library.repository.sql b/server/src/infra/sql/library.repository.sql new file mode 100644 index 000000000..44e6ddcc9 --- /dev/null +++ b/server/src/infra/sql/library.repository.sql @@ -0,0 +1,299 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- LibraryRepository.get +SELECT DISTINCT + "distinctAlias"."LibraryEntity_id" AS "ids_LibraryEntity_id" +FROM + ( + SELECT + "LibraryEntity"."id" AS "LibraryEntity_id", + "LibraryEntity"."name" AS "LibraryEntity_name", + "LibraryEntity"."ownerId" AS "LibraryEntity_ownerId", + "LibraryEntity"."type" AS "LibraryEntity_type", + "LibraryEntity"."importPaths" AS "LibraryEntity_importPaths", + "LibraryEntity"."exclusionPatterns" AS "LibraryEntity_exclusionPatterns", + "LibraryEntity"."createdAt" AS "LibraryEntity_createdAt", + "LibraryEntity"."updatedAt" AS "LibraryEntity_updatedAt", + "LibraryEntity"."deletedAt" AS "LibraryEntity_deletedAt", + "LibraryEntity"."refreshedAt" AS "LibraryEntity_refreshedAt", + "LibraryEntity"."isVisible" AS "LibraryEntity_isVisible", + "LibraryEntity__LibraryEntity_owner"."id" AS "LibraryEntity__LibraryEntity_owner_id", + "LibraryEntity__LibraryEntity_owner"."name" AS "LibraryEntity__LibraryEntity_owner_name", + "LibraryEntity__LibraryEntity_owner"."avatarColor" AS "LibraryEntity__LibraryEntity_owner_avatarColor", + "LibraryEntity__LibraryEntity_owner"."isAdmin" AS "LibraryEntity__LibraryEntity_owner_isAdmin", + "LibraryEntity__LibraryEntity_owner"."email" AS "LibraryEntity__LibraryEntity_owner_email", + "LibraryEntity__LibraryEntity_owner"."storageLabel" AS "LibraryEntity__LibraryEntity_owner_storageLabel", + "LibraryEntity__LibraryEntity_owner"."externalPath" AS "LibraryEntity__LibraryEntity_owner_externalPath", + "LibraryEntity__LibraryEntity_owner"."oauthId" AS "LibraryEntity__LibraryEntity_owner_oauthId", + "LibraryEntity__LibraryEntity_owner"."profileImagePath" AS "LibraryEntity__LibraryEntity_owner_profileImagePath", + "LibraryEntity__LibraryEntity_owner"."shouldChangePassword" AS "LibraryEntity__LibraryEntity_owner_shouldChangePassword", + "LibraryEntity__LibraryEntity_owner"."createdAt" AS "LibraryEntity__LibraryEntity_owner_createdAt", + "LibraryEntity__LibraryEntity_owner"."deletedAt" AS "LibraryEntity__LibraryEntity_owner_deletedAt", + "LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt", + "LibraryEntity__LibraryEntity_owner"."memoriesEnabled" AS "LibraryEntity__LibraryEntity_owner_memoriesEnabled" + FROM + "libraries" "LibraryEntity" + LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" + AND ( + "LibraryEntity__LibraryEntity_owner"."deletedAt" IS NULL + ) + WHERE + (("LibraryEntity"."id" = $1)) + AND ("LibraryEntity"."deletedAt" IS NULL) + ) "distinctAlias" +ORDER BY + "LibraryEntity_id" ASC +LIMIT + 1 + +-- LibraryRepository.existsByName +SELECT + 1 AS "row_exists" +FROM + ( + SELECT + 1 AS dummy_column + ) "dummy_table" +WHERE + EXISTS ( + SELECT + 1 + FROM + "libraries" "LibraryEntity" + WHERE + (("LibraryEntity"."name" = $1)) + AND ("LibraryEntity"."deletedAt" IS NULL) + ) +LIMIT + 1 + +-- LibraryRepository.getCountForUser +SELECT + COUNT(1) AS "cnt" +FROM + "libraries" "LibraryEntity" +WHERE + (("LibraryEntity"."ownerId" = $1)) + AND ("LibraryEntity"."deletedAt" IS NULL) + +-- LibraryRepository.getDefaultUploadLibrary +SELECT + "LibraryEntity"."id" AS "LibraryEntity_id", + "LibraryEntity"."name" AS "LibraryEntity_name", + "LibraryEntity"."ownerId" AS "LibraryEntity_ownerId", + "LibraryEntity"."type" AS "LibraryEntity_type", + "LibraryEntity"."importPaths" AS "LibraryEntity_importPaths", + "LibraryEntity"."exclusionPatterns" AS "LibraryEntity_exclusionPatterns", + "LibraryEntity"."createdAt" AS "LibraryEntity_createdAt", + "LibraryEntity"."updatedAt" AS "LibraryEntity_updatedAt", + "LibraryEntity"."deletedAt" AS "LibraryEntity_deletedAt", + "LibraryEntity"."refreshedAt" AS "LibraryEntity_refreshedAt", + "LibraryEntity"."isVisible" AS "LibraryEntity_isVisible" +FROM + "libraries" "LibraryEntity" +WHERE + ( + ( + "LibraryEntity"."ownerId" = $1 + AND "LibraryEntity"."type" = $2 + ) + ) + AND ("LibraryEntity"."deletedAt" IS NULL) +ORDER BY + "LibraryEntity"."createdAt" ASC +LIMIT + 1 + +-- LibraryRepository.getUploadLibraryCount +SELECT + COUNT(1) AS "cnt" +FROM + "libraries" "LibraryEntity" +WHERE + ( + ( + "LibraryEntity"."ownerId" = $1 + AND "LibraryEntity"."type" = $2 + ) + ) + AND ("LibraryEntity"."deletedAt" IS NULL) + +-- LibraryRepository.getAllByUserId +SELECT + "LibraryEntity"."id" AS "LibraryEntity_id", + "LibraryEntity"."name" AS "LibraryEntity_name", + "LibraryEntity"."ownerId" AS "LibraryEntity_ownerId", + "LibraryEntity"."type" AS "LibraryEntity_type", + "LibraryEntity"."importPaths" AS "LibraryEntity_importPaths", + "LibraryEntity"."exclusionPatterns" AS "LibraryEntity_exclusionPatterns", + "LibraryEntity"."createdAt" AS "LibraryEntity_createdAt", + "LibraryEntity"."updatedAt" AS "LibraryEntity_updatedAt", + "LibraryEntity"."deletedAt" AS "LibraryEntity_deletedAt", + "LibraryEntity"."refreshedAt" AS "LibraryEntity_refreshedAt", + "LibraryEntity"."isVisible" AS "LibraryEntity_isVisible", + "LibraryEntity__LibraryEntity_owner"."id" AS "LibraryEntity__LibraryEntity_owner_id", + "LibraryEntity__LibraryEntity_owner"."name" AS "LibraryEntity__LibraryEntity_owner_name", + "LibraryEntity__LibraryEntity_owner"."avatarColor" AS "LibraryEntity__LibraryEntity_owner_avatarColor", + "LibraryEntity__LibraryEntity_owner"."isAdmin" AS "LibraryEntity__LibraryEntity_owner_isAdmin", + "LibraryEntity__LibraryEntity_owner"."email" AS "LibraryEntity__LibraryEntity_owner_email", + "LibraryEntity__LibraryEntity_owner"."storageLabel" AS "LibraryEntity__LibraryEntity_owner_storageLabel", + "LibraryEntity__LibraryEntity_owner"."externalPath" AS "LibraryEntity__LibraryEntity_owner_externalPath", + "LibraryEntity__LibraryEntity_owner"."oauthId" AS "LibraryEntity__LibraryEntity_owner_oauthId", + "LibraryEntity__LibraryEntity_owner"."profileImagePath" AS "LibraryEntity__LibraryEntity_owner_profileImagePath", + "LibraryEntity__LibraryEntity_owner"."shouldChangePassword" AS "LibraryEntity__LibraryEntity_owner_shouldChangePassword", + "LibraryEntity__LibraryEntity_owner"."createdAt" AS "LibraryEntity__LibraryEntity_owner_createdAt", + "LibraryEntity__LibraryEntity_owner"."deletedAt" AS "LibraryEntity__LibraryEntity_owner_deletedAt", + "LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt", + "LibraryEntity__LibraryEntity_owner"."memoriesEnabled" AS "LibraryEntity__LibraryEntity_owner_memoriesEnabled" +FROM + "libraries" "LibraryEntity" + LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" + AND ( + "LibraryEntity__LibraryEntity_owner"."deletedAt" IS NULL + ) +WHERE + ( + ( + "LibraryEntity"."ownerId" = $1 + AND "LibraryEntity"."isVisible" = $2 + ) + ) + AND ("LibraryEntity"."deletedAt" IS NULL) +ORDER BY + "LibraryEntity"."createdAt" ASC + +-- LibraryRepository.getAll +SELECT + "LibraryEntity"."id" AS "LibraryEntity_id", + "LibraryEntity"."name" AS "LibraryEntity_name", + "LibraryEntity"."ownerId" AS "LibraryEntity_ownerId", + "LibraryEntity"."type" AS "LibraryEntity_type", + "LibraryEntity"."importPaths" AS "LibraryEntity_importPaths", + "LibraryEntity"."exclusionPatterns" AS "LibraryEntity_exclusionPatterns", + "LibraryEntity"."createdAt" AS "LibraryEntity_createdAt", + "LibraryEntity"."updatedAt" AS "LibraryEntity_updatedAt", + "LibraryEntity"."deletedAt" AS "LibraryEntity_deletedAt", + "LibraryEntity"."refreshedAt" AS "LibraryEntity_refreshedAt", + "LibraryEntity"."isVisible" AS "LibraryEntity_isVisible", + "LibraryEntity__LibraryEntity_owner"."id" AS "LibraryEntity__LibraryEntity_owner_id", + "LibraryEntity__LibraryEntity_owner"."name" AS "LibraryEntity__LibraryEntity_owner_name", + "LibraryEntity__LibraryEntity_owner"."avatarColor" AS "LibraryEntity__LibraryEntity_owner_avatarColor", + "LibraryEntity__LibraryEntity_owner"."isAdmin" AS "LibraryEntity__LibraryEntity_owner_isAdmin", + "LibraryEntity__LibraryEntity_owner"."email" AS "LibraryEntity__LibraryEntity_owner_email", + "LibraryEntity__LibraryEntity_owner"."storageLabel" AS "LibraryEntity__LibraryEntity_owner_storageLabel", + "LibraryEntity__LibraryEntity_owner"."externalPath" AS "LibraryEntity__LibraryEntity_owner_externalPath", + "LibraryEntity__LibraryEntity_owner"."oauthId" AS "LibraryEntity__LibraryEntity_owner_oauthId", + "LibraryEntity__LibraryEntity_owner"."profileImagePath" AS "LibraryEntity__LibraryEntity_owner_profileImagePath", + "LibraryEntity__LibraryEntity_owner"."shouldChangePassword" AS "LibraryEntity__LibraryEntity_owner_shouldChangePassword", + "LibraryEntity__LibraryEntity_owner"."createdAt" AS "LibraryEntity__LibraryEntity_owner_createdAt", + "LibraryEntity__LibraryEntity_owner"."deletedAt" AS "LibraryEntity__LibraryEntity_owner_deletedAt", + "LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt", + "LibraryEntity__LibraryEntity_owner"."memoriesEnabled" AS "LibraryEntity__LibraryEntity_owner_memoriesEnabled" +FROM + "libraries" "LibraryEntity" + LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" + AND ( + "LibraryEntity__LibraryEntity_owner"."deletedAt" IS NULL + ) +WHERE + "LibraryEntity"."deletedAt" IS NULL +ORDER BY + "LibraryEntity"."createdAt" ASC + +-- LibraryRepository.getAllDeleted +SELECT + "LibraryEntity"."id" AS "LibraryEntity_id", + "LibraryEntity"."name" AS "LibraryEntity_name", + "LibraryEntity"."ownerId" AS "LibraryEntity_ownerId", + "LibraryEntity"."type" AS "LibraryEntity_type", + "LibraryEntity"."importPaths" AS "LibraryEntity_importPaths", + "LibraryEntity"."exclusionPatterns" AS "LibraryEntity_exclusionPatterns", + "LibraryEntity"."createdAt" AS "LibraryEntity_createdAt", + "LibraryEntity"."updatedAt" AS "LibraryEntity_updatedAt", + "LibraryEntity"."deletedAt" AS "LibraryEntity_deletedAt", + "LibraryEntity"."refreshedAt" AS "LibraryEntity_refreshedAt", + "LibraryEntity"."isVisible" AS "LibraryEntity_isVisible", + "LibraryEntity__LibraryEntity_owner"."id" AS "LibraryEntity__LibraryEntity_owner_id", + "LibraryEntity__LibraryEntity_owner"."name" AS "LibraryEntity__LibraryEntity_owner_name", + "LibraryEntity__LibraryEntity_owner"."avatarColor" AS "LibraryEntity__LibraryEntity_owner_avatarColor", + "LibraryEntity__LibraryEntity_owner"."isAdmin" AS "LibraryEntity__LibraryEntity_owner_isAdmin", + "LibraryEntity__LibraryEntity_owner"."email" AS "LibraryEntity__LibraryEntity_owner_email", + "LibraryEntity__LibraryEntity_owner"."storageLabel" AS "LibraryEntity__LibraryEntity_owner_storageLabel", + "LibraryEntity__LibraryEntity_owner"."externalPath" AS "LibraryEntity__LibraryEntity_owner_externalPath", + "LibraryEntity__LibraryEntity_owner"."oauthId" AS "LibraryEntity__LibraryEntity_owner_oauthId", + "LibraryEntity__LibraryEntity_owner"."profileImagePath" AS "LibraryEntity__LibraryEntity_owner_profileImagePath", + "LibraryEntity__LibraryEntity_owner"."shouldChangePassword" AS "LibraryEntity__LibraryEntity_owner_shouldChangePassword", + "LibraryEntity__LibraryEntity_owner"."createdAt" AS "LibraryEntity__LibraryEntity_owner_createdAt", + "LibraryEntity__LibraryEntity_owner"."deletedAt" AS "LibraryEntity__LibraryEntity_owner_deletedAt", + "LibraryEntity__LibraryEntity_owner"."updatedAt" AS "LibraryEntity__LibraryEntity_owner_updatedAt", + "LibraryEntity__LibraryEntity_owner"."memoriesEnabled" AS "LibraryEntity__LibraryEntity_owner_memoriesEnabled" +FROM + "libraries" "LibraryEntity" + LEFT JOIN "users" "LibraryEntity__LibraryEntity_owner" ON "LibraryEntity__LibraryEntity_owner"."id" = "LibraryEntity"."ownerId" +WHERE + ( + "LibraryEntity"."isVisible" = $1 + AND NOT ("LibraryEntity"."deletedAt" IS NULL) + ) +ORDER BY + "LibraryEntity"."createdAt" ASC + +-- LibraryRepository.getStatistics +SELECT + "libraries"."id" AS "libraries_id", + "libraries"."name" AS "libraries_name", + "libraries"."ownerId" AS "libraries_ownerId", + "libraries"."type" AS "libraries_type", + "libraries"."importPaths" AS "libraries_importPaths", + "libraries"."exclusionPatterns" AS "libraries_exclusionPatterns", + "libraries"."createdAt" AS "libraries_createdAt", + "libraries"."updatedAt" AS "libraries_updatedAt", + "libraries"."deletedAt" AS "libraries_deletedAt", + "libraries"."refreshedAt" AS "libraries_refreshedAt", + "libraries"."isVisible" AS "libraries_isVisible", + COUNT("assets"."id") FILTER ( + WHERE + "assets"."type" = 'IMAGE' + AND "assets"."isVisible" + ) AS "photos", + COUNT("assets"."id") FILTER ( + WHERE + "assets"."type" = 'VIDEO' + AND "assets"."isVisible" + ) AS "videos", + COALESCE(SUM("exif"."fileSizeInByte"), 0) AS "usage" +FROM + "libraries" "libraries" + LEFT JOIN "assets" "assets" ON "assets"."libraryId" = "libraries"."id" + AND ("assets"."deletedAt" IS NULL) + LEFT JOIN "exif" "exif" ON "exif"."assetId" = "assets"."id" +WHERE + ("libraries"."id" = $1) + AND ("libraries"."deletedAt" IS NULL) +GROUP BY + "libraries"."id" + +-- LibraryRepository.getOnlineAssetPaths +SELECT + "assets"."originalPath" AS "assets_originalPath" +FROM + "libraries" "library" + INNER JOIN "assets" "assets" ON "assets"."libraryId" = "library"."id" + AND ("assets"."deletedAt" IS NULL) +WHERE + ( + "library"."id" = $1 + AND "assets"."isOffline" = false + ) + AND ("library"."deletedAt" IS NULL) + +-- LibraryRepository.getAssetIds +SELECT + "assets"."id" AS "assets_id" +FROM + "libraries" "library" + INNER JOIN "assets" "assets" ON "assets"."libraryId" = "library"."id" + AND ("assets"."deletedAt" IS NULL) +WHERE + ("library"."id" = $1) + AND ("library"."deletedAt" IS NULL) diff --git a/server/src/infra/sql/move.repository.sql b/server/src/infra/sql/move.repository.sql new file mode 100644 index 000000000..b83175bd3 --- /dev/null +++ b/server/src/infra/sql/move.repository.sql @@ -0,0 +1,18 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- MoveRepository.getByEntity +SELECT + "MoveEntity"."id" AS "MoveEntity_id", + "MoveEntity"."entityId" AS "MoveEntity_entityId", + "MoveEntity"."pathType" AS "MoveEntity_pathType", + "MoveEntity"."oldPath" AS "MoveEntity_oldPath", + "MoveEntity"."newPath" AS "MoveEntity_newPath" +FROM + "move_history" "MoveEntity" +WHERE + ( + "MoveEntity"."entityId" = $1 + AND "MoveEntity"."pathType" = $2 + ) +LIMIT + 1 diff --git a/server/src/infra/sql/partner.repository.sql b/server/src/infra/sql/partner.repository.sql new file mode 100644 index 000000000..21f9f116b --- /dev/null +++ b/server/src/infra/sql/partner.repository.sql @@ -0,0 +1 @@ +-- NOTE: This file is auto generated by ./sql-generator diff --git a/server/src/infra/sql/person.repository.sql b/server/src/infra/sql/person.repository.sql new file mode 100644 index 000000000..933283746 --- /dev/null +++ b/server/src/infra/sql/person.repository.sql @@ -0,0 +1,367 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- PersonRepository.reassignFaces +UPDATE "asset_faces" +SET + "personId" = $1 +WHERE + "personId" = $2 + +-- PersonRepository.getAllFaces +SELECT + "AssetFaceEntity"."id" AS "AssetFaceEntity_id", + "AssetFaceEntity"."assetId" AS "AssetFaceEntity_assetId", + "AssetFaceEntity"."personId" AS "AssetFaceEntity_personId", + "AssetFaceEntity"."embedding" AS "AssetFaceEntity_embedding", + "AssetFaceEntity"."imageWidth" AS "AssetFaceEntity_imageWidth", + "AssetFaceEntity"."imageHeight" AS "AssetFaceEntity_imageHeight", + "AssetFaceEntity"."boundingBoxX1" AS "AssetFaceEntity_boundingBoxX1", + "AssetFaceEntity"."boundingBoxY1" AS "AssetFaceEntity_boundingBoxY1", + "AssetFaceEntity"."boundingBoxX2" AS "AssetFaceEntity_boundingBoxX2", + "AssetFaceEntity"."boundingBoxY2" AS "AssetFaceEntity_boundingBoxY2", + "AssetFaceEntity__AssetFaceEntity_asset"."id" AS "AssetFaceEntity__AssetFaceEntity_asset_id", + "AssetFaceEntity__AssetFaceEntity_asset"."deviceAssetId" AS "AssetFaceEntity__AssetFaceEntity_asset_deviceAssetId", + "AssetFaceEntity__AssetFaceEntity_asset"."ownerId" AS "AssetFaceEntity__AssetFaceEntity_asset_ownerId", + "AssetFaceEntity__AssetFaceEntity_asset"."libraryId" AS "AssetFaceEntity__AssetFaceEntity_asset_libraryId", + "AssetFaceEntity__AssetFaceEntity_asset"."deviceId" AS "AssetFaceEntity__AssetFaceEntity_asset_deviceId", + "AssetFaceEntity__AssetFaceEntity_asset"."type" AS "AssetFaceEntity__AssetFaceEntity_asset_type", + "AssetFaceEntity__AssetFaceEntity_asset"."originalPath" AS "AssetFaceEntity__AssetFaceEntity_asset_originalPath", + "AssetFaceEntity__AssetFaceEntity_asset"."resizePath" AS "AssetFaceEntity__AssetFaceEntity_asset_resizePath", + "AssetFaceEntity__AssetFaceEntity_asset"."webpPath" AS "AssetFaceEntity__AssetFaceEntity_asset_webpPath", + "AssetFaceEntity__AssetFaceEntity_asset"."thumbhash" AS "AssetFaceEntity__AssetFaceEntity_asset_thumbhash", + "AssetFaceEntity__AssetFaceEntity_asset"."encodedVideoPath" AS "AssetFaceEntity__AssetFaceEntity_asset_encodedVideoPath", + "AssetFaceEntity__AssetFaceEntity_asset"."createdAt" AS "AssetFaceEntity__AssetFaceEntity_asset_createdAt", + "AssetFaceEntity__AssetFaceEntity_asset"."updatedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_updatedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."deletedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_deletedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."fileCreatedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_fileCreatedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."localDateTime" AS "AssetFaceEntity__AssetFaceEntity_asset_localDateTime", + "AssetFaceEntity__AssetFaceEntity_asset"."fileModifiedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_fileModifiedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."isFavorite" AS "AssetFaceEntity__AssetFaceEntity_asset_isFavorite", + "AssetFaceEntity__AssetFaceEntity_asset"."isArchived" AS "AssetFaceEntity__AssetFaceEntity_asset_isArchived", + "AssetFaceEntity__AssetFaceEntity_asset"."isExternal" AS "AssetFaceEntity__AssetFaceEntity_asset_isExternal", + "AssetFaceEntity__AssetFaceEntity_asset"."isReadOnly" AS "AssetFaceEntity__AssetFaceEntity_asset_isReadOnly", + "AssetFaceEntity__AssetFaceEntity_asset"."isOffline" AS "AssetFaceEntity__AssetFaceEntity_asset_isOffline", + "AssetFaceEntity__AssetFaceEntity_asset"."checksum" AS "AssetFaceEntity__AssetFaceEntity_asset_checksum", + "AssetFaceEntity__AssetFaceEntity_asset"."duration" AS "AssetFaceEntity__AssetFaceEntity_asset_duration", + "AssetFaceEntity__AssetFaceEntity_asset"."isVisible" AS "AssetFaceEntity__AssetFaceEntity_asset_isVisible", + "AssetFaceEntity__AssetFaceEntity_asset"."livePhotoVideoId" AS "AssetFaceEntity__AssetFaceEntity_asset_livePhotoVideoId", + "AssetFaceEntity__AssetFaceEntity_asset"."originalFileName" AS "AssetFaceEntity__AssetFaceEntity_asset_originalFileName", + "AssetFaceEntity__AssetFaceEntity_asset"."sidecarPath" AS "AssetFaceEntity__AssetFaceEntity_asset_sidecarPath", + "AssetFaceEntity__AssetFaceEntity_asset"."stackParentId" AS "AssetFaceEntity__AssetFaceEntity_asset_stackParentId" +FROM + "asset_faces" "AssetFaceEntity" + LEFT JOIN "assets" "AssetFaceEntity__AssetFaceEntity_asset" ON "AssetFaceEntity__AssetFaceEntity_asset"."id" = "AssetFaceEntity"."assetId" + +-- PersonRepository.getAll +SELECT + "PersonEntity"."id" AS "PersonEntity_id", + "PersonEntity"."createdAt" AS "PersonEntity_createdAt", + "PersonEntity"."updatedAt" AS "PersonEntity_updatedAt", + "PersonEntity"."ownerId" AS "PersonEntity_ownerId", + "PersonEntity"."name" AS "PersonEntity_name", + "PersonEntity"."birthDate" AS "PersonEntity_birthDate", + "PersonEntity"."thumbnailPath" AS "PersonEntity_thumbnailPath", + "PersonEntity"."faceAssetId" AS "PersonEntity_faceAssetId", + "PersonEntity"."isHidden" AS "PersonEntity_isHidden" +FROM + "person" "PersonEntity" + +-- PersonRepository.getAllWithoutThumbnail +SELECT + "PersonEntity"."id" AS "PersonEntity_id", + "PersonEntity"."createdAt" AS "PersonEntity_createdAt", + "PersonEntity"."updatedAt" AS "PersonEntity_updatedAt", + "PersonEntity"."ownerId" AS "PersonEntity_ownerId", + "PersonEntity"."name" AS "PersonEntity_name", + "PersonEntity"."birthDate" AS "PersonEntity_birthDate", + "PersonEntity"."thumbnailPath" AS "PersonEntity_thumbnailPath", + "PersonEntity"."faceAssetId" AS "PersonEntity_faceAssetId", + "PersonEntity"."isHidden" AS "PersonEntity_isHidden" +FROM + "person" "PersonEntity" +WHERE + ("PersonEntity"."thumbnailPath" = $1) + +-- PersonRepository.getAllForUser +SELECT + "person"."id" AS "person_id", + "person"."createdAt" AS "person_createdAt", + "person"."updatedAt" AS "person_updatedAt", + "person"."ownerId" AS "person_ownerId", + "person"."name" AS "person_name", + "person"."birthDate" AS "person_birthDate", + "person"."thumbnailPath" AS "person_thumbnailPath", + "person"."faceAssetId" AS "person_faceAssetId", + "person"."isHidden" AS "person_isHidden" +FROM + "person" "person" + LEFT JOIN "asset_faces" "face" ON "face"."personId" = "person"."id" + INNER JOIN "assets" "asset" ON "asset"."id" = "face"."assetId" + AND ("asset"."deletedAt" IS NULL) +WHERE + "person"."ownerId" = $1 + AND "person"."isHidden" = false +GROUP BY + "person"."id" +HAVING + "person"."name" != '' + OR COUNT("face"."assetId") >= $2 +ORDER BY + "person"."isHidden" ASC, + NULLIF("person"."name", '') IS NULL ASC, + COUNT("face"."assetId") DESC, + NULLIF("person"."name", '') ASC NULLS LAST +LIMIT + 500 + +-- PersonRepository.getAllWithoutFaces +SELECT + "person"."id" AS "person_id", + "person"."createdAt" AS "person_createdAt", + "person"."updatedAt" AS "person_updatedAt", + "person"."ownerId" AS "person_ownerId", + "person"."name" AS "person_name", + "person"."birthDate" AS "person_birthDate", + "person"."thumbnailPath" AS "person_thumbnailPath", + "person"."faceAssetId" AS "person_faceAssetId", + "person"."isHidden" AS "person_isHidden" +FROM + "person" "person" + LEFT JOIN "asset_faces" "face" ON "face"."personId" = "person"."id" +GROUP BY + "person"."id" +HAVING + COUNT("face"."assetId") = 0 + +-- PersonRepository.getById +SELECT + "PersonEntity"."id" AS "PersonEntity_id", + "PersonEntity"."createdAt" AS "PersonEntity_createdAt", + "PersonEntity"."updatedAt" AS "PersonEntity_updatedAt", + "PersonEntity"."ownerId" AS "PersonEntity_ownerId", + "PersonEntity"."name" AS "PersonEntity_name", + "PersonEntity"."birthDate" AS "PersonEntity_birthDate", + "PersonEntity"."thumbnailPath" AS "PersonEntity_thumbnailPath", + "PersonEntity"."faceAssetId" AS "PersonEntity_faceAssetId", + "PersonEntity"."isHidden" AS "PersonEntity_isHidden" +FROM + "person" "PersonEntity" +WHERE + ("PersonEntity"."id" = $1) +LIMIT + 1 + +-- PersonRepository.getByName +SELECT + "person"."id" AS "person_id", + "person"."createdAt" AS "person_createdAt", + "person"."updatedAt" AS "person_updatedAt", + "person"."ownerId" AS "person_ownerId", + "person"."name" AS "person_name", + "person"."birthDate" AS "person_birthDate", + "person"."thumbnailPath" AS "person_thumbnailPath", + "person"."faceAssetId" AS "person_faceAssetId", + "person"."isHidden" AS "person_isHidden" +FROM + "person" "person" + LEFT JOIN "asset_faces" "face" ON "face"."personId" = "person"."id" +WHERE + "person"."ownerId" = $1 + AND ( + LOWER("person"."name") LIKE $2 + OR LOWER("person"."name") LIKE $3 + ) +GROUP BY + "person"."id" +ORDER BY + COUNT("face"."assetId") DESC +LIMIT + 20 + +-- PersonRepository.getStatistics +SELECT DISTINCT + COUNT(DISTINCT ("face"."id")) AS "cnt" +FROM + "asset_faces" "face" + LEFT JOIN "assets" "asset" ON "asset"."id" = "face"."assetId" + AND ("asset"."deletedAt" IS NULL) +WHERE + "face"."personId" = $1 + AND "asset"."isArchived" = false + AND "asset"."deletedAt" IS NULL + AND "asset"."livePhotoVideoId" IS NULL + +-- PersonRepository.getAssets +SELECT DISTINCT + "distinctAlias"."AssetEntity_id" AS "ids_AssetEntity_id", + "distinctAlias"."AssetEntity_fileCreatedAt" +FROM + ( + SELECT + "AssetEntity"."id" AS "AssetEntity_id", + "AssetEntity"."deviceAssetId" AS "AssetEntity_deviceAssetId", + "AssetEntity"."ownerId" AS "AssetEntity_ownerId", + "AssetEntity"."libraryId" AS "AssetEntity_libraryId", + "AssetEntity"."deviceId" AS "AssetEntity_deviceId", + "AssetEntity"."type" AS "AssetEntity_type", + "AssetEntity"."originalPath" AS "AssetEntity_originalPath", + "AssetEntity"."resizePath" AS "AssetEntity_resizePath", + "AssetEntity"."webpPath" AS "AssetEntity_webpPath", + "AssetEntity"."thumbhash" AS "AssetEntity_thumbhash", + "AssetEntity"."encodedVideoPath" AS "AssetEntity_encodedVideoPath", + "AssetEntity"."createdAt" AS "AssetEntity_createdAt", + "AssetEntity"."updatedAt" AS "AssetEntity_updatedAt", + "AssetEntity"."deletedAt" AS "AssetEntity_deletedAt", + "AssetEntity"."fileCreatedAt" AS "AssetEntity_fileCreatedAt", + "AssetEntity"."localDateTime" AS "AssetEntity_localDateTime", + "AssetEntity"."fileModifiedAt" AS "AssetEntity_fileModifiedAt", + "AssetEntity"."isFavorite" AS "AssetEntity_isFavorite", + "AssetEntity"."isArchived" AS "AssetEntity_isArchived", + "AssetEntity"."isExternal" AS "AssetEntity_isExternal", + "AssetEntity"."isReadOnly" AS "AssetEntity_isReadOnly", + "AssetEntity"."isOffline" AS "AssetEntity_isOffline", + "AssetEntity"."checksum" AS "AssetEntity_checksum", + "AssetEntity"."duration" AS "AssetEntity_duration", + "AssetEntity"."isVisible" AS "AssetEntity_isVisible", + "AssetEntity"."livePhotoVideoId" AS "AssetEntity_livePhotoVideoId", + "AssetEntity"."originalFileName" AS "AssetEntity_originalFileName", + "AssetEntity"."sidecarPath" AS "AssetEntity_sidecarPath", + "AssetEntity"."stackParentId" AS "AssetEntity_stackParentId", + "AssetEntity__AssetEntity_faces"."id" AS "AssetEntity__AssetEntity_faces_id", + "AssetEntity__AssetEntity_faces"."assetId" AS "AssetEntity__AssetEntity_faces_assetId", + "AssetEntity__AssetEntity_faces"."personId" AS "AssetEntity__AssetEntity_faces_personId", + "AssetEntity__AssetEntity_faces"."embedding" AS "AssetEntity__AssetEntity_faces_embedding", + "AssetEntity__AssetEntity_faces"."imageWidth" AS "AssetEntity__AssetEntity_faces_imageWidth", + "AssetEntity__AssetEntity_faces"."imageHeight" AS "AssetEntity__AssetEntity_faces_imageHeight", + "AssetEntity__AssetEntity_faces"."boundingBoxX1" AS "AssetEntity__AssetEntity_faces_boundingBoxX1", + "AssetEntity__AssetEntity_faces"."boundingBoxY1" AS "AssetEntity__AssetEntity_faces_boundingBoxY1", + "AssetEntity__AssetEntity_faces"."boundingBoxX2" AS "AssetEntity__AssetEntity_faces_boundingBoxX2", + "AssetEntity__AssetEntity_faces"."boundingBoxY2" AS "AssetEntity__AssetEntity_faces_boundingBoxY2", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."id" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_id", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."createdAt" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_createdAt", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."updatedAt" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_updatedAt", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."ownerId" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_ownerId", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."name" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_name", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."birthDate" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_birthDate", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."thumbnailPath" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_thumbnailPath", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."faceAssetId" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_faceAssetId", + "8258e303a73a72cf6abb13d73fb592dde0d68280"."isHidden" AS "8258e303a73a72cf6abb13d73fb592dde0d68280_isHidden", + "AssetEntity__AssetEntity_exifInfo"."assetId" AS "AssetEntity__AssetEntity_exifInfo_assetId", + "AssetEntity__AssetEntity_exifInfo"."description" AS "AssetEntity__AssetEntity_exifInfo_description", + "AssetEntity__AssetEntity_exifInfo"."exifImageWidth" AS "AssetEntity__AssetEntity_exifInfo_exifImageWidth", + "AssetEntity__AssetEntity_exifInfo"."exifImageHeight" AS "AssetEntity__AssetEntity_exifInfo_exifImageHeight", + "AssetEntity__AssetEntity_exifInfo"."fileSizeInByte" AS "AssetEntity__AssetEntity_exifInfo_fileSizeInByte", + "AssetEntity__AssetEntity_exifInfo"."orientation" AS "AssetEntity__AssetEntity_exifInfo_orientation", + "AssetEntity__AssetEntity_exifInfo"."dateTimeOriginal" AS "AssetEntity__AssetEntity_exifInfo_dateTimeOriginal", + "AssetEntity__AssetEntity_exifInfo"."modifyDate" AS "AssetEntity__AssetEntity_exifInfo_modifyDate", + "AssetEntity__AssetEntity_exifInfo"."timeZone" AS "AssetEntity__AssetEntity_exifInfo_timeZone", + "AssetEntity__AssetEntity_exifInfo"."latitude" AS "AssetEntity__AssetEntity_exifInfo_latitude", + "AssetEntity__AssetEntity_exifInfo"."longitude" AS "AssetEntity__AssetEntity_exifInfo_longitude", + "AssetEntity__AssetEntity_exifInfo"."projectionType" AS "AssetEntity__AssetEntity_exifInfo_projectionType", + "AssetEntity__AssetEntity_exifInfo"."city" AS "AssetEntity__AssetEntity_exifInfo_city", + "AssetEntity__AssetEntity_exifInfo"."livePhotoCID" AS "AssetEntity__AssetEntity_exifInfo_livePhotoCID", + "AssetEntity__AssetEntity_exifInfo"."state" AS "AssetEntity__AssetEntity_exifInfo_state", + "AssetEntity__AssetEntity_exifInfo"."country" AS "AssetEntity__AssetEntity_exifInfo_country", + "AssetEntity__AssetEntity_exifInfo"."make" AS "AssetEntity__AssetEntity_exifInfo_make", + "AssetEntity__AssetEntity_exifInfo"."model" AS "AssetEntity__AssetEntity_exifInfo_model", + "AssetEntity__AssetEntity_exifInfo"."lensModel" AS "AssetEntity__AssetEntity_exifInfo_lensModel", + "AssetEntity__AssetEntity_exifInfo"."fNumber" AS "AssetEntity__AssetEntity_exifInfo_fNumber", + "AssetEntity__AssetEntity_exifInfo"."focalLength" AS "AssetEntity__AssetEntity_exifInfo_focalLength", + "AssetEntity__AssetEntity_exifInfo"."iso" AS "AssetEntity__AssetEntity_exifInfo_iso", + "AssetEntity__AssetEntity_exifInfo"."exposureTime" AS "AssetEntity__AssetEntity_exifInfo_exposureTime", + "AssetEntity__AssetEntity_exifInfo"."profileDescription" AS "AssetEntity__AssetEntity_exifInfo_profileDescription", + "AssetEntity__AssetEntity_exifInfo"."colorspace" AS "AssetEntity__AssetEntity_exifInfo_colorspace", + "AssetEntity__AssetEntity_exifInfo"."bitsPerSample" AS "AssetEntity__AssetEntity_exifInfo_bitsPerSample", + "AssetEntity__AssetEntity_exifInfo"."fps" AS "AssetEntity__AssetEntity_exifInfo_fps", + "AssetEntity__AssetEntity_exifInfo"."exifTextSearchableColumn" AS "AssetEntity__AssetEntity_exifInfo_exifTextSearchableColumn" + FROM + "assets" "AssetEntity" + LEFT JOIN "asset_faces" "AssetEntity__AssetEntity_faces" ON "AssetEntity__AssetEntity_faces"."assetId" = "AssetEntity"."id" + LEFT JOIN "person" "8258e303a73a72cf6abb13d73fb592dde0d68280" ON "8258e303a73a72cf6abb13d73fb592dde0d68280"."id" = "AssetEntity__AssetEntity_faces"."personId" + LEFT JOIN "exif" "AssetEntity__AssetEntity_exifInfo" ON "AssetEntity__AssetEntity_exifInfo"."assetId" = "AssetEntity"."id" + WHERE + ( + ( + "AssetEntity__AssetEntity_faces"."personId" = $1 + AND "AssetEntity"."isVisible" = $2 + AND "AssetEntity"."isArchived" = $3 + ) + ) + AND ("AssetEntity"."deletedAt" IS NULL) + ) "distinctAlias" +ORDER BY + "distinctAlias"."AssetEntity_fileCreatedAt" DESC, + "AssetEntity_id" ASC +LIMIT + 1000 + +-- PersonRepository.getFacesByIds +SELECT + "AssetFaceEntity"."id" AS "AssetFaceEntity_id", + "AssetFaceEntity"."assetId" AS "AssetFaceEntity_assetId", + "AssetFaceEntity"."personId" AS "AssetFaceEntity_personId", + "AssetFaceEntity"."embedding" AS "AssetFaceEntity_embedding", + "AssetFaceEntity"."imageWidth" AS "AssetFaceEntity_imageWidth", + "AssetFaceEntity"."imageHeight" AS "AssetFaceEntity_imageHeight", + "AssetFaceEntity"."boundingBoxX1" AS "AssetFaceEntity_boundingBoxX1", + "AssetFaceEntity"."boundingBoxY1" AS "AssetFaceEntity_boundingBoxY1", + "AssetFaceEntity"."boundingBoxX2" AS "AssetFaceEntity_boundingBoxX2", + "AssetFaceEntity"."boundingBoxY2" AS "AssetFaceEntity_boundingBoxY2", + "AssetFaceEntity__AssetFaceEntity_asset"."id" AS "AssetFaceEntity__AssetFaceEntity_asset_id", + "AssetFaceEntity__AssetFaceEntity_asset"."deviceAssetId" AS "AssetFaceEntity__AssetFaceEntity_asset_deviceAssetId", + "AssetFaceEntity__AssetFaceEntity_asset"."ownerId" AS "AssetFaceEntity__AssetFaceEntity_asset_ownerId", + "AssetFaceEntity__AssetFaceEntity_asset"."libraryId" AS "AssetFaceEntity__AssetFaceEntity_asset_libraryId", + "AssetFaceEntity__AssetFaceEntity_asset"."deviceId" AS "AssetFaceEntity__AssetFaceEntity_asset_deviceId", + "AssetFaceEntity__AssetFaceEntity_asset"."type" AS "AssetFaceEntity__AssetFaceEntity_asset_type", + "AssetFaceEntity__AssetFaceEntity_asset"."originalPath" AS "AssetFaceEntity__AssetFaceEntity_asset_originalPath", + "AssetFaceEntity__AssetFaceEntity_asset"."resizePath" AS "AssetFaceEntity__AssetFaceEntity_asset_resizePath", + "AssetFaceEntity__AssetFaceEntity_asset"."webpPath" AS "AssetFaceEntity__AssetFaceEntity_asset_webpPath", + "AssetFaceEntity__AssetFaceEntity_asset"."thumbhash" AS "AssetFaceEntity__AssetFaceEntity_asset_thumbhash", + "AssetFaceEntity__AssetFaceEntity_asset"."encodedVideoPath" AS "AssetFaceEntity__AssetFaceEntity_asset_encodedVideoPath", + "AssetFaceEntity__AssetFaceEntity_asset"."createdAt" AS "AssetFaceEntity__AssetFaceEntity_asset_createdAt", + "AssetFaceEntity__AssetFaceEntity_asset"."updatedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_updatedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."deletedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_deletedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."fileCreatedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_fileCreatedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."localDateTime" AS "AssetFaceEntity__AssetFaceEntity_asset_localDateTime", + "AssetFaceEntity__AssetFaceEntity_asset"."fileModifiedAt" AS "AssetFaceEntity__AssetFaceEntity_asset_fileModifiedAt", + "AssetFaceEntity__AssetFaceEntity_asset"."isFavorite" AS "AssetFaceEntity__AssetFaceEntity_asset_isFavorite", + "AssetFaceEntity__AssetFaceEntity_asset"."isArchived" AS "AssetFaceEntity__AssetFaceEntity_asset_isArchived", + "AssetFaceEntity__AssetFaceEntity_asset"."isExternal" AS "AssetFaceEntity__AssetFaceEntity_asset_isExternal", + "AssetFaceEntity__AssetFaceEntity_asset"."isReadOnly" AS "AssetFaceEntity__AssetFaceEntity_asset_isReadOnly", + "AssetFaceEntity__AssetFaceEntity_asset"."isOffline" AS "AssetFaceEntity__AssetFaceEntity_asset_isOffline", + "AssetFaceEntity__AssetFaceEntity_asset"."checksum" AS "AssetFaceEntity__AssetFaceEntity_asset_checksum", + "AssetFaceEntity__AssetFaceEntity_asset"."duration" AS "AssetFaceEntity__AssetFaceEntity_asset_duration", + "AssetFaceEntity__AssetFaceEntity_asset"."isVisible" AS "AssetFaceEntity__AssetFaceEntity_asset_isVisible", + "AssetFaceEntity__AssetFaceEntity_asset"."livePhotoVideoId" AS "AssetFaceEntity__AssetFaceEntity_asset_livePhotoVideoId", + "AssetFaceEntity__AssetFaceEntity_asset"."originalFileName" AS "AssetFaceEntity__AssetFaceEntity_asset_originalFileName", + "AssetFaceEntity__AssetFaceEntity_asset"."sidecarPath" AS "AssetFaceEntity__AssetFaceEntity_asset_sidecarPath", + "AssetFaceEntity__AssetFaceEntity_asset"."stackParentId" AS "AssetFaceEntity__AssetFaceEntity_asset_stackParentId" +FROM + "asset_faces" "AssetFaceEntity" + LEFT JOIN "assets" "AssetFaceEntity__AssetFaceEntity_asset" ON "AssetFaceEntity__AssetFaceEntity_asset"."id" = "AssetFaceEntity"."assetId" +WHERE + ( + ( + "AssetFaceEntity"."assetId" = $1 + AND "AssetFaceEntity"."personId" = $2 + ) + ) + +-- PersonRepository.getRandomFace +SELECT + "AssetFaceEntity"."id" AS "AssetFaceEntity_id", + "AssetFaceEntity"."assetId" AS "AssetFaceEntity_assetId", + "AssetFaceEntity"."personId" AS "AssetFaceEntity_personId", + "AssetFaceEntity"."embedding" AS "AssetFaceEntity_embedding", + "AssetFaceEntity"."imageWidth" AS "AssetFaceEntity_imageWidth", + "AssetFaceEntity"."imageHeight" AS "AssetFaceEntity_imageHeight", + "AssetFaceEntity"."boundingBoxX1" AS "AssetFaceEntity_boundingBoxX1", + "AssetFaceEntity"."boundingBoxY1" AS "AssetFaceEntity_boundingBoxY1", + "AssetFaceEntity"."boundingBoxX2" AS "AssetFaceEntity_boundingBoxX2", + "AssetFaceEntity"."boundingBoxY2" AS "AssetFaceEntity_boundingBoxY2" +FROM + "asset_faces" "AssetFaceEntity" +WHERE + ("AssetFaceEntity"."personId" = $1) +LIMIT + 1 diff --git a/server/src/infra/sql/shared.link.repository.sql b/server/src/infra/sql/shared.link.repository.sql new file mode 100644 index 000000000..ffb05cd39 --- /dev/null +++ b/server/src/infra/sql/shared.link.repository.sql @@ -0,0 +1,327 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- SharedLinkRepository.get +SELECT DISTINCT + "distinctAlias"."SharedLinkEntity_id" AS "ids_SharedLinkEntity_id", + "distinctAlias"."SharedLinkEntity_createdAt", + "distinctAlias"."SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt", + "distinctAlias"."4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileCreatedAt" +FROM + ( + SELECT + "SharedLinkEntity"."id" AS "SharedLinkEntity_id", + "SharedLinkEntity"."description" AS "SharedLinkEntity_description", + "SharedLinkEntity"."password" AS "SharedLinkEntity_password", + "SharedLinkEntity"."userId" AS "SharedLinkEntity_userId", + "SharedLinkEntity"."key" AS "SharedLinkEntity_key", + "SharedLinkEntity"."type" AS "SharedLinkEntity_type", + "SharedLinkEntity"."createdAt" AS "SharedLinkEntity_createdAt", + "SharedLinkEntity"."expiresAt" AS "SharedLinkEntity_expiresAt", + "SharedLinkEntity"."allowUpload" AS "SharedLinkEntity_allowUpload", + "SharedLinkEntity"."allowDownload" AS "SharedLinkEntity_allowDownload", + "SharedLinkEntity"."showExif" AS "SharedLinkEntity_showExif", + "SharedLinkEntity"."albumId" AS "SharedLinkEntity_albumId", + "SharedLinkEntity__SharedLinkEntity_assets"."id" AS "SharedLinkEntity__SharedLinkEntity_assets_id", + "SharedLinkEntity__SharedLinkEntity_assets"."deviceAssetId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceAssetId", + "SharedLinkEntity__SharedLinkEntity_assets"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_assets_ownerId", + "SharedLinkEntity__SharedLinkEntity_assets"."libraryId" AS "SharedLinkEntity__SharedLinkEntity_assets_libraryId", + "SharedLinkEntity__SharedLinkEntity_assets"."deviceId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceId", + "SharedLinkEntity__SharedLinkEntity_assets"."type" AS "SharedLinkEntity__SharedLinkEntity_assets_type", + "SharedLinkEntity__SharedLinkEntity_assets"."originalPath" AS "SharedLinkEntity__SharedLinkEntity_assets_originalPath", + "SharedLinkEntity__SharedLinkEntity_assets"."resizePath" AS "SharedLinkEntity__SharedLinkEntity_assets_resizePath", + "SharedLinkEntity__SharedLinkEntity_assets"."webpPath" AS "SharedLinkEntity__SharedLinkEntity_assets_webpPath", + "SharedLinkEntity__SharedLinkEntity_assets"."thumbhash" AS "SharedLinkEntity__SharedLinkEntity_assets_thumbhash", + "SharedLinkEntity__SharedLinkEntity_assets"."encodedVideoPath" AS "SharedLinkEntity__SharedLinkEntity_assets_encodedVideoPath", + "SharedLinkEntity__SharedLinkEntity_assets"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_assets_createdAt", + "SharedLinkEntity__SharedLinkEntity_assets"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_updatedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_deletedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."fileCreatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."localDateTime" AS "SharedLinkEntity__SharedLinkEntity_assets_localDateTime", + "SharedLinkEntity__SharedLinkEntity_assets"."fileModifiedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileModifiedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."isFavorite" AS "SharedLinkEntity__SharedLinkEntity_assets_isFavorite", + "SharedLinkEntity__SharedLinkEntity_assets"."isArchived" AS "SharedLinkEntity__SharedLinkEntity_assets_isArchived", + "SharedLinkEntity__SharedLinkEntity_assets"."isExternal" AS "SharedLinkEntity__SharedLinkEntity_assets_isExternal", + "SharedLinkEntity__SharedLinkEntity_assets"."isReadOnly" AS "SharedLinkEntity__SharedLinkEntity_assets_isReadOnly", + "SharedLinkEntity__SharedLinkEntity_assets"."isOffline" AS "SharedLinkEntity__SharedLinkEntity_assets_isOffline", + "SharedLinkEntity__SharedLinkEntity_assets"."checksum" AS "SharedLinkEntity__SharedLinkEntity_assets_checksum", + "SharedLinkEntity__SharedLinkEntity_assets"."duration" AS "SharedLinkEntity__SharedLinkEntity_assets_duration", + "SharedLinkEntity__SharedLinkEntity_assets"."isVisible" AS "SharedLinkEntity__SharedLinkEntity_assets_isVisible", + "SharedLinkEntity__SharedLinkEntity_assets"."livePhotoVideoId" AS "SharedLinkEntity__SharedLinkEntity_assets_livePhotoVideoId", + "SharedLinkEntity__SharedLinkEntity_assets"."originalFileName" AS "SharedLinkEntity__SharedLinkEntity_assets_originalFileName", + "SharedLinkEntity__SharedLinkEntity_assets"."sidecarPath" AS "SharedLinkEntity__SharedLinkEntity_assets_sidecarPath", + "SharedLinkEntity__SharedLinkEntity_assets"."stackParentId" AS "SharedLinkEntity__SharedLinkEntity_assets_stackParentId", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."assetId" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_assetId", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."description" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_description", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."exifImageWidth" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_exifImageWidth", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."exifImageHeight" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_exifImageHeight", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."fileSizeInByte" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_fileSizeInByte", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."orientation" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_orientation", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."dateTimeOriginal" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_dateTimeOriginal", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."modifyDate" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_modifyDate", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."timeZone" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_timeZone", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."latitude" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_latitude", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."longitude" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_longitude", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."projectionType" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_projectionType", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."city" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_city", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."livePhotoCID" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_livePhotoCID", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."state" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_state", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."country" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_country", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."make" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_make", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."model" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_model", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."lensModel" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_lensModel", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."fNumber" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_fNumber", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."focalLength" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_focalLength", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."iso" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_iso", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."exposureTime" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_exposureTime", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."profileDescription" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_profileDescription", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."colorspace" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_colorspace", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."bitsPerSample" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_bitsPerSample", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."fps" AS "9b1d35b344d838023994a3233afd6ffe098be6d8_fps", + "9b1d35b344d838023994a3233afd6ffe098be6d8"."exifTextSearchableColumn" AS "e18de9deffa83f81ac3c43b5e8c2f08dba727bf8", + "SharedLinkEntity__SharedLinkEntity_album"."id" AS "SharedLinkEntity__SharedLinkEntity_album_id", + "SharedLinkEntity__SharedLinkEntity_album"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_album_ownerId", + "SharedLinkEntity__SharedLinkEntity_album"."albumName" AS "SharedLinkEntity__SharedLinkEntity_album_albumName", + "SharedLinkEntity__SharedLinkEntity_album"."description" AS "SharedLinkEntity__SharedLinkEntity_album_description", + "SharedLinkEntity__SharedLinkEntity_album"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_album_createdAt", + "SharedLinkEntity__SharedLinkEntity_album"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_album_updatedAt", + "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_album_deletedAt", + "SharedLinkEntity__SharedLinkEntity_album"."albumThumbnailAssetId" AS "SharedLinkEntity__SharedLinkEntity_album_albumThumbnailAssetId", + "SharedLinkEntity__SharedLinkEntity_album"."isActivityEnabled" AS "SharedLinkEntity__SharedLinkEntity_album_isActivityEnabled", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."id" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_id", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deviceAssetId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_deviceAssetId", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."ownerId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_ownerId", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."libraryId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_libraryId", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deviceId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_deviceId", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."type" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_type", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."originalPath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_originalPath", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."resizePath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_resizePath", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."webpPath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_webpPath", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."thumbhash" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_thumbhash", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."encodedVideoPath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_encodedVideoPath", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."createdAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_createdAt", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."updatedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_updatedAt", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deletedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_deletedAt", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."fileCreatedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileCreatedAt", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."localDateTime" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_localDateTime", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."fileModifiedAt" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileModifiedAt", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isFavorite" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isFavorite", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isArchived" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isArchived", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isExternal" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isExternal", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isReadOnly" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isReadOnly", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isOffline" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isOffline", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."checksum" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_checksum", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."duration" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_duration", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."isVisible" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_isVisible", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."livePhotoVideoId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_livePhotoVideoId", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."originalFileName" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_originalFileName", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."sidecarPath" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_sidecarPath", + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."stackParentId" AS "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_stackParentId", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."assetId" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_assetId", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."description" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_description", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."exifImageWidth" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_exifImageWidth", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."exifImageHeight" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_exifImageHeight", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."fileSizeInByte" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_fileSizeInByte", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."orientation" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_orientation", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."dateTimeOriginal" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_dateTimeOriginal", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."modifyDate" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_modifyDate", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."timeZone" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_timeZone", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."latitude" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_latitude", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."longitude" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_longitude", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."projectionType" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_projectionType", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."city" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_city", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."livePhotoCID" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_livePhotoCID", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."state" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_state", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."country" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_country", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."make" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_make", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."model" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_model", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."lensModel" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_lensModel", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."fNumber" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_fNumber", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."focalLength" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_focalLength", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."iso" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_iso", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."exposureTime" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_exposureTime", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."profileDescription" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_profileDescription", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."colorspace" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_colorspace", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."bitsPerSample" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_bitsPerSample", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."fps" AS "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f_fps", + "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."exifTextSearchableColumn" AS "96535c8046de591cca9b8c5825e6c5db502b0e6a", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_id", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."name" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_name", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."avatarColor" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_avatarColor", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."isAdmin" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_isAdmin", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."email" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_email", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."storageLabel" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_storageLabel", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."externalPath" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_externalPath", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."oauthId" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_oauthId", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileImagePath" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileImagePath", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."shouldChangePassword" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_shouldChangePassword", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."createdAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_createdAt", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_deletedAt", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."memoriesEnabled" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_memoriesEnabled" + FROM + "shared_links" "SharedLinkEntity" + LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id" + LEFT JOIN "assets" "SharedLinkEntity__SharedLinkEntity_assets" ON "SharedLinkEntity__SharedLinkEntity_assets"."id" = "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."assetsId" + AND ( + "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" IS NULL + ) + LEFT JOIN "exif" "9b1d35b344d838023994a3233afd6ffe098be6d8" ON "9b1d35b344d838023994a3233afd6ffe098be6d8"."assetId" = "SharedLinkEntity__SharedLinkEntity_assets"."id" + LEFT JOIN "albums" "SharedLinkEntity__SharedLinkEntity_album" ON "SharedLinkEntity__SharedLinkEntity_album"."id" = "SharedLinkEntity"."albumId" + AND ( + "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" IS NULL + ) + LEFT JOIN "albums_assets_assets" "760f12c00d97bdcec1ce224d1e3bf449859942b6" ON "760f12c00d97bdcec1ce224d1e3bf449859942b6"."albumsId" = "SharedLinkEntity__SharedLinkEntity_album"."id" + LEFT JOIN "assets" "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6" ON "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."id" = "760f12c00d97bdcec1ce224d1e3bf449859942b6"."assetsId" + AND ( + "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."deletedAt" IS NULL + ) + LEFT JOIN "exif" "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f" ON "d9f2f4dd8920bad1d6907cdb1d699732daff3c2f"."assetId" = "4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6"."id" + LEFT JOIN "users" "6d7fd45329a05fd86b3dbcacde87fe76e33a422d" ON "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" = "SharedLinkEntity__SharedLinkEntity_album"."ownerId" + AND ( + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" IS NULL + ) + WHERE + ( + "SharedLinkEntity"."id" = $1 + AND "SharedLinkEntity"."userId" = $2 + ) + ) "distinctAlias" +ORDER BY + "distinctAlias"."SharedLinkEntity_createdAt" DESC, + "distinctAlias"."SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt" ASC, + "distinctAlias"."4a35f463ae8c5544ede95c4b6d9ce8c686b6bfe6_fileCreatedAt" ASC, + "SharedLinkEntity_id" ASC +LIMIT + 1 + +-- SharedLinkRepository.getAll +SELECT + "SharedLinkEntity"."id" AS "SharedLinkEntity_id", + "SharedLinkEntity"."description" AS "SharedLinkEntity_description", + "SharedLinkEntity"."password" AS "SharedLinkEntity_password", + "SharedLinkEntity"."userId" AS "SharedLinkEntity_userId", + "SharedLinkEntity"."key" AS "SharedLinkEntity_key", + "SharedLinkEntity"."type" AS "SharedLinkEntity_type", + "SharedLinkEntity"."createdAt" AS "SharedLinkEntity_createdAt", + "SharedLinkEntity"."expiresAt" AS "SharedLinkEntity_expiresAt", + "SharedLinkEntity"."allowUpload" AS "SharedLinkEntity_allowUpload", + "SharedLinkEntity"."allowDownload" AS "SharedLinkEntity_allowDownload", + "SharedLinkEntity"."showExif" AS "SharedLinkEntity_showExif", + "SharedLinkEntity"."albumId" AS "SharedLinkEntity_albumId", + "SharedLinkEntity__SharedLinkEntity_assets"."id" AS "SharedLinkEntity__SharedLinkEntity_assets_id", + "SharedLinkEntity__SharedLinkEntity_assets"."deviceAssetId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceAssetId", + "SharedLinkEntity__SharedLinkEntity_assets"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_assets_ownerId", + "SharedLinkEntity__SharedLinkEntity_assets"."libraryId" AS "SharedLinkEntity__SharedLinkEntity_assets_libraryId", + "SharedLinkEntity__SharedLinkEntity_assets"."deviceId" AS "SharedLinkEntity__SharedLinkEntity_assets_deviceId", + "SharedLinkEntity__SharedLinkEntity_assets"."type" AS "SharedLinkEntity__SharedLinkEntity_assets_type", + "SharedLinkEntity__SharedLinkEntity_assets"."originalPath" AS "SharedLinkEntity__SharedLinkEntity_assets_originalPath", + "SharedLinkEntity__SharedLinkEntity_assets"."resizePath" AS "SharedLinkEntity__SharedLinkEntity_assets_resizePath", + "SharedLinkEntity__SharedLinkEntity_assets"."webpPath" AS "SharedLinkEntity__SharedLinkEntity_assets_webpPath", + "SharedLinkEntity__SharedLinkEntity_assets"."thumbhash" AS "SharedLinkEntity__SharedLinkEntity_assets_thumbhash", + "SharedLinkEntity__SharedLinkEntity_assets"."encodedVideoPath" AS "SharedLinkEntity__SharedLinkEntity_assets_encodedVideoPath", + "SharedLinkEntity__SharedLinkEntity_assets"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_assets_createdAt", + "SharedLinkEntity__SharedLinkEntity_assets"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_updatedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_deletedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."fileCreatedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileCreatedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."localDateTime" AS "SharedLinkEntity__SharedLinkEntity_assets_localDateTime", + "SharedLinkEntity__SharedLinkEntity_assets"."fileModifiedAt" AS "SharedLinkEntity__SharedLinkEntity_assets_fileModifiedAt", + "SharedLinkEntity__SharedLinkEntity_assets"."isFavorite" AS "SharedLinkEntity__SharedLinkEntity_assets_isFavorite", + "SharedLinkEntity__SharedLinkEntity_assets"."isArchived" AS "SharedLinkEntity__SharedLinkEntity_assets_isArchived", + "SharedLinkEntity__SharedLinkEntity_assets"."isExternal" AS "SharedLinkEntity__SharedLinkEntity_assets_isExternal", + "SharedLinkEntity__SharedLinkEntity_assets"."isReadOnly" AS "SharedLinkEntity__SharedLinkEntity_assets_isReadOnly", + "SharedLinkEntity__SharedLinkEntity_assets"."isOffline" AS "SharedLinkEntity__SharedLinkEntity_assets_isOffline", + "SharedLinkEntity__SharedLinkEntity_assets"."checksum" AS "SharedLinkEntity__SharedLinkEntity_assets_checksum", + "SharedLinkEntity__SharedLinkEntity_assets"."duration" AS "SharedLinkEntity__SharedLinkEntity_assets_duration", + "SharedLinkEntity__SharedLinkEntity_assets"."isVisible" AS "SharedLinkEntity__SharedLinkEntity_assets_isVisible", + "SharedLinkEntity__SharedLinkEntity_assets"."livePhotoVideoId" AS "SharedLinkEntity__SharedLinkEntity_assets_livePhotoVideoId", + "SharedLinkEntity__SharedLinkEntity_assets"."originalFileName" AS "SharedLinkEntity__SharedLinkEntity_assets_originalFileName", + "SharedLinkEntity__SharedLinkEntity_assets"."sidecarPath" AS "SharedLinkEntity__SharedLinkEntity_assets_sidecarPath", + "SharedLinkEntity__SharedLinkEntity_assets"."stackParentId" AS "SharedLinkEntity__SharedLinkEntity_assets_stackParentId", + "SharedLinkEntity__SharedLinkEntity_album"."id" AS "SharedLinkEntity__SharedLinkEntity_album_id", + "SharedLinkEntity__SharedLinkEntity_album"."ownerId" AS "SharedLinkEntity__SharedLinkEntity_album_ownerId", + "SharedLinkEntity__SharedLinkEntity_album"."albumName" AS "SharedLinkEntity__SharedLinkEntity_album_albumName", + "SharedLinkEntity__SharedLinkEntity_album"."description" AS "SharedLinkEntity__SharedLinkEntity_album_description", + "SharedLinkEntity__SharedLinkEntity_album"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_album_createdAt", + "SharedLinkEntity__SharedLinkEntity_album"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_album_updatedAt", + "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_album_deletedAt", + "SharedLinkEntity__SharedLinkEntity_album"."albumThumbnailAssetId" AS "SharedLinkEntity__SharedLinkEntity_album_albumThumbnailAssetId", + "SharedLinkEntity__SharedLinkEntity_album"."isActivityEnabled" AS "SharedLinkEntity__SharedLinkEntity_album_isActivityEnabled", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_id", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."name" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_name", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."avatarColor" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_avatarColor", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."isAdmin" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_isAdmin", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."email" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_email", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."storageLabel" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_storageLabel", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."externalPath" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_externalPath", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."oauthId" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_oauthId", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."profileImagePath" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_profileImagePath", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."shouldChangePassword" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_shouldChangePassword", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."createdAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_createdAt", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_deletedAt", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."updatedAt" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_updatedAt", + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."memoriesEnabled" AS "6d7fd45329a05fd86b3dbcacde87fe76e33a422d_memoriesEnabled" +FROM + "shared_links" "SharedLinkEntity" + LEFT JOIN "shared_link__asset" "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity" ON "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."sharedLinksId" = "SharedLinkEntity"."id" + LEFT JOIN "assets" "SharedLinkEntity__SharedLinkEntity_assets" ON "SharedLinkEntity__SharedLinkEntity_assets"."id" = "SharedLinkEntity__SharedLinkEntity_assets_SharedLinkEntity"."assetsId" + AND ( + "SharedLinkEntity__SharedLinkEntity_assets"."deletedAt" IS NULL + ) + LEFT JOIN "albums" "SharedLinkEntity__SharedLinkEntity_album" ON "SharedLinkEntity__SharedLinkEntity_album"."id" = "SharedLinkEntity"."albumId" + AND ( + "SharedLinkEntity__SharedLinkEntity_album"."deletedAt" IS NULL + ) + LEFT JOIN "users" "6d7fd45329a05fd86b3dbcacde87fe76e33a422d" ON "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."id" = "SharedLinkEntity__SharedLinkEntity_album"."ownerId" + AND ( + "6d7fd45329a05fd86b3dbcacde87fe76e33a422d"."deletedAt" IS NULL + ) +WHERE + ("SharedLinkEntity"."userId" = $1) +ORDER BY + "SharedLinkEntity"."createdAt" DESC + +-- SharedLinkRepository.getByKey +SELECT DISTINCT + "distinctAlias"."SharedLinkEntity_id" AS "ids_SharedLinkEntity_id" +FROM + ( + SELECT + "SharedLinkEntity"."id" AS "SharedLinkEntity_id", + "SharedLinkEntity"."description" AS "SharedLinkEntity_description", + "SharedLinkEntity"."password" AS "SharedLinkEntity_password", + "SharedLinkEntity"."userId" AS "SharedLinkEntity_userId", + "SharedLinkEntity"."key" AS "SharedLinkEntity_key", + "SharedLinkEntity"."type" AS "SharedLinkEntity_type", + "SharedLinkEntity"."createdAt" AS "SharedLinkEntity_createdAt", + "SharedLinkEntity"."expiresAt" AS "SharedLinkEntity_expiresAt", + "SharedLinkEntity"."allowUpload" AS "SharedLinkEntity_allowUpload", + "SharedLinkEntity"."allowDownload" AS "SharedLinkEntity_allowDownload", + "SharedLinkEntity"."showExif" AS "SharedLinkEntity_showExif", + "SharedLinkEntity"."albumId" AS "SharedLinkEntity_albumId", + "SharedLinkEntity__SharedLinkEntity_user"."id" AS "SharedLinkEntity__SharedLinkEntity_user_id", + "SharedLinkEntity__SharedLinkEntity_user"."name" AS "SharedLinkEntity__SharedLinkEntity_user_name", + "SharedLinkEntity__SharedLinkEntity_user"."avatarColor" AS "SharedLinkEntity__SharedLinkEntity_user_avatarColor", + "SharedLinkEntity__SharedLinkEntity_user"."isAdmin" AS "SharedLinkEntity__SharedLinkEntity_user_isAdmin", + "SharedLinkEntity__SharedLinkEntity_user"."email" AS "SharedLinkEntity__SharedLinkEntity_user_email", + "SharedLinkEntity__SharedLinkEntity_user"."storageLabel" AS "SharedLinkEntity__SharedLinkEntity_user_storageLabel", + "SharedLinkEntity__SharedLinkEntity_user"."externalPath" AS "SharedLinkEntity__SharedLinkEntity_user_externalPath", + "SharedLinkEntity__SharedLinkEntity_user"."oauthId" AS "SharedLinkEntity__SharedLinkEntity_user_oauthId", + "SharedLinkEntity__SharedLinkEntity_user"."profileImagePath" AS "SharedLinkEntity__SharedLinkEntity_user_profileImagePath", + "SharedLinkEntity__SharedLinkEntity_user"."shouldChangePassword" AS "SharedLinkEntity__SharedLinkEntity_user_shouldChangePassword", + "SharedLinkEntity__SharedLinkEntity_user"."createdAt" AS "SharedLinkEntity__SharedLinkEntity_user_createdAt", + "SharedLinkEntity__SharedLinkEntity_user"."deletedAt" AS "SharedLinkEntity__SharedLinkEntity_user_deletedAt", + "SharedLinkEntity__SharedLinkEntity_user"."updatedAt" AS "SharedLinkEntity__SharedLinkEntity_user_updatedAt", + "SharedLinkEntity__SharedLinkEntity_user"."memoriesEnabled" AS "SharedLinkEntity__SharedLinkEntity_user_memoriesEnabled" + FROM + "shared_links" "SharedLinkEntity" + LEFT JOIN "users" "SharedLinkEntity__SharedLinkEntity_user" ON "SharedLinkEntity__SharedLinkEntity_user"."id" = "SharedLinkEntity"."userId" + AND ( + "SharedLinkEntity__SharedLinkEntity_user"."deletedAt" IS NULL + ) + WHERE + ("SharedLinkEntity"."key" = $1) + ) "distinctAlias" +ORDER BY + "SharedLinkEntity_id" ASC +LIMIT + 1 diff --git a/server/src/infra/sql/system.config.repository.sql b/server/src/infra/sql/system.config.repository.sql new file mode 100644 index 000000000..276cab20f --- /dev/null +++ b/server/src/infra/sql/system.config.repository.sql @@ -0,0 +1,13 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- SystemConfigRepository.load +SELECT + "SystemConfigEntity"."key" AS "SystemConfigEntity_key", + "SystemConfigEntity"."value" AS "SystemConfigEntity_value" +FROM + "system_config" "SystemConfigEntity" + +-- SystemConfigRepository.deleteKeys +DELETE FROM "system_config" +WHERE + "key" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9) diff --git a/server/src/infra/sql/system.metadata.repository.sql b/server/src/infra/sql/system.metadata.repository.sql new file mode 100644 index 000000000..21f9f116b --- /dev/null +++ b/server/src/infra/sql/system.metadata.repository.sql @@ -0,0 +1 @@ +-- NOTE: This file is auto generated by ./sql-generator diff --git a/server/src/infra/sql/tag.repository.sql b/server/src/infra/sql/tag.repository.sql new file mode 100644 index 000000000..21f9f116b --- /dev/null +++ b/server/src/infra/sql/tag.repository.sql @@ -0,0 +1 @@ +-- NOTE: This file is auto generated by ./sql-generator diff --git a/server/src/infra/sql/user.repository.sql b/server/src/infra/sql/user.repository.sql new file mode 100644 index 000000000..d21f1e7b0 --- /dev/null +++ b/server/src/infra/sql/user.repository.sql @@ -0,0 +1,143 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- UserRepository.getAdmin +SELECT + "UserEntity"."id" AS "UserEntity_id", + "UserEntity"."name" AS "UserEntity_name", + "UserEntity"."avatarColor" AS "UserEntity_avatarColor", + "UserEntity"."isAdmin" AS "UserEntity_isAdmin", + "UserEntity"."email" AS "UserEntity_email", + "UserEntity"."storageLabel" AS "UserEntity_storageLabel", + "UserEntity"."externalPath" AS "UserEntity_externalPath", + "UserEntity"."oauthId" AS "UserEntity_oauthId", + "UserEntity"."profileImagePath" AS "UserEntity_profileImagePath", + "UserEntity"."shouldChangePassword" AS "UserEntity_shouldChangePassword", + "UserEntity"."createdAt" AS "UserEntity_createdAt", + "UserEntity"."deletedAt" AS "UserEntity_deletedAt", + "UserEntity"."updatedAt" AS "UserEntity_updatedAt", + "UserEntity"."memoriesEnabled" AS "UserEntity_memoriesEnabled" +FROM + "users" "UserEntity" +WHERE + (("UserEntity"."isAdmin" = $1)) + AND ("UserEntity"."deletedAt" IS NULL) +LIMIT + 1 + +-- UserRepository.hasAdmin +SELECT + 1 AS "row_exists" +FROM + ( + SELECT + 1 AS dummy_column + ) "dummy_table" +WHERE + EXISTS ( + SELECT + 1 + FROM + "users" "UserEntity" + WHERE + (("UserEntity"."isAdmin" = $1)) + AND ("UserEntity"."deletedAt" IS NULL) + ) +LIMIT + 1 + +-- UserRepository.getByEmail +SELECT + "user"."id" AS "user_id", + "user"."name" AS "user_name", + "user"."avatarColor" AS "user_avatarColor", + "user"."isAdmin" AS "user_isAdmin", + "user"."email" AS "user_email", + "user"."storageLabel" AS "user_storageLabel", + "user"."externalPath" AS "user_externalPath", + "user"."oauthId" AS "user_oauthId", + "user"."profileImagePath" AS "user_profileImagePath", + "user"."shouldChangePassword" AS "user_shouldChangePassword", + "user"."createdAt" AS "user_createdAt", + "user"."deletedAt" AS "user_deletedAt", + "user"."updatedAt" AS "user_updatedAt", + "user"."memoriesEnabled" AS "user_memoriesEnabled" +FROM + "users" "user" +WHERE + ("user"."email" = $1) + AND ("user"."deletedAt" IS NULL) + +-- UserRepository.getByStorageLabel +SELECT + "UserEntity"."id" AS "UserEntity_id", + "UserEntity"."name" AS "UserEntity_name", + "UserEntity"."avatarColor" AS "UserEntity_avatarColor", + "UserEntity"."isAdmin" AS "UserEntity_isAdmin", + "UserEntity"."email" AS "UserEntity_email", + "UserEntity"."storageLabel" AS "UserEntity_storageLabel", + "UserEntity"."externalPath" AS "UserEntity_externalPath", + "UserEntity"."oauthId" AS "UserEntity_oauthId", + "UserEntity"."profileImagePath" AS "UserEntity_profileImagePath", + "UserEntity"."shouldChangePassword" AS "UserEntity_shouldChangePassword", + "UserEntity"."createdAt" AS "UserEntity_createdAt", + "UserEntity"."deletedAt" AS "UserEntity_deletedAt", + "UserEntity"."updatedAt" AS "UserEntity_updatedAt", + "UserEntity"."memoriesEnabled" AS "UserEntity_memoriesEnabled" +FROM + "users" "UserEntity" +WHERE + (("UserEntity"."storageLabel" = $1)) + AND ("UserEntity"."deletedAt" IS NULL) +LIMIT + 1 + +-- UserRepository.getByOAuthId +SELECT + "UserEntity"."id" AS "UserEntity_id", + "UserEntity"."name" AS "UserEntity_name", + "UserEntity"."avatarColor" AS "UserEntity_avatarColor", + "UserEntity"."isAdmin" AS "UserEntity_isAdmin", + "UserEntity"."email" AS "UserEntity_email", + "UserEntity"."storageLabel" AS "UserEntity_storageLabel", + "UserEntity"."externalPath" AS "UserEntity_externalPath", + "UserEntity"."oauthId" AS "UserEntity_oauthId", + "UserEntity"."profileImagePath" AS "UserEntity_profileImagePath", + "UserEntity"."shouldChangePassword" AS "UserEntity_shouldChangePassword", + "UserEntity"."createdAt" AS "UserEntity_createdAt", + "UserEntity"."deletedAt" AS "UserEntity_deletedAt", + "UserEntity"."updatedAt" AS "UserEntity_updatedAt", + "UserEntity"."memoriesEnabled" AS "UserEntity_memoriesEnabled" +FROM + "users" "UserEntity" +WHERE + (("UserEntity"."oauthId" = $1)) + AND ("UserEntity"."deletedAt" IS NULL) +LIMIT + 1 + +-- UserRepository.getUserStats +SELECT + "users"."id" AS "userId", + "users"."name" AS "userName", + COUNT("assets"."id") FILTER ( + WHERE + "assets"."type" = 'IMAGE' + AND "assets"."isVisible" + ) AS "photos", + COUNT("assets"."id") FILTER ( + WHERE + "assets"."type" = 'VIDEO' + AND "assets"."isVisible" + ) AS "videos", + COALESCE(SUM("exif"."fileSizeInByte"), 0) AS "usage" +FROM + "users" "users" + LEFT JOIN "assets" "assets" ON "assets"."ownerId" = "users"."id" + AND ("assets"."deletedAt" IS NULL) + LEFT JOIN "exif" "exif" ON "exif"."assetId" = "assets"."id" +WHERE + "users"."deletedAt" IS NULL +GROUP BY + "users"."id" +ORDER BY + "users"."createdAt" ASC diff --git a/server/src/infra/sql/user.token.repository.sql b/server/src/infra/sql/user.token.repository.sql new file mode 100644 index 000000000..e1d190622 --- /dev/null +++ b/server/src/infra/sql/user.token.repository.sql @@ -0,0 +1,46 @@ +-- NOTE: This file is auto generated by ./sql-generator + +-- UserTokenRepository.getByToken +SELECT DISTINCT + "distinctAlias"."UserTokenEntity_id" AS "ids_UserTokenEntity_id" +FROM + ( + SELECT + "UserTokenEntity"."id" AS "UserTokenEntity_id", + "UserTokenEntity"."userId" AS "UserTokenEntity_userId", + "UserTokenEntity"."createdAt" AS "UserTokenEntity_createdAt", + "UserTokenEntity"."updatedAt" AS "UserTokenEntity_updatedAt", + "UserTokenEntity"."deviceType" AS "UserTokenEntity_deviceType", + "UserTokenEntity"."deviceOS" AS "UserTokenEntity_deviceOS", + "UserTokenEntity__UserTokenEntity_user"."id" AS "UserTokenEntity__UserTokenEntity_user_id", + "UserTokenEntity__UserTokenEntity_user"."name" AS "UserTokenEntity__UserTokenEntity_user_name", + "UserTokenEntity__UserTokenEntity_user"."avatarColor" AS "UserTokenEntity__UserTokenEntity_user_avatarColor", + "UserTokenEntity__UserTokenEntity_user"."isAdmin" AS "UserTokenEntity__UserTokenEntity_user_isAdmin", + "UserTokenEntity__UserTokenEntity_user"."email" AS "UserTokenEntity__UserTokenEntity_user_email", + "UserTokenEntity__UserTokenEntity_user"."storageLabel" AS "UserTokenEntity__UserTokenEntity_user_storageLabel", + "UserTokenEntity__UserTokenEntity_user"."externalPath" AS "UserTokenEntity__UserTokenEntity_user_externalPath", + "UserTokenEntity__UserTokenEntity_user"."oauthId" AS "UserTokenEntity__UserTokenEntity_user_oauthId", + "UserTokenEntity__UserTokenEntity_user"."profileImagePath" AS "UserTokenEntity__UserTokenEntity_user_profileImagePath", + "UserTokenEntity__UserTokenEntity_user"."shouldChangePassword" AS "UserTokenEntity__UserTokenEntity_user_shouldChangePassword", + "UserTokenEntity__UserTokenEntity_user"."createdAt" AS "UserTokenEntity__UserTokenEntity_user_createdAt", + "UserTokenEntity__UserTokenEntity_user"."deletedAt" AS "UserTokenEntity__UserTokenEntity_user_deletedAt", + "UserTokenEntity__UserTokenEntity_user"."updatedAt" AS "UserTokenEntity__UserTokenEntity_user_updatedAt", + "UserTokenEntity__UserTokenEntity_user"."memoriesEnabled" AS "UserTokenEntity__UserTokenEntity_user_memoriesEnabled" + FROM + "user_token" "UserTokenEntity" + LEFT JOIN "users" "UserTokenEntity__UserTokenEntity_user" ON "UserTokenEntity__UserTokenEntity_user"."id" = "UserTokenEntity"."userId" + AND ( + "UserTokenEntity__UserTokenEntity_user"."deletedAt" IS NULL + ) + WHERE + ("UserTokenEntity"."token" = $1) + ) "distinctAlias" +ORDER BY + "UserTokenEntity_id" ASC +LIMIT + 1 + +-- UserTokenRepository.delete +DELETE FROM "user_token" +WHERE + "id" = $1