Yii Framework Forum: [EXTENSION] directmongosuite - Yii Framework Forum

Jump to content

  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

[EXTENSION] directmongosuite A collection of components for the mongoDB Rate Topic: ***** 1 Votes

#1 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 01 November 2011 - 05:09 PM

Please add comments here and not at the extension page: directmongosuite
0

#2 User is offline   yiqing95 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 599
  • Joined: 27-December 10
  • Location:china

Posted 01 November 2011 - 11:17 PM

View PostJoblo, on 01 November 2011 - 05:09 PM, said:

Please add comments here and not at the documentation page: directmongosuite


i am interested to this extension :lol: ; why don't you put it on google code or github or bitbucket ,
before download it i always to read the source code first . :D
0

#3 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 02 November 2011 - 03:41 AM

Why don't you download it from the extension page?
There is the directmongosuite.0.1.zip ready for download (only 22KB).

You don't have to install it if you don't want.
0

#4 User is offline   thaddeusmt 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 18
  • Joined: 14-October 09
  • Location:Utah

Posted 02 November 2011 - 08:31 PM

I get an error when I try to use the Clear Log function in the Log Viewer:

'CException' with message 'Property "EDMSLogViewer.db" is not
defined.' on line 254 of EDMSLogViewer.php.

Looks like you just need to re-implement the creation of the capped collection using your new DB connections.
0

#5 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 03 November 2011 - 01:50 AM

Thanks for the hint. Yes I forgot to implement the new DB connection on migrating.

Fixed and extension updated.
0

#6 User is offline   yiqing95 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 599
  • Joined: 27-December 10
  • Location:china

Posted 04 November 2011 - 11:15 PM

@joblo :

in EDMSQuery class this function has wrong result:

	public function findArray($criteria=array(),$select=array(),$sort=array(),$limit=null)
	{
	   	$result = array();

		$cursor = $this->findCursor($criteria,$select,$sort,$limit);

		if (!empty($cursor) && $cursor->count())
			foreach ($cursor as $id => $value)
			   $result[] = array();

		return $result;
	}

$result[] = array(); //you must do something wrong here :rolleyes:
may be it should be : $result[] = $value;
0

#7 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 05 November 2011 - 04:21 AM

Thanks yiqing95. Fixed and published as v0.1.2.

Added findCountBy and some minor changes.
0

#8 User is offline   yiqing95 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 599
  • Joined: 27-December 10
  • Location:china

Posted 06 November 2011 - 09:59 AM

@joblo:
this function in EDMSQuery should be modified to :
 public static function modelToArray($model)
    {
        if (method_exists($model, 'getAttributes'))
            return $model->getAttributes(); //set model attributes with no validation
        else
        { //assign the values to the public properties
            $class = new ReflectionClass(get_class($model));
            $attributes = array();
            foreach ($class->getProperties() as $property)
            {
                if ($property->isPublic() && !$property->isStatic()) {
                    $key = $property->getName();
                    $attributes[$key] = $model->$key;
                }
            }

            return $attributes;
        }
    }


now your 's :
   ...
   $class=new ReflectionClass(get_class($model));
			$attributes = array();
			foreach($model->getProperties() as $property)
			{
				if($property->isPublic() && !$property->isStatic())
				{
				  $key=$property->getName();
				  $attributes[$key] = $model->$key;
				}
			}

change the $model->getProperties =====> $class->getProperties :P
0

#9 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 06 November 2011 - 02:49 PM

I have detected this bug when working on the update 0.1.2.

Please take a look at this latest version.
The function EDMSQuery::arrayToModel and EDMSDataProvider::fetchData has been changed there for a better performance.
If using non CModel classes the model properties should not be analyzed (new ReflectionClass) for each row on fetching data.
0

#10 User is offline   yiqing95 

  • Advanced Member
  • PipPipPip
  • Yii
  • Group: Members
  • Posts: 599
  • Joined: 27-December 10
  • Location:china

Posted 06 November 2011 - 10:02 PM

View PostJoblo, on 06 November 2011 - 02:49 PM, said:

I have detected this bug when working on the update 0.1.2.

Please take a look at this latest version.
The function EDMSQuery::arrayToModel and EDMSDataProvider::fetchData has been changed there for a better performance.
If using non CModel classes the model properties should not be analyzed (new ReflectionClass) for each row on fetching data.

:rolleyes: i v download the latest version . seems everything is ok now .
well done joblo , great extension !
0

#11 User is offline   yilativ 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 20-December 11

Posted 16 January 2012 - 10:25 AM

Hi,
great extension.

I'd like to ask you for assistance in setting authmanager.

I've looked through the source of EDMSAuthManager, and I am not able to understand where the authorization rules are saved to.

I have the following set up in my config/main.php:
 
//uses the collection 'edms_authmanager' for the authmanager
        'authManager' => array(
            'class' => 'EDMSAuthManager',
            'connectionId' => 'mongodb'
        ),


Yet, when I save my authorization rules, I do not see the collection in my mongodb nor the file in protected/data/auth.php

Is there something I should check first, can someone post their successful configuration if they moved to mongodb for their auth rules?

Thanks!
0

#12 User is offline   yilativ 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 2
  • Joined: 20-December 11

Posted 16 January 2012 - 12:57 PM

I believe I got it to work.

It wasn't showing anything in my collections because I forgot to add "Save" to my authorization rules. That was the only difference between PhpAuth and the DbAuth way of doing things.

Again, awesome extension!
0

#13 User is offline   mastermunj 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 34
  • Joined: 12-July 11

Posted 23 January 2012 - 03:02 AM

Nice extension!

Have been using directmongosuite with yiimongodbsuite and both tend to work well together without any problem so far.
0

#14 User is offline   rall0r 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 181
  • Joined: 11-November 10
  • Location:Bln

Posted 03 February 2012 - 04:45 AM

Thank you, for that nice extension.
I have tow questions:

1.) how to set slaveOkay=true? -> http://www.php.net/m...etslaveokay.php
Or is it on by default?

2.) how to realize updates with multiple operators, like:
{ $set : { x : 1 }, $inc : { y : 1 } }


Is there something like an wiki, where I can write down my examples? Maybe other users (which starts with mongoDB) has the same questions?!

Thank you.
0

#15 User is offline   rall0r 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 181
  • Joined: 11-November 10
  • Location:Bln

Posted 03 February 2012 - 08:49 AM

To answer my own question Nr. 2:

I decided change the atomicUpdate method in order to have to possibility to process different modifier at one mongo request:

	public function atomicUpdate($criteria,$values,$modifier = '$set', $multiple = false,$options=array())
	{
		if (empty($values) and !is_array($modifier))
			return false;
		
		if(is_array($modifier))  {$action=$modifier;}
		  else {$action = array($modifier => $values);}
	
		
		if ($multiple)
		   $options = array_merge($options, array('multiple'=>true));

		return $this->getCollection()->update($criteria,$action,$options);
	}


That means, you can leave $values empty and use $modifier as an array with the following layout:
	  array($modifier1 => array($field1=>$value1,
	 			    $field2=>$value2),
	 	$modifier2=> array($field3=>$value5,));


Could that be an valid solution?
0

#16 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 24 February 2012 - 06:05 AM

Sorry for the delay, I didn't get a message that there is a new item in this topic.

1.) SlaveOK is true by default, but in the next release (coming soon) there will be a solution for that too.

2.) Thanks for the input, I will change the code like this
0

#17 User is offline   rall0r 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 181
  • Joined: 11-November 10
  • Location:Bln

Posted 12 March 2012 - 11:24 AM

Hi,

right now we are using directmongosuite and yiimongodbsuite side by side, which works well on an MongoDB replication set.

directmongosuite is using the connection settings from the yiimongodbsuite:

	'behaviors' => array(
   	'edms' => array(
      	'class'=>'EDMSBehavior',
      	'connectionId' => 'mongodb',
 			'debug'=>true //for extended logging
       )
    ),

[....]
        /*yiimongodbsuite zeugs*/
        'mongodb' => array(
        	'class'            => 'EMongoDB',
        	'connectionString' => 'mongodb://server1,server2',
        	'replicaSet'       => 'replSet_RS',
        	'dbName'           => 'testdb',
        	'fsyncFlag'        => true,
        	'safeFlag'         => true,
        	'useCursor'        => false
        ),
	   


Some hours before we did some changes on the Primary/Secondary configuration for the MongoDB.
All the application components, which are using yiimongodbsuite working without any errors with this new configuration.
All the application components using directmongosuite gets the following error:

Quote

not master and slaveok=false

at this point:
305     public function findOne($criteria,$select=array())
306     {
307         //always add the '_id'
308         if (!empty($select) && !in_array('_id',$select))
309             array_push($select,'_id');
310 
311         $cursor = $this->getCollection()->findOne($criteria, $select);   <---here
312 
313         return !empty($cursor) ? $cursor : false;
314     }


May you have any idea what is goning on here?

Thank you, rall0r.
0

#18 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 13 March 2012 - 02:41 AM

I don't know anything about your configuration.
If you google for 'mongodb slaveok php' you will find a lot of information about this.

It seems you try to read from a secondary without setSlaveOk = true.
See the mongodb manual and the php manual.

You have to configure the options of the edms-component with 'replicaSet'=>...
Maybe you have to add ->setSlaveOkay in the code of the 'function edmsMongoDb' of the file EDMSBehavior.
In the next release (coming soon) if have added a property 'setSlaveOkay' so that you can configure this call in the config/main.php.


But how did you configure the yiimongodbsuite with replicaSet=...?
As I can see in the source, the replicaSet-option is not available in EMongoDb.php from yiimongodbsuite.
Where is setSlaveOkay is set in the yiimongodbsuite?
I can't find this in the source.
Please compare the codes from EMongoDb.php and EDMSConnection.php and how 'new Mongo' is called.
0

#19 User is offline   rall0r 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 181
  • Joined: 11-November 10
  • Location:Bln

Posted 13 March 2012 - 03:41 AM

Hi Joblo,

Quote

It seems you try to read from a secondary without setSlaveOk = true.

right. But the point is: not to read from slave, becaus by using replicaSets, the PHP-mongoDB driver has to choose the master/primary. (i think so)

Quote

But how did you configure the yiimongodbsuite with replicaSet=...?

ups.. i forget, that I modified the getConnection() method from yiimongodbsuite. Probably this is the point, why yiimongodbsuite works and directmongosuite doesn't.

My new getConnetion method from yiimongodbsuite looks like that:
	public function getConnection()
	{
		if($this->_mongoConnection === null)
		{
			try
			{
				Yii::trace('Opening MongoDB connection', 'ext.MongoDb.EMongoDB');
				if(empty($this->connectionString))
					throw new EMongoException(Yii::t('yii', 'EMongoDB.connectionString cannot be empty.'));

				if($this->persistentConnection !== false)
					$this->_mongoConnection = new Mongo($this->connectionString, array(
						'connect'=>$this->autoConnect,
						'persist'=>$this->persistentConnection,
						'replicaSet'=>$this->replicaSet          <--- added this
					));
				else
					$this->_mongoConnection = new Mongo($this->connectionString, array(
						'connect'=>$this->autoConnect,
						'replicaSet'=>$this->replicaSet         <--- added this
					));

				return $this->_mongoConnection;
			}
			catch(MongoConnectionException $e)
			{
				throw new EMongoException(Yii::t(
					'yii',
					'EMongoDB failed to open connection: {error}',
					array('{error}'=>$e->getMessage())
				), $e->getCode());
			}
		}
		else
			return $this->_mongoConnection;
	}

So i thought this configuration...
        'behaviors' => array(
        'edms' => array(
        'class'=>'EDMSBehavior',
        'connectionId' => 'mongodb',
                        'debug'=>true //for extended logging
       )
    ),

..will work with replicaSets too, because yiimogodbsuite does - which is wrong, because directmongosuite "only" takes the connection-information, but not the connection method (logisch :-/ )
So I have to add 2 things at directmongosuite :
1.) slaveOk=true <- in order to read from slave if the slave is "closer" than the master and
2.) replicaSet configuration to the code from directmongosuite
..right?!?
0

#20 User is offline   Joblo 

  • Master Member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 685
  • Joined: 12-September 10
  • Location:Austria

Posted 13 March 2012 - 03:51 AM

In directmongosuite you can config the replicaSet in main.php by using the options of the EDMSConnection component.
The options array is used when calling 'new Mongo(...)'.


 'components'=>array(
 
        //configure the mongodb connection
        //set the values for server and options analog to the constructor 
        //Mongo::__construct from the PHP manual
        'edms' => array(
            'class'            => 'EDMSConnection',
            'dbName'           => 'testdb',
            'options'  => array('replicaSet'=>....); 
        ),




setSlaveOk is supported in the next release, so you have to change the EDMSBehavior.php to something like below.
Then you can configure the behavior to setSlaveOkay=true in config/main.php


This is a preview of v2.5 ....

   
class EDMSBehavior extends CBehavior
{
    /**
     * The connection id for config in config/main
     * @var string
     */
	public $connectionId = 'edms';
    /**
     * Set Mongo::setSlaveOkay after creating Mongo if set
     * @var boolean
     */
	public $setSlaveOkay = null;  //<---------------- add this property   
   

/**
	 * Get edmsMongoDb instance
	 * @since v1.0
	 */
	public function edmsMongoDb($dbName=null,$connectionId = null)
	{
		if (empty($dbName))
			$dbName = $this->edmsGetDbName($connectionId);

		if (empty($connectionId))
			$connectionId = $this->edmsGetConnectionId();

		if (!isset(self::$_db))
			self::$_db = array();

		if (!isset(self::$_db[$connectionId][$dbName]))
		{
			if ($this->edmsIsDebugMode())
			   self::edmsLog("Selecting db: $connectionId.$dbName","edms.debug.db.$dbName.$connectionId");

			$mongo = $this->edmsMongo($connectionId);

            if(isset($this->setSlaveOkay))
                $mongo->setSlaveOkay($this->setSlaveOkay);

            self::$_db[$connectionId][$dbName] =  $mongo->selectDB($dbName);
		}

		return self::$_db[$connectionId][$dbName];
	}


0

Share this topic:


  • (2 Pages)
  • +
  • 1
  • 2
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users