I have this delete function in my model. When you press the delete button, it will subtract the number of total notes from the total notes column in my database. For eg. if you had 200 notes, and you deleted one of them, it will be 199 notes AND the note will be deleted from the database.
My code:
public function entry_delete($pid) {
$uid=$this->session->userdata('uid');
$whereConditions = array('pid' => $pid, 'uid' => $uid);
$this->db->where($whereConditions);
$this->db->delete('dayone_entries');
if ($this->db->affected_rows() == 0) {
$sql_entry = "UPDATE users set total_entry = total_entry - 1 WHERE uid = $uid";
$this->db->query($sql_entry);
return true;
} else {
return false;
}
}
But this doesn't work. I don't know why but when I press the delete button from my view, it will delete it from the database AND subtract -1 from my total_entry table. However, if I comment out the
$this->db->delete('dayone_entries');
It will still subtract 1 from the total_entry.
How do I fix this? Thanks.
I don't know if you have fixed this yet, but I think what Ghost was saying is your
if ($this->db->affected_rows() == 0) {}
is doing the wrong check. If you only want it to trigger if the rows where successfully deleted you would want to check
if ($this->db->affected_rows() > 0) {}
This is saying if the affected rows is more than 0 then do this. In CodeIgniter is says that the affected_rows() method is for "doing 'write' type queries (insert, update, etc.)".
It then goes on to say "Note: In MySQL "DELETE FROM TABLE" returns 0 affected rows. The database class has a small hack that allows it to return the correct number of affected rows. By default this hack is enabled but it can be turned off in the database driver file." So if your if ($this->db->affected_rows() == 0) {} is triggering in both situations then this hack could be disabled because your asking "if the affected rows equals zero do this" and it should't trigger if your delete was successful.
Related
I want to move my audits table records which got million of rows to another table by using console/command and chunkbyid but it stop in the middle. For example I want to move the audit date of MONTH(created_at) = 02 and YEAR(created_at) = 2021, it does not run through all the records following that condition. As i checked in mysql it suppose to have like 5mils of records but only run up to hundreds thousand only. My codes as below in console
Audit::query()
->whereRaw("MONTH(created_at) = '$month'")
->whereRaw("YEAR(created_at) = '$year'")
->chunkById(1, function ($audits) use ($table_name) {
foreach($audits as $audit){
dump($audit->id);
$newRecord = $audit->replicate()->fill([
'audit_id' => $audit->id,
'created_at' => $audit->created_at,
'updated_at' => $audit->updated_at,
]);
$newRecord->setTable($table_name);
$newRecord->save();
if(str_contains($audit->auditable_type, 'User') || str_contains($audit->auditable_type, 'Trans') || str_contains($audit->auditable_type, 'Step')|| str_contains($audit->auditable_type, 'Team')){
$audit->delete();
}
}
}, $column = 'id');
I already followed many solutions i found in many sites but still not working. Is there anything i missed?
In Laravel documentaion (https://laravel.com/docs/9.x/queries)
there is a block of note say When updating or deleting records inside the chunk callback, any changes to the primary key or foreign keys could affect the chunk query. This could potentially result in records not being included in the chunked results.
and in your code you deleting audit in some cases.
My app is being made in laravel 5.6
Situation:
I have a table called "members" with a column called "membershipstatus_id".
options for status are 4, 5 and 1
4 = Active, 5 = pending and 1= expired
Target:
I want to update all active(4) members to pending(5) and all pending ones to expire(1).
Solutions I have tried:
So far, below is what i have tried with no result.
// get all active and pending members
$members = Member::where('membershipstatus_id', 5)
->orWhere('membershipstatus_id', 4)
->get();
// bulk update with chunk of 200, if this is possible
$members->chunk(200, function($members)
{
foreach($members as $member)
{
// if status is pending, update to expire
if($member->membershipstatus_id == 5)
{
$member->update(['membershipstatus_id' => 1]);
}
// if status is active, update to pending, i updated a small mistake here.
if($member->membershipstatus_id == 5)
{
$member->update(['membershipstatus_id' => 4]);
}
}
}
);
return "update confirm";
Now, If anyone has a cleaner and swift way to do this, Please let me know, also, Im sure i have made some stupid mistake up there. Please point me to the right direction.
Ashish
Use the query builder like:
// update pending to expired
DB::table('members')
->where('membershipstatus_id', 5)
->update(['membershipstatus_id' => 1]);
// update active to pending
DB::table('members')
->where('membershipstatus_id', 4)
->update(['membershipstatus_id' => 5]);
I have created a Symfony 2 Bundle that supports private messages between users. I gave them the ability to send messages from their inbox or sent folder to the trash one. Messages will be marked as trash through the isRTrash and isSTrash fields, marked by receiver and by sender, respectively. That is because, being the same message in my database, if I had one single field here, one user marking it as trash, would mark it for the other one, as well.
Now, I want to give them the possibility to delete them, too, from their trash folder. Messages won't be deleted, but marked similarly to trash ones, just that they are forever gone from standard user view. I'm having problems with marking them like this, because I have to mark both messages that are sent and received by the user.
I've made the following query in the entity's repository:
public function delete($user, $msg)
{
$qb = $this->createQueryBuilder('a')
->update('PrivateMessageBundle:Message', 'a')
->where('a IN(:msg)')
->andwhere('a.receiver = :user AND a.isRTrash IS NOT null AND a.isRDeleted = false')->set('a.isRDeleted', true)
->orWhere('a.sender = :user AND a.isSTrash IS NOT null AND a.isSDeleted = false')->set('a.isSDeleted', true)
->setParameters(
array('user' => $user, 'msg' => $msg)
);
echo '<pre>';
\Doctrine\Common\Util\Debug::dump($qb->getQuery()->getSQL()); exit;
echo '</pre>';
return $qb->getQuery();
}
And the output query is string(196) "UPDATE message SET isRDeleted = 1, isSDeleted = 1 WHERE (id IN (?) AND (receiver_id = ? AND isRTrash IS NOT NULL AND isRDeleted = 0)) OR (sender_id = ? AND isSTrash IS NOT NULL AND isSDeleted = 0)"
I give as input the curent logged in user and an array of message id's. Then, I check messages that are in trash, are not marked as deleted and have the curent user as receiver or sender and want to mark them as deleted.
The problem is that both conditions are met, and both SET are being called, marking a message's isRDeleted and isSDeleted to true, regardless.
I am very close, but don't know how to make it so that the fields are marked separately, only if their condition is met.
Meanwhile, I'm using a foreach loop, but I think it can be done faster with a query
$em = $this->getDoctrine()->getManager();
foreach ($msgs as $msgid) {
$msg = $messages->findOneBy(array('id' => $msgid));
if ($msg->getSender() == $this->getUser() && $msg->getIsSTrash() && $msg->getIsSDeleted() == false) {
$msg->setIsSDeleted(true);
$changedno++;
} else if ($msg->getReceiver() == $this->getUser() && $msg->getIsRTrash() && $msg->getIsRDeleted() == false) {
$msg->setIsRDeleted(true);
$changedno++;
}
$em->flush();
}
I think you need a CASE .. WHEN construction but Doctrine doesn't have that in DQL (See the Grammar). So you either must use a raw query, something along these lines (it's pseudo MySQL) :
UPDATE PrivateMessageBundle:Message a
SET a.isRDeleted = CASE
WHEN a.receiver = :user AND a.isRTrash IS NOT null THEN TRUE
ELSE a.isRDeleted = FALSE
END,
SET a.isSSDeleted = CASE
WHEN a.receiver = :user AND a.isRTrash IS NOT null THEN TRUE
ELSE a.isSDeleted = FALSE
END
... or use two standard queries, one for isRDeleted and one for isSDeleted, like the one you already did. To be honest I think that's a pretty simple solution in your case, and it looks more maintenance-friendly if you ever need to read your code again in six months.
NB : on a side note, the ->set() or ->when() functions in Doctrine (and all the others, in fact) do not follow a specific order; they are just adding properties to the Doctrine query object, and when you call getQuery(), a SQL query is made. That means that the following construction :
->when()->set()
->orwhen()->set()
is equivalent to :
->set()->set()
->when()->orWhen()
which is why your solution cannot work. There is no condition to be met before set() is called (if I'm not clear, tell me)
Firstly, I will show what I want to do.
I want check if user has more than one record:
WHERE 'from_user_id' == '$id'
When query return > 0, I want update only ONE record where 'from_user_id' == '$id',
I dont care about order, It can be last or first record, but I have to update only one record.
Here is part of my model:
public function get_bonuses() {
if ($this->db->where('from_user_id', $this->user_id())->from($this->reff_table)->count_all_results()>0 ) {
$this->db->where('from_user_id', $this->user_id());
$this->db->update($this->reff_table, array('used' => '1'));
return true;
} else
return false;
}
It works fine but I want update only one record :<
I hope anyone will help me.
Regards
----- EDIT
SOLVED - I'm so stupid but I needed to look from the other side to my code :)
Here is working code:
if ($this->db->where(array('from_user_id' =>$this->user_id(), 'used' => '0' ))->from($this->reff_table)->count_all_results()>0 ) { $this->db->where(array('from_user_id' =>$this->user_id(), 'used' => '0' ))->limit(1); $this->db->update($this->reff_table, array('used' => '1')); return true;
If you want to update any one record from result, simply limit the query where you check count to 1 & grab its unique id (primary key) and update that row.
I have a table of categories that have a "position" field. The results will be ordered by this field. I want to be able to select a position (other than last) for the new row.
Basically, the form has a field that lets a user select "Before" or "After", and then lists all the categories by position. Once the form is submitted, it should update the form based on the selection. For example, if there are 7 existing rows and the user selects "Before 5" it should give the new row the position of 5 and then update every row after that (including the row that previously was position 5). If "After 5" is selected, the new row will be given a position of 6 and rows that were previously 6 and 7 will be updated to 7 and 8.
Anyone have any ideas?
PS: I'm doing this in CodeIgniter (if you couldn't tell), but I'm pretty sure the logic will be basically the same.
if(count($this->info) > 0)
{
if($this->info['place'] == 0)
{
$new_cat_position = $this->info['where'];
}
else
{
$new_cat_position = $this->info['where'] + 1;
}
$data = array(
'title' => $this->info['title'],
'collapsible' => $this->info['collapsible'],
'position' => $new_cat_position
);
if($this->db->insert('forum_parents', $data))
{
if($this->info['place'] == 0)
{
$this->db->where('position > ', $new_cat_position + 1);
}
else
{
$this->db->where('position > ', $new_cat_position);
}
if(!$this->db->update('forum_parents', $data))
{
$this->error = "The category was created, however, the positions of the other categories were not updated correctly... ".$this->db->_error_message();
}
}
else
{
$this->error = "An unknown system error occurred while processing your request. Please try again later... ".$this->db->_error_message();
}
}
Try to use DataTable. It will help you. In that try row-reordering function as per your requirement.
Here is the link :
http://code.google.com/p/jquery-datatables-row-reordering/wiki/Index
Here is the Working Example:
http://live.datatables.net/onigip/2
Once you are able to Roe-Reordering, You can update that records in your database using some logic.
Hope this help.