aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/guff/handlers.cr20
-rw-r--r--src/guff/models/blog.cr111
-rw-r--r--src/guff/paged-result-set.cr2
-rw-r--r--src/guff/views/blog/list-item.cr2
-rw-r--r--src/guff/views/blog/list.cr6
-rw-r--r--src/guff/views/blog/post.cr7
-rw-r--r--src/views/blog/list-item.ecr7
-rw-r--r--src/views/blog/post.ecr30
8 files changed, 140 insertions, 45 deletions
diff --git a/src/guff/handlers.cr b/src/guff/handlers.cr
index 8b5d96c..8690095 100644
--- a/src/guff/handlers.cr
+++ b/src/guff/handlers.cr
@@ -446,31 +446,35 @@ module Guff::Handlers
$}x
def call(context : HTTP::Server::Context)
- if id = get_id(context.request)
+ if r = get(context.request)
# TODO: render page
context.response.headers["x-frame-options"] = "SAMEORIGIN"
context.response.content_type = "text/html; charset=utf-8"
context.response.status_code = 200
- context.response << "blog post id: #{id}"
+ Views::Blog::PostView.new(@context, r).to_s(context.response)
else
# unknown page
call_next(context)
end
end
- private def get_id(request : HTTP::Request) : Int64?
+ private def get(request : HTTP::Request) : Hash(String, String)?
r = nil
if request.method == "GET"
if md = PATH_RE.match(request.path.not_nil!)
if site_id = get_site_id(request.headers["host"]?)
- r = @context.models.blog.get_id(
+ results = @context.models.blog.find(
site_id: site_id,
year: md["year"].to_i,
month: md["month"].to_i,
day: md["day"].to_i,
slug: md["slug"],
)
+
+ if results.num_rows > 0
+ r = results.rows.first
+ end
end
end
end
@@ -494,20 +498,20 @@ module Guff::Handlers
$}x
def call(context : HTTP::Server::Context)
- if ids = get_ids(context.request)
+ if r = find(context.request)
# TODO: render page
context.response.headers["x-frame-options"] = "SAMEORIGIN"
context.response.content_type = "text/html; charset=utf-8"
context.response.status_code = 200
- Views::Blog::ListView.new(@context, ids).to_s(context.response)
+ Views::Blog::ListView.new(@context, r).to_s(context.response)
else
# unknown page
call_next(context)
end
end
- private def get_ids(request : HTTP::Request) : Array(Int64)?
+ private def find(request : HTTP::Request) : PagedResultSet?
r = nil
if request.method == "GET"
@@ -516,7 +520,7 @@ module Guff::Handlers
# get request parameters
params = request.query_params
- r = @context.models.blog.get_ids(
+ r = @context.models.blog.find(
site_id: site_id,
year: md["year"]? ? md["year"].to_i : nil,
month: md["month"]? ? md["month"].to_i : nil,
diff --git a/src/guff/models/blog.cr b/src/guff/models/blog.cr
index 9c25b77..ed5bddc 100644
--- a/src/guff/models/blog.cr
+++ b/src/guff/models/blog.cr
@@ -2,8 +2,8 @@ require "./model"
class Guff::Models::BlogModel < Guff::Models::Model
SQL = {
- get_ids: "
- SELECT b.post_id
+ count: "
+ SELECT COUNT(*)
FROM sites a
JOIN posts b
@@ -12,21 +12,50 @@ class Guff::Models::BlogModel < Guff::Models::Model
ON (c.post_id = b.post_id)
JOIN states d
ON (d.state_id = b.state_id)
+ JOIN users e
+ ON (e.user_id = b.created_by)
WHERE a.site_id = ?
+ AND d.state = 'public'
+ AND (0 + strftime('%%s'))
+ BETWEEN (0 + strftime('%%s', COALESCE(b.posted_at, 'now')))
+ AND (0 + strftime('%%s', COALESCE(b.expires_at,'now')))
AND %s
+ ",
+
+ find: "
+ SELECT b.post_id,
+ b.site_id,
+ b.posted_at,
+ datetime(b.posted_at, 'localtime') AS posted_at_text,
+ b.slug,
+ b.name,
+ b.body,
+ e.user_id,
+ e.name AS user_name
+
+ FROM sites a
+ JOIN posts b
+ ON (b.site_id = a.site_id)
+ JOIN blogs c
+ ON (c.post_id = b.post_id)
+ JOIN states d
+ ON (d.state_id = b.state_id)
+ JOIN users e
+ ON (e.user_id = b.created_by)
+
+ WHERE a.site_id = ?
AND d.state = 'public'
- -- TODO: handle posted_at and expired_at
+ AND (0 + strftime('%%s'))
+ BETWEEN (0 + strftime('%%s', COALESCE(b.posted_at, 'now')))
+ AND (0 + strftime('%%s', COALESCE(b.expires_at,'now')))
+ AND %s
ORDER BY COALESCE(b.posted_at, b.created_at) DESC
LIMIT ? OFFSET ?
",
- add: "
- INSERT INTO blogs(post_id) VALUES (?)
- ",
-
get: "
SELECT a.post_id,
a.site_id,
@@ -46,35 +75,36 @@ class Guff::Models::BlogModel < Guff::Models::Model
WHERE a.post_id = ?
",
- }
- def get_id(
- site_id : Int64,
- year : Int32,
- month : Int32,
- day : Int32,
- slug : String
- ) : Int64?
- ids = get_ids(site_id, year, month, day, slug)
- (ids.size > 0) ? ids.first : nil
- end
+
+ add: "
+ INSERT INTO blogs(post_id) VALUES (?)
+ ",
+ }
# TODO: make this configurable
LIMIT = 50
- def get_ids(
+ def find(
site_id : Int64,
+ post_id : Int32? = nil,
year : Int32? = nil,
month : Int32? = nil,
day : Int32? = nil,
slug : String? = nil,
page : Int32? = nil
- ) : Array(Int64)
+ ) : PagedResultSet
sql = ["1"]
args = [site_id.to_s]
# STDERR.puts "DEBUG: site_id = #{site_id}, year = #{year}, month = #{month}, day = #{day}, slug = \"#{slug}\""
+ if post_id
+ # add post_id filter
+ sql << "b.post_id = ?"
+ args << post_id.to_s
+ end
+
if year
# add year filter
sql << "strftime('%Y', b.posted_at) + 0 = ? + 0"
@@ -99,25 +129,46 @@ class Guff::Models::BlogModel < Guff::Models::Model
args << slug
end
+ # get page
page ||= 1
raise "invalid page: #{page}" if page < 1
+ # STDERR.puts "DEBUG: args = #{args.to_json}"
+
+ num_rows = @context.dbs.ro.one(SQL[:count] % [
+ sql.join(" AND ")
+ ], args).not_nil!.to_i64
+
+ # add limit and offset to args
args << LIMIT.to_s
args << ((page - 1) * LIMIT).to_s
- # STDERR.puts "DEBUG: args = #{args.to_json}"
-
- # exec query, build result
- r = [] of Int64
- @context.dbs.ro.all(SQL[:get_ids] % sql.join(" AND "), args) do |row|
- p row
- r << row["post_id"] as Int64
+ # get rows
+ rows = [] of Hash(String, String)
+ @context.dbs.ro.all(SQL[:find] % [
+ sql.join(" AND ")
+ ], args) do |row|
+ # p row
+ rows << row.reduce({} of String => String) do |r, kv|
+ r[kv[0]] = kv[1].to_s
+ r
+ end
end
# return results
- r
+ PagedResultSet.new(
+ page: page,
+ num_rows: num_rows,
+ limit: LIMIT,
+ rows: rows,
+ )
+ end
+
+ def get(post_id : Int64)
+ @context.dbs.ro.row(SQL[:get], [post_id.to_s]).not_nil!
end
+
def add(
site_id : Int64,
user_id : Int64,
@@ -172,8 +223,4 @@ class Guff::Models::BlogModel < Guff::Models::Model
body: body,
)
end
-
- def get(post_id : Int64)
- @context.dbs.ro.row(SQL[:get], [post_id.to_s]).not_nil!
- end
end
diff --git a/src/guff/paged-result-set.cr b/src/guff/paged-result-set.cr
index 2db3619..2798eb9 100644
--- a/src/guff/paged-result-set.cr
+++ b/src/guff/paged-result-set.cr
@@ -1,6 +1,8 @@
require "json"
class Guff::PagedResultSet
+ getter :page, :num_rows, :limit, :rows
+
def initialize(
@page : Int32,
@num_rows : Int64,
diff --git a/src/guff/views/blog/list-item.cr b/src/guff/views/blog/list-item.cr
index 3ebe411..12add51 100644
--- a/src/guff/views/blog/list-item.cr
+++ b/src/guff/views/blog/list-item.cr
@@ -1,5 +1,5 @@
class Guff::Views::Blog::ListItemView < Guff::Views::HTMLView
- def initialize(context : Context, @post_id : Int64)
+ def initialize(context : Context, @item : Hash(String, String))
super(context)
end
diff --git a/src/guff/views/blog/list.cr b/src/guff/views/blog/list.cr
index 31437a6..0b26f98 100644
--- a/src/guff/views/blog/list.cr
+++ b/src/guff/views/blog/list.cr
@@ -4,14 +4,14 @@
class Guff::Views::Blog::ListView < Guff::Views::HTMLView
TITLE = "Blog List"
- def initialize(context : Context, @post_ids : Array(Int64))
+ def initialize(context : Context, @results : PagedResultSet)
super(context)
end
def posts
String.build do |io|
- @post_ids.each do |id|
- ListItemView.new(@context, id).to_s(io)
+ @results.rows.each do |row|
+ ListItemView.new(@context, row).to_s(io)
end
end
end
diff --git a/src/guff/views/blog/post.cr b/src/guff/views/blog/post.cr
new file mode 100644
index 0000000..4b1dc1e
--- /dev/null
+++ b/src/guff/views/blog/post.cr
@@ -0,0 +1,7 @@
+class Guff::Views::Blog::PostView < Guff::Views::HTMLView
+ def initialize(context : Context, @item : Hash(String, String))
+ super(context)
+ end
+
+ ECR.def_to_s("src/views/blog/post.ecr")
+end
diff --git a/src/views/blog/list-item.ecr b/src/views/blog/list-item.ecr
index 13131e0..23b868e 100644
--- a/src/views/blog/list-item.ecr
+++ b/src/views/blog/list-item.ecr
@@ -1,3 +1,8 @@
<div class='post'>
- id: <%= @post_id %>
+ <b><%= h(@item["name"]) %></b><br/>
+ <b>
+ by <%= h(@item["user_name"]) %>
+ on <%= h(@item["posted_at_text"]) %>
+ </b><br/><br/>
+ <%= @item["body"] %>
</div>
diff --git a/src/views/blog/post.ecr b/src/views/blog/post.ecr
new file mode 100644
index 0000000..d0aa534
--- /dev/null
+++ b/src/views/blog/post.ecr
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html lang='en-US'>
+ <head>
+ <meta charset="utf-8"/>
+ <title><%=
+ h(@item["name"])
+ %></title>
+
+ <%
+ # TODO: add theme styles
+ %>
+ </head>
+
+ <body>
+ <b>blog post</b>
+
+ <div class='post'>
+ <b><%= h(@item["name"]) %></b><br/>
+ <b>
+ by <%= h(@item["user_name"]) %>
+ on <%= h(@item["posted_at_text"]) %>
+ </b><br/><br/>
+ <%= @item["body"] %>
+ </div>
+ </body>
+
+ <%
+ # TODO: add theme scripts
+ %>
+</html>