2016-07-09 04:18:44 +00:00
|
|
|
module myWebLog.Data.Post
|
|
|
|
|
2016-07-10 04:21:23 +00:00
|
|
|
open FSharp.Interop.Dynamic
|
2016-07-09 04:18:44 +00:00
|
|
|
open myWebLog.Entities
|
|
|
|
open Rethink
|
2016-07-10 04:21:23 +00:00
|
|
|
open RethinkDb.Driver.Ast
|
|
|
|
open System.Dynamic
|
2016-07-09 04:18:44 +00:00
|
|
|
|
2016-07-20 03:44:39 +00:00
|
|
|
let private r = RethinkDb.Driver.RethinkDB.R
|
2016-07-09 04:18:44 +00:00
|
|
|
|
2016-07-13 03:26:00 +00:00
|
|
|
/// Shorthand to select all published posts for a web log
|
2016-07-20 03:44:39 +00:00
|
|
|
let private publishedPosts (webLogId : string)=
|
|
|
|
r.Table(Table.Post)
|
|
|
|
.GetAll(r.Array(webLogId, PostStatus.Published)).OptArg("index", "webLogAndStatus")
|
2016-07-13 03:26:00 +00:00
|
|
|
|
|
|
|
/// Shorthand to sort posts by published date, slice for the given page, and return a list
|
2016-07-20 03:44:39 +00:00
|
|
|
let private toPostList conn pageNbr nbrPerPage (filter : ReqlExpr) =
|
2016-07-13 03:26:00 +00:00
|
|
|
filter
|
2016-07-20 03:44:39 +00:00
|
|
|
.OrderBy(r.Desc("publishedOn"))
|
|
|
|
.Slice((pageNbr - 1) * nbrPerPage, pageNbr * nbrPerPage)
|
|
|
|
.RunListAsync<Post>(conn)
|
|
|
|
|> await
|
2016-07-09 04:18:44 +00:00
|
|
|
|> Seq.toList
|
|
|
|
|
2016-07-13 03:26:00 +00:00
|
|
|
/// Shorthand to get a newer or older post
|
2016-07-20 03:44:39 +00:00
|
|
|
// TODO: older posts need to sort by published on DESC
|
|
|
|
//let private adjacentPost conn post (theFilter : ReqlExpr -> ReqlExpr) (sort :ReqlExpr) : Post option =
|
2016-07-23 18:44:49 +00:00
|
|
|
let private adjacentPost conn post (theFilter : ReqlExpr -> obj) (sort : obj) : Post option =
|
2016-07-20 03:44:39 +00:00
|
|
|
(publishedPosts post.webLogId)
|
|
|
|
.Filter(theFilter)
|
|
|
|
.OrderBy(sort)
|
|
|
|
.Limit(1)
|
|
|
|
.RunListAsync<Post>(conn)
|
|
|
|
|> await
|
2016-07-09 04:18:44 +00:00
|
|
|
|> Seq.tryHead
|
2016-07-13 03:26:00 +00:00
|
|
|
|
2016-07-20 03:44:39 +00:00
|
|
|
/// Find a newer post
|
|
|
|
let private newerPost conn post theFilter = adjacentPost conn post theFilter <| r.Asc "publishedOn"
|
|
|
|
|
|
|
|
/// Find an older post
|
|
|
|
let private olderPost conn post theFilter = adjacentPost conn post theFilter <| r.Desc "publishedOn"
|
|
|
|
|
2016-07-13 03:26:00 +00:00
|
|
|
/// Get a page of published posts
|
|
|
|
let findPageOfPublishedPosts conn webLogId pageNbr nbrPerPage =
|
|
|
|
publishedPosts webLogId
|
|
|
|
|> toPostList conn pageNbr nbrPerPage
|
|
|
|
|
|
|
|
/// Get a page of published posts assigned to a given category
|
|
|
|
let findPageOfCategorizedPosts conn webLogId (categoryId : string) pageNbr nbrPerPage =
|
2016-07-20 03:44:39 +00:00
|
|
|
(publishedPosts webLogId)
|
2016-07-26 00:54:45 +00:00
|
|
|
.Filter(ReqlFunction1(fun p -> upcast p.["categoryIds"].Contains(categoryId)))
|
2016-07-13 03:26:00 +00:00
|
|
|
|> toPostList conn pageNbr nbrPerPage
|
|
|
|
|
|
|
|
/// Get a page of published posts tagged with a given tag
|
|
|
|
let findPageOfTaggedPosts conn webLogId (tag : string) pageNbr nbrPerPage =
|
2016-07-20 03:44:39 +00:00
|
|
|
(publishedPosts webLogId)
|
2016-07-26 00:54:45 +00:00
|
|
|
.Filter(ReqlFunction1(fun p -> upcast p.["tags"].Contains(tag)))
|
2016-07-13 03:26:00 +00:00
|
|
|
|> toPostList conn pageNbr nbrPerPage
|
|
|
|
|
|
|
|
/// Try to get the next newest post from the given post
|
2016-07-23 18:44:49 +00:00
|
|
|
let tryFindNewerPost conn post = newerPost conn post (fun p -> upcast p.["publishedOn"].Gt(post.publishedOn))
|
2016-07-13 03:26:00 +00:00
|
|
|
|
|
|
|
/// Try to get the next newest post assigned to the given category
|
|
|
|
let tryFindNewerCategorizedPost conn (categoryId : string) post =
|
2016-07-23 18:44:49 +00:00
|
|
|
newerPost conn post (fun p -> upcast p.["publishedOn"].Gt(post.publishedOn)
|
|
|
|
.And(p.["categoryIds"].Contains(categoryId)))
|
2016-07-13 03:26:00 +00:00
|
|
|
|
|
|
|
/// Try to get the next newest tagged post from the given tagged post
|
|
|
|
let tryFindNewerTaggedPost conn (tag : string) post =
|
2016-07-23 18:44:49 +00:00
|
|
|
newerPost conn post (fun p -> upcast p.["publishedOn"].Gt(post.publishedOn).And(p.["tags"].Contains(tag)))
|
2016-07-09 04:18:44 +00:00
|
|
|
|
|
|
|
/// Try to get the next oldest post from the given post
|
2016-07-23 18:44:49 +00:00
|
|
|
let tryFindOlderPost conn post = olderPost conn post (fun p -> upcast p.["publishedOn"].Lt(post.publishedOn))
|
2016-07-13 03:26:00 +00:00
|
|
|
|
|
|
|
/// Try to get the next oldest post assigned to the given category
|
|
|
|
let tryFindOlderCategorizedPost conn (categoryId : string) post =
|
2016-07-23 18:44:49 +00:00
|
|
|
olderPost conn post (fun p -> upcast p.["publishedOn"].Lt(post.publishedOn)
|
|
|
|
.And(p.["categoryIds"].Contains(categoryId)))
|
2016-07-13 03:26:00 +00:00
|
|
|
|
|
|
|
/// Try to get the next oldest tagged post from the given tagged post
|
|
|
|
let tryFindOlderTaggedPost conn (tag : string) post =
|
2016-07-23 18:44:49 +00:00
|
|
|
olderPost conn post (fun p -> upcast p.["publishedOn"].Lt(post.publishedOn).And(p.["tags"].Contains(tag)))
|
2016-07-09 04:18:44 +00:00
|
|
|
|
|
|
|
/// Get a page of all posts in all statuses
|
2016-07-20 03:44:39 +00:00
|
|
|
let findPageOfAllPosts conn (webLogId : string) pageNbr nbrPerPage =
|
2016-07-23 18:44:49 +00:00
|
|
|
// FIXME: sort unpublished posts by their last updated date
|
2016-07-20 03:44:39 +00:00
|
|
|
r.Table(Table.Post)
|
|
|
|
.GetAll(webLogId).OptArg("index", "webLogId")
|
2016-07-23 18:44:49 +00:00
|
|
|
.OrderBy(r.Desc("publishedOn"))
|
2016-07-20 03:44:39 +00:00
|
|
|
.Slice((pageNbr - 1) * nbrPerPage, pageNbr * nbrPerPage)
|
2016-07-23 18:44:49 +00:00
|
|
|
.RunListAsync<Post>(conn)
|
2016-07-20 03:44:39 +00:00
|
|
|
|> await
|
2016-07-09 04:18:44 +00:00
|
|
|
|> Seq.toList
|
2016-07-10 02:11:50 +00:00
|
|
|
|
|
|
|
/// Try to find a post by its Id and web log Id
|
|
|
|
let tryFindPost conn webLogId postId : Post option =
|
2016-07-20 03:44:39 +00:00
|
|
|
match r.Table(Table.Post)
|
|
|
|
.Get(postId)
|
|
|
|
.Filter(fun p -> p.["webLogId"].Eq(webLogId))
|
|
|
|
.RunAtomAsync<Post>(conn)
|
2016-07-10 02:11:50 +00:00
|
|
|
|> box with
|
|
|
|
| null -> None
|
|
|
|
| post -> Some <| unbox post
|
|
|
|
|
2016-07-10 04:21:23 +00:00
|
|
|
/// Try to find a post by its permalink
|
2016-07-26 00:54:45 +00:00
|
|
|
// TODO: see if we can make .Merge work for page list even though the attribute is ignored
|
|
|
|
// (needs to be ignored for serialization, but included for deserialization)
|
2016-07-10 04:21:23 +00:00
|
|
|
let tryFindPostByPermalink conn webLogId permalink =
|
2016-07-26 00:54:45 +00:00
|
|
|
match r.Table(Table.Post)
|
|
|
|
.GetAll(r.Array(webLogId, permalink)).OptArg("index", "permalink")
|
|
|
|
.Filter(fun p -> p.["status"].Eq(PostStatus.Published))
|
|
|
|
.Without("revisions")
|
|
|
|
.RunCursorAsync<Post>(conn)
|
|
|
|
|> await
|
|
|
|
|> Seq.tryHead with
|
|
|
|
| Some p -> Some { p with categories = r.Table(Table.Category)
|
|
|
|
.GetAll(p.categoryIds |> List.toArray)
|
|
|
|
.Without("children")
|
|
|
|
.OrderBy("name")
|
|
|
|
.RunListAsync<Category>(conn)
|
|
|
|
|> await
|
|
|
|
|> Seq.toList
|
|
|
|
comments = r.Table(Table.Comment)
|
|
|
|
.GetAll(p.id).OptArg("index", "postId")
|
|
|
|
.OrderBy("postedOn")
|
|
|
|
.RunListAsync<Comment>(conn)
|
|
|
|
|> await
|
|
|
|
|> Seq.toList }
|
|
|
|
| None -> None
|
2016-07-10 04:21:23 +00:00
|
|
|
|
|
|
|
/// Try to find a post by its prior permalink
|
2016-07-20 03:44:39 +00:00
|
|
|
let tryFindPostByPriorPermalink conn (webLogId : string) (permalink : string) =
|
|
|
|
r.Table(Table.Post)
|
|
|
|
.GetAll(webLogId).OptArg("index", "webLogId")
|
|
|
|
.Filter(fun p -> p.["priorPermalinks"].Contains(permalink).And(p.["status"].Eq(PostStatus.Published)))
|
|
|
|
.Without("revisions")
|
|
|
|
.RunCursorAsync<Post>(conn)
|
|
|
|
|> await
|
2016-07-10 04:21:23 +00:00
|
|
|
|> Seq.tryHead
|
|
|
|
|
2016-07-10 02:11:50 +00:00
|
|
|
/// Save a post
|
|
|
|
let savePost conn post =
|
|
|
|
match post.id with
|
|
|
|
| "new" -> let newPost = { post with id = string <| System.Guid.NewGuid() }
|
2016-07-20 03:44:39 +00:00
|
|
|
r.Table(Table.Post)
|
|
|
|
.Insert(newPost)
|
|
|
|
.RunResultAsync(conn)
|
2016-07-10 02:11:50 +00:00
|
|
|
|> ignore
|
|
|
|
newPost.id
|
2016-07-20 03:44:39 +00:00
|
|
|
| _ -> r.Table(Table.Post)
|
|
|
|
.Get(post.id)
|
|
|
|
.Replace(post)
|
|
|
|
.RunResultAsync(conn)
|
2016-07-10 02:11:50 +00:00
|
|
|
|> ignore
|
|
|
|
post.id
|