@@ -308,21 +308,34 @@ func GetGatewaysForMACs(db *sqlx.DB, macs []lorawan.EUI64) (map[lorawan.EUI64]Ga
308
308
func GetGatewayStats (db * sqlx.DB , mac lorawan.EUI64 , interval string , start , end time.Time ) ([]Stats , error ) {
309
309
var valid bool
310
310
interval = strings .ToUpper (interval )
311
- zone , _ := start .In (common .TimeLocation ).Zone ()
312
311
312
+ // validate aggregation interval
313
313
for _ , i := range statsAggregationIntervals {
314
314
if i == interval {
315
315
valid = true
316
316
}
317
317
}
318
-
319
318
if ! valid {
320
319
return nil , ErrInvalidAggregationInterval
321
320
}
322
321
323
- var stats []Stats
322
+ tx , err := db .Beginx ()
323
+ if err != nil {
324
+ return nil , errors .Wrap (err , "begin transaction error" )
325
+ }
326
+ defer tx .Rollback ()
327
+
328
+ // set the database timezone for this transaction
329
+ if common .TimeLocation != time .Local {
330
+ // when TimeLocation == time.Local, it would have 'Local' as name
331
+ _ , err = tx .Exec (fmt .Sprintf ("set local time zone '%s'" , common .TimeLocation .String ()))
332
+ if err != nil {
333
+ return nil , errors .Wrap (err , "set timezone error" )
334
+ }
335
+ }
324
336
325
- err := db .Select (& stats , `
337
+ var stats []Stats
338
+ err = tx .Select (& stats , `
326
339
select
327
340
$1::bytea as mac,
328
341
$2 as interval,
@@ -339,20 +352,19 @@ func GetGatewayStats(db *sqlx.DB, mac lorawan.EUI64, interval string, start, end
339
352
where
340
353
mac = $1
341
354
and interval = $2
342
- and "timestamp" >= cast(date_trunc($2, $3 at time zone $4 ) as timestamp) at time zone $4
343
- and "timestamp" < $5 ) gs
355
+ and "timestamp" >= cast(date_trunc($2, $3::timestamptz ) as timestamp with time zone)
356
+ and "timestamp" < $4 ) gs
344
357
right join (
345
358
select generate_series(
346
- cast(date_trunc($2, $3 at time zone $4 ) as timestamp) at time zone $4 ,
347
- $5 ,
348
- $6 ) as "timestamp"
359
+ cast(date_trunc($2, $3) as timestamp with time zone) ,
360
+ $4 ,
361
+ $5 ) as "timestamp"
349
362
) s
350
363
on gs.timestamp = s.timestamp
351
364
order by s.timestamp` ,
352
365
mac [:],
353
366
interval ,
354
367
start ,
355
- zone ,
356
368
end ,
357
369
fmt .Sprintf ("1 %s" , interval ),
358
370
)
@@ -431,9 +443,29 @@ func handleStatsPacket(db *sqlx.DB, stats gw.GatewayStatsPacket) error {
431
443
}
432
444
}
433
445
446
+ comitted := false
447
+ tx , err := db .Beginx ()
448
+ if err != nil {
449
+ return errors .Wrap (err , "begin transaction error" )
450
+ }
451
+ defer func () {
452
+ if ! comitted {
453
+ tx .Rollback ()
454
+ }
455
+ }()
456
+
457
+ // set the database timezone for this transaction
458
+ if common .TimeLocation != time .Local {
459
+ // when TimeLocation == time.Local, it would have 'Local' as name
460
+ _ , err = tx .Exec (fmt .Sprintf ("set local time zone '%s'" , common .TimeLocation .String ()))
461
+ if err != nil {
462
+ return errors .Wrap (err , "set timezone error" )
463
+ }
464
+ }
465
+
434
466
// store the stats
435
467
for _ , aggr := range statsAggregationIntervals {
436
- if err := aggregateGatewayStats (db , Stats {
468
+ if err := aggregateGatewayStats (tx , Stats {
437
469
MAC : stats .MAC ,
438
470
Timestamp : stats .Time ,
439
471
Interval : aggr ,
@@ -446,12 +478,14 @@ func handleStatsPacket(db *sqlx.DB, stats gw.GatewayStatsPacket) error {
446
478
}
447
479
}
448
480
481
+ if err := tx .Commit (); err != nil {
482
+ return errors .Wrap (err , "commit error" )
483
+ }
484
+ comitted = true
449
485
return nil
450
486
}
451
487
452
- func aggregateGatewayStats (db * sqlx.DB , stats Stats ) error {
453
- zone , _ := stats .Timestamp .In (common .TimeLocation ).Zone ()
454
-
488
+ func aggregateGatewayStats (db sqlx.Execer , stats Stats ) error {
455
489
_ , err := db .Exec (`
456
490
insert into gateway_stats (
457
491
mac,
@@ -463,23 +497,22 @@ func aggregateGatewayStats(db *sqlx.DB, stats Stats) error {
463
497
tx_packets_emitted
464
498
) values (
465
499
$1,
466
- cast(date_trunc($2, $3 at time zone $4 ) as timestamp) at time zone $4 ,
500
+ cast(date_trunc($2, $3::timestamptz ) as timestamp with time zone) ,
467
501
$2,
502
+ $4,
468
503
$5,
469
504
$6,
470
- $7,
471
- $8
505
+ $7
472
506
)
473
507
on conflict (mac, "timestamp", "interval")
474
508
do update set
475
- rx_packets_received = gateway_stats.rx_packets_received + $5 ,
476
- rx_packets_received_ok = gateway_stats.rx_packets_received_ok + $6 ,
477
- tx_packets_received = gateway_stats.tx_packets_received + $7 ,
478
- tx_packets_emitted = gateway_stats.tx_packets_emitted + $8 ` ,
509
+ rx_packets_received = gateway_stats.rx_packets_received + $4 ,
510
+ rx_packets_received_ok = gateway_stats.rx_packets_received_ok + $5 ,
511
+ tx_packets_received = gateway_stats.tx_packets_received + $6 ,
512
+ tx_packets_emitted = gateway_stats.tx_packets_emitted + $7 ` ,
479
513
stats .MAC [:],
480
514
stats .Interval ,
481
515
stats .Timestamp ,
482
- zone ,
483
516
stats .RXPacketsReceived ,
484
517
stats .RXPacketsReceivedOK ,
485
518
stats .TXPacketsReceived ,
0 commit comments