CActiveRecord союзы
У меня есть несколько таблиц в среде MySQL. Я использую Yii, поэтому я хотел добавить поддержку шардинга. Мне удалось создать пользовательский класс CActiveRecord, который будет матерью для всех моделей с сегрегами:
class ShardedActiveRecord extends CActiveRecord{
private $_shard;
public function tableName(){
return get_class($this) . $this->getShard();
}
public function setShard($shard) {
$this->_shard = $shard;
call_user_func(array(get_class($this), 'model'))->_shard = $shard;
$this->refreshMetaData();
return $this;
}
public function getShard() {
if($this->_shard === null){
$this->setShard("");
}
return $this->_shard;
}
public function createShardedTable($shard){
$connection=Yii::app()->db;
$command = $connection->createCommand("CREATE TABLE IF NOT EXISTS ".get_class($this).$shard." LIKE ".get_class($this));
$command->execute();
}
}
Все отлично работает при вставке, но когда мне нужно получить некоторые данные, я не знаю, как поступить. Я хотел бы, чтобы в моей модели был параметр, который будет объединять сегментированные таблицы. Вот пример того, что я хотел бы сделать возможным:
MyModel:: модель ()-> осколок ("01,"02",03")-> FindAll();
И в конце концов, чтобы вернуть последние 3 таблицы:
$ data = new CActiveDataProvider ("MyModel")
Sql для получения данных shoold выглядит следующим образом, если я хочу выбрать первые 3 таблицы:
SELECT * FROM stats01
UNION SELECT * FROM stats02
UNION SELECT * FROM stats03
Я попытался переопределить функцию fetchData(), но она не сработала, переопределенная функция не изменяла набор данных... Мне нужно, чтобы все данные были в виде одного большого блока, как если бы это была одна таблица.
Спасибо!
1 ответ
Обновить:
Я нашел решение проблемы. Я создал функцию в своем классе ShardedActiveRecord, которая генерирует пользовательский CActiveRecord и возвращает его. Вот как это выглядит:
public function getMergedDataProvider($back){
$modelArray = array();
$model = array();
$now = date("Ym");
for($i=0; $i<$back; $i++){
array_push($modelArray, $this->model()->setShard(date("Ym", strtotime("-".$i." month", strtotime($now))))->findAll());
}
foreach($modelArray as $ma){
$model = array_merge($model, $ma);
}
$dataProvider = new CActiveDataProvider(get_class($this), array(
'data'=>$model,
));
return $dataProvider;
}
Я добавил параметр, который позволит мне получить последние 3 осколка таблицы (они относятся к дате).
В действии, которое требует использования изолированной модели, я могу вызвать функцию как таковую и использовать ее как обычный CActiveDataProvider:
$ dataProvider = MyModel:: model () -> getMergedDataProvider (3);
Я надеюсь, что это поможет кому-то!