v 3.1 (#42)
- Use PostgreSQL document library - Remove `isLegacy` property from profiles and listings - Update Docker image parameters (v 3.1 is deployed as a container) - Update dependencies
This commit was merged in pull request #42.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
module JobsJobsJobs.Profiles.Data
|
||||
|
||||
open BitBadger.Npgsql.FSharp.Documents
|
||||
open JobsJobsJobs.Common.Data
|
||||
open JobsJobsJobs.Domain
|
||||
open JobsJobsJobs.Profiles.Domain
|
||||
@@ -7,83 +8,63 @@ open Npgsql.FSharp
|
||||
|
||||
/// Count the current profiles
|
||||
let count () =
|
||||
dataSource ()
|
||||
|> Sql.query
|
||||
$"""SELECT COUNT(id) AS the_count FROM {Table.Profile} WHERE data @> '{{ "isLegacy": false }}'::jsonb"""
|
||||
|> Sql.executeRowAsync (fun row -> row.int64 "the_count")
|
||||
Count.all Table.Profile
|
||||
|
||||
/// Delete a profile by its ID
|
||||
let deleteById citizenId = backgroundTask {
|
||||
let! _ =
|
||||
dataSource ()
|
||||
|> Sql.query $"DELETE FROM {Table.Profile} WHERE id = @id"
|
||||
|> Sql.parameters [ "@id", Sql.string (CitizenId.toString citizenId) ]
|
||||
|> Sql.executeNonQueryAsync
|
||||
()
|
||||
}
|
||||
let deleteById citizenId =
|
||||
Delete.byId Table.Profile (CitizenId.toString citizenId)
|
||||
|
||||
/// Find a profile by citizen ID
|
||||
let findById citizenId = backgroundTask {
|
||||
match! dataSource () |> getDocument<Profile> Table.Profile (CitizenId.toString citizenId) with
|
||||
| Some profile when not profile.IsLegacy -> return Some profile
|
||||
| Some _
|
||||
| None -> return None
|
||||
}
|
||||
let findById citizenId =
|
||||
Find.byId<Profile> Table.Profile (CitizenId.toString citizenId)
|
||||
|
||||
/// Convert a data row to a profile for viewing
|
||||
let private toProfileForView row =
|
||||
{ Profile = toDocument<Profile> row
|
||||
Citizen = toDocumentFrom<Citizen> "cit_data" row
|
||||
Continent = toDocumentFrom<Continent> "cont_data" row
|
||||
{ Profile = fromData<Profile> row
|
||||
Citizen = fromDocument<Citizen> "cit_data" row
|
||||
Continent = fromDocument<Continent> "cont_data" row
|
||||
}
|
||||
|
||||
/// Find a profile by citizen ID for viewing (includes citizen and continent information)
|
||||
let findByIdForView citizenId = backgroundTask {
|
||||
let! tryCitizen =
|
||||
dataSource ()
|
||||
|> Sql.query $"""
|
||||
SELECT p.*, c.data AS cit_data, o.data AS cont_data
|
||||
FROM {Table.Profile} p
|
||||
INNER JOIN {Table.Citizen} c ON c.id = p.id
|
||||
INNER JOIN {Table.Continent} o ON o.id = p.data ->> 'continentId'
|
||||
WHERE p.id = @id
|
||||
AND p.data @> '{{ "isLegacy": false }}'::jsonb"""
|
||||
|> Sql.parameters [ "@id", Sql.string (CitizenId.toString citizenId) ]
|
||||
|> Sql.executeAsync toProfileForView
|
||||
return List.tryHead tryCitizen
|
||||
}
|
||||
let findByIdForView citizenId =
|
||||
Custom.single<ProfileForView>
|
||||
$"SELECT p.*, c.data AS cit_data, o.data AS cont_data
|
||||
FROM {Table.Profile} p
|
||||
INNER JOIN {Table.Citizen} c ON c.id = p.id
|
||||
INNER JOIN {Table.Continent} o ON o.id = p.data ->> 'continentId'
|
||||
WHERE p.id = @id"
|
||||
[ "@id", Sql.string (CitizenId.toString citizenId) ]
|
||||
toProfileForView
|
||||
|
||||
/// Save a profile
|
||||
let save (profile : Profile) =
|
||||
dataSource () |> saveDocument Table.Profile (CitizenId.toString profile.Id) <| mkDoc profile
|
||||
save Table.Profile (CitizenId.toString profile.Id) profile
|
||||
|
||||
/// Search profiles
|
||||
let search (search : ProfileSearchForm) isPublic = backgroundTask {
|
||||
let searches = [
|
||||
if search.ContinentId <> "" then
|
||||
"p.data @> @continent", [ "@continent", Sql.jsonb (mkDoc {| continentId = search.ContinentId |}) ]
|
||||
"p.data @> @continent", [ "@continent", Query.jsonbDocParam {| continentId = search.ContinentId |} ]
|
||||
if search.RemoteWork <> "" then
|
||||
"p.data @> @remote", [ "@remote", Sql.jsonb (mkDoc {| isRemote = search.RemoteWork = "yes" |}) ]
|
||||
"p.data @> @remote", [ "@remote", Query.jsonbDocParam {| isRemote = search.RemoteWork = "yes" |} ]
|
||||
if search.Text <> "" then
|
||||
"p.text_search @@ plainto_tsquery(@text_search)", [ "@text_search", Sql.string search.Text ]
|
||||
]
|
||||
let vizSql =
|
||||
if isPublic then
|
||||
sprintf "(p.data @> '%s'::jsonb OR p.data @> '%s'::jsonb)"
|
||||
(mkDoc {| visibility = ProfileVisibility.toString Public |})
|
||||
(mkDoc {| visibility = ProfileVisibility.toString Anonymous |})
|
||||
(Configuration.serializer().Serialize {| visibility = ProfileVisibility.toString Public |})
|
||||
(Configuration.serializer().Serialize {| visibility = ProfileVisibility.toString Anonymous |})
|
||||
else sprintf "p.data ->> 'visibility' <> '%s'" (ProfileVisibility.toString Hidden)
|
||||
let! results =
|
||||
dataSource ()
|
||||
|> Sql.query $"""
|
||||
SELECT p.*, c.data AS cit_data, o.data AS cont_data
|
||||
FROM {Table.Profile} p
|
||||
INNER JOIN {Table.Citizen} c ON c.id = p.id
|
||||
INNER JOIN {Table.Continent} o ON o.id = p.data ->> 'continentId'
|
||||
WHERE p.data @> '{{ "isLegacy": false }}'::jsonb
|
||||
AND {vizSql}
|
||||
{searchSql searches}"""
|
||||
|> Sql.parameters (searches |> List.collect snd)
|
||||
|> Sql.executeAsync toProfileForView
|
||||
Custom.list<ProfileForView>
|
||||
$" SELECT p.*, c.data AS cit_data, o.data AS cont_data
|
||||
FROM {Table.Profile} p
|
||||
INNER JOIN {Table.Citizen} c ON c.id = p.id
|
||||
INNER JOIN {Table.Continent} o ON o.id = p.data ->> 'continentId'
|
||||
WHERE {vizSql}
|
||||
{searchSql searches}"
|
||||
(searches |> List.collect snd)
|
||||
toProfileForView
|
||||
return results |> List.sortBy (fun pfv -> (Citizen.name pfv.Citizen).ToLowerInvariant ())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user