Passed
Push — sudav3 ( b29c56...468d62 )
by 世昌
02:20
created

DataAccess::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
namespace suda\orm;
3
4
use ReflectionClass;
5
use ReflectionProperty;
6
use suda\orm\DataSource;
7
use suda\orm\TableAccess;
8
use suda\orm\struct\ReadStatement;
9
use suda\orm\struct\QueryStatement;
10
use suda\orm\struct\WriteStatement;
11
use suda\orm\struct\TableStructBuilder;
12
use suda\orm\struct\TableStructMiddleware;
13
use suda\orm\struct\TableStructAwareInterface;
14
15
/**
16
 * 数据访问
17
 */
18
class DataAccess
19
{
20
21
    /**
22
     * 数据源
23
     *
24
     * @var TableAccess
25
     */
26
    protected $access;
27
28
    /**
29
     * 数据类型
30
     *
31
     * @var string
32
     */
33
    protected $type;
34
35
    /**
36
     * 创建对数据的操作
37
     *
38
     * @param string $object
39
     * @param \suda\orm\DataSource $source
40
     * @param Middleware|null $middleware
41
     */
42
    public function __construct(string $object, DataSource $source, ?Middleware $middleware = null)
43
    {
44
        $this->type = $object;
45
        $struct = $this->createStruct($object);
46
        $middleware = $middleware ?? new TableStructMiddleware($object);
47
        $this->access = new TableAccess($struct, $source, $middleware);
48
    }
49
50
    /**
51
     * 读取数据
52
     *
53
     * @param array|string $fields
54
     * @return \suda\orm\struct\ReadStatement
55
     */
56
    public function read($fields): ReadStatement
57
    {
58
        if ($fields === null) {
59
            $fields = \array_keys($this->fields);
0 ignored issues
show
Bug Best Practice introduced by
The property fields does not exist on suda\orm\DataAccess. Did you maybe forget to declare it?
Loading history...
60
        } elseif (\func_num_args() > 1) {
61
            $fields = \func_get_args();
62
        }
63
        return $this->access->read($fields)->wantType($this->type);
64
    }
65
    
66
    /**
67
     * 写数据
68
     *
69
     * @param array|object $object
70
     * @return \suda\orm\struct\WriteStatement
71
     */
72
    public function write($object): WriteStatement
73
    {
74
        if (\is_object($object)) {
75
            $object = $this->createDataFromObject($object);
76
        }
77
        return $this->access->write($object);
78
    }
79
80
    /**
81
     * 统计计数
82
     *
83
     * @param string|array $where
84
     * @param array $whereBinder
85
     * @return integer
86
     */
87
    public function count($where, array $whereBinder):int
88
    {
89
        $fields = $this->access->getStruct()->getFields();
90
        $field = \array_shift($fields);
0 ignored issues
show
Bug introduced by
$fields of type suda\orm\struct\Fields is incompatible with the type array expected by parameter $array of array_shift(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

90
        $field = \array_shift(/** @scrutinizer ignore-type */ $fields);
Loading history...
91
        $total = $this->access->read([$field->getName()])->where($where, $whereBinder);
92
        $data = $this->access->query('SELECT count(*) as `count` from ('.$total.') as total', $total->getBinder())->one();
93
        return intval($data['count']);
94
    }
95
96
    /**
97
     * 查询语句
98
     *
99
     * @param string $query
100
     * @param mixed ...$parameter
101
     * @return QueryStatement
102
     */
103
    public function query(string $query, ...$parameter):QueryStatement
104
    {
105
        return $this->access->query($query, ...$parameter);
106
    }
107
108
    /**
109
     * 获取最后一次插入的主键ID(用于自增值
110
     *
111
     * @param string $name
112
     * @return string 则获取失败,整数则获取成功
113
     */
114
    public function lastInsertId(string $name = null):string
115
    {
116
        return $this->access->lastInsertId($name);
117
    }
118
119
    /**
120
     * 事务系列,开启事务
121
     *
122
     * @return void
123
     */
124
    public function beginTransaction()
125
    {
126
        $this->access->beginTransaction();
127
    }
128
129
    /**
130
     * 事务系列,提交事务
131
     *
132
     * @return void
133
     */
134
    public function commit()
135
    {
136
        $this->access->commit();
137
    }
138
139
    /**
140
     * 事务系列,撤销事务
141
     *
142
     * @return void
143
     */
144
    public function rollBack()
145
    {
146
        $this->access->rollBack();
147
    }
148
149
    /**
150
     * 创建数据
151
     *
152
     * @param object $object
153
     * @return array
154
     */
155
    protected function createDataFromObject($object)
156
    {
157
        if (\method_exists($object, '__get')) {
158
            return $this->createDataViaMagicGet($object);
159
        }
160
        return $this->createDataViaReflection($object);
161
    }
162
163
    /**
164
     * 使用魔术方法获取值
165
     *
166
     * @param object $object
167
     * @return array
168
     */
169
    protected function createDataViaMagicGet($object)
170
    {
171
        $fields = $this->access->getStruct()->getFields();
172
        $data = [];
173
        $isset = \method_exists($object, '__isset');
174
        if ($isset) {
175
            foreach ($fields as $name => $value) {
176
                if ($data->__isset($name)) {
177
                    $data[$name] = $data->__get($name);
178
                }
179
            }
180
        } else {
181
            foreach ($fields as $name => $value) {
182
                $data[$name] = $data->__get($name);
183
            }
184
        }
185
        return $data;
186
    }
187
188
    /**
189
     * 使用反射方法获取值
190
     *
191
     * @param object $object
192
     * @return array
193
     */
194
    protected function createDataViaReflection($object)
195
    {
196
        $fields = $this->access->getStruct()->getFields();
197
        $reflection = new ReflectionClass($object);
198
        $data = [];
199
        foreach ($reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE) as $property) {
200
            $name = TableStructBuilder::getFieldName($property);
201
            if ($fields->hasField($name)) {
202
                $property->setAccessible(true);
203
                $value = $property->getValue($object);
204
                if ($value !== null) {
205
                    $data[$name] = $value;
206
                }
207
            }
208
        }
209
        return $data;
210
    }
211
212
    /**
213
     * 创建表结构
214
     *
215
     * @param string $object
216
     * @return TableStruct
217
     */
218
    protected function createStruct(string $object)
219
    {
220
        $reflection = new ReflectionClass($object);
221
        $hasMethod = $reflection->implementsInterface(TableStructAwareInterface::class) || \method_exists($object, 'getTableStruct');
222
        if ($hasMethod) {
223
            return $reflection->getMethod('getTableStruct')->invoke(null);
224
        }
225
        return (new TableStructBuilder($object))->createStruct();
226
    }
227
228
    /**
229
     * 获取表结构
230
     *
231
     * @return \suda\orm\TableStruct
232
     */
233
    public function getStruct():TableStruct
234
    {
235
        return $this->access->getStruct();
236
    }
237
238
    /**
239
     * 获取表名
240
     *
241
     * @return string
242
     */
243
    public function getName():string
244
    {
245
        return $this->access->getName();
246
    }
247
}
248