Skip to content

Commit 9b72a78

Browse files
authored
Add repositories (#24)
1 parent 2a3810d commit 9b72a78

10 files changed

+261
-121
lines changed

app/Http/Controllers/DashboardStatsController.php

Lines changed: 9 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -3,119 +3,25 @@
33
namespace Waterline\Http\Controllers;
44

55
use Illuminate\Support\Facades\DB;
6+
use Waterline\Repositories\Workflow\Interfaces\WorkflowRepositoryInterface;
67
use Workflow\Models\StoredWorkflow;
78
use Workflow\Models\StoredWorkflowException;
89

910
class DashboardStatsController extends Controller
1011
{
11-
public function index() {
12+
public function index(WorkflowRepositoryInterface $repository) {
1213

13-
$flowsPastHour = config('workflows.stored_workflow_model', StoredWorkflow::class)::where('updated_at', '>=', now()->subHour())
14-
->count();
15-
16-
$exceptionsPastHour = config('workflows.stored_workflow_exception_model', StoredWorkflowException::class)::where('created_at', '>=', now()->subHour())
17-
->count();
18-
19-
$failedFlowsPastWeek = config('workflows.stored_workflow_model', StoredWorkflow::class)::where('status', 'failed')
20-
->where('updated_at', '>=', now()->subDays(7))
21-
->count();
22-
23-
$maxWaitTimeWorkflow = config('workflows.stored_workflow_model', StoredWorkflow::class)::where('status', 'pending')
24-
->orderBy('updated_at')
25-
->first();
26-
27-
$dbDriverName = DB::connection()->getDriverName();
28-
29-
if ($dbDriverName === 'mongodb' && $maxWaitTimeWorkflow && $maxWaitTimeWorkflow->_id) {
30-
$maxWaitTimeWorkflow->id = $maxWaitTimeWorkflow->_id;
31-
}
32-
33-
if ($dbDriverName === 'mongodb') {
34-
$maxDurationWorkflow = config('workflows.stored_workflow_model', StoredWorkflow::class)::select('*')
35-
->raw(function ($collection) {
36-
return $collection->aggregate([
37-
[
38-
'$match' => [
39-
'status' => [ '$ne' => 'pending' ]
40-
]
41-
],
42-
[
43-
'$addFields' => [
44-
'duration' => [
45-
'$subtract' => [
46-
['$toDate' => '$updated_at'],
47-
['$toDate' => '$created_at']
48-
]
49-
]
50-
]
51-
],
52-
[
53-
'$sort' => ['duration' => -1]
54-
],
55-
[
56-
'$limit' => 1
57-
]
58-
]);
59-
})
60-
->first();
61-
if ($maxDurationWorkflow) {
62-
$maxDurationWorkflow->id = $maxDurationWorkflow->_id;
63-
}
64-
} else {
65-
$maxDurationWorkflow = config('workflows.stored_workflow_model', StoredWorkflow::class)::select('*')
66-
->when($dbDriverName === 'sqlite', function ($q) {
67-
return $q->addSelect(DB::raw('julianday(created_at) - julianday(updated_at) as duration'));
68-
})
69-
->when($dbDriverName === 'mysql', function ($q) {
70-
return $q->addSelect(DB::raw('TIMEDIFF(created_at, updated_at) as duration'));
71-
})
72-
->when($dbDriverName === 'pgsql', function ($q) {
73-
return $q->addSelect(DB::raw('(EXTRACT(EPOCH FROM created_at - updated_at)) as duration'));
74-
})
75-
->when($dbDriverName === 'sqlsrv', function ($q) {
76-
return $q->addSelect(DB::raw('DATEDIFF(SECOND, created_at, updated_at) as duration'));
77-
})
78-
->where('status', '!=', 'pending')
79-
->orderBy('duration')
80-
->first();
81-
}
82-
83-
if ($dbDriverName === 'mongodb') {
84-
$maxExceptionsWorkflow = StoredWorkflowException::raw(function ($collection) {
85-
return $collection->aggregate([
86-
['$group' => ['_id' => '$stored_workflow_id', 'count' => ['$sum' => 1]]],
87-
['$sort' => ['count' => -1]],
88-
['$limit' => 1]
89-
]);
90-
})->first();
91-
92-
if ($maxExceptionsWorkflow) {
93-
$mostExceptionWorkflowId = $maxExceptionsWorkflow['_id'];
94-
95-
$maxExceptionsWorkflow = StoredWorkflow::where('_id', $mostExceptionWorkflowId)->first();
96-
97-
if ($maxExceptionsWorkflow) {
98-
$maxExceptionsWorkflow->exceptions_count = StoredWorkflowException::where('stored_workflow_id', $mostExceptionWorkflowId)->count();
99-
$maxExceptionsWorkflow->id = $maxExceptionsWorkflow->_id;
100-
}
101-
}
102-
} else {
103-
$maxExceptionsWorkflow = config('workflows.stored_workflow_model', StoredWorkflow::class)::withCount('exceptions')
104-
->has('exceptions')
105-
->orderByDesc('exceptions_count')
106-
->orderByDesc('updated_at')
107-
->first();
108-
}
14+
$flowsPastHour = $repository->flowsPastHour();
10915

11016
return response()->json([
111-
'flows' => config('workflows.stored_workflow_model', StoredWorkflow::class)::count(),
17+
'flows' => $repository->totalFlows(),
11218
'flows_per_minute' => $flowsPastHour / 60,
11319
'flows_past_hour' => $flowsPastHour,
114-
'exceptions_past_hour' => $exceptionsPastHour,
115-
'failed_flows_past_week' => $failedFlowsPastWeek,
116-
'max_wait_time_workflow' => $maxWaitTimeWorkflow,
117-
'max_duration_workflow' => $maxDurationWorkflow,
118-
'max_exceptions_workflow' => $maxExceptionsWorkflow,
20+
'exceptions_past_hour' => $repository->exceptionsPastHour(),
21+
'failed_flows_past_week' => $repository->failedFlowsPastWeek(),
22+
'max_wait_time_workflow' => $repository->maxWaitTimeWorkflow(),
23+
'max_duration_workflow' => $repository->maxDurationWorkflow(),
24+
'max_exceptions_workflow' => $repository->maxExceptionsWorkflow(),
11925
]);
12026
}
12127
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
namespace Waterline\Repositories\Workflow\Infrastructure;
4+
5+
use Waterline\Repositories\Workflow\Interfaces\WorkflowRepositoryInterface;
6+
7+
abstract class WorkflowRepositoryBaseSQL implements WorkflowRepositoryInterface
8+
{
9+
protected $workflowModel;
10+
protected $workflowExceptionModel;
11+
12+
public function __construct()
13+
{
14+
$this->workflowModel = config('workflows.stored_workflow_model', \Workflow\Models\StoredWorkflow::class);
15+
$this->workflowExceptionModel = config('workflows.stored_workflow_exception_model', \Workflow\Models\StoredWorkflowException::class);
16+
}
17+
18+
public function flowsPastHour(): int
19+
{
20+
return $this->workflowModel::where('updated_at', '>=', now()->subHour())->count();
21+
}
22+
23+
public function exceptionsPastHour(): int
24+
{
25+
return $this->workflowExceptionModel::where('created_at', '>=', now()->subHour())->count();
26+
}
27+
28+
public function failedFlowsPastWeek(): int
29+
{
30+
return $this->workflowModel::where('status', 'failed')
31+
->where('updated_at', '>=', now()->subDays(7))
32+
->count();
33+
}
34+
35+
public function maxWaitTimeWorkflow()
36+
{
37+
return $this->workflowModel::where('status', 'pending')
38+
->orderBy('updated_at')
39+
->first();
40+
}
41+
42+
public function maxExceptionsWorkflow()
43+
{
44+
return $this->workflowModel::withCount('exceptions')
45+
->has('exceptions')
46+
->orderByDesc('exceptions_count')
47+
->orderByDesc('updated_at')
48+
->first();
49+
}
50+
51+
public function totalFlows(): int
52+
{
53+
return $this->workflowModel::count();
54+
}
55+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<?php
2+
3+
namespace Waterline\Repositories\Workflow\Infrastructure;
4+
5+
class WorkflowRepositoryMongoDB extends WorkflowRepositoryBaseSQL
6+
{
7+
public function maxWaitTimeWorkflow()
8+
{
9+
$maxWaitTimeWorkflow = $this->workflowModel::where('status', 'pending')
10+
->orderBy('updated_at')
11+
->first();
12+
13+
if ($maxWaitTimeWorkflow && $maxWaitTimeWorkflow->_id) {
14+
$maxWaitTimeWorkflow->id = $maxWaitTimeWorkflow->_id;
15+
}
16+
17+
return $maxWaitTimeWorkflow;
18+
}
19+
20+
public function maxDurationWorkflow()
21+
{
22+
$maxDurationWorkflow = $this->workflowModel::select('*')
23+
->raw(function ($collection) {
24+
return $collection->aggregate([
25+
[
26+
'$match' => [
27+
'status' => [ '$ne' => 'pending' ]
28+
]
29+
],
30+
[
31+
'$addFields' => [
32+
'duration' => [
33+
'$subtract' => [
34+
['$toDate' => '$updated_at'],
35+
['$toDate' => '$created_at']
36+
]
37+
]
38+
]
39+
],
40+
[
41+
'$sort' => ['duration' => -1]
42+
],
43+
[
44+
'$limit' => 1
45+
]
46+
]);
47+
})
48+
->first();
49+
50+
if ($maxDurationWorkflow) {
51+
$maxDurationWorkflow->id = $maxDurationWorkflow->_id;
52+
}
53+
54+
return $maxDurationWorkflow;
55+
}
56+
57+
public function maxExceptionsWorkflow()
58+
{
59+
$maxExceptionsWorkflow = $this->workflowExceptionModel::raw(function ($collection) {
60+
return $collection->aggregate([
61+
['$group' => ['_id' => '$stored_workflow_id', 'count' => ['$sum' => 1]]],
62+
['$sort' => ['count' => -1]],
63+
['$limit' => 1]
64+
]);
65+
})->first();
66+
67+
if ($maxExceptionsWorkflow) {
68+
$mostExceptionWorkflowId = $maxExceptionsWorkflow['_id'];
69+
70+
$maxExceptionsWorkflow = $this->workflowModel::where('_id', $mostExceptionWorkflowId)->first();
71+
72+
if ($maxExceptionsWorkflow) {
73+
$maxExceptionsWorkflow->exceptions_count = $this->workflowExceptionModel::where('stored_workflow_id', $mostExceptionWorkflowId)->count();
74+
$maxExceptionsWorkflow->id = $maxExceptionsWorkflow->_id;
75+
}
76+
}
77+
78+
return $maxExceptionsWorkflow;
79+
}
80+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Waterline\Repositories\Workflow\Infrastructure;
4+
5+
class WorkflowRepositoryMySQL extends WorkflowRepositoryBaseSQL
6+
{
7+
public function maxDurationWorkflow()
8+
{
9+
return $this->workflowModel::select('*')
10+
->selectRaw('TIMEDIFF(created_at, updated_at) as duration')
11+
->where('status', '!=', 'pending')
12+
->orderByDesc('duration')
13+
->first();
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Waterline\Repositories\Workflow\Infrastructure;
4+
5+
class WorkflowRepositoryPostgreSQL extends WorkflowRepositoryBaseSQL
6+
{
7+
public function maxDurationWorkflow()
8+
{
9+
return $this->workflowModel::select('*')
10+
->selectRaw('(EXTRACT(EPOCH FROM created_at - updated_at)) as duration')
11+
->where('status', '!=', 'pending')
12+
->orderByDesc('duration')
13+
->first();
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Waterline\Repositories\Workflow\Infrastructure;
4+
5+
class WorkflowRepositorySQLServer extends WorkflowRepositoryBaseSQL
6+
{
7+
public function maxDurationWorkflow()
8+
{
9+
return $this->workflowModel::select('*')
10+
->selectRaw('DATEDIFF(SECOND, created_at, updated_at) as duration')
11+
->where('status', '!=', 'pending')
12+
->orderByDesc('duration')
13+
->first();
14+
}
15+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
3+
namespace Waterline\Repositories\Workflow\Infrastructure;
4+
5+
class WorkflowRepositorySQLite extends WorkflowRepositoryBaseSQL
6+
{
7+
public function maxDurationWorkflow()
8+
{
9+
return $this->workflowModel::select('*')
10+
->selectRaw('julianday(created_at) - julianday(updated_at) as duration')
11+
->where('status', '!=', 'pending')
12+
->orderByDesc('duration')
13+
->first();
14+
}
15+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
namespace Waterline\Repositories\Workflow\Interfaces;
4+
5+
interface WorkflowRepositoryInterface
6+
{
7+
public function flowsPastHour();
8+
9+
public function exceptionsPastHour();
10+
11+
public function failedFlowsPastWeek();
12+
13+
public function maxWaitTimeWorkflow();
14+
15+
public function maxDurationWorkflow();
16+
17+
public function maxExceptionsWorkflow();
18+
19+
public function totalFlows();
20+
}

app/WaterlineApplicationServiceProvider.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,16 @@
22

33
namespace Waterline;
44

5+
use Illuminate\Support\Facades\DB;
56
use Illuminate\Support\Facades\Gate;
67
use Illuminate\Support\ServiceProvider;
8+
use Waterline\Repositories\Workflow\Infrastructure\WorkflowRepositoryMongoDB;
9+
use Waterline\Repositories\Workflow\Infrastructure\WorkflowRepositoryMySQL;
10+
use Waterline\Repositories\Workflow\Infrastructure\WorkflowRepositoryPostgreSQL;
11+
use Waterline\Repositories\Workflow\Infrastructure\WorkflowRepositorySQLite;
12+
use Waterline\Repositories\Workflow\Infrastructure\WorkflowRepositorySQLServer;
13+
use Waterline\Repositories\Workflow\Interfaces\WorkflowRepositoryInterface;
14+
use Workflow\Models\StoredWorkflow;
715

816
class WaterlineApplicationServiceProvider extends ServiceProvider
917
{
@@ -32,6 +40,16 @@ protected function gate()
3240

3341
public function register()
3442
{
35-
//
43+
$drivers = [
44+
'mongodb' => WorkflowRepositoryMongoDB::class,
45+
'mysql' => WorkflowRepositoryMySQL::class,
46+
'pgsql' => WorkflowRepositoryPostgreSQL::class,
47+
'sqlite' => WorkflowRepositorySQLite::class,
48+
'sqlsrv' => WorkflowRepositorySQLServer::class,
49+
];
50+
51+
$driver = DB::connection((new (config('workflows.stored_workflow_model', StoredWorkflow::class)))->getConnectionName())->getDriverName();
52+
53+
$this->app->bind(WorkflowRepositoryInterface::class, $drivers[$driver] ?? WorkflowRepositoryMySQL::class);
3654
}
3755
}

0 commit comments

Comments
 (0)