Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yii2
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
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
PSDI Army
yii2
Commits
62336b43
Commit
62336b43
authored
Mar 02, 2012
by
Qiang Xue
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
...
parent
50743935
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
270 additions
and
113 deletions
+270
-113
ActiveFinder.php
framework/db/ar/ActiveFinder.php
+174
-45
ActiveQuery.php
framework/db/ar/ActiveQuery.php
+5
-5
ActiveRecord.php
framework/db/ar/ActiveRecord.php
+12
-6
JoinElement.php
framework/db/ar/JoinElement.php
+79
-57
No files found.
framework/db/ar/ActiveFinder.php
View file @
62336b43
...
@@ -31,7 +31,6 @@ use yii\db\Exception;
...
@@ -31,7 +31,6 @@ use yii\db\Exception;
* todo: lazy loading
* todo: lazy loading
* todo: scope
* todo: scope
* todo: test via option
* todo: test via option
* todo: count, sum, exists
todo: inner join with one or multiple relations as filters
todo: inner join with one or multiple relations as filters
joinType should default to inner join in this case
joinType should default to inner join in this case
*
*
...
@@ -61,7 +60,7 @@ class ActiveFinder extends \yii\base\Object
...
@@ -61,7 +60,7 @@ class ActiveFinder extends \yii\base\Object
* @param bool $all
* @param bool $all
* @return array
* @return array
*/
*/
public
function
findRecords
(
$query
,
$all
=
true
)
public
function
findRecords
(
$query
)
{
{
if
(
$query
->
sql
!==
null
)
{
if
(
$query
->
sql
!==
null
)
{
$sql
=
$query
->
sql
;
$sql
=
$query
->
sql
;
...
@@ -81,16 +80,7 @@ class ActiveFinder extends \yii\base\Object
...
@@ -81,16 +80,7 @@ class ActiveFinder extends \yii\base\Object
}
}
$command
=
$this
->
connection
->
createCommand
(
$sql
,
$query
->
params
);
$command
=
$this
->
connection
->
createCommand
(
$sql
,
$query
->
params
);
if
(
$all
)
{
$rows
=
$command
->
queryAll
();
$rows
=
$command
->
queryAll
();
}
else
{
$row
=
$command
->
queryRow
();
if
(
$row
===
false
)
{
return
array
();
}
$rows
=
array
(
$row
);
}
$records
=
array
();
$records
=
array
();
if
(
$query
->
asArray
)
{
if
(
$query
->
asArray
)
{
if
(
$query
->
indexBy
===
null
)
{
if
(
$query
->
indexBy
===
null
)
{
...
@@ -120,20 +110,18 @@ class ActiveFinder extends \yii\base\Object
...
@@ -120,20 +110,18 @@ class ActiveFinder extends \yii\base\Object
}
}
public
function
findRecordsWithRelations
()
public
function
findRecordsWithRelations
(
$query
)
{
{
if
(
!
empty
(
$this
->
with
))
{
// todo: handle findBySql() and limit cases
// todo: handle findBySql() and limit cases
$joinTree
=
$this
->
buildRelationalQuery
();
$joinTree
=
$this
->
buildRelationalQuery
();
}
if
(
$this
->
sql
===
null
)
{
if
(
$this
->
sql
===
null
)
{
$this
->
initFrom
(
$
this
->
query
);
$this
->
initFrom
(
$
element
->
query
);
$command
=
$
this
->
query
->
createCommand
(
$this
->
getDbConnection
());
$command
=
$
element
->
query
->
createCommand
(
$this
->
getDbConnection
());
$this
->
sql
=
$command
->
getSql
();
$this
->
sql
=
$command
->
getSql
();
}
else
{
}
else
{
$command
=
$this
->
getDbConnection
()
->
createCommand
(
$this
->
sql
);
$command
=
$this
->
getDbConnection
()
->
createCommand
(
$this
->
sql
);
$command
->
bindValues
(
$
this
->
query
->
params
);
$command
->
bindValues
(
$
element
->
query
->
params
);
}
}
$rows
=
$command
->
queryAll
();
$rows
=
$command
->
queryAll
();
...
@@ -204,43 +192,49 @@ class ActiveFinder extends \yii\base\Object
...
@@ -204,43 +192,49 @@ class ActiveFinder extends \yii\base\Object
}
}
}
}
protected
function
buildRelationalQuery
()
private
$_joinCount
;
private
$_tableAliases
;
protected
function
buildQuery
()
{
{
$joinTree
=
new
JoinElement
(
$this
,
null
,
null
);
$this
->
_joinCount
=
0
;
$this
->
buildJoinTree
(
$joinTree
,
$this
->
with
);
$joinTree
=
new
JoinElement
(
$this
->
_joinCount
++
,
$element
->
query
,
null
,
null
);
$this
->
buildJoinTree
(
$joinTree
,
$element
->
query
->
with
);
$this
->
_tableAliases
=
array
();
$this
->
buildTableAlias
(
$joinTree
);
$this
->
buildTableAlias
(
$joinTree
);
$query
=
new
Query
;
$query
=
new
Query
;
foreach
(
$joinTree
->
children
as
$child
)
{
foreach
(
$joinTree
->
children
as
$child
)
{
$child
->
buildQuery
(
$query
);
$child
->
buildQuery
(
$query
);
}
}
$select
=
$joinTree
->
buildSelect
(
$
this
->
query
->
select
);
$select
=
$joinTree
->
buildSelect
(
$
element
,
$element
->
query
->
select
);
if
(
!
empty
(
$query
->
select
))
{
if
(
!
empty
(
$query
->
select
))
{
$
this
->
query
->
select
=
array_merge
(
$select
,
$query
->
select
);
$
element
->
query
->
select
=
array_merge
(
$select
,
$query
->
select
);
}
else
{
}
else
{
$
this
->
query
->
select
=
$select
;
$
element
->
query
->
select
=
$select
;
}
}
if
(
!
empty
(
$query
->
where
))
{
if
(
!
empty
(
$query
->
where
))
{
$
this
->
query
->
andWhere
(
'('
.
implode
(
') AND ('
,
$query
->
where
)
.
')'
);
$
element
->
query
->
andWhere
(
'('
.
implode
(
') AND ('
,
$query
->
where
)
.
')'
);
}
}
if
(
!
empty
(
$query
->
having
))
{
if
(
!
empty
(
$query
->
having
))
{
$
this
->
query
->
andHaving
(
'('
.
implode
(
') AND ('
,
$query
->
having
)
.
')'
);
$
element
->
query
->
andHaving
(
'('
.
implode
(
') AND ('
,
$query
->
having
)
.
')'
);
}
}
if
(
!
empty
(
$query
->
join
))
{
if
(
!
empty
(
$query
->
join
))
{
if
(
$
this
->
query
->
join
===
null
)
{
if
(
$
element
->
query
->
join
===
null
)
{
$
this
->
query
->
join
=
$query
->
join
;
$
element
->
query
->
join
=
$query
->
join
;
}
else
{
}
else
{
$
this
->
query
->
join
=
array_merge
(
$this
->
query
->
join
,
$query
->
join
);
$
element
->
query
->
join
=
array_merge
(
$element
->
query
->
join
,
$query
->
join
);
}
}
}
}
if
(
!
empty
(
$query
->
orderBy
))
{
if
(
!
empty
(
$query
->
orderBy
))
{
$
this
->
query
->
addOrderBy
(
$query
->
orderBy
);
$
element
->
query
->
addOrderBy
(
$query
->
orderBy
);
}
}
if
(
!
empty
(
$query
->
groupBy
))
{
if
(
!
empty
(
$query
->
groupBy
))
{
$
this
->
query
->
addGroupBy
(
$query
->
groupBy
);
$
element
->
query
->
addGroupBy
(
$query
->
groupBy
);
}
}
if
(
!
empty
(
$query
->
params
))
{
if
(
!
empty
(
$query
->
params
))
{
$
this
->
query
->
addParams
(
$query
->
params
);
$
element
->
query
->
addParams
(
$query
->
params
);
}
}
return
$joinTree
;
return
$joinTree
;
...
@@ -257,10 +251,10 @@ class ActiveFinder extends \yii\base\Object
...
@@ -257,10 +251,10 @@ class ActiveFinder extends \yii\base\Object
{
{
if
(
is_array
(
$with
))
{
if
(
is_array
(
$with
))
{
foreach
(
$with
as
$name
=>
$value
)
{
foreach
(
$with
as
$name
=>
$value
)
{
if
(
is_string
(
$value
))
{
if
(
is_array
(
$value
))
{
$this
->
buildJoinTree
(
$parent
,
$value
);
}
elseif
(
is_string
(
$name
)
&&
is_array
(
$value
))
{
$this
->
buildJoinTree
(
$parent
,
$name
,
$value
);
$this
->
buildJoinTree
(
$parent
,
$name
,
$value
);
}
else
{
$this
->
buildJoinTree
(
$parent
,
$value
);
}
}
}
}
return
null
;
return
null
;
...
@@ -275,38 +269,173 @@ class ActiveFinder extends \yii\base\Object
...
@@ -275,38 +269,173 @@ class ActiveFinder extends \yii\base\Object
$child
=
$parent
->
children
[
$with
];
$child
=
$parent
->
children
[
$with
];
$child
->
joinOnly
=
false
;
$child
->
joinOnly
=
false
;
}
else
{
}
else
{
$modelClass
=
$parent
->
relation
->
modelClass
;
$modelClass
=
$parent
->
query
->
modelClass
;
$relations
=
$modelClass
::
getMetaData
()
->
relations
;
$relations
=
$modelClass
::
getMetaData
()
->
relations
;
if
(
!
isset
(
$relations
[
$with
]))
{
if
(
!
isset
(
$relations
[
$with
]))
{
throw
new
Exception
(
"
$modelClass
has no relation named '
$with
'."
);
throw
new
Exception
(
"
$modelClass
has no relation named '
$with
'."
);
}
}
$relation
=
clone
$relations
[
$with
];
$relation
=
clone
$relations
[
$with
];
if
(
$relation
->
via
!==
null
&&
isset
(
$relations
[
$relation
->
via
]))
{
if
(
$relation
->
via
!==
null
&&
isset
(
$relations
[
$relation
->
via
]))
{
$relation
->
via
=
null
;
$parent2
=
$this
->
buildJoinTree
(
$parent
,
$relation
->
via
);
$parent2
=
$this
->
buildJoinTree
(
$parent
,
$relation
->
via
);
$relation
->
via
=
null
;
if
(
$parent2
->
joinOnly
===
null
)
{
if
(
$parent2
->
joinOnly
===
null
)
{
$parent2
->
joinOnly
=
true
;
$parent2
->
joinOnly
=
true
;
}
}
$child
=
new
JoinElement
(
$relation
,
$parent2
,
$parent
);
$child
=
new
JoinElement
(
$
this
->
_joinCount
++
,
$
relation
,
$parent2
,
$parent
);
}
else
{
}
else
{
$child
=
new
JoinElement
(
$relation
,
$parent
,
$parent
);
$child
=
new
JoinElement
(
$
this
->
_joinCount
++
,
$
relation
,
$parent
,
$parent
);
}
}
}
}
foreach
(
$config
as
$name
=>
$value
)
{
foreach
(
$config
as
$name
=>
$value
)
{
$child
->
relation
->
$name
=
$value
;
$child
->
query
->
$name
=
$value
;
}
}
return
$child
;
return
$child
;
}
}
protected
function
buildTableAlias
(
$element
,
&
$count
=
0
)
/**
* @param JoinElement $element
*/
protected
function
buildTableAlias
(
$element
)
{
{
if
(
$element
->
relation
->
tableAlias
===
null
)
{
if
(
$element
->
query
->
tableAlias
!==
null
)
{
$element
->
relation
->
tableAlias
=
't'
.
(
$count
++
);
$alias
=
$element
->
query
->
tableAlias
;
}
elseif
(
$element
->
query
instanceof
ActiveRelation
)
{
$alias
=
$element
->
query
->
name
;
}
else
{
$alias
=
't'
;
}
}
$count
=
0
;
while
(
isset
(
$this
->
_tableAliases
[
$alias
]))
{
$alias
=
't'
.
$count
++
;
}
$this
->
_tableAliases
[
$alias
]
=
true
;
$element
->
query
->
tableAlias
=
$alias
;
foreach
(
$element
->
children
as
$child
)
{
foreach
(
$element
->
children
as
$child
)
{
$this
->
buildTableAlias
(
$child
,
$count
);
$this
->
buildTableAlias
(
$child
,
$count
);
}
}
}
}
/**
* @param JoinElement $element
* @param Query $query
*/
protected
function
buildJoinQuery
(
$element
,
$query
)
{
$prefixes
=
array
(
'@.'
=>
$element
->
query
->
tableAlias
.
'.'
,
'?.'
=>
$element
->
parent
->
query
->
tableAlias
.
'.'
,
);
$quotedPrefixes
=
array
(
'@.'
=>
$this
->
connection
->
quoteTableName
(
$element
->
query
->
tableAlias
,
true
)
.
'.'
,
'?.'
=>
$this
->
connection
->
quoteTableName
(
$element
->
parent
->
query
->
tableAlias
,
true
)
.
'.'
,
);
foreach
(
$this
->
buildSelect
(
$element
,
$element
->
query
->
select
)
as
$column
)
{
$query
->
select
[]
=
strtr
(
$column
,
$prefixes
);
}
if
(
$element
->
query
->
where
!==
null
)
{
$query
->
where
[]
=
strtr
(
$element
->
query
->
where
,
$quotedPrefixes
);
}
if
(
$element
->
query
->
having
!==
null
)
{
$query
->
having
[]
=
strtr
(
$element
->
query
->
having
,
$quotedPrefixes
);
}
if
(
$element
->
query
->
via
!==
null
)
{
$query
->
join
[]
=
strtr
(
$element
->
query
->
via
,
$quotedPrefixes
);
}
if
(
$element
->
query
->
joinType
===
null
)
{
$joinType
=
$element
->
query
->
select
===
false
?
'INNER JOIN'
:
'LEFT JOIN'
;
}
else
{
$joinType
=
$element
->
query
->
joinType
;
}
$modelClass
=
$element
->
query
->
modelClass
;
$tableName
=
$this
->
connection
->
quoteTableName
(
$modelClass
::
tableName
());
$tableAlias
=
$this
->
connection
->
quoteTableName
(
$element
->
query
->
tableAlias
);
$join
=
"
$joinType
$tableName
$tableAlias
"
;
if
(
$element
->
query
->
on
!==
null
)
{
$join
.=
' ON '
.
strtr
(
$element
->
query
->
on
,
$quotedPrefixes
);
}
$query
->
join
[]
=
$join
;
if
(
$element
->
query
->
join
!==
null
)
{
$query
->
join
[]
=
strtr
(
$element
->
query
->
join
,
$quotedPrefixes
);
}
if
(
$element
->
query
->
orderBy
!==
null
)
{
if
(
!
is_array
(
$element
->
query
->
orderBy
))
{
$element
->
query
->
orderBy
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$element
->
query
->
orderBy
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
foreach
(
$element
->
query
->
orderBy
as
$orderBy
)
{
$query
->
orderBy
[]
=
strtr
(
$orderBy
,
$prefixes
);
}
}
if
(
$element
->
query
->
groupBy
!==
null
)
{
if
(
!
is_array
(
$element
->
query
->
groupBy
))
{
$element
->
query
->
groupBy
=
preg_split
(
'/\s*,\s*/'
,
trim
(
$element
->
query
->
groupBy
),
-
1
,
PREG_SPLIT_NO_EMPTY
);
}
foreach
(
$element
->
query
->
groupBy
as
$groupBy
)
{
$query
->
groupBy
[]
=
strtr
(
$groupBy
,
$prefixes
);
}
}
if
(
$element
->
query
->
params
!==
null
)
{
$query
->
addParams
(
$element
->
query
->
params
);
}
foreach
(
$element
->
children
as
$child
)
{
$this
->
buildQuery
(
$child
,
$query
);
}
}
protected
function
buildSelect
(
$element
,
$select
)
{
if
(
$select
===
false
)
{
return
array
();
}
$modelClass
=
$element
->
query
->
modelClass
;
$table
=
$modelClass
::
getMetaData
()
->
table
;
$columns
=
array
();
$columnCount
=
0
;
$prefix
=
$element
->
query
->
tableAlias
;
if
(
empty
(
$select
)
||
$select
===
'*'
)
{
foreach
(
$table
->
columns
as
$column
)
{
$alias
=
"t
{
$element
->
id
}
c"
.
(
$columnCount
++
);
$columns
[]
=
"
$prefix
.
{
$column
->
name
}
AS
$alias
"
;
$element
->
columnAliases
[
$alias
]
=
$column
->
name
;
if
(
$column
->
isPrimaryKey
)
{
$element
->
pkAlias
[
$column
->
name
]
=
$alias
;
}
}
}
else
{
if
(
is_string
(
$select
))
{
$select
=
explode
(
','
,
$select
);
}
foreach
(
$table
->
primaryKey
as
$column
)
{
$alias
=
"t
{
$element
->
id
}
c"
.
(
$columnCount
++
);
$columns
[]
=
"
$prefix
.
$column
AS
$alias
"
;
$element
->
pkAlias
[
$column
]
=
$alias
;
}
foreach
(
$select
as
$column
)
{
$column
=
trim
(
$column
);
if
(
preg_match
(
'/^(.*?)\s+AS\s+(\w+)$/im'
,
$column
,
$matches
))
{
// if the column is already aliased
$element
->
columnAliases
[
$matches
[
2
]]
=
$matches
[
2
];
$columns
[]
=
$column
;
}
elseif
(
!
isset
(
$element
->
pkAlias
[
$column
]))
{
$alias
=
"t
{
$element
->
id
}
c"
.
(
$columnCount
++
);
$columns
[]
=
"
$prefix
.
$column
AS
$alias
"
;
$element
->
columnAliases
[
$alias
]
=
$column
;
}
}
}
return
$columns
;
}
}
}
framework/db/ar/ActiveQuery.php
View file @
62336b43
...
@@ -91,8 +91,8 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
...
@@ -91,8 +91,8 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
public
function
one
()
public
function
one
()
{
{
if
(
$this
->
records
===
null
)
{
if
(
$this
->
records
===
null
)
{
// todo: load only one record
$this
->
limit
=
1
;
$this
->
records
=
$this
->
findRecords
(
false
);
$this
->
records
=
$this
->
findRecords
();
}
}
return
isset
(
$this
->
records
[
0
])
?
$this
->
records
[
0
]
:
null
;
return
isset
(
$this
->
records
[
0
])
?
$this
->
records
[
0
]
:
null
;
}
}
...
@@ -240,13 +240,13 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
...
@@ -240,13 +240,13 @@ class ActiveQuery extends BaseActiveQuery implements \IteratorAggregate, \ArrayA
unset
(
$this
->
records
[
$offset
]);
unset
(
$this
->
records
[
$offset
]);
}
}
protected
function
findRecords
(
$all
=
true
)
protected
function
findRecords
()
{
{
$finder
=
new
ActiveFinder
(
$this
->
getDbConnection
());
$finder
=
new
ActiveFinder
(
$this
->
getDbConnection
());
if
(
!
empty
(
$this
->
with
))
{
if
(
!
empty
(
$this
->
with
))
{
return
$finder
->
findRecordsWithRelations
();
return
$finder
->
findRecordsWithRelations
(
$this
);
}
else
{
}
else
{
return
$finder
->
findRecords
(
$this
,
$all
);
return
$finder
->
findRecords
(
$this
);
}
}
}
}
}
}
framework/db/ar/ActiveRecord.php
View file @
62336b43
...
@@ -517,10 +517,18 @@ abstract class ActiveRecord extends Model
...
@@ -517,10 +517,18 @@ abstract class ActiveRecord extends Model
$this
->
_related
[
$relation
->
name
]
=
$relation
->
hasMany
?
array
()
:
null
;
$this
->
_related
[
$relation
->
name
]
=
$relation
->
hasMany
?
array
()
:
null
;
}
}
/**
* @param ActiveRelation $relation
* @param ActiveRecord $record
*/
public
function
addRelatedRecord
(
$relation
,
$record
)
public
function
addRelatedRecord
(
$relation
,
$record
)
{
{
if
(
$relation
->
hasMany
)
{
if
(
$relation
->
hasMany
)
{
$this
->
_related
[
$relation
->
name
][]
=
$record
;
if
(
$relation
->
indexBy
!==
null
)
{
$this
->
_related
[
$relation
->
name
][
$record
->
{
$relation
->
indexBy
}]
=
$record
;
}
else
{
$this
->
_related
[
$relation
->
name
][]
=
$record
;
}
}
else
{
}
else
{
$this
->
_related
[
$relation
->
name
]
=
$record
;
$this
->
_related
[
$relation
->
name
]
=
$record
;
}
}
...
@@ -1027,12 +1035,10 @@ abstract class ActiveRecord extends Model
...
@@ -1027,12 +1035,10 @@ abstract class ActiveRecord extends Model
/**
/**
* Creates an active record with the given attributes.
* Creates an active record with the given attributes.
* This method is internally used by the find methods.
* @param array $row attribute values (name => value)
* @param array $row attribute values (column name=>column value)
* @return ActiveRecord the newly created active record.
* @return ActiveRecord the newly created active record. The class of the object is the same as the model class.
* Null is returned if the input data is false.
*/
*/
public
static
function
create
Record
(
$row
)
public
static
function
create
(
$row
)
{
{
$record
=
static
::
instantiate
(
$row
);
$record
=
static
::
instantiate
(
$row
);
$columns
=
static
::
getMetaData
()
->
table
->
columns
;
$columns
=
static
::
getMetaData
()
->
table
->
columns
;
...
...
framework/db/ar/JoinElement.php
View file @
62336b43
...
@@ -18,9 +18,13 @@ use yii\db\Exception;
...
@@ -18,9 +18,13 @@ use yii\db\Exception;
class
JoinElement
extends
\yii\base\Object
class
JoinElement
extends
\yii\base\Object
{
{
/**
/**
* @var
ActiveRelation
* @var
integer ID of this join element
*/
*/
public
$relation
;
public
$id
;
/**
* @var BaseActiveQuery
*/
public
$query
;
/**
/**
* @var JoinElement the parent element that this element needs to join with
* @var JoinElement the parent element that this element needs to join with
*/
*/
...
@@ -32,9 +36,9 @@ class JoinElement extends \yii\base\Object
...
@@ -32,9 +36,9 @@ class JoinElement extends \yii\base\Object
/**
/**
* @var JoinElement[] the child elements that have relations declared in the AR class of this element
* @var JoinElement[] the child elements that have relations declared in the AR class of this element
*/
*/
public
$relat
edChildren
=
array
();
public
$relat
ions
=
array
();
/**
/**
* @var boolean whether this element is only for join purpose. If
tru
e, data will also be populated into the AR of this element.
* @var boolean whether this element is only for join purpose. If
fals
e, data will also be populated into the AR of this element.
*/
*/
public
$joinOnly
;
public
$joinOnly
;
...
@@ -44,17 +48,27 @@ class JoinElement extends \yii\base\Object
...
@@ -44,17 +48,27 @@ class JoinElement extends \yii\base\Object
public
$records
;
public
$records
;
public
$relatedRecords
;
public
$relatedRecords
;
public
function
__construct
(
$relation
,
$parent
,
$relatedParent
)
/**
* @param ActiveRelation|ActiveQuery $query
* @param JoinElement $parent
* @param JoinElement $container
*/
public
function
__construct
(
$id
,
$query
,
$parent
,
$container
)
{
{
$this
->
relation
=
$relation
;
$this
->
id
=
$id
;
$this
->
query
=
$query
;
if
(
$parent
!==
null
)
{
if
(
$parent
!==
null
)
{
$this
->
parent
=
$parent
;
$this
->
parent
=
$parent
;
$parent
->
children
[
$
relation
->
name
]
=
$this
;
$parent
->
children
[
$
query
->
name
]
=
$this
;
$
relatedParent
->
relatedChildren
[
$relation
->
name
]
=
$this
;
$
container
->
relations
[
$query
->
name
]
=
$this
;
}
}
}
}
public
function
populateData
(
$row
)
/**
* @param array $row
* @return null|ActiveRecord
*/
public
function
createRecord
(
$row
)
{
{
$pk
=
array
();
$pk
=
array
();
foreach
(
$this
->
pkAlias
as
$alias
)
{
foreach
(
$this
->
pkAlias
as
$alias
)
{
...
@@ -66,7 +80,7 @@ class JoinElement extends \yii\base\Object
...
@@ -66,7 +80,7 @@ class JoinElement extends \yii\base\Object
}
}
$pk
=
count
(
$pk
)
===
1
?
$pk
[
0
]
:
serialize
(
$pk
);
$pk
=
count
(
$pk
)
===
1
?
$pk
[
0
]
:
serialize
(
$pk
);
// create
active
record
// create record
if
(
isset
(
$this
->
records
[
$pk
]))
{
if
(
isset
(
$this
->
records
[
$pk
]))
{
$record
=
$this
->
records
[
$pk
];
$record
=
$this
->
records
[
$pk
];
}
else
{
}
else
{
...
@@ -76,33 +90,37 @@ class JoinElement extends \yii\base\Object
...
@@ -76,33 +90,37 @@ class JoinElement extends \yii\base\Object
$attributes
[
$this
->
columnAliases
[
$alias
]]
=
$value
;
$attributes
[
$this
->
columnAliases
[
$alias
]]
=
$value
;
}
}
}
}
$modelClass
=
$this
->
relation
->
modelClass
;
$modelClass
=
$this
->
query
->
modelClass
;
$
record
=
$modelClass
::
populateData
(
$attributes
);
$
this
->
records
[
$pk
]
=
$record
=
$modelClass
::
create
(
$attributes
);
foreach
(
$this
->
children
as
$child
)
{
foreach
(
$this
->
children
as
$child
)
{
if
(
$child
->
relation
->
select
!==
false
)
{
if
(
$child
->
query
->
select
!==
false
||
$child
->
joinOnly
)
{
$record
->
initRelation
(
$child
->
relation
);
$record
->
initRelation
(
$child
->
query
);
}
}
}
}
$this
->
records
[
$pk
]
=
$record
;
}
}
//
populate chil
d records
//
add relate
d records
foreach
(
$this
->
relat
edChildren
as
$child
)
{
foreach
(
$this
->
relat
ions
as
$child
)
{
if
(
$child
->
relation
->
select
===
false
||
$child
->
joinOnly
)
{
if
(
$child
->
query
->
select
===
false
||
$child
->
joinOnly
)
{
continue
;
continue
;
}
}
$childRecord
=
$child
->
populateData
(
$row
);
$childRecord
=
$child
->
createRecord
(
$row
);
if
(
$childRecord
===
null
)
{
if
(
$childRecord
===
null
)
{
continue
;
continue
;
}
}
if
(
$child
->
relation
->
hasMany
)
{
if
(
$child
->
query
->
hasMany
)
{
$fpk
=
serialize
(
$childRecord
->
getPrimaryKey
());
if
(
$child
->
query
->
indexBy
!==
null
)
{
if
(
isset
(
$this
->
relatedRecords
[
$pk
][
$child
->
relation
->
name
][
$fpk
]))
{
$hash
=
$childRecord
->
{
$child
->
query
->
indexBy
};
continue
;
}
else
{
$hash
=
serialize
(
$childRecord
->
getPrimaryKey
());
}
if
(
!
isset
(
$this
->
relatedRecords
[
$pk
][
$child
->
query
->
name
][
$hash
]))
{
$this
->
relatedRecords
[
$pk
][
$child
->
query
->
name
][
$hash
]
=
true
;
$record
->
addRelatedRecord
(
$child
->
query
,
$childRecord
);
}
}
$this
->
relatedRecords
[
$pk
][
$child
->
relation
->
name
][
$fpk
]
=
true
;
}
else
{
$record
->
addRelatedRecord
(
$child
->
query
,
$childRecord
);
}
}
$record
->
addRelatedRecord
(
$child
->
relation
,
$childRecord
);
}
}
return
$record
;
return
$record
;
...
@@ -110,52 +128,53 @@ class JoinElement extends \yii\base\Object
...
@@ -110,52 +128,53 @@ class JoinElement extends \yii\base\Object
public
function
buildQuery
(
$query
)
public
function
buildQuery
(
$query
)
{
{
$
token
s
=
array
(
$
prefixe
s
=
array
(
'@.'
=>
$this
->
relation
->
tableAlias
.
'.'
,
'@.'
=>
$this
->
query
->
tableAlias
.
'.'
,
'?.'
=>
$this
->
parent
->
relation
->
tableAlias
.
'.'
,
'?.'
=>
$this
->
parent
->
query
->
tableAlias
.
'.'
,
);
);
foreach
(
$this
->
buildSelect
(
$this
->
relation
->
select
)
as
$column
)
{
$quotedPrefixes
=
''
;
$query
->
select
[]
=
strtr
(
$column
,
$tokens
);
foreach
(
$this
->
buildSelect
(
$this
->
query
->
select
)
as
$column
)
{
$query
->
select
[]
=
strtr
(
$column
,
$prefixes
);
}
}
if
(
$this
->
relation
->
where
!==
null
)
{
if
(
$this
->
query
->
where
!==
null
)
{
$query
->
where
[]
=
strtr
(
$this
->
relation
->
where
,
$token
s
);
$query
->
where
[]
=
strtr
(
$this
->
query
->
where
,
$prefixe
s
);
}
}
if
(
$this
->
relation
->
having
!==
null
)
{
if
(
$this
->
query
->
having
!==
null
)
{
$query
->
having
[]
=
strtr
(
$this
->
relation
->
having
,
$token
s
);
$query
->
having
[]
=
strtr
(
$this
->
query
->
having
,
$prefixe
s
);
}
}
if
(
$this
->
relation
->
via
!==
null
)
{
if
(
$this
->
query
->
via
!==
null
)
{
$query
->
join
[]
=
$this
->
relation
->
via
;
$query
->
join
[]
=
$this
->
query
->
via
;
}
}
$modelClass
=
$this
->
relation
->
modelClass
;
$modelClass
=
$this
->
query
->
modelClass
;
$tableName
=
$modelClass
::
tableName
();
$tableName
=
$modelClass
::
tableName
();
$joinType
=
$this
->
relation
->
joinType
===
null
?
'LEFT JOIN'
:
$this
->
relation
->
joinType
;
$joinType
=
$this
->
query
->
joinType
===
null
?
'LEFT JOIN'
:
$this
->
query
->
joinType
;
$join
=
"
$joinType
$tableName
{
$this
->
relation
->
tableAlias
}
"
;
$join
=
"
$joinType
$tableName
{
$this
->
query
->
tableAlias
}
"
;
if
(
$this
->
relation
->
on
!==
null
)
{
if
(
$this
->
query
->
on
!==
null
)
{
$join
.=
' ON '
.
strtr
(
$this
->
relation
->
on
,
$token
s
);
$join
.=
' ON '
.
strtr
(
$this
->
query
->
on
,
$prefixe
s
);
}
}
$query
->
join
[]
=
$join
;
$query
->
join
[]
=
$join
;
if
(
$this
->
relation
->
join
!==
null
)
{
if
(
$this
->
query
->
join
!==
null
)
{
$query
->
join
[]
=
strtr
(
$this
->
relation
->
join
,
$token
s
);
$query
->
join
[]
=
strtr
(
$this
->
query
->
join
,
$prefixe
s
);
}
}
// todo: convert orderBy to array first
// todo: convert orderBy to array first
if
(
$this
->
relation
->
orderBy
!==
null
)
{
if
(
$this
->
query
->
orderBy
!==
null
)
{
$query
->
orderBy
[]
=
strtr
(
$this
->
relation
->
orderBy
,
$token
s
);
$query
->
orderBy
[]
=
strtr
(
$this
->
query
->
orderBy
,
$prefixe
s
);
}
}
// todo: convert groupBy to array first
// todo: convert groupBy to array first
if
(
$this
->
relation
->
groupBy
!==
null
)
{
if
(
$this
->
query
->
groupBy
!==
null
)
{
$query
->
groupBy
[]
=
strtr
(
$this
->
relation
->
groupBy
,
$token
s
);
$query
->
groupBy
[]
=
strtr
(
$this
->
query
->
groupBy
,
$prefixe
s
);
}
}
if
(
$this
->
relation
->
params
!==
null
)
{
if
(
$this
->
query
->
params
!==
null
)
{
foreach
(
$this
->
relation
->
params
as
$name
=>
$value
)
{
foreach
(
$this
->
query
->
params
as
$name
=>
$value
)
{
if
(
is_integer
(
$name
))
{
if
(
is_integer
(
$name
))
{
$query
->
params
[]
=
$value
;
$query
->
params
[]
=
$value
;
}
else
{
}
else
{
...
@@ -171,14 +190,17 @@ class JoinElement extends \yii\base\Object
...
@@ -171,14 +190,17 @@ class JoinElement extends \yii\base\Object
public
function
buildSelect
(
$select
)
public
function
buildSelect
(
$select
)
{
{
$modelClass
=
$this
->
relation
->
modelClass
;
if
(
$select
===
false
)
{
$tableSchema
=
$modelClass
::
getMetaData
()
->
table
;
return
array
();
}
$modelClass
=
$this
->
query
->
modelClass
;
$table
=
$modelClass
::
getMetaData
()
->
table
;
$columns
=
array
();
$columns
=
array
();
$columnCount
=
0
;
$columnCount
=
0
;
$prefix
=
$this
->
relation
->
tableAlias
;
$prefix
=
$this
->
query
->
tableAlias
;
if
(
empty
(
$select
)
||
$select
===
'*'
)
{
if
(
empty
(
$select
)
||
$select
===
'*'
)
{
foreach
(
$table
Schema
->
columns
as
$column
)
{
foreach
(
$table
->
columns
as
$column
)
{
$alias
=
$this
->
relation
->
tableAlias
.
'_'
.
(
$columnCount
++
);
$alias
=
"t
{
$this
->
id
}
c"
.
(
$columnCount
++
);
$columns
[]
=
"
$prefix
.
{
$column
->
name
}
AS
$alias
"
;
$columns
[]
=
"
$prefix
.
{
$column
->
name
}
AS
$alias
"
;
$this
->
columnAliases
[
$alias
]
=
$column
->
name
;
$this
->
columnAliases
[
$alias
]
=
$column
->
name
;
if
(
$column
->
isPrimaryKey
)
{
if
(
$column
->
isPrimaryKey
)
{
...
@@ -189,8 +211,8 @@ class JoinElement extends \yii\base\Object
...
@@ -189,8 +211,8 @@ class JoinElement extends \yii\base\Object
if
(
is_string
(
$select
))
{
if
(
is_string
(
$select
))
{
$select
=
explode
(
','
,
$select
);
$select
=
explode
(
','
,
$select
);
}
}
foreach
(
$table
Schema
->
primaryKey
as
$column
)
{
foreach
(
$table
->
primaryKey
as
$column
)
{
$alias
=
$this
->
relation
->
tableAlias
.
'_'
.
(
$columnCount
++
);
$alias
=
"t
{
$this
->
id
}
c"
.
(
$columnCount
++
);
$columns
[]
=
"
$prefix
.
$column
AS
$alias
"
;
$columns
[]
=
"
$prefix
.
$column
AS
$alias
"
;
$this
->
pkAlias
[
$column
]
=
$alias
;
$this
->
pkAlias
[
$column
]
=
$alias
;
}
}
...
@@ -201,7 +223,7 @@ class JoinElement extends \yii\base\Object
...
@@ -201,7 +223,7 @@ class JoinElement extends \yii\base\Object
$this
->
columnAliases
[
$matches
[
2
]]
=
$matches
[
2
];
$this
->
columnAliases
[
$matches
[
2
]]
=
$matches
[
2
];
$columns
[]
=
$column
;
$columns
[]
=
$column
;
}
elseif
(
!
isset
(
$this
->
pkAlias
[
$column
]))
{
}
elseif
(
!
isset
(
$this
->
pkAlias
[
$column
]))
{
$alias
=
$this
->
relation
->
tableAlias
.
'_'
.
(
$columnCount
++
);
$alias
=
"t
{
$this
->
id
}
c"
.
(
$columnCount
++
);
$columns
[]
=
"
$prefix
.
$column
AS
$alias
"
;
$columns
[]
=
"
$prefix
.
$column
AS
$alias
"
;
$this
->
columnAliases
[
$alias
]
=
$column
;
$this
->
columnAliases
[
$alias
]
=
$column
;
}
}
...
...
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