Skip to content

Commit d9e39ce

Browse files
author
Miguel Molina
authored
Merge pull request #127 from erizocosmico/feature/store-from
implement StoreFrom function to transmute stores
2 parents d558b78 + 6ce6cf5 commit d9e39ce

File tree

5 files changed

+321
-16
lines changed

5 files changed

+321
-16
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,11 +572,12 @@ store.Transaction(func(s *UserStore) error {
572572
})
573573
```
574574

575-
The fact that a transaction receives a store with the type of the model can be a problem if you want to store several models of different types. You can, indeed, create new stores of the other types, but do so with care. Do not use the internal `*kallax.Store`, as it does not perform any type checks or some of the operations the concrete type stores do.
575+
The fact that a transaction receives a store with the type of the model can be a problem if you want to store several models of different types. Kallax has a method named `StoreFrom` that initializes a store of the type you want to have the same underlying store as some other.
576576

577577
```go
578578
store.Transaction(func(s *UserStore) error {
579-
postStore := &PostStore{s.Store}
579+
var postStore PostStore
580+
kallax.StoreFrom(&postStore, s)
580581

581582
for _, p := range posts {
582583
if err := postStore.Insert(p); err != nil {

generator/templates/model.tgo

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ func New{{.StoreName}}(db *sql.DB) *{{.StoreName}} {
9696
return &{{.StoreName}}{kallax.NewStore(db)}
9797
}
9898

99+
// GenericStore returns the generic store of this store.
100+
func (s *{{.StoreName}}) GenericStore() *kallax.Store {
101+
return s.Store
102+
}
103+
104+
// SetGenericStore changes the generic store of this store.
105+
func (s *{{.StoreName}}) SetGenericStore(store *kallax.Store) {
106+
s.Store = store
107+
}
108+
99109
{{if .HasNonInverses}}
100110
func (s *{{.StoreName}}) relationshipRecords(record *{{.Name}}) []kallax.RecordWithSchema {
101111
var records []kallax.RecordWithSchema

store.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ var (
3333
ErrCantSetID = errors.New("kallax: model does not have an auto incrementable primary key, it needs to implement IDSetter interface")
3434
)
3535

36+
// GenericStorer is a type that contains a generic store and has methods to
37+
// retrieve it and set it.
38+
type GenericStorer interface {
39+
// GenericStore returns the generic store in this type.
40+
GenericStore() *Store
41+
// SetGenericStore sets the generic store for this type.
42+
SetGenericStore(*Store)
43+
}
44+
45+
// StoreFrom sets the generic store of `from` in `to`.
46+
func StoreFrom(to, from GenericStorer) {
47+
if to == nil || from == nil {
48+
return
49+
}
50+
51+
to.SetGenericStore(from.GenericStore())
52+
}
53+
3654
// Store is a structure capable of retrieving records from a concrete table in
3755
// the database.
3856
type Store struct {

store_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"testing"
77

88
_ "github.com/lib/pq"
9+
"github.com/stretchr/testify/require"
910
"github.com/stretchr/testify/suite"
1011
)
1112

@@ -526,3 +527,26 @@ func (s *StoreSuite) assertNotExists(m *model) {
526527
func TestStore(t *testing.T) {
527528
suite.Run(t, new(StoreSuite))
528529
}
530+
531+
type store1 struct {
532+
*Store
533+
}
534+
535+
func (s *store1) GenericStore() *Store {
536+
return s.Store
537+
}
538+
539+
func (s *store1) SetGenericStore(store *Store) {
540+
s.Store = store
541+
}
542+
543+
func TestStoreFrom(t *testing.T) {
544+
var s1 = &store1{new(Store)}
545+
var s2 store1
546+
547+
require := require.New(t)
548+
require.NotEqual(s1.Store, s2.Store)
549+
550+
StoreFrom(&s2, s1)
551+
require.Exactly(s1.Store, s2.Store)
552+
}

0 commit comments

Comments
 (0)