私のアプリには1つのプライマリデータベースと多くのセカンダリデータベースがあります。データベースごとに2GBの制限があるため、複数のデータベースが必要です。
データは、メインデータベースと多くのセカンダリデータベースの1つに保存する必要があります。プライマリデータベースから、データを保存するセカンダリデータベースがわかります。
私のデータベースは同一ではなく、小さな違いがあります。メインデータベース用のモデルとセカンダリデータベース用の別のモデルを作成しました。
これはエラーです:
CException
SlaveUrl and its behaviors do not have a method or closure named "findByUrl".
これは私が再び戦っているラインです:
$record = SlaveUrl::model()->findByUrl($query);
そしてそれはこのコードにあります:
<?php
class ScannerCommand extends CConsoleCommand {
private $time;
private $urls = 0;
/**
* Executes the command.
* @param array command line parameters for this command.
*/
public function run($args) {
// $args gives an array of the command-line arguments for this command
$this->time = time();
$instance_scanner = new InstanceScanner();
$instance_scanner->create = $this->time;
$instance_scanner->urls = 0;
if ($instance_scanner->save()) {
echo 'scanner start' . PHP_EOL;
$criteria = new CDbCriteria();
$criteria->condition = 'status=:status';
$criteria->order = '`update` asc';
$criteria->limit = 1;
$criteria->params = array(':status' => 1);
$model_website = Website::model()->find($criteria);
$model_website->update = $this->time;
$model_website->save();
echo 'scanning ' . $model_website->name . ' ... ' . PHP_EOL;
$model_pattern_url = PatternUrl::model()->findByAttributes(array('website_id' => $model_website->id));
//$website_file_content = file_get_contents($model_website->link);
$website_file_content = CurlTool::fetchContent($model_website->link,array(),true);
preg_match_all('/<a href=[\'"](.*?)[\'"].*?>([^<]+)<\/a>/ims', $website_file_content, $matches_url);
if ((is_array($matches_url[0])) && (count($matches_url[0]) > 0))
foreach ($matches_url[0] as $key => $value) {
$ok = false;
preg_match_all($model_pattern_url->pattern, $matches_url[1][$key], $matches_pattern_url);
//print_r($matches_pattern_url);
if ((is_array($matches_pattern_url)) && (count($matches_pattern_url[0]) > 0))
if (strpos($matches_url[1][$key], $matches_pattern_url[0][0]) !== false)
$ok = true;
SlaveUrl::$server_id = $model_website->server_id;
echo $query = "select * from `url` where ( ( `website_id`='".($model_website->id)."' ) and ( `link`='".($matches_url[1][$key])."' ) ) or ( ( `website_id`='".($model_website->id)."' ) and ( `name` = '".(addslashes($matches_url[2][$key]))."' ) );";
$record = SlaveUrl::model()->findByUrl($query);
if( $record == null )
{
$model_slave_url = new SlaveUrl();
$model_slave_url->website_id = $model_website->server_id;
$model_slave_url->link = $matches_url[1][$key];
$model_slave_url->name = $matches_url[2][$key];
$model_slave_url->created = time();
$model_slave_url->status = 1;
if( $model_slave_url->save() )
{
//$data = Url::model()->findByAttributes(array('website_id' => $model_website->id, 'link' => $matches_url[1][$key], 'name' => $matches_url[2][$key]));
$query = "select * from `url` where ( ( `website_id`='".($model_website->id)."' ) and ( `link`='".($matches_url[1][$key])."' ) ) or ( ( `website_id`='".($model_website->id)."' ) and ( `name` = '".(addslashes($matches_url[2][$key]))."' ) );";
echo $query.'<br>';
//$command_slave = ;
$command = Yii::app()->db->createCommand($query);
$data = $command->queryAll();
if((count($data)==0) && ($ok === true)) {
$model_url = new Url();
$model_url->website_id = $model_website->id;
$model_url->link = $matches_url[1][$key];
$model_url->name = $matches_url[2][$key];
$model_url->created = $this->time;
$model_url->instance_scanner_id = $instance_scanner->id;
$model_url->status = 0;
if ($model_url->save())
$this->urls++;
$command = "INSERT INTO `url` (`id` ,`website_id` ,`link` ,`name` ,`created` ,`instance_scanner_id` ,`status`)VALUES (NULL , '".($model_url->website_id)."', '".($model_url->link)."', '".(addslashes($model_url->name))."', '".($model_url->created)."', '".($model_url->instance_scanner_id)."', '".($model_url->status)."');";
}
}
}
}
echo $this->urls . ' new urls found' . PHP_EOL;
$instance_scanner->urls = $this->urls;
$instance_scanner->save();
echo 'scanner stop';
}
else echo 'something went wrong while trying to start the scanning process';
}
/**
* Provides the command description.
* This method may be overridden to return the actual command description.
* @return string the command description. Defaults to 'Usage: php entry-script.php command-name'.
*/
public function getHelp() {
return 'Usage: how to use this command';
}
}
これがメインモデルです。
<?php
/**
* This is the model class for table "url".
*
* The followings are the available columns in table 'url':
* @property string $id
* @property integer $server_id
* @property integer $website_id
* @property integer $slave_url_id
* @property string $link
* @property string $name
* @property integer $created
* @property integer $instance_scanner_id
* @property integer $status
*/
class Url extends CActiveRecord
{
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Url the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'url';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('server_id, website_id, slave_url_id, link, name, created, instance_scanner_id, status', 'required'),
array('server_id, website_id, slave_url_id, created, instance_scanner_id, status', 'numerical', 'integerOnly'=>true),
array('link, name', 'length', 'max'=>255),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, server_id, website_id, slave_url_id, link, name, created, instance_scanner_id, status', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'server_id' => 'Server',
'website_id' => 'Website',
'slave_url_id' => 'Slave Url',
'link' => 'Link',
'name' => 'Name',
'created' => 'Created',
'instance_scanner_id' => 'Instance Scanner',
'status' => 'Status',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id,true);
$criteria->compare('server_id',$this->server_id);
$criteria->compare('website_id',$this->website_id);
$criteria->compare('slave_url_id',$this->slave_url_id);
$criteria->compare('link',$this->link,true);
$criteria->compare('name',$this->name,true);
$criteria->compare('created',$this->created);
$criteria->compare('instance_scanner_id',$this->instance_scanner_id);
$criteria->compare('status',$this->status);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
これはスレーブモデルです。
<?php
/**
* This is the model class for table "url".
*
* The followings are the available columns in table 'url':
* @property string $id
* @property integer $website_id
* @property string $link
* @property string $name
* @property integer $created
* @property integer $status
*/
class SlaveUrl extends HActiveRecord
{
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Url the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
return 'url';
}
/**
* @return array validation rules for model attributes.
*/
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('website_id, link, name, created, status', 'required'),
array('website_id, created, status', 'numerical', 'integerOnly'=>true),
array('link, name', 'length', 'max'=>255),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, website_id, link, name, created, status', 'safe', 'on'=>'search'),
);
}
/**
* @return array relational rules.
*/
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'relation_website'=>array(self::BELONGS_TO,'Website','website_id'),
);
}
/**
* @return array customized attribute labels (name=>label)
*/
public function attributeLabels()
{
return array(
'id' => 'ID',
'website_id' => 'Website',
'link' => 'Link',
'name' => 'Name',
'created' => 'Created',
'status' => 'Status',
);
}
/**
* Retrieves a list of models based on the current search/filter conditions.
* @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
*/
public function search()
{
// Warning: Please modify the following code to remove attributes that
// should not be searched.
$criteria=new CDbCriteria;
$criteria->compare('id',$this->id,true);
$criteria->compare('website_id',$this->website_id);
$criteria->compare('link',$this->link,true);
$criteria->compare('name',$this->name,true);
$criteria->compare('created',$this->created);
$criteria->compare('status',$this->status);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
}
適切なスレーブDB接続を割り当てる特別なクラスと一緒に:
<?php
class HActiveRecord extends CActiveRecord
{
public static $server_id=1;
public static $master_db;
public function getDbConnection()
{
self::$master_db=Yii::app()->{"db".self::$server_id};
if(self::$master_db instanceof CDbConnection)
{
self::$master_db->setActive(true);
return self::$master_db;
}
else
throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));
}
public function getDbConnection2()
{
if(self::$master_db!==null)
return self::$master_db;
else
{
self::$master_db=Yii::app()->db1;
echo self::$master_db->connectionString;
if(self::$master_db instanceof CDbConnection)
{
self::$master_db->setActive(true);
return self::$master_db;
}
else
throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));
}
}
}
?>