Table::getRegistry()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 7
Bugs 1 Features 0
Metric Value
c 7
b 1
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
/**
3
 * Fwk
4
 *
5
 * Copyright (c) 2011-2012, Julien Ballestracci <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
15
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
16
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
17
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
20
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
21
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
22
 * POSSIBILITY OF SUCH DAMAGE.
23
 *
24
 * PHP Version 5.3
25
 * 
26
 * @category  Database
27
 * @package   Fwk\Db
28
 * @author    Julien Ballestracci <[email protected]>
29
 * @copyright 2011-2012 Julien Ballestracci <[email protected]>
30
 * @license   http://www.opensource.org/licenses/bsd-license.php  BSD License
31
 * @link      http://www.phpfwk.com
32
 */
33
namespace Fwk\Db;
34
35
use Fwk\Db\Registry\Registry;
36
37
/**
38
 * Table 
39
 * 
40
 * Represents a database table. 
41
 * 
42
 * @category Library
43
 * @package  Fwk\Db
44
 * @author   Julien Ballestracci <[email protected]>
45
 * @license  http://www.opensource.org/licenses/bsd-license.php  BSD License
46
 * @link     http://www.phpfwk.com
47
 */
48
class Table
49
{
50
    /**
51
     * Table name
52
     *
53
     * @var string
54
     */
55
    protected $name;
56
57
    /**
58
     * Connection
59
     *
60
     * @var Connection
61
     */
62
    protected $connection;
63
64
    /**
65
     * Array of primary keys
66
     *
67
     * @var array
68
     */
69
    protected $identifiersKey;
70
71
    /**
72
     * Entity registry
73
     *
74
     * @var Registry
75
     */
76
    protected $registry;
77
78
    /**
79
     * Classname of the default entity for this table
80
     *
81
     * @var string
82
     */
83
    protected $defaultEntity;
84
85
    /**
86
     * List of default entity listeners to be used with this table
87
     *
88
     * @var array
89
     */
90
    protected $defaultEntityListeners = array();
91
92
    /**
93
     * Constructor
94
     *
95
     * @param string $tableName This table name
96
     * 
97
     * @return void
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
98
     */
99
    public function __construct($tableName)
100
    {
101
        $this->name     = $tableName;
102
    }
103
104
    /**
105
     * Returns all columns from this table
106
     *
107
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use \Doctrine\DBAL\Schema\Column[].

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
108
     */
109
    public function getColumns()
110
    {
111
        return $this
112
            ->getConnection()
113
            ->getSchema()
114
            ->getTable($this->name)
115
            ->getColumns();
116
    }
117
118
    /**
119
     * Defines a connection for this table
120
     *
121
     * @param Connection $connection Database connection
122
     * 
123
     * @return Table
124
     */
125
    public function setConnection(Connection $connection)
126
    {
127
        $this->connection   = $connection;
128
129
        return $this;
130
    }
131
132
    /**
133
     * Returns current connection for this table
134
     *
135
     * @throws Exception If no connection is defined
136
     * @return Connection
137
     */
138
    public function getConnection()
139
    {
140
        if (!isset($this->connection)) {
141
            throw new Exception(
142
                sprintf(
143
                    'No connection defined for table "%s"', 
144
                    $this->name
145
                )
146
            );
147
        }
148
149
        return $this->connection;
150
    }
151
152
    /**
153
     * Returns a Finder instance to navigate into this table
154
     *
155
     * @param string $entity    Entity class to be returned by this Finder
0 ignored issues
show
Documentation introduced by
Should the type for parameter $entity not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
156
     * @param array  $listeners Overrides default entity/table listeners
157
     *
158
     * @return Finder
159
     */
160
    public function finder($entity = null, array $listeners = array())
161
    {
162
163
        $finder = new Finder($this, $this->connection);
164
        $finder->setEntity($entity, $listeners);
165
166
        return $finder;
167
    }
168
169
    /**
170
     * Returns this table's name
171
     *
172
     * @return string
173
     */
174
    public function getName()
175
    {
176
177
        return $this->name;
178
    }
179
180
    /**
181
     * Returns primary identifiers keys for this table
182
     *
183
     * @throws Exceptions\TableLacksIdentifiersException
184
     *
185
     * @return array
186
     */
187
    public function getIdentifiersKeys()
188
    {
189
        if (!isset($this->identifiersKey)) {
190
            $idx = $this
191
                ->getConnection()
192
                ->getSchema()
193
                ->getTable($this->name)
194
                ->getIndexes();
195
196
            if (!count($idx)) {
197
                throw new Exceptions\TableLacksIdentifiersException(
198
                    sprintf('"%s" has no indexes', $this->name)
199
                );
200
            }
201
202
            $final = array();
203
            foreach ($idx as $index) {
204
                if ($index->isPrimary()) {
205
                    $final += $index->getColumns();
206
                }
207
            }
208
209
            $final = array_unique($final);
210
            if (!count($final)) {
211
                throw new Exceptions\TableLacksIdentifiersException(
212
                    sprintf('"%s" has no identifiers key(s)', $this->name)
213
                );
214
            }
215
216
            $this->identifiersKey = $final;
217
        }
218
219
        return $this->identifiersKey;
220
    }
221
222
    /**
223
     * Returns the entity registry for this table
224
     *
225
     * @return Registry
226
     */
227
    public function getRegistry()
228
    {
229
        if (!isset($this->registry)) {
230
            $this->registry = new Registry($this->name);
231
        }
232
233
        return $this->registry;
234
    }
235
236
    /**
237
     * Returns an object representation of a given column
238
     *
239
     * @param string $columnName Column name
240
     * 
241
     * @return \Doctrine\DBAL\Schema\Column
242
     */
243
    public function getColumn($columnName)
244
    {
245
        if (!$this->hasColumn($columnName)) {
246
            throw new Exceptions\TableColumnNotFoundException(
247
                sprintf(
248
                    'Unknown Column "%s" on table %s',
249
                    $columnName,
250
                    $this->name
251
                )
252
            );
253
        }
254
255
        return $this->getConnection()
256
            ->getSchema()
257
            ->getTable($this->name)
258
            ->getColumn($columnName);
259
    }
260
261
    /**
262
     * Tells if this table has a column named $columnName
263
     * 
264
     * @param string $columnName Column name
265
     * 
266
     * @return boolean 
267
     */
268
    public function hasColumn($columnName)
269
    {
270
        $tbl = $this->getConnection()->getSchema()->getTable($this->name);
271
272
        return $tbl->hasColumn($columnName);
273
    }
274
275
    /**
276
     * Defines the default returned entity
277
     * 
278
     * @param string $entityClass Entity class name
279
     * 
280
     * @return Table 
281
     */
282
    public function setDefaultEntity($entityClass)
283
    {
284
        $this->defaultEntity = (string)$entityClass;
285
286
        return $this;
287
    }
288
289
    /**
290
     * Returns the default returned entity for this table
291
     * 
292
     * @return string 
293
     */
294
    public function getDefaultEntity()
295
    {
296
        if (!isset($this->defaultEntity)) {
297
            $this->defaultEntity = '\stdClass';
298
        }
299
300
        return $this->defaultEntity;
301
    }
302
303
    /**
304
     * Defines the default entity listeners to be used with this table
305
     *
306
     * @param array $listeners List of listeners
307
     *
308
     * @return Table
309
     */
310
    public function setDefaultEntityListeners(array $listeners)
311
    {
312
        $this->defaultEntityListeners = $listeners;
313
314
        return $this;
315
    }
316
317
    /**
318
     * Returns the default entity listeners used this table
319
     *
320
     * @return array
321
     */
322
    public function getDefaultEntityListeners()
323
    {
324
        return $this->defaultEntityListeners;
325
    }
326
327
    /**
328
     * Save one or more entities into this table
329
     * 
330
     * @param mixed $entity    Entity or List of entities
331
     * @param array $listeners Overrides default entity/table listeners
332
     * 
333
     * @return void 
334
     */
335
    public function save($entity, array $listeners = array())
336
    {
337
        if (!\is_array($entity)) {
338
            $entity = array($entity);
339
        }
340
        
341
        foreach ($entity as $object) {
342
            if (!\is_object($object) || is_null($object)) {
343
                throw new \InvalidArgumentException(
344
                    sprintf(
345
                        "You can only save an object or a list of objects"
346
                    )
347
                );
348
            }
349
            
350
            $this->getRegistry()->markForAction(
351
                $object,
352
                Registry::ACTION_SAVE,
353
                (count($listeners) ? $listeners : $this->getDefaultEntityListeners())
354
            );
355
        }
356
357
        $this->work();
358
    }
359
360
    /**
361
     * Delete one or more entities from this table
362
     * 
363
     * @param mixed $entity    Entity or List of entities
364
     * @param array $listeners Overrides default entity listeners
365
     * 
366
     * @return void 
367
     */
368
    public function delete($entity, array $listeners = array())
369
    {
370
        if (!\is_array($entity)) {
371
            $entity = array($entity);
372
        }
373
374
        foreach ($entity as $object) {
375
            if (!\is_object($object) || is_null($object)) {
376
                throw new \InvalidArgumentException(
377
                    sprintf(
378
                        "You can only save an object or a list of objects"
379
                    )
380
                );
381
            }
382
383
            $this->getRegistry()->markForAction(
384
                $object, 
385
                Registry::ACTION_DELETE,
386
                (count($listeners) ? $listeners : $this->getDefaultEntityListeners())
387
            );
388
        }
389
390
        $this->work();
391
    }
392
393
    /**
394
     * Executes all waiting workers
395
     * 
396
     * @return void
397
     */
398
    protected function work()
399
    {
400
        $queue          = $this->getRegistry()->getWorkersQueue();
401
        $connection     = $this->getConnection();
402
403
        foreach ($queue as $worker) {
404
            $worker->execute($connection);
405
        }
406
    }
407
408
    /**
409
     * Delete all entries from this table
410
     * 
411
     * @return void 
412
     */
413
    public function deleteAll()
414
    {
415
        $query = Query::factory()->delete($this->getName());
416
        $this->getConnection()->execute($query);
417
    }
418
}