Passed
Push — master ( 3660fa...998d5d )
by Marcel
03:22
created

DataloadService::execute()   B

Complexity

Conditions 7
Paths 8

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 21
c 1
b 0
f 0
nc 8
nop 1
dl 0
loc 33
rs 8.6506
1
<?php
2
/**
3
 * Analytics
4
 *
5
 * This file is licensed under the Affero General Public License version 3 or
6
 * later. See the LICENSE.md file.
7
 *
8
 * @author Marcel Scherello <[email protected]>
9
 * @copyright 2020 Marcel Scherello
10
 */
11
12
namespace OCA\Analytics\Service;
13
14
use Exception;
15
use OCA\Analytics\Activity\ActivityManager;
16
use OCA\Analytics\Controller\DatasourceController;
17
use OCA\Analytics\Controller\StorageController;
18
use OCA\Analytics\Db\DataloadMapper;
19
use OCP\AppFramework\Http\DataResponse;
20
use OCP\AppFramework\Http\NotFoundResponse;
21
use OCP\Files\NotFoundException;
22
use OCP\IL10N;
23
use OCP\ILogger;
24
25
class DataloadService
26
{
27
    private $logger;
28
    private $StorageController;
29
    private $DatasourceController;
30
    private $ActivityManager;
31
    private $DatasetService;
32
    private $l10n;
33
    private $DataloadMapper;
34
35
    public function __construct(
36
        IL10N $l10n,
37
        ILogger $logger,
38
        ActivityManager $ActivityManager,
39
        DatasourceController $DatasourceController,
40
        DatasetService $DatasetService,
41
        StorageController $StorageController,
42
        DataloadMapper $DataloadMapper
43
    )
44
    {
45
        $this->l10n = $l10n;
46
        $this->logger = $logger;
47
        $this->StorageController = $StorageController;
48
        $this->ActivityManager = $ActivityManager;
49
        $this->DatasourceController = $DatasourceController;
50
        $this->DatasetService = $DatasetService;
51
        $this->DataloadMapper = $DataloadMapper;
52
    }
53
54
    // Dataloads
55
    // Dataloads
56
    // Dataloads
57
58
    /**
59
     * create a new dataload
60
     *
61
     * @param int $datasetId
62
     * @param int $datasourceId
63
     * @return int
64
     */
65
    public function create(int $datasetId, int $datasourceId)
66
    {
67
        return $this->DataloadMapper->create($datasetId, $datasourceId);
68
    }
69
70
    /**
71
     * get all dataloads for a dataset
72
     *
73
     * @param int $datasetId
74
     * @return array
75
     */
76
    public function read(int $datasetId)
77
    {
78
        return $this->DataloadMapper->read($datasetId);
79
    }
80
81
    /**
82
     * update dataload
83
     *
84
     * @param int $dataloadId
85
     * @param $name
86
     * @param $option
87
     * @param $schedule
88
     * @return bool
89
     */
90
    public function update(int $dataloadId, $name, $option, $schedule)
91
    {
92
        return $this->DataloadMapper->update($dataloadId, $name, $option, $schedule);
93
    }
94
95
    /**
96
     * delete a dataload
97
     *
98
     * @param int $dataloadId
99
     * @return bool
100
     */
101
    public function delete(int $dataloadId)
102
    {
103
        return $this->DataloadMapper->delete($dataloadId);
104
    }
105
106
    /**
107
     * execute all dataloads depending on their schedule
108
     * daily or hourly
109
     *
110
     * @param $schedule
111
     * @return void
112
     * @throws Exception
113
     */
114
    public function executeBySchedule($schedule)
115
    {
116
        $schedules = $this->DataloadMapper->getDataloadBySchedule($schedule);
117
        //$this->logger->debug('DataLoadController 145: execute schedule '.$schedule);
118
        foreach ($schedules as $dataload) {
119
            //$this->logger->debug('DataLoadController 147: execute dataload '.$dataload['id']);
120
            $this->execute($dataload['id']);
121
        }
122
    }
123
124
    /**
125
     * execute a dataload from datasource and store into dataset
126
     *
127
     * @param int $dataloadId
128
     * @return DataResponse
129
     * @throws Exception
130
     */
131
    public function execute(int $dataloadId)
132
    {
133
        $dataloadMetadata = $this->DataloadMapper->getDataloadById($dataloadId);
134
        $result = $this->getDataFromDatasource($dataloadId);
135
        $insert = $update = 0;
136
        $datasetId = $result['datasetId'];
137
        $option = json_decode($dataloadMetadata['option'], true);
138
139
        if (isset($option['delete']) and $option['delete'] === 'true') {
140
            $this->StorageController->delete($datasetId, '*', '*');
141
        }
142
        if ($result['error'] === 0) {
143
            foreach ($result['data'] as &$row) {
144
                if (count($row) === 2) {
145
                    // if datasource only delivers 2 colums, the value needs to be in the last one
146
                    $row[2] = $row[1];
147
                    $row[1] = null;
148
                }
149
                $action = $this->StorageController->update($datasetId, $row[0], $row[1], $row[2], $dataloadMetadata['user_id']);
150
                $insert = $insert + $action['insert'];
151
                $update = $update + $action['update'];
152
            }
153
        }
154
155
        $result = [
156
            'insert' => $insert,
157
            'update' => $update,
158
            'error' => $result['error'],
159
        ];
160
161
        if ($result['error'] === 0) $this->ActivityManager->triggerEvent($datasetId, ActivityManager::OBJECT_DATA, ActivityManager::SUBJECT_DATA_ADD_DATALOAD, $dataloadMetadata['user_id']);
162
163
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type array<string,integer|mixed> which is incompatible with the documented return type OCP\AppFramework\Http\DataResponse.
Loading history...
164
    }
165
166
    /**
167
     * get the data from datasource
168
     * to be used in simulation or execution
169
     *
170
     * @param int $dataloadId
171
     * @return array|NotFoundResponse
172
     * @throws NotFoundResponse|NotFoundException
173
     */
174
    public function getDataFromDatasource(int $dataloadId)
175
    {
176
        $dataloadMetadata = $this->DataloadMapper->getDataloadById($dataloadId);
177
        $datasetMetadata = $this->DatasetService->getOwnDataset($dataloadMetadata['dataset'], $dataloadMetadata['user_id']);
178
179
        if (!empty($datasetMetadata)) {
180
            $option = json_decode($dataloadMetadata['option'], true);
181
            $option['user_id'] = $dataloadMetadata['user_id'];
182
183
            //$this->logger->debug('DataLoadController 187: ' . $dataloadMetadata['option'] . '---' . json_encode($option));
184
            $result = $this->DatasourceController->read((int)$dataloadMetadata['datasource'], $option);
185
            $result['datasetId'] = $dataloadMetadata['dataset'];
186
187
            if (isset($option['timestamp']) and $option['timestamp'] === 'true') {
188
                // if datasource should be timestamped/snapshoted
189
                // shift values by one dimension and stores date in second column
190
                $result['data'] = array_map(function ($tag) {
191
                    $columns = count($tag);
192
                    return array($tag[$columns - 2], $tag[$columns - 2], $tag[$columns - 1]);
193
                }, $result['data']);
194
                $result['data'] = $this->replaceDimension($result['data'], 1, date("Y-m-d H:i:s"));
195
            }
196
197
            return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result also could return the type OCP\Files\NotFoundException which is incompatible with the documented return type OCP\AppFramework\Http\NotFoundResponse|array.
Loading history...
198
        } else {
199
            return new NotFoundResponse();
200
        }
201
    }
202
203
    /**
204
     * replace all values of one dimension
205
     *
206
     * @NoAdminRequired
207
     * @param $Array
208
     * @param $Find
209
     * @param $Replace
210
     * @return array
211
     */
212
    private function replaceDimension($Array, $Find, $Replace)
213
    {
214
        if (is_array($Array)) {
215
            foreach ($Array as $Key => $Val) {
216
                if (is_array($Array[$Key])) {
217
                    $Array[$Key] = $this->replaceDimension($Array[$Key], $Find, $Replace);
218
                } else {
219
                    if ($Key === $Find) {
220
                        $Array[$Key] = $Replace;
221
                    }
222
                }
223
            }
224
        }
225
        return $Array;
226
    }
227
}