Allowing user input once per minute - mysql

I have trouble getting this to work.
The thing is that a user is only allowed to create a comment once per minute. As simple as that....
$checkLastComment = Comment::where('user_id', '=', 1)
->where('created_at', '<', 'CURDATE() + INTERVAL 1 MINUTE')->count();

You should use here rather:
$checkLastComment = Comment::where('user_id', '=', $id)
->where('created_at', '>=', 'DATE_SUB(NOW(), INTERVAL 1 MINUTE)')->first();
if ($checkLastComment) {
// user not allowed to add new comment
}

3 issues in your code:
You need greater than >, not less than < operator
You need raw condition
You can't use curdate() since it's time part is 00:00:00 always.
So here's what you want:
$notAllowedToComment = Comment::where('user_id', '=', 1)
->where('created_at', '>', DB::raw('now() - INTERVAL 1 MINUTE'))->count();

Related

How to write the below eloquent query code using raw query in laravel?

My eloquent query:
$data = (new Model())->whereDate('start_date', '<=', Carbon::today())
->whereDate('end_date', '>=', Carbon::today())
->count();
The raw query I have tried:
$data = (new Model())->select(DB::raw("COUNT(id) as countData where date(start_date) <= NOW() and date(end_date) >= NOW()"))->get();
How can I write my eloquent query as raw query. The below raw query gives me syntax violation error;
This is because of how you are constructing your query. If you inspect the generated SQL statement you'll see that the SQL FROM clause is actually on the end of your statement and not at all where it should be.
You'll want to split your WHERE clauses out and use either where or whereRaw. For example:
$data = (new Model)->select(DB::raw('COUNT(id) as countData'))
->whereRaw('date("start_date") <= NOW() AND date("end_date") >= NOW()')
->get();
Your question was a little unclear but if you want to do what you did with eloquent in raw query, be noted that the select function of DB in raw by itself, so simply write your query inside select function:
$tableName = (new Model)->getTable();
$data = DB::select("
SELECT COUNT(`id`) as `countData` FROM `$tableName`
WHERE DATE(`start_date`) <= NOW() AND DATE(`end_date`) >= NOW()
")->first();
Alternatively you may use whereRaw function of your Model:
$data = Model::whereRaw(
"DATE(`start_date`) <= NOW() AND DATE(end_date) >= NOW()"
)->count();

Find a date older than 15 days in laravel

i need to show compare a delivery date if it is 15 days over and also show a track_track_status=0 as default.when i do this it throws the error
Error
Column not found: 1054 Unknown column ''delivery_date' + INTERVAL 15 DAY < NOW()' in 'where clause
$secondstatus = DB::table('registrations')
->join('ssi_tracks', 'registrations.registration_id', '=', 'ssi_tracks.registration_id')
->select('ssi_tracks.ssi_track_id', 'address', 'model', 'chassis', 'delivery_date','ssi_tracks.track_second_status')
->where([["ssi_tracks.track_second_status", "=", 0]])
->orWhereRaw('registrations.delivery_date + INTERVAL 15 DAY <= NOW()')
->get();
Use Carbon with laravel orWhere instead
->orWhere( 'delivery_date', '<=', Carbon::now()->subDays(15))
use raw query as below:
$now = \Carbon\Carbon::now();
->orWhere(DB::raw(registrations.delivery_date + INTERVAL 15 DAY, "<=", $now))
check it and response here if it returns any error.
Just do:
$secondstatus = DB::table('registrations')
->join('ssi_tracks', 'registrations.registration_id', '=', 'ssi_tracks.registration_id')
->select('ssi_tracks.ssi_track_id', 'address', 'model', 'chassis', 'delivery_date','ssi_tracks.track_second_status')
->where([["ssi_tracks.track_second_status", "=", 0]])
->orWhere('registrations.delivery_date', '<=', \DB::raw("NOW() - INTERVAL 15 DAYS")))
->get();
Problem being that the query builder will alias the table name and will but will not alias it if it's within a whereRaw

Illuminate database query with date_sub

I'm struggling with a query using the Illuminate database query builder.
When I use the query the result is not as I expected.
When using the query from the querylog directly with mysql cli, I get the expected result.
With query builder:
->table('CompanyTools')
->select(
'CompanyTools.toolId',
$db->raw('COUNT(CompanyTools.toolId) as count')
)
->whereYear('CompanyTools.date', '>', 'YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')
->groupBy('CompanyTools.toolId')
->orderBy('count', 'DESC')
->take(1)
->get();
Result:
Array ( [toolId] => 88 [count] => 55 )
With mysql cli:
select `CompanyTools`.`toolId`, COUNT(CompanyTools.toolId) as count from `CompanyTools`
where year(`CompanyTools`.`date`) > YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))
group by `CompanyTools`.`toolId`
order by `count` desc
limit 1
Result:
ToolId: 88
count: 17
If I (in the query builder) replace 'YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))'with 2013 I get:
Array ( [toolId] => 88 [count] => 17 )
Somehow the date_sub get ignored so the result includes all years
I tried with ->whereYear('CompanyTools.date', '>', $db->raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')) without any luck.
I guess I could use php to calculate the desired year, but I would rather get the query right.
Thx in advance
/ j
UPDATE
Replacing
->whereYear('CompanyTools.date', '>', 'YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')
with
->where($db->raw('YEAR(CompanyTools.date)'), '>', $db->raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))'))
solves it. Not clever enough to figure out why, but perhaps the whereYear function is supposed to be used diffently
As you already found out using
->where($db->raw('YEAR(CompanyTools.date)'), '>', $db->raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))'))
Or alternatively
->whereRaw('YEAR(CompanyTools.date) > YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))')
solves the problem.
But why is that?
For every "normal" query, Laravel uses bindings. Obviously SQL functions like YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR)) don't work with bindings.
Normally, you can use DB::raw('YEAR(DATE_SUB(CURDATE(), INTERVAL 1 YEAR))') and the Laravel won't use bindings. For example in where() (Expression is the class DB::raw() returns)
if ( ! $value instanceof Expression)
{
$this->addBinding($value, 'where');
}
But the whereYear() function doesn't do such a thing. It uses addDateBasedWhere() and just adds a binding without checking if the value is an instance of Expression
protected function addDateBasedWhere($type, $column, $operator, $value, $boolean = 'and')
{
$this->wheres[] = compact('column', 'type', 'boolean', 'operator', 'value');
$this->addBinding($value, 'where');
return $this;
}
This means the query will use bindings and therefore NOT execute the date calculation at all.

Zend Db Sql Where

Hi how can I do a query like this in zf2 with zend\db\sql?
Query:
SELECT * FROM table WHERE field = $field AND data > SUBDATE(NOW(), INTERVAL 1 DAY)
In ZF2
$select = $this->sql->select();
$select->from(self::MYTABLE)
->where(array('fiels' => $field))
->where(array('data > ' => 'SUBDATE(NOW(), INTERVAL '.$lifetime.' SECOND'));
$statement = $this->sql->prepareStatementForSqlObject($select);
return $statement->execute()->current();
change the line
->where(array('data > ' => 'SUBDATE(NOW(), INTERVAL '.$lifetime.' SECOND'));
to
->where(array('data > ?' => 'SUBDATE(NOW(), INTERVAL '.$lifetime.' SECOND'));
From the code snippet, it's seen you had missed the place holder for the parameter(?), include a question mark, I had mentioned the existing line of code and the modified code for quick reference
There's no parameter there so it doesn't need to be an array. Assuming you know $lifetime is a safe, integer value, try:
->where('data > SUBDATE(NOW(), INTERVAL '.$lifetime.' SECOND)');

How can I update TIMESTAMP with Codeigniter and MySQL?

How can I update TIMESTAMP with Codeigniter and MySQL? I want to update with INTERVAL 1 MINUTE
I've tried the next code:
$data = array('is_active' => $state,
'timestamp_demo' => "DATE_ADD(NOW(), INTERVAL 1 MINUTE)");
$this->db->where('demo_session_id', 'web');
$this->db->update('demo_session', $data);
But not work. How can I do?
Try your query like this
$this->db->query("UPDATE demo_session
SET
is_active = 1,
timestamp_demo = DATE_ADD(NOW(), INTERVAL 1 MINUTE)
WHERE demo_session_id = 'web'");
You can do this with Active Records, which you're using:
$this->db->where('demo_session_id', 'web');
$this->db->set('is_active', $state);
$this->db->set('timestamp_demo', 'DATE_ADD(NOW(), INTERVAL 1 MINUTE)', FALSE);
$this->db->update('demo_session');
The third parameter in $this->db->set() prevents CodeIgniter from escaping the data so it'll use the MySQL function.
It'll end up something like this:
UPDATE 'demo_session' SET 'is_active' = $state, 'timestamp_demo' = DATE_ADD(NOW(), INTERVAL 1 MINUTE) WHERE 'demo_session_id' = 'web'