/
store.go
111 lines (96 loc) · 2.73 KB
/
store.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
// Copyright © 2017 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.
package device
import (
"fmt"
"time"
"github.com/TheThingsNetwork/ttn/core/storage"
"github.com/TheThingsNetwork/ttn/utils/errors"
"gopkg.in/redis.v5"
)
// Store interface for Devices
type Store interface {
List() ([]*Device, error)
ListForApp(appID string) ([]*Device, error)
Get(appID, devID string) (*Device, error)
Set(new *Device, properties ...string) (err error)
Delete(appID, devID string) error
}
const defaultRedisPrefix = "handler"
const redisDevicePrefix = "device"
// NewRedisDeviceStore creates a new Redis-based Device store
func NewRedisDeviceStore(client *redis.Client, prefix string) *RedisDeviceStore {
if prefix == "" {
prefix = defaultRedisPrefix
}
store := storage.NewRedisMapStore(client, prefix+":"+redisDevicePrefix)
store.SetBase(Device{}, "")
return &RedisDeviceStore{
store: store,
}
}
// RedisDeviceStore stores Devices in Redis.
// - Devices are stored as a Hash
type RedisDeviceStore struct {
store *storage.RedisMapStore
}
// List all Devices
func (s *RedisDeviceStore) List() ([]*Device, error) {
devicesI, err := s.store.List("", nil)
if err != nil {
return nil, err
}
devices := make([]*Device, 0, len(devicesI))
for _, deviceI := range devicesI {
if device, ok := deviceI.(Device); ok {
devices = append(devices, &device)
}
}
return devices, nil
}
// ListForApp lists all devices for a specific Application
func (s *RedisDeviceStore) ListForApp(appID string) ([]*Device, error) {
devicesI, err := s.store.List(fmt.Sprintf("%s:*", appID), nil)
if err != nil {
return nil, err
}
devices := make([]*Device, 0, len(devicesI))
for _, deviceI := range devicesI {
if device, ok := deviceI.(Device); ok {
devices = append(devices, &device)
}
}
return devices, nil
}
// Get a specific Device
func (s *RedisDeviceStore) Get(appID, devID string) (*Device, error) {
deviceI, err := s.store.Get(fmt.Sprintf("%s:%s", appID, devID))
if err != nil {
return nil, err
}
if device, ok := deviceI.(Device); ok {
return &device, nil
}
return nil, errors.New("Database did not return a Device")
}
// Set a new Device or update an existing one
func (s *RedisDeviceStore) Set(new *Device, properties ...string) (err error) {
now := time.Now()
new.UpdatedAt = now
key := fmt.Sprintf("%s:%s", new.AppID, new.DevID)
if new.old != nil {
err = s.store.Update(key, *new, properties...)
} else {
new.CreatedAt = now
err = s.store.Create(key, *new, properties...)
}
if err != nil {
return
}
return nil
}
// Delete a Device
func (s *RedisDeviceStore) Delete(appID, devID string) error {
key := fmt.Sprintf("%s:%s", appID, devID)
return s.store.Delete(key)
}