1
0
mirror of https://github.com/mxpv/podsync.git synced 2024-05-11 05:55:04 +00:00

Create hash id from feed parameters

This commit is contained in:
Maksym Pavlenko
2017-08-05 15:02:26 -07:00
parent 372577e7f1
commit 23ea998147
4 changed files with 71 additions and 22 deletions

View File

@@ -21,7 +21,7 @@ type PgStorage struct {
func (p *PgStorage) CreateFeed(feed *Feed) error { func (p *PgStorage) CreateFeed(feed *Feed) error {
feed.LastAccess = time.Now().UTC() feed.LastAccess = time.Now().UTC()
_, err := p.db.Model(feed).Insert() _, err := p.db.Model(feed).OnConflict("DO NOTHING").Insert()
if err != nil { if err != nil {
return errors.Wrap(err, "failed to create feed") return errors.Wrap(err, "failed to create feed")
} }

View File

@@ -18,6 +18,31 @@ func TestCreate(t *testing.T) {
require.True(t, feed.Id > 0) require.True(t, feed.Id > 0)
} }
func TestCreateDuplicate(t *testing.T) {
feed := &Feed{
HashId: "123",
URL: "http://youtube.com",
}
client := createClient(t)
err := client.CreateFeed(feed)
require.NoError(t, err)
// Ensure 1 record
count, err := client.db.Model(&Feed{}).Count()
require.NoError(t, err)
require.Equal(t, 1, count)
// Insert duplicated feed
err = client.CreateFeed(feed)
require.NoError(t, err)
// Check no duplicates inserted
count, err = client.db.Model(&Feed{}).Count()
require.NoError(t, err)
require.Equal(t, 1, count)
}
func TestGetFeed(t *testing.T) { func TestGetFeed(t *testing.T) {
feed := &Feed{ feed := &Feed{
HashId: "xyz", HashId: "xyz",
@@ -57,16 +82,6 @@ func TestUpdateLastAccess(t *testing.T) {
require.True(t, last.LastAccess.Unix() > lastAccess.Unix()) require.True(t, last.LastAccess.Unix() > lastAccess.Unix())
} }
func TestUniqueHashId(t *testing.T) {
client := createClient(t)
err := client.CreateFeed(&Feed{HashId: "xyz", URL: "url"})
require.NoError(t, err)
err = client.CreateFeed(&Feed{HashId: "xyz", URL: "url"})
require.Error(t, err)
}
const TestDatabaseConnectionUrl = "postgres://postgres:@localhost/podsync?sslmode=disable" const TestDatabaseConnectionUrl = "postgres://postgres:@localhost/podsync?sslmode=disable"
func createClient(t *testing.T) *PgStorage { func createClient(t *testing.T) *PgStorage {

View File

@@ -1,6 +1,9 @@
package id package id
import ( import (
"hash/fnv"
"github.com/mxpv/podsync/web/pkg/database"
hd "github.com/speps/go-hashids" hd "github.com/speps/go-hashids"
) )
@@ -14,9 +17,24 @@ type hashId struct {
hid *hd.HashID hid *hd.HashID
} }
func (h *hashId) Encode(x ...int) (string, error) { func hashString(s string) int {
var d []int h := fnv.New32a()
return h.hid.Encode(append(d, x...)) h.Write([]byte(s))
return int(h.Sum32())
}
func (h *hashId) Encode(feed *database.Feed) (string, error) {
// Don't create duplicate urls for same playlist/settings
// https://github.com/podsync/issues/issues/6
numbers := []int{
hashString(feed.UserId),
hashString(feed.URL),
feed.PageSize,
hashString(string(feed.Quality)),
hashString(string(feed.Format)),
}
return h.hid.Encode(numbers)
} }
func NewIdGenerator() (*hashId, error) { func NewIdGenerator() (*hashId, error) {
@@ -24,10 +42,6 @@ func NewIdGenerator() (*hashId, error) {
data.MinLength = minLength data.MinLength = minLength
data.Salt = salt data.Salt = salt
data.Alphabet = alphabet data.Alphabet = alphabet
hid, err := hd.NewWithData(data) hid := hd.NewWithData(data)
if err != nil {
return nil, err
}
return &hashId{hid}, nil return &hashId{hid}, nil
} }

View File

@@ -1,15 +1,35 @@
package id package id
import ( import (
"github.com/stretchr/testify/require"
"testing" "testing"
"github.com/mxpv/podsync/web/pkg/database"
"github.com/stretchr/testify/require"
) )
func TestEncode(t *testing.T) { func TestEncode(t *testing.T) {
hid, err := NewIdGenerator() hid, err := NewIdGenerator()
require.NoError(t, err) require.NoError(t, err)
hash, err := hid.Encode(1) feed := &database.Feed{
UserId: "1",
URL: "https://www.youtube.com/channel/UC2yTVSttx7lxAOAzx1opjoA",
PageSize: 10,
Quality: database.HighQuality,
Format: database.AudioFormat,
}
hash1, err := hid.Encode(feed)
require.NoError(t, err) require.NoError(t, err)
require.NotEmpty(t, hash) require.NotEmpty(t, hash1)
// Ensure we have same hash for same feed/parameters
hash2, err := hid.Encode(feed)
require.NoError(t, err)
require.Equal(t, hash1, hash2)
feed.UserId = ""
hash3, err := hid.Encode(feed)
require.NoError(t, err)
require.NotEqual(t, hash1, hash3)
} }