1
0
mirror of synced 2024-12-14 15:16:04 +03:00

added Search component, new record event listeners and some tests

This commit is contained in:
zYne 2007-07-11 14:39:15 +00:00
parent b32163fab3
commit d434174a96
20 changed files with 632 additions and 67 deletions

View File

@ -193,6 +193,7 @@ final class Doctrine
const ATTR_CACHE = 150; const ATTR_CACHE = 150;
const ATTR_CACHE_LIFESPAN = 151; const ATTR_CACHE_LIFESPAN = 151;
const ATTR_LOAD_REFERENCES = 153; const ATTR_LOAD_REFERENCES = 153;
const ATTR_RECORD_LISTENER = 154;
/** /**
* LIMIT CONSTANTS * LIMIT CONSTANTS

View File

@ -33,8 +33,8 @@ class Doctrine_AuditLog
{ {
protected $_options = array( protected $_options = array(
'className' => '%CLASS%Version', 'className' => '%CLASS%Version',
'deleteTrigger' => '%TABLE%_ddt', 'deleteTrigger' => '%TABLE%_ddtr',
'updateTrigger' => '%TABLE%_dut', 'updateTrigger' => '%TABLE%_dutr',
'versionTable' => '%TABLE%_dvt', 'versionTable' => '%TABLE%_dvt',
'versionColumn' => 'version', 'versionColumn' => 'version',
); );

View File

@ -97,12 +97,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object
} }
break; break;
case Doctrine::ATTR_CREATE_TABLES: case Doctrine::ATTR_CREATE_TABLES:
$attribute = Doctrine::ATTR_EXPORT; throw new Doctrine_Exception("ATTR_CREATE_TABLES has been deprecated. See exporting in the first chapter of the manual.");
if ($value) {
$value = Doctrine::EXPORT_TABLES;
} else {
$value = Doctrine::EXPORT_NONE;
}
break; break;
case Doctrine::ATTR_ACCESSORS: case Doctrine::ATTR_ACCESSORS:
throw new Doctrine_Exception("Get / Set filtering is deprecated (slowed down Doctrine too much)."); throw new Doctrine_Exception("Get / Set filtering is deprecated (slowed down Doctrine too much).");
@ -141,6 +136,7 @@ abstract class Doctrine_Configurable extends Doctrine_Object
case Doctrine::ATTR_EXPORT: case Doctrine::ATTR_EXPORT:
case Doctrine::ATTR_DECIMAL_PLACES: case Doctrine::ATTR_DECIMAL_PLACES:
case Doctrine::ATTR_LOAD_REFERENCES: case Doctrine::ATTR_LOAD_REFERENCES:
case Doctrine::ATTR_RECORD_LISTENER:
break; break;
case Doctrine::ATTR_SEQCOL_NAME: case Doctrine::ATTR_SEQCOL_NAME:
@ -187,13 +183,60 @@ abstract class Doctrine_Configurable extends Doctrine_Object
{ {
return $this->setListener($listener); return $this->setListener($listener);
} }
/**
* addRecordListener
*
* @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
* @return mixed this object
*/
public function addRecordListener($listener, $name = null)
{
if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER]) ||
! ($this->attributes[Doctrine::ATTR_LISTENER] instanceof Doctrine_Record_Listener_Chain)) {
$this->attributes[Doctrine::ATTR_RECORD_LISTENER] = new Doctrine_Record_Listener_Chain();
}
$this->attributes[Doctrine::ATTR_RECORD_LISTENER]->add($listener, $name);
return $this;
}
/**
* getListener
*
* @return Doctrine_EventListener_Interface|Doctrine_Overloadable
*/
public function getRecordListener()
{
if ( ! isset($this->attributes[Doctrine::ATTR_RECORD_LISTENER])) {
if (isset($this->parent)) {
return $this->parent->getRecordListener();
}
return null;
}
return $this->attributes[Doctrine::ATTR_RECORD_LISTENER];
}
/**
* setListener
*
* @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
* @return Doctrine_Configurable this object
*/
public function setRecordListener($listener)
{
if ( ! ($listener instanceof Doctrine_Record_Listener_Interface)
&& ! ($listener instanceof Doctrine_Overloadable)
) {
throw new Doctrine_Exception("Couldn't set eventlistener. Record listeners should implement either Doctrine_Record_Listener_Interface or Doctrine_Overloadable");
}
$this->attributes[Doctrine::ATTR_RECORD_LISTENER] = $listener;
return $this;
}
/** /**
* addListener * addListener
* *
* @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener * @param Doctrine_EventListener_Interface|Doctrine_Overloadable $listener
* @return Doctrine_Connection_Informix|Doctrine_Connection_Mssql|Doctrine_Connection_Oracle| * @return mixed this object
* Doctrine_Connection_Db2|Doctrine_Connection_Firebird|Doctrine_Connection_Common|
* Doctrine_Manager|Doctrine_Connection|Doctrine_Table
*/ */
public function addListener($listener, $name = null) public function addListener($listener, $name = null)
{ {

View File

@ -181,10 +181,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
*/ */
public function save(Doctrine_Record $record) public function save(Doctrine_Record $record)
{ {
$event = new Doctrine_Event($this, Doctrine_Event::RECORD_SAVE); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_SAVE);
$record->preSave($event); $record->preSave($event);
$record->getTable()->getRecordListener()->preSave($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
switch ($record->state()) { switch ($record->state()) {
case Doctrine_Record::STATE_TDIRTY: case Doctrine_Record::STATE_TDIRTY:
@ -201,6 +203,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
} }
$record->getTable()->getRecordListener()->postSave($event);
$record->postSave($event); $record->postSave($event);
} }
/** /**
@ -218,10 +222,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
$this->conn->beginTransaction(); $this->conn->beginTransaction();
$event = new Doctrine_Event($this, Doctrine_Event::RECORD_DELETE); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_DELETE);
$record->preDelete($event); $record->preDelete($event);
$record->getTable()->getRecordListener()->preDelete($event);
$record->state(Doctrine_Record::STATE_LOCKED); $record->state(Doctrine_Record::STATE_LOCKED);
$this->deleteComposites($record); $this->deleteComposites($record);
@ -233,6 +239,9 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$record->state(Doctrine_Record::STATE_TCLEAN); $record->state(Doctrine_Record::STATE_TCLEAN);
} }
$record->getTable()->getRecordListener()->postDelete($event);
$record->postDelete($event); $record->postDelete($event);
$this->conn->commit(); $this->conn->commit();
@ -382,10 +391,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
*/ */
public function update(Doctrine_Record $record) public function update(Doctrine_Record $record)
{ {
$event = new Doctrine_Event($this, Doctrine_Event::RECORD_UPDATE); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_UPDATE);
$record->preUpdate($event); $record->preUpdate($event);
$record->getTable()->getRecordListener()->preUpdate($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$array = $record->getPrepared(); $array = $record->getPrepared();
@ -430,6 +441,9 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
$record->assignIdentifier(true); $record->assignIdentifier(true);
} }
$record->getTable()->getRecordListener()->postUpdate($event);
$record->postUpdate($event); $record->postUpdate($event);
return true; return true;
@ -443,10 +457,12 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
public function insert(Doctrine_Record $record) public function insert(Doctrine_Record $record)
{ {
// listen the onPreInsert event // listen the onPreInsert event
$event = new Doctrine_Event($this, Doctrine_Event::RECORD_INSERT); $event = new Doctrine_Event($record, Doctrine_Event::RECORD_INSERT);
$record->preInsert($event); $record->preInsert($event);
$record->getTable()->getRecordListener()->preInsert($event);
if ( ! $event->skipOperation) { if ( ! $event->skipOperation) {
$array = $record->getPrepared(); $array = $record->getPrepared();
@ -488,6 +504,8 @@ class Doctrine_Connection_UnitOfWork extends Doctrine_Connection_Module
} }
$record->getTable()->addRecord($record); $record->getTable()->addRecord($record);
$record->getTable()->getRecordListener()->postInsert($event);
$record->postInsert($event); $record->postInsert($event);
return true; return true;

View File

@ -190,7 +190,9 @@ class Doctrine_Import extends Doctrine_Connection_Module
$classes = array(); $classes = array();
foreach ($this->listTables() as $table) { foreach ($this->listTables() as $table) {
$builder->buildRecord($table, $this->listTableColumns($table)); $builder->buildRecord(array('tableName' => $table,
'className' => Doctrine::classify($table)),
$this->listTableColumns($table));
$classes[] = Doctrine::classify($table); $classes[] = Doctrine::classify($table);
} }

View File

@ -87,10 +87,8 @@ class Doctrine_Import_Builder
} }
self::$tpl =<<<END self::$tpl =<<<END
<?php
/** /**
* This class has been auto-generated by the Doctrine ORM Framework * This class has been auto-generated by the Doctrine ORM Framework
* Created: %s
*/ */
class %s extends Doctrine_Record class %s extends Doctrine_Record
{ {
@ -100,10 +98,9 @@ class %s extends Doctrine_Record
} }
public function setUp() public function setUp()
{ {
%s
} }
} }
?>
END; END;
} }
@ -114,9 +111,9 @@ END;
* @param string $table * @param string $table
* @param array $tableColumns * @param array $tableColumns
*/ */
public function buildDefinition($table, $tableColumns) public function buildColumnDefinition(array $tableColumns)
{ {
$columns = array(0 => str_repeat(' ', 8) . '$this->setTableName(\''. $table .'\');'); $columns = array();
$i = 1; $i = 1;
foreach ($tableColumns as $name => $column) { foreach ($tableColumns as $name => $column) {
@ -158,7 +155,7 @@ END;
} }
$columns[$i] .= ');'; $columns[$i] .= ');';
if ($i < (count($table) - 1)) { if ($i < (count($tableColumns) - 1)) {
$columns[$i] .= PHP_EOL; $columns[$i] .= PHP_EOL;
} }
$i++; $i++;
@ -166,13 +163,69 @@ END;
return implode("\n", $columns); return implode("\n", $columns);
} }
public function buildRelationDefinition(array $relations)
public function buildRecord($table, $tableColumns, $className='', $fileName='')
{ {
if (empty($className)) { $ret = array();
$className = Doctrine::classify($table); $i = 0;
foreach ($relations as $name => $relation) {
$alias = (isset($relation['alias']) && $relation['alias'] !== $name) ? ' as ' . $relation['alias'] : '';
if ( ! isset($relation['type'])) {
$relation['type'] = Doctrine_Relation::ONE;
}
if ($relation['type'] === Doctrine_Relation::ONE ||
$relation['type'] === Doctrine_Relation::ONE_COMPOSITE) {
$ret[$i] = ' $this->hasOne(\'' . $name . $alias . '\'';
} else {
$ret[$i] = ' $this->hasMany(\'' . $name . $alias . '\'';
}
$a = array();
if (isset($relation['deferred']) && $relation['deferred']) {
$a[] = '\'default\' => ' . var_export($relation['deferred'], true);
}
if (isset($relation['local']) && $relation['local']) {
$a[] = '\'local\' => ' . var_export($relation['local'], true);
}
if (isset($relation['foreign']) && $relation['foreign']) {
$a[] = '\'foreign\' => ' . var_export($relation['foreign'], true);
}
if (isset($relation['onDelete']) && $relation['onDelete']) {
$a[] = '\'onDelete\' => ' . var_export($relation['onDelete'], true);
}
if (isset($relation['onUpdate']) && $relation['onUpdate']) {
$a[] = '\'onUpdate\' => ' . var_export($relation['onUpdate'], true);
}
if ( ! empty($a)) {
$ret[$i] .= ', ' . 'array(';
$length = strlen($ret[$i]);
$ret[$i] .= implode(',' . PHP_EOL . str_repeat(' ', $length), $a) . ')';
}
$ret[$i] .= ');';
$i++;
} }
return implode("\n", $ret);
}
public function buildDefinition(array $options, array $columns, array $relations = array())
{
if ( ! isset($options['className'])) {
throw new Doctrine_Import_Builder_Exception('Missing class name.');
}
//$opt = array(0 => str_repeat(' ', 8) . '$this->setTableName(\''. $table .'\');');
$content = sprintf(self::$tpl, $options['className'],
$this->buildColumnDefinition($columns),
$this->buildRelationDefinition($relations));
return $content;
}
public function buildRecord($table, $columns, $relations)
{
if (empty($fileName)) { if (empty($fileName)) {
if (empty($this->path)) { if (empty($this->path)) {
$errMsg = 'No build target directory set.'; $errMsg = 'No build target directory set.';
@ -187,13 +240,10 @@ END;
$fileName = $this->path . DIRECTORY_SEPARATOR . $className . $this->suffix; $fileName = $this->path . DIRECTORY_SEPARATOR . $className . $this->suffix;
} }
$created = date('l dS \of F Y h:i:s A');
$content = sprintf(self::$tpl, $created, $className,
$this->buildDefinition($table, $tableColumns));
$bytes = file_put_contents($fileName, $content); $content = $this->buildDefinition($options, $columns, $relations);
$bytes = file_put_contents($fileName, '<?php' . PHP_EOL . $content);
if ($bytes === false) { if ($bytes === false) {
throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $fileName); throw new Doctrine_Import_Builder_Exception("Couldn't write file " . $fileName);

View File

@ -110,6 +110,7 @@ class Doctrine_Manager extends Doctrine_Configurable implements Countable, Itera
Doctrine::ATTR_CACHE => null, Doctrine::ATTR_CACHE => null,
Doctrine::ATTR_LOAD_REFERENCES => true, Doctrine::ATTR_LOAD_REFERENCES => true,
Doctrine::ATTR_LISTENER => new Doctrine_EventListener(), Doctrine::ATTR_LISTENER => new Doctrine_EventListener(),
Doctrine::ATTR_RECORD_LISTENER => new Doctrine_Record_Listener(),
Doctrine::ATTR_LOCKMODE => 1, Doctrine::ATTR_LOCKMODE => 1,
Doctrine::ATTR_VLD => false, Doctrine::ATTR_VLD => false,
Doctrine::ATTR_AUTO_LENGTH_VLD => true, Doctrine::ATTR_AUTO_LENGTH_VLD => true,

View File

@ -1238,7 +1238,7 @@ class Doctrine_Query extends Doctrine_Query_Abstract implements Countable
} }
} else { } else {
$queryPart = $join . $foreignSql $queryPart = $join . $foreignSql
. ' ON ' . ' ON '
. $this->_conn->quoteIdentifier($localAlias . '.' . $relation->getLocal()) . $this->_conn->quoteIdentifier($localAlias . '.' . $relation->getLocal())

View File

@ -1379,9 +1379,9 @@ abstract class Doctrine_Record extends Doctrine_Record_Abstract implements Count
* *
* @param string $template * @param string $template
*/ */
public function loadTemplate($template) public function loadTemplate($template, $options = array())
{ {
$tpl = new $template(); $tpl = new $template($options);
$tpl->setTable($this->_table); $tpl->setTable($this->_table);
$tpl->setUp(); $tpl->setUp();
$tpl->setTableDefinition(); $tpl->setTableDefinition();

View File

@ -40,7 +40,7 @@ abstract class Doctrine_Record_Abstract extends Doctrine_Access
*/ */
public function addListener($listener, $name = null) public function addListener($listener, $name = null)
{ {
$this->_table->addListener($listener, $name = null); $this->_table->addRecordListener($listener, $name = null);
return $this; return $this;
} }
@ -51,7 +51,7 @@ abstract class Doctrine_Record_Abstract extends Doctrine_Access
*/ */
public function getListener() public function getListener()
{ {
return $this->_table->getListener(); return $this->_table->getRecordListener();
} }
/** /**
* setListener * setListener
@ -61,7 +61,7 @@ abstract class Doctrine_Record_Abstract extends Doctrine_Access
*/ */
public function setListener($listener) public function setListener($listener)
{ {
$this->_table->setListener($listener); $this->_table->setRecordListener($listener);
return $this; return $this;
} }

View File

@ -33,7 +33,7 @@ Doctrine::autoload('Doctrine_Access');
* @since 1.0 * @since 1.0
* @version $Revision$ * @version $Revision$
*/ */
class Doctrine_Record_Listener_Chain extends Doctrine_Access implements Doctrine_EventListener_Interface class Doctrine_Record_Listener_Chain extends Doctrine_Access implements Doctrine_Record_Listener_Interface
{ {
/** /**
* @var array $listeners an array containing all listeners * @var array $listeners an array containing all listeners
@ -49,10 +49,10 @@ class Doctrine_Record_Listener_Chain extends Doctrine_Access implements Doctrine
*/ */
public function add($listener, $name = null) public function add($listener, $name = null)
{ {
if ( ! ($listener instanceof Doctrine_EventListener_Interface) && if ( ! ($listener instanceof Doctrine_Record_Listener_Interface) &&
! ($listener instanceof Doctrine_Overloadable)) { ! ($listener instanceof Doctrine_Overloadable)) {
throw new Doctrine_EventListener_Exception("Couldn't add eventlistener. EventListeners should implement either Doctrine_EventListener_Interface or Doctrine_Overloadable"); throw new Doctrine_EventListener_Exception("Couldn't add eventlistener. Record listeners should implement either Doctrine_EventListener_Interface or Doctrine_Overloadable");
} }
if ($name === null) { if ($name === null) {
$this->_listeners[] = $listener; $this->_listeners[] = $listener;

View File

@ -30,7 +30,7 @@
* @version $Revision$ * @version $Revision$
* @author Konsta Vesterinen <kvesteri@cc.hut.fi> * @author Konsta Vesterinen <kvesteri@cc.hut.fi>
*/ */
abstract class Doctrine_Relation abstract class Doctrine_Relation implements ArrayAccess
{ {
/** /**
* RELATION CONSTANTS * RELATION CONSTANTS
@ -157,6 +157,32 @@ abstract class Doctrine_Relation
{ {
return $this->definition['equal']; return $this->definition['equal'];
} }
public function offsetExists($offset)
{
return isset($this->definition[$offset]);
}
public function offsetGet($offset)
{
if (isset($this->definition[$offset])) {
return $this->definition[$offset];
}
return null;
}
public function offsetSet($offset, $value)
{
if (isset($this->definition[$offset])) {
$this->definition[$offset] = $value;
}
}
public function offsetUnset($offset)
{
$this->definition[$offset] = false;
}
/** /**
* toArray * toArray
* *

View File

@ -37,17 +37,26 @@ class Doctrine_Search
public function __construct(array $options) public function __construct(array $options)
{ {
$this->_options = array_merge($this->_options, $options); $this->_options = array_merge($this->_options, $options);
if ( ! isset($this->_options['analyzer'])) {
$this->_options['analyzer'] = new Doctrine_Search_Analyzer_Standard();
}
} }
public function getOption($option) public function getOption($option)
{ {
if (isset($this->_options[$option])) { if (isset($this->_options[$option])) {
return $this->_option[$option]; return $this->_options[$option];
} }
return null; return null;
} }
public function analyze($text)
{
return $this->_options['analyzer']->analyze($text);
}
public function setOption($option, $value) public function setOption($option, $value)
{ {
$this->_options[$option] = $value; $this->_options[$option] = $value;

View File

@ -32,14 +32,261 @@
*/ */
class Doctrine_Search_Analyzer_Standard implements Doctrine_Search_Analyzer_Interface class Doctrine_Search_Analyzer_Standard implements Doctrine_Search_Analyzer_Interface
{ {
protected static $_stopwords = array(
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'a',
'about',
'after',
'all',
'almost',
'along',
'also',
'amp',
'an',
'and',
'another',
'any',
'are',
'area',
'around',
'as',
'at',
'available',
'back',
'be',
'because',
'been',
'being',
'best',
'better',
'big',
'bit',
'both',
'but',
'by',
'c',
'came',
'can',
'capable',
'control',
'could',
'course',
'd',
'dan',
'day',
'decided',
'did',
'didn',
'different',
'div',
'do',
'doesn',
'don',
'down',
'drive',
'e',
'each',
'easily',
'easy',
'edition',
'end',
'enough',
'even',
'every',
'example',
'few',
'find',
'first',
'for',
'found',
'from',
'get',
'go',
'going',
'good',
'got',
'gt',
'had',
'hard',
'has',
'have',
'he',
'her',
'here',
'how',
'i',
'if',
'in',
'into',
'is',
'isn',
'it',
'just',
'know',
'last',
'left',
'li',
'like',
'little',
'll',
'long',
'look',
'lot',
'lt',
'm',
'made',
'make',
'many',
'mb',
'me',
'menu',
'might',
'mm',
'more',
'most',
'much',
'my',
'name',
'nbsp',
'need',
'new',
'no',
'not',
'now',
'number',
'of',
'off',
'old',
'on',
'one',
'only',
'or',
'original',
'other',
'our',
'out',
'over',
'part',
'place',
'point',
'pretty',
'probably',
'problem',
'put',
'quite',
'quot',
'r',
're',
'really',
'results',
'right',
's',
'same',
'saw',
'see',
'set',
'several',
'she',
'sherree',
'should',
'since',
'size',
'small',
'so',
'some',
'something',
'special',
'still',
'stuff',
'such',
'sure',
'system',
't',
'take',
'than',
'that',
'the',
'their',
'them',
'then',
'there',
'these',
'they',
'thing',
'things',
'think',
'this',
'those',
'though',
'through',
'time',
'to',
'today',
'together',
'too',
'took',
'two',
'up',
'us',
'use',
'used',
'using',
've',
'very',
'want',
'was',
'way',
'we',
'well',
'went',
'were',
'what',
'when',
'where',
'which',
'while',
'white',
'who',
'will',
'with',
'would',
'you',
'your',
);
public function analyze($text) public function analyze($text)
{ {
$text = explode(' ', $text); $text = preg_replace('/[.()&#!,]/', ' ', $text);
$text = str_replace(' ', ' ', $text);
foreach ($text as $i => $term) {
$text[$i] = strtolower(trim($term));
}
return $text; $terms = explode(' ', $text);
$ret = array();
if ( ! empty($terms)) {
foreach ($terms as $i => $term) {
if (empty($term)) {
continue;
}
$lower = strtolower(trim($term));
if (in_array($lower, self::$_stopwords)) {
continue;
}
$pos = strpos($text, $term);
$ret[$pos] = $lower;
}
}
return $ret;
} }
} }

View File

@ -47,21 +47,27 @@ class Doctrine_Search_Listener extends Doctrine_Record_Listener
{ {
} }
public function preInsert(Doctrine_Event $event)
{
}
public function postInsert(Doctrine_Event $event) public function postInsert(Doctrine_Event $event)
{ {
$fields = $this->_search->getOption('fields'); $fields = $this->_search->getOption('fields');
$class = $this->_search->getOption('className');
$record = $event->getInvoker();
$name = $record->getTable()->getComponentName();
foreach ($fields as $field) { foreach ($fields as $field) {
$terms = $this->_search->analyze($field); $data = $record->get($field);
foreach ($terms as $term) { $terms = $this->_search->analyze($data);
foreach ($terms as $pos => $term) {
$index = new $class();
$index->keyword = $term;
$index->position = $pos;
$index->field = $field;
$index->$name = $record;
$index->save();
} }
} }
} }

View File

@ -48,10 +48,10 @@ class Doctrine_Search_Template extends Doctrine_Template
$this->_search->setOption('className', $name); $this->_search->setOption('className', $name);
foreach ((array) $id as $column) { foreach ((array) $id as $column) {
$foreign[] = strtolower($name . '_' . $column); $foreign[] = strtolower($this->_table->getComponentName() . '_' . $column);
} }
$foreign = (count($foreign) > 1) ? array_keys($foreign) : key($foreign); $foreign = (count($foreign) > 1) ? $foreign : current($foreign);
$this->hasMany($name, array('local' => $id, 'foreign' => $foreign)); $this->hasMany($name, array('local' => $id, 'foreign' => $foreign));

View File

@ -0,0 +1,44 @@
<?php
/*
* $Id$
*
* 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_Import_Builder_TestCase
*
* @package Doctrine
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
*/
class Doctrine_Import_Builder_TestCase extends Doctrine_UnitTestCase
{
public function testBuildingOfRecord()
{
$table = $this->conn->getTable('Phonenumber');
$builder = new Doctrine_Import_Builder();
$rel = $builder->buildRelationDefinition($table->getRelations());
}
}

View File

@ -54,7 +54,6 @@ class Doctrine_Query_Having_TestCase extends Doctrine_UnitTestCase
$q = new Doctrine_Query(); $q = new Doctrine_Query();
$q->parseQuery("SELECT CONCAT(u.name, u.loginname) name FROM User u LEFT JOIN u.Phonenumber p HAVING name = 'xx'"); $q->parseQuery("SELECT CONCAT(u.name, u.loginname) name FROM User u LEFT JOIN u.Phonenumber p HAVING name = 'xx'");
} }
} }

117
tests/SearchTestCase.php Normal file
View File

@ -0,0 +1,117 @@
<?php
/*
* $Id$
*
* 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_Search_TestCase
*
* @package Doctrine
* @author Konsta Vesterinen <kvesteri@cc.hut.fi>
* @license http://www.opensource.org/licenses/lgpl-license.php LGPL
* @category Object Relational Mapping
* @link www.phpdoctrine.com
* @since 1.0
* @version $Revision$
*/
class Doctrine_Search_TestCase extends Doctrine_UnitTestCase
{
public function prepareTables()
{
$this->tables = array('SearchTest', 'SearchTestIndex');
parent::prepareTables();
}
public function prepareData()
{ }
public function testBuildingOfSearchRecordDefinition()
{
$e = new SearchTest();
$this->assertTrue($e->SearchTestIndex instanceof Doctrine_Collection);
$rel = $e->getTable()->getRelation('SearchTestIndex');
$this->assertIdentical($rel->getLocal(), 'id');
$this->assertIdentical($rel->getForeign(), 'searchtest_id');
}
public function testSavingEntriesUpdatesIndex()
{
$e = new SearchTest();
$e->title = 'Once there was an ORM framework';
$e->content = 'There are many ORM frameworks, but nevertheless we decided to create one.';
$e->save();
}
public function testQuerying()
{
$q = new Doctrine_Query();
$q->select('t.title')
->from('SearchTest t')
->innerJoin('t.SearchTestIndex i')
->where('i.keyword = ?');
$array = $q->execute(array('orm'), Doctrine_Hydrate::HYDRATE_ARRAY);
$this->assertEqual($array[0]['title'], 'Once there was an ORM framework');
}
public function testQueryingReturnsEmptyArrayForStopKeyword()
{
$q = new Doctrine_Query();
$q->select('t.title')
->from('SearchTest t')
->innerJoin('t.SearchTestIndex i')
->where('i.keyword = ?');
$array = $q->execute(array('was'), Doctrine_Hydrate::HYDRATE_ARRAY);
$this->assertEqual(count($array), 0);
}
public function testQueryingReturnsEmptyArrayForUnknownKeyword()
{
$q = new Doctrine_Query();
$q->select('t.title')
->from('SearchTest t')
->innerJoin('t.SearchTestIndex i')
->where('i.keyword = ?');
$array = $q->execute(array('someunknownword'), Doctrine_Hydrate::HYDRATE_ARRAY);
$this->assertEqual(count($array), 0);
}
}
class SearchTest extends Doctrine_Record
{
public function setTableDefinition()
{
$this->hasColumn('title', 'string', 100);
$this->hasColumn('content', 'string');
}
public function setUp()
{
$options = array('generateFiles' => false,
'fields' => array('title', 'content'));
$this->loadTemplate('Doctrine_Search_Template', $options);
}
}

View File

@ -70,7 +70,7 @@ $test = new GroupTest('Doctrine Framework Unit Tests');
$test->addTestCase(new Doctrine_Ticket330_TestCase()); $test->addTestCase(new Doctrine_Ticket330_TestCase());
*/ */
/** */
// Connection drivers (not yet fully tested) // Connection drivers (not yet fully tested)
$test->addTestCase(new Doctrine_Connection_Pgsql_TestCase()); $test->addTestCase(new Doctrine_Connection_Pgsql_TestCase());
$test->addTestCase(new Doctrine_Connection_Oracle_TestCase()); $test->addTestCase(new Doctrine_Connection_Oracle_TestCase());
@ -322,9 +322,11 @@ $test->addTestCase(new Doctrine_Cache_Sqlite_TestCase());
$test->addTestCase(new Doctrine_Record_SaveBlankRecord_TestCase()); $test->addTestCase(new Doctrine_Record_SaveBlankRecord_TestCase());
$test->addTestCase(new Doctrine_Template_TestCase()); $test->addTestCase(new Doctrine_Template_TestCase());
$test->addTestCase(new Doctrine_Import_Builder_TestCase());
$test->addTestCase(new Doctrine_Search_TestCase());
//$test->addTestCase(new Doctrine_IntegrityAction_TestCase()); //$test->addTestCase(new Doctrine_IntegrityAction_TestCase());
//$test->addTestCase(new Doctrine_AuditLog_TestCase()); //$test->addTestCase(new Doctrine_AuditLog_TestCase());