Passed
Push — main ( 29aefa...acd765 )
by Pranjal
02:34
created

RecordManager::getAll()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 2
b 0
f 0
nc 1
nop 1
dl 0
loc 7
rs 10
1
<?php
2
3
/*
4
 * This file is part of the Scrawler package.
5
 *
6
 * (c) Pranjal Pandey <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Scrawler\Arca\Manager;
13
14
use Doctrine\DBAL\Connection;
15
use Ramsey\Uuid\Uuid;
16
use Scrawler\Arca\Collection;
17
use Scrawler\Arca\Config;
18
use Scrawler\Arca\Model;
19
use Scrawler\Arca\QueryBuilder;
20
21
/**
22
 * Class responsible for manging single records.
23
 */
24
final class RecordManager
25
{
26
    private const ID_COLUMN = 'id';
27
    private const DEFAULT_ALIAS = 't';
28
    private const ALL_COLUMNS = '*';
29
30
    /**
31
     * Create RecordManager.
32
     */
33
    public function __construct(
34
        private readonly Connection $connection,
35
        private readonly ModelManager $modelManager,
36
        private readonly Config $config,
37
    ) {
38
    }
39
40
    /**
41
     * Execute operations within a transaction
42
     * 
43
     * @template T
44
     * @param callable(): T $callback
45
     * @return T
46
     * @throws \Exception
47
     */
48
    private function executeInTransaction(callable $callback): mixed
49
    {
50
        $this->connection->beginTransaction();
51
        try {
52
            $result = $callback();
53
            $this->connection->commit();
54
            return $result;
55
        } catch (\Exception $e) {
56
            $this->connection->rollBack();
57
            throw $e;
58
        }
59
    }
60
61
    /**
62
     * Create a new record.
63
     */
64
    public function insert(Model $model): mixed
65
    {
66
        return $this->executeInTransaction(function() use ($model) {
67
            if ($this->config->isUsingUUID()) {
68
                $model->set(self::ID_COLUMN, Uuid::uuid4()->toString());
69
            }
70
            
71
            $this->connection->insert(
72
                $model->getName(), 
73
                $model->getSelfProperties()
74
            );
75
            
76
            if ($this->config->isUsingUUID()) {
77
                return $model->get(self::ID_COLUMN);
78
            }
79
80
            return (int) $this->connection->lastInsertId();
81
        });
82
    }
83
84
    /**
85
     * Update a record.
86
     */
87
    public function update(Model $model): mixed
88
    {
89
        return $this->executeInTransaction(function() use ($model) {
90
            $this->connection->update(
91
                $model->getName(),
92
                $model->getSelfProperties(),
93
                [self::ID_COLUMN => $model->getId()]
94
            );
95
            return $model->getId();
96
        });
97
    }
98
99
    /**
100
     * Delete a record.
101
     */
102
    public function delete(Model $model): mixed
103
    {
104
        return $this->executeInTransaction(function() use ($model) {
105
            $this->connection->delete(
106
                $model->getName(),
107
                [self::ID_COLUMN => $model->getId()]
108
            );
109
            return $model->getId();
110
        });
111
    }
112
113
    /**
114
     * Get single record by id.
115
     */
116
    public function getById(string $table, mixed $id): ?Model
117
    {
118
        return $this->executeInTransaction(function() use ($table, $id) {
119
            return $this->createQueryBuilder()
120
                ->select(self::ALL_COLUMNS)
121
                ->from($table, self::DEFAULT_ALIAS)
122
                ->where(self::DEFAULT_ALIAS . '.' . self::ID_COLUMN . ' = ?')
123
                ->setParameter(0, $id)
124
                ->first();
125
        });
126
    }
127
128
    /**
129
     * Get all records.
130
     */
131
    public function getAll(string $tableName): Collection
132
    {
133
        return $this->executeInTransaction(function() use ($tableName) {
134
            return $this->createQueryBuilder()
135
                ->select(self::ALL_COLUMNS)
136
                ->from($tableName, self::DEFAULT_ALIAS)
137
                ->get();
138
        });
139
    }
140
141
    /**
142
     * Create a new QueryBuilder instance
143
     */
144
    private function createQueryBuilder(): QueryBuilder
145
    {
146
        return new QueryBuilder($this->connection, $this->modelManager);
147
    }
148
149
    /**
150
     * Get query builder from db.
151
     */
152
    public function find(string $name): QueryBuilder
153
    {
154
        return $this->createQueryBuilder()
155
            ->select(self::ALL_COLUMNS)
156
            ->from($name, self::DEFAULT_ALIAS);
157
    }
158
159
    /**
160
     * Get query builder from db.
161
     */
162
    public function select(string $expression): QueryBuilder
163
    {
164
        return $this->createQueryBuilder()->select($expression);
165
    }
166
}
167