|
139 | 139 | (:method :before ((obj record-timestamps-mixin))
|
140 | 140 | (let ((now (local-time:now)))
|
141 | 141 | (setf (object-created-at obj) now)
|
142 |
| - (setf (object-updated-at obj) now)))) |
| 142 | + (setf (object-updated-at obj) now))) |
| 143 | + (:documentation "Insert the object OBJ into the DB.")) |
143 | 144 |
|
144 | 145 | (defgeneric create-dao (class &rest initargs)
|
145 | 146 | (:method ((class-name symbol) &rest initargs)
|
146 | 147 | (apply #'create-dao (find-class class-name) initargs))
|
147 | 148 | (:method ((class dao-table-class) &rest initargs)
|
148 | 149 | (let ((obj (apply #'make-instance class initargs)))
|
149 | 150 | (setf (dao-synced obj) nil)
|
150 |
| - (save-dao obj)))) |
| 151 | + (save-dao obj))) |
| 152 | + (:documentation "Create an object of class CLASS with INITARGS and save it into the DB. |
| 153 | +
|
| 154 | +Example: |
| 155 | +
|
| 156 | +(mito:create-dao 'user :name \"Eitaro Fukamachi\" :email \"[email protected]\") |
| 157 | +
|
| 158 | +same as: |
| 159 | +
|
| 160 | +(defvar me |
| 161 | + (make-instance 'user :name \"Eitaro Fukamachi\" :email \"[email protected]\")) |
| 162 | +;=> USER |
| 163 | +
|
| 164 | +(mito:insert-dao me)")) |
151 | 165 |
|
152 | 166 | (defgeneric update-dao (obj &key columns)
|
153 | 167 | (:method ((obj dao-class) &key columns)
|
|
167 | 181 | (:method :before ((obj record-timestamps-mixin) &key columns)
|
168 | 182 | (declare (ignore columns))
|
169 | 183 | (let ((now (local-time:now)))
|
170 |
| - (setf (object-updated-at obj) now)))) |
| 184 | + (setf (object-updated-at obj) now))) |
| 185 | + (:documentation "Update the object OBJ into the DB.")) |
171 | 186 |
|
172 | 187 | (defgeneric delete-dao (obj)
|
173 | 188 | (:method ((obj dao-class))
|
|
184 | 199 | `(:= ,(unlispify key) ,(slot-value obj key)))
|
185 | 200 | primary-key)))))
|
186 | 201 | (setf (dao-synced obj) nil)))
|
187 |
| - (values))) |
| 202 | + (values)) |
| 203 | + (:documentation "Delete the object OBJ from the DB.")) |
188 | 204 |
|
189 | 205 | (defgeneric delete-by-values (class &rest fields-and-values)
|
190 | 206 | (:method ((class symbol) &rest fields-and-values)
|
|
194 | 210 | (execute-sql
|
195 | 211 | (sxql:delete-from (sxql:make-sql-symbol (table-name class))
|
196 | 212 | (where-and fields-and-values class))))
|
197 |
| - (values))) |
| 213 | + (values)) |
| 214 | + (:documentation "Delete the records of class CLASS matching FIELDS-AND-VALUES from the DB. |
| 215 | +For example: (mito:delete-by-values 'user :id 1)")) |
198 | 216 |
|
199 | 217 | (defgeneric save-dao (obj)
|
200 | 218 | (:method ((obj dao-class))
|
201 | 219 | (if (dao-synced obj)
|
202 | 220 | (update-dao obj)
|
203 |
| - (insert-dao obj)))) |
| 221 | + (insert-dao obj))) |
| 222 | + (:documentation "Save the object OBJ into the DB.")) |
204 | 223 |
|
205 | 224 | (defstruct mito-cursor
|
206 | 225 | cursor
|
|
342 | 361 | (defparameter *want-cursor* nil)
|
343 | 362 |
|
344 | 363 | (defmacro select-dao (class &body clauses)
|
| 364 | + "Build custom queries with SxQL. |
| 365 | +
|
| 366 | +Example: |
| 367 | +
|
| 368 | + (select-dao 'tweet |
| 369 | + (where (:like :status \"%Japan%\"))) |
| 370 | +
|
| 371 | +You can use \"includes\" to eagerly load another table and prevent the \"N+1 query\" performance problem. |
| 372 | +
|
| 373 | +Example: |
| 374 | +
|
| 375 | + (defvar *tweets-contain-japan* |
| 376 | + (select-dao 'tweet |
| 377 | + (includes 'user) |
| 378 | + (where (:like :status \"%Japan%\")))) |
| 379 | +
|
| 380 | +See the SxQL documentation for the available clauses and operators." |
345 | 381 | (with-gensyms (sql clause results include-classes foreign-class)
|
346 | 382 | (once-only (class)
|
347 | 383 | `(#+sb-package-locks locally #+sb-package-locks (declare (sb-ext:disable-package-locks sxql:where))
|
|
0 commit comments