Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
project
drupal
Commits
a7f6efc8
Commit
a7f6efc8
authored
Nov 08, 2008
by
Dries
Browse files
- Patch
#329080
by chx, Damien Tournoud, pwolanin: statics in objects are not per-instance.
parent
50b3072f
Changes
3
Hide whitespace changes
Inline
Side-by-side
includes/database/database.inc
View file @
a7f6efc8
...
...
@@ -155,6 +155,68 @@ abstract class DatabaseConnection extends PDO {
*/
protected
$logger
=
NULL
;
/**
* Cache of prepared statements.
*
* This cache only lasts as long as the current page request, so it's not
* as useful as it could be, but every little bit helps.
*
* @var Array
*/
protected
$preparedStatements
=
array
();
/**
* The name of the Select class for this connection.
*
* Normally this and the following class names would be static variables,
* but statics in methods are still global and shared by all instances.
*
* @var string
*/
protected
$selectClass
=
NULL
;
/**
* The name of the Delete class for this connection.
*
* @var string
*/
protected
$deleteClass
=
NULL
;
/**
* The name of the Insert class for this connection.
*
* @var string
*/
protected
$insertClass
=
NULL
;
/**
* The name of the Merge class for this connection.
*
* @var string
*/
protected
$mergeClass
=
NULL
;
/**
* The name of the Update class for this connection.
*
* @var string
*/
protected
$updateClass
=
NULL
;
/**
* The name of the Transaction class for this connection.
*
* @var string
*/
protected
$transactionClass
=
NULL
;
/**
* The schema object for this connection.
*
* @var object
*/
protected
$schema
=
NULL
;
function
__construct
(
$dsn
,
$username
,
$password
,
$driver_options
=
array
())
{
// Because the other methods don't seem to work right.
$driver_options
[
PDO
::
ATTR_ERRMODE
]
=
PDO
::
ERRMODE_EXCEPTION
;
...
...
@@ -262,7 +324,7 @@ protected function prefixTables($sql) {
/**
* Prepare a query string and return the prepared statement.
*
* This method
statically
caches prepared statements, reusing them when
* This method caches prepared statements, reusing them when
* possible. It also prefixes tables names enclosed in curly-braces.
*
* @param $query
...
...
@@ -272,13 +334,12 @@ protected function prefixTables($sql) {
* A PDO prepared statement ready for its execute() method.
*/
protected
function
prepareQuery
(
$query
)
{
static
$statements
=
array
();
$query
=
self
::
prefixTables
(
$query
);
if
(
empty
(
$
s
tatements
[
$query
]))
{
if
(
empty
(
$
this
->
preparedS
tatements
[
$query
]))
{
// Call PDO::prepare.
$
s
tatements
[
$query
]
=
parent
::
prepare
(
$query
);
$
this
->
preparedS
tatements
[
$query
]
=
parent
::
prepare
(
$query
);
}
return
$
s
tatements
[
$query
];
return
$
this
->
preparedS
tatements
[
$query
];
}
/**
...
...
@@ -352,8 +413,7 @@ public function makeSequenceName($table, $field) {
*
* This method provides a central handler for the actual execution
* of every query. All queries executed by Drupal are executed as
* PDO prepared statements. This method statically caches those
* prepared statements, reusing them when possible.
* PDO prepared statements.
*
* @param $query
* The query to execute. In most cases this will be a string containing
...
...
@@ -444,14 +504,18 @@ public function query($query, Array $args = array(), $options = array()) {
* A new SelectQuery object.
*/
public
function
select
(
$table
,
$alias
=
NULL
,
Array
$options
=
array
())
{
static
$class_type
;
if
(
empty
(
$class_type
))
{
$class_type
=
'SelectQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$class_type
))
{
$class_type
=
'SelectQuery'
;
if
(
empty
(
$this
->
selectClass
))
{
$this
->
selectClass
=
'SelectQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$this
->
selectClass
))
{
$this
->
selectClass
=
'SelectQuery'
;
}
}
return
new
$class_type
(
$table
,
$alias
,
$this
,
$options
);
$class
=
$this
->
selectClass
;
// new is documented as the highest precedence operator so this will
// create a class named $class and pass the arguments into the constructor,
// instead of calling a function named $class with the arguments listed and
// then creating using the return value as the class name.
return
new
$class
(
$table
,
$alias
,
$this
,
$options
);
}
/**
...
...
@@ -464,14 +528,14 @@ public function select($table, $alias = NULL, Array $options = array()) {
* A new InsertQuery object.
*/
public
function
insert
(
$table
,
Array
$options
=
array
())
{
static
$class_type
;
if
(
empty
(
$class_type
))
{
$class_type
=
'InsertQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$class_type
))
{
$class_type
=
'InsertQuery'
;
if
(
empty
(
$this
->
insertClass
))
{
$this
->
insertClass
=
'InsertQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$this
->
insertClass
))
{
$this
->
insertClass
=
'InsertQuery'
;
}
}
return
new
$class_type
(
$this
,
$table
,
$options
);
$class
=
$this
->
insertClass
;
return
new
$class
(
$this
,
$table
,
$options
);
}
/**
...
...
@@ -484,16 +548,17 @@ public function insert($table, Array $options = array()) {
* A new MergeQuery object.
*/
public
function
merge
(
$table
,
Array
$options
=
array
())
{
static
$class_type
;
if
(
empty
(
$class_type
))
{
$class_type
=
'MergeQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$class_type
))
{
$class_type
=
'MergeQuery'
;
if
(
empty
(
$this
->
mergeClass
))
{
$this
->
mergeClass
=
'MergeQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$this
->
mergeClass
))
{
$this
->
mergeClass
=
'MergeQuery'
;
}
}
return
new
$class_type
(
$this
,
$table
,
$options
);
$class
=
$this
->
mergeClass
;
return
new
$class
(
$this
,
$table
,
$options
);
}
/**
* Prepare and return an UPDATE query object with the specified ID.
*
...
...
@@ -504,14 +569,14 @@ public function merge($table, Array $options = array()) {
* A new UpdateQuery object.
*/
public
function
update
(
$table
,
Array
$options
=
array
())
{
static
$class_type
;
if
(
empty
(
$class_type
))
{
$class_type
=
'UpdateQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$class_type
))
{
$class_type
=
'UpdateQuery'
;
if
(
empty
(
$this
->
updateClass
))
{
$this
->
updateClass
=
'UpdateQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$this
->
updateClass
))
{
$this
->
updateClass
=
'UpdateQuery'
;
}
}
return
new
$class_type
(
$this
,
$table
,
$options
);
$class
=
$this
->
updateClass
;
return
new
$class
(
$this
,
$table
,
$options
);
}
/**
...
...
@@ -524,14 +589,14 @@ public function update($table, Array $options = array()) {
* A new DeleteQuery object.
*/
public
function
delete
(
$table
,
Array
$options
=
array
())
{
static
$class_type
;
if
(
empty
(
$class_type
))
{
$class_type
=
'DeleteQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$class_type
))
{
$class_type
=
'DeleteQuery'
;
if
(
empty
(
$this
->
deleteClass
))
{
$this
->
deleteClass
=
'DeleteQuery_'
.
$this
->
driver
();
if
(
!
class_exists
(
$this
->
deleteClass
))
{
$this
->
deleteClass
=
'DeleteQuery'
;
}
}
return
new
$class_type
(
$this
,
$table
,
$options
);
$class
=
$this
->
deleteClass
;
return
new
$class
(
$this
,
$table
,
$options
);
}
/**
...
...
@@ -543,12 +608,11 @@ public function delete($table, Array $options = array()) {
* The DatabaseSchema object for this connection.
*/
public
function
schema
()
{
static
$schema
;
if
(
empty
(
$schema
))
{
if
(
empty
(
$this
->
schema
))
{
$class_type
=
'DatabaseSchema_'
.
$this
->
driver
();
$schema
=
new
$class_type
(
$this
);
$
this
->
schema
=
new
$class_type
(
$this
);
}
return
$schema
;
return
$
this
->
schema
;
}
/**
...
...
@@ -575,19 +639,17 @@ public function escapeTable($table) {
* @see DatabaseTransaction
*/
public
function
startTransaction
(
$required
=
FALSE
)
{
static
$class_type
;
if
(
$required
&&
!
$this
->
supportsTransactions
())
{
throw
new
TransactionsNotSupportedException
();
}
if
(
empty
(
$
class_type
))
{
$
class_type
=
'DatabaseTransaction_'
.
$this
->
driver
();
if
(
!
class_exists
(
$
class_type
))
{
$
class_type
=
'DatabaseTransaction'
;
if
(
empty
(
$
this
->
transactionClass
))
{
$
this
->
transactionClass
=
'DatabaseTransaction_'
.
$this
->
driver
();
if
(
!
class_exists
(
$
this
->
transactionClass
))
{
$
this
->
transactionClass
=
'DatabaseTransaction'
;
}
}
return
new
$
class_type
(
$this
);
return
new
$
this
->
transactionClass
(
$this
);
}
/**
...
...
includes/database/select.inc
View file @
a7f6efc8
...
...
@@ -400,6 +400,13 @@ public function fields($table_alias, Array $fields = array()) {
return
$this
;
}
/**
* Private list of aliases already attributed to expression fields.
*
* @var Array
*/
private
$expressionAliases
=
array
();
/**
* Adds an expression to the list of "fields" to be SELECTed.
*
...
...
@@ -412,7 +419,7 @@ public function fields($table_alias, Array $fields = array()) {
* @param $alias
* The alias for this expression. If not specified, one will be generated
* automatically in the form "expression_#". The alias will be checked for
* uniqueness, so the requested alias may not be the alias that is asigned
* uniqueness, so the requested alias may not be the alias that is as
s
igned
* in all cases.
* @param $arguments
* Any placeholder arguments needed for this expression.
...
...
@@ -420,19 +427,16 @@ public function fields($table_alias, Array $fields = array()) {
* The unique alias that was assigned for this expression.
*/
public
function
addExpression
(
$expression
,
$alias
=
NULL
,
$arguments
=
array
())
{
static
$alaises
=
array
();
if
(
empty
(
$alias
))
{
$alias
=
'expression'
;
}
if
(
empty
(
$aliases
[
$alias
]))
{
$aliases
[
$alias
]
=
1
;
}
if
(
!
empty
(
$this
->
expressions
[
$alias
]))
{
$alias
=
$alias
.
'_'
.
$aliases
[
$alias
]
++
;
$alias_candidate
=
$alias
;
$count
=
2
;
while
(
!
empty
(
$this
->
expressions
[
$alias_candidate
]))
{
$alias_candidate
=
$alias
.
'_'
.
$count
++
;
}
$alias
=
$alias_candidate
;
$this
->
expressions
[
$alias
]
=
array
(
'expression'
=>
$expression
,
...
...
modules/simpletest/tests/database_test.test
View file @
a7f6efc8
...
...
@@ -1043,6 +1043,28 @@ class DatabaseSelectTestCase extends DatabaseTestCase {
$this
->
assertEqual
(
$record
->
$age_field
,
27
*
2
,
t
(
'Fetched age expression is correct.'
));
}
/**
* Test SELECT statements with multiple expressions.
*/
function
testSimpleSelectExpressionMultiple
()
{
$query
=
db_select
(
'test'
);
$name_field
=
$query
->
addField
(
'test'
,
'name'
);
$age_double_field
=
$query
->
addExpression
(
"age*2"
);
$age_triple_field
=
$query
->
addExpression
(
"age*3"
);
$query
->
condition
(
'age'
,
27
);
$result
=
$query
->
execute
();
// Check that the aliases are being created the way we want.
$this
->
assertEqual
(
$age_double_field
,
'expression'
,
t
(
'Double age field alias is correct.'
));
$this
->
assertEqual
(
$age_triple_field
,
'expression_2'
,
t
(
'Triple age field alias is correct.'
));
// Ensure that we got the right record.
$record
=
$result
->
fetch
();
$this
->
assertEqual
(
$record
->
$name_field
,
'George'
,
t
(
'Fetched name is correct.'
));
$this
->
assertEqual
(
$record
->
$age_double_field
,
27
*
2
,
t
(
'Fetched double age expression is correct.'
));
$this
->
assertEqual
(
$record
->
$age_triple_field
,
27
*
3
,
t
(
'Fetched triple age expression is correct.'
));
}
/**
* Test adding multiple fields to a select statement at the same time.
*/
...
...
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