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
b8d1ab88
Commit
b8d1ab88
authored
May 11, 2007
by
zYne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
--no commit message
--no commit message
parent
34fd9731
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
2587 additions
and
447 deletions
+2587
-447
Connection.php
draft/new-core/Connection.php
+1042
-0
Query.php
draft/new-core/Query.php
+46
-447
Table.php
draft/new-core/Table.php
+1499
-0
No files found.
draft/new-core/Connection.php
0 → 100644
View file @
b8d1ab88
<?php
/*
* $Id: Connection.php 1270 2007-04-18 09:47:02Z zYne $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
Doctrine
::
autoload
(
'Doctrine_Configurable'
);
/**
* Doctrine_Connection
*
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision: 1270 $
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @author Lukas Smith <smith@pooteeweet.org> (MDB2 library)
*/
abstract
class
Doctrine_Connection
extends
Doctrine_Configurable
implements
Countable
,
IteratorAggregate
{
/**
* @var $dbh the database handler
*/
protected
$dbh
;
/**
* @var array $tables an array containing all the initialized Doctrine_Table objects
* keys representing Doctrine_Table component names and values as Doctrine_Table objects
*/
protected
$tables
=
array
();
/**
* @var array $exported
*/
protected
$exported
=
array
();
/**
* @var string $driverName the name of this connection driver
*/
protected
$driverName
;
/**
* @var array $supported an array containing all features this driver supports,
* keys representing feature names and values as
* one of the following (true, false, 'emulated')
*/
protected
$supported
=
array
();
/**
* @var array $modules an array containing all modules
* transaction Doctrine_Transaction driver, handles savepoint and transaction isolation abstraction
*
* expression Doctrine_Expression driver, handles expression abstraction
*
* dataDict Doctrine_DataDict driver, handles datatype abstraction
*
* export Doctrine_Export driver, handles db structure modification abstraction (contains
* methods such as alterTable, createConstraint etc.)
* import Doctrine_Import driver, handles db schema reading
*
* sequence Doctrine_Sequence driver, handles sequential id generation and retrieval
*
* @see Doctrine_Connection::__get()
* @see Doctrine_DataDict
* @see Doctrine_Expression
* @see Doctrine_Export
* @see Doctrine_Transaction
* @see Doctrine_Sequence
*/
private
$modules
=
array
(
'transaction'
=>
false
,
'expression'
=>
false
,
'dataDict'
=>
false
,
'export'
=>
false
,
'import'
=>
false
,
'sequence'
=>
false
,
'unitOfWork'
=>
false
,
);
/**
* @var array $properties an array of connection properties
*/
protected
$properties
=
array
(
'sql_comments'
=>
array
(
array
(
'start'
=>
'--'
,
'end'
=>
"
\n
"
,
'escape'
=>
false
),
array
(
'start'
=>
'/*'
,
'end'
=>
'*/'
,
'escape'
=>
false
)
),
'identifier_quoting'
=>
array
(
'start'
=>
'"'
,
'end'
=>
'"'
,
'escape'
=>
'"'
),
'string_quoting'
=>
array
(
'start'
=>
"'"
,
'end'
=>
"'"
,
'escape'
=>
false
,
'escape_pattern'
=>
false
),
'wildcards'
=>
array
(
'%'
,
'_'
),
'varchar_max_length'
=>
255
,
);
/**
* @var array $serverInfo
*/
protected
$serverInfo
=
array
();
/**
* @var array $availableDrivers an array containing all availible drivers
*/
private
static
$availableDrivers
=
array
(
'Mysql'
,
'Pgsql'
,
'Oracle'
,
'Informix'
,
'Mssql'
,
'Sqlite'
,
'Firebird'
);
/**
* the constructor
*
* @param Doctrine_Manager $manager the manager object
* @param PDO|Doctrine_Adapter_Interface $adapter database driver
*/
public
function
__construct
(
Doctrine_Manager
$manager
,
$adapter
)
{
if
(
!
(
$adapter
instanceof
PDO
)
&&
!
in_array
(
'Doctrine_Adapter_Interface'
,
class_implements
(
$adapter
)))
{
throw
new
Doctrine_Connection_Exception
(
"First argument should be an instance of PDO or implement Doctrine_Adapter_Interface"
);
}
$this
->
dbh
=
$adapter
;
//$this->modules['transaction'] = new Doctrine_Connection_Transaction($this);
$this
->
modules
[
'unitOfWork'
]
=
new
Doctrine_Connection_UnitOfWork
(
$this
);
$this
->
setParent
(
$manager
);
$this
->
dbh
->
setAttribute
(
PDO
::
ATTR_CASE
,
PDO
::
CASE_NATURAL
);
$this
->
dbh
->
setAttribute
(
PDO
::
ATTR_ERRMODE
,
PDO
::
ERRMODE_EXCEPTION
);
$this
->
getAttribute
(
Doctrine
::
ATTR_LISTENER
)
->
onOpen
(
$this
);
}
/**
* getName
* returns the name of this driver
*
* @return string the name of this driver
*/
public
function
getName
()
{
return
$this
->
driverName
;
}
/**
* __get
* lazy loads given module and returns it
*
* @see Doctrine_DataDict
* @see Doctrine_Expression
* @see Doctrine_Export
* @see Doctrine_Transaction
* @see Doctrine_Connection::$modules all availible modules
* @param string $name the name of the module to get
* @throws Doctrine_Connection_Exception if trying to get an unknown module
* @return Doctrine_Connection_Module connection module
*/
public
function
__get
(
$name
)
{
if
(
isset
(
$this
->
properties
[
$name
]))
return
$this
->
properties
[
$name
];
if
(
!
isset
(
$this
->
modules
[
$name
]))
{
throw
new
Doctrine_Connection_Exception
(
'Unknown module / property '
.
$name
);
}
if
(
$this
->
modules
[
$name
]
===
false
)
{
switch
(
$name
)
{
case
'unitOfWork'
:
$this
->
modules
[
$name
]
=
new
Doctrine_Connection_UnitOfWork
(
$this
);
break
;
default
:
$class
=
'Doctrine_'
.
ucwords
(
$name
)
.
'_'
.
$this
->
getName
();
$this
->
modules
[
$name
]
=
new
$class
(
$this
);
}
}
return
$this
->
modules
[
$name
];
}
/**
* Quotes pattern (% and _) characters in a string)
*
* EXPERIMENTAL
*
* WARNING: this function is experimental and may change signature at
* any time until labelled as non-experimental
*
* @param string the input string to quote
*
* @return string quoted string
*/
public
function
escapePattern
(
$text
)
{
if
(
$this
->
string_quoting
[
'escape_pattern'
])
{
$text
=
str_replace
(
$this
->
string_quoting
[
'escape_pattern'
],
$this
->
string_quoting
[
'escape_pattern'
]
.
$this
->
string_quoting
[
'escape_pattern'
],
$text
);
foreach
(
$this
->
wildcards
as
$wildcard
)
{
$text
=
str_replace
(
$wildcard
,
$this
->
string_quoting
[
'escape_pattern'
]
.
$wildcard
,
$text
);
}
}
return
$text
;
}
/**
* convertBoolean
* some drivers need the boolean values to be converted into integers
* when using DQL API
*
* This method takes care of that conversion
*
* @param array $item
* @return void
*/
public
function
convertBooleans
(
$item
)
{
if
(
is_array
(
$item
))
{
foreach
(
$item
as
$k
=>
$value
)
{
if
(
is_bool
(
$item
))
{
$item
[
$k
]
=
(
int
)
$value
;
}
}
}
else
{
$item
=
(
int
)
$item
;
}
return
$item
;
}
/**
* Quote a string so it can be safely used as a table or column name
*
* Delimiting style depends on which database driver is being used.
*
* NOTE: just because you CAN use delimited identifiers doesn't mean
* you SHOULD use them. In general, they end up causing way more
* problems than they solve.
*
* Portability is broken by using the following characters inside
* delimited identifiers:
* + backtick (<kbd>`</kbd>) -- due to MySQL
* + double quote (<kbd>"</kbd>) -- due to Oracle
* + brackets (<kbd>[</kbd> or <kbd>]</kbd>) -- due to Access
*
* Delimited identifiers are known to generally work correctly under
* the following drivers:
* + mssql
* + mysql
* + mysqli
* + oci8
* + pgsql
* + sqlite
*
* InterBase doesn't seem to be able to use delimited identifiers
* via PHP 4. They work fine under PHP 5.
*
* @param string $str identifier name to be quoted
* @param bool $checkOption check the 'quote_identifier' option
*
* @return string quoted identifier string
*/
public
function
quoteIdentifier
(
$str
,
$checkOption
=
true
)
{
if
(
$checkOption
&&
!
$this
->
getAttribute
(
Doctrine
::
ATTR_QUOTE_IDENTIFIER
))
{
return
$str
;
}
$str
=
str_replace
(
$this
->
properties
[
'identifier_quoting'
][
'end'
],
$this
->
properties
[
'identifier_quoting'
][
'escape'
]
.
$this
->
properties
[
'identifier_quoting'
][
'end'
],
$str
);
return
$this
->
properties
[
'identifier_quoting'
][
'start'
]
.
$str
.
$this
->
properties
[
'identifier_quoting'
][
'end'
];
}
/**
* returns the manager that created this connection
*
* @return Doctrine_Manager
*/
public
function
getManager
()
{
return
$this
->
getParent
();
}
/**
* returns the database handler of which this connection uses
*
* @return PDO the database handler
*/
public
function
getDbh
()
{
return
$this
->
dbh
;
}
/**
* converts given driver name
*
* @param
*/
public
function
driverName
(
$name
)
{
}
/**
* supports
*
* @param string $feature the name of the feature
* @return boolean whether or not this drivers supports given feature
*/
public
function
supports
(
$feature
)
{
return
(
isset
(
$this
->
supported
[
$feature
])
&&
(
$this
->
supported
[
$feature
]
===
'emulated'
||
$this
->
supported
[
$feature
]
)
);
}
/**
* quote
* quotes given input parameter
*
* @param mixed $input parameter to be quoted
* @param string $type
* @return mixed
*/
public
function
quote
(
$input
,
$type
=
null
)
{
if
(
$type
==
null
)
{
$type
=
gettype
(
$input
);
}
switch
(
$type
)
{
case
'integer'
:
case
'enum'
:
case
'boolean'
:
case
'double'
:
case
'float'
:
case
'bool'
:
case
'int'
:
return
$input
;
case
'array'
:
case
'object'
:
$input
=
serialize
(
$input
);
case
'string'
:
case
'char'
:
case
'varchar'
:
case
'text'
:
case
'gzip'
:
case
'blob'
:
case
'clob'
:
return
$this
->
dbh
->
quote
(
$input
);
}
}
/**
* Removes any formatting in an sequence name using the 'seqname_format' option
*
* @param string $sqn string that containts name of a potential sequence
* @return string name of the sequence with possible formatting removed
*/
public
function
fixSequenceName
(
$sqn
)
{
$seqPattern
=
'/^'
.
preg_replace
(
'/%s/'
,
'([a-z0-9_]+)'
,
$this
->
getAttribute
(
Doctrine
::
ATTR_SEQNAME_FORMAT
))
.
'$/i'
;
$seqName
=
preg_replace
(
$seqPattern
,
'\\1'
,
$sqn
);
if
(
$seqName
&&
!
strcasecmp
(
$sqn
,
$this
->
getSequenceName
(
$seqName
)))
{
return
$seqName
;
}
return
$sqn
;
}
/**
* Removes any formatting in an index name using the 'idxname_format' option
*
* @param string $idx string that containts name of anl index
* @return string name of the index with possible formatting removed
*/
public
function
fixIndexName
(
$idx
)
{
$indexPattern
=
'/^'
.
preg_replace
(
'/%s/'
,
'([a-z0-9_]+)'
,
$this
->
getAttribute
(
Doctrine
::
ATTR_IDXNAME_FORMAT
))
.
'$/i'
;
$indexName
=
preg_replace
(
$indexPattern
,
'\\1'
,
$idx
);
if
(
$indexName
&&
!
strcasecmp
(
$idx
,
$this
->
getIndexName
(
$indexName
)))
{
return
$indexName
;
}
return
$idx
;
}
/**
* adds sequence name formatting to a sequence name
*
* @param string name of the sequence
* @return string formatted sequence name
*/
public
function
getSequenceName
(
$sqn
)
{
return
sprintf
(
$this
->
getAttribute
(
Doctrine
::
ATTR_SEQNAME_FORMAT
),
preg_replace
(
'/[^a-z0-9_\$.]/i'
,
'_'
,
$sqn
));
}
/**
* adds index name formatting to a index name
*
* @param string name of the index
* @return string formatted index name
*/
public
function
getIndexName
(
$idx
)
{
return
sprintf
(
$this
->
getAttribute
(
Doctrine
::
ATTR_IDXNAME_FORMAT
),
preg_replace
(
'/[^a-z0-9_\$]/i'
,
'_'
,
$idx
));
}
/**
* Execute a SQL REPLACE query. A REPLACE query is identical to a INSERT
* query, except that if there is already a row in the table with the same
* key field values, the REPLACE query just updates its values instead of
* inserting a new row.
*
* The REPLACE type of query does not make part of the SQL standards. Since
* practically only MySQL and SQLIte implement it natively, this type of
* query isemulated through this method for other DBMS using standard types
* of queries inside a transaction to assure the atomicity of the operation.
*
* @param string name of the table on which the REPLACE query will
* be executed.
*
* @param array an associative array that describes the fields and the
* values that will be inserted or updated in the specified table. The
* indexes of the array are the names of all the fields of the table.
*
* The values of the array are values to be assigned to the specified field.
*
* @param array $keys an array containing all key fields (primary key fields
* or unique index fields) for this table
*
* the uniqueness of a row will be determined according to
* the provided key fields
*
* this method will fail if no key fields are specified
*
* @throws Doctrine_Connection_Exception if this driver doesn't support replace
* @throws Doctrine_Connection_Exception if some of the key values was null
* @throws Doctrine_Connection_Exception if there were no key fields
* @throws PDOException if something fails at PDO level
* @return integer number of rows affected
*/
public
function
replace
(
$table
,
array
$fields
,
array
$keys
)
{
//if ( ! $this->supports('replace'))
// throw new Doctrine_Connection_Exception('replace query is not supported');
if
(
empty
(
$keys
))
{
throw
new
Doctrine_Connection_Exception
(
'Not specified which fields are keys'
);
}
$condition
=
$values
=
array
();
foreach
(
$fields
as
$name
=>
$value
)
{
$values
[
$name
]
=
$value
;
if
(
in_array
(
$name
,
$keys
))
{
if
(
$value
===
null
)
throw
new
Doctrine_Connection_Exception
(
'key value '
.
$name
.
' may not be null'
);
$condition
[]
=
$name
.
' = ?'
;
$conditionValues
[]
=
$value
;
}
}
$query
=
'DELETE FROM '
.
$this
->
quoteIdentifier
(
$table
)
.
' WHERE '
.
implode
(
' AND '
,
$condition
);
$affectedRows
=
$this
->
exec
(
$query
);
$this
->
insert
(
$table
,
$values
);
$affectedRows
++
;
return
$affectedRows
;
}
/**
* Inserts a table row with specified data.
*
* @param string $table The table to insert data into.
* @param array $values An associateve array containing column-value pairs.
* @return boolean
*/
public
function
insert
(
$table
,
array
$values
=
array
())
{
if
(
empty
(
$values
))
{
return
false
;
}
// column names are specified as array keys
$cols
=
array_keys
(
$values
);
// build the statement
$query
=
'INSERT INTO '
.
$this
->
quoteIdentifier
(
$table
)
.
'('
.
implode
(
', '
,
$cols
)
.
') '
.
'VALUES ('
.
substr
(
str_repeat
(
'?, '
,
count
(
$values
)),
0
,
-
2
)
.
')'
;
// prepare and execute the statement
$this
->
execute
(
$query
,
array_values
(
$values
));
return
true
;
}
/**
* Set the charset on the current connection
*
* @param string charset
*
* @return void
*/
public
function
setCharset
(
$charset
)
{
}
/**
* Set the date/time format for the current connection
*
* @param string time format
*
* @return void
*/
public
function
setDateFormat
(
$format
=
null
)
{
}
/**
* fetchAll
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public
function
fetchAll
(
$statement
,
array
$params
=
array
())
{
return
$this
->
execute
(
$statement
,
$params
)
->
fetchAll
(
PDO
::
FETCH_ASSOC
);
}
/**
* fetchOne
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @param int $colnum 0-indexed column number to retrieve
* @return mixed
*/
public
function
fetchOne
(
$statement
,
array
$params
=
array
(),
$colnum
=
0
)
{
return
$this
->
execute
(
$statement
,
$params
)
->
fetchColumn
(
$colnum
);
}
/**
* fetchRow
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public
function
fetchRow
(
$statement
,
array
$params
=
array
())
{
return
$this
->
execute
(
$statement
,
$params
)
->
fetch
(
PDO
::
FETCH_ASSOC
);
}
/**
* fetchArray
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public
function
fetchArray
(
$statement
,
array
$params
=
array
())
{
return
$this
->
execute
(
$statement
,
$params
)
->
fetch
(
PDO
::
FETCH_NUM
);
}
/**
* fetchColumn
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @param int $colnum 0-indexed column number to retrieve
* @return array
*/
public
function
fetchColumn
(
$statement
,
array
$params
=
array
(),
$colnum
=
0
)
{
return
$this
->
execute
(
$statement
,
$params
)
->
fetchAll
(
PDO
::
FETCH_COLUMN
,
$colnum
);
}
/**
* fetchAssoc
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public
function
fetchAssoc
(
$statement
,
array
$params
=
array
())
{
return
$this
->
execute
(
$statement
,
$params
)
->
fetchAll
(
PDO
::
FETCH_ASSOC
);
}
/**
* fetchBoth
*
* @param string $statement sql query to be executed
* @param array $params prepared statement params
* @return array
*/
public
function
fetchBoth
(
$statement
,
array
$params
=
array
())
{
return
$this
->
execute
(
$statement
,
$params
)
->
fetchAll
(
PDO
::
FETCH_BOTH
);
}
/**
* query
* queries the database using Doctrine Query Language
* returns a collection of Doctrine_Record objects
*
* <code>
* $users = $conn->query('SELECT u.* FROM User u');
*
* $users = $conn->query('SELECT u.* FROM User u WHERE u.name LIKE ?', array('someone'));
* </code>
*
* @param string $query DQL query
* @param array $params query parameters
* @see Doctrine_Query
* @return Doctrine_Collection Collection of Doctrine_Record objects
*/
public
function
query
(
$query
,
array
$params
=
array
())
{
$parser
=
new
Doctrine_Query
(
$this
);
return
$parser
->
query
(
$query
,
$params
);
}
/**
* query
* queries the database using Doctrine Query Language and returns
* the first record found
*
* <code>
* $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.id = ?', array(1));
*
* $user = $conn->queryOne('SELECT u.* FROM User u WHERE u.name LIKE ? AND u.password = ?',
* array('someone', 'password')
* );
* </code>
*
* @param string $query DQL query
* @param array $params query parameters
* @see Doctrine_Query
* @return Doctrine_Record|false Doctrine_Record object on success,
* boolean false on failure
*/
public
function
queryOne
(
$query
,
array
$params
=
array
())
{
$parser
=
new
Doctrine_Query
(
$this
);
$coll
=
$parser
->
query
(
$query
,
$params
);
if
(
!
$coll
->
contains
(
0
))
{
return
false
;
}
return
$coll
[
0
];
}
/**
* queries the database with limit and offset
* added to the query and returns a PDOStatement object
*
* @param string $query
* @param integer $limit
* @param integer $offset
* @return PDOStatement
*/
public
function
select
(
$query
,
$limit
=
0
,
$offset
=
0
)
{
if
(
$limit
>
0
||
$offset
>
0
)
{
$query
=
$this
->
modifyLimitQuery
(
$query
,
$limit
,
$offset
);
}
return
$this
->
dbh
->
query
(
$query
);
}
/**
* standaloneQuery
*
* @param string $query sql query
* @param array $params query parameters
*
* @return PDOStatement|Doctrine_Adapter_Statement
*/
public
function
standaloneQuery
(
$query
,
$params
=
array
())
{
return
$this
->
execute
(
$query
,
$params
);
}
/**
* execute
* @param string $query sql query
* @param array $params query parameters
*
* @return PDOStatement|Doctrine_Adapter_Statement
*/
public
function
execute
(
$query
,
array
$params
=
array
())
{
try
{
if
(
!
empty
(
$params
))
{
$stmt
=
$this
->
dbh
->
prepare
(
$query
);
$stmt
->
execute
(
$params
);
return
$stmt
;
}
else
{
return
$this
->
dbh
->
query
(
$query
);
}
}
catch
(
Doctrine_Adapter_Exception
$e
)
{
}
catch
(
PDOException
$e
)
{
}
$this
->
rethrowException
(
$e
);
}
/**
* exec
* @param string $query sql query
* @param array $params query parameters
*
* @return PDOStatement|Doctrine_Adapter_Statement
*/
public
function
exec
(
$query
,
array
$params
=
array
())
{
try
{
if
(
!
empty
(
$params
))
{
$stmt
=
$this
->
dbh
->
prepare
(
$query
);
$stmt
->
execute
(
$params
);
return
$stmt
->
rowCount
();
}
else
{
return
$this
->
dbh
->
exec
(
$query
);
}
}
catch
(
Doctrine_Adapter_Exception
$e
)
{
}
catch
(
PDOException
$e
)
{
}
$this
->
rethrowException
(
$e
);
}
/**
* rethrowException
*
* @throws Doctrine_Connection_Exception
*/
private
function
rethrowException
(
Exception
$e
)
{
$name
=
'Doctrine_Connection_'
.
$this
->
driverName
.
'_Exception'
;
$exc
=
new
$name
(
$e
->
getMessage
(),
(
int
)
$e
->
getCode
());
if
(
!
is_array
(
$e
->
errorInfo
))
{
$e
->
errorInfo
=
array
(
null
,
null
,
null
,
null
);
}
$exc
->
processErrorInfo
(
$e
->
errorInfo
);
throw
$exc
;
}
/**
* hasTable
* whether or not this connection has table $name initialized
*
* @param mixed $name
* @return boolean
*/
public
function
hasTable
(
$name
)
{
return
isset
(
$this
->
tables
[
$name
]);
}
/**
* returns a table object for given component name
*
* @param string $name component name
* @return object Doctrine_Table
*/
public
function
getTable
(
$name
,
$allowExport
=
true
)
{
if
(
isset
(
$this
->
tables
[
$name
]))
{
return
$this
->
tables
[
$name
];
}
$class
=
$name
.
'Table'
;
if
(
class_exists
(
$class
)
&&
in_array
(
'Doctrine_Table'
,
class_parents
(
$class
)))
{
$table
=
new
$class
(
$name
,
$this
);
}
else
{
$table
=
new
Doctrine_Table
(
$name
,
$this
);
}
$this
->
tables
[
$name
]
=
$table
;
if
(
$allowExport
)
{
// the following is an algorithm for loading all
// the related tables for all loaded tables
$next
=
count
(
$this
->
tables
);
$prev
=
count
(
$this
->
exported
);
$stack
=
$this
->
exported
;
while
(
$prev
<
$next
)
{
$prev
=
count
(
$this
->
tables
);
foreach
(
$this
->
tables
as
$name
=>
$tableObject
)
{
if
(
isset
(
$stack
[
$name
]))
{
continue
;
}
else
{
$stack
[
$name
]
=
true
;
}
$tableObject
->
getRelations
();
//$this->getTable('RelationTestChild')->getRelation('Children');
}
$next
=
count
(
$this
->
tables
);
}
// when all the tables are loaded we build the array in which the order of the tables is
// relationally correct so that then those can be created in the given order)
$names
=
array_keys
(
$this
->
tables
);
$names
=
$this
->
unitOfWork
->
buildFlushTree
(
$names
);
foreach
(
$names
as
$name
)
{
$tableObject
=
$this
->
tables
[
$name
];
if
(
isset
(
$this
->
exported
[
$name
]))
{
continue
;
}
if
(
$tableObject
->
getAttribute
(
Doctrine
::
ATTR_EXPORT
)
&
Doctrine
::
EXPORT_TABLES
)
{
$tableObject
->
export
();
}
$this
->
exported
[
$name
]
=
true
;
}
}
return
$table
;
}
/**
* returns an array of all initialized tables
*
* @return array
*/
public
function
getTables
()
{
return
$this
->
tables
;
}
/**
* returns an iterator that iterators through all
* initialized table objects
*
* <code>
* foreach ($conn as $index => $table) {
* print $table; // get a string representation of each table object
* }
* </code>
*
* @return ArrayIterator SPL ArrayIterator object
*/
public
function
getIterator
()
{
return
new
ArrayIterator
(
$this
->
tables
);
}
/**
* returns the count of initialized table objects
*
* @return integer
*/
public
function
count
()
{
return
count
(
$this
->
tables
);
}
/**
* addTable
* adds a Doctrine_Table object into connection registry
*
* @param $objTable a Doctrine_Table object to be added into registry
* @return boolean
*/
public
function
addTable
(
Doctrine_Table
$objTable
)
{
$name
=
$objTable
->
getComponentName
();
if
(
isset
(
$this
->
tables
[
$name
]))
{
return
false
;
}
$this
->
tables
[
$name
]
=
$objTable
;
return
true
;
}
/**
* create
* creates a record
*
* create creates a record
* @param string $name component name
* @return Doctrine_Record Doctrine_Record object
*/
public
function
create
(
$name
)
{
return
$this
->
getTable
(
$name
)
->
create
();
}
/**
* flush
* saves all the records from all tables
* this operation is isolated using a transaction
*
* @throws PDOException if something went wrong at database level
* @return void
*/
public
function
flush
()
{
$this
->
beginTransaction
();
$this
->
unitOfWork
->
saveAll
();
$this
->
commit
();
}
/**
* clear
* clears all repositories
*
* @return void
*/
public
function
clear
()
{
foreach
(
$this
->
tables
as
$k
=>
$table
)
{
$table
->
getRepository
()
->
evictAll
();
$table
->
clear
();
}
}
/**
* evictTables
* evicts all tables
*
* @return void
*/
public
function
evictTables
()
{
$this
->
tables
=
array
();
$this
->
exported
=
array
();
}
/**
* close
* closes the connection
*
* @return void
*/
public
function
close
()
{
$this
->
getAttribute
(
Doctrine
::
ATTR_LISTENER
)
->
onPreClose
(
$this
);
$this
->
clear
();
$this
->
getAttribute
(
Doctrine
::
ATTR_LISTENER
)
->
onClose
(
$this
);
}
/**
* get the current transaction nesting level
*
* @return integer
*/
public
function
getTransactionLevel
()
{
return
$this
->
transaction
->
getTransactionLevel
();
}
/**
* beginTransaction
* starts a new transaction
*
* this method can be listened by onPreBeginTransaction and onBeginTransaction
* listener methods
*
* @return void
*/
public
function
beginTransaction
()
{
$this
->
transaction
->
beginTransaction
();
}
/**
* commits the current transaction
* if lockmode is optimistic this method starts a transaction
* and commits it instantly
*
* @return void
*/
public
function
commit
()
{
$this
->
transaction
->
commit
();
}
/**
* rollback
* rolls back all transactions
*
* this method also listens to onPreTransactionRollback and onTransactionRollback
* eventlisteners
*
* @return void
*/
public
function
rollback
()
{
$this
->
transaction
->
rollback
();
}
/**
* saves the given record
*
* @param Doctrine_Record $record
* @return void
*/
public
function
save
(
Doctrine_Record
$record
)
{
$record
->
getTable
()
->
getAttribute
(
Doctrine
::
ATTR_LISTENER
)
->
onPreSave
(
$record
);
switch
(
$record
->
state
())
{
case
Doctrine_Record
::
STATE_TDIRTY
:
$this
->
unitOfWork
->
insert
(
$record
);
break
;
case
Doctrine_Record
::
STATE_DIRTY
:
case
Doctrine_Record
::
STATE_PROXY
:
$this
->
unitOfWork
->
update
(
$record
);
break
;
case
Doctrine_Record
::
STATE_CLEAN
:
case
Doctrine_Record
::
STATE_TCLEAN
:
// do nothing
break
;
};
$record
->
getTable
()
->
getAttribute
(
Doctrine
::
ATTR_LISTENER
)
->
onSave
(
$record
);
}
/**
* deletes this data access object and all the related composites
* this operation is isolated by a transaction
*
* this event can be listened by the onPreDelete and onDelete listeners
*
* @return boolean true on success, false on failure
*/
public
function
delete
(
Doctrine_Record
$record
)
{
if
(
!
$record
->
exists
())
{
return
false
;
}
$this
->
beginTransaction
();
$record
->
getTable
()
->
getListener
()
->
onPreDelete
(
$record
);
$this
->
unitOfWork
->
deleteComposites
(
$record
);
$this
->
transaction
->
addDelete
(
$record
);
$record
->
getTable
()
->
getListener
()
->
onDelete
(
$record
);
$this
->
commit
();
return
true
;
}
/**
* returns a string representation of this object
* @return string
*/
public
function
__toString
()
{
return
Doctrine_Lib
::
getConnectionAsString
(
$this
);
}
}
draft/new-core/Query.php
View file @
b8d1ab88
...
@@ -49,14 +49,10 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -49,14 +49,10 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
*/
*/
private
$isSubquery
;
private
$isSubquery
;
private
$tableStack
;
private
$relationStack
=
array
();
private
$relationStack
=
array
();
private
$isDistinct
=
false
;
private
$isDistinct
=
false
;
protected
$components
=
array
();
private
$neededTables
=
array
();
private
$neededTables
=
array
();
/**
/**
* @var array $pendingFields
* @var array $pendingFields
...
@@ -123,16 +119,6 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -123,16 +119,6 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
return
null
;
return
null
;
}
}
public
function
getTableStack
()
{
return
$this
->
tableStack
;
}
public
function
getRelationStack
()
{
return
$this
->
relationStack
;
}
public
function
isDistinct
(
$distinct
=
null
)
public
function
isDistinct
(
$distinct
=
null
)
{
{
if
(
isset
(
$distinct
))
if
(
isset
(
$distinct
))
...
@@ -146,7 +132,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -146,7 +132,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
$tableAlias
=
$this
->
getTableAlias
(
$componentAlias
);
$tableAlias
=
$this
->
getTableAlias
(
$componentAlias
);
if
(
!
isset
(
$this
->
tables
[
$tableAlias
]))
if
(
!
isset
(
$this
->
tables
[
$tableAlias
]))
throw
new
Doctrine_Query_Exception
(
'Unknown component path '
.
$componentAlias
);
throw
new
Doctrine_Query_Exception
(
'Unknown component path '
.
$componentAlias
);
$table
=
$this
->
tables
[
$tableAlias
];
$table
=
$this
->
tables
[
$tableAlias
];
...
@@ -415,60 +401,6 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -415,60 +401,6 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
$this
->
parts
=
$parts_old
;
$this
->
parts
=
$parts_old
;
return
(
int
)
$this
->
getConnection
()
->
fetchOne
(
$q
,
$params
);
return
(
int
)
$this
->
getConnection
()
->
fetchOne
(
$q
,
$params
);
}
}
/**
* loadFields
* loads fields for a given table and
* constructs a little bit of sql for every field
*
* fields of the tables become: [tablename].[fieldname] as [tablename]__[fieldname]
*
* @access private
* @param object Doctrine_Table $table a Doctrine_Table object
* @param integer $fetchmode fetchmode the table is using eg. Doctrine::FETCH_LAZY
* @param array $names fields to be loaded (only used in lazy property loading)
* @return void
*/
protected
function
loadFields
(
Doctrine_Table
$table
,
$fetchmode
,
array
$names
,
$cpath
)
{
$name
=
$table
->
getComponentName
();
switch
(
$fetchmode
)
:
case
Doctrine
::
FETCH_OFFSET
:
$this
->
limit
=
$table
->
getAttribute
(
Doctrine
::
ATTR_COLL_LIMIT
);
case
Doctrine
::
FETCH_IMMEDIATE
:
if
(
!
empty
(
$names
))
{
// only auto-add the primary key fields if this query object is not
// a subquery of another query object
$names
=
array_unique
(
array_merge
(
$table
->
getPrimaryKeys
(),
$names
));
}
else
{
$names
=
$table
->
getColumnNames
();
}
break
;
case
Doctrine
::
FETCH_LAZY_OFFSET
:
$this
->
limit
=
$table
->
getAttribute
(
Doctrine
::
ATTR_COLL_LIMIT
);
case
Doctrine
::
FETCH_LAZY
:
case
Doctrine
::
FETCH_BATCH
:
$names
=
array_unique
(
array_merge
(
$table
->
getPrimaryKeys
(),
$names
));
break
;
default
:
throw
new
Doctrine_Exception
(
"Unknown fetchmode."
);
endswitch
;
$component
=
$table
->
getComponentName
();
$tablename
=
$this
->
tableAliases
[
$cpath
];
$this
->
fetchModes
[
$tablename
]
=
$fetchmode
;
$count
=
count
(
$this
->
tables
);
foreach
(
$names
as
$name
)
{
if
(
$count
==
0
)
{
$this
->
parts
[
'select'
][]
=
$tablename
.
'.'
.
$name
;
}
else
{
$this
->
parts
[
'select'
][]
=
$tablename
.
'.'
.
$name
.
' AS '
.
$tablename
.
'__'
.
$name
;
}
}
}
/**
/**
* addFrom
* addFrom
*
*
...
@@ -656,35 +588,6 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -656,35 +588,6 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
}
}
return
$this
;
}
/**
* returns a query part
*
* @param $name query part name
* @return mixed
*/
public
function
get
(
$name
)
{
if
(
!
isset
(
$this
->
parts
[
$name
]))
return
false
;
return
$this
->
parts
[
$name
];
}
/**
* set
* sets a query SET part
* this method should only be used with UPDATE queries
*
* @param $name name of the field
* @param $value field value
* @return Doctrine_Query
*/
public
function
set
(
$name
,
$value
)
{
$class
=
new
Doctrine_Query_Set
(
$this
);
$this
->
parts
[
'set'
][]
=
$class
->
parse
(
$name
.
' = '
.
$value
);
return
$this
;
return
$this
;
}
}
/**
/**
...
@@ -704,15 +607,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -704,15 +607,7 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
{
{
switch
(
$this
->
type
)
{
switch
(
$this
->
type
)
{
case
self
::
DELETE
:
case
self
::
DELETE
:
/**
no longer needed?
if ($this->conn->getName() == 'Mysql') {
$q = 'DELETE ' . end($this->tableAliases) . ' FROM ';
} else {
*/
$q
=
'DELETE FROM '
;
$q
=
'DELETE FROM '
;
// }
break
;
break
;
case
self
::
UPDATE
:
case
self
::
UPDATE
:
$q
=
'UPDATE '
;
$q
=
'UPDATE '
;
...
@@ -1058,49 +953,49 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -1058,49 +953,49 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
foreach
(
$parts
as
$k
=>
$part
)
{
foreach
(
$parts
as
$k
=>
$part
)
{
$part
=
implode
(
' '
,
$part
);
$part
=
implode
(
' '
,
$part
);
switch
(
strto
upp
er
(
$k
))
{
switch
(
strto
low
er
(
$k
))
{
case
'
CREATE
'
:
case
'
create
'
:
$this
->
type
=
self
::
CREATE
;
$this
->
type
=
self
::
CREATE
;
break
;
break
;
case
'
INSERT
'
:
case
'
insert
'
:
$this
->
type
=
self
::
INSERT
;
$this
->
type
=
self
::
INSERT
;
break
;
break
;
case
'
DELETE
'
:
case
'
delete
'
:
$this
->
type
=
self
::
DELETE
;
$this
->
type
=
self
::
DELETE
;
break
;
break
;
case
'
SELECT
'
:
case
'
select
'
:
$this
->
type
=
self
::
SELECT
;
$this
->
type
=
self
::
SELECT
;
$this
->
parseSelect
(
$part
);
$this
->
parseSelect
(
$part
);
break
;
break
;
case
'
UPDATE
'
:
case
'
update
'
:
$this
->
type
=
self
::
UPDATE
;
$this
->
type
=
self
::
UPDATE
;
$k
=
'FROM'
;
$k
=
'FROM'
;
case
'
FROM
'
:
case
'
from
'
:
$class
=
'Doctrine_Query_'
.
ucwords
(
strtolower
(
$k
));
$class
=
'Doctrine_Query_'
.
ucwords
(
strtolower
(
$k
));
$parser
=
new
$class
(
$this
);
$parser
=
new
$class
(
$this
);
$parser
->
parse
(
$part
);
$parser
->
parse
(
$part
);
break
;
break
;
case
'
SET
'
:
case
'
set
'
:
$class
=
'Doctrine_Query_'
.
ucwords
(
strtolower
(
$k
));
$class
=
'Doctrine_Query_'
.
ucwords
(
strtolower
(
$k
));
$parser
=
new
$class
(
$this
);
$parser
=
new
$class
(
$this
);
$this
->
parts
[
'set'
][]
=
$parser
->
parse
(
$part
);
$this
->
parts
[
'set'
][]
=
$parser
->
parse
(
$part
);
break
;
break
;
case
'
GROUP
'
:
case
'
group
'
:
case
'
ORDER
'
:
case
'
order
'
:
$k
.=
'by'
;
$k
.=
'by'
;
case
'
WHERE
'
:
case
'
where
'
:
case
'
HAVING
'
:
case
'
having
'
:
$class
=
'Doctrine_Query_'
.
ucwords
(
strtolower
(
$k
));
$class
=
'Doctrine_Query_'
.
ucwords
(
strtolower
(
$k
));
$parser
=
new
$class
(
$this
);
$parser
=
new
$class
(
$this
);
$name
=
strtolower
(
$k
);
$name
=
strtolower
(
$k
);
$this
->
parts
[
$name
][]
=
$parser
->
parse
(
$part
);
$this
->
parts
[
$name
][]
=
$parser
->
parse
(
$part
);
break
;
break
;
case
'
LIMIT
'
:
case
'
limit
'
:
$this
->
parts
[
'limit'
]
=
trim
(
$part
);
$this
->
parts
[
'limit'
]
=
trim
(
$part
);
break
;
break
;
case
'
OFFSET
'
:
case
'
offset
'
:
$this
->
parts
[
'offset'
]
=
trim
(
$part
);
$this
->
parts
[
'offset'
]
=
trim
(
$part
);
break
;
break
;
}
}
...
@@ -1121,235 +1016,48 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -1121,235 +1016,48 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
return
$parser
->
parse
(
$str
);
return
$parser
->
parse
(
$str
);
}
}
/**
/**
* returns Doctrine::FETCH_* constant
* generateAlias
*
* @param string $mode
* @return integer
*/
final
public
function
parseFetchMode
(
$mode
)
{
switch
(
strtolower
(
$mode
))
:
case
"i"
:
case
"immediate"
:
$fetchmode
=
Doctrine
::
FETCH_IMMEDIATE
;
break
;
case
"b"
:
case
"batch"
:
$fetchmode
=
Doctrine
::
FETCH_BATCH
;
break
;
case
"l"
:
case
"lazy"
:
$fetchmode
=
Doctrine
::
FETCH_LAZY
;
break
;
case
"o"
:
case
"offset"
:
$fetchmode
=
Doctrine
::
FETCH_OFFSET
;
break
;
case
"lo"
:
case
"lazyoffset"
:
$fetchmode
=
Doctrine
::
FETCH_LAZYOFFSET
;
default
:
throw
new
Doctrine_Query_Exception
(
"Unknown fetchmode '
$mode
'. The availible fetchmodes are 'i', 'b' and 'l'."
);
endswitch
;
return
$fetchmode
;
}
/**
* trims brackets
*
* @param string $str
* @param string $e1 the first bracket, usually '('
* @param string $e2 the second bracket, usually ')'
*/
public
static
function
bracketTrim
(
$str
,
$e1
=
'('
,
$e2
=
')'
)
{
if
(
substr
(
$str
,
0
,
1
)
==
$e1
&&
substr
(
$str
,
-
1
)
==
$e2
)
return
substr
(
$str
,
1
,
-
1
);
else
return
$str
;
}
/**
* bracketExplode
*
* 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'")
*
* @param string $str
* @param string $d the delimeter which explodes the string
* @param string $e1 the first bracket, usually '('
* @param string $e2 the second bracket, usually ')'
*
*
* @param string $tableName
* @return string
*/
*/
public
static
function
bracketExplode
(
$str
,
$d
=
' '
,
$e1
=
'('
,
$e2
=
')'
)
public
function
generateAlias
(
$tableName
)
{
{
if
(
is_array
(
$d
))
{
if
(
isset
(
$this
->
tableIndexes
[
$tableName
]))
{
$a
=
preg_split
(
'/('
.
implode
(
'|'
,
$d
)
.
')/'
,
$str
);
return
$tableName
.++
$this
->
tableIndexes
[
$tableName
];
$d
=
stripslashes
(
$d
[
0
]);
}
else
$a
=
explode
(
"
$d
"
,
$str
);
$i
=
0
;
$term
=
array
();
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
"
);
if
(
$s1
==
$s2
)
$i
++
;
}
else
{
}
else
{
$term
[
$i
]
.=
"
$d
"
.
trim
(
$val
);
$this
->
tableIndexes
[
$tableName
]
=
1
;
$c1
=
substr_count
(
$term
[
$i
],
"
$e1
"
);
return
$tableName
;
$c2
=
substr_count
(
$term
[
$i
],
"
$e2
"
);
if
(
$c1
==
$c2
)
$i
++
;
}
}
}
return
$term
;
}
}
/**
public
function
load
(
$path
,
$loadFields
=
true
)
* quoteExplode
*
* example:
*
* parameters:
* $str = email LIKE 'John@example.com'
* $d = ' AND '
*
* would return an array:
* array("email", "LIKE", "'John@example.com'")
*
* @param string $str
* @param string $d the delimeter which explodes the string
*/
public
static
function
quoteExplode
(
$str
,
$d
=
' '
)
{
{
if
(
is_array
(
$d
))
{
// parse custom join conditions
$a
=
preg_split
(
'/('
.
implode
(
'|'
,
$d
)
.
')/'
,
$str
);
$e
=
explode
(
' ON '
,
$path
);
$d
=
stripslashes
(
$d
[
0
]);
}
else
$a
=
explode
(
"
$d
"
,
$str
);
$i
=
0
;
$term
=
array
();
foreach
(
$a
as
$key
=>
$val
)
{
if
(
empty
(
$term
[
$i
]))
{
$term
[
$i
]
=
trim
(
$val
);
if
(
!
(
substr_count
(
$term
[
$i
],
"'"
)
&
1
))
$joinCondition
=
''
;
$i
++
;
}
else
{
$term
[
$i
]
.=
"
$d
"
.
trim
(
$val
);
if
(
!
(
substr_count
(
$term
[
$i
],
"'"
)
&
1
))
if
(
count
(
$e
)
>
1
)
{
$i
++
;
$joinCondition
=
' AND '
.
$e
[
1
];
}
$path
=
$e
[
0
];
}
return
$term
;
}
/**
* sqlExplode
*
* 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 '('
* @param string $e2 the second bracket, usually ')'
*
* @return array
*/
public
static
function
sqlExplode
(
$str
,
$d
=
' '
,
$e1
=
'('
,
$e2
=
')'
)
{
if
(
$d
==
' '
)
{
$d
=
array
(
' '
,
'\s'
);
}
if
(
is_array
(
$d
))
{
if
(
in_array
(
' '
,
$d
))
{
$d
[]
=
'\s'
;
}
$str
=
preg_split
(
'/('
.
implode
(
'|'
,
$d
)
.
')/'
,
$str
);
$d
=
stripslashes
(
$d
[
0
]);
}
else
{
$str
=
explode
(
"
$d
"
,
$str
);
}
}
$i
=
0
;
$tmp
=
explode
(
' '
,
$path
);
$term
=
array
();
$componentAlias
=
(
count
(
$tmp
)
>
1
)
?
end
(
$tmp
)
:
false
;
foreach
(
$str
as
$key
=>
$val
)
{
if
(
empty
(
$term
[
$i
]))
{
$term
[
$i
]
=
trim
(
$val
);
$s1
=
substr_count
(
$term
[
$i
],
"
$e1
"
);
$s2
=
substr_count
(
$term
[
$i
],
"
$e2
"
);
if
(
substr
(
$term
[
$i
],
0
,
1
)
==
"("
)
{
$e
=
preg_split
(
"/[.:]/"
,
$tmp
[
0
],
-
1
);
if
(
$s1
==
$s2
)
{
$i
++
;
foreach
(
$e
as
$key
=>
$part
)
{
}
}
else
{
if
(
$key
===
0
)
{
if
(
!
(
substr_count
(
$term
[
$i
],
"'"
)
&
1
)
&&
// process the root of the path
!
(
substr_count
(
$term
[
$i
],
"
\"
"
)
&
1
)
&&
!
(
substr_count
(
$term
[
$i
],
"�"
)
&
1
)
)
{
$i
++
;
}
}
}
else
{
$term
[
$i
]
.=
"
$d
"
.
trim
(
$val
);
$c1
=
substr_count
(
$term
[
$i
],
"
$e1
"
);
$c2
=
substr_count
(
$term
[
$i
],
"
$e2
"
);
if
(
substr
(
$term
[
$i
],
0
,
1
)
==
"("
)
{
if
(
$c1
==
$c2
)
{
$i
++
;
}
}
else
{
}
else
{
if
(
!
(
substr_count
(
$term
[
$i
],
"'"
)
&
1
)
&&
!
(
substr_count
(
$term
[
$i
],
"
\"
"
)
&
1
)
&&
!
(
substr_count
(
$term
[
$i
],
"�"
)
&
1
)
)
{
$i
++
;
}
}
}
}
}
}
return
$term
;
}
}
/**
* generateAlias
*
* @param string $tableName
* @return string
*/
public
function
generateAlias
(
$tableName
)
{
if
(
isset
(
$this
->
tableIndexes
[
$tableName
]))
{
return
$tableName
.++
$this
->
tableIndexes
[
$tableName
];
}
else
{
$this
->
tableIndexes
[
$tableName
]
=
1
;
return
$tableName
;
}
}
/**
/**
* loads a component
* loads a component
*
*
...
@@ -1358,18 +1066,8 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -1358,18 +1066,8 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
* @throws Doctrine_Query_Exception
* @throws Doctrine_Query_Exception
* @return Doctrine_Table
* @return Doctrine_Table
*/
*/
final
public
function
load
(
$path
,
$loadFields
=
true
)
final
public
function
load
2
(
$path
,
$loadFields
=
true
)
{
{
// parse custom join conditions
$e
=
explode
(
' ON '
,
$path
);
$joinCondition
=
''
;
if
(
count
(
$e
)
>
1
)
{
$joinCondition
=
' AND '
.
$e
[
1
];
$path
=
$e
[
0
];
}
$tmp
=
explode
(
' '
,
$path
);
$tmp
=
explode
(
' '
,
$path
);
$componentAlias
=
(
count
(
$tmp
)
>
1
)
?
end
(
$tmp
)
:
false
;
$componentAlias
=
(
count
(
$tmp
)
>
1
)
?
end
(
$tmp
)
:
false
;
...
@@ -1577,104 +1275,5 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
...
@@ -1577,104 +1275,5 @@ class Doctrine_Query2 extends Doctrine_Hydrate2 implements Countable {
return
$table
;
return
$table
;
}
}
/**
* parseFields
*
* @param string $fullName
* @param string $tableName
* @param array $exploded
* @param string $currPath
* @return void
*/
final
public
function
parseFields
(
$fullName
,
$tableName
,
array
$exploded
,
$currPath
)
{
$table
=
$this
->
tables
[
$tableName
];
$fields
=
array
();
if
(
strpos
(
$fullName
,
'-'
)
===
false
)
{
$fetchmode
=
$table
->
getAttribute
(
Doctrine
::
ATTR_FETCHMODE
);
if
(
isset
(
$exploded
[
1
]))
{
if
(
count
(
$exploded
)
>
2
)
{
$fields
=
$this
->
parseAggregateValues
(
$fullName
,
$tableName
,
$exploded
,
$currPath
);
}
elseif
(
count
(
$exploded
)
==
2
)
{
$fields
=
explode
(
','
,
substr
(
$exploded
[
1
],
0
,
-
1
));
}
}
}
else
{
if
(
isset
(
$exploded
[
1
]))
{
$fetchmode
=
$this
->
parseFetchMode
(
$exploded
[
1
]);
}
else
$fetchmode
=
$table
->
getAttribute
(
Doctrine
::
ATTR_FETCHMODE
);
if
(
isset
(
$exploded
[
2
]))
{
if
(
substr_count
(
$exploded
[
2
],
')'
)
>
1
)
{
}
else
{
$fields
=
explode
(
','
,
substr
(
$exploded
[
2
],
0
,
-
1
));
}
}
}
if
(
!
$this
->
aggregate
)
$this
->
loadFields
(
$table
,
$fetchmode
,
$fields
,
$currPath
);
}
/**
* parseAggregateFunction
*
* @param string $func
* @param string $reference
* @return string
*/
public
function
parseAggregateFunction
(
$func
,
$reference
)
{
$pos
=
strpos
(
$func
,
'('
);
if
(
$pos
!==
false
)
{
$funcs
=
array
();
$name
=
substr
(
$func
,
0
,
$pos
);
$func
=
substr
(
$func
,
(
$pos
+
1
),
-
1
);
$params
=
Doctrine_Query
::
bracketExplode
(
$func
,
','
,
'('
,
')'
);
foreach
(
$params
as
$k
=>
$param
)
{
$params
[
$k
]
=
$this
->
parseAggregateFunction
(
$param
,
$reference
);
}
$funcs
=
$name
.
'('
.
implode
(
', '
,
$params
)
.
')'
;
return
$funcs
;
}
else
{
if
(
!
is_numeric
(
$func
))
{
$func
=
$this
->
getTableAlias
(
$reference
)
.
'.'
.
$func
;
return
$func
;
}
else
{
return
$func
;
}
}
}
/**
* parseAggregateValues
*/
public
function
parseAggregateValues
(
$fullName
,
$tableName
,
array
$exploded
,
$currPath
)
{
$this
->
aggregate
=
true
;
$pos
=
strpos
(
$fullName
,
'('
);
$name
=
substr
(
$fullName
,
0
,
$pos
);
$string
=
substr
(
$fullName
,
(
$pos
+
1
),
-
1
);
$exploded
=
Doctrine_Query
::
bracketExplode
(
$string
,
','
);
foreach
(
$exploded
as
$k
=>
$value
)
{
$func
=
$this
->
parseAggregateFunction
(
$value
,
$currPath
);
$exploded
[
$k
]
=
$func
;
$this
->
parts
[
'select'
][]
=
$exploded
[
$k
];
}
}
}
}
draft/new-core/Table.php
0 → 100644
View file @
b8d1ab88
<?php
/*
* $Id: Table.php 1288 2007-04-20 23:58:28Z zYne $
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the LGPL. For more information, see
* <http://www.phpdoctrine.com>.
*/
/**
* Doctrine_Table represents a database table
* each Doctrine_Table holds the information of foreignKeys and associations
*
*
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @package Doctrine
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @version $Revision: 1288 $
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
*/
class
Doctrine_Table
extends
Doctrine_Configurable
implements
Countable
{
/**
* @var array $data temporary data which is then loaded into Doctrine_Record::$data
*/
private
$data
=
array
();
/**
* @var array $relations an array containing all the Doctrine_Relation objects for this table
*/
private
$relations
=
array
();
/**
* @var array $primaryKeys an array containing all primary key column names
*/
private
$primaryKeys
=
array
();
/**
* @var mixed $identifier
*/
private
$identifier
;
/**
* @see Doctrine_Identifier constants
* @var integer $identifierType the type of identifier this table uses
*/
private
$identifierType
;
/**
* @var string $query cached simple query
*/
private
$query
;
/**
* @var Doctrine_Connection $conn Doctrine_Connection object that created this table
*/
private
$conn
;
/**
* @var string $name
*/
private
$name
;
/**
* @var array $identityMap first level cache
*/
private
$identityMap
=
array
();
/**
* @var Doctrine_Table_Repository $repository record repository
*/
private
$repository
;
/**
* @var array $columns an array of column definitions,
* keys as column names and values as column definitions
*
* the value array has three values:
*
* the column type, eg. 'integer'
* the column length, eg. 11
* the column options/constraints/validators. eg array('notnull' => true)
*
* so the full columns array might look something like the following:
* array(
* 'name' => array('string', 20, array('notnull' => true, 'default' => 'someone')),
* 'age' => array('integer', 11, array('notnull' => true))
* )
*/
protected
$columns
=
array
();
/**
* @var array $columnAliases an array of column aliases
* keys as column aliases and values as column names
*/
protected
$columnAliases
=
array
();
/**
* @var array $bound bound relations
*/
private
$bound
=
array
();
/**
* @var array $boundAliases bound relation aliases
*/
private
$boundAliases
=
array
();
/**
* @var integer $columnCount cached column count, Doctrine_Record uses this column count in when
* determining its state
*/
private
$columnCount
;
/**
* @var boolean $hasDefaultValues whether or not this table has default values
*/
private
$hasDefaultValues
;
/**
* @var array $options an array containing all options
*
* -- name name of the component, for example component name of the GroupTable is 'Group'
*
* -- parents the parent classes of this component
*
* -- declaringClass name of the table definition declaring class (when using inheritance the class
* that defines the table structure can be any class in the inheritance hierarchy,
* hence we need reflection to check out which class actually calls setTableDefinition)
*
* -- tableName database table name, in most cases this is the same as component name but in some cases
* where one-table-multi-class inheritance is used this will be the name of the inherited table
*
* -- sequenceName Some databases need sequences instead of auto incrementation primary keys,
* you can set specific sequence for your table by calling setOption('sequenceName', $seqName)
* where $seqName is the name of the desired sequence
*
* -- enumMap enum value arrays
*
* -- inheritanceMap inheritanceMap is used for inheritance mapping, keys representing columns and values
* the column values that should correspond to child classes
*
* -- type table type (mysql example: INNODB)
*
* -- charset character set
*
* -- foreignKeys the foreign keys of this table
*
* -- collation
*
* -- indexes the index definitions of this table
*
* -- treeImpl the tree implementation of this table (if any)
*
* -- treeOptions the tree options
*/
protected
$options
=
array
(
'name'
=>
null
,
'tableName'
=>
null
,
'sequenceName'
=>
null
,
'inheritanceMap'
=>
array
(),
'enumMap'
=>
array
(),
'engine'
=>
null
,
'charset'
=>
null
,
'collation'
=>
null
,
'treeImpl'
=>
null
,
'treeOptions'
=>
null
,
'indexes'
=>
array
(),
);
/**
* @var Doctrine_Tree $tree tree object associated with this table
*/
protected
$tree
;
/**
* the constructor
* @throws Doctrine_Connection_Exception if there are no opened connections
* @throws Doctrine_Table_Exception if there is already an instance of this table
* @return void
*/
public
function
__construct
(
$name
,
Doctrine_Connection
$conn
)
{
$this
->
conn
=
$conn
;
$this
->
setParent
(
$this
->
conn
);
$this
->
options
[
'name'
]
=
$name
;
if
(
!
class_exists
(
$name
)
||
empty
(
$name
))
{
throw
new
Doctrine_Exception
(
"Couldn't find class
$name
"
);
}
$record
=
new
$name
(
$this
);
$names
=
array
();
$class
=
$name
;
// get parent classes
do
{
if
(
$class
==
"Doctrine_Record"
)
break
;
$name
=
$class
;
$names
[]
=
$name
;
}
while
(
$class
=
get_parent_class
(
$class
));
// reverse names
$names
=
array_reverse
(
$names
);
// create database table
if
(
method_exists
(
$record
,
'setTableDefinition'
))
{
$record
->
setTableDefinition
();
// set the table definition for the given tree implementation
if
(
$this
->
isTree
())
$this
->
getTree
()
->
setTableDefinition
();
$this
->
columnCount
=
count
(
$this
->
columns
);
if
(
isset
(
$this
->
columns
))
{
// get the declaring class of setTableDefinition method
$method
=
new
ReflectionMethod
(
$this
->
options
[
'name'
],
'setTableDefinition'
);
$class
=
$method
->
getDeclaringClass
();
$this
->
options
[
'declaringClass'
]
=
$class
;
if
(
!
isset
(
$this
->
options
[
'tableName'
]))
{
$this
->
options
[
'tableName'
]
=
Doctrine
::
tableize
(
$class
->
getName
());
}
switch
(
count
(
$this
->
primaryKeys
))
{
case
0
:
$this
->
columns
=
array_merge
(
array
(
'id'
=>
array
(
'integer'
,
20
,
array
(
'autoincrement'
=>
true
,
'primary'
=>
true
,
)
)
),
$this
->
columns
);
$this
->
primaryKeys
[]
=
'id'
;
$this
->
identifier
=
'id'
;
$this
->
identifierType
=
Doctrine_Identifier
::
AUTO_INCREMENT
;
$this
->
columnCount
++
;
break
;
default
:
if
(
count
(
$this
->
primaryKeys
)
>
1
)
{
$this
->
identifier
=
$this
->
primaryKeys
;
$this
->
identifierType
=
Doctrine_Identifier
::
COMPOSITE
;
}
else
{
foreach
(
$this
->
primaryKeys
as
$pk
)
{
$e
=
$this
->
columns
[
$pk
][
2
];
$found
=
false
;
foreach
(
$e
as
$option
=>
$value
)
{
if
(
$found
)
break
;
$e2
=
explode
(
':'
,
$option
);
switch
(
strtolower
(
$e2
[
0
]))
{
case
'autoincrement'
:
case
'autoinc'
:
$this
->
identifierType
=
Doctrine_Identifier
::
AUTO_INCREMENT
;
$found
=
true
;
break
;
case
'seq'
:
case
'sequence'
:
$this
->
identifierType
=
Doctrine_Identifier
::
SEQUENCE
;
$found
=
true
;
if
(
$value
)
{
$this
->
options
[
'sequenceName'
]
=
$value
;
}
else
{
if
((
$sequence
=
$this
->
getAttribute
(
Doctrine
::
ATTR_DEFAULT_SEQUENCE
))
!==
null
)
{
$this
->
options
[
'sequenceName'
]
=
$sequence
;
}
else
{
$this
->
options
[
'sequenceName'
]
=
$this
->
conn
->
getSequenceName
(
$this
->
options
[
'tableName'
]);
}
}
break
;
}
}
if
(
!
isset
(
$this
->
identifierType
))
{
$this
->
identifierType
=
Doctrine_Identifier
::
NORMAL
;
}
$this
->
identifier
=
$pk
;
}
}
};
/**
if ( ! isset($definition['values'])) {
throw new Doctrine_Table_Exception('No values set for enum column ' . $name);
}
if ( ! is_array($definition['values'])) {
throw new Doctrine_Table_Exception('Enum column values should be specified as an array.');
}
*/
}
}
else
{
throw
new
Doctrine_Table_Exception
(
"Class '
$name
' has no table definition."
);
}
$record
->
setUp
();
// if tree, set up tree
if
(
$this
->
isTree
())
{
$this
->
getTree
()
->
setUp
();
}
// save parents
array_pop
(
$names
);
$this
->
options
[
'parents'
]
=
$names
;
$this
->
query
=
'SELECT '
.
implode
(
', '
,
array_keys
(
$this
->
columns
))
.
' FROM '
.
$this
->
getTableName
();
$this
->
repository
=
new
Doctrine_Table_Repository
(
$this
);
}
/**
* export
* exports this table to database based on column and option definitions
*
* @throws Doctrine_Connection_Exception if some error other than Doctrine::ERR_ALREADY_EXISTS
* occurred during the create table operation
* @return boolean whether or not the export operation was successful
* false if table already existed in the database
*/
public
function
export
()
{
if
(
!
Doctrine
::
isValidClassname
(
$this
->
options
[
'declaringClass'
]
->
getName
()))
{
throw
new
Doctrine_Table_Exception
(
'Class name not valid.'
);
}
try
{
$columns
=
array
();
$primary
=
array
();
foreach
(
$this
->
columns
as
$name
=>
$column
)
{
$definition
=
$column
[
2
];
$definition
[
'type'
]
=
$column
[
0
];
$definition
[
'length'
]
=
$column
[
1
];
switch
(
$definition
[
'type'
])
{
case
'enum'
:
if
(
isset
(
$definition
[
'default'
]))
{
$definition
[
'default'
]
=
$this
->
enumIndex
(
$name
,
$definition
[
'default'
]);
}
break
;
case
'boolean'
:
if
(
isset
(
$definition
[
'default'
]))
{
$definition
[
'default'
]
=
$this
->
conn
->
convertBooleans
(
$definition
[
'default'
]);
}
break
;
}
$columns
[
$name
]
=
$definition
;
if
(
isset
(
$definition
[
'primary'
])
&&
$definition
[
'primary'
])
{
$primary
[]
=
$name
;
}
}
if
(
$this
->
getAttribute
(
Doctrine
::
ATTR_EXPORT
)
&
Doctrine
::
EXPORT_CONSTRAINTS
)
{
foreach
(
$this
->
getRelations
()
as
$name
=>
$relation
)
{
$fk
=
$relation
->
toArray
();
$fk
[
'foreignTable'
]
=
$relation
->
getTable
()
->
getTableName
();
if
(
$relation
->
getTable
()
===
$this
&&
in_array
(
$relation
->
getLocal
(),
$primary
))
{
continue
;
}
if
(
$relation
->
hasConstraint
())
{
$options
[
'foreignKeys'
][]
=
$fk
;
}
elseif
(
$relation
instanceof
Doctrine_Relation_LocalKey
)
{
$options
[
'foreignKeys'
][]
=
$fk
;
}
}
}
$options
[
'primary'
]
=
$primary
;
$this
->
conn
->
export
->
createTable
(
$this
->
options
[
'tableName'
],
$columns
,
array_merge
(
$this
->
options
,
$options
));
}
catch
(
Doctrine_Connection_Exception
$e
)
{
// we only want to silence table already exists errors
if
(
$e
->
getPortableCode
()
!==
Doctrine
::
ERR_ALREADY_EXISTS
)
{
throw
$e
;
}
}
}
/**
* exportConstraints
* exports the constraints of this table into database based on option definitions
*
* @throws Doctrine_Connection_Exception if something went wrong on db level
* @return void
*/
public
function
exportConstraints
()
{
try
{
$this
->
conn
->
beginTransaction
();
foreach
(
$this
->
options
[
'index'
]
as
$index
=>
$definition
)
{
$this
->
conn
->
export
->
createIndex
(
$this
->
options
[
'tableName'
],
$index
,
$definition
);
}
$this
->
conn
->
commit
();
}
catch
(
Doctrine_Connection_Exception
$e
)
{
$this
->
conn
->
rollback
();
throw
$e
;
}
}
/**
* __get
* an alias for getOption
*
* @param string $option
*/
public
function
__get
(
$option
)
{
if
(
isset
(
$this
->
options
[
$option
]))
{
return
$this
->
options
[
$option
];
}
return
null
;
}
/**
* __isset
*
* @param string $option
*/
public
function
__isset
(
$option
)
{
return
isset
(
$this
->
options
[
$option
]);
}
/**
* addForeignKey
*
* adds a foreignKey to this table
*
* @return void
*/
public
function
addForeignKey
(
array
$definition
)
{
$this
->
options
[
'foreignKeys'
][]
=
$definition
;
}
/**
* addIndex
*
* adds an index to this table
*
* @return void
*/
public
function
addIndex
(
$index
,
array
$definition
)
{
$index
=
$this
->
conn
->
getIndexName
(
$index
);
$this
->
options
[
'indexes'
][
$index
]
=
$definition
;
}
/**
* getIndex
*
* @return array|boolean array on success, FALSE on failure
*/
public
function
getIndex
(
$index
)
{
if
(
isset
(
$this
->
options
[
'indexes'
][
$index
]))
{
return
$this
->
options
[
'indexes'
][
$index
];
}
return
false
;
}
/**
* createQuery
* creates a new Doctrine_Query object and adds the component name
* of this table as the query 'from' part
*
* @return Doctrine_Query
*/
public
function
createQuery
()
{
return
Doctrine_Query
::
create
()
->
from
(
$this
->
getComponentName
());
}
/**
* getRepository
*
* @return Doctrine_Table_Repository
*/
public
function
getRepository
()
{
return
$this
->
repository
;
}
public
function
setOption
(
$name
,
$value
)
{
switch
(
$name
)
{
case
'name'
:
case
'tableName'
:
break
;
case
'enumMap'
:
case
'inheritanceMap'
:
case
'index'
:
case
'treeOptions'
:
if
(
!
is_array
(
$value
))
{
throw
new
Doctrine_Table_Exception
(
$name
.
' should be an array.'
);
}
break
;
}
$this
->
options
[
$name
]
=
$value
;
}
public
function
getOption
(
$name
)
{
if
(
isset
(
$this
->
options
[
$name
]))
{
return
$this
->
options
[
$name
];
}
return
null
;
}
/**
* getColumnName
*
* returns a column name for column alias
* if the actual name for the alias cannot be found
* this method returns the given alias
*
* @param string $alias column alias
* @return string column name
*/
public
function
getColumnName
(
$alias
)
{
if
(
isset
(
$this
->
columnAliases
[
$alias
]))
{
return
$this
->
columnAliases
[
$alias
];
}
return
$alias
;
}
/**
* setColumn
*
* @param string $name
* @param string $type
* @param integer $length
* @param mixed $options
* @throws Doctrine_Table_Exception if trying use wrongly typed parameter
* @return void
*/
public
function
setColumn
(
$name
,
$type
,
$length
=
null
,
$options
=
array
())
{
if
(
is_string
(
$options
))
{
$options
=
explode
(
'|'
,
$options
);
}
foreach
(
$options
as
$k
=>
$option
)
{
if
(
is_numeric
(
$k
))
{
if
(
!
empty
(
$option
))
{
$options
[
$option
]
=
true
;
}
unset
(
$options
[
$k
]);
}
}
$name
=
strtolower
(
$name
);
$parts
=
explode
(
' as '
,
$name
);
if
(
count
(
$parts
)
>
1
)
{
$this
->
columnAliases
[
$parts
[
1
]]
=
$parts
[
0
];
$name
=
$parts
[
0
];
}
if
(
$length
==
null
)
{
$length
=
2147483647
;
}
if
((
string
)
(
int
)
$length
!==
(
string
)
$length
)
{
throw
new
Doctrine_Table_Exception
(
'Invalid argument given for column length'
);
}
$this
->
columns
[
$name
]
=
array
(
$type
,
$length
,
$options
);
if
(
isset
(
$options
[
'primary'
]))
{
$this
->
primaryKeys
[]
=
$name
;
}
if
(
isset
(
$options
[
'default'
]))
{
$this
->
hasDefaultValues
=
true
;
}
}
/**
* hasDefaultValues
* returns true if this table has default values, otherwise false
*
* @return boolean
*/
public
function
hasDefaultValues
()
{
return
$this
->
hasDefaultValues
;
}
/**
* getDefaultValueOf
* returns the default value(if any) for given column
*
* @param string $column
* @return mixed
*/
public
function
getDefaultValueOf
(
$column
)
{
$column
=
strtolower
(
$column
);
if
(
!
isset
(
$this
->
columns
[
$column
]))
{
throw
new
Doctrine_Table_Exception
(
"Couldn't get default value. Column "
.
$column
.
" doesn't exist."
);
}
if
(
isset
(
$this
->
columns
[
$column
][
2
][
'default'
]))
{
return
$this
->
columns
[
$column
][
2
][
'default'
];
}
else
{
return
null
;
}
}
/**
* @return mixed
*/
public
function
getIdentifier
()
{
return
$this
->
identifier
;
}
/**
* @return integer
*/
public
function
getIdentifierType
()
{
return
$this
->
identifierType
;
}
/**
* hasColumn
* @return boolean
*/
public
function
hasColumn
(
$name
)
{
return
isset
(
$this
->
columns
[
$name
]);
}
/**
* @param mixed $key
* @return void
*/
public
function
setPrimaryKey
(
$key
)
{
switch
(
gettype
(
$key
))
{
case
"array"
:
$this
->
primaryKeys
=
array_values
(
$key
);
break
;
case
"string"
:
$this
->
primaryKeys
[]
=
$key
;
break
;
};
}
/**
* returns all primary keys
* @return array
*/
public
function
getPrimaryKeys
()
{
return
$this
->
primaryKeys
;
}
/**
* @return boolean
*/
public
function
hasPrimaryKey
(
$key
)
{
return
in_array
(
$key
,
$this
->
primaryKeys
);
}
/**
* returns all bound relations
*
* @return array
*/
public
function
getBounds
()
{
return
$this
->
bound
;
}
/**
* returns a bound relation array
*
* @param string $name
* @return array
*/
public
function
getBound
(
$name
)
{
if
(
!
isset
(
$this
->
bound
[
$name
]))
{
throw
new
Doctrine_Table_Exception
(
'Unknown bound '
.
$name
);
}
return
$this
->
bound
[
$name
];
}
/**
* returns a bound relation array
*
* @param string $name
* @return array
*/
public
function
getBoundForName
(
$name
,
$component
)
{
foreach
(
$this
->
bound
as
$k
=>
$bound
)
{
$e
=
explode
(
'.'
,
$bound
[
'field'
]);
if
(
$bound
[
'class'
]
==
$name
&&
$e
[
0
]
==
$component
)
{
return
$this
->
bound
[
$k
];
}
}
throw
new
Doctrine_Table_Exception
(
'Unknown bound '
.
$name
);
}
/**
* returns the alias for given component name
*
* @param string $name
* @return string
*/
public
function
getAlias
(
$name
)
{
if
(
isset
(
$this
->
boundAliases
[
$name
]))
{
return
$this
->
boundAliases
[
$name
];
}
return
$name
;
}
/**
* returns component name for given alias
*
* @param string $alias
* @return string
*/
public
function
getAliasName
(
$alias
)
{
if
(
$name
=
array_search
(
$alias
,
$this
->
boundAliases
))
{
return
$name
;
}
return
$alias
;
}
/**
* unbinds all relations
*
* @return void
*/
public
function
unbindAll
()
{
throw
new
Exception
();
$this
->
bound
=
array
();
$this
->
relations
=
array
();
$this
->
boundAliases
=
array
();
}
/**
* unbinds a relation
* returns true on success, false on failure
*
* @param $name
* @return boolean
*/
public
function
unbind
(
$name
)
{
if
(
!
isset
(
$this
->
bound
[
$name
]))
{
return
false
;
}
unset
(
$this
->
bound
[
$name
]);
if
(
isset
(
$this
->
relations
[
$name
]))
{
unset
(
$this
->
relations
[
$name
]);
}
if
(
isset
(
$this
->
boundAliases
[
$name
]))
{
unset
(
$this
->
boundAliases
[
$name
]);
}
return
true
;
}
/**
* binds a relation
*
* @param string $name
* @param string $field
* @return void
*/
public
function
bind
(
$name
,
$field
,
$type
,
$options
=
null
)
{
if
(
isset
(
$this
->
relations
[
$name
]))
{
unset
(
$this
->
relations
[
$name
]);
}
$lower
=
strtolower
(
$name
);
if
(
isset
(
$this
->
columns
[
$lower
]))
{
throw
new
Doctrine_Table_Exception
(
"Couldn't bind relation. Column with name "
.
$lower
.
' already exists!'
);
}
$e
=
explode
(
' as '
,
$name
);
$name
=
$e
[
0
];
if
(
isset
(
$e
[
1
]))
{
$alias
=
$e
[
1
];
$this
->
boundAliases
[
$name
]
=
$alias
;
}
else
{
$alias
=
$name
;
}
$this
->
bound
[
$alias
]
=
array
(
'field'
=>
$field
,
'type'
=>
$type
,
'class'
=>
$name
,
'alias'
=>
$alias
);
if
(
$options
!==
null
)
{
$opt
=
array
();
if
(
is_string
(
$options
))
{
$opt
[
'local'
]
=
$options
;
}
else
{
$opt
=
(
array
)
$options
;
}
$this
->
bound
[
$alias
]
=
array_merge
(
$this
->
bound
[
$alias
],
$opt
);
}
}
/**
* @return Doctrine_Connection
*/
public
function
getConnection
()
{
return
$this
->
conn
;
}
/**
* hasRelatedComponent
* @return boolean
*/
public
function
hasRelatedComponent
(
$name
,
$component
)
{
return
(
strpos
(
$this
->
bound
[
$name
][
'field'
],
$component
.
'.'
)
!==
false
);
}
/**
* @param string $name component name of which a foreign key object is bound
* @return boolean
*/
final
public
function
hasRelation
(
$name
)
{
if
(
isset
(
$this
->
bound
[
$name
]))
{
return
true
;
}
foreach
(
$this
->
bound
as
$k
=>
$v
)
{
if
(
$this
->
hasRelatedComponent
(
$k
,
$name
))
{
return
true
;
}
}
return
false
;
}
/**
* getRelation
*
* @param string $name component name of which a foreign key object is bound
* @return Doctrine_Relation
*/
public
function
getRelation
(
$name
,
$recursive
=
true
)
{
if
(
isset
(
$this
->
relations
[
$name
]))
{
return
$this
->
relations
[
$name
];
}
if
(
!
$this
->
conn
->
hasTable
(
$this
->
options
[
'name'
]))
{
$allowExport
=
true
;
}
else
{
$allowExport
=
false
;
}
if
(
isset
(
$this
->
bound
[
$name
]))
{
$definition
=
$this
->
bound
[
$name
];
list
(
$component
,
$definition
[
'foreign'
])
=
explode
(
'.'
,
$definition
[
'field'
]);
unset
(
$definition
[
'field'
]);
$definition
[
'table'
]
=
$this
->
conn
->
getTable
(
$definition
[
'class'
],
$allowExport
);
$definition
[
'constraint'
]
=
false
;
if
(
$component
==
$this
->
options
[
'name'
]
||
in_array
(
$component
,
$this
->
options
[
'parents'
]))
{
// ONE-TO-ONE
if
(
$definition
[
'type'
]
==
Doctrine_Relation
::
ONE_COMPOSITE
||
$definition
[
'type'
]
==
Doctrine_Relation
::
ONE_AGGREGATE
)
{
// tree structure parent relation found
if
(
!
isset
(
$definition
[
'local'
]))
{
$definition
[
'local'
]
=
$definition
[
'foreign'
];
$definition
[
'foreign'
]
=
$definition
[
'table'
]
->
getIdentifier
();
}
$relation
=
new
Doctrine_Relation_LocalKey
(
$definition
);
}
else
{
// tree structure children relation found
if
(
!
isset
(
$definition
[
'local'
]))
{
$tmp
=
$definition
[
'table'
]
->
getIdentifier
();
$definition
[
'local'
]
=
$tmp
;
}
//$definition['foreign'] = $tmp;
$definition
[
'constraint'
]
=
true
;
$relation
=
new
Doctrine_Relation_ForeignKey
(
$definition
);
}
}
elseif
(
$component
==
$definition
[
'class'
]
||
(
$component
==
$definition
[
'alias'
]))
{
// && ($name == $this->options['name'] || in_array($name,$this->parents))
if
(
!
isset
(
$defintion
[
'local'
]))
{
$definition
[
'local'
]
=
$this
->
identifier
;
}
$definition
[
'constraint'
]
=
true
;
// ONE-TO-MANY or ONE-TO-ONE
$relation
=
new
Doctrine_Relation_ForeignKey
(
$definition
);
}
else
{
// MANY-TO-MANY
// only aggregate relations allowed
if
(
$definition
[
'type'
]
!=
Doctrine_Relation
::
MANY_AGGREGATE
)
{
throw
new
Doctrine_Table_Exception
(
"Only aggregate relations are allowed for many-to-many relations"
);
}
$classes
=
array_merge
(
$this
->
options
[
'parents'
],
array
(
$this
->
options
[
'name'
]));
foreach
(
array_reverse
(
$classes
)
as
$class
)
{
try
{
$bound
=
$definition
[
'table'
]
->
getBoundForName
(
$class
,
$component
);
break
;
}
catch
(
Doctrine_Table_Exception
$exc
)
{
}
}
if
(
!
isset
(
$bound
))
{
throw
new
Doctrine_Table_Exception
(
"Couldn't map many-to-many relation for "
.
$this
->
options
[
'name'
]
.
" and
$name
. Components use different join tables."
);
}
if
(
!
isset
(
$definition
[
'local'
]))
{
$definition
[
'local'
]
=
$this
->
identifier
;
}
$e2
=
explode
(
'.'
,
$bound
[
'field'
]);
$fields
=
explode
(
'-'
,
$e2
[
1
]);
if
(
$e2
[
0
]
!=
$component
)
{
throw
new
Doctrine_Table_Exception
(
$e2
[
0
]
.
' doesn\'t match '
.
$component
);
}
$associationTable
=
$this
->
conn
->
getTable
(
$e2
[
0
],
$allowExport
);
if
(
count
(
$fields
)
>
1
)
{
// SELF-REFERENCING THROUGH JOIN TABLE
$def
[
'table'
]
=
$associationTable
;
$def
[
'local'
]
=
$this
->
identifier
;
$def
[
'foreign'
]
=
$fields
[
0
];
$def
[
'alias'
]
=
$e2
[
0
];
$def
[
'class'
]
=
$e2
[
0
];
$def
[
'type'
]
=
Doctrine_Relation
::
MANY_COMPOSITE
;
$this
->
relations
[
$e2
[
0
]]
=
new
Doctrine_Relation_ForeignKey
(
$def
);
$definition
[
'assocTable'
]
=
$associationTable
;
$definition
[
'local'
]
=
$fields
[
0
];
$definition
[
'foreign'
]
=
$fields
[
1
];
$relation
=
new
Doctrine_Relation_Association_Self
(
$definition
);
}
else
{
if
(
$definition
[
'table'
]
===
$this
)
{
}
else
{
// auto initialize a new one-to-one relationships for association table
$associationTable
->
bind
(
$this
->
getComponentName
(),
$associationTable
->
getComponentName
()
.
'.'
.
$e2
[
1
],
Doctrine_Relation
::
ONE_AGGREGATE
);
$associationTable
->
bind
(
$definition
[
'table'
]
->
getComponentName
(),
$associationTable
->
getComponentName
()
.
'.'
.
$definition
[
'foreign'
],
Doctrine_Relation
::
ONE_AGGREGATE
);
// NORMAL MANY-TO-MANY RELATIONSHIP
$def
[
'table'
]
=
$associationTable
;
$def
[
'foreign'
]
=
$e2
[
1
];
$def
[
'local'
]
=
$definition
[
'local'
];
$def
[
'alias'
]
=
$e2
[
0
];
$def
[
'class'
]
=
$e2
[
0
];
$def
[
'type'
]
=
Doctrine_Relation
::
MANY_COMPOSITE
;
$this
->
relations
[
$e2
[
0
]]
=
new
Doctrine_Relation_ForeignKey
(
$def
);
$definition
[
'local'
]
=
$e2
[
1
];
$definition
[
'assocTable'
]
=
$associationTable
;
$relation
=
new
Doctrine_Relation_Association
(
$definition
);
}
}
}
$this
->
relations
[
$name
]
=
$relation
;
return
$this
->
relations
[
$name
];
}
// load all relations
$this
->
getRelations
();
if
(
$recursive
)
{
return
$this
->
getRelation
(
$name
,
false
);
}
else
{
throw
new
Doctrine_Table_Exception
(
$this
->
options
[
'name'
]
.
" doesn't have a relation to "
.
$name
);
}
}
/**
* returns an array containing all foreign key objects
*
* @return array
*/
final
public
function
getRelations
()
{
foreach
(
$this
->
bound
as
$k
=>
$v
)
{
$this
->
getRelation
(
$k
);
}
return
$this
->
relations
;
}
/**
* create
* creates a new record
*
* @param $array an array where keys are field names and values representing field values
* @return Doctrine_Record
*/
public
function
create
(
array
$array
=
array
())
{
$this
->
data
=
$array
;
$record
=
new
$this
->
options
[
'name'
](
$this
,
true
);
$this
->
data
=
array
();
return
$record
;
}
/**
* finds a record by its identifier
*
* @param $id database row id
* @return Doctrine_Record|false a record for given database identifier
*/
public
function
find
(
$id
)
{
if
(
$id
!==
null
)
{
if
(
!
is_array
(
$id
))
{
$id
=
array
(
$id
);
}
else
{
$id
=
array_values
(
$id
);
}
$query
=
$this
->
query
.
' WHERE '
.
implode
(
' = ? AND '
,
$this
->
primaryKeys
)
.
' = ?'
;
$query
=
$this
->
applyInheritance
(
$query
);
$params
=
array_merge
(
$id
,
array_values
(
$this
->
options
[
'inheritanceMap'
]));
$stmt
=
$this
->
conn
->
execute
(
$query
,
$params
);
$this
->
data
=
$stmt
->
fetch
(
PDO
::
FETCH_ASSOC
);
if
(
$this
->
data
===
false
)
return
false
;
return
$this
->
getRecord
();
}
return
false
;
}
/**
* applyInheritance
* @param $where query where part to be modified
* @return string query where part with column aggregation inheritance added
*/
final
public
function
applyInheritance
(
$where
)
{
if
(
!
empty
(
$this
->
options
[
'inheritanceMap'
]))
{
$a
=
array
();
foreach
(
$this
->
options
[
'inheritanceMap'
]
as
$field
=>
$value
)
{
$a
[]
=
$field
.
' = ?'
;
}
$i
=
implode
(
' AND '
,
$a
);
$where
.=
' AND '
.
$i
;
}
return
$where
;
}
/**
* findAll
* returns a collection of records
*
* @return Doctrine_Collection
*/
public
function
findAll
()
{
$graph
=
new
Doctrine_Query
(
$this
->
conn
);
$users
=
$graph
->
query
(
"FROM "
.
$this
->
options
[
'name'
]);
return
$users
;
}
/**
* findByDql
* finds records with given DQL where clause
* returns a collection of records
*
* @param string $dql DQL after WHERE clause
* @param array $params query parameters
* @return Doctrine_Collection
*/
public
function
findBySql
(
$dql
,
array
$params
=
array
())
{
$q
=
new
Doctrine_Query
(
$this
->
conn
);
$users
=
$q
->
query
(
"FROM "
.
$this
->
options
[
'name'
]
.
" WHERE "
.
$dql
,
$params
);
return
$users
;
}
public
function
findByDql
(
$dql
,
array
$params
=
array
())
{
return
$this
->
findBySql
(
$dql
,
$params
);
}
/**
* clear
* clears the first level cache (identityMap)
*
* @return void
*/
public
function
clear
()
{
$this
->
identityMap
=
array
();
}
/**
* getRecord
* first checks if record exists in identityMap, if not
* returns a new record
*
* @return Doctrine_Record
*/
public
function
getRecord
()
{
$this
->
data
=
array_change_key_case
(
$this
->
data
,
CASE_LOWER
);
$key
=
$this
->
getIdentifier
();
if
(
!
is_array
(
$key
))
{
$key
=
array
(
$key
);
}
foreach
(
$key
as
$k
)
{
if
(
!
isset
(
$this
->
data
[
$k
]))
{
throw
new
Doctrine_Table_Exception
(
"Primary key value for
$k
wasn't found"
);
}
$id
[]
=
$this
->
data
[
$k
];
}
$id
=
implode
(
' '
,
$id
);
if
(
isset
(
$this
->
identityMap
[
$id
]))
{
$record
=
$this
->
identityMap
[
$id
];
$record
->
hydrate
(
$this
->
data
);
}
else
{
$recordName
=
$this
->
getClassnameToReturn
();
$record
=
new
$recordName
(
$this
);
$this
->
identityMap
[
$id
]
=
$record
;
}
$this
->
data
=
array
();
return
$record
;
}
/**
* Get the classname to return. Most often this is just the options['name']
*
* Check the subclasses option and the inheritanceMap for each subclass to see
* if all the maps in a subclass is met. If this is the case return that
* subclass name. If no subclasses match or if there are no subclasses defined
* return the name of the class for this tables record.
*
* @todo this function could use reflection to check the first time it runs
* if the subclassing option is not set.
*
* @return string The name of the class to create
*
*/
public
function
getClassnameToReturn
()
{
if
(
!
isset
(
$this
->
options
[
'subclasses'
]))
{
return
$this
->
options
[
'name'
];
}
foreach
(
$this
->
options
[
'subclasses'
]
as
$subclass
)
{
$table
=
$this
->
conn
->
getTable
(
$subclass
);
$inheritanceMap
=
$table
->
getOption
(
'inheritanceMap'
);
$nomatch
=
false
;
foreach
(
$inheritanceMap
as
$key
=>
$value
)
{
if
(
!
isset
(
$this
->
data
[
$key
])
||
$this
->
data
[
$key
]
!=
$value
)
{
$nomatch
=
true
;
break
;
}
}
if
(
!
$nomatch
)
{
return
$table
->
getComponentName
();
}
}
return
$this
->
options
[
'name'
];
}
/**
* @param $id database row id
* @throws Doctrine_Find_Exception
*/
final
public
function
getProxy
(
$id
=
null
)
{
if
(
$id
!==
null
)
{
$query
=
'SELECT '
.
implode
(
', '
,
$this
->
primaryKeys
)
.
' FROM '
.
$this
->
getTableName
()
.
' WHERE '
.
implode
(
' = ? && '
,
$this
->
primaryKeys
)
.
' = ?'
;
$query
=
$this
->
applyInheritance
(
$query
);
$params
=
array_merge
(
array
(
$id
),
array_values
(
$this
->
options
[
'inheritanceMap'
]));
$this
->
data
=
$this
->
conn
->
execute
(
$query
,
$params
)
->
fetch
(
PDO
::
FETCH_ASSOC
);
if
(
$this
->
data
===
false
)
return
false
;
}
return
$this
->
getRecord
();
}
/**
* count
*
* @return integer
*/
public
function
count
()
{
$a
=
$this
->
conn
->
getDBH
()
->
query
(
"SELECT COUNT(1) FROM "
.
$this
->
options
[
'tableName'
])
->
fetch
(
PDO
::
FETCH_NUM
);
return
current
(
$a
);
}
/**
* @return Doctrine_Query a Doctrine_Query object
*/
public
function
getQueryObject
()
{
$graph
=
new
Doctrine_Query
(
$this
->
getConnection
());
$graph
->
load
(
$this
->
getComponentName
());
return
$graph
;
}
/**
* execute
* @param string $query
* @param array $array
* @param integer $limit
* @param integer $offset
*/
public
function
execute
(
$query
,
array
$array
=
array
(),
$limit
=
null
,
$offset
=
null
)
{
$coll
=
new
Doctrine_Collection
(
$this
);
$query
=
$this
->
conn
->
modifyLimitQuery
(
$query
,
$limit
,
$offset
);
if
(
!
empty
(
$array
))
{
$stmt
=
$this
->
conn
->
getDBH
()
->
prepare
(
$query
);
$stmt
->
execute
(
$array
);
}
else
{
$stmt
=
$this
->
conn
->
getDBH
()
->
query
(
$query
);
}
$data
=
$stmt
->
fetchAll
(
PDO
::
FETCH_ASSOC
);
$stmt
->
closeCursor
();
foreach
(
$data
as
$row
)
{
$this
->
data
=
$row
;
$record
=
$this
->
getRecord
();
$coll
->
add
(
$record
);
}
return
$coll
;
}
/**
* @param string $field
* @return array
*/
final
public
function
getEnumValues
(
$field
)
{
if
(
isset
(
$this
->
columns
[
$field
][
2
][
'values'
]))
{
return
$this
->
columns
[
$field
][
2
][
'values'
];
}
else
{
return
array
();
}
}
/**
* enumValue
*
* @param string $field
* @param integer $index
* @return mixed
*/
public
function
enumValue
(
$field
,
$index
)
{
if
(
$index
instanceof
Doctrine_Null
)
return
$index
;
return
isset
(
$this
->
columns
[
$field
][
2
][
'values'
][
$index
])
?
$this
->
columns
[
$field
][
2
][
'values'
][
$index
]
:
$index
;
}
/**
* enumIndex
*
* @param string $field
* @param mixed $value
* @return mixed
*/
public
function
enumIndex
(
$field
,
$value
)
{
$values
=
$this
->
getEnumValues
(
$field
);
return
array_search
(
$value
,
$values
);
}
/**
* invokeSet
*
* @param mixed $value
*/
public
function
invokeSet
(
Doctrine_Record
$record
,
$name
,
$value
)
{
if
(
!
(
$this
->
getAttribute
(
Doctrine
::
ATTR_ACCESSORS
)
&
Doctrine
::
ACCESSOR_SET
))
{
return
$value
;
}
$prefix
=
$this
->
getAttribute
(
Doctrine
::
ATTR_ACCESSOR_PREFIX_SET
);
if
(
!
$prefix
)
$prefix
=
'set'
;
$method
=
$prefix
.
$name
;
if
(
method_exists
(
$record
,
$method
))
{
return
$record
->
$method
(
$value
);
}
return
$value
;
}
/**
* invokeGet
*
* @param mixed $value
*/
public
function
invokeGet
(
Doctrine_Record
$record
,
$name
,
$value
)
{
if
(
!
(
$this
->
getAttribute
(
Doctrine
::
ATTR_ACCESSORS
)
&
Doctrine
::
ACCESSOR_GET
))
{
return
$value
;
}
$prefix
=
$this
->
getAttribute
(
Doctrine
::
ATTR_ACCESSOR_PREFIX_GET
);
if
(
!
$prefix
)
$prefix
=
'get'
;
$method
=
$prefix
.
$name
;
if
(
method_exists
(
$record
,
$method
))
{
return
$record
->
$method
(
$value
);
}
return
$value
;
}
/**
* getDefinitionOf
*
* @return string ValueWrapper class name on success, false on failure
*/
public
function
getValueWrapperOf
(
$column
)
{
if
(
isset
(
$this
->
columns
[
$column
][
2
][
'wrapper'
]))
{
return
$this
->
columns
[
$column
][
2
][
'wrapper'
];
}
return
false
;
}
/**
* getColumnCount
*
* @return integer the number of columns in this table
*/
final
public
function
getColumnCount
()
{
return
$this
->
columnCount
;
}
/**
* returns all columns and their definitions
*
* @return array
*/
final
public
function
getColumns
()
{
return
$this
->
columns
;
}
/**
* returns an array containing all the column names
*
* @return array
*/
public
function
getColumnNames
()
{
return
array_keys
(
$this
->
columns
);
}
/**
* getDefinitionOf
*
* @return mixed array on success, false on failure
*/
public
function
getDefinitionOf
(
$column
)
{
if
(
isset
(
$this
->
columns
[
$column
]))
{
return
$this
->
columns
[
$column
];
}
return
false
;
}
/**
* getTypeOf
*
* @return mixed string on success, false on failure
*/
public
function
getTypeOf
(
$column
)
{
if
(
isset
(
$this
->
columns
[
$column
]))
{
return
$this
->
columns
[
$column
][
0
];
}
return
false
;
}
/**
* setData
* doctrine uses this function internally
* users are strongly discouraged to use this function
*
* @param array $data internal data
* @return void
*/
public
function
setData
(
array
$data
)
{
$this
->
data
=
$data
;
}
/**
* returns the maximum primary key value
*
* @return integer
*/
final
public
function
getMaxIdentifier
()
{
$sql
=
"SELECT MAX("
.
$this
->
getIdentifier
()
.
") FROM "
.
$this
->
getTableName
();
$stmt
=
$this
->
conn
->
getDBH
()
->
query
(
$sql
);
$data
=
$stmt
->
fetch
(
PDO
::
FETCH_NUM
);
return
isset
(
$data
[
0
])
?
$data
[
0
]
:
1
;
}
/**
* returns simple cached query
*
* @return string
*/
final
public
function
getQuery
()
{
return
$this
->
query
;
}
/**
* returns internal data, used by Doctrine_Record instances
* when retrieving data from database
*
* @return array
*/
final
public
function
getData
()
{
return
$this
->
data
;
}
/**
* getter for associated tree
*
* @return mixed if tree return instance of Doctrine_Tree, otherwise returns false
*/
public
function
getTree
()
{
if
(
isset
(
$this
->
options
[
'treeImpl'
]))
{
if
(
!
$this
->
tree
)
{
$options
=
isset
(
$this
->
options
[
'treeOptions'
])
?
$this
->
options
[
'treeOptions'
]
:
array
();
$this
->
tree
=
Doctrine_Tree
::
factory
(
$this
,
$this
->
options
[
'treeImpl'
],
$options
);
}
return
$this
->
tree
;
}
return
false
;
}
public
function
getComponentName
()
{
return
$this
->
options
[
'name'
];
}
public
function
getTableName
()
{
return
$this
->
options
[
'tableName'
];
}
public
function
setTableName
(
$tableName
)
{
$this
->
options
[
'tableName'
]
=
$tableName
;
}
/**
* determine if table acts as tree
*
* @return mixed if tree return true, otherwise returns false
*/
public
function
isTree
()
{
return
(
!
is_null
(
$this
->
options
[
'treeImpl'
]))
?
true
:
false
;
}
/**
* returns a string representation of this object
*
* @return string
*/
public
function
__toString
()
{
return
Doctrine_Lib
::
getTableAsString
(
$this
);
}
}
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