Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
D
drupal
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Custom Issue Tracker
Custom Issue Tracker
Labels
Merge Requests
300
Merge Requests
300
Requirements
Requirements
List
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Analytics
Analytics
Code Review
Insights
Issue
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
project
drupal
Commits
d4a597fd
Commit
d4a597fd
authored
Sep 11, 2009
by
webchick
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
#561104
by Crell: Added support for random ordering in dynamic select queries.
parent
f24f709e
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
93 additions
and
1 deletion
+93
-1
includes/database/pgsql/query.inc
includes/database/pgsql/query.inc
+10
-0
includes/database/select.inc
includes/database/select.inc
+33
-0
modules/simpletest/tests/database_test.test
modules/simpletest/tests/database_test.test
+50
-1
No files found.
includes/database/pgsql/query.inc
View file @
d4a597fd
...
...
@@ -173,3 +173,13 @@ public function execute() {
return
$stmt
->
rowCount
();
}
}
class
SelectQuery_pgsql
extends
SelectQuery
{
public
function
orderRandom
()
{
$alias
=
$this
->
addExpression
(
'RANDOM()'
,
'random_field'
);
$this
->
orderBy
(
$alias
);
return
$this
;
}
}
includes/database/select.inc
View file @
d4a597fd
...
...
@@ -347,6 +347,28 @@ public function addJoin($type, $table, $alias = NULL, $condition = NULL, $argume
*/
public
function
orderBy
(
$field
,
$direction
=
'ASC'
);
/**
* Orders the result set by a random value.
*
* This may be stacked with other orderBy() calls. If so, the query will order
* by each specified field, including this one, in the order called. Although
* this method may be called multiple times on the same query, doing so
* is not particularly useful.
*
* Note: The method used by most drivers may not scale to very large result
* sets. If you need to work with extremely large data sets, you may create
* your own database driver by subclassing off of an existing driver and
* implementing your own randomization mechanism. See
*
* http://jan.kneschke.de/projects/mysql/order-by-rand/
*
* for an example of such an alternate sorting mechanism.
*
* @return
* The called object
*/
public
function
orderRandom
();
/**
* Restricts a query to a given range in the result set.
*
...
...
@@ -643,6 +665,11 @@ public function orderBy($field, $direction = 'ASC') {
return
$this
;
}
public
function
orderRandom
()
{
$this
->
query
->
orderRandom
();
return
$this
;
}
public
function
range
(
$start
=
NULL
,
$length
=
NULL
)
{
$this
->
query
->
range
(
$start
,
$length
);
return
$this
;
...
...
@@ -1182,6 +1209,12 @@ public function orderBy($field, $direction = 'ASC') {
return
$this
;
}
public
function
orderRandom
()
{
$alias
=
$this
->
addExpression
(
'RAND()'
,
'random_field'
);
$this
->
orderBy
(
$alias
);
return
$this
;
}
public
function
range
(
$start
=
NULL
,
$length
=
NULL
)
{
$this
->
range
=
func_num_args
()
?
array
(
'start'
=>
$start
,
'length'
=>
$length
)
:
array
();
return
$this
;
...
...
modules/simpletest/tests/database_test.test
View file @
d4a597fd
...
...
@@ -1400,6 +1400,55 @@ class DatabaseSelectTestCase extends DatabaseTestCase {
$this
->
assertEqual
(
$names
[
1
],
'Ringo'
,
t
(
'Second query returned correct second name.'
));
$this
->
assertEqual
(
$names
[
2
],
'Ringo'
,
t
(
'Third query returned correct name.'
));
}
/**
* Test that random ordering of queries works.
*
* This is a non-deterministic query. That is, it is not guaranteed to pass
* 100% of the time. Random numbers are like that. Instead, we take two sets
* of random selects. By the laws of probability, the average of each set
* should be roughly the average of the data set being selected from and
* roughly the same each time through, provided that the original data set
* is evenly distributed. Because we know that ours is, this test should pass
* correctly 99% of the time. It is not possible to unit test for that other
* 1% successfully, so that will have to do.
*/
function
testRandomOrder
()
{
$sets
=
2
;
$runs
=
50
;
$ids
=
array
();
$ids
=
array
();
$max
=
db_query
(
"SELECT MAX(id) FROM
{
test
}
"
)
->
fetchField
();
$min
=
db_query
(
"SELECT MIN(id) FROM
{
test
}
"
)
->
fetchField
();
$ideal_average
=
(
$min
+
$max
)
/
2
;
$allowed_deviation
=
(
$max
-
$min
)
/
4
;
for
(
$i
=
0
;
$i
<
$sets
;
++
$i
)
{
for
(
$j
=
0
;
$j
<
$runs
;
++
$j
)
{
$ids
[
$i
][]
=
db_select
(
'test'
,
't'
)
->
fields
(
't'
,
array
(
'id'
))
->
range
(
0
,
1
)
->
orderRandom
()
->
orderBy
(
'id'
)
->
execute
()
->
fetchField
();
}
}
for
(
$i
=
0
;
$i
<
$sets
;
++
$i
)
{
$found_average
[
$i
]
=
array_sum
(
$ids
[
$i
])
/
count
(
$ids
[
$i
]);
$deviation
=
abs
(
$found_average
[
$i
]
-
$ideal_average
);
$this
->
assertTrue
(
$deviation
<=
$allowed_deviation
,
t
(
'Random ids are within allowed deviation.'
));
}
for
(
$i
=
1
;
$i
<
$sets
;
++
$i
)
{
$deviation
=
abs
(
$found_average
[
$i
]
-
$found_average
[
$i
-
1
]);
$this
->
assertTrue
(
$deviation
<=
$allowed_deviation
,
t
(
'Random ids are within allowed deviation from each other.'
));
}
}
}
/**
...
...
@@ -2897,7 +2946,7 @@ class DatabaseExtraTypesTestCase extends DrupalWebTestCase {
'description'
=>
t
(
'Test Time field'
),
'type'
=>
'time'
,
'not null'
=>
FALSE
,
),
),
),
);
$ret
=
array
();
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment