Test Failed
Push — master ( 3c3be4...ec7459 )
by Ricardo Jesus Ruiz
02:59
created

CI_DB_result   F

Complexity

Total Complexity 81

Size/Duplication

Total Lines 613
Duplicated Lines 15.66 %

Importance

Changes 0
Metric Value
dl 96
loc 613
rs 1.5378
c 0
b 0
f 0
wmc 81

23 Methods

Rating   Name   Duplication   Size   Complexity  
A first_row() 0 4 2
A __construct() 0 4 1
A unbuffered_row() 0 12 3
A result() 0 13 3
A row_object() 14 14 4
C result_object() 32 32 8
A previous_row() 0 13 3
A num_fields() 0 3 1
A last_row() 0 4 2
A _fetch_assoc() 0 3 1
C custom_result_object() 0 46 11
A next_row() 0 11 3
B row() 0 19 7
B custom_row_object() 0 15 5
B set_row() 0 20 6
A list_fields() 0 3 1
A free_result() 0 3 1
C result_array() 32 32 8
A _fetch_object() 0 3 1
A field_data() 0 3 1
A row_array() 14 14 4
A num_rows() 0 16 4
A data_seek() 0 3 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like CI_DB_result often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CI_DB_result, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP
6
 *
7
 * This content is released under the MIT License (MIT)
8
 *
9
 * Copyright (c) 2014 - 2017, British Columbia Institute of Technology
10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a copy
12
 * of this software and associated documentation files (the "Software"), to deal
13
 * in the Software without restriction, including without limitation the rights
14
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
 * copies of the Software, and to permit persons to whom the Software is
16
 * furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies or substantial portions of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
 * THE SOFTWARE.
28
 *
29
 * @package	CodeIgniter
30
 * @author	EllisLab Dev Team
31
 * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
32
 * @copyright	Copyright (c) 2014 - 2017, British Columbia Institute of Technology (http://bcit.ca/)
33
 * @license	http://opensource.org/licenses/MIT	MIT License
34
 * @link	https://codeigniter.com
35
 * @since	Version 1.0.0
36
 * @filesource
37
 */
38
namespace Rioxygen\CiCoreDatabase;
39
40
/**
41
 * Database Result Class
42
 *
43
 * This is the platform-independent result class.
44
 * This class will not be called directly. Rather, the adapter
45
 * class for the specific database will extend and instantiate it.
46
 *
47
 * @category	Database
48
 * @author		EllisLab Dev Team
49
 * @link		https://codeigniter.com/user_guide/database/
50
 */
51
class CI_DB_result {
52
53
	/**
54
	 * Connection ID
55
	 *
56
	 * @var	resource|object
57
	 */
58
	public $conn_id;
59
60
	/**
61
	 * Result ID
62
	 *
63
	 * @var	resource|object
64
	 */
65
	public $result_id;
66
67
	/**
68
	 * Result Array
69
	 *
70
	 * @var	array[]
71
	 */
72
	public $result_array			= array();
73
74
	/**
75
	 * Result Object
76
	 *
77
	 * @var	object[]
78
	 */
79
	public $result_object			= array();
80
81
	/**
82
	 * Custom Result Object
83
	 *
84
	 * @var	object[]
85
	 */
86
	public $custom_result_object		= array();
87
88
	/**
89
	 * Current Row index
90
	 *
91
	 * @var	int
92
	 */
93
	public $current_row			= 0;
94
95
	/**
96
	 * Number of rows
97
	 *
98
	 * @var	int
99
	 */
100
	public $num_rows;
101
102
	/**
103
	 * Row data
104
	 *
105
	 * @var	array
106
	 */
107
	public $row_data;
108
109
	// --------------------------------------------------------------------
110
111
	/**
112
	 * Constructor
113
	 *
114
	 * @param	object	$driver_object
115
	 * @return	void
116
	 */
117
	public function __construct(&$driver_object)
118
	{
119
		$this->conn_id = $driver_object->conn_id;
120
		$this->result_id = $driver_object->result_id;
121
	}
122
123
	// --------------------------------------------------------------------
124
125
	/**
126
	 * Number of rows in the result set
127
	 *
128
	 * @return	int
129
	 */
130
	public function num_rows()
131
	{
132
		if (is_int($this->num_rows))
133
		{
134
			return $this->num_rows;
135
		}
136
		elseif (count($this->result_array) > 0)
137
		{
138
			return $this->num_rows = count($this->result_array);
139
		}
140
		elseif (count($this->result_object) > 0)
141
		{
142
			return $this->num_rows = count($this->result_object);
143
		}
144
145
		return $this->num_rows = count($this->result_array());
146
	}
147
148
	// --------------------------------------------------------------------
149
150
	/**
151
	 * Query result. Acts as a wrapper function for the following functions.
152
	 *
153
	 * @param	string	$type	'object', 'array' or a custom class name
154
	 * @return	array
155
	 */
156
	public function result($type = 'object')
157
	{
158
		if ($type === 'array')
159
		{
160
			return $this->result_array();
161
		}
162
		elseif ($type === 'object')
163
		{
164
			return $this->result_object();
165
		}
166
		else
167
		{
168
			return $this->custom_result_object($type);
169
		}
170
	}
171
172
	// --------------------------------------------------------------------
173
174
	/**
175
	 * Custom query result.
176
	 *
177
	 * @param	string	$class_name
178
	 * @return	array
179
	 */
180
	public function custom_result_object($class_name)
181
	{
182
		if (isset($this->custom_result_object[$class_name]))
183
		{
184
			return $this->custom_result_object[$class_name];
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->custom_result_object[$class_name] returns the type object which is incompatible with the documented return type array.
Loading history...
185
		}
186
		elseif ( ! $this->result_id OR $this->num_rows === 0)
187
		{
188
			return array();
189
		}
190
191
		// Don't fetch the result set again if we already have it
192
		$_data = NULL;
193
		if (($c = count($this->result_array)) > 0)
194
		{
195
			$_data = 'result_array';
196
		}
197
		elseif (($c = count($this->result_object)) > 0)
198
		{
199
			$_data = 'result_object';
200
		}
201
202
		if ($_data !== NULL)
203
		{
204
			for ($i = 0; $i < $c; $i++)
205
			{
206
				$this->custom_result_object[$class_name][$i] = new $class_name();
207
208
				foreach ($this->{$_data}[$i] as $key => $value)
209
				{
210
					$this->custom_result_object[$class_name][$i]->$key = $value;
211
				}
212
			}
213
214
			return $this->custom_result_object[$class_name];
215
		}
216
217
		is_null($this->row_data) OR $this->data_seek(0);
218
		$this->custom_result_object[$class_name] = array();
219
220
		while ($row = $this->_fetch_object($class_name))
221
		{
222
			$this->custom_result_object[$class_name][] = $row;
223
		}
224
225
		return $this->custom_result_object[$class_name];
226
	}
227
228
	// --------------------------------------------------------------------
229
230
	/**
231
	 * Query result. "object" version.
232
	 *
233
	 * @return	array
234
	 */
235 View Code Duplication
	public function result_object()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
236
	{
237
		if (count($this->result_object) > 0)
238
		{
239
			return $this->result_object;
240
		}
241
242
		// In the event that query caching is on, the result_id variable
243
		// will not be a valid resource so we'll simply return an empty
244
		// array.
245
		if ( ! $this->result_id OR $this->num_rows === 0)
246
		{
247
			return array();
248
		}
249
250
		if (($c = count($this->result_array)) > 0)
251
		{
252
			for ($i = 0; $i < $c; $i++)
253
			{
254
				$this->result_object[$i] = (object) $this->result_array[$i];
255
			}
256
257
			return $this->result_object;
258
		}
259
260
		is_null($this->row_data) OR $this->data_seek(0);
261
		while ($row = $this->_fetch_object())
262
		{
263
			$this->result_object[] = $row;
264
		}
265
266
		return $this->result_object;
267
	}
268
269
	// --------------------------------------------------------------------
270
271
	/**
272
	 * Query result. "array" version.
273
	 *
274
	 * @return	array
275
	 */
276 View Code Duplication
	public function result_array()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
277
	{
278
		if (count($this->result_array) > 0)
279
		{
280
			return $this->result_array;
281
		}
282
283
		// In the event that query caching is on, the result_id variable
284
		// will not be a valid resource so we'll simply return an empty
285
		// array.
286
		if ( ! $this->result_id OR $this->num_rows === 0)
287
		{
288
			return array();
289
		}
290
291
		if (($c = count($this->result_object)) > 0)
292
		{
293
			for ($i = 0; $i < $c; $i++)
294
			{
295
				$this->result_array[$i] = (array) $this->result_object[$i];
296
			}
297
298
			return $this->result_array;
299
		}
300
301
		is_null($this->row_data) OR $this->data_seek(0);
302
		while ($row = $this->_fetch_assoc())
303
		{
304
			$this->result_array[] = $row;
305
		}
306
307
		return $this->result_array;
308
	}
309
310
	// --------------------------------------------------------------------
311
312
	/**
313
	 * Row
314
	 *
315
	 * A wrapper method.
316
	 *
317
	 * @param	mixed	$n
318
	 * @param	string	$type	'object' or 'array'
319
	 * @return	mixed
320
	 */
321
	public function row($n = 0, $type = 'object')
322
	{
323
		if ( ! is_numeric($n))
324
		{
325
			// We cache the row data for subsequent uses
326
			is_array($this->row_data) OR $this->row_data = $this->row_array(0);
327
328
			// array_key_exists() instead of isset() to allow for NULL values
329
			if (empty($this->row_data) OR ! array_key_exists($n, $this->row_data))
330
			{
331
				return NULL;
332
			}
333
334
			return $this->row_data[$n];
335
		}
336
337
		if ($type === 'object') return $this->row_object($n);
338
		elseif ($type === 'array') return $this->row_array($n);
339
		else return $this->custom_row_object($n, $type);
340
	}
341
342
	// --------------------------------------------------------------------
343
344
	/**
345
	 * Assigns an item into a particular column slot
346
	 *
347
	 * @param	mixed	$key
348
	 * @param	mixed	$value
349
	 * @return	void
350
	 */
351
	public function set_row($key, $value = NULL)
352
	{
353
		// We cache the row data for subsequent uses
354
		if ( ! is_array($this->row_data))
355
		{
356
			$this->row_data = $this->row_array(0);
357
		}
358
359
		if (is_array($key))
360
		{
361
			foreach ($key as $k => $v)
362
			{
363
				$this->row_data[$k] = $v;
364
			}
365
			return;
366
		}
367
368
		if ($key !== '' && $value !== NULL)
369
		{
370
			$this->row_data[$key] = $value;
371
		}
372
	}
373
374
	// --------------------------------------------------------------------
375
376
	/**
377
	 * Returns a single result row - custom object version
378
	 *
379
	 * @param	int	$n
380
	 * @param	string	$type
381
	 * @return	object
382
	 */
383
	public function custom_row_object($n, $type)
384
	{
385
		isset($this->custom_result_object[$type]) OR $this->custom_result_object($type);
386
387
		if (count($this->custom_result_object[$type]) === 0)
388
		{
389
			return NULL;
390
		}
391
392
		if ($n !== $this->current_row && isset($this->custom_result_object[$type][$n]))
393
		{
394
			$this->current_row = $n;
395
		}
396
397
		return $this->custom_result_object[$type][$this->current_row];
398
	}
399
400
	// --------------------------------------------------------------------
401
402
	/**
403
	 * Returns a single result row - object version
404
	 *
405
	 * @param	int	$n
406
	 * @return	object
407
	 */
408 View Code Duplication
	public function row_object($n = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
409
	{
410
		$result = $this->result_object();
411
		if (count($result) === 0)
412
		{
413
			return NULL;
414
		}
415
416
		if ($n !== $this->current_row && isset($result[$n]))
417
		{
418
			$this->current_row = $n;
419
		}
420
421
		return $result[$this->current_row];
422
	}
423
424
	// --------------------------------------------------------------------
425
426
	/**
427
	 * Returns a single result row - array version
428
	 *
429
	 * @param	int	$n
430
	 * @return	array
431
	 */
432 View Code Duplication
	public function row_array($n = 0)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
433
	{
434
		$result = $this->result_array();
435
		if (count($result) === 0)
436
		{
437
			return NULL;
438
		}
439
440
		if ($n !== $this->current_row && isset($result[$n]))
441
		{
442
			$this->current_row = $n;
443
		}
444
445
		return $result[$this->current_row];
446
	}
447
448
	// --------------------------------------------------------------------
449
450
	/**
451
	 * Returns the "first" row
452
	 *
453
	 * @param	string	$type
454
	 * @return	mixed
455
	 */
456
	public function first_row($type = 'object')
457
	{
458
		$result = $this->result($type);
459
		return (count($result) === 0) ? NULL : $result[0];
460
	}
461
462
	// --------------------------------------------------------------------
463
464
	/**
465
	 * Returns the "last" row
466
	 *
467
	 * @param	string	$type
468
	 * @return	mixed
469
	 */
470
	public function last_row($type = 'object')
471
	{
472
		$result = $this->result($type);
473
		return (count($result) === 0) ? NULL : $result[count($result) - 1];
474
	}
475
476
	// --------------------------------------------------------------------
477
478
	/**
479
	 * Returns the "next" row
480
	 *
481
	 * @param	string	$type
482
	 * @return	mixed
483
	 */
484
	public function next_row($type = 'object')
485
	{
486
		$result = $this->result($type);
487
		if (count($result) === 0)
488
		{
489
			return NULL;
490
		}
491
492
		return isset($result[$this->current_row + 1])
493
			? $result[++$this->current_row]
494
			: NULL;
495
	}
496
497
	// --------------------------------------------------------------------
498
499
	/**
500
	 * Returns the "previous" row
501
	 *
502
	 * @param	string	$type
503
	 * @return	mixed
504
	 */
505
	public function previous_row($type = 'object')
506
	{
507
		$result = $this->result($type);
508
		if (count($result) === 0)
509
		{
510
			return NULL;
511
		}
512
513
		if (isset($result[$this->current_row - 1]))
514
		{
515
			--$this->current_row;
516
		}
517
		return $result[$this->current_row];
518
	}
519
520
	// --------------------------------------------------------------------
521
522
	/**
523
	 * Returns an unbuffered row and move pointer to next row
524
	 *
525
	 * @param	string	$type	'array', 'object' or a custom class name
526
	 * @return	mixed
527
	 */
528
	public function unbuffered_row($type = 'object')
529
	{
530
		if ($type === 'array')
531
		{
532
			return $this->_fetch_assoc();
533
		}
534
		elseif ($type === 'object')
535
		{
536
			return $this->_fetch_object();
537
		}
538
539
		return $this->_fetch_object($type);
540
	}
541
542
	// --------------------------------------------------------------------
543
544
	/**
545
	 * The following methods are normally overloaded by the identically named
546
	 * methods in the platform-specific driver -- except when query caching
547
	 * is used. When caching is enabled we do not load the other driver.
548
	 * These functions are primarily here to prevent undefined function errors
549
	 * when a cached result object is in use. They are not otherwise fully
550
	 * operational due to the unavailability of the database resource IDs with
551
	 * cached results.
552
	 */
553
554
	// --------------------------------------------------------------------
555
556
	/**
557
	 * Number of fields in the result set
558
	 *
559
	 * Overridden by driver result classes.
560
	 *
561
	 * @return	int
562
	 */
563
	public function num_fields()
564
	{
565
		return 0;
566
	}
567
568
	// --------------------------------------------------------------------
569
570
	/**
571
	 * Fetch Field Names
572
	 *
573
	 * Generates an array of column names.
574
	 *
575
	 * Overridden by driver result classes.
576
	 *
577
	 * @return	array
578
	 */
579
	public function list_fields()
580
	{
581
		return array();
582
	}
583
584
	// --------------------------------------------------------------------
585
586
	/**
587
	 * Field data
588
	 *
589
	 * Generates an array of objects containing field meta-data.
590
	 *
591
	 * Overridden by driver result classes.
592
	 *
593
	 * @return	array
594
	 */
595
	public function field_data()
596
	{
597
		return array();
598
	}
599
600
	// --------------------------------------------------------------------
601
602
	/**
603
	 * Free the result
604
	 *
605
	 * Overridden by driver result classes.
606
	 *
607
	 * @return	void
608
	 */
609
	public function free_result()
610
	{
611
		$this->result_id = FALSE;
612
	}
613
614
	// --------------------------------------------------------------------
615
616
	/**
617
	 * Data Seek
618
	 *
619
	 * Moves the internal pointer to the desired offset. We call
620
	 * this internally before fetching results to make sure the
621
	 * result set starts at zero.
622
	 *
623
	 * Overridden by driver result classes.
624
	 *
625
	 * @param	int	$n
626
	 * @return	bool
627
	 */
628
	public function data_seek($n = 0)
629
	{
630
		return FALSE;
631
	}
632
633
	// --------------------------------------------------------------------
634
635
	/**
636
	 * Result - associative array
637
	 *
638
	 * Returns the result set as an array.
639
	 *
640
	 * Overridden by driver result classes.
641
	 *
642
	 * @return	array
643
	 */
644
	protected function _fetch_assoc()
645
	{
646
		return array();
647
	}
648
649
	// --------------------------------------------------------------------
650
651
	/**
652
	 * Result - object
653
	 *
654
	 * Returns the result set as an object.
655
	 *
656
	 * Overridden by driver result classes.
657
	 *
658
	 * @param	string	$class_name
659
	 * @return	object
660
	 */
661
	protected function _fetch_object($class_name = 'stdClass')
662
	{
663
		return new $class_name();
664
	}
665
666
}
667