summaryrefslogtreecommitdiff
path: root/srv/src/post
diff options
context:
space:
mode:
authorBrian Picciano <mediocregopher@gmail.com>2022-05-06 21:49:00 -0600
committerBrian Picciano <mediocregopher@gmail.com>2022-05-06 21:49:00 -0600
commitc99b37c5b37d8944522eb73288581ca99670b660 (patch)
treedafb1ccb650cbab7eca4e127a5ecebd898f65c59 /srv/src/post
parentf7d72adfb594980b0442c0fa7b5586e6248f96ac (diff)
Use unix timestamps for post.Store
Diffstat (limited to 'srv/src/post')
-rw-r--r--srv/src/post/store.go46
-rw-r--r--srv/src/post/store_test.go33
2 files changed, 47 insertions, 32 deletions
diff --git a/srv/src/post/store.go b/srv/src/post/store.go
index 2898315..3f044e2 100644
--- a/srv/src/post/store.go
+++ b/srv/src/post/store.go
@@ -6,10 +6,10 @@ import (
"fmt"
"path"
"strings"
+ "time"
- _ "github.com/mattn/go-sqlite3"
+ _ "github.com/mattn/go-sqlite3" // we need dis
migrate "github.com/rubenv/sql-migrate"
- "github.com/tilinna/clock"
)
var (
@@ -23,8 +23,8 @@ var (
type StoredPost struct {
Post
- PublishedAt Date
- LastUpdatedAt Date
+ PublishedAt time.Time
+ LastUpdatedAt time.Time
}
// URL returns the relative URL of the StoredPost.
@@ -32,9 +32,9 @@ func (p StoredPost) URL() string {
return path.Join(
fmt.Sprintf(
"%d/%0d/%0d",
- p.PublishedAt.Year,
- p.PublishedAt.Month,
- p.PublishedAt.Day,
+ p.PublishedAt.Year(),
+ p.PublishedAt.Month(),
+ p.PublishedAt.Day(),
),
p.ID+".html",
)
@@ -45,7 +45,7 @@ type Store interface {
// Set sets the Post data into the storage, keyed by the Post's ID. It
// overwrites a previous Post with the same ID, if there was one.
- Set(Post) error
+ Set(post Post, now time.Time) error
// Get returns count StoredPosts, sorted time descending, offset by the given page
// number. The returned boolean indicates if there are more pages or not.
@@ -102,8 +102,6 @@ type StoreParams struct {
// Path to the file the database will be stored at.
DBFilePath string
-
- Clock clock.Clock
}
type store struct {
@@ -136,7 +134,7 @@ func (s *store) Close() error {
return s.db.Close()
}
-// if the callback returns an error then the transaction is aborted
+// if the callback returns an error then the transaction is aborted.
func (s *store) withTx(cb func(*sql.Tx) error) error {
tx, err := s.db.Begin()
@@ -164,9 +162,12 @@ func (s *store) withTx(cb func(*sql.Tx) error) error {
return nil
}
-func (s *store) Set(post Post) error {
+func (s *store) Set(post Post, now time.Time) error {
return s.withTx(func(tx *sql.Tx) error {
- currentDate := DateFromTime(s.params.Clock.Now())
+
+ nowTS := now.Unix()
+
+ nowSql := sql.NullInt64{Int64: nowTS, Valid: !now.IsZero()}
_, err := tx.Exec(
`INSERT INTO posts (
@@ -184,9 +185,9 @@ func (s *store) Set(post Post) error {
post.Title,
post.Description,
&sql.NullString{String: post.Series, Valid: post.Series != ""},
- currentDate,
+ nowSql,
post.Body,
- currentDate,
+ nowSql,
)
if err != nil {
@@ -257,13 +258,14 @@ func (s *store) get(
for rows.Next() {
var (
- post StoredPost
- series, tag sql.NullString
+ post StoredPost
+ series, tag sql.NullString
+ publishedAt, lastUpdatedAt sql.NullInt64
)
err := rows.Scan(
&post.ID, &post.Title, &post.Description, &series, &tag,
- &post.PublishedAt, &post.LastUpdatedAt,
+ &publishedAt, &lastUpdatedAt,
&post.Body,
)
@@ -283,6 +285,14 @@ func (s *store) get(
post.Series = series.String
+ if publishedAt.Valid {
+ post.PublishedAt = time.Unix(publishedAt.Int64, 0).UTC()
+ }
+
+ if lastUpdatedAt.Valid {
+ post.LastUpdatedAt = time.Unix(lastUpdatedAt.Int64, 0).UTC()
+ }
+
posts = append(posts, post)
}
diff --git a/srv/src/post/store_test.go b/srv/src/post/store_test.go
index 1890511..9b0ee45 100644
--- a/srv/src/post/store_test.go
+++ b/srv/src/post/store_test.go
@@ -29,7 +29,7 @@ type storeTestHarness struct {
func newStoreTestHarness(t *testing.T) storeTestHarness {
- clock := clock.NewMock(time.Now().Truncate(1 * time.Hour))
+ clock := clock.NewMock(time.Now().UTC().Truncate(1 * time.Hour))
tmpFile, err := ioutil.TempFile(os.TempDir(), "mediocre-blog-post-store-test-")
if err != nil {
@@ -48,7 +48,6 @@ func newStoreTestHarness(t *testing.T) storeTestHarness {
store, err := NewStore(StoreParams{
DBFilePath: tmpFilePath,
- Clock: clock,
})
assert.NoError(t, err)
@@ -66,7 +65,7 @@ func (h *storeTestHarness) testStoredPost(i int) StoredPost {
post := testPost(i)
return StoredPost{
Post: post,
- PublishedAt: DateFromTime(h.clock.Now()),
+ PublishedAt: h.clock.Now(),
}
}
@@ -101,41 +100,41 @@ func TestStore(t *testing.T) {
t.Run("set_get_delete", func(t *testing.T) {
h := newStoreTestHarness(t)
- nowDate := DateFromTime(h.clock.Now())
+ now := h.clock.Now().UTC()
post := testPost(0)
post.Tags = []string{"foo", "bar"}
- assert.NoError(t, h.store.Set(post))
+ assert.NoError(t, h.store.Set(post, now))
gotPost, err := h.store.GetByID(post.ID)
assert.NoError(t, err)
assertPostEqual(t, StoredPost{
Post: post,
- PublishedAt: nowDate,
+ PublishedAt: now,
}, gotPost)
// we will now try updating the post on a different day, and ensure it
// updates properly
h.clock.Add(24 * time.Hour)
- newNowDate := DateFromTime(h.clock.Now())
+ newNow := h.clock.Now().UTC()
post.Title = "something else"
post.Series = "whatever"
post.Body = "anything"
post.Tags = []string{"bar", "baz"}
- assert.NoError(t, h.store.Set(post))
+ assert.NoError(t, h.store.Set(post, newNow))
gotPost, err = h.store.GetByID(post.ID)
assert.NoError(t, err)
assertPostEqual(t, StoredPost{
Post: post,
- PublishedAt: nowDate,
- LastUpdatedAt: newNowDate,
+ PublishedAt: now,
+ LastUpdatedAt: newNow,
}, gotPost)
// delete the post, it should go away
@@ -148,6 +147,8 @@ func TestStore(t *testing.T) {
t.Run("get", func(t *testing.T) {
h := newStoreTestHarness(t)
+ now := h.clock.Now().UTC()
+
posts := []StoredPost{
h.testStoredPost(0),
h.testStoredPost(1),
@@ -156,7 +157,7 @@ func TestStore(t *testing.T) {
}
for _, post := range posts {
- assert.NoError(t, h.store.Set(post.Post))
+ assert.NoError(t, h.store.Set(post.Post, now))
}
gotPosts, hasMore, err := h.store.Get(0, 2)
@@ -170,7 +171,7 @@ func TestStore(t *testing.T) {
assertPostsEqual(t, posts[2:4], gotPosts)
posts = append(posts, h.testStoredPost(4))
- assert.NoError(t, h.store.Set(posts[4].Post))
+ assert.NoError(t, h.store.Set(posts[4].Post, now))
gotPosts, hasMore, err = h.store.Get(1, 2)
assert.NoError(t, err)
@@ -186,6 +187,8 @@ func TestStore(t *testing.T) {
t.Run("get_by_series", func(t *testing.T) {
h := newStoreTestHarness(t)
+ now := h.clock.Now().UTC()
+
posts := []StoredPost{
h.testStoredPost(0),
h.testStoredPost(1),
@@ -198,7 +201,7 @@ func TestStore(t *testing.T) {
posts[2].Series = "bar"
for _, post := range posts {
- assert.NoError(t, h.store.Set(post.Post))
+ assert.NoError(t, h.store.Set(post.Post, now))
}
fooPosts, err := h.store.GetBySeries("foo")
@@ -218,6 +221,8 @@ func TestStore(t *testing.T) {
h := newStoreTestHarness(t)
+ now := h.clock.Now().UTC()
+
posts := []StoredPost{
h.testStoredPost(0),
h.testStoredPost(1),
@@ -230,7 +235,7 @@ func TestStore(t *testing.T) {
posts[2].Tags = []string{"bar"}
for _, post := range posts {
- assert.NoError(t, h.store.Set(post.Post))
+ assert.NoError(t, h.store.Set(post.Post, now))
}
fooPosts, err := h.store.GetByTag("foo")