Skip to content

Commit 299361c

Browse files
committed
- Refactored date format SQL into enum
- Added ability to track current query model
1 parent d9d1290 commit 299361c

5 files changed

Lines changed: 61 additions & 6 deletions

File tree

src/Contracts/TimeSeriesStatsRepository.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@ interface TimeSeriesStatsRepository extends
1111
InteractsWithFilters,
1212
InteractsWithDateRange
1313
{
14+
/**
15+
* Get which time series mode is being queried with
16+
* Null means total
17+
*/
18+
public function getCurrentMode(): ?TimeSeriesModes;
19+
1420
/**
1521
* Get the stats
1622
*/

src/Enums/TimeSeriesModes.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ public function getInternalDateFormat(): string
6767
};
6868
}
6969

70+
public function getSql(string $date_field): string
71+
{
72+
return match ($this) {
73+
self::HOUR => "DATE_FORMAT($date_field, '%Y-%m-%d %H:00')",
74+
self::DAY => "DATE($date_field)",
75+
self::WEEK => "YEARWEEK($date_field, " . TimeSeriesStats::weekMode() . ")",
76+
self::MONTH => "DATE_FORMAT($date_field, '%Y, %m')",
77+
self::YEAR => "YEAR($date_field)",
78+
};
79+
}
80+
7081
public function increment(Carbon $date): Carbon
7182
{
7283
$date = $date->copy()->locale(TimeSeriesStats::dateLocale());

src/Repositories/TimeSeries/AbstractTimeSeriesStatsRepository.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ abstract class AbstractTimeSeriesStatsRepository implements TimeSeriesStatsRepos
2222
use HasDateRange;
2323
use HasFilters;
2424

25+
protected ?TimeSeriesModes $current_mode = null;
26+
2527
/**
2628
* Create a new stats repository instance.
2729
*/
@@ -31,6 +33,16 @@ public function __construct(DateRange $date_range = PresetDateRanges::THIS_YEAR,
3133
$this->setFilters($filters);
3234
}
3335

36+
protected function setCurrentMode(?TimeSeriesModes $mode)
37+
{
38+
$this->current_mode = $mode;
39+
}
40+
41+
public function getCurrentMode(): ?TimeSeriesModes
42+
{
43+
return $this->current_mode;
44+
}
45+
3446
/**
3547
* Check whether the given user can view the stat
3648
*/

src/Repositories/TimeSeries/AggregateStatsRepository.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Illuminate\Database\Eloquent\Builder;
99
use Illuminate\Support\Facades\DB;
10+
use Javaabu\Stats\Enums\TimeSeriesModes;
1011
use Javaabu\Stats\TimeSeriesStats;
1112

1213
abstract class AggregateStatsRepository extends AbstractTimeSeriesStatsRepository
@@ -21,6 +22,11 @@ public abstract function getTable(): string;
2122
*/
2223
public abstract function getAggregateSql(): string;
2324

25+
public function getDateSqlForTimeMode(TimeSeriesModes $mode): string
26+
{
27+
return $mode->getSql($this->getDateField());
28+
}
29+
2430
/**
2531
* Get the date field name for the repository
2632
*/
@@ -44,8 +50,10 @@ public function getDateField(): string
4450
*/
4551
public function hour(): Builder
4652
{
53+
$this->setCurrentMode(TimeSeriesModes::HOUR);
54+
4755
return $this->filteredQuery()
48-
->select(DB::raw($this->getAggregateSql().", DATE_FORMAT(".$this->getDateField().", '%Y-%m-%d %H:00') as hour"))
56+
->select(DB::raw($this->getAggregateSql().", " . $this->getDateSqlForTimeMode(TimeSeriesModes::HOUR) . " as hour"))
4957
->groupBy('hour')
5058
->orderBy('hour', 'ASC');
5159
}
@@ -57,8 +65,10 @@ public function hour(): Builder
5765
*/
5866
public function day(): Builder
5967
{
68+
$this->setCurrentMode(TimeSeriesModes::DAY);
69+
6070
return $this->filteredQuery()
61-
->select(DB::raw($this->getAggregateSql().", DATE(".$this->getDateField().") as day"))
71+
->select(DB::raw($this->getAggregateSql().", " . $this->getDateSqlForTimeMode(TimeSeriesModes::DAY) . " as day"))
6272
->groupBy('day')
6373
->orderBy('day', 'ASC');
6474
}
@@ -70,11 +80,11 @@ public function day(): Builder
7080
*/
7181
public function week(): Builder
7282
{
73-
$week_mode = TimeSeriesStats::weekMode();
83+
$this->setCurrentMode(TimeSeriesModes::WEEK);
7484

7585
return $this->filteredQuery()
7686
//->select(DB::raw($this->getAggregateSql().", DATE_FORMAT(".$this->getDateField().", '%X, %V') as week"))
77-
->select(DB::raw($this->getAggregateSql().", YEARWEEK(".$this->getDateField().", $week_mode) as week"))
87+
->select(DB::raw($this->getAggregateSql().", " . $this->getDateSqlForTimeMode(TimeSeriesModes::WEEK) . " as week"))
7888
->groupBy('week')
7989
->orderBy('week', 'ASC');
8090
}
@@ -86,8 +96,10 @@ public function week(): Builder
8696
*/
8797
public function month(): Builder
8898
{
99+
$this->setCurrentMode(TimeSeriesModes::MONTH);
100+
89101
return $this->filteredQuery()
90-
->select(DB::raw($this->getAggregateSql().", DATE_FORMAT(".$this->getDateField().", '%Y, %m') as month"))
102+
->select(DB::raw($this->getAggregateSql().", " . $this->getDateSqlForTimeMode(TimeSeriesModes::MONTH) . " as month"))
91103
->groupBy('month')
92104
->orderBy('month', 'ASC');
93105
}
@@ -99,8 +111,10 @@ public function month(): Builder
99111
*/
100112
public function year(): Builder
101113
{
114+
$this->setCurrentMode(TimeSeriesModes::YEAR);
115+
102116
return $this->filteredQuery()
103-
->select(DB::raw($this->getAggregateSql().", YEAR(".$this->getDateField().") as year"))
117+
->select(DB::raw($this->getAggregateSql().", " . $this->getDateSqlForTimeMode(TimeSeriesModes::YEAR) . " as year"))
104118
->groupBy('year')
105119
->orderBy('year', 'ASC');
106120
}
@@ -110,6 +124,8 @@ public function year(): Builder
110124
*/
111125
public function total(): float|int
112126
{
127+
$this->setCurrentMode(null);
128+
113129
$total = $this->filteredQuery()
114130
->select(DB::raw($this->getAggregateSql()))
115131
->value($this->getAggregateFieldName());

tests/Unit/Enums/TimeSeriesModesTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88

99
class TimeSeriesModesTest extends TestCase
1010
{
11+
/** @test */
12+
public function it_can_generate_the_correct_mysql_query_for_each_mode(): void
13+
{
14+
$this->assertEquals('DATE_FORMAT(created_at, \'%Y-%m-%d %H:00\')', TimeSeriesModes::HOUR->getSql('created_at'), 'Invalid mysql query for HOUR');
15+
$this->assertEquals('DATE(created_at)', TimeSeriesModes::DAY->getSql('created_at'), 'Invalid mysql query for DAY');
16+
$this->assertEquals('YEARWEEK(created_at, 6)', TimeSeriesModes::WEEK->getSql('created_at'), 'Invalid mysql query for WEEK');
17+
$this->assertEquals('DATE_FORMAT(created_at, \'%Y, %m\')', TimeSeriesModes::MONTH->getSql('created_at'), 'Invalid mysql query for MONTH');
18+
$this->assertEquals('YEAR(created_at)', TimeSeriesModes::YEAR->getSql('created_at'), 'Invalid mysql query for YEAR');
19+
}
20+
1121
/** @test */
1222
public function it_can_get_the_date_format_for_the_time_series_mode(): void
1323
{

0 commit comments

Comments
 (0)