data-app.lisp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. (in-package :server)
  2. (defvar *data-connections* (make-hash-table))
  3. (defun handle-new-data-connection (con env)
  4. (setf (gethash con *data-connections*)
  5. (current-id env)))
  6. (defun handle-close-data-connection (con)
  7. (remhash con *data-connections*))
  8. (defun broadcast-data (data)
  9. (loop :for con :being :the :hash-key :of *data-connections* :do
  10. (websocket-driver:send con data)))
  11. (defun data-server (env)
  12. (let ((ws (websocket-driver:make-server env)))
  13. (websocket-driver:on :open ws
  14. (lambda () (handle-new-data-connection ws env)))
  15. (websocket-driver:on :message ws
  16. (lambda (msg) msg))
  17. (websocket-driver:on :close ws
  18. (lambda (&key code reason)
  19. (declare (ignore code reason))
  20. (handle-close-data-connection ws)))
  21. (lambda (responder)
  22. (declare (ignore responder))
  23. (websocket-driver:start-connection ws))))
  24. (defparameter *data-app*
  25. (lack:builder
  26. ;;;;editors
  27. (:mount "/add"
  28. (lambda (env)
  29. (let ((parsed-json (parse-json env)))
  30. (data:with-transaction ()
  31. (let ((object (make-instance (intern
  32. (string-upcase (gethash "type" parsed-json))
  33. (find-package :data)))))
  34. (data:set-from-parsed-json object parsed-json)
  35. (broadcast-data (data:data-json object))
  36. `(200 (:content-type "text/plain") (,(format nil "~a" (data:id object)))))))))
  37. (:mount "/set"
  38. (lambda (env)
  39. (let* ((parsed-json (parse-json env))
  40. (old-data (data:data-with-id (gethash "id" parsed-json))))
  41. (cond (old-data
  42. (data:with-transaction ()
  43. (data:set-from-parsed-json old-data parsed-json))
  44. (broadcast-data (data:data-json old-data))
  45. `(200 (:content-type "text/plain") ("set")))
  46. (t `(200 (:content-type "text/plain") ("no longer exists")))))))
  47. (:mount "/delete"
  48. (lambda (env)
  49. (let ((object (data:data-with-id (parse-integer
  50. (subseq (getf env :path-info) 1)))))
  51. (cond ((> (length (data:all-of object)) 1)
  52. (let ((msg (format nil "{\"delete\":true,\"data\":~a}"
  53. (data:data-json object))))
  54. (broadcast-data msg))
  55. (data:delete-data object)
  56. `(200 (:content-type "text/plain") ("deleted")))
  57. (t `(200 (:content-type "text/plain") ("saved last of kind")))))))
  58. ;;;;all of type
  59. (:mount "/all"
  60. (lambda (env)
  61. (let* ((type (intern (string-upcase (subseq (getf env :path-info) 1))
  62. (find-package :data)))
  63. (json (data:data-type-json type)))
  64. `(200 (:content-type "application/json")
  65. (,json)))))
  66. ;;;;by id
  67. (:mount "/get"
  68. (lambda (env)
  69. (let* ((path (getf env :path-info))
  70. (object (data:data-with-id (parse-integer path))))
  71. `(200 (:content-type "application/json") (,(data:data-json object))))))
  72. (:mount "/highest-id"
  73. (lambda (env)
  74. (declare (ignore env))
  75. (let ((highest-id (format nil "~a"
  76. (apply #'max (mapcar #'data:id (data:all-data))))))
  77. `(200 (:content-type "application/json")
  78. (,highest-id)))))
  79. ;;;;denizen specific
  80. (:mount "/current-configuration"
  81. (lambda (env)
  82. `(200
  83. (:content-type "application/json")
  84. (,(current-configuration-json env)))))
  85. (:mount "/current-denizen"
  86. (lambda (env)
  87. `(200
  88. (:content-type "application/json")
  89. (,(data:data-json (denizenp env))))))
  90. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  91. (lambda (env)
  92. (let ((path-info (getf env :path-info)))
  93. (princ "bad data path-info: ")
  94. (princ path-info)
  95. (cond (t '(404 (:content-type "text/plain") ("no such data"))))))))