make new engine primary, rename package
This commit is contained in:
@@ -31,7 +31,7 @@ import (
|
||||
"github.com/umputun/remark/backend/app/rest/proxy"
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/image"
|
||||
"github.com/umputun/remark/backend/app/store/service"
|
||||
)
|
||||
@@ -401,7 +401,7 @@ func (a *serverApp) activateBackup(ctx context.Context) {
|
||||
}
|
||||
|
||||
// makeDataStore creates store for all sites
|
||||
func (s *ServerCommand) makeDataStore() (result engine2.Interface, err error) {
|
||||
func (s *ServerCommand) makeDataStore() (result engine.Interface, err error) {
|
||||
log.Printf("[INFO] make data store, type=%s", s.Store.Type)
|
||||
|
||||
switch s.Store.Type {
|
||||
@@ -409,11 +409,11 @@ func (s *ServerCommand) makeDataStore() (result engine2.Interface, err error) {
|
||||
if err = makeDirs(s.Store.Bolt.Path); err != nil {
|
||||
return nil, errors.Wrap(err, "failed to create bolt store")
|
||||
}
|
||||
sites := []engine2.BoltSite{}
|
||||
sites := []engine.BoltSite{}
|
||||
for _, site := range s.Sites {
|
||||
sites = append(sites, engine2.BoltSite{SiteID: site, FileName: fmt.Sprintf("%s/%s.db", s.Store.Bolt.Path, site)})
|
||||
sites = append(sites, engine.BoltSite{SiteID: site, FileName: fmt.Sprintf("%s/%s.db", s.Store.Bolt.Path, site)})
|
||||
}
|
||||
result, err = engine2.NewBoltDB(bolt.Options{Timeout: s.Store.Bolt.Timeout}, sites...)
|
||||
result, err = engine.NewBoltDB(bolt.Options{Timeout: s.Store.Bolt.Timeout}, sites...)
|
||||
// case "mongo":
|
||||
// mgServer, e := s.makeMongo()
|
||||
// if e != nil {
|
||||
|
||||
@@ -12,13 +12,13 @@ import (
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/service"
|
||||
)
|
||||
|
||||
func TestDisqus_Import(t *testing.T) {
|
||||
defer os.Remove("/tmp/remark-test.db")
|
||||
b, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
require.Nil(t, err, "create store")
|
||||
dataStore := service.DataStore{Engine: b, AdminStore: admin.NewStaticStore("12345", []string{}, "")}
|
||||
d := Disqus{DataStore: &dataStore}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/service"
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ func TestMigrator_ImportDisqus(t *testing.T) {
|
||||
err := ioutil.WriteFile("/tmp/disqus-test.xml", []byte(xmlTestDisqus), 0600)
|
||||
require.Nil(t, err)
|
||||
|
||||
b, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
require.Nil(t, err, "create store")
|
||||
dataStore := &service.DataStore{Engine: b, AdminStore: admin.NewStaticStore("12345", []string{}, "")}
|
||||
size, err := ImportComments(ImportParams{
|
||||
@@ -51,7 +51,7 @@ func TestMigrator_ImportWordPress(t *testing.T) {
|
||||
err := ioutil.WriteFile("/tmp/wordpress-test.xml", []byte(xmlTestWP), 0600)
|
||||
require.Nil(t, err)
|
||||
|
||||
b, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
require.Nil(t, err, "create store")
|
||||
dataStore := &service.DataStore{Engine: b, AdminStore: admin.NewStaticStore("12345", []string{}, "")}
|
||||
size, err := ImportComments(ImportParams{
|
||||
@@ -80,7 +80,7 @@ func TestMigrator_ImportNative(t *testing.T) {
|
||||
err := ioutil.WriteFile("/tmp/disqus-test.r42", []byte(data), 0600)
|
||||
require.Nil(t, err)
|
||||
|
||||
b, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "radio-t"})
|
||||
b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "radio-t"})
|
||||
require.Nil(t, err, "create store")
|
||||
dataStore := &service.DataStore{Engine: b, AdminStore: admin.NewStaticStore("12345", []string{}, "")}
|
||||
|
||||
@@ -100,7 +100,7 @@ func TestMigrator_ImportNative(t *testing.T) {
|
||||
|
||||
func TestMigrator_ImportFailed(t *testing.T) {
|
||||
defer os.Remove("/tmp/remark-test.db")
|
||||
b, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: "/tmp/remark-test.db", SiteID: "test"})
|
||||
require.Nil(t, err, "create store")
|
||||
dataStore := &service.DataStore{Engine: b}
|
||||
_, err = ImportComments(ImportParams{
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/service"
|
||||
)
|
||||
|
||||
@@ -142,7 +142,7 @@ func TestNative_ImportManyWithError(t *testing.T) {
|
||||
func prep(t *testing.T) *service.DataStore {
|
||||
os.Remove(testDb)
|
||||
|
||||
boltStore, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{SiteID: "radio-t", FileName: testDb})
|
||||
boltStore, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{SiteID: "radio-t", FileName: testDb})
|
||||
assert.Nil(t, err)
|
||||
|
||||
b := &service.DataStore{Engine: boltStore, AdminStore: admin.NewStaticStore("12345", []string{}, "")}
|
||||
|
||||
@@ -11,14 +11,14 @@ import (
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/service"
|
||||
)
|
||||
|
||||
func TestWordPress_Import(t *testing.T) {
|
||||
siteID := "testWP"
|
||||
defer func() { _ = os.Remove("/tmp/remark-test.db") }()
|
||||
b, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: "/tmp/remark-test.db", SiteID: siteID})
|
||||
b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: "/tmp/remark-test.db", SiteID: siteID})
|
||||
assert.Nil(t, err, "create store")
|
||||
|
||||
dataStore := service.DataStore{Engine: b, AdminStore: admin.NewStaticStore("12345", []string{}, "")}
|
||||
|
||||
@@ -31,7 +31,7 @@ import (
|
||||
"github.com/umputun/remark/backend/app/rest/proxy"
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
adminstore "github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/image"
|
||||
"github.com/umputun/remark/backend/app/store/service"
|
||||
)
|
||||
@@ -291,7 +291,7 @@ func startupT(t *testing.T) (ts *httptest.Server, srv *Rest, teardown func()) {
|
||||
os.RemoveAll("/tmp/ava-remark42")
|
||||
os.RemoveAll("/tmp/pics-remark42")
|
||||
|
||||
b, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: testDb, SiteID: "radio-t"})
|
||||
b, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: testDb, SiteID: "radio-t"})
|
||||
require.Nil(t, err)
|
||||
|
||||
memCache, err := cache.NewMemoryCache()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package engine2
|
||||
package engine
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@@ -1,4 +1,4 @@
|
||||
package engine2
|
||||
package engine
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,6 +1,7 @@
|
||||
package engine
|
||||
|
||||
// Package engine defines interfaces each supported storage should implement.
|
||||
// Includes default implementation with boltdb
|
||||
package engine
|
||||
|
||||
import (
|
||||
"sort"
|
||||
@@ -15,28 +16,68 @@ import (
|
||||
|
||||
// Interface defines methods provided by low-level storage engine
|
||||
type Interface interface {
|
||||
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
|
||||
Get(locator store.Locator, commentID string) (store.Comment, error) // get comment by id
|
||||
Put(locator store.Locator, comment store.Comment) error // update comment, mutable parts only
|
||||
Find(locator store.Locator, sort string) ([]store.Comment, error) // find comments for locator
|
||||
Last(siteID string, limit int, since time.Time) ([]store.Comment, error) // last comments for given site, sorted by time
|
||||
User(siteID, userID string, limit, skip int) ([]store.Comment, error) // comments by user, sorted by time
|
||||
UserCount(siteID, userID string) (int, error) // comments count by user
|
||||
Count(locator store.Locator) (int, error) // number of comments for the post
|
||||
List(siteID string, limit int, skip int) ([]store.PostInfo, error) // list of commented posts
|
||||
Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) // get post info
|
||||
Delete(locator store.Locator, commentID string, mode store.DeleteMode) error // delete comment by id
|
||||
DeleteAll(siteID string) error // delete all data from site
|
||||
DeleteUser(siteID string, userID string) error // remove all comments from user
|
||||
SetBlock(siteID string, userID string, status bool, ttl time.Duration) error // block or unblock user with TTL (0-permanent)
|
||||
IsBlocked(siteID string, userID string) bool // check if user blocked
|
||||
Blocked(siteID string) ([]store.BlockedUser, error) // get list of blocked users
|
||||
SetReadOnly(locator store.Locator, status bool) error // set/reset read-only flag
|
||||
IsReadOnly(locator store.Locator) bool // check if post read-only
|
||||
SetVerified(siteID string, userID string, status bool) error // set/reset verified flag
|
||||
IsVerified(siteID string, userID string) bool // check verified status
|
||||
Verified(siteID string) ([]string, error) // list of verified user ids
|
||||
Close() error // close/stop engine
|
||||
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
|
||||
Update(locator store.Locator, comment store.Comment) error // update comment, mutable parts only
|
||||
Get(locator store.Locator, commentID string) (store.Comment, error) // get comment by id
|
||||
Find(req FindRequest) ([]store.Comment, error) // find comments for locator or site
|
||||
Info(req InfoRequest) ([]store.PostInfo, error) // get post(s) meta info
|
||||
Count(req FindRequest) (int, error) // get count for post or user
|
||||
Delete(req DeleteRequest) error // delete post(s) by id or by userID
|
||||
Flag(req FlagRequest) (bool, error) // set and get flags
|
||||
ListFlags(siteID string, flag Flag) ([]interface{}, error) // get list of flagged keys, like blocked & verified user
|
||||
Close() error // close storage engine
|
||||
}
|
||||
|
||||
// FindRequest is the input for all find operations
|
||||
type FindRequest struct {
|
||||
Locator store.Locator // lack of URL means site operation
|
||||
UserID string // presence of UserID treated as user-related find
|
||||
Sort string // sort order with +/-field syntax
|
||||
Since time.Time // time limit for found results
|
||||
Limit, Skip int
|
||||
}
|
||||
|
||||
// InfoRequest is the input of Info operation used to get meta data about posts
|
||||
type InfoRequest struct {
|
||||
Locator store.Locator
|
||||
Limit, Skip int
|
||||
ReadOnlyAge int
|
||||
}
|
||||
|
||||
type DeleteRequest struct {
|
||||
Locator store.Locator // lack of URL means site operation
|
||||
CommentID string
|
||||
UserID string
|
||||
DeleteMode store.DeleteMode
|
||||
}
|
||||
|
||||
// Flag defines type of binary attribute
|
||||
type Flag string
|
||||
|
||||
// FlagStatus represents values of the flag update
|
||||
type FlagStatus int
|
||||
|
||||
// enum of update values
|
||||
const (
|
||||
FlagNonSet FlagStatus = 0
|
||||
FlagTrue FlagStatus = 1
|
||||
FlagFalse FlagStatus = -1
|
||||
)
|
||||
|
||||
// Enum of all flags
|
||||
const (
|
||||
ReadOnly = Flag("readonly")
|
||||
Verified = Flag("verified")
|
||||
Blocked = Flag("blocked")
|
||||
)
|
||||
|
||||
// FlagRequest is the input for both get/set for flags, like blocked, verified and so on
|
||||
type FlagRequest struct {
|
||||
Flag Flag // flag type
|
||||
Locator store.Locator // post locator
|
||||
UserID string // for flags setting user status
|
||||
Update FlagStatus // if FlagNonSet it will be get op, if set will set the value
|
||||
TTL time.Duration // ttl for time-sensitive flags only, like blocked for some period
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
@@ -3,36 +3,12 @@ package engine
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import store "github.com/umputun/remark/backend/app/store"
|
||||
import time "time"
|
||||
|
||||
// MockInterface is an autogenerated mock type for the Interface type
|
||||
type MockInterface struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Blocked provides a mock function with given fields: siteID
|
||||
func (_m *MockInterface) Blocked(siteID string) ([]store.BlockedUser, error) {
|
||||
ret := _m.Called(siteID)
|
||||
|
||||
var r0 []store.BlockedUser
|
||||
if rf, ok := ret.Get(0).(func(string) []store.BlockedUser); ok {
|
||||
r0 = rf(siteID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.BlockedUser)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(siteID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
func (_m *MockInterface) Close() error {
|
||||
ret := _m.Called()
|
||||
@@ -47,20 +23,20 @@ func (_m *MockInterface) Close() error {
|
||||
return r0
|
||||
}
|
||||
|
||||
// Count provides a mock function with given fields: locator
|
||||
func (_m *MockInterface) Count(locator store.Locator) (int, error) {
|
||||
ret := _m.Called(locator)
|
||||
// Count provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Count(req FindRequest) (int, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func(store.Locator) int); ok {
|
||||
r0 = rf(locator)
|
||||
if rf, ok := ret.Get(0).(func(FindRequest) int); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator) error); ok {
|
||||
r1 = rf(locator)
|
||||
if rf, ok := ret.Get(1).(func(FindRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -89,13 +65,13 @@ func (_m *MockInterface) Create(comment store.Comment) (string, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: locator, commentID, mode
|
||||
func (_m *MockInterface) Delete(locator store.Locator, commentID string, mode store.DeleteMode) error {
|
||||
ret := _m.Called(locator, commentID, mode)
|
||||
// Delete provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Delete(req DeleteRequest) error {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, string, store.DeleteMode) error); ok {
|
||||
r0 = rf(locator, commentID, mode)
|
||||
if rf, ok := ret.Get(0).(func(DeleteRequest) error); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
@@ -103,41 +79,13 @@ func (_m *MockInterface) Delete(locator store.Locator, commentID string, mode st
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteAll provides a mock function with given fields: siteID
|
||||
func (_m *MockInterface) DeleteAll(siteID string) error {
|
||||
ret := _m.Called(siteID)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(siteID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteUser provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) DeleteUser(siteID string, userID string) error {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Find provides a mock function with given fields: locator, sort
|
||||
func (_m *MockInterface) Find(locator store.Locator, sort string) ([]store.Comment, error) {
|
||||
ret := _m.Called(locator, sort)
|
||||
// Find provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Find(req FindRequest) ([]store.Comment, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 []store.Comment
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, string) []store.Comment); ok {
|
||||
r0 = rf(locator, sort)
|
||||
if rf, ok := ret.Get(0).(func(FindRequest) []store.Comment); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.Comment)
|
||||
@@ -145,8 +93,29 @@ func (_m *MockInterface) Find(locator store.Locator, sort string) ([]store.Comme
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator, string) error); ok {
|
||||
r1 = rf(locator, sort)
|
||||
if rf, ok := ret.Get(1).(func(FindRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Flag provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Flag(req FlagRequest) (bool, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(FlagRequest) bool); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(FlagRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -175,99 +144,13 @@ func (_m *MockInterface) Get(locator store.Locator, commentID string) (store.Com
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Info provides a mock function with given fields: locator, readonlyAge
|
||||
func (_m *MockInterface) Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) {
|
||||
ret := _m.Called(locator, readonlyAge)
|
||||
|
||||
var r0 store.PostInfo
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, int) store.PostInfo); ok {
|
||||
r0 = rf(locator, readonlyAge)
|
||||
} else {
|
||||
r0 = ret.Get(0).(store.PostInfo)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator, int) error); ok {
|
||||
r1 = rf(locator, readonlyAge)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// IsBlocked provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) IsBlocked(siteID string, userID string) bool {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(string, string) bool); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// IsReadOnly provides a mock function with given fields: locator
|
||||
func (_m *MockInterface) IsReadOnly(locator store.Locator) bool {
|
||||
ret := _m.Called(locator)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(store.Locator) bool); ok {
|
||||
r0 = rf(locator)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// IsVerified provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) IsVerified(siteID string, userID string) bool {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(string, string) bool); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Last provides a mock function with given fields: siteID, limit, since
|
||||
func (_m *MockInterface) Last(siteID string, limit int, since time.Time) ([]store.Comment, error) {
|
||||
ret := _m.Called(siteID, limit, since)
|
||||
|
||||
var r0 []store.Comment
|
||||
if rf, ok := ret.Get(0).(func(string, int, time.Time) []store.Comment); ok {
|
||||
r0 = rf(siteID, limit, since)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.Comment)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, int, time.Time) error); ok {
|
||||
r1 = rf(siteID, limit, since)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// List provides a mock function with given fields: siteID, limit, skip
|
||||
func (_m *MockInterface) List(siteID string, limit int, skip int) ([]store.PostInfo, error) {
|
||||
ret := _m.Called(siteID, limit, skip)
|
||||
// Info provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Info(req InfoRequest) ([]store.PostInfo, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 []store.PostInfo
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) []store.PostInfo); ok {
|
||||
r0 = rf(siteID, limit, skip)
|
||||
if rf, ok := ret.Get(0).(func(InfoRequest) []store.PostInfo); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.PostInfo)
|
||||
@@ -275,8 +158,8 @@ func (_m *MockInterface) List(siteID string, limit int, skip int) ([]store.PostI
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, int, int) error); ok {
|
||||
r1 = rf(siteID, limit, skip)
|
||||
if rf, ok := ret.Get(1).(func(InfoRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -284,8 +167,31 @@ func (_m *MockInterface) List(siteID string, limit int, skip int) ([]store.PostI
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Put provides a mock function with given fields: locator, comment
|
||||
func (_m *MockInterface) Put(locator store.Locator, comment store.Comment) error {
|
||||
// ListFlags provides a mock function with given fields: siteID, flag
|
||||
func (_m *MockInterface) ListFlags(siteID string, flag Flag) ([]interface{}, error) {
|
||||
ret := _m.Called(siteID, flag)
|
||||
|
||||
var r0 []interface{}
|
||||
if rf, ok := ret.Get(0).(func(string, Flag) []interface{}); ok {
|
||||
r0 = rf(siteID, flag)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, Flag) error); ok {
|
||||
r1 = rf(siteID, flag)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Update provides a mock function with given fields: locator, comment
|
||||
func (_m *MockInterface) Update(locator store.Locator, comment store.Comment) error {
|
||||
ret := _m.Called(locator, comment)
|
||||
|
||||
var r0 error
|
||||
@@ -297,112 +203,3 @@ func (_m *MockInterface) Put(locator store.Locator, comment store.Comment) error
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetBlock provides a mock function with given fields: siteID, userID, status, ttl
|
||||
func (_m *MockInterface) SetBlock(siteID string, userID string, status bool, ttl time.Duration) error {
|
||||
ret := _m.Called(siteID, userID, status, ttl)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool, time.Duration) error); ok {
|
||||
r0 = rf(siteID, userID, status, ttl)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetReadOnly provides a mock function with given fields: locator, status
|
||||
func (_m *MockInterface) SetReadOnly(locator store.Locator, status bool) error {
|
||||
ret := _m.Called(locator, status)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, bool) error); ok {
|
||||
r0 = rf(locator, status)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetVerified provides a mock function with given fields: siteID, userID, status
|
||||
func (_m *MockInterface) SetVerified(siteID string, userID string, status bool) error {
|
||||
ret := _m.Called(siteID, userID, status)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool) error); ok {
|
||||
r0 = rf(siteID, userID, status)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// User provides a mock function with given fields: siteID, userID, limit, skip
|
||||
func (_m *MockInterface) User(siteID string, userID string, limit int, skip int) ([]store.Comment, error) {
|
||||
ret := _m.Called(siteID, userID, limit, skip)
|
||||
|
||||
var r0 []store.Comment
|
||||
if rf, ok := ret.Get(0).(func(string, string, int, int) []store.Comment); ok {
|
||||
r0 = rf(siteID, userID, limit, skip)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.Comment)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, int, int) error); ok {
|
||||
r1 = rf(siteID, userID, limit, skip)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UserCount provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) UserCount(siteID string, userID string) (int, error) {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func(string, string) int); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(siteID, userID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Verified provides a mock function with given fields: siteID
|
||||
func (_m *MockInterface) Verified(siteID string) ([]string, error) {
|
||||
ret := _m.Called(siteID)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(string) []string); ok {
|
||||
r0 = rf(siteID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(siteID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
@@ -1,128 +0,0 @@
|
||||
package engine2
|
||||
|
||||
// Package engine defines interfaces each supported storage should implement.
|
||||
// Includes default implementation with boltdb
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
)
|
||||
|
||||
// NOTE: mockery works from linked to go-path and with GOFLAGS='-mod=vendor' go generate
|
||||
//go:generate sh -c "mockery -inpkg -name Interface -print > /tmp/engine-mock.tmp && mv /tmp/engine-mock.tmp engine_mock.go"
|
||||
|
||||
// Interface defines methods provided by low-level storage engine
|
||||
type Interface interface {
|
||||
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
|
||||
Update(locator store.Locator, comment store.Comment) error // update comment, mutable parts only
|
||||
Get(locator store.Locator, commentID string) (store.Comment, error) // get comment by id
|
||||
Find(req FindRequest) ([]store.Comment, error) // find comments for locator or site
|
||||
Info(req InfoRequest) ([]store.PostInfo, error) // get post(s) meta info
|
||||
Count(req FindRequest) (int, error) // get count for post or user
|
||||
Delete(req DeleteRequest) error // delete post(s) by id or by userID
|
||||
Flag(req FlagRequest) (bool, error) // set and get flags
|
||||
ListFlags(siteID string, flag Flag) ([]interface{}, error) // get list of flagged keys, like blocked & verified user
|
||||
Close() error // close storage engine
|
||||
}
|
||||
|
||||
// FindRequest is the input for all find operations
|
||||
type FindRequest struct {
|
||||
Locator store.Locator // lack of URL means site operation
|
||||
UserID string // presence of UserID treated as user-related find
|
||||
Sort string // sort order with +/-field syntax
|
||||
Since time.Time // time limit for found results
|
||||
Limit, Skip int
|
||||
}
|
||||
|
||||
// InfoRequest is the input of Info operation used to get meta data about posts
|
||||
type InfoRequest struct {
|
||||
Locator store.Locator
|
||||
Limit, Skip int
|
||||
ReadOnlyAge int
|
||||
}
|
||||
|
||||
type DeleteRequest struct {
|
||||
Locator store.Locator // lack of URL means site operation
|
||||
CommentID string
|
||||
UserID string
|
||||
DeleteMode store.DeleteMode
|
||||
}
|
||||
|
||||
// Flag defines type of binary attribute
|
||||
type Flag string
|
||||
|
||||
// FlagStatus represents values of the flag update
|
||||
type FlagStatus int
|
||||
|
||||
// enum of update values
|
||||
const (
|
||||
FlagNonSet FlagStatus = 0
|
||||
FlagTrue FlagStatus = 1
|
||||
FlagFalse FlagStatus = -1
|
||||
)
|
||||
|
||||
// Enum of all flags
|
||||
const (
|
||||
ReadOnly = Flag("readonly")
|
||||
Verified = Flag("verified")
|
||||
Blocked = Flag("blocked")
|
||||
)
|
||||
|
||||
// FlagRequest is the input for both get/set for flags, like blocked, verified and so on
|
||||
type FlagRequest struct {
|
||||
Flag Flag // flag type
|
||||
Locator store.Locator // post locator
|
||||
UserID string // for flags setting user status
|
||||
Update FlagStatus // if FlagNonSet it will be get op, if set will set the value
|
||||
TTL time.Duration // ttl for time-sensitive flags only, like blocked for some period
|
||||
}
|
||||
|
||||
const (
|
||||
// limits
|
||||
lastLimit = 1000
|
||||
userLimit = 500
|
||||
)
|
||||
|
||||
// SortComments is for engines can't sort data internally
|
||||
func SortComments(comments []store.Comment, sortFld string) []store.Comment {
|
||||
sort.Slice(comments, func(i, j int) bool {
|
||||
switch sortFld {
|
||||
case "+time", "-time", "time", "+active", "-active", "active":
|
||||
if strings.HasPrefix(sortFld, "-") {
|
||||
return comments[i].Timestamp.After(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
|
||||
case "+score", "-score", "score":
|
||||
if strings.HasPrefix(sortFld, "-") {
|
||||
if comments[i].Score == comments[j].Score {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Score > comments[j].Score
|
||||
}
|
||||
if comments[i].Score == comments[j].Score {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Score < comments[j].Score
|
||||
|
||||
case "+controversy", "-controversy", "controversy":
|
||||
if strings.HasPrefix(sortFld, "-") {
|
||||
if comments[i].Controversy == comments[j].Controversy {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Controversy > comments[j].Controversy
|
||||
}
|
||||
if comments[i].Controversy == comments[j].Controversy {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Controversy < comments[j].Controversy
|
||||
|
||||
default:
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
})
|
||||
return comments
|
||||
}
|
||||
@@ -1,205 +0,0 @@
|
||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
||||
package engine2
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import store "github.com/umputun/remark/backend/app/store"
|
||||
|
||||
// MockInterface is an autogenerated mock type for the Interface type
|
||||
type MockInterface struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
func (_m *MockInterface) Close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Count provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Count(req FindRequest) (int, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func(FindRequest) int); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(FindRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Create provides a mock function with given fields: comment
|
||||
func (_m *MockInterface) Create(comment store.Comment) (string, error) {
|
||||
ret := _m.Called(comment)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(store.Comment) string); ok {
|
||||
r0 = rf(comment)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Comment) error); ok {
|
||||
r1 = rf(comment)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Delete(req DeleteRequest) error {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(DeleteRequest) error); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Find provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Find(req FindRequest) ([]store.Comment, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 []store.Comment
|
||||
if rf, ok := ret.Get(0).(func(FindRequest) []store.Comment); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.Comment)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(FindRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Flag provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Flag(req FlagRequest) (bool, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(FlagRequest) bool); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(FlagRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: locator, commentID
|
||||
func (_m *MockInterface) Get(locator store.Locator, commentID string) (store.Comment, error) {
|
||||
ret := _m.Called(locator, commentID)
|
||||
|
||||
var r0 store.Comment
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, string) store.Comment); ok {
|
||||
r0 = rf(locator, commentID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(store.Comment)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator, string) error); ok {
|
||||
r1 = rf(locator, commentID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Info provides a mock function with given fields: req
|
||||
func (_m *MockInterface) Info(req InfoRequest) ([]store.PostInfo, error) {
|
||||
ret := _m.Called(req)
|
||||
|
||||
var r0 []store.PostInfo
|
||||
if rf, ok := ret.Get(0).(func(InfoRequest) []store.PostInfo); ok {
|
||||
r0 = rf(req)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.PostInfo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(InfoRequest) error); ok {
|
||||
r1 = rf(req)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// ListFlags provides a mock function with given fields: siteID, flag
|
||||
func (_m *MockInterface) ListFlags(siteID string, flag Flag) ([]interface{}, error) {
|
||||
ret := _m.Called(siteID, flag)
|
||||
|
||||
var r0 []interface{}
|
||||
if rf, ok := ret.Get(0).(func(string, Flag) []interface{}); ok {
|
||||
r0 = rf(siteID, flag)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]interface{})
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, Flag) error); ok {
|
||||
r1 = rf(siteID, flag)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Update provides a mock function with given fields: locator, comment
|
||||
func (_m *MockInterface) Update(locator store.Locator, comment store.Comment) error {
|
||||
ret := _m.Called(locator, comment)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, store.Comment) error); ok {
|
||||
r0 = rf(locator, comment)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package engine
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package engine
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -1,4 +1,4 @@
|
||||
package engine
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package engine
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -0,0 +1,87 @@
|
||||
// Package engine defines interfaces each supported storage should implement.
|
||||
// Includes default implementation with boltdb
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
)
|
||||
|
||||
// NOTE: mockery works from linked to go-path and with GOFLAGS='-mod=vendor' go generate
|
||||
//go:generate sh -c "mockery -inpkg -name Interface -print > /tmp/engine-mock.tmp && mv /tmp/engine-mock.tmp engine_mock.go"
|
||||
|
||||
// Interface defines methods provided by low-level storage engine
|
||||
type Interface interface {
|
||||
Create(comment store.Comment) (commentID string, err error) // create new comment, avoid dups by id
|
||||
Get(locator store.Locator, commentID string) (store.Comment, error) // get comment by id
|
||||
Put(locator store.Locator, comment store.Comment) error // update comment, mutable parts only
|
||||
Find(locator store.Locator, sort string) ([]store.Comment, error) // find comments for locator
|
||||
Last(siteID string, limit int, since time.Time) ([]store.Comment, error) // last comments for given site, sorted by time
|
||||
User(siteID, userID string, limit, skip int) ([]store.Comment, error) // comments by user, sorted by time
|
||||
UserCount(siteID, userID string) (int, error) // comments count by user
|
||||
Count(locator store.Locator) (int, error) // number of comments for the post
|
||||
List(siteID string, limit int, skip int) ([]store.PostInfo, error) // list of commented posts
|
||||
Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) // get post info
|
||||
Delete(locator store.Locator, commentID string, mode store.DeleteMode) error // delete comment by id
|
||||
DeleteAll(siteID string) error // delete all data from site
|
||||
DeleteUser(siteID string, userID string) error // remove all comments from user
|
||||
SetBlock(siteID string, userID string, status bool, ttl time.Duration) error // block or unblock user with TTL (0-permanent)
|
||||
IsBlocked(siteID string, userID string) bool // check if user blocked
|
||||
Blocked(siteID string) ([]store.BlockedUser, error) // get list of blocked users
|
||||
SetReadOnly(locator store.Locator, status bool) error // set/reset read-only flag
|
||||
IsReadOnly(locator store.Locator) bool // check if post read-only
|
||||
SetVerified(siteID string, userID string, status bool) error // set/reset verified flag
|
||||
IsVerified(siteID string, userID string) bool // check verified status
|
||||
Verified(siteID string) ([]string, error) // list of verified user ids
|
||||
Close() error // close/stop engine
|
||||
}
|
||||
|
||||
const (
|
||||
// limits
|
||||
lastLimit = 1000
|
||||
userLimit = 500
|
||||
)
|
||||
|
||||
// SortComments is for engines can't sort data internally
|
||||
func SortComments(comments []store.Comment, sortFld string) []store.Comment {
|
||||
sort.Slice(comments, func(i, j int) bool {
|
||||
switch sortFld {
|
||||
case "+time", "-time", "time", "+active", "-active", "active":
|
||||
if strings.HasPrefix(sortFld, "-") {
|
||||
return comments[i].Timestamp.After(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
|
||||
case "+score", "-score", "score":
|
||||
if strings.HasPrefix(sortFld, "-") {
|
||||
if comments[i].Score == comments[j].Score {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Score > comments[j].Score
|
||||
}
|
||||
if comments[i].Score == comments[j].Score {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Score < comments[j].Score
|
||||
|
||||
case "+controversy", "-controversy", "controversy":
|
||||
if strings.HasPrefix(sortFld, "-") {
|
||||
if comments[i].Controversy == comments[j].Controversy {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Controversy > comments[j].Controversy
|
||||
}
|
||||
if comments[i].Controversy == comments[j].Controversy {
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
return comments[i].Controversy < comments[j].Controversy
|
||||
|
||||
default:
|
||||
return comments[i].Timestamp.Before(comments[j].Timestamp)
|
||||
}
|
||||
})
|
||||
return comments
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
// Code generated by mockery v1.0.0. DO NOT EDIT.
|
||||
package engine_old
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
import store "github.com/umputun/remark/backend/app/store"
|
||||
import time "time"
|
||||
|
||||
// MockInterface is an autogenerated mock type for the Interface type
|
||||
type MockInterface struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Blocked provides a mock function with given fields: siteID
|
||||
func (_m *MockInterface) Blocked(siteID string) ([]store.BlockedUser, error) {
|
||||
ret := _m.Called(siteID)
|
||||
|
||||
var r0 []store.BlockedUser
|
||||
if rf, ok := ret.Get(0).(func(string) []store.BlockedUser); ok {
|
||||
r0 = rf(siteID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.BlockedUser)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(siteID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
func (_m *MockInterface) Close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Count provides a mock function with given fields: locator
|
||||
func (_m *MockInterface) Count(locator store.Locator) (int, error) {
|
||||
ret := _m.Called(locator)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func(store.Locator) int); ok {
|
||||
r0 = rf(locator)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator) error); ok {
|
||||
r1 = rf(locator)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Create provides a mock function with given fields: comment
|
||||
func (_m *MockInterface) Create(comment store.Comment) (string, error) {
|
||||
ret := _m.Called(comment)
|
||||
|
||||
var r0 string
|
||||
if rf, ok := ret.Get(0).(func(store.Comment) string); ok {
|
||||
r0 = rf(comment)
|
||||
} else {
|
||||
r0 = ret.Get(0).(string)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Comment) error); ok {
|
||||
r1 = rf(comment)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Delete provides a mock function with given fields: locator, commentID, mode
|
||||
func (_m *MockInterface) Delete(locator store.Locator, commentID string, mode store.DeleteMode) error {
|
||||
ret := _m.Called(locator, commentID, mode)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, string, store.DeleteMode) error); ok {
|
||||
r0 = rf(locator, commentID, mode)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteAll provides a mock function with given fields: siteID
|
||||
func (_m *MockInterface) DeleteAll(siteID string) error {
|
||||
ret := _m.Called(siteID)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string) error); ok {
|
||||
r0 = rf(siteID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// DeleteUser provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) DeleteUser(siteID string, userID string) error {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string) error); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Find provides a mock function with given fields: locator, sort
|
||||
func (_m *MockInterface) Find(locator store.Locator, sort string) ([]store.Comment, error) {
|
||||
ret := _m.Called(locator, sort)
|
||||
|
||||
var r0 []store.Comment
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, string) []store.Comment); ok {
|
||||
r0 = rf(locator, sort)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.Comment)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator, string) error); ok {
|
||||
r1 = rf(locator, sort)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Get provides a mock function with given fields: locator, commentID
|
||||
func (_m *MockInterface) Get(locator store.Locator, commentID string) (store.Comment, error) {
|
||||
ret := _m.Called(locator, commentID)
|
||||
|
||||
var r0 store.Comment
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, string) store.Comment); ok {
|
||||
r0 = rf(locator, commentID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(store.Comment)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator, string) error); ok {
|
||||
r1 = rf(locator, commentID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Info provides a mock function with given fields: locator, readonlyAge
|
||||
func (_m *MockInterface) Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) {
|
||||
ret := _m.Called(locator, readonlyAge)
|
||||
|
||||
var r0 store.PostInfo
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, int) store.PostInfo); ok {
|
||||
r0 = rf(locator, readonlyAge)
|
||||
} else {
|
||||
r0 = ret.Get(0).(store.PostInfo)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(store.Locator, int) error); ok {
|
||||
r1 = rf(locator, readonlyAge)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// IsBlocked provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) IsBlocked(siteID string, userID string) bool {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(string, string) bool); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// IsReadOnly provides a mock function with given fields: locator
|
||||
func (_m *MockInterface) IsReadOnly(locator store.Locator) bool {
|
||||
ret := _m.Called(locator)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(store.Locator) bool); ok {
|
||||
r0 = rf(locator)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// IsVerified provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) IsVerified(siteID string, userID string) bool {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 bool
|
||||
if rf, ok := ret.Get(0).(func(string, string) bool); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(bool)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Last provides a mock function with given fields: siteID, limit, since
|
||||
func (_m *MockInterface) Last(siteID string, limit int, since time.Time) ([]store.Comment, error) {
|
||||
ret := _m.Called(siteID, limit, since)
|
||||
|
||||
var r0 []store.Comment
|
||||
if rf, ok := ret.Get(0).(func(string, int, time.Time) []store.Comment); ok {
|
||||
r0 = rf(siteID, limit, since)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.Comment)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, int, time.Time) error); ok {
|
||||
r1 = rf(siteID, limit, since)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// List provides a mock function with given fields: siteID, limit, skip
|
||||
func (_m *MockInterface) List(siteID string, limit int, skip int) ([]store.PostInfo, error) {
|
||||
ret := _m.Called(siteID, limit, skip)
|
||||
|
||||
var r0 []store.PostInfo
|
||||
if rf, ok := ret.Get(0).(func(string, int, int) []store.PostInfo); ok {
|
||||
r0 = rf(siteID, limit, skip)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.PostInfo)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, int, int) error); ok {
|
||||
r1 = rf(siteID, limit, skip)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Put provides a mock function with given fields: locator, comment
|
||||
func (_m *MockInterface) Put(locator store.Locator, comment store.Comment) error {
|
||||
ret := _m.Called(locator, comment)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, store.Comment) error); ok {
|
||||
r0 = rf(locator, comment)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetBlock provides a mock function with given fields: siteID, userID, status, ttl
|
||||
func (_m *MockInterface) SetBlock(siteID string, userID string, status bool, ttl time.Duration) error {
|
||||
ret := _m.Called(siteID, userID, status, ttl)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool, time.Duration) error); ok {
|
||||
r0 = rf(siteID, userID, status, ttl)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetReadOnly provides a mock function with given fields: locator, status
|
||||
func (_m *MockInterface) SetReadOnly(locator store.Locator, status bool) error {
|
||||
ret := _m.Called(locator, status)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(store.Locator, bool) error); ok {
|
||||
r0 = rf(locator, status)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// SetVerified provides a mock function with given fields: siteID, userID, status
|
||||
func (_m *MockInterface) SetVerified(siteID string, userID string, status bool) error {
|
||||
ret := _m.Called(siteID, userID, status)
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func(string, string, bool) error); ok {
|
||||
r0 = rf(siteID, userID, status)
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// User provides a mock function with given fields: siteID, userID, limit, skip
|
||||
func (_m *MockInterface) User(siteID string, userID string, limit int, skip int) ([]store.Comment, error) {
|
||||
ret := _m.Called(siteID, userID, limit, skip)
|
||||
|
||||
var r0 []store.Comment
|
||||
if rf, ok := ret.Get(0).(func(string, string, int, int) []store.Comment); ok {
|
||||
r0 = rf(siteID, userID, limit, skip)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]store.Comment)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string, int, int) error); ok {
|
||||
r1 = rf(siteID, userID, limit, skip)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// UserCount provides a mock function with given fields: siteID, userID
|
||||
func (_m *MockInterface) UserCount(siteID string, userID string) (int, error) {
|
||||
ret := _m.Called(siteID, userID)
|
||||
|
||||
var r0 int
|
||||
if rf, ok := ret.Get(0).(func(string, string) int); ok {
|
||||
r0 = rf(siteID, userID)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string, string) error); ok {
|
||||
r1 = rf(siteID, userID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Verified provides a mock function with given fields: siteID
|
||||
func (_m *MockInterface) Verified(siteID string) ([]string, error) {
|
||||
ret := _m.Called(siteID)
|
||||
|
||||
var r0 []string
|
||||
if rf, ok := ret.Get(0).(func(string) []string); ok {
|
||||
r0 = rf(siteID)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]string)
|
||||
}
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(string) error); ok {
|
||||
r1 = rf(siteID)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
package engine2
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -1,4 +1,4 @@
|
||||
package engine
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"time"
|
||||
@@ -1,4 +1,4 @@
|
||||
package engine
|
||||
package engine_old
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@@ -19,13 +19,12 @@ import (
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/image"
|
||||
)
|
||||
|
||||
// DataStore wraps store.Interface with additional methods
|
||||
type DataStore struct {
|
||||
Engine engine2.Interface
|
||||
Engine engine.Interface
|
||||
EditDuration time.Duration
|
||||
AdminStore admin.Store
|
||||
MaxCommentSize int
|
||||
@@ -105,7 +104,7 @@ func (s *DataStore) Create(comment store.Comment) (commentID string, err error)
|
||||
// Find wraps engine's Find call and alter results if needed
|
||||
// user used to filter results for self vs others
|
||||
func (s *DataStore) Find(locator store.Locator, sort string, user store.User) ([]store.Comment, error) {
|
||||
req := engine2.FindRequest{Locator: locator, Sort: sort}
|
||||
req := engine.FindRequest{Locator: locator, Sort: sort}
|
||||
comments, err := s.Engine.Find(req)
|
||||
if err != nil {
|
||||
return comments, err
|
||||
@@ -192,7 +191,7 @@ func (s *DataStore) prepareNewComment(comment store.Comment) (store.Comment, err
|
||||
|
||||
// DeleteAll removes all data from site
|
||||
func (s *DataStore) DeleteAll(siteID string) error {
|
||||
req := engine2.DeleteRequest{Locator: store.Locator{SiteID: siteID}}
|
||||
req := engine.DeleteRequest{Locator: store.Locator{SiteID: siteID}}
|
||||
return s.Engine.Delete(req)
|
||||
}
|
||||
|
||||
@@ -317,7 +316,7 @@ func (s *DataStore) EditComment(locator store.Locator, commentID string, req Edi
|
||||
|
||||
if req.Delete { // delete request
|
||||
comment.Deleted = true
|
||||
delReq := engine2.DeleteRequest{Locator: locator, CommentID: commentID, DeleteMode: store.SoftDelete}
|
||||
delReq := engine.DeleteRequest{Locator: locator, CommentID: commentID, DeleteMode: store.SoftDelete}
|
||||
return comment, s.Engine.Delete(delReq)
|
||||
}
|
||||
|
||||
@@ -351,7 +350,7 @@ func (s *DataStore) HasReplies(comment store.Comment) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
req := engine2.FindRequest{Locator: store.Locator{SiteID: comment.Locator.SiteID}, Limit: maxLastCommentsReply}
|
||||
req := engine.FindRequest{Locator: store.Locator{SiteID: comment.Locator.SiteID}, Limit: maxLastCommentsReply}
|
||||
comments, err := s.Engine.Find(req)
|
||||
if err != nil {
|
||||
log.Printf("[WARN] can't get last comments for reply check, %v", err)
|
||||
@@ -430,7 +429,7 @@ func (s *DataStore) SetTitle(locator store.Locator, commentID string) (comment s
|
||||
func (s *DataStore) Counts(siteID string, postIDs []string) ([]store.PostInfo, error) {
|
||||
res := []store.PostInfo{}
|
||||
for _, p := range postIDs {
|
||||
req := engine2.FindRequest{Locator: store.Locator{SiteID: siteID, URL: p}}
|
||||
req := engine.FindRequest{Locator: store.Locator{SiteID: siteID, URL: p}}
|
||||
if c, err := s.Engine.Count(req); err == nil {
|
||||
res = append(res, store.PostInfo{URL: p, Count: c})
|
||||
}
|
||||
@@ -468,63 +467,63 @@ func (s *DataStore) IsAdmin(siteID string, userID string) bool {
|
||||
|
||||
// IsReadOnly checks if post read-only
|
||||
func (s *DataStore) IsReadOnly(locator store.Locator) bool {
|
||||
req := engine2.FlagRequest{Locator: locator, Flag: engine2.ReadOnly}
|
||||
req := engine.FlagRequest{Locator: locator, Flag: engine.ReadOnly}
|
||||
ro, err := s.Engine.Flag(req)
|
||||
return err == nil && ro
|
||||
}
|
||||
|
||||
// SetReadOnly set/reset read-only flag
|
||||
func (s *DataStore) SetReadOnly(locator store.Locator, status bool) error {
|
||||
roStatus := engine2.FlagFalse
|
||||
roStatus := engine.FlagFalse
|
||||
if status {
|
||||
roStatus = engine2.FlagTrue
|
||||
roStatus = engine.FlagTrue
|
||||
|
||||
}
|
||||
req := engine2.FlagRequest{Locator: locator, Flag: engine2.ReadOnly, Update: roStatus}
|
||||
req := engine.FlagRequest{Locator: locator, Flag: engine.ReadOnly, Update: roStatus}
|
||||
_, err := s.Engine.Flag(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// IsVerified checks if user verified
|
||||
func (s *DataStore) IsVerified(siteID string, userID string) bool {
|
||||
req := engine2.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Flag: engine2.Verified}
|
||||
req := engine.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Flag: engine.Verified}
|
||||
ro, err := s.Engine.Flag(req)
|
||||
return err == nil && ro
|
||||
}
|
||||
|
||||
// SetVerified set/reset verified status for user
|
||||
func (s *DataStore) SetVerified(siteID string, userID string, status bool) error {
|
||||
roStatus := engine2.FlagFalse
|
||||
roStatus := engine.FlagFalse
|
||||
if status {
|
||||
roStatus = engine2.FlagTrue
|
||||
roStatus = engine.FlagTrue
|
||||
}
|
||||
req := engine2.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Flag: engine2.Verified, Update: roStatus}
|
||||
req := engine.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Flag: engine.Verified, Update: roStatus}
|
||||
_, err := s.Engine.Flag(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// IsBlocked checks if user blocked
|
||||
func (s *DataStore) IsBlocked(siteID string, userID string) bool {
|
||||
req := engine2.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Flag: engine2.Blocked}
|
||||
req := engine.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Flag: engine.Blocked}
|
||||
ro, err := s.Engine.Flag(req)
|
||||
return err == nil && ro
|
||||
}
|
||||
|
||||
// SetBlock set/reset verified status for user
|
||||
func (s *DataStore) SetBlock(siteID string, userID string, status bool, ttl time.Duration) error {
|
||||
roStatus := engine2.FlagFalse
|
||||
roStatus := engine.FlagFalse
|
||||
if status {
|
||||
roStatus = engine2.FlagTrue
|
||||
roStatus = engine.FlagTrue
|
||||
}
|
||||
req := engine2.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID,
|
||||
Flag: engine2.Blocked, Update: roStatus, TTL: ttl}
|
||||
req := engine.FlagRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID,
|
||||
Flag: engine.Blocked, Update: roStatus, TTL: ttl}
|
||||
_, err := s.Engine.Flag(req)
|
||||
return err
|
||||
}
|
||||
|
||||
// Blocked returns list with all blocked users
|
||||
func (s *DataStore) Blocked(siteID string) (res []store.BlockedUser, err error) {
|
||||
blocked, e := s.Engine.ListFlags(siteID, engine2.Blocked)
|
||||
blocked, e := s.Engine.ListFlags(siteID, engine.Blocked)
|
||||
if e != nil {
|
||||
return nil, errors.Wrapf(err, "can't get list of blocked users for %s", siteID)
|
||||
}
|
||||
@@ -536,7 +535,7 @@ func (s *DataStore) Blocked(siteID string) (res []store.BlockedUser, err error)
|
||||
|
||||
// Info get post info
|
||||
func (s *DataStore) Info(locator store.Locator, readonlyAge int) (store.PostInfo, error) {
|
||||
req := engine2.InfoRequest{Locator: locator, ReadOnlyAge: readonlyAge}
|
||||
req := engine.InfoRequest{Locator: locator, ReadOnlyAge: readonlyAge}
|
||||
res, err := s.Engine.Info(req)
|
||||
if err != nil {
|
||||
return store.PostInfo{}, err
|
||||
@@ -549,25 +548,25 @@ func (s *DataStore) Info(locator store.Locator, readonlyAge int) (store.PostInfo
|
||||
|
||||
// Delete comment by id
|
||||
func (s *DataStore) Delete(locator store.Locator, commentID string, mode store.DeleteMode) error {
|
||||
req := engine2.DeleteRequest{Locator: locator, CommentID: commentID, DeleteMode: mode}
|
||||
req := engine.DeleteRequest{Locator: locator, CommentID: commentID, DeleteMode: mode}
|
||||
return s.Engine.Delete(req)
|
||||
}
|
||||
|
||||
// DeleteUser removes all comments from user
|
||||
func (s *DataStore) DeleteUser(siteID string, userID string) error {
|
||||
req := engine2.DeleteRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, DeleteMode: store.HardDelete}
|
||||
req := engine.DeleteRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, DeleteMode: store.HardDelete}
|
||||
return s.Engine.Delete(req)
|
||||
}
|
||||
|
||||
// List of commented posts
|
||||
func (s *DataStore) List(siteID string, limit int, skip int) ([]store.PostInfo, error) {
|
||||
req := engine2.InfoRequest{Locator: store.Locator{SiteID: siteID}, Limit: limit, Skip: skip}
|
||||
req := engine.InfoRequest{Locator: store.Locator{SiteID: siteID}, Limit: limit, Skip: skip}
|
||||
return s.Engine.Info(req)
|
||||
}
|
||||
|
||||
// Count gets number of comments for the post
|
||||
func (s *DataStore) Count(locator store.Locator) (int, error) {
|
||||
req := engine2.FindRequest{Locator: locator}
|
||||
req := engine.FindRequest{Locator: locator}
|
||||
return s.Engine.Count(req)
|
||||
}
|
||||
|
||||
@@ -577,7 +576,7 @@ func (s *DataStore) Metas(siteID string) (umetas []UserMetaData, pmetas []PostMe
|
||||
pmetas = []PostMetaData{}
|
||||
|
||||
// set posts meta
|
||||
posts, err := s.Engine.Info(engine2.InfoRequest{Locator: store.Locator{SiteID: siteID}})
|
||||
posts, err := s.Engine.Info(engine.InfoRequest{Locator: store.Locator{SiteID: siteID}})
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "can't get list of posts for %s", siteID)
|
||||
}
|
||||
@@ -607,7 +606,7 @@ func (s *DataStore) Metas(siteID string) (umetas []UserMetaData, pmetas []PostMe
|
||||
}
|
||||
|
||||
// process verified users
|
||||
verified, err := s.Engine.ListFlags(siteID, engine2.Verified)
|
||||
verified, err := s.Engine.ListFlags(siteID, engine.Verified)
|
||||
if err != nil {
|
||||
return nil, nil, errors.Wrapf(err, "can't get list of verified users for %s", siteID)
|
||||
}
|
||||
@@ -655,7 +654,7 @@ func (s *DataStore) SetMetas(siteID string, umetas []UserMetaData, pmetas []Post
|
||||
|
||||
// User gets comment for given userID on siteID
|
||||
func (s *DataStore) User(siteID, userID string, limit, skip int, user store.User) ([]store.Comment, error) {
|
||||
req := engine2.FindRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Limit: limit, Skip: skip}
|
||||
req := engine.FindRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID, Limit: limit, Skip: skip}
|
||||
comments, err := s.Engine.Find(req)
|
||||
if err != nil {
|
||||
return comments, err
|
||||
@@ -665,13 +664,13 @@ func (s *DataStore) User(siteID, userID string, limit, skip int, user store.User
|
||||
|
||||
// UserCount is comments count by user
|
||||
func (s *DataStore) UserCount(siteID, userID string) (int, error) {
|
||||
req := engine2.FindRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID}
|
||||
req := engine.FindRequest{Locator: store.Locator{SiteID: siteID}, UserID: userID}
|
||||
return s.Engine.Count(req)
|
||||
}
|
||||
|
||||
// Last gets last comments for site, cross-post. Limited by count and optional since ts
|
||||
func (s *DataStore) Last(siteID string, limit int, since time.Time, user store.User) ([]store.Comment, error) {
|
||||
req := engine2.FindRequest{Locator: store.Locator{SiteID: siteID}, Limit: limit, Since: since, Sort: "-time"}
|
||||
req := engine.FindRequest{Locator: store.Locator{SiteID: siteID}, Limit: limit, Since: since, Sort: "-time"}
|
||||
comments, err := s.Engine.Find(req)
|
||||
if err != nil {
|
||||
return comments, err
|
||||
@@ -720,7 +719,7 @@ func (s *DataStore) alterComments(cc []store.Comment, user store.User) (res []st
|
||||
|
||||
func (s *DataStore) alterComment(c store.Comment, user store.User) (res store.Comment) {
|
||||
|
||||
blocReq := engine2.FlagRequest{Flag: engine2.Blocked, Locator: store.Locator{SiteID: c.Locator.SiteID}, UserID: c.User.ID}
|
||||
blocReq := engine.FlagRequest{Flag: engine.Blocked, Locator: store.Locator{SiteID: c.Locator.SiteID}, UserID: c.User.ID}
|
||||
blocked, _ := s.Engine.Flag(blocReq)
|
||||
|
||||
// process blocked users
|
||||
@@ -734,7 +733,7 @@ func (s *DataStore) alterComment(c store.Comment, user store.User) (res store.Co
|
||||
|
||||
// set verified status retroactively
|
||||
if !blocked {
|
||||
verifReq := engine2.FlagRequest{Flag: engine2.Verified, Locator: store.Locator{SiteID: c.Locator.SiteID}, UserID: c.User.ID}
|
||||
verifReq := engine.FlagRequest{Flag: engine.Verified, Locator: store.Locator{SiteID: c.Locator.SiteID}, UserID: c.User.ID}
|
||||
c.User.Verified, _ = s.Engine.Flag(verifReq)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import (
|
||||
|
||||
"github.com/umputun/remark/backend/app/store"
|
||||
"github.com/umputun/remark/backend/app/store/admin"
|
||||
"github.com/umputun/remark/backend/app/store/engine2"
|
||||
"github.com/umputun/remark/backend/app/store/engine"
|
||||
"github.com/umputun/remark/backend/app/store/image"
|
||||
)
|
||||
|
||||
@@ -1015,9 +1015,9 @@ func TestService_submitImages(t *testing.T) {
|
||||
func TestService_alterComment(t *testing.T) {
|
||||
defer teardown(t)
|
||||
|
||||
engineMock := engine2.MockInterface{}
|
||||
engineMock.On("Flag", engine2.FlagRequest{Flag: engine2.Blocked, UserID: "devid"}).Return(false, nil)
|
||||
engineMock.On("Flag", engine2.FlagRequest{Flag: engine2.Verified, UserID: "devid"}).Return(false, nil)
|
||||
engineMock := engine.MockInterface{}
|
||||
engineMock.On("Flag", engine.FlagRequest{Flag: engine.Blocked, UserID: "devid"}).Return(false, nil)
|
||||
engineMock.On("Flag", engine.FlagRequest{Flag: engine.Verified, UserID: "devid"}).Return(false, nil)
|
||||
svc := DataStore{Engine: &engineMock}
|
||||
|
||||
r := svc.alterComment(store.Comment{ID: "123", User: store.User{IP: "127.0.0.1", ID: "devid"}},
|
||||
@@ -1027,17 +1027,17 @@ func TestService_alterComment(t *testing.T) {
|
||||
store.User{Name: "dev", ID: "devid", Admin: true})
|
||||
assert.Equal(t, store.Comment{ID: "123", User: store.User{IP: "127.0.0.1", ID: "devid"}}, r, "ip not cleaned")
|
||||
|
||||
engineMock = engine2.MockInterface{}
|
||||
engineMock.On("Flag", engine2.FlagRequest{Flag: engine2.Blocked, UserID: "devid"}).Return(false, nil)
|
||||
engineMock.On("Flag", engine2.FlagRequest{Flag: engine2.Verified, UserID: "devid"}).Return(true, nil)
|
||||
engineMock = engine.MockInterface{}
|
||||
engineMock.On("Flag", engine.FlagRequest{Flag: engine.Blocked, UserID: "devid"}).Return(false, nil)
|
||||
engineMock.On("Flag", engine.FlagRequest{Flag: engine.Verified, UserID: "devid"}).Return(true, nil)
|
||||
svc = DataStore{Engine: &engineMock}
|
||||
r = svc.alterComment(store.Comment{ID: "123", User: store.User{IP: "127.0.0.1", ID: "devid", Verified: true}},
|
||||
store.User{Name: "dev", ID: "devid", Admin: false})
|
||||
assert.Equal(t, store.Comment{ID: "123", User: store.User{IP: "", ID: "devid", Verified: true}}, r, "verified set")
|
||||
|
||||
engineMock = engine2.MockInterface{}
|
||||
engineMock.On("Flag", engine2.FlagRequest{Flag: engine2.Blocked, UserID: "devid"}).Return(true, nil)
|
||||
engineMock.On("Flag", engine2.FlagRequest{Flag: engine2.Verified, UserID: "devid"}).Return(false, nil)
|
||||
engineMock = engine.MockInterface{}
|
||||
engineMock.On("Flag", engine.FlagRequest{Flag: engine.Blocked, UserID: "devid"}).Return(true, nil)
|
||||
engineMock.On("Flag", engine.FlagRequest{Flag: engine.Verified, UserID: "devid"}).Return(false, nil)
|
||||
svc = DataStore{Engine: &engineMock}
|
||||
r = svc.alterComment(store.Comment{ID: "123", User: store.User{IP: "127.0.0.1", ID: "devid", Verified: true}},
|
||||
store.User{Name: "dev", ID: "devid", Admin: false})
|
||||
@@ -1046,10 +1046,10 @@ func TestService_alterComment(t *testing.T) {
|
||||
}
|
||||
|
||||
// makes new boltdb, put two records
|
||||
func prepStoreEngine(t *testing.T) engine2.Interface {
|
||||
func prepStoreEngine(t *testing.T) engine.Interface {
|
||||
_ = os.Remove(testDb)
|
||||
|
||||
boltStore, err := engine2.NewBoltDB(bolt.Options{}, engine2.BoltSite{FileName: "/tmp/test-remark.db", SiteID: "radio-t"})
|
||||
boltStore, err := engine.NewBoltDB(bolt.Options{}, engine.BoltSite{FileName: "/tmp/test-remark.db", SiteID: "radio-t"})
|
||||
assert.NoError(t, err)
|
||||
b := boltStore
|
||||
|
||||
|
||||
Reference in New Issue
Block a user