Import posts in dev-shell target
This commit is contained in:
parent
e41ff2b897
commit
e24dd6d630
6
Makefile
6
Makefile
@ -15,7 +15,11 @@ test:
|
||||
|
||||
srv.dev-shell:
|
||||
$$(nix-build --no-out-link -A pkgs.bash)/bin/bash srv-dev-env.sh \
|
||||
--command "cd srv/src; return"
|
||||
--command " \
|
||||
cd srv/src; \
|
||||
go run cmd/import-posts/main.go ../../static/src/_posts/*; \
|
||||
return; \
|
||||
"
|
||||
|
||||
srv.shell:
|
||||
nix-shell -A srv.shellWithBuild --arg baseConfig '(import ${CONFIG})' \
|
||||
|
@ -59,7 +59,7 @@ func (a *api) renderIndexHandler() http.Handler {
|
||||
return
|
||||
}
|
||||
|
||||
posts, _, err := a.params.PostStore.Get(page, pageCount)
|
||||
posts, hasMore, err := a.params.PostStore.WithOrderDesc().Get(page, pageCount)
|
||||
if err != nil {
|
||||
apiutil.InternalServerError(
|
||||
rw, r, fmt.Errorf("fetching page %d of posts: %w", page, err),
|
||||
@ -69,8 +69,19 @@ func (a *api) renderIndexHandler() http.Handler {
|
||||
|
||||
tplData := struct {
|
||||
Posts []post.StoredPost
|
||||
PrevPage, NextPage int
|
||||
}{
|
||||
Posts: posts,
|
||||
PrevPage: -1,
|
||||
NextPage: -1,
|
||||
}
|
||||
|
||||
if page > 0 {
|
||||
tplData.PrevPage = page - 1
|
||||
}
|
||||
|
||||
if hasMore {
|
||||
tplData.NextPage = page + 1
|
||||
}
|
||||
|
||||
if err := tpl.Execute(rw, tplData); err != nil {
|
||||
|
@ -17,4 +17,12 @@
|
||||
</ul>
|
||||
{{ end }}
|
||||
|
||||
{{ if ge .PrevPage 0 }}
|
||||
<a href="?p={{ .PrevPage}}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ if ge .NextPage 0 }}
|
||||
<a href="?p={{ .NextPage}}">Next</a>
|
||||
{{ end }}
|
||||
|
||||
{{ template "base.html" . }}
|
||||
|
@ -74,21 +74,33 @@ type Store interface {
|
||||
// ascending, or empty slice.
|
||||
GetByTag(tag string) ([]StoredPost, error)
|
||||
|
||||
// WithOrderDesc will return a Store whose Get operations return Posts in
|
||||
// time descending order, rather than ascending.
|
||||
WithOrderDesc() Store
|
||||
|
||||
// Delete will delete the StoredPost with the given ID.
|
||||
Delete(id string) error
|
||||
}
|
||||
|
||||
type store struct {
|
||||
db *sql.DB
|
||||
order string
|
||||
}
|
||||
|
||||
// NewStore initializes a new Store using an existing SQLDB.
|
||||
func NewStore(db *SQLDB) Store {
|
||||
return &store{
|
||||
db: db.db,
|
||||
order: "ASC",
|
||||
}
|
||||
}
|
||||
|
||||
func (s *store) WithOrderDesc() Store {
|
||||
s2 := *s
|
||||
s2.order = "DESC"
|
||||
return &s2
|
||||
}
|
||||
|
||||
// if the callback returns an error then the transaction is aborted.
|
||||
func (s *store) withTx(cb func(*sql.Tx) error) error {
|
||||
|
||||
@ -185,15 +197,17 @@ func (s *store) get(
|
||||
[]StoredPost, error,
|
||||
) {
|
||||
|
||||
query := `
|
||||
SELECT
|
||||
query := fmt.Sprintf(
|
||||
`SELECT
|
||||
p.id, p.title, p.description, p.series, pt.tag,
|
||||
p.published_at, p.last_updated_at,
|
||||
p.body
|
||||
FROM posts p
|
||||
LEFT JOIN post_tags pt ON (p.id = pt.post_id)
|
||||
` + where + `
|
||||
ORDER BY p.published_at ASC, p.title ASC`
|
||||
`+where+`
|
||||
ORDER BY p.published_at %s, p.title %s`,
|
||||
s.order, s.order,
|
||||
)
|
||||
|
||||
if limit > 0 {
|
||||
query += fmt.Sprintf(" LIMIT %d", limit)
|
||||
|
@ -187,6 +187,47 @@ func TestStore(t *testing.T) {
|
||||
assertPostsEqual(t, posts[4:], gotPosts)
|
||||
})
|
||||
|
||||
t.Run("get_desc", func(t *testing.T) {
|
||||
h := newStoreTestHarness(t)
|
||||
h.store = h.store.WithOrderDesc()
|
||||
|
||||
now := h.clock.Now().UTC()
|
||||
|
||||
posts := []StoredPost{
|
||||
h.testStoredPost(3),
|
||||
h.testStoredPost(2),
|
||||
h.testStoredPost(1),
|
||||
h.testStoredPost(0),
|
||||
}
|
||||
|
||||
for _, post := range posts {
|
||||
assert.NoError(t, h.store.Set(post.Post, now))
|
||||
}
|
||||
|
||||
gotPosts, hasMore, err := h.store.Get(0, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, hasMore)
|
||||
assertPostsEqual(t, posts[:2], gotPosts)
|
||||
|
||||
gotPosts, hasMore, err = h.store.Get(1, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, hasMore)
|
||||
assertPostsEqual(t, posts[2:4], gotPosts)
|
||||
|
||||
posts = append([]StoredPost{h.testStoredPost(4)}, posts...)
|
||||
assert.NoError(t, h.store.Set(posts[0].Post, now))
|
||||
|
||||
gotPosts, hasMore, err = h.store.Get(1, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, hasMore)
|
||||
assertPostsEqual(t, posts[2:4], gotPosts)
|
||||
|
||||
gotPosts, hasMore, err = h.store.Get(2, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, hasMore)
|
||||
assertPostsEqual(t, posts[4:], gotPosts)
|
||||
})
|
||||
|
||||
t.Run("get_by_series", func(t *testing.T) {
|
||||
h := newStoreTestHarness(t)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user