Reputation: 825
Is there a better way deleting dataobject older than x-days instead of using custom sql queries?
that's what I do now
$host = 'localhost';
$username = 'db123';
$password = 'pass';
$db_name = 'db123';
mysql_connect("$host", "$username", "$password")or die("cannot connect");
mysql_select_db("$db_name")or die("cannot select DB");
$sql = "DELETE FROM Cart WHERE Created < (CURDATE() - INTERVAL 1 DAY)";
$result = mysql_query($sql);
mysql_close();
Upvotes: 3
Views: 4818
Reputation: 4015
first of all, using mysql_query
is bad, not just in this case.
mysql_query
has been deprecated and should no longer be used.
secondly, SilverStripe already has a DB connect, do not attempt to create another one. SilverStripe offers many ways to query the database.
Option 1:
the cleanest way of course is to use the SilverStripe ORM.
A DataObject
has a method called ->delete()
.
Using delete has several advantages over writing your own SQL query.
Folder
is a subclass of File
, so if you do $myFolder->delete()
it will go and delete this Folder
in the File
Table but also in the Folder
Table (if there is a Folder
table))onBeforeDelete
and onAfterDelete
) its pretty straight forward:
// to delete all `DataObject`s in a List, just loop it and call ->delete()
foreach($list as $item) {
$item->delete();
}
// there also is a method that does that for you, however, I would advise against it
// because it is currently inconsistently implemented and might lead to unexpected results
// $list->removeAll(); // i STRONGLY RECOMMEND AGAINST THIS
// if $list is a DataList, it will delete all records
// if $list is a ManyManyList, it will unlink all records
// if $list is a ArrayList, it will error because there is no removeAll() method on ArrayList
to solve your problem:
$date = date('Y-m-d H:i:s', strtotime("now -1 day"));
$list = Cart::get()->filter('Created:LessThan', $date);
foreach($list as $item) {
$item->delete();
}
it however has also a major disadvantage when deleting many DataObject
s: performance.
I will however still recommend using ->delete()
if you can say that performance is not a huge problem. The benefits usually outweigh the drawbacks.
Read more about DataList
, ::get()
, ->filter()
and ->delete()
in the SilverStripe docs for Datamodel / ORM and DataObject
Option 2:
if you however really need to, it is possible to use a lower level of the ORM to perform the delete:
$query = new SQLQuery();
$query->setDelete(true);
$query->setFrom('Cart');
$query->setWhere('Created < (CURDATE() - INTERVAL 1 DAY)"');
// if you want to debug the query, you can use ->sql() to get it as string
// echo $query->sql();
$query->execute();
Read more about SQLQuery
in the SilverStripe docs
Option 3:
if you for some reason really want to avoid the ORM at all, SilverStripe also lets you execute raw SQL queries:
DB::query("DELETE FROM Cart WHERE Created < (CURDATE() - INTERVAL 1 DAY)");
Upvotes: 15