Skip to content

Commit 82d285e

Browse files
authored
Merge pull request #19 from DirectoryTree/make-metrics-table-command
Add `metrics:table` command to generate metric table migrations
2 parents 56fd72e + 5824b51 commit 82d285e

File tree

6 files changed

+255
-18
lines changed

6 files changed

+255
-18
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"require-dev": {
1212
"laravel/pint": "^1.0",
1313
"pestphp/pest": "^1.0|^2.0|^3.0",
14+
"pestphp/pest-plugin-laravel": "^1.0|^2.0|^3.0",
1415
"orchestra/testbench": "^7.0|^8.0|^9.0|^10.0"
1516
},
1617
"license": "MIT",

src/Commands/MakeMetricsTable.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
namespace DirectoryTree\Metrics\Commands;
4+
5+
use Illuminate\Console\Command;
6+
use Illuminate\Filesystem\Filesystem;
7+
8+
class MakeMetricsTable extends Command
9+
{
10+
/**
11+
* The name and signature of the console command.
12+
*
13+
* @var string
14+
*/
15+
protected $signature = 'metrics:table {name : The name of the metrics table}';
16+
17+
/**
18+
* The console command description.
19+
*
20+
* @var string
21+
*/
22+
protected $description = 'Create a new metrics table migration';
23+
24+
/**
25+
* Execute the console command.
26+
*/
27+
public function handle(Filesystem $files): int
28+
{
29+
$table = $this->argument('name');
30+
31+
$this->writeMigration($files, $table);
32+
33+
$this->components->info(sprintf('Migration [%s] created successfully.', $this->getMigrationFileName($table)));
34+
35+
return self::SUCCESS;
36+
}
37+
38+
/**
39+
* Write the migration file to disk.
40+
*/
41+
protected function writeMigration(Filesystem $files, string $table): void
42+
{
43+
$file = $this->getMigrationPath($table);
44+
45+
$files->ensureDirectoryExists(dirname($file));
46+
47+
$files->put($file, $this->populateStub($table));
48+
}
49+
50+
/**
51+
* Populate the stub with the table name.
52+
*/
53+
protected function populateStub(string $table): string
54+
{
55+
$stub = $this->getStub();
56+
57+
return str_replace('{{ table }}', $table, $stub);
58+
}
59+
60+
/**
61+
* Get the migration file path.
62+
*/
63+
protected function getMigrationPath(string $table): string
64+
{
65+
return database_path('migrations/'.$this->getMigrationFileName($table));
66+
}
67+
68+
/**
69+
* Get the migration file name.
70+
*/
71+
protected function getMigrationFileName(string $table): string
72+
{
73+
return date('Y_m_d_His').'_create_'.$table.'_table.php';
74+
}
75+
76+
/**
77+
* Get the stub file contents.
78+
*/
79+
protected function getStub(): string
80+
{
81+
return file_get_contents(__DIR__.'/../../stubs/metrics.table.stub');
82+
}
83+
}

src/MetricServiceProvider.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace DirectoryTree\Metrics;
44

55
use DirectoryTree\Metrics\Commands\CommitMetrics;
6+
use DirectoryTree\Metrics\Commands\MakeMetricsTable;
67
use Illuminate\Contracts\Foundation\Application;
78
use Illuminate\Support\Facades\App;
89
use Illuminate\Support\Facades\Queue;
@@ -36,7 +37,10 @@ public function register(): void
3637
public function boot(): void
3738
{
3839
if ($this->app->runningInConsole()) {
39-
$this->commands(CommitMetrics::class);
40+
$this->commands([
41+
CommitMetrics::class,
42+
MakeMetricsTable::class,
43+
]);
4044
}
4145

4246
if ($this->app->make('config')->get('metrics.auto_commit', true)) {

stubs/metrics.table.stub

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::create('{{ table }}', function (Blueprint $table) {
15+
$table->id();
16+
$table->string('name')->index();
17+
$table->string('category')->nullable()->index();
18+
$table->nullableMorphs('measurable');
19+
$table->unsignedSmallInteger('year');
20+
$table->unsignedTinyInteger('month');
21+
$table->unsignedTinyInteger('day');
22+
$table->unsignedTinyInteger('hour')->nullable();
23+
$table->unsignedInteger('value');
24+
$table->timestamps();
25+
26+
$table->index(['year', 'month', 'day', 'hour']);
27+
});
28+
}
29+
30+
/**
31+
* Reverse the migrations.
32+
*/
33+
public function down(): void
34+
{
35+
Schema::dropIfExists('{{ table }}');
36+
}
37+
};
38+

tests/Commands/CommitMetricsTest.php

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Illuminate\Support\Facades\Queue;
1212
use Illuminate\Support\Facades\Redis;
1313

14+
use function Pest\Laravel\artisan;
15+
1416
beforeEach(function () {
1517
Queue::fake();
1618
Redis::flushdb();
@@ -19,7 +21,7 @@
1921
});
2022

2123
it('displays message when no metrics to commit', function () {
22-
$this->artisan(CommitMetrics::class)
24+
artisan(CommitMetrics::class)
2325
->expectsOutput('No metrics to commit.')
2426
->assertSuccessful();
2527

@@ -34,7 +36,7 @@
3436

3537
expect(Metric::count())->toBe(0);
3638

37-
$this->artisan(CommitMetrics::class)
39+
artisan(CommitMetrics::class)
3840
->expectsOutput('Committed 2 metric(s).')
3941
->assertSuccessful();
4042

@@ -52,7 +54,7 @@
5254
Metrics::record(new MetricData('page_views'));
5355
Metrics::record(new MetricData('api_calls'));
5456

55-
$this->artisan(CommitMetrics::class)
57+
artisan(CommitMetrics::class)
5658
->expectsOutput('Committed 2 metric(s).')
5759
->assertSuccessful();
5860

@@ -65,7 +67,7 @@
6567
Metrics::capture();
6668
Metrics::record(new MetricData('page_views'));
6769

68-
$this->artisan(CommitMetrics::class)
70+
artisan(CommitMetrics::class)
6971
->expectsOutput('Committed 1 metric(s).')
7072
->assertSuccessful();
7173

@@ -78,7 +80,7 @@
7880
Metrics::record(new MetricData('api_calls'));
7981
Metrics::record(new MetricData('logins'));
8082

81-
$this->artisan(CommitMetrics::class)
83+
artisan(CommitMetrics::class)
8284
->expectsOutput('Committed 3 metric(s).')
8385
->assertSuccessful();
8486

@@ -89,13 +91,13 @@
8991
Metrics::capture();
9092
Metrics::record(new MetricData('page_views'));
9193

92-
$this->artisan(CommitMetrics::class)
94+
artisan(CommitMetrics::class)
9395
->assertSuccessful();
9496

9597
expect(Metric::count())->toBe(1);
9698

9799
// Running again should show no metrics
98-
$this->artisan(CommitMetrics::class)
100+
artisan(CommitMetrics::class)
99101
->expectsOutput('No metrics to commit.')
100102
->assertSuccessful();
101103

@@ -108,7 +110,7 @@
108110
Metrics::record(new MetricData('page_views', 'analytics'));
109111
Metrics::record(new MetricData('api_calls'));
110112

111-
$this->artisan(CommitMetrics::class)
113+
artisan(CommitMetrics::class)
112114
->expectsOutput('Committed 3 metric(s).')
113115
->assertSuccessful();
114116

@@ -127,7 +129,7 @@
127129
Metrics::record(new MetricData('logins', measurable: $user2));
128130
Metrics::record(new MetricData('logins'));
129131

130-
$this->artisan(CommitMetrics::class)
132+
artisan(CommitMetrics::class)
131133
->expectsOutput('Committed 3 metric(s).')
132134
->assertSuccessful();
133135

@@ -144,7 +146,7 @@
144146
Metrics::record(new MetricData('page_views'));
145147
}
146148

147-
$this->artisan(CommitMetrics::class)
149+
artisan(CommitMetrics::class)
148150
->expectsOutput('Committed 1 metric(s).')
149151
->assertSuccessful();
150152

@@ -156,13 +158,13 @@
156158
Metrics::capture();
157159
Metrics::record(new MetricData('page_views'));
158160

159-
$this->artisan(CommitMetrics::class)
161+
artisan(CommitMetrics::class)
160162
->expectsOutput('Committed 1 metric(s).')
161163
->assertSuccessful();
162164

163165
Metrics::record(new MetricData('api_calls'));
164166

165-
$this->artisan(CommitMetrics::class)
167+
artisan(CommitMetrics::class)
166168
->expectsOutput('Committed 1 metric(s).')
167169
->assertSuccessful();
168170

@@ -173,7 +175,7 @@
173175
// Record without capturing
174176
Metrics::record(new MetricData('page_views'));
175177

176-
$this->artisan(CommitMetrics::class)
178+
artisan(CommitMetrics::class)
177179
->expectsOutput('No metrics to commit.')
178180
->assertSuccessful();
179181

@@ -187,7 +189,7 @@
187189
Metrics::record(new MetricData('revenue', value: 250));
188190
Metrics::record(new MetricData('revenue', value: 50));
189191

190-
$this->artisan(CommitMetrics::class)
192+
artisan(CommitMetrics::class)
191193
->expectsOutput('Committed 1 metric(s).')
192194
->assertSuccessful();
193195

@@ -203,7 +205,7 @@
203205
Metrics::record(new MetricData('page_views', date: $today));
204206
Metrics::record(new MetricData('page_views', date: $yesterday));
205207

206-
$this->artisan(CommitMetrics::class)
208+
artisan(CommitMetrics::class)
207209
->expectsOutput('Committed 2 metric(s).')
208210
->assertSuccessful();
209211

@@ -217,7 +219,7 @@
217219
Metrics::capture();
218220
Metrics::record(new MetricData('page_views', 'marketing', value: 5, date: $date, measurable: $user));
219221

220-
$this->artisan(CommitMetrics::class)
222+
artisan(CommitMetrics::class)
221223
->expectsOutput('Committed 1 metric(s).')
222224
->assertSuccessful();
223225

@@ -242,7 +244,7 @@
242244
Metrics::record(new MetricData('page_views'));
243245
Metrics::record(new MetricData('api_calls'));
244246

245-
$this->artisan(CommitMetrics::class)
247+
artisan(CommitMetrics::class)
246248
->expectsOutput('Committed 2 metric(s).')
247249
->assertSuccessful();
248250

0 commit comments

Comments
 (0)