summaryrefslogtreecommitdiff
path: root/framework/web/CSqlDataProvider.php
diff options
context:
space:
mode:
Diffstat (limited to 'framework/web/CSqlDataProvider.php')
-rw-r--r--framework/web/CSqlDataProvider.php132
1 files changed, 132 insertions, 0 deletions
diff --git a/framework/web/CSqlDataProvider.php b/framework/web/CSqlDataProvider.php
new file mode 100644
index 0000000..bd2c926
--- /dev/null
+++ b/framework/web/CSqlDataProvider.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ * CSqlDataProvider implements a data provider based on a plain SQL statement.
+ *
+ * CSqlDataProvider provides data in terms of arrays, each representing a row of query result.
+ *
+ * Like other data providers, CSqlDataProvider also supports sorting and pagination.
+ * It does so by modifying the given {@link sql} statement with "ORDER BY" and "LIMIT"
+ * clauses. You may configure the {@link sort} and {@link pagination} properties to
+ * customize sorting and pagination behaviors.
+ *
+ * CSqlDataProvider may be used in the following way:
+ * <pre>
+ * $count=Yii::app()->db->createCommand('SELECT COUNT(*) FROM tbl_user')->queryScalar();
+ * $sql='SELECT * FROM tbl_user';
+ * $dataProvider=new CSqlDataProvider($sql, array(
+ * 'totalItemCount'=>$count,
+ * 'sort'=>array(
+ * 'attributes'=>array(
+ * 'id', 'username', 'email',
+ * ),
+ * ),
+ * 'pagination'=>array(
+ * 'pageSize'=>10,
+ * ),
+ * ));
+ * // $dataProvider->getData() will return a list of arrays.
+ * </pre>
+ *
+ * Note: if you want to use the pagination feature, you must configure the {@link totalItemCount} property
+ * to be the total number of rows (without pagination). And if you want to use the sorting feature,
+ * you must configure {@link sort} property so that the provider knows which columns can be sorted.
+ *
+ * @author Qiang Xue <qiang.xue@gmail.com>
+ * @version $Id: CSqlDataProvider.php 2820 2011-01-06 17:15:56Z mdomba $
+ * @package system.web
+ * @since 1.1.4
+ */
+class CSqlDataProvider extends CDataProvider
+{
+ /**
+ * @var CDbConnection the database connection to be used in the queries.
+ * Defaults to null, meaning using Yii::app()->db.
+ */
+ public $db;
+ /**
+ * @var string the SQL statement to be used for fetching data rows.
+ */
+ public $sql;
+ /**
+ * @var array parameters (name=>value) to be bound to the SQL statement.
+ */
+ public $params=array();
+ /**
+ * @var string the name of key field. Defaults to 'id'.
+ */
+ public $keyField='id';
+
+ /**
+ * Constructor.
+ * @param string $sql the SQL statement to be used for fetching data rows.
+ * @param array $config configuration (name=>value) to be applied as the initial property values of this class.
+ */
+ public function __construct($sql,$config=array())
+ {
+ $this->sql=$sql;
+ foreach($config as $key=>$value)
+ $this->$key=$value;
+ }
+
+ /**
+ * Fetches the data from the persistent data storage.
+ * @return array list of data items
+ */
+ protected function fetchData()
+ {
+ $sql=$this->sql;
+ $db=$this->db===null ? Yii::app()->db : $this->db;
+ $db->active=true;
+
+ if(($sort=$this->getSort())!==false)
+ {
+ $order=$sort->getOrderBy();
+ if(!empty($order))
+ {
+ if(preg_match('/\s+order\s+by\s+[\w\s,]+$/i',$sql))
+ $sql.=', '.$order;
+ else
+ $sql.=' ORDER BY '.$order;
+ }
+ }
+
+ if(($pagination=$this->getPagination())!==false)
+ {
+ $pagination->setItemCount($this->getTotalItemCount());
+ $limit=$pagination->getLimit();
+ $offset=$pagination->getOffset();
+ $sql=$db->getCommandBuilder()->applyLimit($sql,$limit,$offset);
+ }
+
+ $command=$db->createCommand($sql);
+ foreach($this->params as $name=>$value)
+ $command->bindValue($name,$value);
+
+ return $command->queryAll();
+ }
+
+ /**
+ * Fetches the data item keys from the persistent data storage.
+ * @return array list of data item keys.
+ */
+ protected function fetchKeys()
+ {
+ $keys=array();
+ foreach($this->getData() as $i=>$data)
+ $keys[$i]=$data[$this->keyField];
+ return $keys;
+ }
+
+ /**
+ * Calculates the total number of data items.
+ * This method is invoked when {@link getTotalItemCount()} is invoked
+ * and {@link totalItemCount} is not set previously.
+ * The default implementation simply returns 0.
+ * You may override this method to return accurate total number of data items.
+ * @return integer the total number of data items.
+ */
+ protected function calculateTotalItemCount()
+ {
+ return 0;
+ }
+}