How to set ActiveRecord table name dynamicly
#1
Posted 28 January 2012 - 11:40 AM
$ar = new ArTable();
$ar->setTable('table_abc');
$ar->find();
...
My problem is:
Follw Yii ActiveRecord Design, table name must be set when constructed, especially for ::model() static method, that's losting lost of flexibility.
#2
Posted 28 January 2012 - 12:10 PM
Looking for something like this?
public function actionSomething ($table){
$ar = new ArTable();
$ar->setTable($table);
$ar->find();
}
Open:
/project/?r=controller/something&table=users
and that will find everything from table users. Also, you can set default table by:
public function actionSomething ($table='some_table')
I hope that is what you are looking for.
#3
Posted 28 January 2012 - 12:21 PM
$ar = new ArTable();
This setTable(assumed) method:
$ar->setTable('shardding_table_1');
...
$ar->setTable('shardding_table_2');
...
will allow you to choose different sharding tables(set specific table name) after ArTable constructed.
Or can we assign table name to ArTable when it's constructed like:
$ar1 = new ArTable('shardding_table_1');
$ar2 = new ArTable('shardding_table_2');
That would be nice too, It's not realistic to creat every class file according to every shard_table which have the same database structure.
Or there is other way on current yii version? To set table name when ar class is initiating.
#4
Posted 28 January 2012 - 12:38 PM
public function tableName(){}Won't work. Because getting a sharding table name must have a sharding key passed into the tableName() function, unless we introduce an external dependency in tableName():
class ArTable extends CActiveRecord{
public $sharding_table;
public function tableName(){
if(!isset($this->sharding_table)){
global $sharding_table;
$this->sharding_table = $sharding_table;
}
return $this->sharding_table;
}
}
The execution flow is(Just prototyping):
$sharding_table = 'table_1';
$ar1 = new ArTable();
..then $ar1 is with table_1
$sharding_table = 'table_2';
$ar2 = new ArTable();
..then $ar2 is with table_2
Though it's workable but not secure
#5
Posted 28 January 2012 - 02:51 PM
http://www.yiiframew...le-inheritance/
#6
Posted 28 January 2012 - 07:58 PM
jellysandwich, on 28 January 2012 - 02:51 PM, said:
http://www.yiiframew...le-inheritance/
That still need to create specific classes for different shards in my point:(
#7
Posted 28 January 2012 - 07:59 PM
"The schema and table names may also be specified via constructor configuration directives, which override any default values specified with the $_name and $_schema properties. A schema specification given with the name directive overrides any value provided with the schema option."
http://framework.zen...d.db.table.html
which give flexibilities.
#8
Posted 29 January 2012 - 03:14 AM
kernel, on 28 January 2012 - 12:38 PM, said:
public function tableName(){}Won't work. Because getting a sharding table name must have a sharding key passed into the tableName() function, unless we introduce an external dependency in tableName():
class ArTable extends CActiveRecord{
public $sharding_table;
public function tableName(){
if(!isset($this->sharding_table)){
global $sharding_table;
$this->sharding_table = $sharding_table;
}
return $this->sharding_table;
}
}
The execution flow is(Just prototyping):
$sharding_table = 'table_1';
$ar1 = new ArTable();
..then $ar1 is with table_1
$sharding_table = 'table_2';
$ar2 = new ArTable();
..then $ar2 is with table_2
Though it's workable but not secure
Why should it be in such a strange manner? You don't need globals. Next code seem to be similar to what You need:
/**
* @property string $shard Shard defining suffix to be added to table name.
*/
class ShardedActiveRecord extends CActiveRecord
{
private $_shard;
public function tableName(){
return get_class($this) . '_' . $this->shard;
}
public function setShard($shard) {
$this->_shard = $shard;
return $this;
}
public function getShard() {
//Just to have meaningful default behavior
if($this->_shard === null){
$this->_shard = 1;
}
return $this->_shard;
}
}
class Model extends ShardedActiveRecord{
/**
* @static
* @return Model
*/
public static function model(){
return parent::model(__CLASS__);
}
}
$recordsFromShardOne = Model::model()->setShard(1)->findAll();
$model = new Model();
$model->shard = 2;
//do other stuff
#9
Posted 29 January 2012 - 04:12 AM
Yurko, on 29 January 2012 - 03:14 AM, said:
/**
* @property string $shard Shard defining suffix to be added to table name.
*/
class ShardedActiveRecord extends CActiveRecord
{
private $_shard;
public function tableName(){
return get_class($this) . '_' . $this->shard;
}
public function setShard($shard) {
$this->_shard = $shard;
return $this;
}
public function getShard() {
//Just to have meaningful default behavior
if($this->_shard === null){
$this->_shard = 1;
}
return $this->_shard;
}
}
class Model extends ShardedActiveRecord{
/**
* @static
* @return Model
*/
public static function model(){
return parent::model(__CLASS__);
}
}
$recordsFromShardOne = Model::model()->setShard(1)->findAll();
$model = new Model();
$model->shard = 2;
//do other stuffThe point is:
IN THE Process OF CActiveRecord initiation, the __construct() or ::model() method will call tableName() immediately to read the table meta info , which give no chance to call setShard($shard), you will have to
First:
$ar = new ShardedActiveRecord(); <- In this inside __construct() tableName() will be called before setShard($shard) take place
Then:
$ar->setShard($shard);
================
I not sure if set table name after new ShardedActiveRecord() will work, It's not tested yet.
#10
Posted 29 January 2012 - 04:23 AM
/**
* @property string $shard Shard defining suffix to be added to table name.
*/
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() {
//Just to have meaningful default behavior
if($this->_shard === null){
$this->setShard(1);
}
return $this->_shard;
}
}You may also play with getMetaData() and getTableSchema() to make it return different values depending on current tableName() value;
#11
Posted 29 January 2012 - 05:24 AM
#13
Posted 09 April 2012 - 03:03 AM
class AutoPay extends CActiveRecord
{
public $tname = '';
public function __construct($tname = '',$scenario='insert')
{
$this->tname = $tname;
parent::__construct($scenario='insert');
}
/**
* Returns the static model of the specified AR class.
* @param string $className active record class name.
* @return Pay the static model class
*/
public static function model($className=__CLASS__)
{
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName()
{
echo $this->tname;exit;
return '{{'.$this->tname.'}}';
}
error:Fatal error: Maximum function nesting level of '512' reached, aborting!
#14
Posted 18 May 2012 - 10:35 AM
and the same error :-)
private $tab = 'experiments';
/*
public function __construct($scenario) {
$this->tab = 'well_it_works';
parent::__construct($scenario); // chiamo il costruttore padre
}
*/
public function __construct($table = 'table_test',$scenario='search')
{
$this->tab = $table;
parent::__construct($scenario); // chiamo il costruttore padre
}
Fatal error: Allowed memory size of 1073741824 bytes exhausted (tried to allocate 261900 bytes) in /var/www/yii-1.1.9.r3527/framework/db/ar/CActiveRecord.php on line 48
Non preoccuparti, รจ dentro il monitor!Sapevi che cercando su google yii + "la funzione su cui stai impazzendo", trovi quasi sempre dei buoni indizi in italiano, per risolvere i tuoi problemi, senza perdere tempo a postare?

Help













