How to insert Array to Database using firstOrCreate in Laravel? - php

I have an array like this and it has 120 elements in it
`array (size=120)
0 =>
array (size=8)
'name' => That the quick brown fox jumps over the lazy - 7' (length=53)
'url' => string 'google.com/zyx' (length=134)
'category' => string 'search-engine' (length=6)
1 =>
array (size=8)
'name' => string 'Mr. john brandy gave me a wall nut of quite' (length=67)
'url' => string 'yahoo.com/dzxser' (length=166)
'category' => string 'indian' (length=6)`
I want to insert them to my bookmark table which model I have created and I want to make sure duplication doesn't occur. I have found this https://laravel.com/docs/5.4/eloquent#other-creation-methods specially firstOrCreate method.
I assume I have to use foreach but I am not sure how. Can anyone help me with some workaround.

Actually you don't need firstOrCreate, you need updateOrCreate. Checking Laravel Other Creation methods You will find that method.
Say that array is in $alldata:
foreach($alldata as $data) {
MyModel::updateOrCreate($data); //the fields must be fillable in the model
}
This will run update/or create of 120 queries while cycling through the loop. The advantage is that, you cannot have a duplicate, rather if there is a repetition, its only going to perform an update to the table.
However the best way to ensure that there is no duplication in whatever way the data comes is to set it up when making your database table. You can set unique constraints on many fields if thats your case.

If you don't want duplication to occur when inserting array of records then all you have to do it set a constraint making sure fields are unique.
If you're using migrations to create databse schema you can use something like this: $table->string('name')->unique();
Now for example, this will make sure that 'name' column data is

Related

Query Exception when creating a database record using laravel eloquent

I am encountering a weird error.
In a laravel project I am reading a CSV file. In my Controller I am parsing the CSV and creating database records for a mysql database.
I convert the CSV lines into individual arrays which are located within a big array -> two dimensional array. So far so good.
When iterating through my array the first iteration works just fine and I get the database records as expected. However, during the second iteration a Query Exception is thrown.
The stack trace leads me to a line where I am assigning a double value to an attribute of the model.
Transaction::firstOrCreate([
'date' => $date,
'transaction_type' => $the_big_array[$i][2],
'db_counter_party_id' => $db_counter_party_id,
'amount' => $amount,
'currency' => $the_big_array[$i][6],
'usage' => $the_big_array[$i][7],
'category' => "none",
'balance' => $balance_after_transaction,
]);
The last assignment is causing the error. The variable balance_after_transaction is of type double and calculated according to previous transactions. So it is not directly retrieved from the CSV.
Does someone have a clue what is going on?
The error was caused by a wrong character encoding.

Get value of object in array

I have an array with an object. The value of the object is a counter from my database.
I need to make a condition on that object.
var_dump($myArray);
return
array (size=1)
0 =>
object(stdClass)[62]
public 'count(videos_like.videos_like_id)' => string '5' (length=1)
I try to do it like so:
if($myArray[0]->count(videos_like.videos_like_id) == '5'){...}
But of course I get an error.
Does anyone have an idea?
I'd rather advise you to update your SQL query and replace code:
count(videos_like.videos_like_id)
to
count(videos_like.videos_like_id) AS videosCount
hence you won't have this problem.
PS: Even you don't have plain SQL and use any framework - it's definitely possible to provide alias to your count column.

Effeciant way of inserting array of data in database using codeigniter

I have following table fields in the database :
id, user_id, permission_id, value, created.
I have one result of an array which may contain more than 20 different values at a time. That whole contains the permission_id values and rest of the fields are similar. like user_id will be only one which will be inserted same with each permission_id and value will be always 1 and created is same as it would contain current date and time.
Now I am able to insert into database with following code:
$user_perms=$this->input->post('permissions');
foreach($user_perms as $perms) {
$userPerms['permission_id']=$perms;
$userPerms['user_id']=$uid;
$userPerms['value']=1;
$userPerms['created']=date("Y-m-d H:i:s");
$this->admins->insertPerms($userPerms);
}
Now it runs very well. But i want to make it more efficient and fast. As you may have noticed that i run that insert query in the foreach loop . So, when the user will click the submit at the back end the query may run more than 30 times at a time. which is not a good idea.
Therefore, how can i insert data without loop at once ?
You can use $this->db->insert_batch() to insert multiple rows at once:
$this->db->insert_batch(
'table_name',
array(
// first row:
array('permission_id' => 1, 'user_id' => 1, 'value' => 1, 'created' => '...'),
// second row:
array('permission_id' => 2, 'user_id' => 1, 'value' => 1, 'created' => '...')
)
);
(read more here)
However, you obviously don't avoid the foreach loop that way because you'd need to somehow create the array of data that you're passing to it ...
So, another way to optimize it is to run those inserts inside a transaction. That would (as far as SQL is concerned at least) be the equivalent of inserting them all at once in a single query, because it's COMMIT that's the most expensive operation and therefore 1 commit is faster than 20 commits.

Save php function in mysql

It has been my late-childhood dream to create a game, and now as I actually know how I thought I should fulfill my dream and started working on a little game project in my spare time. It's basically a combat type of game where you have up to 3 units, as well as your opponent, and you take turns ( since it's http, you know that feel ) to attack each other and cast spells and stuff. The issue I came across with is with abilities and how to store them. Basically if I were to store abilities in an array it would look something like
$abilities = array(
0 => array(
'name' => 'Fire ball',
'desc' => 'Hurls a fire ball at your enemy, dealing X damage.'
'effect' => function($data){
$data['caster']->damage($data['target'], $data['caster']->magicPower);
}
),
1 => array(...
);
But if I were to store abilities this way, every time I needed to fetch information about a single ability I would need to load the whole array and it's probably going to get pretty big in time, so that would be a tremendous waste of memory. So I jumped to my other option, to save the abilities in a mysql table, however I'm having issues with the effect part. How can I save a function into a mysql field and be able to run it on demand?
Or if you can suggest another way to save the abilities, I may have missed.
To answer your question related to storing arrays into database like MySQL I would like you to serialize the Array as String. The normal direct serialization not going to work because they don't deal with closure.
You need to use classes like super_closure which can serialize the methods and convert them into string. Read more here
https://github.com/jeremeamia/super_closure
$helloWorld = new SerializableClosure(function($data){
$data['caster']->damage($data['target'], $data['caster']->magicPower);
});
$serializedFunc = serialize($helloWorld);
Now you can create array like this:
$abilities = array(
0 => array(
'name' => 'Fire ball',
'desc' => 'Hurls a fire ball at your enemy, dealing X damage.'
'effect' => $serializedFunc
));
This Array can now be saved directly, serialized or encoded to JSON.
I would recommend you to look at Redis or Memcache for caching query results and don't use MySQL to store functions.
You could have tree tables
spell
id
name
description
spell_effect
id
name
serversidescript
spell_effect_binder
spell_id
spell_effect_id
This would make sure, that your logic is in php files, where ever you would like them to be located, but all the meta of the spells, effects and how they bind together in the database. Meaning you will only load the function/script of the ones in need. Plus, giving you the possibility to append multiple effects to one spell.
//Firedamage.php
public function calculateEffects($level,$caster,$target) {
$extraDamage = 5*$level;
$randDamage = rand(10,50);
$caster->damage( $target, ($randDamage+$extraDamage) );
}
Spell_effect entry
id = 1
name = 'firedamage'
serversidescript = 'Firedamage.php'
spell
id = 1
name = 'Fireball'
description = 'Hurls a fireball at your foe'
spell_effect_binder
spell_id = 1
spell_effect_id = 1

Reusing Propel query bug or my bad?

Simple Propel reusing query is not working here, despite my code is similar to the example on Propel website. Is this a bug or my bad?
$q = MashupSettingQuery::create()->filterByMashup($this);
var_dump($q->count(), $q->findOneByKey('redirect_uri'), $q->count());
Output is:
int 5
object(MashupSetting)[28]
protected 'startCopy' => boolean false
protected 'id' => int 9
protected 'key' => string 'redirect_uri' (length=12)
int 1
that is, resusing is not working because count() first returns 5 and then 1.
Even using MashupSettingQuery::create()->filterByMashup($this)->keepQuery(true) didn't fix the problem.
I think it's normal because just before the second count you make a findOneByKey query, and so the second count just count how many objects this specific query return.
And your query return just one object, obviously because it's a findOneByKey.

Categories