-
Notifications
You must be signed in to change notification settings - Fork 0
/
datastore_insert.go
105 lines (96 loc) · 2.9 KB
/
datastore_insert.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package dalgo2datastore
import (
"cloud.google.com/go/datastore"
"context"
"errors"
"fmt"
"github.com/dal-go/dalgo/dal"
"github.com/strongo/log"
)
type inserter = func(key *datastore.Key, isPartialKey bool, dst interface{}) error
type exister = func(key *datastore.Key) error
func (tx transaction) Insert(c context.Context, record dal.Record, opts ...dal.InsertOption) error {
var inserter = func(key *datastore.Key, isPartialKey bool, dst interface{}) (err error) {
var pendingKey *datastore.PendingKey
pendingKey, err = tx.datastoreTx.Put(key, dst)
if err != nil {
return err
}
if isPartialKey && pendingKey != nil {
tx.pendingKeys = append(tx.pendingKeys, partialKey{record.Key(), pendingKey})
}
return nil
}
var exister = func(key *datastore.Key) error {
return tx.datastoreTx.Get(key, nil)
}
return insert(c, record, inserter, exister, dal.NewInsertOptions(opts...))
}
func (db database) Insert(c context.Context, record dal.Record, opts ...dal.InsertOption) error {
if record == nil {
panic("record == nil")
}
recordKey := record.Key()
kind := recordKey.Collection()
log.Debugf(c, "Insert(kind=%v)", kind)
data := record.Data()
if data == nil {
return errors.New("not allowed to insert nil data")
}
options := dal.NewInsertOptions(opts...)
var inserter = func(key *datastore.Key, isPartialKey bool, dst interface{}) (err error) {
if key, err = db.client.Put(c, key, dst); err != nil {
return err
}
updatePartialKey(record.Key(), key)
return nil
}
var exister = func(key *datastore.Key) error {
return db.client.Get(c, key, nil)
}
return insert(c, record, inserter, exister, options)
}
func updatePartialKey(key *dal.Key, dsKey *datastore.Key) {
key.ID = dsKey.ID
}
func insert(ctx context.Context, record dal.Record, insert inserter, exists exister, options dal.InsertOptions) error {
if record == nil {
panic("record == nil")
}
recordKey := record.Key()
kind := recordKey.Collection()
record.SetError(nil)
entity := record.Data()
if entity == nil {
panic("record == nil")
}
wrapErr := func(err error) error {
return fmt.Errorf("failed to create record with random str ID for [%s]: %w", kind, err)
}
key, isPartial, err := getDatastoreKey(recordKey)
if err != nil {
return wrapErr(err)
}
if isPartial {
if idGenerator := options.IDGenerator(); idGenerator != nil {
recordExists := func(key *dal.Key) error {
k, _, err := getDatastoreKey(key)
if err != nil {
return err
}
if err := exists(k); err == datastore.ErrNoSuchEntity {
return dal.ErrRecordNotFound
} else {
return err
}
}
insertRandom := func(record dal.Record) error {
return insert(key, false, record.Data())
}
return dal.InsertWithRandomID(ctx, record, idGenerator, 5, recordExists, insertRandom)
}
panic(fmt.Sprintf("database.insert() called for key with incomplete ID: %+v", key))
}
err = insert(key, isPartial, record.Data())
return err
}