-
Notifications
You must be signed in to change notification settings - Fork 175
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Core-Database] added 2 new functions to help avoid code duplication #3428
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -744,6 +744,77 @@ class Database | |
return $result; | ||
} | ||
|
||
/** | ||
* Runs an SQL select statement as a prepared query and re-indexes | ||
* the results using the given unique non-nullable key. | ||
* | ||
* @param string $query The SQL SELECT query to be run | ||
* @param array $params Values to use for binding to the prepared statement | ||
* @param string $uniqueKey Key to use when re-indexing, this key must be a | ||
* single column, must be unique and must not be | ||
* nullable | ||
* | ||
* @throws LorisException If the supplied key is empty or null | ||
* @throws DatabaseException If the key is not part of the query itself | ||
* @throws DatabaseException If the key is not unique within the resulting set | ||
* | ||
* @return array An array of arrays containing the data. The outermost array is | ||
* associative and uses the supplied $uniqueKey parameter as | ||
* a key for each of the sub-arrays with the format | ||
* rowPrimaryKey=>rowValuesArray. Each nested array represents | ||
* a row from the returned by the query. Each element in the | ||
* nested array is an associative array representing the row in | ||
* the format ColumnName => Value | ||
*/ | ||
function pselectWithIndexKey($query, $params, $uniqueKey) | ||
{ | ||
if (is_null($uniqueKey) || empty($uniqueKey)) { | ||
throw new LorisException( | ||
"The pselectWithIndexKey() function expects the uniqueKey parameter | ||
to not be null or empty. If re-indexing on the primary key is | ||
not necessary please use the pselect() function instead." | ||
); | ||
} | ||
|
||
$result = $this->pselect($query, $params); | ||
|
||
if (empty($result)) { | ||
return $result; | ||
} | ||
|
||
$filteredResult = array(); | ||
// re-order the return array | ||
foreach ($result as $row) { | ||
// Check first that the row contains the primary key supplied | ||
if (!array_key_exists($uniqueKey, $row)) { | ||
throw new DatabaseException( | ||
"The query supplied to pselectWithIndexKey() does not contain | ||
the unique key to re-index on. Make sure to supply the | ||
appropriate key in the SELECT statement to match the supplied | ||
parameter of this function", | ||
$query | ||
); | ||
} | ||
|
||
// Check that the primary key is indeed unique to avoid overriding data | ||
// in the result array | ||
if (isset($filteredResult[$row[$uniqueKey]])) { | ||
throw new DatabaseException( | ||
"The uniqueKey supplied to pselectWithIndexKey() does not appear | ||
to be unique or is nullable. This function expects the key to | ||
be both UNIQUE and NOT NULL.", | ||
$query | ||
); | ||
} | ||
|
||
// If you get here, we just need to build the new array | ||
$filteredResult[$row[$uniqueKey]] = $row; | ||
unset($filteredResult[$row[$uniqueKey]][$uniqueKey]); | ||
} | ||
|
||
return $filteredResult; | ||
} | ||
|
||
/** | ||
* Runs a query as a prepared statement and returns the first row as an | ||
* associative array. Automatically adds a limit clause to the query being | ||
|
@@ -772,6 +843,8 @@ class Database | |
* @param string $query The SQL SELECT query to be run | ||
* @param array $params Values to use for binding to prepared statement | ||
* | ||
* @throws DatabaseException if the query selected more than one column | ||
* | ||
* @return array Associative array of form rowID=>value containing all values | ||
* for the first element of the select statement | ||
*/ | ||
|
@@ -796,6 +869,82 @@ class Database | |
return $result; | ||
} | ||
|
||
/** | ||
* Runs an SQL select statement as a prepared query and re-indexes | ||
* the results using the given unique non-nullable key in the same | ||
* format as the pselectCol() function. | ||
* | ||
* @param string $query The SQL SELECT query to be run | ||
* @param array $params Values to use for binding to the prepared statement | ||
* @param string $uniqueKey Key to use when re-indexing, this key must be a | ||
* single column, must be unique and must not be | ||
* nullable | ||
* | ||
* @throws LorisException If the supplied key is empty or null | ||
* @throws DatabaseException If the key is not part of the query itself or | ||
* if there are not exactly 2 columns selected | ||
* @throws DatabaseException If the key is not unique within the resulting set | ||
* | ||
* @return array Associative array of form uniqueKey=>value containing all | ||
* value for the non-uniqueKey element of the select statement | ||
*/ | ||
function pselectColWithIndexKey($query, $params, $uniqueKey) | ||
{ | ||
if (is_null($uniqueKey) || empty($uniqueKey)) { | ||
throw new LorisException( | ||
"The pselectColWithIndexKey() function expects the uniqueKey | ||
parameter to not be null or empty. If re-indexing on the primary | ||
key is not necessary please use the pselectCol() function instead." | ||
); | ||
} | ||
|
||
$result = $this->pselect($query, $params); | ||
|
||
if (empty($result)) { | ||
return $result; | ||
} | ||
|
||
$filteredResult = array(); | ||
// re-order the return array | ||
foreach ($result as $row) { | ||
$colNumber = count($row); | ||
// Check first that the row contains the primary key supplied | ||
if (!array_key_exists($uniqueKey, $row) || $colNumber !== 2) { | ||
throw new DatabaseException( | ||
"The query supplied to pselectColWithIndexKey() should only | ||
contain the unique key and one other column in the SELECT | ||
clause. Make sure to supply the appropriate key in the SELECT | ||
statement to match the supplied parameter of this function.", | ||
$query | ||
); | ||
} | ||
|
||
// Check that the primary key is indeed unique to avoid overriding data | ||
// in the result array | ||
if (isset($filteredResult[$row[$uniqueKey]])) { | ||
throw new DatabaseException( | ||
"The uniqueKey supplied to pselectColWithIndexKey() does not | ||
appear to be unique or is nullable. This function expects the | ||
key to be both UNIQUE and NOT NULL.", | ||
$query | ||
); | ||
} | ||
|
||
// Store the value of the key for this specific row then unset that | ||
// value from the $row array so that the only element remaining is | ||
// the column desired and its value for this row | ||
$uniqueKeyValue = $row[$uniqueKey]; | ||
unset($row[$uniqueKey]); | ||
|
||
// Note: reset() rewinds array's internal pointer to the first element | ||
// and returns the value of the first array element, in this case the | ||
// desired column value | ||
$filteredResult[$uniqueKeyValue] = reset($row); | ||
} | ||
|
||
return $filteredResult; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I fail to see how this is useful in light of the first function - is the plan to make 1:1 index to value mappings? If that is the case, it does not seem that you are able to specify which column you are targeting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that I think of it, you're right. Doesn't pselectCol always return a single column? Isn't this just requiring an extra parameter @ridz1208? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The idea here... Ideally what you want and what is used all throughout the loris codebase is an array of the form
But currently we can only get one of the following... in either case we will need a secondary forloop to extract the key=>value association we are looking for.
I think this function might just be a better version of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @driusan did the explanation make it clearer ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Other than the fact that I didn't see the comment until now, yes. |
||
/** | ||
* Runs a query as a prepared statement and returns the value of the first | ||
* column of the first row | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me and will be very useful - this will replace a lot of the work that the biobank DAO is currently doing when querying the database.