Skip to content

Instantly share code, notes, and snippets.

@ToJans
Last active December 18, 2015 09:49
Show Gist options
  • Save ToJans/5764367 to your computer and use it in GitHub Desktop.
Save ToJans/5764367 to your computer and use it in GitHub Desktop.
A simple blogging routine in Elixir
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
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