From 826a0ceb950872bb311addd24c1a8da76a1cccc6 Mon Sep 17 00:00:00 2001 From: wei <> Date: Mon, 19 Feb 2007 02:23:19 +0000 Subject: Add trace to active records and TDbCommand --- .../ActiveRecord/Scaffold/TScaffoldEditView.php | 11 ++-- .../ActiveRecord/Scaffold/TScaffoldListView.php | 77 +++++++++++++++++++++- framework/Data/ActiveRecord/TActiveRecord.php | 12 +++- .../Data/ActiveRecord/TActiveRecordCriteria.php | 5 ++ .../Data/ActiveRecord/TActiveRecordGateway.php | 14 +++- framework/Data/ActiveRecord/Vendor/TDbMetaData.php | 13 +++- 6 files changed, 123 insertions(+), 9 deletions(-) (limited to 'framework/Data/ActiveRecord') diff --git a/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php b/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php index a792aeb9..14b4098a 100644 --- a/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php +++ b/framework/Data/ActiveRecord/Scaffold/TScaffoldEditView.php @@ -17,9 +17,11 @@ Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase'); /** * Template control for editing an Active Record instance. + * The RecordClass determines the Active Record class to be edited. + * A particular record can be edited by specifying the {@link setRecordPk RecordPk} + * value (may be an array for composite keys). * * The default editor input controls are created based on the column types. - * * The editor layout can be specified by a renderer. A renderer is an external * template control that implements IScaffoldEditRenderer. * @@ -33,9 +35,10 @@ Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase'); * (the edit view instance is the Parent of the IScaffoldEditRenderer in most * cases. * - * The RecordClass determines the Active Record class to be edited. - * A particular record can be edited by specifying the {@link setRecordPk RecordPk} - * value (may be an array for composite keys). + * Cosmetic changes to the default editor should be done using Cascading Stylesheets. + * For example, a particular field/property can be hidden by specifying "display:none" for + * the corresponding style (each field/property has unique Css class name as "property_xxx", where + * xxx is the property name). * * @author Wei Zhuo * @version $Id$ diff --git a/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php b/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php index 2ac3fe99..62bf351b 100644 --- a/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php +++ b/framework/Data/ActiveRecord/Scaffold/TScaffoldListView.php @@ -16,7 +16,15 @@ Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase'); /** - * TScaffoldListView displays instance of Active Record class. + * TScaffoldListView displays a list of Active Records. + * + * The {@link getHeader Header} property is a TRepeater displaying the + * Active Record property/field names. The {@link getSort Sort} property + * is a drop down list displaying the combination of properties and its possible + * ordering. The {@link getPager Pager} property is a TPager control that + * determines the number of records display in one page (e.g. Page.. + * + * * * @author Wei Zhuo * @version $Id$ @@ -25,6 +33,9 @@ Prado::using('System.Data.ActiveRecord.Scaffold.TScaffoldBase'); */ class TScaffoldListView extends TScaffoldBase { + /** + * Initialize the sort drop down list in non post back mode (i.e. GET requests). + */ public function onLoad($param) { parent::onLoad($param); @@ -32,6 +43,9 @@ class TScaffoldListView extends TScaffoldBase $this->initializeSort(); } + /** + * Initialize the sort drop down list and the column names repeater. + */ protected function initializeSort() { $table = $this->getTableMetaData(); @@ -50,12 +64,18 @@ class TScaffoldListView extends TScaffoldBase $this->_header->dataBind(); } + /** + * Loads and display the data. + */ public function onPreRender($param) { parent::onPreRender($param); $this->loadRecordData(); } + /** + * Fetch the records and data bind it to the list. + */ protected function loadRecordData() { $this->_list->setVirtualItemCount($this->getRecordFinder()->count()); @@ -65,6 +85,9 @@ class TScaffoldListView extends TScaffoldBase $this->_list->dataBind(); } + /** + * @return TActiveRecordCriteria sort/search/paging criteria + */ protected function getRecordCriteria() { $total = $this->_list->getVirtualItemCount(); @@ -81,26 +104,41 @@ class TScaffoldListView extends TScaffoldBase return $criteria; } + /** + * @param string search condition, the SQL string after the WHERE clause. + */ public function setSearchCondition($value) { $this->setViewState('SearchCondition', $value); } + /** + * @param string SQL search condition for list display. + */ public function getSearchCondition() { return $this->getViewState('SearchCondition'); } + /** + * @param array search parameters + */ public function setSearchParameters($value) { $this->setViewState('SearchParameters', TPropertyValue::ensureArray($value),array()); } + /** + * @return array search parameters + */ public function getSearchParameters() { return $this->getViewState('SearchParameters', array()); } + /** + * Continue bubbling the "edit" command, "delete" command is handled in this class. + */ public function bubbleEvent($sender, $param) { switch(strtolower($param->getCommandName())) @@ -114,6 +152,9 @@ class TScaffoldListView extends TScaffoldBase return true; } + /** + * Initialize the edit view control form when EditViewID is set. + */ protected function initializeEdit($sender, $param) { if(($ctrl=$this->getEditViewControl())!==null) @@ -127,6 +168,9 @@ class TScaffoldListView extends TScaffoldBase } } + /** + * Deletes an Active Record. + */ protected function deleteRecord($sender, $param) { if($param instanceof TRepeaterCommandEventParameter) @@ -136,6 +180,9 @@ class TScaffoldListView extends TScaffoldBase } } + /** + * Initialize the default display for each Active Record item. + */ protected function listItemCreated($sender, $param) { $item = $param->getItem(); @@ -147,6 +194,10 @@ class TScaffoldListView extends TScaffoldBase } } + /** + * Sets the Record primary key to the current repeater item's CustomData. + * Binds the inner repeater with properties of the current Active Record. + */ protected function populateField($sender, $param) { $item = $param->getItem(); @@ -161,45 +212,69 @@ class TScaffoldListView extends TScaffoldBase } } + /** + * Updates repeater page index with the pager new index value. + */ protected function pageChanged($sender, $param) { $this->_list->setCurrentPageIndex($param->getNewPageIndex()); } + /** + * @return TRepeater Repeater control for Active Record instances. + */ public function getList() { $this->ensureChildControls(); return $this->getRegisteredObject('_list'); } + /** + * @return TPager List pager control. + */ public function getPager() { $this->ensureChildControls(); return $this->getRegisteredObject('_pager'); } + /** + * @return TDropDownList Control that displays and controls the record ordering. + */ public function getSort() { $this->ensureChildControls(); return $this->getRegisteredObject('_sort'); } + /** + * @return TRepeater Repeater control for record property names. + */ public function getHeader() { $this->ensureChildControls(); return $this->getRegisteredObject('_header'); } + /** + * @return string TScaffoldEditView control ID for editing selected Active Record. + */ public function getEditViewID() { return $this->getViewState('EditViewID'); } + /** + * @param string TScaffoldEditView control ID for editing selected Active Record. + */ public function setEditViewID($value) { $this->setViewState('EditViewID', $value); } + /** + * @return TScaffoldEditView control for editing selected Active Record, null if EditViewID is not set. + */ protected function getEditViewControl() { if(($id=$this->getEditViewID())!==null) diff --git a/framework/Data/ActiveRecord/TActiveRecord.php b/framework/Data/ActiveRecord/TActiveRecord.php index bdb03596..ea33035d 100644 --- a/framework/Data/ActiveRecord/TActiveRecord.php +++ b/framework/Data/ActiveRecord/TActiveRecord.php @@ -171,6 +171,16 @@ abstract class TActiveRecord extends TComponent * @return boolean true if record was saved successfully, false otherwise. */ public function save() + { + $this->commitChanges(); + } + + /** + * Commit changes to the record, may insert, update or delete depending + * on the record state given in TObjectStateRegistery. + * @return boolean true if changes were made. + */ + protected function commitChanges() { $registry = $this->getRecordManager()->getObjectStateRegistry(); $gateway = $this->getRecordManager()->getRecordGateway(); @@ -190,7 +200,7 @@ abstract class TActiveRecord extends TComponent { $registry = $this->getRecordManager()->getObjectStateRegistry(); $registry->registerRemoved($this); - return $this->save(); + return $this->commitChanges(); } /** diff --git a/framework/Data/ActiveRecord/TActiveRecordCriteria.php b/framework/Data/ActiveRecord/TActiveRecordCriteria.php index 968a2691..6adfe4ce 100644 --- a/framework/Data/ActiveRecord/TActiveRecordCriteria.php +++ b/framework/Data/ActiveRecord/TActiveRecordCriteria.php @@ -153,6 +153,11 @@ class TActiveRecordCriteria extends TComponent { return $this->getCondition(); } + + public function repr() + { + return var_export($this->getParameters()->toArray(),true); + } } ?> \ No newline at end of file diff --git a/framework/Data/ActiveRecord/TActiveRecordGateway.php b/framework/Data/ActiveRecord/TActiveRecordGateway.php index 7bcd0eb2..1486e9c3 100644 --- a/framework/Data/ActiveRecord/TActiveRecordGateway.php +++ b/framework/Data/ActiveRecord/TActiveRecordGateway.php @@ -143,11 +143,12 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getFindByPkCommand($record->getDbConnection(),$keys); $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$keys); + Prado::trace(get_class($record).'::FindRecordByPk('.var_export($keys,true).')', 'System.Data.ActiveRecord'); return $meta->postQueryRow($command->queryRow()); } /** - * Returns records matching the list of given primary keys. + * Returns records matching the list of given primary keys. * @param TActiveRecord active record instance. * @param array list of primary name value pairs * @return array matching data. @@ -157,9 +158,10 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getFindInPksCommand($record->getDbConnection(), $keys); $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$keys); + Prado::trace(get_class($record).'::FindRecordsByPks('.var_export($keys,true).')', 'System.Data.ActiveRecord'); return $meta->postQuery($command->query()); } - + /** * Returns record data matching the given critera. If $iterator is true, it will @@ -174,6 +176,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getFindByCriteriaCommand($record->getDbConnection(),$criteria); $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$criteria); + Prado::trace(get_class($record).'::FindRecordsByCriteria('.is_string($criteria) ? $criteria : $criteria->repr().')', 'System.Data.ActiveRecord'); return $iterator ? $meta->postQuery($command->query()) : $meta->postQueryRow($command->queryRow()); } @@ -189,6 +192,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getFindBySqlCommand($record->getDbConnection(),$sql,$parameters); $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$parameters); + Prado::trace(get_class($record).'::FindRecordsBySql('.var_export($parameters,true).')', 'System.Data.ActiveRecord'); return $meta->postQuery($command->query()); } @@ -203,6 +207,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getCountRecordsCommand($record->getDbConnection(),$criteria); $this->raiseCommandEvent(TActiveRecordStatementType::Select,$command,$record,$criteria); + Prado::trace(get_class($record).'::CountRecords('.is_string($criteria) ? $criteria : $criteria->repr().')', 'System.Data.ActiveRecord'); return intval($command->queryScalar()); } @@ -216,6 +221,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getInsertCommand($record->getDbConnection(),$record); $this->raiseCommandEvent(TActiveRecordStatementType::Insert,$command,$record); + Prado::trace(get_class($record).'::Insert()', 'System.Data.ActiveRecord'); $rowsAffected = $command->execute(); if($rowsAffected===1) $meta->updatePostInsert($record->getDbConnection(),$record); @@ -232,6 +238,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getUpdateCommand($record->getDbConnection(),$record); $this->raiseCommandEvent(TActiveRecordStatementType::Update,$command,$record); + Prado::trace(get_class($record).'::Update()', 'System.Data.ActiveRecord'); return $command->execute(); } @@ -245,6 +252,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getDeleteCommand($record->getDbConnection(),$record); $this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record); + Prado::trace(get_class($record).'::Delete()', 'System.Data.ActiveRecord'); return $command->execute(); } @@ -258,6 +266,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getDeleteByPkCommand($record->getDBConnection(),$keys); $this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record,$keys); + Prado::trace(get_class($record).'::DeleteRecordsByPk('.var_export($keys,true).')', 'System.Data.ActiveRecord'); return $command->execute(); } @@ -272,6 +281,7 @@ class TActiveRecordGateway extends TComponent $meta = $this->getMetaData($record); $command = $meta->getDeleteByCriteriaCommand($record->getDBConnection(),$criteria); $this->raiseCommandEvent(TActiveRecordStatementType::Delete,$command,$record,$criteria); + Prado::trace(get_class($record).'::DeleteRecordsByCriteria('.is_string($criteria) ? $criteria : $criteria->repr().')', 'System.Data.ActiveRecord'); return $command->execute(); } diff --git a/framework/Data/ActiveRecord/Vendor/TDbMetaData.php b/framework/Data/ActiveRecord/Vendor/TDbMetaData.php index 3a959ba4..a3a13120 100644 --- a/framework/Data/ActiveRecord/Vendor/TDbMetaData.php +++ b/framework/Data/ActiveRecord/Vendor/TDbMetaData.php @@ -212,15 +212,26 @@ abstract class TDbMetaData extends TComponent /** * Gets the columns that can be inserted into the database. + * Missing properties are assumed to be null. * @param TActiveRecord record object to be inserted. * @return array name value pairs of fields to be added. + * @throws TActiveRecordException if property is null and table column is + * defined as not null unless primary key column. */ protected function getInsertableColumns($record) { $columns = array(); foreach($this->getColumns() as $name=>$column) { - $value = $record->{$name}; + try + { + $value = $record->{$name}; + } + catch (TInvalidOperationException $e) //ignore missing properties + { + $value = null; + } + if($column->getNotNull() && $value===null && !$column->getIsPrimaryKey()) { throw new TActiveRecordException( -- cgit v1.2.3