I’ve been playing with extensions to PDO and PDOStatement, trying to get database statements working even more smoothly. Without going through the exact code, this is what I’m doing in the extension. I’m wanting help spotting potential problems because this is so low level that tons of code are going to end up sitting on it and I don’t want to be rewriting it.
Gazelle\Database extends PDO
override __construct:
@param mixed (string or array)
Extended to accept a configuration array rather than just a DSN - however it will still accept a DSN. Also sets PDOAttribute defaults for the framework - placing PDO into Throw Exceptions mode and setting the Statement class below as the default statement object.
Gazelle\Statement extends PDOStatement
override __construct:
@param Database object
Accept a reference to the creating db object? At the moment I haven’t needed this. The plan was to have the statement update the main database object with performance information like query execution time. With PHP 5.4 on the horizon though I’ve decided to hold off to a later version of the framework and farm such debug related tasks to Traits that can be attached to the object only when the Debug mode is invoked explicitly. For the moment I’ve left this alone.
override execute
[@param array]
@return this
Parent returns Bool. The override function returns this for chaining statements and throws an error if the parent method returned false.
bindArray
@param array
Bind an array by its keys to the statement. The draft of this function has me uneasy because it can get messed up by the calling code pretty easy and I’d like to harden it. Currently if the array has named keys then the statement should have named parameter tokens. If the array has numeric keys the statement should have question mark tokens. I’d like to tolerate receiving an array with numeric keys even if the statement has named tokens, but to do this I need to be able to retrieve a token list in order. PDOStatement has no public method that does this, does it have an undocumented protected method that provides this?
The function returns $this for chaining purposes.
key
[@param mixed (string or integer)]
This statement causes the statement to index the return on the argument (if present) or first column (if not) instead of generating a key. return self for chaining. If this function never gets called the first column is used when indexed functions are explicitly requested.
fetchMixed
@return mixed
Fetches the data based on the nature of the return. The using programmer should be able to predict what this is going to return based on the structure of the query. For example, “SELECT name
FROM table
WHERE id
= 1 LIMIT 1” will return a single value, so fetchMixed returns just that value, not an array of 1 row with an array of 1 column with the value. fetchMixed is a very powerful shorthand, but if queries aren’t watched it can cause trouble. There are times when we need to force the return to stay an array, and other functions exist for this as we go down the list.
fetchAllAssoc
@return container array
This started life as an alias to fetchAll( PDO::FETCH_ASSOC ), but when I wrote the key function I realized this should be affected by that. If key is called then this function will move the contents of the key column into the key position of the return array.
fetchIndexedResults
Returns the results with the key set on the return. If there’s only two columns this function will return a single array as if you’d called fetchAll(PDO::FETCH_COLUMN) but with the keys being one of the columns (by default the first) and the values being the other.
fetchCollection
@parameter Collator
This function collates the results into a structured return. By default the structure is inferred from the key names. Collation of sql returns into multidimensional arrays is perhaps one of the most common tasks in PHP. The function can accept a collator object to do the collation - otherwise it creates one of class TierCollator.
fetchTree
This function uses two collators - first collating the rows into multidimensional array, and then passes that to a tree collator that creates a result tree. This is used by the core framework, but its use is infrequent enough I’m considering pulling it out of the base statement object.
The addition of chaining allows for these statements;
$ret = $db->prepare("SELECT * FROM table WHERE name = :name")->bindArray($array)->execute()->fetchMixed();
$ret = $db->query("SELECT * FROM table WHERE name = '{$name}'")->fetchMixed();
Thoughts?