@@ -2,22 +2,17 @@ package datastore
2
2
3
3
import (
4
4
"database/sql"
5
- "errors"
6
5
"io"
7
6
"net"
8
7
"net/url"
9
- "strconv"
10
8
"strings"
11
9
"time"
12
10
13
11
_ "gopkg.in/mattes/migrate.v1/driver/postgres" //for migrations
14
12
"gopkg.in/mattes/migrate.v1/migrate"
15
13
16
14
dat "github.com/nerdynz/dat/dat"
17
- "github.com/nerdynz/dat/kvs"
18
15
runner "github.com/nerdynz/dat/sqlx-runner"
19
- "github.com/nerdynz/trove"
20
- "github.com/shomali11/xredis"
21
16
)
22
17
23
18
type Websocket interface {
@@ -43,7 +38,7 @@ type Logger interface {
43
38
44
39
type Datastore struct {
45
40
DB * runner.DB
46
- Cache * Cache
41
+ Cache Cache
47
42
Settings Settings
48
43
Websocket Websocket
49
44
Logger Logger
@@ -57,6 +52,16 @@ type Settings interface {
57
52
IsDevelopment () bool
58
53
}
59
54
55
+ type Cache interface {
56
+ Set (key string , value string , duration time.Duration ) error
57
+ Get (key string ) (string , error )
58
+ Expire (key string ) error
59
+ Del (key string ) error
60
+ GetBytes (key string ) ([]byte , error )
61
+ SetBytes (key string , value []byte , duration time.Duration ) error
62
+ FlushDB () error
63
+ }
64
+
60
65
func (ds * Datastore ) TurnOnLogging () {
61
66
dat .SetDebugLogger (ds .Logger .Warnf )
62
67
dat .SetSQLLogger (ds .Logger .Infof )
@@ -112,50 +117,26 @@ func (ds *Datastore) TurnOffLogging() {
112
117
113
118
// New - returns a new datastore which contains redis, database and settings.
114
119
// everything in the datastore should be concurrent safe and stand within thier own right. i.e. accessible at anypoint from the app
115
- func New (logger Logger , ws Websocket ) * Datastore {
120
+ func New (logger Logger , settings Settings , cache Cache , ws Websocket ) * Datastore {
116
121
store := Simple ()
117
122
store .Logger = logger
118
-
119
- logger .Info ("Current IP Addresses" )
120
- ifaces , err := net .Interfaces ()
121
- if err != nil {
122
- logger .Error ("Failed to load interfaces" , err )
123
- }
124
- for _ , i := range ifaces {
125
- addrs , err := i .Addrs ()
126
- if err != nil {
127
- logger .Error ("Failed to load addresses" , err )
128
- }
129
- // handle err
130
- for _ , addr := range addrs {
131
- var ip net.IP
132
- switch v := addr .(type ) {
133
- case * net.IPNet :
134
- ip = v .IP
135
- case * net.IPAddr :
136
- ip = v .IP
137
- }
138
- logger .Info ("ip: " , ip .String ())
139
- }
140
- }
141
-
142
- store .Cache = getCache (store )
143
- store .DB = getDBConnection (store )
123
+ store .Settings = settings
124
+ store .DB = getDBConnection (store , cache )
125
+ store .Cache = cache
144
126
return store
145
127
}
146
128
147
129
func (ds * Datastore ) Cleanup () {
148
130
ds .DB .DB .Close ()
149
- ds .Cache .Client .Close ()
131
+ // ds.Cache.Client.Close()
150
132
}
151
133
152
134
func Simple () * Datastore {
153
135
store := & Datastore {}
154
- store .Settings = trove .Load ()
155
136
return store
156
137
}
157
138
158
- func getDBConnection (store * Datastore ) * runner.DB {
139
+ func getDBConnection (store * Datastore , cache Cache ) * runner.DB {
159
140
//get url from ENV in the following format postgres://user:[email protected] :5432/spaceio")
160
141
dbURL := store .Settings .Get ("DATABASE_URL" )
161
142
u , err := url .Parse (dbURL )
@@ -172,8 +153,8 @@ func getDBConnection(store *Datastore) *runner.DB {
172
153
dbName := strings .Replace (u .Path , "/" , "" , 1 )
173
154
174
155
if host == "GCLOUD_SQL_INSTANCE" {
175
- // USE THE GCLOUD_SQL_INSTANCE SETTING instead... e.g. host= /cloudsql/INSTANCE_CONNECTION_NAME // JC I wonder if it is always /cloudsql
176
- host = "/cloudsql" + store .Settings .Get ("GCLOUD_SQL_INSTANCE" )
156
+ // USE THE GCLOUD_SQL_INSTANCE SETTING instead... e.g. host= /cloudsql/INSTANCE_CONNECTION_NAME
157
+ host = store .Settings .Get ("GCLOUD_SQL_INSTANCE" )
177
158
}
178
159
179
160
dbStr := "dbname=" + dbName + " user=" + username + " host=" + host
@@ -192,17 +173,20 @@ func getDBConnection(store *Datastore) *runner.DB {
192
173
// ensures the database can be pinged with an exponential backoff (15 min)
193
174
runner .MustPing (db )
194
175
195
- if store .Settings .Get ("CACHE_NAMESPACE" ) != "" {
196
- redisUrl := ":6379"
197
- if store .Settings .Get ("CACHE_URL" ) != "" {
198
- redisUrl = store .Settings .Get ("CACHE_URL" )
199
- }
200
- cache , err := kvs .NewRedisStore (store .Settings .Get ("CACHE_NAMESPACE" ), redisUrl , "" )
201
- if err != nil {
202
- store .Logger .Error (err )
203
- panic (err )
204
- }
205
- store .Logger .Info ("USING CACHE" , store .Settings .Get ("CACHE_NAMESPACE" ))
176
+ // if store.Settings.Get("CACHE_NAMESPACE") != "" {
177
+ // redisUrl := ":6379"
178
+ // if store.Settings.Get("CACHE_URL") != "" {
179
+ // redisUrl = store.Settings.Get("CACHE_URL")
180
+ // }
181
+ // cache, err := kvs.NewRedisStore(store.Settings.Get("CACHE_NAMESPACE"), redisUrl, "")
182
+ // if err != nil {
183
+ // store.Logger.Error(err)
184
+ // panic(err)
185
+ // }
186
+ // store.Logger.Info("USING CACHE", store.Settings.Get("CACHE_NAMESPACE"))
187
+ // runner.SetCache(cache)
188
+ // }
189
+ if cache != nil {
206
190
runner .SetCache (cache )
207
191
}
208
192
@@ -236,94 +220,3 @@ func getDBConnection(store *Datastore) *runner.DB {
236
220
// db connection
237
221
return runner .NewDB (db , "postgres" )
238
222
}
239
-
240
- func getCache (store * Datastore ) * Cache {
241
- opts := & xredis.Options {
242
- Host : "localhost" ,
243
- Port : 6379 ,
244
- Password : "" , // no password set
245
- // DB: 0, // use default DB
246
- }
247
-
248
- redisURL := store .Settings .Get ("CACHE_URL" )
249
- if redisURL != "" {
250
- opts = & xredis.Options {}
251
- u , err := url .Parse (redisURL )
252
- if err != nil {
253
- store .Logger .Error (err )
254
- return nil
255
- }
256
- opts .Host = u .Host
257
- if strings .Contains (opts .Host , ":" ) {
258
- opts .Host = strings .Split (opts .Host , ":" )[0 ]
259
- }
260
- p , _ := u .User .Password ()
261
- opts .Password = p
262
- // opts.User = u.User.Username()
263
- port , err := strconv .Atoi (u .Port ())
264
- if err != nil {
265
- store .Logger .Error ("cache couldn't parse port" )
266
- return nil
267
- }
268
- opts .Port = port
269
- }
270
-
271
- client := xredis .SetupClient (opts )
272
- pong , err := client .Ping ()
273
- if err != nil {
274
- store .Logger .Error (err )
275
- return nil
276
- }
277
-
278
- store .Logger .Info ("cache running" , pong )
279
- return & Cache {
280
- Client : client ,
281
- }
282
- }
283
-
284
- type Cache struct {
285
- Client * xredis.Client
286
- }
287
-
288
- func (cache * Cache ) Get (key string ) (string , bool , error ) {
289
- val , ok , err := cache .Client .Get (key )
290
- if val == "" {
291
- return "" , false , errors .New ("no value for [" + key + "]" )
292
- }
293
- return val , ok , err
294
- }
295
-
296
- func (cache * Cache ) Expire (key string ) (bool , error ) {
297
- ok , err := cache .Client .Expire (key , 1 )
298
- return ok , err
299
- }
300
-
301
- func (cache * Cache ) GetBytes (key string ) ([]byte , bool , error ) {
302
- val , ok , err := cache .Get (key )
303
- if ok {
304
- return []byte (val ), ok , err
305
- }
306
-
307
- if err == nil && ! ok {
308
- return nil , false , errors .New ("Not Found" )
309
- }
310
-
311
- return nil , ok , err
312
- }
313
-
314
- func (cache * Cache ) Set (key string , value string , duration time.Duration ) (bool , error ) {
315
- secs := int64 (duration / time .Second )
316
- ok , err := cache .Client .SetEx (key , value , secs )
317
- if ! ok {
318
- if strings .Contains (err .Error (), "invalid expire time in set" ) {
319
- return ok , errors .New ("Invalid expire timeout in seconds [" + strconv .Itoa (int (secs )) + "]" )
320
- }
321
- }
322
- return ok , err
323
- }
324
-
325
- func (cache * Cache ) SetBytes (key string , value []byte , duration time.Duration ) (bool , error ) {
326
- result := string (value [:])
327
- val , err := cache .Set (key , result , duration )
328
- return val , err
329
- }
0 commit comments