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);

Я надеюсь, что это поможет кому-то!

Другие вопросы по тегам