Otóż chciałbym pobrać wszystkie zapytania, których data aktualizacji + interval minut jest mniejsza od aktualnego czasu, coś na wzór:
@requests = Request.where(‘created_at = updated_at OR (updated_at + interval60) <= ?’, Time.now)
z czym to jest źle
próbowałem też coś w tym stylu
@requests = Request.where('created_at = updated_at OR ADDTIME(updated_at,interval60)) <= ?’, Time.now)
ale nadal jest źle, nawet jakbym to poprawił to z funkcją ADDTIME, to i tak na innych bazach niż mysql może to nie śmigać, potrzebuję czegoś bardziej uniwersalnego. Jak to zrobić dobrze?
Nie prościej:
Request.where(‘created_at = updated_at OR (updated_at) <= ?’, Time.now - interval * 1.minute)
?
prościej, ale nie dobrze. Wtedy musiałbym znać interval z góry, a każdy rekord tą wartość ma różną
Zalozmy ze Twoj interval to 5 minut. Czy chodzi Ci o znalezienie wszystkich zapytan zaktualizowanych wczesniej niz ostatnie 5 minut? Wtedy faktycznie byloby to
Request.where('created_at = updated_at OR updated_at <= ?', Time.now - 5.minutes)
wtedy to by było rzeczywiście proste. Dam przykład. Mam takie oto dane:
id|created_at|interval
1|2012-12-19 10:55:00|10
2|2012-12-19 10:55:00|20
3|2012-12-19 10:55:00|30
chcę o godzinie 11:05:00 pobrać tylko krotkę o ID=1, o 11:15:00 dwie krotki o ID=1 oraz ID=2, a natomiast o 11:25:00 pobrać już wszystkie trzy.
W takim przypadku jestes skazany na zapytanie SQL z INTERVAL. Nie mozesz z poziomu aplikacji korzystac z danych ktorych jeszcze nie wyciagnales z bazy. U mnie dziala cos takiego:
Request.where('created_at = updated_at OR DATE_ADD(created_at, INTERVAL interval SECOND) <= ?', Time.now)
http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_addtime
ale to już jest zależne od bazy danych. Do postgresa mam: Select * From TABLE Where (updated_at + Interval ‘? minutes’) >= now();
tylko pytanie jest czy jest coś niezależnego od silnika bazy danych
Oddzielne moduly zalezne od bazy danych? Koniecznie potrzebujesz dzialania w roznych bazach danych czy to tylko premature optimisation? Ewentualnie jesli interval jest rodzaju enum (kilka zdefiniowanych wartosci) to moze wyjsciem bedzie rozbicie wyszukiwania na kilka zapytac SQL, kazde “proste” typu “Time.now - current_interval”
Nie masz dużego pola manewru.
Jeśli nie możesz przemodelować bazy danych (żeby np trzymać ostateczną datę zamiast/z interval) i chcesz to mieć przenośne, to w jednym zapytaniu będzie krucho wyjąć to tak jak chcesz. Ewentualnie jeśli interval jest z jakiegoś skończonego zakresu, to można coś pokombinować.
Podejdź do problemu inaczej. W bazie zapisuj sobie interwał + datę najbliższego wykonania. Co jakiś czas sprawdzasz czy są jakieś zadania do wykonania:
Request.where(“run_at > ?”, Time.now)
Po wykonaniu aktualizujesz rekord:
request.run_at = Time.now + request.interval.seconds
request.save!
tak też robię, tylko byłem ciekawy, czy można to zrobić w ten sposób bez dodawania kolejnej komórki do tabeli w bazie