Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Add seed values support for Query Builder order_by

(feature request #1987)
  • Loading branch information...
commit 98e46cf96447a2a6448d8dc984948a8694dbf747 1 parent 9e94576
Andrey Andreev narfbg authored

Showing 22 changed files with 166 additions and 41 deletions. Show diff stats Hide diff stats

  1. +2 2 system/database/DB_driver.php
  2. +8 5 system/database/DB_query_builder.php
  3. +7 0 system/database/drivers/cubrid/cubrid_driver.php
  4. +2 2 system/database/drivers/ibase/ibase_driver.php
  5. +2 2 system/database/drivers/mssql/mssql_driver.php
  6. +2 2 system/database/drivers/oci8/oci8_driver.php
  7. +7 2 system/database/drivers/odbc/odbc_driver.php
  8. +7 0 system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
  9. +2 2 system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
  10. +2 2 system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
  11. +9 0 system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
  12. +2 2 system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
  13. +7 0 system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
  14. +37 2 system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
  15. +1 1  system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
  16. +2 2 system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
  17. +37 2 system/database/drivers/postgre/postgre_driver.php
  18. +2 2 system/database/drivers/sqlite/sqlite_driver.php
  19. +2 2 system/database/drivers/sqlite3/sqlite3_driver.php
  20. +2 2 system/database/drivers/sqlsrv/sqlsrv_driver.php
  21. +1 0  user_guide_src/source/changelog.rst
  22. +23 7 user_guide_src/source/database/query_builder.rst
4 system/database/DB_driver.php
@@ -329,9 +329,9 @@
329 329 /**
330 330 * ORDER BY random keyword
331 331 *
332   - * @var string
  332 + * @var array
333 333 */
334   - protected $_random_keyword = ' RAND()';
  334 + protected $_random_keyword = array('RAND()', 'RAND(%d)');
335 335
336 336 /**
337 337 * COUNT string
13 system/database/DB_query_builder.php
@@ -1144,13 +1144,16 @@ public function or_having($key, $value = NULL, $escape = NULL)
1144 1144 */
1145 1145 public function order_by($orderby, $direction = '', $escape = NULL)
1146 1146 {
1147   - $direction = trim($direction);
  1147 + $direction = strtoupper(trim($direction));
1148 1148
1149   - if (strtolower($direction) === 'random' OR $orderby === $this->_random_keyword)
  1149 + if ($direction === 'RANDOM')
1150 1150 {
1151   - // Random ordered results don't need a field name
1152   - $orderby = $this->_random_keyword;
1153 1151 $direction = '';
  1152 +
  1153 + // Do we have a seed value?
  1154 + $orderby = ctype_digit((string) $orderby)
  1155 + ? $orderby = sprintf($this->_random_keyword[1], $orderby)
  1156 + : $this->_random_keyword[0];
1154 1157 }
1155 1158 elseif (empty($orderby))
1156 1159 {
@@ -1158,7 +1161,7 @@ public function order_by($orderby, $direction = '', $escape = NULL)
1158 1161 }
1159 1162 elseif ($direction !== '')
1160 1163 {
1161   - $direction = in_array(strtoupper(trim($direction)), array('ASC', 'DESC'), TRUE) ? ' '.$direction : '';
  1164 + $direction = in_array($direction, array('ASC', 'DESC'), TRUE) ? ' '.$direction : '';
1162 1165 }
1163 1166
1164 1167 is_bool($escape) OR $escape = $this->_protect_identifiers;
7 system/database/drivers/cubrid/cubrid_driver.php
@@ -64,6 +64,13 @@ class CI_DB_cubrid_driver extends CI_DB {
64 64 */
65 65 protected $_escape_char = '`';
66 66
  67 + /**
  68 + * ORDER BY random keyword
  69 + *
  70 + * @var array
  71 + */
  72 + protected $_random_keyword = array('RANDOM()', 'RANDOM(%d)');
  73 +
67 74 // --------------------------------------------------------------------
68 75
69 76 /**
4 system/database/drivers/ibase/ibase_driver.php
@@ -53,9 +53,9 @@ class CI_DB_ibase_driver extends CI_DB {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58   - protected $_random_keyword = ' Random()';
  58 + protected $_random_keyword = array('RAND()', 'RAND()');
59 59
60 60 /**
61 61 * IBase Transaction status flag
4 system/database/drivers/mssql/mssql_driver.php
@@ -53,9 +53,9 @@ class CI_DB_mssql_driver extends CI_DB {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58   - protected $_random_keyword = ' NEWID()';
  58 + protected $_random_keyword = array('NEWID()', 'RAND(%d)');
59 59
60 60 /**
61 61 * Quoted identifier flag
4 system/database/drivers/oci8/oci8_driver.php
@@ -102,9 +102,9 @@ class CI_DB_oci8_driver extends CI_DB {
102 102 /**
103 103 * ORDER BY random keyword
104 104 *
105   - * @var string
  105 + * @var array
106 106 */
107   - protected $_random_keyword = ' ASC'; // not currently supported
  107 + protected $_random_keyword = array('ASC', 'ASC'); // not currently supported
108 108
109 109 /**
110 110 * COUNT string
9 system/database/drivers/odbc/odbc_driver.php
@@ -73,6 +73,13 @@ class CI_DB_odbc_driver extends CI_DB {
73 73 */
74 74 protected $_like_escape_str = " {escape '%s'} ";
75 75
  76 + /**
  77 + * ORDER BY random keyword
  78 + *
  79 + * @var array
  80 + */
  81 + protected $_random_keyword = array('RND()', 'RND(%d)');
  82 +
76 83 // --------------------------------------------------------------------
77 84
78 85 /**
@@ -85,8 +92,6 @@ public function __construct($params)
85 92 {
86 93 parent::__construct($params);
87 94
88   - $this->_random_keyword = ' RND('.time().')'; // database specific random keyword
89   -
90 95 // Legacy support for DSN in the hostname field
91 96 if (empty($this->dsn))
92 97 {
7 system/database/drivers/pdo/subdrivers/pdo_cubrid_driver.php
@@ -55,6 +55,13 @@ class CI_DB_pdo_cubrid_driver extends CI_DB_pdo_driver {
55 55 */
56 56 protected $_escape_char = '`';
57 57
  58 + /**
  59 + * ORDER BY random keyword
  60 + *
  61 + * @var array
  62 + */
  63 + protected $_random_keyword = array('RANDOM()', 'RANDOM(%d)');
  64 +
58 65 // --------------------------------------------------------------------
59 66
60 67 /**
4 system/database/drivers/pdo/subdrivers/pdo_dblib_driver.php
@@ -53,9 +53,9 @@ class CI_DB_pdo_dblib_driver extends CI_DB_pdo_driver {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58   - protected $_random_keyword = ' NEWID()';
  58 + protected $_random_keyword = array('NEWID()', 'RAND(%d)');
59 59
60 60 /**
61 61 * Quoted identifier flag
4 system/database/drivers/pdo/subdrivers/pdo_firebird_driver.php
@@ -53,9 +53,9 @@ class CI_DB_pdo_firebird_driver extends CI_DB_pdo_driver {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58   - protected $_random_keyword = ' RANDOM()';
  58 + protected $_random_keyword = array('RAND()', 'RAND()');
59 59
60 60 // --------------------------------------------------------------------
61 61
9 system/database/drivers/pdo/subdrivers/pdo_informix_driver.php
@@ -51,6 +51,15 @@ class CI_DB_pdo_informix_driver extends CI_DB_pdo_driver {
51 51 // --------------------------------------------------------------------
52 52
53 53 /**
  54 + * ORDER BY random keyword
  55 + *
  56 + * @var array
  57 + */
  58 + protected $_random_keyword = array('ASC', 'ASC'); // Currently not supported
  59 +
  60 + // --------------------------------------------------------------------
  61 +
  62 + /**
54 63 * Class constructor
55 64 *
56 65 * Builds the DSN if not already set.
4 system/database/drivers/pdo/subdrivers/pdo_oci_driver.php
@@ -62,9 +62,9 @@ class CI_DB_pdo_oci_driver extends CI_DB_pdo_driver {
62 62 /**
63 63 * ORDER BY random keyword
64 64 *
65   - * @var string
  65 + * @var array
66 66 */
67   - protected $_random_keyword = ' ASC'; // Currently not supported
  67 + protected $_random_keyword = array('ASC', 'ASC'); // Currently not supported
68 68
69 69 /**
70 70 * COUNT string
7 system/database/drivers/pdo/subdrivers/pdo_odbc_driver.php
@@ -73,6 +73,13 @@ class CI_DB_pdo_odbc_driver extends CI_DB_pdo_driver {
73 73 */
74 74 protected $_like_escape_str = " {escape '%s'} ";
75 75
  76 + /**
  77 + * ORDER BY random keyword
  78 + *
  79 + * @var array
  80 + */
  81 + protected $_random_keyword = array('RND()', 'RND(%d)');
  82 +
76 83 // --------------------------------------------------------------------
77 84
78 85 /**
39 system/database/drivers/pdo/subdrivers/pdo_pgsql_driver.php
@@ -60,9 +60,9 @@ class CI_DB_pdo_pgsql_driver extends CI_DB_pdo_driver {
60 60 /**
61 61 * ORDER BY random keyword
62 62 *
63   - * @var string
  63 + * @var array
64 64 */
65   - protected $_random_keyword = ' RANDOM()';
  65 + protected $_random_keyword = array('RANDOM()', 'RANDOM()');
66 66
67 67 // --------------------------------------------------------------------
68 68
@@ -110,6 +110,41 @@ public function insert_id($name = NULL)
110 110 // --------------------------------------------------------------------
111 111
112 112 /**
  113 + * ORDER BY
  114 + *
  115 + * @param string $orderby
  116 + * @param string $direction ASC or DESC
  117 + * @param bool $escape
  118 + * @return object
  119 + */
  120 + public function order_by($orderby, $direction = '', $escape = NULL)
  121 + {
  122 + $direction = strtoupper(trim($direction));
  123 + if ($direction === 'RANDOM')
  124 + {
  125 + if ( ! is_float($orderby) && ctype_digit((string) $orderby))
  126 + {
  127 + $orderby = ($orderby > 1)
  128 + ? (float) '0.'.$orderby
  129 + : (float) $orderby;
  130 + }
  131 +
  132 + if (is_float($orderby))
  133 + {
  134 + $this->simple_query('SET SEED '.$orderby);
  135 + }
  136 +
  137 + $orderby = $this->_random_keyword[0];
  138 + $direction = '';
  139 + $escape = FALSE;
  140 + }
  141 +
  142 + return parent::order_by($orderby, $direction, $escape);
  143 + }
  144 +
  145 + // --------------------------------------------------------------------
  146 +
  147 + /**
113 148 * Show table query
114 149 *
115 150 * Generates a platform-specific query string so that the table names can be fetched
2  system/database/drivers/pdo/subdrivers/pdo_sqlite_driver.php
@@ -53,7 +53,7 @@ class CI_DB_pdo_sqlite_driver extends CI_DB_pdo_driver {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58 58 protected $_random_keyword = ' RANDOM()';
59 59
4 system/database/drivers/pdo/subdrivers/pdo_sqlsrv_driver.php
@@ -53,9 +53,9 @@ class CI_DB_pdo_sqlsrv_driver extends CI_DB_pdo_driver {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58   - protected $_random_keyword = ' NEWID()';
  58 + protected $_random_keyword = array('NEWID()', 'RAND(%d)');
59 59
60 60 /**
61 61 * Quoted identifier flag
39 system/database/drivers/postgre/postgre_driver.php
@@ -60,9 +60,9 @@ class CI_DB_postgre_driver extends CI_DB {
60 60 /**
61 61 * ORDER BY random keyword
62 62 *
63   - * @var string
  63 + * @var array
64 64 */
65   - protected $_random_keyword = ' RANDOM()'; // database specific random keyword
  65 + protected $_random_keyword = array('RANDOM()', 'RANDOM()');
66 66
67 67 // --------------------------------------------------------------------
68 68
@@ -482,6 +482,41 @@ public function error()
482 482 // --------------------------------------------------------------------
483 483
484 484 /**
  485 + * ORDER BY
  486 + *
  487 + * @param string $orderby
  488 + * @param string $direction ASC or DESC
  489 + * @param bool $escape
  490 + * @return object
  491 + */
  492 + public function order_by($orderby, $direction = '', $escape = NULL)
  493 + {
  494 + $direction = strtoupper(trim($direction));
  495 + if ($direction === 'RANDOM')
  496 + {
  497 + if ( ! is_float($orderby) && ctype_digit((string) $orderby))
  498 + {
  499 + $orderby = ($orderby > 1)
  500 + ? (float) '0.'.$orderby
  501 + : (float) $orderby;
  502 + }
  503 +
  504 + if (is_float($orderby))
  505 + {
  506 + $this->simple_query('SET SEED '.$orderby);
  507 + }
  508 +
  509 + $orderby = $this->_random_keyword[0];
  510 + $direction = '';
  511 + $escape = FALSE;
  512 + }
  513 +
  514 + return parent::order_by($orderby, $direction, $escape);
  515 + }
  516 +
  517 + // --------------------------------------------------------------------
  518 +
  519 + /**
485 520 * Update statement
486 521 *
487 522 * Generates a platform-specific update string from the supplied data
4 system/database/drivers/sqlite/sqlite_driver.php
@@ -53,9 +53,9 @@ class CI_DB_sqlite_driver extends CI_DB {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58   - protected $_random_keyword = ' Random()'; // database specific random keyword
  58 + protected $_random_keyword = array('RANDOM()', 'RANDOM()');
59 59
60 60 // --------------------------------------------------------------------
61 61
4 system/database/drivers/sqlite3/sqlite3_driver.php
@@ -54,9 +54,9 @@ class CI_DB_sqlite3_driver extends CI_DB {
54 54 /**
55 55 * ORDER BY random keyword
56 56 *
57   - * @var string
  57 + * @var array
58 58 */
59   - protected $_random_keyword = ' RANDOM()';
  59 + protected $_random_keyword = array('RANDOM()', 'RANDOM()');
60 60
61 61 // --------------------------------------------------------------------
62 62
4 system/database/drivers/sqlsrv/sqlsrv_driver.php
@@ -53,9 +53,9 @@ class CI_DB_sqlsrv_driver extends CI_DB {
53 53 /**
54 54 * ORDER BY random keyword
55 55 *
56   - * @var string
  56 + * @var array
57 57 */
58   - protected $_random_keyword = ' NEWID()';
  58 + protected $_random_keyword = array('NEWID()', 'RAND(%d)');
59 59
60 60 /**
61 61 * Quoted identifier flag
1  user_guide_src/source/changelog.rst
Source Rendered
@@ -126,6 +126,7 @@ Release Date: Not Released
126 126 - Added an optional parameter that allows to disable escaping (useful for custom fields) for methods ``join()``, ``order_by()``, ``where_in()``, ``or_where_in()``, ``where_not_in()``, ``or_where_not_in()``, ``insert()``, ``insert_batch()``.
127 127 - Added support for ``join()`` with multiple conditions.
128 128 - Added support for *USING* in ``join()``.
  129 + - Added seed values support for random ordering with ``order_by(seed, 'RANDOM')``.
129 130 - Changed ``limit()`` to ignore NULL values instead of always casting to integer.
130 131 - Changed ``offset()`` to ignore empty values instead of always casting to integer.
131 132 - Methods ``insert_batch()`` and ``update_batch()`` now return an integer representing the number of rows affected by them.
30 user_guide_src/source/database/query_builder.rst
Source Rendered
@@ -469,25 +469,41 @@ Identical to having(), only separates multiple clauses with "OR".
469 469 $this->db->order_by()
470 470 =====================
471 471
472   -Lets you set an ORDER BY clause. The first parameter contains the name
473   -of the column you would like to order by. The second parameter lets you
474   -set the direction of the result. Options are asc or desc, or random.
  472 +Lets you set an ORDER BY clause.
  473 +
  474 +The first parameter contains the name of the column you would like to order by.
  475 +
  476 +The second parameter lets you set the direction of the result.
  477 +Options are **ASC**, **DESC** AND **RANDOM**.
475 478
476 479 ::
477 480
478   - $this->db->order_by("title", "desc"); // Produces: ORDER BY title DESC
  481 + $this->db->order_by('title', 'DESC');
  482 + // Produces: ORDER BY `title` DESC
479 483
480 484 You can also pass your own string in the first parameter::
481 485
482   - $this->db->order_by('title desc, name asc'); // Produces: ORDER BY title DESC, name ASC
  486 + $this->db->order_by('title DESC, name ASC');
  487 + // Produces: ORDER BY `title` DESC, `name` ASC
483 488
484 489 Or multiple function calls can be made if you need multiple fields.
485 490
486 491 ::
487 492
488   - $this->db->order_by("title", "desc");
489   - $this->db->order_by("name", "asc"); // Produces: ORDER BY title DESC, name ASC
  493 + $this->db->order_by('title', 'DESC');
  494 + $this->db->order_by('name', 'ASC');
  495 + // Produces: ORDER BY `title` DESC, `name` ASC
  496 +
  497 +If you choose the **RANDOM** direction option, then the first parameters will
  498 +be ignored, unless you specify a numeric seed value.
  499 +
  500 +::
  501 +
  502 + $this->db->order_by('title', 'RANDOM');
  503 + // Produces: ORDER BY RAND()
490 504
  505 + $this->db->order_by(42, 'RANDOM');
  506 + // Produces: ORDER BY RAND(42)
491 507
492 508 .. note:: order_by() was formerly known as orderby(), which has been
493 509 removed.

0 comments on commit 98e46cf

Please sign in to comment.
Something went wrong with that request. Please try again.