From f4d520e34b20e43ffea1547fadd8e1bfda1ed531 Mon Sep 17 00:00:00 2001 From: "Daniel J. Summers" Date: Sun, 18 Sep 2016 22:20:10 -0500 Subject: [PATCH] DB work Wrapped all Filter and Merge lambdas in a ReqlFunction1 constructor (which made them work); fixed some ReQL logic errors; removed RunListAsync extension and changed calls to RunResultAsync<* list> --- src/MyWebLog.App/ViewModels.fs | 2 +- src/MyWebLog.Data.RethinkDB/Category.fs | 21 +++-- src/MyWebLog.Data.RethinkDB/Extensions.fs | 4 - src/MyWebLog.Data.RethinkDB/Page.fs | 9 +-- src/MyWebLog.Data.RethinkDB/Post.fs | 95 ++++++++++++----------- src/MyWebLog.Data.RethinkDB/SetUp.fs | 22 +++--- src/MyWebLog.Data.RethinkDB/User.fs | 7 +- src/MyWebLog.Data.RethinkDB/WebLog.fs | 21 ++--- src/MyWebLog.Entities/AssemblyInfo.fs | 2 +- src/MyWebLog.Logic/Post.fs | 2 +- 10 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/MyWebLog.App/ViewModels.fs b/src/MyWebLog.App/ViewModels.fs index c5a9120..9486c02 100644 --- a/src/MyWebLog.App/ViewModels.fs +++ b/src/MyWebLog.App/ViewModels.fs @@ -385,7 +385,7 @@ type EditPostForm() = member val PublishNow = true with get, set /// Fill the form with applicable values from a post - member this.ForPost post = + member this.ForPost (post : Post) = this.Title <- post.Title this.Permalink <- post.Permalink this.Tags <- List.reduce (fun acc x -> sprintf "%s, %s" acc x) post.Tags diff --git a/src/MyWebLog.Data.RethinkDB/Category.fs b/src/MyWebLog.Data.RethinkDB/Category.fs index fdd4acd..226922a 100644 --- a/src/MyWebLog.Data.RethinkDB/Category.fs +++ b/src/MyWebLog.Data.RethinkDB/Category.fs @@ -9,23 +9,23 @@ let private r = RethinkDb.Driver.RethinkDB.R let private category (webLogId : string) (catId : string) = r.Table(Table.Category) .Get(catId) - .Filter(fun c -> c.["WebLogId"].Eq(webLogId)) + .Filter(ReqlFunction1(fun c -> upcast c.["WebLogId"].Eq(webLogId))) /// Get all categories for a web log let getAllCategories conn (webLogId : string) = r.Table(Table.Category) .GetAll(webLogId).OptArg("index", "WebLogId") .OrderBy("Name") - .RunListAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.toList /// Get a specific category by its Id let tryFindCategory conn webLogId catId : Category option = - match (category webLogId catId) - .RunAtomAsync(conn) |> await |> box with - | null -> None - | cat -> Some <| unbox cat + (category webLogId catId) + .RunResultAsync(conn) + |> await + |> box + |> function null -> None | cat -> Some <| unbox cat /// Add a category let addCategory conn (cat : Category) = @@ -81,9 +81,8 @@ let deleteCategory conn (cat : Category) = r.Table(Table.Post) .GetAll(cat.WebLogId).OptArg("index", "WebLogId") .Filter(ReqlFunction1(fun p -> upcast p.["CategoryIds"].Contains(cat.Id))) - .RunCursorAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.toList |> List.iter (fun post -> let newCats = { PostCategoriesUpdateRecord.CategoryIds = post.CategoryIds |> List.filter (fun c -> c <> cat.Id) } @@ -101,6 +100,6 @@ let deleteCategory conn (cat : Category) = let tryFindCategoryBySlug conn (webLogId : string) (slug : string) = r.Table(Table.Category) .GetAll(r.Array(webLogId, slug)).OptArg("index", "Slug") - .RunCursorAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.tryHead + |> List.tryHead diff --git a/src/MyWebLog.Data.RethinkDB/Extensions.fs b/src/MyWebLog.Data.RethinkDB/Extensions.fs index 747f212..0582f5d 100644 --- a/src/MyWebLog.Data.RethinkDB/Extensions.fs +++ b/src/MyWebLog.Data.RethinkDB/Extensions.fs @@ -5,7 +5,3 @@ open RethinkDb.Driver.Ast open RethinkDb.Driver.Net let await task = task |> Async.AwaitTask |> Async.RunSynchronously - -type ReqlExpr with - /// Run a SUCCESS_ATOM response that returns multiple values - member this.RunListAsync<'T> (conn : IConnection) = this.RunAtomAsync> conn diff --git a/src/MyWebLog.Data.RethinkDB/Page.fs b/src/MyWebLog.Data.RethinkDB/Page.fs index 3338f34..93874cd 100644 --- a/src/MyWebLog.Data.RethinkDB/Page.fs +++ b/src/MyWebLog.Data.RethinkDB/Page.fs @@ -9,7 +9,7 @@ let private r = RethinkDb.Driver.RethinkDB.R let tryFindPageById conn webLogId (pageId : string) includeRevs = let pg = r.Table(Table.Page) .Get(pageId) - match includeRevs with true -> pg.RunAtomAsync(conn) | _ -> pg.Without("Revisions").RunAtomAsync(conn) + match includeRevs with true -> pg.RunResultAsync(conn) | _ -> pg.Without("Revisions").RunResultAsync(conn) |> await |> box |> function @@ -22,9 +22,9 @@ let tryFindPageByPermalink conn (webLogId : string) (permalink : string) = r.Table(Table.Page) .GetAll(r.Array(webLogId, permalink)).OptArg("index", "Permalink") .Without("Revisions") - .RunCursorAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.tryHead + |> List.tryHead /// Get a list of all pages (excludes page text and revisions) let findAllPages conn (webLogId : string) = @@ -32,9 +32,8 @@ let findAllPages conn (webLogId : string) = .GetAll(webLogId).OptArg("index", "WebLogId") .OrderBy("Title") .Without("Text", "Revisions") - .RunListAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.toList /// Add a page let addPage conn (page : Page) = diff --git a/src/MyWebLog.Data.RethinkDB/Post.fs b/src/MyWebLog.Data.RethinkDB/Post.fs index 6809090..e2c60b2 100644 --- a/src/MyWebLog.Data.RethinkDB/Post.fs +++ b/src/MyWebLog.Data.RethinkDB/Post.fs @@ -15,25 +15,24 @@ let private toPostList conn pageNbr nbrPerPage (filter : ReqlExpr) = filter .OrderBy(r.Desc("PublishedOn")) .Slice((pageNbr - 1) * nbrPerPage, pageNbr * nbrPerPage) - .RunListAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.toList /// Shorthand to get a newer or older post -let private adjacentPost conn post (theFilter : ReqlExpr -> obj) (sort : obj) = +let private adjacentPost conn (post : Post) (theFilter : ReqlExpr -> obj) (sort : obj) = (publishedPosts post.WebLogId) .Filter(theFilter) .OrderBy(sort) .Limit(1) - .RunListAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.tryHead + |> List.tryHead /// Find a newer post -let private newerPost conn post theFilter = adjacentPost conn post theFilter <| r.Asc "publishedOn" +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" +let private olderPost conn post theFilter = adjacentPost conn post theFilter <| r.Desc "PublishedOn" /// Get a page of published posts let findPageOfPublishedPosts conn webLogId pageNbr nbrPerPage = @@ -83,89 +82,94 @@ let findPageOfAllPosts conn (webLogId : string) pageNbr nbrPerPage = .GetAll(webLogId).OptArg("index", "WebLogId") .OrderBy(r.Desc("PublishedOn")) .Slice((pageNbr - 1) * nbrPerPage, pageNbr * nbrPerPage) - .RunListAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.toList /// Try to find a post by its Id and web log Id let tryFindPost conn webLogId postId : Post option = - match r.Table(Table.Post) - .Get(postId) - .Filter(ReqlFunction1(fun p -> upcast p.["WebLogId"].Eq(webLogId))) - .RunAtomAsync(conn) - |> box with - | null -> None - | post -> Some <| unbox post + r.Table(Table.Post) + .Get(postId) + .Filter(ReqlFunction1(fun p -> upcast p.["WebLogId"].Eq(webLogId))) + .RunResultAsync(conn) + |> await + |> box + |> function null -> None | post -> Some <| unbox post /// Try to find a post by its permalink let tryFindPostByPermalink conn webLogId permalink = r.Table(Table.Post) .GetAll(r.Array(webLogId, permalink)).OptArg("index", "Permalink") - .Filter(fun p -> p.["Status"].Eq(PostStatus.Published)) + .Filter(ReqlFunction1(fun p -> upcast p.["Status"].Eq(PostStatus.Published))) .Without("Revisions") - .Merge(fun p -> r.HashMap("Categories", r.Table(Table.Category) - .GetAll(p.["CategoryIds"]) - .Without("Children") - .OrderBy("Name") - .CoerceTo("array"))) - .Merge(fun p -> r.HashMap("Comments", r.Table(Table.Comment) - .GetAll(p.["Id"]).OptArg("index", "PostId") - .OrderBy("PostedOn") - .CoerceTo("array"))) - .RunCursorAsync(conn) + .Merge(ReqlFunction1(fun p -> + upcast r.HashMap("Categories", r.Table(Table.Category) + .GetAll(p.["CategoryIds"]) + .Without("Children") + .OrderBy("Name") + .CoerceTo("array")))) + .Merge(ReqlFunction1(fun p -> + upcast r.HashMap("Comments", r.Table(Table.Comment) + .GetAll(p.["id"]).OptArg("index", "PostId") + .OrderBy("PostedOn") + .CoerceTo("array")))) + .RunResultAsync(conn) |> await - |> Seq.tryHead + |> List.tryHead /// Try to find a post by its prior permalink 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))) + .Filter(ReqlFunction1(fun p -> + upcast p.["PriorPermalinks"].Contains(permalink).And(p.["Status"].Eq(PostStatus.Published)))) .Without("Revisions") - .RunCursorAsync(conn) + .RunResultAsync(conn) |> await - |> Seq.tryHead + |> List.tryHead /// Get a set of posts for RSS let findFeedPosts conn webLogId nbr : (Post * User option) list = (publishedPosts webLogId) - .Merge(fun post -> r.HashMap("Categories", r.Table(Table.Category) - .GetAll(post.["CategoryIds"]) - .OrderBy("Name") - .Pluck("Id", "Name") - .CoerceTo("array"))) + .Merge(ReqlFunction1(fun post -> + upcast r.HashMap("Categories", r.Table(Table.Category) + .GetAll(post.["CategoryIds"]) + .OrderBy("Name") + .Pluck("id", "Name") + .CoerceTo("array")))) |> toPostList conn 1 nbr - |> List.map (fun post -> post, match r.Table(Table.User) - .Get(post.AuthorId) - .RunAtomAsync(conn) - |> await - |> box with - | null -> None - | user -> Some <| unbox user) + |> List.map (fun post -> post, r.Table(Table.User) + .Get(post.AuthorId) + .RunAtomAsync(conn) + |> await + |> box + |> function null -> None | user -> Some <| unbox user) /// Add a post let addPost conn post = r.Table(Table.Post) .Insert(post) .RunResultAsync(conn) + |> await |> ignore /// Update a post -let updatePost conn post = +let updatePost conn (post : Post) = r.Table(Table.Post) .Get(post.Id) .Replace( { post with Categories = [] Comments = [] } ) .RunResultAsync(conn) + |> await |> ignore /// Save a post -let savePost conn post = +let savePost conn (post : Post) = match post.Id with | "new" -> let newPost = { post with Id = string <| System.Guid.NewGuid() } r.Table(Table.Post) .Insert(newPost) .RunResultAsync(conn) + |> await |> ignore newPost.Id | _ -> r.Table(Table.Post) @@ -173,5 +177,6 @@ let savePost conn post = .Replace( { post with Categories = [] Comments = [] } ) .RunResultAsync(conn) + |> await |> ignore post.Id diff --git a/src/MyWebLog.Data.RethinkDB/SetUp.fs b/src/MyWebLog.Data.RethinkDB/SetUp.fs index 244af16..e9296ba 100644 --- a/src/MyWebLog.Data.RethinkDB/SetUp.fs +++ b/src/MyWebLog.Data.RethinkDB/SetUp.fs @@ -11,8 +11,8 @@ let private logStepDone () = Console.Out.WriteLine (" done.") /// Ensure the myWebLog database exists let private checkDatabase (cfg : DataConfig) = logStep "|> Checking database" - let dbs = r.DbList().RunListAsync(cfg.Conn) |> await - match dbs.Contains cfg.Database with + let dbs = r.DbList().RunResultAsync(cfg.Conn) |> await + match List.contains cfg.Database dbs with | true -> () | _ -> logStepStart (sprintf " %s database not found - creating" cfg.Database) r.DbCreate(cfg.Database).RunResultAsync(cfg.Conn) |> await |> ignore @@ -21,14 +21,12 @@ let private checkDatabase (cfg : DataConfig) = /// Ensure all required tables exist let private checkTables cfg = logStep "|> Checking tables" - let tables = r.Db(cfg.Database).TableList().RunListAsync(cfg.Conn) |> await + let tables = r.Db(cfg.Database).TableList().RunResultAsync(cfg.Conn) |> await [ Table.Category; Table.Comment; Table.Page; Table.Post; Table.User; Table.WebLog ] - |> List.map (fun tbl -> match tables.Contains tbl with true -> None | _ -> Some (tbl, r.TableCreate tbl)) - |> List.filter Option.isSome - |> List.map Option.get - |> List.iter (fun (tbl, create) -> logStepStart (sprintf " Creating table %s" tbl) - create.RunResultAsync(cfg.Conn) |> await |> ignore - logStepDone ()) + |> List.filter (fun tbl -> not (List.contains tbl tables)) + |> List.iter (fun tbl -> logStepStart (sprintf " Creating table %s" tbl) + (r.TableCreate tbl).RunResultAsync(cfg.Conn) |> await |> ignore + logStepDone ()) /// Shorthand to get the table let private tbl cfg table = r.Db(cfg.Database).Table(table) @@ -42,15 +40,15 @@ let private createIndex cfg table (index : string * (ReqlExpr -> obj) option) = | None -> (tbl cfg table).IndexCreate(idxName)) .RunResultAsync(cfg.Conn) |> await |> ignore - (tbl cfg table).IndexWait(idxName).RunAtomAsync(cfg.Conn) |> await |> ignore + (tbl cfg table).IndexWait(idxName).RunResultAsync(cfg.Conn) |> await |> ignore logStepDone () /// Ensure that the given indexes exist, and create them if required let private ensureIndexes cfg (indexes : (string * (string * (ReqlExpr -> obj) option) list) list) = let ensureForTable (tblName, idxs) = - let idx = (tbl cfg tblName).IndexList().RunListAsync(cfg.Conn) |> await + let idx = (tbl cfg tblName).IndexList().RunResultAsync(cfg.Conn) |> await idxs - |> List.iter (fun index -> match idx.Contains (fst index) with true -> () | _ -> createIndex cfg tblName index) + |> List.iter (fun index -> match List.contains (fst index) idx with true -> () | _ -> createIndex cfg tblName index) indexes |> List.iter ensureForTable diff --git a/src/MyWebLog.Data.RethinkDB/User.fs b/src/MyWebLog.Data.RethinkDB/User.fs index e4e3330..5d34b58 100644 --- a/src/MyWebLog.Data.RethinkDB/User.fs +++ b/src/MyWebLog.Data.RethinkDB/User.fs @@ -1,6 +1,7 @@ module MyWebLog.Data.RethinkDB.User open MyWebLog.Entities +open RethinkDb.Driver.Ast let private r = RethinkDb.Driver.RethinkDB.R @@ -11,7 +12,7 @@ let private r = RethinkDb.Driver.RethinkDB.R let tryUserLogOn conn (email : string) (passwordHash : string) = r.Table(Table.User) .GetAll(email).OptArg("index", "UserName") - .Filter(fun u -> u.["PasswordHash"].Eq(passwordHash)) - .RunCursorAsync(conn) + .Filter(ReqlFunction1(fun u -> upcast u.["PasswordHash"].Eq(passwordHash))) + .RunResultAsync(conn) |> await - |> Seq.tryHead + |> List.tryHead diff --git a/src/MyWebLog.Data.RethinkDB/WebLog.fs b/src/MyWebLog.Data.RethinkDB/WebLog.fs index 95fbfd8..0fcd7d0 100644 --- a/src/MyWebLog.Data.RethinkDB/WebLog.fs +++ b/src/MyWebLog.Data.RethinkDB/WebLog.fs @@ -9,21 +9,22 @@ let private r = RethinkDb.Driver.RethinkDB.R let tryFindWebLogByUrlBase conn (urlBase : string) = r.Table(Table.WebLog) .GetAll(urlBase).OptArg("index", "UrlBase") - .Merge(fun w -> r.HashMap("PageList", r.Table(Table.Page) - .GetAll(w.["Id"]).OptArg("index", "WebLogId") - .Filter(ReqlFunction1(fun pg -> upcast pg.["ShowInPageList"].Eq(true))) - .OrderBy("Title") - .Pluck("Title", "Permalink") - .CoerceTo("array"))) - .RunCursorAsync(conn) + .Merge(ReqlFunction1(fun w -> + upcast r.HashMap("PageList", r.Table(Table.Page) + .GetAll(w.G("id")).OptArg("index", "WebLogId") + .Filter(ReqlFunction1(fun pg -> upcast pg.["ShowInPageList"].Eq(true))) + .OrderBy("Title") + .Pluck("Title", "Permalink") + .CoerceTo("array")))) + .RunResultAsync(conn) |> await - |> Seq.tryHead - + |> List.tryHead + /// Get counts for the admin dashboard let findDashboardCounts conn (webLogId : string) = r.Expr( r.HashMap("Pages", r.Table(Table.Page ).GetAll(webLogId).OptArg("index", "WebLogId").Count())) .Merge(r.HashMap("Posts", r.Table(Table.Post ).GetAll(webLogId).OptArg("index", "WebLogId").Count())) .Merge(r.HashMap("Categories", r.Table(Table.Category).GetAll(webLogId).OptArg("index", "WebLogId").Count())) - .RunAtomAsync(conn) + .RunResultAsync(conn) |> await \ No newline at end of file diff --git a/src/MyWebLog.Entities/AssemblyInfo.fs b/src/MyWebLog.Entities/AssemblyInfo.fs index e0db21f..1726ea3 100644 --- a/src/MyWebLog.Entities/AssemblyInfo.fs +++ b/src/MyWebLog.Entities/AssemblyInfo.fs @@ -1,4 +1,4 @@ -namespace myWebLog.Data.AssemblyInfo +namespace MyWebLog.Entities.AssemblyInfo open System.Reflection open System.Runtime.CompilerServices diff --git a/src/MyWebLog.Logic/Post.fs b/src/MyWebLog.Logic/Post.fs index 410b819..1918cbf 100644 --- a/src/MyWebLog.Logic/Post.fs +++ b/src/MyWebLog.Logic/Post.fs @@ -51,7 +51,7 @@ let tryFindPostByPriorPermalink (data : IMyWebLogData) webLogId permalink = data let findFeedPosts (data : IMyWebLogData) webLogId nbrOfPosts = data.FeedPosts webLogId nbrOfPosts /// Save a post -let savePost (data : IMyWebLogData) post = +let savePost (data : IMyWebLogData) (post : Post) = match post.Id with | "new" -> let newPost = { post with Id = string <| System.Guid.NewGuid() } data.AddPost newPost