utils.lisp 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. (in-package :cl-user)
  2. (defpackage #:timeliner.utils
  3. (:use :cl :cl-mongo)
  4. (:export
  5. #:ts->ms
  6. #:ms->ts
  7. #:$between
  8. #:make-keyword
  9. #:starts-with
  10. #:aget
  11. #:doc->plist))
  12. (in-package :timeliner.utils)
  13. (defun ts->ms (ts)
  14. (+ (* 1000 (local-time:timestamp-to-unix ts))
  15. (floor (local-time:nsec-of ts) 1000000)))
  16. (defun ms->ts (ms)
  17. (multiple-value-bind (unix msec) (floor ms 1000)
  18. (local-time:unix-to-timestamp unix :nsec (* msec 1000000))))
  19. (defgeneric $between (a from to)
  20. (:documentation "cl-mongo between query"))
  21. (defmethod $between (a from to)
  22. (kv ($>= a from) ($< a to)))
  23. (defmethod $between (a (from local-time:timestamp) (to local-time:timestamp))
  24. ($between a
  25. (cl-mongo::make-bson-time (ts->ms from))
  26. (cl-mongo::make-bson-time (ts->ms to))))
  27. (defun make-keyword (name) (values (intern (string-upcase name) "KEYWORD")))
  28. (defun starts-with (str with)
  29. (string= (subseq str 0 (min (length str)
  30. (length with)))
  31. with))
  32. (defmacro aget (key alist)
  33. `(cdr (assoc ,key ,alist :test #'string=)))
  34. (defvar *decode-doc-to* :plist "Document object type")
  35. (defgeneric decode-element (element)
  36. (:documentation "Convert cl-mongo element to preferred type"))
  37. (defmethod decode-element (element)
  38. element)
  39. (defmethod decode-element ((element document))
  40. (case *decode-doc-to*
  41. (:plist (doc->plist element))))
  42. (defmethod decode-element ((element cl-mongo::bson-time))
  43. (ms->ts (cl-mongo::raw element)))
  44. (defun doc->plist (doc)
  45. (let ((*decode-doc-to* :plist)
  46. result)
  47. (loop for key in (get-keys doc)
  48. do (setf (getf result (make-keyword key))
  49. (decode-element (get-element key doc))))
  50. result))
  51. (defmethod yason:encode ((object document) &optional (stream *standard-output*))
  52. (yason:encode (cl-mongo::elements object) stream))
  53. (defmethod yason:encode ((object cl-mongo::bson-time) &optional (stream *standard-output*))
  54. (yason:encode (cl-mongo::raw object) stream))