Create a MongoDB database with PHP - php

The only way I found to do this is:
$mongo->selectDB('new_db')->createCollection('tmp_collection');
$mongo->selectDB('new_db')->dropCollection('tmp_collection');
Doing just $mongo->selectDB('new_db') actually doesn't work.
Got any idea?

You'll need to run at least one command on the Database before it is created ...
This command can be run before you add any Collections ... so you can merely list (the nonexistent) Collections.
<?php
$connection = new Mongo();
$db = $connection->foo;
$list = $db->listCollections();
foreach ($list as $collection) {
echo "$collection </br>";
}
?>
Your new Database should now exist, with no user Collections created yet.

Technically, you don't need to manually create databases or collections in MongoDB due to its schemaless "lazy" way of creating databases and collections.
I understand if you're coming from an SQL world this doesn't make much sense. You may want to ask yourself though, "If it automatically creates a collection or database for me on the fly, is there really a need to define it ahead of time?"

Related

PDO transaction with multiple models

How could I make a transaction using multiple php controllers to make the queries?
Currently, my code is like this (A bit more complex, but I am not allowed to show anymore)
$operation = new Operations();
$bill = new Bills();
$employee = new Employee();
$operation->setName("Name");
$operationCreated = $operation->create();
$result = "";
if($operationCreated){
$bill->setAmount(1000);
$billCreated = $bill->create();
if($billCreated){
$employee->setName("Name");
$result= $employee->create();
}
}
return $result;
The way it is right now leads to a problem where I might have an operation created well, but no billing and no employee and my database ends with a row I don't want because I don't have all the information I need in the database.
I need a way to revert the changes if any one of them fails, and I think a transaction would do the trick, but I don't know how can be done. All three classes extend the Database class that has the create() method.

AR in Yii add duplicate rows

I have common model, which is generated by gii.
3 columns in mySql: id (int, A_I), setting(tinytext, null) and value(tinitext, null).
After this:
$cfg = new Config();
$cfg->setting = "sdd";
$cfg->value = 'dsf';
$cfg->save();
This effect I get even if create absolutely clear, new table and model.
This code runs in defaultAction.
Yii 1.1.4
PHP 5.5
MySQL 5.6.12
Help me, I'm tired search this bug =)
You said that the code runs in defaultAction. Is possible that you are calling it also in some other action. This way, the code runs twice.

Selecting a collection with a dot in its name

I usually select a collection by using the following method...
assuming the collection name is "fantastic" in a database called "somedb"
$conn = new Mongo();
$fantastic_coll = $conn->somedb->fantastic;
This has worked famously for me for a long time. The number of collections I am using has grown a lot and I'm trying to use dots in the collection names to organise them a little more logically.
eg.
store.items
store.categories
store.coupons
events
events.categories
This seems to work fine in the mongodb shell, but not in php?
if I try....
$conn = new Mongo();
$store_coupons_coll = $conn->somedb->store.coupons;
and then try to save documents into the collection it doesn't like me.
if I instead use...
$conn = new Mongo();
$store_coupons_coll = $conn->somedb->selectCollection('store.coupons');
everything works as expected.
Is this the right way to do it?
If so then I hope this helps anyone having the same trouble.
If not then is there a short way to write the collection name?
Is using dots in the collection name for organisation wrong to begin with?
The preferred way of doing this is with:
$collection = $conn->somedb->selectCollection( 'store.coupons' );
Or if you want:
$collection = $conn->selectCollection( 'somedb', 'store.coupons' );

Preventing Laravel adding multiple records to a pivot table

I have a many to many relationship set up and working, to add an item to the cart I use:
$cart->items()->attach($item);
Which adds an item to the pivot table (as it should), but if the user clicks on the link again to add an item they have already added it creates a duplicate entry in the pivot table.
Is there a built in way to add a record to a pivot table only if one does not already exist?
If not, how can I check the pivot table to find if a matching record already exists?
You can also use the $model->sync(array $ids, $detaching = true) method and disable detaching (the second param).
$cart->items()->sync([$item->id], false);
Update:
Since Laravel 5.3 or 5.2.44, you can also call syncWithoutDetaching:
$cart->items()->syncWithoutDetaching([$item->id]);
Which does exactly the same, but more readable :)
You can check the presence of an existing record by writing a very simple condition like this one :
if (! $cart->items->contains($newItem->id)) {
$cart->items()->save($newItem);
}
Or/and you can add unicity condition in your database, it would throw an exception during an attempt of saving a doublet.
You should also take a look at the more straightforward answer from Barryvdh.
#alexandre Butynsky method works very well but use two sql queries.
One to check if cart contains the item and one to save.
To use only one query use this:
try {
$cart->items()->save($newItem);
}
catch(\Exception $e) {}
As good as all this answers are because I had tried them all, one thing is still left unanswer or not taken care of: the issue of updating a previously checked value (unchecked the checked box[es]). I do have something similar to the above question expect i want to check and uncheck features of products in my product-feature table (the pivot table). I am a newbie and I have realised none of the above did that. The are both good when adding new features but not when i want to remove existing features (i.e. uncheck it)
I will appreciate any enlightenment in to this.
$features = $request->get('features');
if (isset($features) && Count($features)>0){
foreach ($features as $feature_id){
$feature = Feature::whereId($feature_id)->first();
$product->updateFeatures($feature);
}
}
//product.php (extract)
public function updateFeatures($feature) {
return $this->features()->sync($feature, false);
}
or
public function updateFeatures($feature) {
if (! $this->features->contains($features))
return $this->features()->attach($feature);
}
//where my attach() is:
public function addFeatures($feature) {
return $this->features()->attach($feature);
}
Sorry guys, not sure is I should delete the question because having figure out the answer myself, it sounds a bit stupid, well the answer to the above is as simple as working #Barryvdh sync() as follows; having read more and more about:
$features = $request->get('features');
if (isset($features) && Count($features)>0){
$product->features()->sync($features);
}
There are some great answers posted already. I wanted to throw this one out here as well though.
The answers from #AlexandreButynski and #Barryvdh are more readable than my suggestion, what this answer adds is some efficiency.
It retrieves only the entries for the current combination (actually only the id) and it than attaches it if it does not exist. The sync method (even without detaching) retrieves all currently attached ids. For smaller sets with little iterations this will hardly be a difference, ... you get my point.
Anyway, it is definitely not as readable, but it does the trick.
if (is_null($book->authors()->find($author->getKey(), [$author->getQualifiedKeyName()])))
$book->authors()->attach($author);
I just had this problem and was able to solve it.
For future readers: instead of using atach() you can use
syncWithoutDetaching()
This will make sure you do not get any duplicates!
There are more alternatives to attach()
That might be usefull in the laravel documentation
Note that this is not for Laravel 4
$branch->permissions()->syncWithoutDetaching([1,2,3]);

Doctrine : do not load related records

In order to improve performance of app, I would like to separate queries instead of using leftJoins. Then I have to create my own related Doctrine_Collection :
$user->Friends->add($current_friend);
But I don't want doctrine does a query when I try to access related (not loaded) Collection.
How I can do that.
Thanks in advance.
I think the answer is in this ยง about relation handling. Build a new friendship relation and save it instead of adding a friend to a user object.
then I found this way (I should optimize this) :
$my_relation_collFriend = FriendTable::getInstance()->findByIdUser($user->id_user);
foreach($my_relation_collFriend as $friend)
{
$collFriend = $user->get('Friends', false); //get the related collection without db query
if(!$collFriend ) //unfornatly, It can be null
{
$collFriend = new Doctrine_Collection::create('friend'); //create the collection
$user->set('Friends', $collFriend, false); // define the related collection without db query
}
$collFriend->add($friend); //add the record to related collection
}
With this example I know this is useless but with lot of joins and datas it becomes necessary

Categories