1 (uiop:define-package
#:lw2.backend-modules
3 (:import-from
#:alexandria
#:symbolicate
)
5 #:backend-class
#:class-cached-databases
#:class-own-databases
#:class-databases-epoch
7 #:backend-lmdb-cache
#:backend-lmdb-environment
#:backend-cache-db-path
10 #:backend-password-login
11 #:backend-websocket-login
12 #:backend-passport-js-login
13 #:backend-oauth2.0-login
14 #:graphql-uri
#:websocket-uri
#:algolia-search-uri
#:rest-api-uri
15 #:oauth2.0-login-uri
#:oauth2.0-client-id
#:oauth2.0-client-secret
16 #:backend-feed-crossposts
17 #:backend-q-and-a
#:backend-related-questions
19 #:backend-alignment-forum
23 #:backend-push-notifications
25 #:backend-lw2-tags-comments
26 #:backend-lw2-wiki-tags
27 #:backend-magnum-crossposts
#:backend-magnum-crosspost-site
28 #:backend-lw2-misc-workarounds
29 #:backend-lw2-misc-features
30 #:backend-lw2-legacy
#:backend-lw2-modernized
#:backend-lw2
#:backend-algolia-search
#:backend-ea-forum
#:backend-accordius
32 #:make-backend
#:define-backend-function
#:define-backend-operation
#:backend
33 #:call-with-backend-context
)
34 (:unintern
#:declare-backend-function
)
35 (:recycle
#:lw2.backend
#:lw2.login
))
37 (in-package #:lw2.backend-modules
)
39 (defclass backend-class
(standard-class)
40 ((cached-databases :accessor class-cached-databases
:initform nil
)
41 (own-databases :accessor class-own-databases
:initform nil
)
42 (databases-epoch :accessor class-databases-epoch
:initform
0)))
44 (defmethod closer-mop:validate-superclass
((c backend-class
) (sc standard-class
))
47 (defclass backend-base
() () (:metaclass backend-class
))
49 (defclass backend-lmdb-cache
(backend-base)
50 ((lmdb-environment :accessor backend-lmdb-environment
:initform nil
)
51 (cache-db-path :accessor backend-cache-db-path
:initarg
:cache-db-path
:type simple-string
))
52 (:metaclass backend-class
))
54 (defclass backend-graphql
(backend-lmdb-cache)
55 ((graphql-uri :accessor graphql-uri
:initarg
:graphql-uri
:type simple-string
))
56 (:metaclass backend-class
))
58 (defclass backend-token-login
(backend-base) ()
59 (:metaclass backend-class
))
61 (defclass backend-password-login
(backend-base) ()
62 (:metaclass backend-class
))
64 (defclass backend-websocket-login
(backend-token-login backend-password-login
)
65 ((websocket-uri :accessor websocket-uri
:initarg
:websocket-uri
:type simple-string
))
66 (:metaclass backend-class
))
68 (defclass backend-passport-js-login
(backend-token-login backend-password-login
) ()
69 (:metaclass backend-class
))
71 (defclass backend-oauth2.0-login
(backend-token-login)
72 ((oauth2.0-login-uri
:accessor oauth2.0-login-uri
:initarg
:oauth2.0-login-uri
:type simple-string
)
73 (oauth2.0-client-id
:accessor oauth2.0-client-id
:initarg
:oauth2.0-client-id
:type simple-string
)
74 (oauth2.0-client-secret
:accessor oauth2.0-client-secret
:initarg
:oauth2.0-client-secret
:type simple-string
))
75 (:metaclass backend-class
))
77 (defclass backend-algolia-search
(backend-base)
78 ((algolia-search-uri :accessor algolia-search-uri
:initarg
:algolia-search-uri
:type simple-string
))
79 (:metaclass backend-class
))
81 (defclass backend-feed-crossposts
(backend-graphql) ()
82 (:metaclass backend-class
))
84 (defclass backend-q-and-a
(backend-graphql) ()
85 (:metaclass backend-class
))
87 (defclass backend-related-questions
(backend-graphql) ()
88 (:metaclass backend-class
))
90 (defclass backend-debates
(backend-graphql) ()
91 (:metaclass backend-class
))
93 (defclass backend-backlinks
(backend-lmdb-cache) ()
94 (:metaclass backend-class
))
96 (defclass backend-push-notifications
(backend-lmdb-cache) ()
97 (:metaclass backend-class
))
99 (defclass backend-alignment-forum
(backend-graphql) ()
100 (:metaclass backend-class
))
102 (defclass backend-events
(backend-graphql) ()
103 (:metaclass backend-class
))
105 (defclass backend-shortform
(backend-graphql) ()
106 (:metaclass backend-class
))
108 (defclass backend-lw2-tags
(backend-graphql) ()
109 (:metaclass backend-class
))
111 (defclass backend-lw2-tags-comments
(backend-lw2-tags) ()
112 (:metaclass backend-class
))
114 (defclass backend-magnum-crossposts
(backend-graphql)
115 ((magnum-crosspost-site :accessor backend-magnum-crosspost-site
:initarg
:magnum-crosspost-site
:type
(or simple-string null
) :initform nil
))
116 (:metaclass backend-class
))
118 (defclass backend-lw2-wiki-tags
(backend-lw2-tags) ()
119 (:metaclass backend-class
))
121 (defclass backend-lw2-misc-workarounds
(backend-graphql) ()
122 (:metaclass backend-class
))
124 (defclass backend-lw2-misc-features
(backend-graphql) ()
125 (:metaclass backend-class
))
127 (defclass backend-lw2-legacy
(backend-graphql) ()
128 (:metaclass backend-class
))
130 (defclass backend-lw2-modernized
(backend-graphql) ()
131 (:metaclass backend-class
))
133 (defclass backend-lw2
(backend-passport-js-login
134 backend-lw2-modernized
136 backend-lw2-misc-workarounds
137 backend-lw2-misc-features
138 backend-algolia-search
140 backend-related-questions
142 backend-alignment-forum
144 backend-feed-crossposts
146 backend-push-notifications
148 backend-lw2-tags-comments
149 backend-lw2-wiki-tags
150 backend-magnum-crossposts
) ()
151 (:metaclass backend-class
))
153 (defclass backend-ea-forum
(backend-oauth2.0-login
154 backend-lw2-modernized
156 backend-lw2-misc-features
157 backend-algolia-search
159 backend-related-questions
160 backend-feed-crossposts
162 backend-push-notifications
164 backend-lw2-tags-comments
165 backend-lw2-wiki-tags
166 backend-magnum-crossposts
) ()
167 (:metaclass backend-class
))
169 (defclass backend-accordius
(backend-lw2-legacy backend-lw2-modernized
)
170 ((rest-api-uri :accessor rest-api-uri
:initarg
:rest-api-uri
:type simple-string
))
171 (:metaclass backend-class
))
173 (defclass backend-arbital
(backend-lmdb-cache) ()
174 (:metaclass backend-class
))
176 (defun make-backend (type-string &rest args
)
177 (apply #'make-instance
(symbolicate "BACKEND-" (string-upcase type-string
)) args
))
179 (defun process-operation-definition (args)
180 (let* ((latter-args (member-if #'listp args
))
181 (method-qualifiers (ldiff args latter-args
))
182 (method-args (first latter-args
))
183 (body (rest latter-args
)))
184 (values method-qualifiers method-args body
)))
186 (defun operation-name-and-lambda-list-translator (name)
187 (labels ((setf-lambda-list (backend lambda-list
)
188 `(,(first lambda-list
) (backend ,backend
) ,@(rest lambda-list
)))
189 (ordinary-lambda-list (backend lambda-list
)
190 `((backend ,backend
) ,@lambda-list
)))
192 ((list 'setf
(and (type symbol
) bare-name
))
193 (let* ((inner-bare-name (symbolicate "%" bare-name
))
194 (inner-name (list 'setf inner-bare-name
)))
197 `(defun ,name
(set-value &rest args
) (setf (apply #',inner-bare-name lw2.context
:*current-backend
* args
) set-value
))
201 (let ((inner-name (symbolicate "%" name
)))
203 #'ordinary-lambda-list
204 `(defun ,name
(&rest args
) (apply #',inner-name lw2.context
:*current-backend
* args
))
208 (error "Invalid function name: ~A" name
)))))
210 (defun names-only-lambda-list (lambda-list)
211 (map 'list
(lambda (x) (if (atom x
) x
(first x
))) lambda-list
))
213 (defmacro define-backend-function
(name lambda-list
&rest operations
)
214 (multiple-value-bind (inner-name lambda-list-translator wrapper-defun
bare-name inner-bare-name
)
215 (operation-name-and-lambda-list-translator name
)
216 (let ((lambda-list (names-only-lambda-list lambda-list
))
219 (destructuring-bind (backend &rest body
) op
220 `(:method
,(funcall lambda-list-translator backend lambda-list
) ,@body
)))
223 (export '(,bare-name
,inner-bare-name
))
224 (declaim (inline ,name
))
226 (defgeneric ,inner-name
,(names-only-lambda-list (funcall lambda-list-translator t lambda-list
)) ,.method-definitions
)))))
228 (defmacro define-backend-operation
(name backend
&rest args
)
229 (multiple-value-bind (inner-name lambda-list-translator
) (operation-name-and-lambda-list-translator name
)
230 (multiple-value-bind (method-qualifiers method-args body
) (process-operation-definition args
)
231 `(defmethod ,inner-name
,.method-qualifiers
,(funcall lambda-list-translator backend method-args
) ,@body
))))
233 (defgeneric call-with-backend-context
(backend request fn
)
234 (:method
((backend backend-base
) (request t
) fn
)