forked from ortuman/jackal
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstorage.go
126 lines (103 loc) · 3.2 KB
/
storage.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
* Copyright (c) 2018 Miguel Ángel Ortuño.
* See the LICENSE file for more information.
*/
package storage
import (
"errors"
"sync"
"sync/atomic"
"github.com/ortuman/jackal/bufferpool"
"github.com/ortuman/jackal/config"
"github.com/ortuman/jackal/log"
"github.com/ortuman/jackal/storage/model"
"github.com/ortuman/jackal/xml"
)
var pool = bufferpool.New()
// ErrMockedError represents a storage mocked error value.
var ErrMockedError = errors.New("storage mocked error")
// Storage represents an entity storage interface.
type Storage interface {
Shutdown()
InsertOrUpdateUser(user *model.User) error
DeleteUser(username string) error
FetchUser(username string) (*model.User, error)
UserExists(username string) (bool, error)
InsertOrUpdateRosterItem(ri *model.RosterItem) error
DeleteRosterItem(user, contact string) error
FetchRosterItems(user string) ([]model.RosterItem, error)
FetchRosterItem(user, contact string) (*model.RosterItem, error)
InsertOrUpdateRosterNotification(rn *model.RosterNotification) error
DeleteRosterNotification(user, contact string) error
FetchRosterNotifications(contact string) ([]model.RosterNotification, error)
InsertOrUpdateVCard(vCard xml.Element, username string) error
FetchVCard(username string) (xml.Element, error)
FetchPrivateXML(namespace string, username string) ([]xml.Element, error)
InsertOrUpdatePrivateXML(privateXML []xml.Element, namespace string, username string) error
InsertOfflineMessage(message xml.Element, username string) error
CountOfflineMessages(username string) (int, error)
FetchOfflineMessages(username string) ([]xml.Element, error)
DeleteOfflineMessages(username string) error
}
var (
inst Storage
instMu sync.RWMutex
initialized uint32
)
// Initialize initializes storage sub system.
func Initialize(storageConfig *config.Storage) {
if atomic.CompareAndSwapUint32(&initialized, 0, 1) {
instMu.Lock()
defer instMu.Unlock()
switch storageConfig.Type {
case config.BadgerDB:
inst = newBadgerDB(storageConfig.BadgerDB)
case config.MySQL:
inst = newMySQLStorage(storageConfig.MySQL)
case config.Mock:
inst = newMockStorage()
default:
// should not be reached
break
}
}
}
// Instance returns global storage sub system.
func Instance() Storage {
instMu.RLock()
defer instMu.RUnlock()
if inst == nil {
log.Fatalf("storage subsystem not initialized")
}
return inst
}
// Shutdown shuts down storage sub system.
// This method should be used only for testing purposes.
func Shutdown() {
if atomic.CompareAndSwapUint32(&initialized, 1, 0) {
instMu.Lock()
defer instMu.Unlock()
inst.Shutdown()
inst = nil
}
}
// ActivateMockedError forces the return of ErrMockedError from current storage manager.
// This method should only be used for testing purposes.
func ActivateMockedError() {
instMu.Lock()
defer instMu.Unlock()
switch inst := inst.(type) {
case *mockStorage:
inst.activateMockedError()
}
}
// DeactivateMockedError disables mocked storage error from a previous activation.
// This method should only be used for testing purposes.
func DeactivateMockedError() {
instMu.Lock()
defer instMu.Unlock()
switch inst := inst.(type) {
case *mockStorage:
inst.deactivateMockedError()
}
}