1
// Copyright 2016 Canonical Ltd.
2
// Licensed under the AGPLv3, see LICENCE file for details.
7
"github.com/juju/errors"
9
"github.com/juju/juju/mongo"
12
// modelBackend collects together some useful internal state methods for
13
// accessing mongo and mapping local and global ids to one another.
15
// Its primary purpose is to insulate watcher implementations from the
16
// other features of state (specifically, to deny access to the .workers
17
// field and prevent a class of bug in which it tries to use two
18
// different underlying TxnWatchers), but it's probably also useful
20
type modelBackend interface {
22
localID(string) string
23
strictLocalID(string) (string, error)
24
getCollection(name string) (mongo.Collection, func())
27
// isLocalID returns a watcher filter func that rejects ids not specific
28
// to the supplied modelBackend.
29
func isLocalID(st modelBackend) func(interface{}) bool {
30
return func(id interface{}) bool {
31
key, ok := id.(string)
35
_, err := st.strictLocalID(key)
40
// docID generates a globally unique id value
41
// where the model uuid is prefixed to the
43
func (st *State) docID(localID string) string {
44
return ensureModelUUID(st.ModelUUID(), localID)
47
// localID returns the local id value by stripping
48
// off the model uuid prefix if it is there.
49
func (st *State) localID(ID string) string {
50
modelUUID, localID, ok := splitDocID(ID)
51
if !ok || modelUUID != st.ModelUUID() {
57
// strictLocalID returns the local id value by removing the
60
// If there is no prefix matching the State's model, an error is
62
func (st *State) strictLocalID(ID string) (string, error) {
63
modelUUID, localID, ok := splitDocID(ID)
64
if !ok || modelUUID != st.ModelUUID() {
65
return "", errors.Errorf("unexpected id: %#v", ID)
70
// getCollection fetches a named collection using a new session if the
71
// database has previously been logged in to. It returns the
72
// collection and a closer function for the session.
74
// If the collection stores documents for multiple models, the
75
// returned collection will automatically perform model
76
// filtering where possible. See modelStateCollection below.
77
func (st *State) getCollection(name string) (mongo.Collection, func()) {
78
return st.database.GetCollection(name)