Syntactically valid
No compile errors - but does it work...?
This commit is contained in:
@@ -1,13 +1,14 @@
|
||||
namespace MyPrayerJournal
|
||||
|
||||
open FSharp.Control.Tasks.V2.ContextInsensitive
|
||||
open Microsoft.EntityFrameworkCore
|
||||
open Microsoft.FSharpLu
|
||||
|
||||
open Newtonsoft.Json
|
||||
open Raven.Client.Documents.Indexes
|
||||
open System
|
||||
open System.Collections.Generic
|
||||
open Raven.Client.Documents.Linq
|
||||
open Raven.Client.Documents
|
||||
|
||||
/// JSON converter for request IDs
|
||||
type RequestIdJsonConverter() =
|
||||
@@ -35,12 +36,34 @@ type TicksJsonConverter() =
|
||||
override __.ReadJson(reader: JsonReader, _ : Type, _ : Ticks, _ : bool, _ : JsonSerializer) =
|
||||
(string >> int64 >> Ticks) reader.Value
|
||||
|
||||
/// Index episodes by their series Id
|
||||
/// Index requests by user ID
|
||||
type Requests_ByUserId () as this =
|
||||
inherit AbstractJavaScriptIndexCreationTask ()
|
||||
do
|
||||
this.Maps <- HashSet<string> [ "map('Requests', function (req) { return { userId : req.userId } })" ]
|
||||
|
||||
/// Index requests for a journal view
|
||||
type Requests_AsJournal () as this =
|
||||
inherit AbstractJavaScriptIndexCreationTask ()
|
||||
do
|
||||
this.Maps <- HashSet<string> [
|
||||
"map('Requests', function (req) {
|
||||
var hist = req.history
|
||||
.filter(function (hist) { return hist.text !== null })
|
||||
.sort(function (a, b) { return b - a })
|
||||
return {
|
||||
requestId : req.Id,
|
||||
userId : req.userId,
|
||||
text : hist[0].text,
|
||||
asOf : req.history[req.history.length - 1].asOf,
|
||||
snoozedUntil : req.snoozedUntil,
|
||||
showAfter : req.showAfter,
|
||||
recurType : req.recurType,
|
||||
recurCount : req.recurCount
|
||||
}
|
||||
})"
|
||||
|
||||
]
|
||||
|
||||
/// Extensions on the IAsyncDocumentSession interface to support our data manipulation needs
|
||||
[<AutoOpen>]
|
||||
@@ -55,19 +78,32 @@ module Extensions =
|
||||
let fromIndex (typ : Type) =
|
||||
typ.Name.Replace ("_", "/") |> sprintf "from index '%s'"
|
||||
|
||||
/// Utility method to create patch requests
|
||||
let createPatch<'T> collName itemId (item : 'T) =
|
||||
/// Utility method to create a patch request to push an item on the end of a list
|
||||
let listPush<'T> listName docId (item : 'T) =
|
||||
let r = PatchRequest()
|
||||
r.Script <- sprintf "this.%s.push(args.Item)" collName
|
||||
r.Script <- sprintf "this.%s.push(args.Item)" listName
|
||||
r.Values.["Item"] <- item
|
||||
PatchCommandData (itemId, null, r, null)
|
||||
PatchCommandData (docId, null, r, null)
|
||||
|
||||
/// Utility method to create a patch to update a single field
|
||||
// TODO: think we need to include quotes if it's a string
|
||||
let fieldUpdate<'T> fieldName docId (item : 'T) =
|
||||
let r = PatchRequest()
|
||||
r.Script <- sprintf "this.%s = args.Item" fieldName
|
||||
r.Values.["Item"] <- item
|
||||
PatchCommandData (docId, null, r, null)
|
||||
|
||||
// Extensions for the RavenDB session type
|
||||
type IAsyncDocumentSession with
|
||||
|
||||
/// Add a history entry
|
||||
member this.AddHistory (reqId : RequestId) (hist : History) =
|
||||
createPatch "history" (string reqId) hist
|
||||
listPush "history" (string reqId) hist
|
||||
|> this.Advanced.Defer
|
||||
|
||||
/// Add a note
|
||||
member this.AddNote (reqId : RequestId) (note : Note) =
|
||||
listPush "notes" (string reqId) note
|
||||
|> this.Advanced.Defer
|
||||
|
||||
/// Add a request
|
||||
@@ -78,18 +114,18 @@ module Extensions =
|
||||
// TODO: not right
|
||||
member this.AnsweredRequests (userId : UserId) =
|
||||
sprintf "%s where userId = '%s' and lastStatus = 'Answered' order by asOf as long desc"
|
||||
(fromIndex typeof<Requests_ByUserId>) (string userId)
|
||||
(fromIndex typeof<Requests_AsJournal>) (string userId)
|
||||
|> this.Advanced.AsyncRawQuery<JournalRequest>
|
||||
|
||||
/// Retrieve the user's current journal
|
||||
// TODO: probably not right either
|
||||
member this.JournalByUserId (userId : UserId) =
|
||||
sprintf "%s where userId = '%s' and lastStatus <> 'Answered' order by showAfter as long"
|
||||
(fromIndex typeof<Requests_ByUserId>) (string userId)
|
||||
(fromIndex typeof<Requests_AsJournal>) (string userId)
|
||||
|> this.Advanced.AsyncRawQuery<JournalRequest>
|
||||
|
||||
/// Retrieve a request by its ID and user ID
|
||||
member this.TryRequestById (reqId : RequestId) userId =
|
||||
/// Retrieve a request, including its history and notes, by its ID and user ID
|
||||
member this.TryFullRequestById (reqId : RequestId) userId =
|
||||
task {
|
||||
let! req = this.LoadAsync (string reqId)
|
||||
match Option.fromObject req with
|
||||
@@ -97,37 +133,56 @@ module Extensions =
|
||||
| _ -> return None
|
||||
}
|
||||
|
||||
/// Retrieve a request by its ID and user ID (without notes and history)
|
||||
member this.TryRequestById reqId userId =
|
||||
task {
|
||||
match! this.TryFullRequestById reqId userId with
|
||||
| Some r -> return Some { r with history = []; notes = [] }
|
||||
| _ -> return None
|
||||
}
|
||||
|
||||
/// Retrieve notes for a request by its ID and user ID
|
||||
member this.NotesById reqId userId =
|
||||
task {
|
||||
match! this.TryRequestById reqId userId with
|
||||
| Some _ -> return this.Notes.AsNoTracking().Where(fun n -> n.requestId = reqId) |> List.ofSeq
|
||||
| Some req -> return req.notes
|
||||
| None -> return []
|
||||
}
|
||||
|
||||
/// Retrieve a journal request by its ID and user ID
|
||||
member this.TryJournalById reqId userId =
|
||||
member this.TryJournalById (reqId : RequestId) userId =
|
||||
task {
|
||||
let! req = this.Journal.FirstOrDefaultAsync(fun r -> r.requestId = reqId && r.userId = userId)
|
||||
let! req =
|
||||
this.Query<Request, Requests_AsJournal>()
|
||||
.Where(fun x -> x.Id = (string reqId) && x.userId = userId)
|
||||
.ProjectInto<JournalRequest>()
|
||||
.FirstOrDefaultAsync ()
|
||||
return Option.fromObject req
|
||||
}
|
||||
|
||||
/// Retrieve a request, including its history and notes, by its ID and user ID
|
||||
member this.TryFullRequestById requestId userId =
|
||||
task {
|
||||
match! this.TryJournalById requestId userId with
|
||||
| Some req ->
|
||||
let! fullReq =
|
||||
this.Requests.AsNoTracking()
|
||||
.Include(fun r -> r.history)
|
||||
.Include(fun r -> r.notes)
|
||||
.FirstOrDefaultAsync(fun r -> r.requestId = requestId && r.userId = userId)
|
||||
match Option.fromObject fullReq with
|
||||
| Some _ -> return Some { req with history = List.ofSeq fullReq.history; notes = List.ofSeq fullReq.notes }
|
||||
| None -> return None
|
||||
| None -> return None
|
||||
}
|
||||
|
||||
/// Update the recurrence for a request
|
||||
member this.UpdateRecurrence (reqId : RequestId) (recurType : Recurrence) (recurCount : int16) =
|
||||
let r = PatchRequest()
|
||||
r.Script <- "this.recurType = args.Type; this.recurCount = args.Count"
|
||||
r.Values.["Type"] <- string recurType
|
||||
r.Values.["Count"] <- recurCount
|
||||
PatchCommandData (string reqId, null, r, null) |> this.Advanced.Defer
|
||||
|
||||
/// Update the "show after" timestamp for a request
|
||||
member this.UpdateShowAfter (reqId : RequestId) (showAfter : Ticks) =
|
||||
fieldUpdate "showAfter" (string reqId) (showAfter.toLong ())
|
||||
|> this.Advanced.Defer
|
||||
|
||||
/// Update a snoozed request
|
||||
member this.UpdateSnoozed (reqId : RequestId) (until : Ticks) =
|
||||
let r = PatchRequest()
|
||||
r.Script <- "this.snoozedUntil = args.Item; this.showAfter = args.Item"
|
||||
r.Values.["Item"] <- until.toLong ()
|
||||
PatchCommandData (string reqId, null, r, null) |> this.Advanced.Defer
|
||||
|
||||
|
||||
|
||||
(*
|
||||
/// Entity Framework configuration for myPrayerJournal
|
||||
module internal EFConfig =
|
||||
|
||||
@@ -278,3 +333,4 @@ type AppDbContext (opts : DbContextOptions<AppDbContext>) =
|
||||
| None -> return None
|
||||
| None -> return None
|
||||
}
|
||||
*)
|
||||
Reference in New Issue
Block a user