Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
7ef869ee
Commit
7ef869ee
authored
Oct 30, 2006
by
zYne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactored Doctrine_Connection and Doctrine_Record, fixes #212
parent
d8dddffc
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
312 additions
and
301 deletions
+312
-301
Collection.php
lib/Doctrine/Collection.php
+19
-4
Connection.php
lib/Doctrine/Connection.php
+29
-178
Mysql.php
lib/Doctrine/Connection/Mysql.php
+22
-0
UnitOfWork.php
lib/Doctrine/Connection/UnitOfWork.php
+79
-0
Query.php
lib/Doctrine/Query.php
+70
-25
Record.php
lib/Doctrine/Record.php
+11
-90
Association.php
lib/Doctrine/Relation/Association.php
+39
-0
ForeignKey.php
lib/Doctrine/Relation/ForeignKey.php
+29
-0
LocalKey.php
lib/Doctrine/Relation/LocalKey.php
+12
-0
run.php
tests/run.php
+2
-4
No files found.
lib/Doctrine/Collection.php
View file @
7ef869ee
...
...
@@ -645,7 +645,7 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
}
/**
* save
* saves all records
* saves all records
of this collection
*
* @return void
*/
...
...
@@ -653,19 +653,34 @@ class Doctrine_Collection extends Doctrine_Access implements Countable, Iterator
if
(
$conn
==
null
)
{
$conn
=
$this
->
table
->
getConnection
();
}
$conn
->
saveCollection
(
$this
);
$conn
->
beginTransaction
();
foreach
(
$this
as
$key
=>
$record
)
:
$record
->
save
();
endforeach
;
$conn
->
commit
();
}
/**
* single shot delete
* deletes all records from this collection
* uses only one database query to perform this operation
* and uses only one database query to perform this operation
*
* @return boolean
*/
public
function
delete
(
Doctrine_Connection
$conn
=
null
)
{
if
(
$conn
==
null
)
{
$conn
=
$this
->
table
->
getConnection
();
}
$ids
=
$conn
->
deleteCollection
(
$this
);
$conn
->
beginTransaction
();
foreach
(
$this
as
$key
=>
$record
)
{
$record
->
delete
();
}
$conn
->
commit
();
$this
->
data
=
array
();
}
/**
...
...
lib/Doctrine/Connection.php
View file @
7ef869ee
This diff is collapsed.
Click to expand it.
lib/Doctrine/Connection/Mysql.php
View file @
7ef869ee
...
...
@@ -35,6 +35,28 @@ class Doctrine_Connection_Mysql extends Doctrine_Connection_Common {
public
function
__construct
(
Doctrine_Manager
$manager
,
PDO
$pdo
)
{
$pdo
->
setAttribute
(
PDO
::
ATTR_EMULATE_PREPARES
,
true
);
$this
->
setAttribute
(
Doctrine
::
ATTR_QUERY_LIMIT
,
Doctrine
::
LIMIT_ROWS
);
$this
->
supported
=
array
(
'sequences'
=>
'emulated'
,
'indexes'
=>
true
,
'affected_rows'
=>
true
,
'transactions'
=>
true
,
'savepoints'
=>
false
,
'summary_functions'
=>
true
,
'order_by_text'
=>
true
,
'current_id'
=>
'emulated'
,
'limit_queries'
=>
true
,
'LOBs'
=>
true
,
'replace'
=>
true
,
'sub_selects'
=>
true
,
'auto_increment'
=>
true
,
'primary_key'
=>
true
,
'result_introspection'
=>
true
,
'prepared_statements'
=>
'emulated'
,
'identifier_quoting'
=>
true
,
'pattern_escaping'
=>
true
);
parent
::
__construct
(
$manager
,
$pdo
);
}
/**
...
...
lib/Doctrine/Connection/UnitOfWork.php
View file @
7ef869ee
...
...
@@ -44,7 +44,12 @@ class Doctrine_Connection_UnitOfWork implements IteratorAggregate, Countable {
/**
* buildFlushTree
* builds a flush tree that is used in transactions
*
* The returned array has all the initialized components in
* 'correct' order. Basically this means that the records of those
* components can be saved safely in the order specified by the returned array.
*
* @param array $tables
* @return array
*/
public
function
buildFlushTree
(
array
$tables
)
{
...
...
@@ -133,7 +138,81 @@ class Doctrine_Connection_UnitOfWork implements IteratorAggregate, Countable {
}
return
array_values
(
$tree
);
}
/**
* saveRelated
* saves all related records to $record
*
* @param Doctrine_Record $record
*/
public
function
saveRelated
(
Doctrine_Record
$record
)
{
$saveLater
=
array
();
foreach
(
$record
->
getReferences
()
as
$k
=>
$v
)
{
$fk
=
$record
->
getTable
()
->
getRelation
(
$k
);
if
(
$fk
instanceof
Doctrine_Relation_ForeignKey
||
$fk
instanceof
Doctrine_Relation_LocalKey
)
{
if
(
$fk
->
isComposite
())
{
$local
=
$fk
->
getLocal
();
$foreign
=
$fk
->
getForeign
();
if
(
$record
->
getTable
()
->
hasPrimaryKey
(
$fk
->
getLocal
()))
{
if
(
!
$record
->
exists
())
$saveLater
[
$k
]
=
$fk
;
else
$v
->
save
();
}
else
{
// ONE-TO-ONE relationship
$obj
=
$record
->
get
(
$fk
->
getTable
()
->
getComponentName
());
if
(
$obj
->
getState
()
!=
Doctrine_Record
::
STATE_TCLEAN
)
$obj
->
save
();
}
}
}
elseif
(
$fk
instanceof
Doctrine_Relation_Association
)
{
$v
->
save
();
}
}
return
$saveLater
;
}
/**
* saveAssociations
*
* this method takes a diff of one-to-many / many-to-many original and
* current collections and applies the changes
*
* for example if original many-to-many related collection has records with
* primary keys 1,2 and 3 and the new collection has records with primary keys
* 3, 4 and 5, this method would first destroy the associations to 1 and 2 and then
* save new associations to 4 and 5
*
* @param Doctrine_Record $record
* @return void
*/
public
function
saveAssociations
(
Doctrine_Record
$record
)
{
foreach
(
$record
->
getTable
()
->
getRelations
()
as
$rel
)
{
$table
=
$rel
->
getTable
();
$alias
=
$rel
->
getAlias
();
$rel
->
processDiff
(
$record
);
}
}
/**
* deletes all related composites
* this method is always called internally when a record is deleted
*
* @return void
*/
public
function
deleteComposites
(
Doctrine_Record
$record
)
{
foreach
(
$record
->
getTable
()
->
getRelations
()
as
$fk
)
{
switch
(
$fk
->
getType
())
:
case
Doctrine_Relation
::
ONE_COMPOSITE
:
case
Doctrine_Relation
::
MANY_COMPOSITE
:
$obj
=
$record
->
get
(
$fk
->
getAlias
());
$obj
->
delete
();
break
;
endswitch
;
}
}
public
function
getIterator
()
{
}
public
function
count
()
{
}
...
...
lib/Doctrine/Query.php
View file @
7ef869ee
...
...
@@ -598,25 +598,26 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
}
}
/**
* DQL PARSER
* parses a DQL query
* first splits the query in parts and then uses individual
* parsers for each part
* splitQuery
* splits the given dql query into an array where keys
* represent different query part names and values are
* arrays splitted using sqlExplode method
*
* example:
*
* parameter:
* $query = "SELECT u.* FROM User u WHERE u.name LIKE ?"
* returns:
* array('select' => array('u.*'),
* 'from' => array('User', 'u'),
* 'where' => array('u.name', 'LIKE', '?'))
*
* @param string $query DQL query
* @param boolean $clear whether or not to clear the aliases
* @throws Doctrine_Query_Exception if some generic parsing error occurs
* @return
Doctrine_Query
* @return
array an array containing the query string parts
*/
public
function
parseQuery
(
$query
,
$clear
=
true
)
{
if
(
$clear
)
$this
->
clear
();
$query
=
trim
(
$query
);
$query
=
str_replace
(
"
\n
"
,
" "
,
$query
);
$query
=
str_replace
(
"
\r
"
,
" "
,
$query
);
$e
=
self
::
sqlExplode
(
$query
,
" "
,
"("
,
")"
);
public
function
splitQuery
(
$query
)
{
$e
=
self
::
sqlExplode
(
$query
,
' '
);
foreach
(
$e
as
$k
=>
$part
)
{
$part
=
trim
(
$part
);
...
...
@@ -651,6 +652,28 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
$parts
[
$p
][]
=
$part
;
}
}
return
$parts
;
}
/**
* DQL PARSER
* parses a DQL query
* first splits the query in parts and then uses individual
* parsers for each part
*
* @param string $query DQL query
* @param boolean $clear whether or not to clear the aliases
* @throws Doctrine_Query_Exception if some generic parsing error occurs
* @return Doctrine_Query
*/
public
function
parseQuery
(
$query
,
$clear
=
true
)
{
if
(
$clear
)
$this
->
clear
();
$query
=
trim
(
$query
);
$query
=
str_replace
(
"
\n
"
,
" "
,
$query
);
$query
=
str_replace
(
"
\r
"
,
" "
,
$query
);
$parts
=
$this
->
splitQuery
(
$query
);
foreach
(
$parts
as
$k
=>
$part
)
{
$part
=
implode
(
" "
,
$part
);
...
...
@@ -753,11 +776,18 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
}
/**
* bracketExplode
* usage:
* $str = (age < 20 AND age > 18) AND email LIKE 'John@example.com'
* now exploding $str with parameters $d = ' AND ', $e1 = '(' and $e2 = ')'
*
* example:
*
* parameters:
* $str = (age < 20 AND age > 18) AND email LIKE 'John@example.com'
* $d = ' AND '
* $e1 = '('
* $e2 = ')'
*
* would return an array:
* array("(age < 20 AND age > 18)", "email LIKE 'John@example.com'")
* array("(age < 20 AND age > 18)",
* "email LIKE 'John@example.com'")
*
* @param string $str
* @param string $d the delimeter which explodes the string
...
...
@@ -765,7 +795,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* @param string $e2 the second bracket, usually ')'
*
*/
public
static
function
bracketExplode
(
$str
,
$d
,
$e1
=
'('
,
$e2
=
')'
)
{
public
static
function
bracketExplode
(
$str
,
$d
=
' '
,
$e1
=
'('
,
$e2
=
')'
)
{
if
(
is_array
(
$d
))
{
$a
=
preg_split
(
'/('
.
implode
(
'|'
,
$d
)
.
')/'
,
$str
);
$d
=
stripslashes
(
$d
[
0
]);
...
...
@@ -777,13 +807,13 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
foreach
(
$a
as
$key
=>
$val
)
{
if
(
empty
(
$term
[
$i
]))
{
$term
[
$i
]
=
trim
(
$val
);
$s1
=
substr_count
(
$term
[
$i
],
"
$e1
"
);
$s2
=
substr_count
(
$term
[
$i
],
"
$e2
"
);
$s1
=
substr_count
(
$term
[
$i
],
"
$e1
"
);
$s2
=
substr_count
(
$term
[
$i
],
"
$e2
"
);
if
(
$s1
==
$s2
)
$i
++
;
}
else
{
$term
[
$i
]
.=
"
$d
"
.
trim
(
$val
);
$c1
=
substr_count
(
$term
[
$i
],
"
$e1
"
);
$c2
=
substr_count
(
$term
[
$i
],
"
$e2
"
);
$c1
=
substr_count
(
$term
[
$i
],
"
$e1
"
);
$c2
=
substr_count
(
$term
[
$i
],
"
$e2
"
);
if
(
$c1
==
$c2
)
$i
++
;
}
}
...
...
@@ -795,6 +825,21 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
* explodes a string into array using custom brackets and
* quote delimeters
*
*
* example:
*
* parameters:
* $str = "(age < 20 AND age > 18) AND name LIKE 'John Doe'"
* $d = ' '
* $e1 = '('
* $e2 = ')'
*
* would return an array:
* array('(age < 20 AND age > 18)',
* 'name',
* 'LIKE',
* 'John Doe')
*
* @param string $str
* @param string $d the delimeter which explodes the string
* @param string $e1 the first bracket, usually '('
...
...
@@ -802,7 +847,7 @@ class Doctrine_Query extends Doctrine_Hydrate implements Countable {
*
* @return array
*/
public
static
function
sqlExplode
(
$str
,
$d
=
" "
,
$e1
=
'('
,
$e2
=
')'
)
{
public
static
function
sqlExplode
(
$str
,
$d
=
' '
,
$e1
=
'('
,
$e2
=
')'
)
{
if
(
is_array
(
$d
))
{
$str
=
preg_split
(
'/('
.
implode
(
'|'
,
$d
)
.
')/'
,
$str
);
$d
=
stripslashes
(
$d
[
0
]);
...
...
lib/Doctrine/Record.php
View file @
7ef869ee
...
...
@@ -857,8 +857,9 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
$conn
=
$this
->
_table
->
getConnection
();
}
$conn
->
beginTransaction
();
$saveLater
=
$conn
->
saveRelated
(
$this
);
$saveLater
=
$conn
->
getUnitOfWork
()
->
saveRelated
(
$this
);
if
(
$this
->
isValid
())
{
$conn
->
save
(
$this
);
...
...
@@ -878,7 +879,8 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
// save the MANY-TO-MANY associations
$this
->
saveAssociations
();
$conn
->
getUnitOfWork
()
->
saveAssociations
(
$this
);
//$this->saveAssociations();
$conn
->
commit
();
}
...
...
@@ -1012,98 +1014,17 @@ abstract class Doctrine_Record extends Doctrine_Access implements Countable, Ite
public
function
getIterator
()
{
return
new
Doctrine_Record_Iterator
(
$this
);
}
public
function
obtainOriginals
(
$name
)
{
if
(
isset
(
$this
->
originals
[
$name
]))
return
$this
->
originals
[
$name
];
return
false
;
}
/**
* saveAssociations
*
* save the associations of many-to-many relations
* this method also deletes associations that do not exist anymore
*
* @return void
*/
final
public
function
saveAssociations
()
{
foreach
(
$this
->
_table
->
getRelations
()
as
$fk
)
{
$table
=
$fk
->
getTable
();
$name
=
$table
->
getComponentName
();
$alias
=
$this
->
_table
->
getAlias
(
$name
);
if
(
$fk
instanceof
Doctrine_Relation_Association
)
{
switch
(
$fk
->
getType
())
:
case
Doctrine_Relation
::
MANY_AGGREGATE
:
$asf
=
$fk
->
getAssociationFactory
();
if
(
isset
(
$this
->
references
[
$alias
]))
{
$new
=
$this
->
references
[
$alias
];
if
(
!
isset
(
$this
->
originals
[
$alias
]))
{
$this
->
loadReference
(
$alias
);
}
$r
=
Doctrine_Relation
::
getDeleteOperations
(
$this
->
originals
[
$alias
],
$new
);
foreach
(
$r
as
$record
)
{
$query
=
"DELETE FROM "
.
$asf
->
getTableName
()
.
" WHERE "
.
$fk
->
getForeign
()
.
" = ?"
.
" AND "
.
$fk
->
getLocal
()
.
" = ?"
;
$this
->
_table
->
getConnection
()
->
execute
(
$query
,
array
(
$record
->
getIncremented
(),
$this
->
getIncremented
()));
}
$r
=
Doctrine_Relation
::
getInsertOperations
(
$this
->
originals
[
$alias
],
$new
);
foreach
(
$r
as
$record
)
{
$reldao
=
$asf
->
create
();
$reldao
->
set
(
$fk
->
getForeign
(),
$record
);
$reldao
->
set
(
$fk
->
getLocal
(),
$this
);
$reldao
->
save
();
}
$this
->
originals
[
$alias
]
=
clone
$this
->
references
[
$alias
];
}
break
;
endswitch
;
}
elseif
(
$fk
instanceof
Doctrine_Relation_ForeignKey
||
$fk
instanceof
Doctrine_Relation_LocalKey
)
{
if
(
$fk
->
isOneToOne
())
{
if
(
isset
(
$this
->
originals
[
$alias
])
&&
$this
->
originals
[
$alias
]
->
obtainIdentifier
()
!=
$this
->
references
[
$alias
]
->
obtainIdentifier
())
$this
->
originals
[
$alias
]
->
delete
();
}
else
{
if
(
isset
(
$this
->
references
[
$alias
]))
{
$new
=
$this
->
references
[
$alias
];
if
(
!
isset
(
$this
->
originals
[
$alias
]))
$this
->
loadReference
(
$alias
);
$r
=
Doctrine_Relation
::
getDeleteOperations
(
$this
->
originals
[
$alias
],
$new
);
foreach
(
$r
as
$record
)
{
$record
->
delete
();
}
$this
->
originals
[
$alias
]
=
clone
$this
->
references
[
$alias
];
}
}
}
}
}
/**
* getOriginals
* returns an original collection of related component
*
* @return Doctrine_Collection
* @return Doctrine_Collection
|false
*/
final
public
function
get
Originals
(
$name
)
{
if
(
!
isset
(
$this
->
originals
[
$name
]))
throw
new
InvalidKeyException
()
;
return
$this
->
originals
[
$name
]
;
public
function
obtain
Originals
(
$name
)
{
if
(
isset
(
$this
->
originals
[
$name
]))
return
$this
->
originals
[
$name
]
;
return
false
;
}
/**
* deletes this data access object and all the related composites
...
...
lib/Doctrine/Relation/Association.php
View file @
7ef869ee
...
...
@@ -52,6 +52,45 @@ class Doctrine_Relation_Association extends Doctrine_Relation {
public
function
getAssociationFactory
()
{
return
$this
->
associationTable
;
}
/**
* processDiff
*
* @param Doctrine_Record
*/
public
function
processDiff
(
Doctrine_Record
$record
)
{
$asf
=
$this
->
getAssociationFactory
();
$alias
=
$this
->
getAlias
();
if
(
$record
->
hasReference
(
$alias
))
{
$new
=
$record
->
obtainReference
(
$alias
);
if
(
!
$record
->
obtainOriginals
(
$alias
))
$record
->
loadReference
(
$alias
);
$operations
=
Doctrine_Relation
::
getDeleteOperations
(
$record
->
obtainOriginals
(
$alias
),
$new
);
foreach
(
$operations
as
$r
)
{
$query
=
'DELETE FROM '
.
$asf
->
getTableName
()
.
' WHERE '
.
$this
->
getForeign
()
.
' = ?'
.
' AND '
.
$this
->
getLocal
()
.
' = ?'
;
$this
->
getTable
()
->
getConnection
()
->
execute
(
$query
,
array
(
$r
->
getIncremented
(),
$record
->
getIncremented
()));
}
$operations
=
Doctrine_Relation
::
getInsertOperations
(
$record
->
obtainOriginals
(
$alias
),
$new
);
foreach
(
$operations
as
$r
)
{
$reldao
=
$asf
->
create
();
$reldao
->
set
(
$this
->
getForeign
(),
$r
);
$reldao
->
set
(
$this
->
getLocal
(),
$record
);
$reldao
->
save
();
}
$record
->
assignOriginals
(
$alias
,
clone
$record
->
get
(
$alias
));
}
}
/**
* getRelationDql
*
...
...
lib/Doctrine/Relation/ForeignKey.php
View file @
7ef869ee
...
...
@@ -28,6 +28,35 @@ Doctrine::autoload('Doctrine_Relation');
* @package Doctrine
*/
class
Doctrine_Relation_ForeignKey
extends
Doctrine_Relation
{
/**
* processDiff
*
* @param Doctrine_Record $record
*/
public
function
processDiff
(
Doctrine_Record
$record
)
{
$alias
=
$this
->
getAlias
();
if
(
$this
->
isOneToOne
())
{
if
(
$record
->
obtainOriginals
(
$alias
)
&&
$record
->
obtainOriginals
(
$alias
)
->
obtainIdentifier
()
!=
$this
->
obtainReference
(
$alias
)
->
obtainIdentifier
())
$record
->
obtainOriginals
(
$alias
)
->
delete
();
}
else
{
if
(
$record
->
hasReference
(
$alias
))
{
$new
=
$record
->
obtainReference
(
$alias
);
if
(
!
$record
->
obtainOriginals
(
$alias
))
$record
->
loadReference
(
$alias
);
$operations
=
Doctrine_Relation
::
getDeleteOperations
(
$record
->
obtainOriginals
(
$alias
),
$new
);
foreach
(
$operations
as
$r
)
{
$r
->
delete
();
}
$record
->
assignOriginals
(
$alias
,
clone
$record
->
get
(
$alias
));
}
}
}
/**
* fetchRelatedFor
*
...
...
lib/Doctrine/Relation/LocalKey.php
View file @
7ef869ee
...
...
@@ -28,6 +28,18 @@ Doctrine::autoload('Doctrine_Relation');
* @package Doctrine
*/
class
Doctrine_Relation_LocalKey
extends
Doctrine_Relation
{
/**
* processDiff
*
* @param Doctrine_Record $record
*/
public
function
processDiff
(
Doctrine_Record
$record
)
{
$alias
=
$this
->
getAlias
();
if
(
$record
->
obtainOriginals
(
$alias
)
&&
$record
->
obtainOriginals
(
$alias
)
->
obtainIdentifier
()
!=
$this
->
references
[
$alias
]
->
obtainIdentifier
())
$record
->
obtainOriginals
(
$alias
)
->
delete
();
}
/**
* fetchRelatedFor
*
...
...
tests/run.php
View file @
7ef869ee
...
...
@@ -64,16 +64,14 @@ print '<pre>';
$test
=
new
GroupTest
(
'Doctrine Framework Unit Tests'
);
$test
->
addTestCase
(
new
Doctrine_
DataDict_Pgsql
_TestCase
());
$test
->
addTestCase
(
new
Doctrine_
Record
_TestCase
());
$test
->
addTestCase
(
new
Doctrine_DataDict_Pgsql_TestCase
());
$test
->
addTestCase
(
new
Doctrine_Relation_ManyToMany_TestCase
());
$test
->
addTestCase
(
new
Doctrine_Relation_TestCase
());
$test
->
addTestCase
(
new
Doctrine_Record_TestCase
());
$test
->
addTestCase
(
new
Doctrine_Record_State_TestCase
());
$test
->
addTestCase
(
new
Doctrine_Import_TestCase
());
...
...
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