-- NOTE: This file is auto generated by ./sql-generator

-- AssetRepository.updateAllExif
update "exif"
set
  "model" = $1
where
  "assetId" in ($2)

-- AssetRepository.getByDayOfYear
with
  "res" as (
    with
      "today" as (
        select
          make_date(year::int, $1::int, $2::int) as "date"
        from
          generate_series(
            (
              select
                date_part(
                  'year',
                  min(("localDateTime" at time zone 'UTC')::date)
                )::int
              from
                assets
            ),
            date_part('year', current_date)::int - 1
          ) as "year"
      )
    select
      "a".*,
      to_json("exif") as "exifInfo"
    from
      "today"
      inner join lateral (
        select
          "assets".*
        from
          "assets"
          inner join "asset_job_status" on "assets"."id" = "asset_job_status"."assetId"
        where
          "asset_job_status"."previewAt" is not null
          and (assets."localDateTime" at time zone 'UTC')::date = today.date
          and "assets"."ownerId" = any ($3::uuid[])
          and "assets"."visibility" = $4
          and exists (
            select
            from
              "asset_files"
            where
              "assetId" = "assets"."id"
              and "asset_files"."type" = $5
          )
          and "assets"."deletedAt" is null
        order by
          (assets."localDateTime" at time zone 'UTC')::date desc
        limit
          $6
      ) as "a" on true
      inner join "exif" on "a"."id" = "exif"."assetId"
  )
select
  date_part(
    'year',
    ("localDateTime" at time zone 'UTC')::date
  )::int as "year",
  json_agg("res") as "assets"
from
  "res"
group by
  ("localDateTime" at time zone 'UTC')::date
order by
  ("localDateTime" at time zone 'UTC')::date desc

-- AssetRepository.getByIds
select
  "assets".*
from
  "assets"
where
  "assets"."id" = any ($1::uuid[])

-- AssetRepository.getByIdsWithAllRelationsButStacks
select
  "assets".*,
  (
    select
      coalesce(json_agg(agg), '[]')
    from
      (
        select
          "asset_faces".*,
          "person" as "person"
        from
          "asset_faces"
          left join lateral (
            select
              "person".*
            from
              "person"
            where
              "asset_faces"."personId" = "person"."id"
          ) as "person" on true
        where
          "asset_faces"."assetId" = "assets"."id"
          and "asset_faces"."deletedAt" is null
      ) as agg
  ) as "faces",
  (
    select
      coalesce(json_agg(agg), '[]')
    from
      (
        select
          "tags"."id",
          "tags"."value",
          "tags"."createdAt",
          "tags"."updatedAt",
          "tags"."color",
          "tags"."parentId"
        from
          "tags"
          inner join "tag_asset" on "tags"."id" = "tag_asset"."tagsId"
        where
          "assets"."id" = "tag_asset"."assetsId"
      ) as agg
  ) as "tags",
  to_json("exif") as "exifInfo"
from
  "assets"
  left join "exif" on "assets"."id" = "exif"."assetId"
where
  "assets"."id" = any ($1::uuid[])

-- AssetRepository.deleteAll
delete from "assets"
where
  "ownerId" = $1

-- AssetRepository.getByLibraryIdAndOriginalPath
select
  "assets".*
from
  "assets"
where
  "libraryId" = $1::uuid
  and "originalPath" = $2
limit
  $3

-- AssetRepository.getAllByDeviceId
select
  "deviceAssetId"
from
  "assets"
where
  "ownerId" = $1::uuid
  and "deviceId" = $2
  and "visibility" != $3
  and "deletedAt" is null

-- AssetRepository.getLivePhotoCount
select
  count(*) as "count"
from
  "assets"
where
  "livePhotoVideoId" = $1::uuid

-- AssetRepository.getById
select
  "assets".*
from
  "assets"
where
  "assets"."id" = $1::uuid
limit
  $2

-- AssetRepository.updateAll
update "assets"
set
  "deviceId" = $1
where
  "id" = any ($2::uuid[])

-- AssetRepository.updateDuplicates
update "assets"
set
  "duplicateId" = $1
where
  (
    "duplicateId" = any ($2::uuid[])
    or "id" = any ($3::uuid[])
  )

-- AssetRepository.getByChecksum
select
  "assets".*
from
  "assets"
where
  "ownerId" = $1::uuid
  and "checksum" = $2
  and "libraryId" = $3::uuid
limit
  $4

-- AssetRepository.getByChecksums
select
  "id",
  "checksum",
  "deletedAt"
from
  "assets"
where
  "ownerId" = $1::uuid
  and "checksum" in ($2)

-- AssetRepository.getUploadAssetIdByChecksum
select
  "id"
from
  "assets"
where
  "ownerId" = $1::uuid
  and "checksum" = $2
  and "libraryId" is null
limit
  $3

-- AssetRepository.getTimeBuckets
with
  "assets" as (
    select
      date_trunc('MONTH', "localDateTime" at time zone 'UTC') at time zone 'UTC' as "timeBucket"
    from
      "assets"
    where
      "assets"."deletedAt" is null
      and "assets"."visibility" in ('archive', 'timeline')
  )
select
  "timeBucket",
  count(*) as "count"
from
  "assets"
group by
  "timeBucket"
order by
  "timeBucket" desc

-- AssetRepository.getTimeBucket
with
  "cte" as (
    select
      "assets"."duration",
      "assets"."id",
      "assets"."visibility",
      "assets"."isFavorite",
      assets.type = 'IMAGE' as "isImage",
      assets."deletedAt" is not null as "isTrashed",
      "assets"."livePhotoVideoId",
      "assets"."localDateTime",
      "assets"."ownerId",
      "assets"."status",
      encode("assets"."thumbhash", 'base64') as "thumbhash",
      "exif"."city",
      "exif"."country",
      "exif"."projectionType",
      coalesce(
        case
          when exif."exifImageHeight" = 0
          or exif."exifImageWidth" = 0 then 1
          when "exif"."orientation" in ('5', '6', '7', '8', '-90', '90') then round(
            exif."exifImageHeight"::numeric / exif."exifImageWidth"::numeric,
            3
          )
          else round(
            exif."exifImageWidth"::numeric / exif."exifImageHeight"::numeric,
            3
          )
        end,
        1
      ) as "ratio",
      "stack"
    from
      "assets"
      inner join "exif" on "assets"."id" = "exif"."assetId"
      left join lateral (
        select
          array[stacked."stackId"::text, count('stacked')::text] as "stack"
        from
          "assets" as "stacked"
        where
          "stacked"."stackId" = "assets"."stackId"
          and "stacked"."deletedAt" is null
          and "stacked"."visibility" = $1
        group by
          "stacked"."stackId"
      ) as "stacked_assets" on true
    where
      "assets"."deletedAt" is null
      and "assets"."visibility" in ('archive', 'timeline')
      and date_trunc('MONTH', "localDateTime" at time zone 'UTC') at time zone 'UTC' = $2
      and not exists (
        select
        from
          "asset_stack"
        where
          "asset_stack"."id" = "assets"."stackId"
          and "asset_stack"."primaryAssetId" != "assets"."id"
      )
    order by
      "assets"."localDateTime" desc
  ),
  "agg" as (
    select
      coalesce(array_agg("city"), '{}') as "city",
      coalesce(array_agg("country"), '{}') as "country",
      coalesce(array_agg("duration"), '{}') as "duration",
      coalesce(array_agg("id"), '{}') as "id",
      coalesce(array_agg("visibility"), '{}') as "visibility",
      coalesce(array_agg("isFavorite"), '{}') as "isFavorite",
      coalesce(array_agg("isImage"), '{}') as "isImage",
      coalesce(array_agg("isTrashed"), '{}') as "isTrashed",
      coalesce(array_agg("livePhotoVideoId"), '{}') as "livePhotoVideoId",
      coalesce(array_agg("localDateTime"), '{}') as "localDateTime",
      coalesce(array_agg("ownerId"), '{}') as "ownerId",
      coalesce(array_agg("projectionType"), '{}') as "projectionType",
      coalesce(array_agg("ratio"), '{}') as "ratio",
      coalesce(array_agg("status"), '{}') as "status",
      coalesce(array_agg("thumbhash"), '{}') as "thumbhash",
      coalesce(json_agg("stack"), '[]') as "stack"
    from
      "cte"
  )
select
  to_json(agg)::text as "assets"
from
  "agg"

-- AssetRepository.getDuplicates
with
  "duplicates" as (
    select
      "assets"."duplicateId",
      json_agg(
        "asset"
        order by
          "assets"."localDateTime" asc
      ) as "assets"
    from
      "assets"
      left join lateral (
        select
          "assets".*,
          "exif" as "exifInfo"
        from
          "exif"
        where
          "exif"."assetId" = "assets"."id"
      ) as "asset" on true
    where
      "assets"."visibility" in ('archive', 'timeline')
      and "assets"."ownerId" = $1::uuid
      and "assets"."duplicateId" is not null
      and "assets"."deletedAt" is null
      and "assets"."stackId" is null
    group by
      "assets"."duplicateId"
  ),
  "unique" as (
    select
      "duplicateId"
    from
      "duplicates"
    where
      json_array_length("assets") = $2
  ),
  "removed_unique" as (
    update "assets"
    set
      "duplicateId" = $3
    from
      "unique"
    where
      "assets"."duplicateId" = "unique"."duplicateId"
  )
select
  *
from
  "duplicates"
where
  not exists (
    select
    from
      "unique"
    where
      "unique"."duplicateId" = "duplicates"."duplicateId"
  )

-- AssetRepository.getAssetIdByCity
with
  "cities" as (
    select
      "city"
    from
      "exif"
    where
      "city" is not null
    group by
      "city"
    having
      count("assetId") >= $1
  )
select distinct
  on ("exif"."city") "assetId" as "data",
  "exif"."city" as "value"
from
  "assets"
  inner join "exif" on "assets"."id" = "exif"."assetId"
  inner join "cities" on "exif"."city" = "cities"."city"
where
  "ownerId" = $2::uuid
  and "visibility" = $3
  and "type" = $4
  and "deletedAt" is null
limit
  $5

-- AssetRepository.getAllForUserFullSync
select
  "assets".*,
  to_json("exif") as "exifInfo",
  to_json("stacked_assets") as "stack"
from
  "assets"
  left join "exif" on "assets"."id" = "exif"."assetId"
  left join "asset_stack" on "asset_stack"."id" = "assets"."stackId"
  left join lateral (
    select
      "asset_stack".*,
      count("stacked") as "assetCount"
    from
      "assets" as "stacked"
    where
      "stacked"."stackId" = "asset_stack"."id"
    group by
      "asset_stack"."id"
  ) as "stacked_assets" on "asset_stack"."id" is not null
where
  "assets"."ownerId" = $1::uuid
  and "assets"."visibility" != $2
  and "assets"."updatedAt" <= $3
  and "assets"."id" > $4
order by
  "assets"."id"
limit
  $5

-- AssetRepository.getChangedDeltaSync
select
  "assets".*,
  to_json("exif") as "exifInfo",
  to_json("stacked_assets") as "stack"
from
  "assets"
  left join "exif" on "assets"."id" = "exif"."assetId"
  left join "asset_stack" on "asset_stack"."id" = "assets"."stackId"
  left join lateral (
    select
      "asset_stack".*,
      count("stacked") as "assetCount"
    from
      "assets" as "stacked"
    where
      "stacked"."stackId" = "asset_stack"."id"
    group by
      "asset_stack"."id"
  ) as "stacked_assets" on "asset_stack"."id" is not null
where
  "assets"."ownerId" = any ($1::uuid[])
  and "assets"."visibility" != $2
  and "assets"."updatedAt" > $3
limit
  $4

-- AssetRepository.detectOfflineExternalAssets
update "assets"
set
  "isOffline" = $1,
  "deletedAt" = $2
where
  "isOffline" = $3
  and "isExternal" = $4
  and "libraryId" = $5::uuid
  and (
    not "originalPath" like $6
    or "originalPath" like $7
  )

-- AssetRepository.filterNewExternalAssetPaths
select
  "path"
from
  unnest(array[$1]::text[]) as "path"
where
  not exists (
    select
      "originalPath"
    from
      "assets"
    where
      "assets"."originalPath" = "path"
      and "libraryId" = $2::uuid
      and "isExternal" = $3
  )
