Passed
Push — master ( a325c0...46b506 )
by 世昌
02:20
created

DataAccess::commit()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
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\middleware\Middleware;
10
use suda\orm\struct\QueryStatement;
11
use suda\orm\struct\WriteStatement;
12
use suda\orm\middleware\NullMiddleware;
13
use suda\orm\struct\TableStructBuilder;
14
use suda\orm\struct\TableStructMiddleware;
15
use suda\orm\struct\TableStructAwareInterface;
16
use suda\orm\middleware\MiddlewareAwareInterface;
17
18
/**
19
 * 数据访问
20
 */
21
class DataAccess
22
{
23
24
    /**
25
     * 数据源
26
     *
27
     * @var TableAccess
28
     */
29
    protected $access;
30
31
    /**
32
     * 数据类型
33
     *
34
     * @var string
35
     */
36
    protected $type;
37
38
    /**
39
     * 创建对数据的操作
40
     *
41
     * @param string $object
42
     * @param \suda\orm\DataSource $source
43
     * @param Middleware|null $middleware
44
     */
45
    public function __construct(string $object, DataSource $source, ?Middleware $middleware = null)
46
    {
47
        $this->type = $object;
48
        $struct = $this->createStruct($object);
49
        $middleware = $middleware ?? $this->createMiddleware($object, $struct);
50
        $this->access = new TableAccess($struct, $source, $middleware);
51
    }
52
53
    /**
54
     * 读取数据
55
     *
56
     * @param array|string $fields
57
     * @return \suda\orm\struct\ReadStatement
58
     */
59
    public function read(...$fields): ReadStatement
60
    {
61
        return $this->access->read(...$fields)->wantType($this->type);
62
    }
63
    
64
    /**
65
     * 写数据
66
     *
67
     * @param array|object $object
68
     * @return \suda\orm\struct\WriteStatement
69
     */
70
    public function write($object): WriteStatement
71
    {
72
        if (\is_object($object)) {
73
            $object = $this->createDataFromObject($object);
74
        }
75
        return $this->access->write($object);
76
    }
77
78
    /**
79
     * 统计计数
80
     *
81
     * @param string|array|object $where
82
     * @param array $whereBinder
83
     * @return integer
84
     */
85
    public function count($where, array $whereBinder = []):int
86
    {
87
        if (\is_object($where)) {
88
            $where = $this->createDataFromObject($where);
89
        }
90
        $fields = $this->access->getStruct()->getFields()->all();
91
        $field = \array_shift($fields);
92
        $total = $this->access->read([$field->getName()])->where($where, $whereBinder);
93
        $data = $this->access->query('SELECT count(*) as `count` from ('.$total.') as total', $total->getBinder())->one();
94
        return intval($data['count']);
95
    }
96
97
    /**
98
     * 查询语句
99
     *
100
     * @param string $query
101
     * @param mixed ...$parameter
102
     * @return QueryStatement
103
     */
104
    public function query(string $query, ...$parameter):QueryStatement
105
    {
106
        return $this->access->query($query, ...$parameter);
107
    }
108
109
    /**
110
     * 获取最后一次插入的主键ID(用于自增值
111
     *
112
     * @param string $name
113
     * @return string 则获取失败,整数则获取成功
114
     */
115
    public function lastInsertId(string $name = null):string
116
    {
117
        return $this->access->lastInsertId($name);
118
    }
119
120
    /**
121
     * 事务系列,开启事务
122
     *
123
     * @return void
124
     */
125
    public function beginTransaction()
126
    {
127
        $this->access->beginTransaction();
128
    }
129
130
    /**
131
     * 事务系列,提交事务
132
     *
133
     * @return void
134
     */
135
    public function commit()
136
    {
137
        $this->access->commit();
138
    }
139
140
    /**
141
     * 事务系列,撤销事务
142
     *
143
     * @return void
144
     */
145
    public function rollBack()
146
    {
147
        $this->access->rollBack();
148
    }
149
150
    /**
151
     * 创建数据
152
     *
153
     * @param object $object
154
     * @return array
155
     */
156
    protected function createDataFromObject($object)
157
    {
158
        if (\method_exists($object, '__get')) {
159
            return $this->createDataViaMagicGet($object);
160
        }
161
        return $this->createDataViaReflection($object);
162
    }
163
164
    /**
165
     * 使用魔术方法获取值
166
     *
167
     * @param object $object
168
     * @return array
169
     */
170
    protected function createDataViaMagicGet($object)
171
    {
172
        $fields = $this->access->getStruct()->getFields();
173
        $data = [];
174
        $isset = \method_exists($object, '__isset');
175
        if ($isset) {
176
            foreach ($fields as $name => $value) {
177
                if ($object->__isset($name)) {
178
                    $dataField = $this->access->getMiddleware()->inputName($name);
179
                    $data[$dataField] = $object->__get($name);
180
                }
181
            }
182
        } else {
183
            foreach ($fields as $name => $value) {
184
                $dataField = $this->access->getMiddleware()->inputName($name);
185
                $data[$dataField] = $object->__get($name);
186
            }
187
        }
188
        return $data;
189
    }
190
191
    /**
192
     * 使用反射方法获取值
193
     *
194
     * @param object $object
195
     * @return array
196
     */
197
    protected function createDataViaReflection($object)
198
    {
199
        $reflection = new ReflectionClass($object);
200
        $data = [];
201
        foreach ($reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED | ReflectionProperty::IS_PRIVATE) as $property) {
202
            if (TableStructBuilder::isTableField($property)) {
203
                $property->setAccessible(true);
204
                $value = $property->getValue($object);
205
                if ($value !== null) {
206
                    $dataField = $this->access->getMiddleware()->inputName($property->getName());
207
                    $data[$dataField] = $value;
208
                }
209
            }
210
        }
211
        return $data;
212
    }
213
214
    /**
215
     * 创建表结构
216
     *
217
     * @param string $object
218
     * @return TableStruct
219
     */
220
    protected function createStruct(string $object)
221
    {
222
        if (is_subclass_of($object, TableStructAwareInterface::class)) {
223
            return $object::getTableStruct();
224
        }
225
        return (new TableStructBuilder($object))->createStruct();
226
    }
227
228
    /**
229
     * 创建中间件
230
     *
231
     * @param string $object
232
     * @param TableStruct $struct
233
     * @return Middleware
234
     */
235
    protected function createMiddleware(string $object, TableStruct $struct)
236
    {
237
        if (is_subclass_of($object, MiddlewareAwareInterface::class)) {
238
            return $object::getMiddleware($struct);
239
        }
240
        return new NullMiddleware;
241
    }
242
243
    /**
244
     * 获取表结构
245
     *
246
     * @return \suda\orm\TableStruct
247
     */
248
    public function getStruct():TableStruct
249
    {
250
        return $this->access->getStruct();
251
    }
252
253
    /**
254
     * 获取表名
255
     *
256
     * @return string
257
     */
258
    public function getName():string
259
    {
260
        return $this->access->getName();
261
    }
262
}
263