db.lisp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. (in-package #:chatikbot)
  2. (defvar *db-name* "db.sqlite" "SQLite database name")
  3. (defun db-path ()
  4. (merge-pathnames *db-name*
  5. (asdf:component-pathname
  6. (asdf:find-system '#:chatikbot))))
  7. (defun db-init ()
  8. (unless (probe-file (db-path))
  9. (sqlite:with-open-database (db (db-path))
  10. (sqlite:execute-non-query db "create table finance (ts, usd, eur, gbp, brent)")
  11. (sqlite:execute-non-query db "create index fin_ts_ids on finance (ts)"))))
  12. (defun db-add-finance (ts usd eur gbp brent)
  13. (sqlite:with-open-database (db (db-path) :busy-timeout 10)
  14. (sqlite:execute-non-query db "insert into finance (ts, usd, eur, gbp, brent) values (?, ?, ?, ?, ?)"
  15. ts usd eur gbp brent)))
  16. (defun db-get-last-finance ()
  17. (sqlite:with-open-database (db (db-path) :busy-timeout 10)
  18. (sqlite:execute-one-row-m-v db "select ts, usd, eur, gbp, brent from finance order by ts desc limit 1")))
  19. (defun %finance-alist (statement)
  20. (let ((names (sqlite:statement-column-names statement))
  21. (map '(("usd" . "USD/RUB") ("eur" . "EUR/RUB") ("gbp" . "GBP/RUB") ("brent" . "Brent"))))
  22. (cons (sqlite:statement-column-value statement 0)
  23. (loop
  24. for i from 1 below (length names)
  25. for col in (rest names)
  26. collect (cons (aget col map) (sqlite:statement-column-value statement i))))))
  27. (defun db-get-series (after-ts &optional usd eur gbp brent)
  28. (let ((sql (format nil "select ts~:[~;,usd~]~:[~;,eur~]~:[~;,gbp~]~:[~;,brent~] from finance where ts >= ? order by ts" usd eur gbp brent)))
  29. (sqlite:with-open-database (db (db-path) :busy-timeout 10)
  30. (loop
  31. with statement = (sqlite:prepare-statement db sql)
  32. initially (sqlite:bind-parameter statement 1 (local-time:timestamp-to-unix after-ts))
  33. while (sqlite:step-statement statement)
  34. collect (%finance-alist statement)
  35. finally (sqlite:finalize-statement statement)))))