Last active
December 18, 2015 09:49
-
-
Save ToJans/5764367 to your computer and use it in GitHub Desktop.
A simple blogging routine in Elixir
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
store=Posts.MemStore.start | |
store |> Posts.createPost("Another one bites the dust") | |
newPost = store |> Posts.Query.items |> Posts.OrderBy.recentlyCreated |> Enum.first | |
# now it works!!! | |
store |> Posts.publishPost(newPost.id) | |
recentPosts = store |> Posts.Query.items |> Posts.Filter.published |> Posts.OrderBy.recentlyPublished | |
output = recentPosts |> Posts.Filter.page(1) |> Posts.Format.text | |
IO.puts output |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Posts do | |
defrecord Post, id: nil, title: nil, body: nil, createdOn: nil, publishedOn: nil | |
def createPost(pid,title), do: pid <- {:create,title} | |
def updateContent(pid,id,content), do: pid <- {:update,id,content} | |
def deletePost(pid,id), do: pid <- {:delete,id } | |
def publishPost(pid,id,onDate // :calendar.local_time), do: pid <- {:update,id,[publishedOn: onDate] } | |
defmodule MemStore do | |
def start(posts // examplePosts), do: Process.spawn_link(fn ->loop(posts) end) | |
def stop(pid), do: Process.exit(pid,:kill) | |
defp loop(items) do | |
receive do | |
{:create,title} -> create(title,items) | |
{:update,id,content} -> update(id,content,items) | |
{:delete,id} -> delete(id,items) | |
{:get,pid} -> pid <- {:ok,items } | |
items | |
end | |
|> loop | |
end | |
defp create(title,items) do | |
maxid = items | |
|> Enum.map(fn x-> x.id end) | |
|> Enum.max | |
createdOn = :calendar.local_time | |
item = Post.new id: maxid+1, title: title, createdOn: createdOn | |
[item|items] | |
end | |
defp update(id,content,items) do | |
post = Enum.filter(items, fn x-> x.id == id end) |> Enum.first | |
updateFields( post,content,items) | |
end | |
defp updateFields(post, [{:title,title}|tail],items) do | |
post = post.title(title) | |
updateFields(post,tail,items) | |
end | |
defp updateFields(post, [{:body,body}|tail],items) do | |
post = post.body(body) | |
updateFields(post,tail,items) | |
end | |
defp updateFields(post, [{:publishedOn,publishedOn}|tail],items) do | |
post = post.publishedOn(publishedOn) | |
updateFields(post,tail,items) | |
end | |
defp updateFields(post,[],items) do | |
[post|delete(items,post.id)] | |
end | |
defp delete(items,id) do | |
Enum.filter(items,fn x-> x.id !== id end) | |
end | |
defp examplePosts(n // 22) do | |
addExample([],n) | |
end | |
defp addExample(elements,0) do | |
elements | |
end | |
defp addExample(elements,n) do | |
post = Post.new(id: n,title: "Blog post #{n}") | |
.createdOn({{2013,03,n},{0,0,0}}) | |
.publishedOn({{2013,03,n+2},{0,0,0}}) | |
addExample([post|elements],n-1) | |
end | |
end | |
defmodule Query do | |
def item(source,id) do | |
items(source) |> Enum.find(fn x -> x.id == id end) | |
end | |
def items(source) do | |
source <- {:get,self} | |
receive do | |
{:ok,items} -> items | |
after 100 -> | |
{:timeout} | |
end | |
end | |
end | |
defmodule Filter do | |
def page(posts,pageNumber // 1, itemsPerPage // 10) do | |
posts | |
|> Enum.drop((pageNumber-1)*itemsPerPage) | |
|> Enum.take(itemsPerPage) | |
end | |
def published(posts) do | |
posts |> Enum.filter(fn x-> x.publishedOn !== nil end) | |
end | |
def unpublished(posts) do | |
posts |> Enum.filter(fn x-> x.publishedOn == nil end) | |
end | |
end | |
defmodule Format do | |
def text(posts) do | |
posts | |
|> Enum.map(fn x -> | |
""" | |
#{x.id} - #{x.title} | |
===== | |
Created on: #{datefmt(x.createdOn)} ||| Published on: #{datefmt(x.publishedOn)} | |
#{x.body} | |
----- | |
""" | |
end) | |
end | |
def datefmt({{y,m,d},{_hh,_mm,_ss}}) do | |
"#{y}/#{m}/#{d}" | |
end | |
end | |
defmodule OrderBy do | |
def recentlyCreated(posts) do | |
posts |> Enum.sort(fn x,y->x.createdOn > y.createdOn end) | |
end | |
def recentlyPublished(posts) do | |
posts |> Enum.sort(fn x,y -> x.publishedOn > y.publishedOn end) | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment