src/models/post.lisp
(defpackage murja.models.post
(:use :cl)
(:export :get-page :get-post :post-id :post-title :article :creator :tags :created-at :post-hidden? :post-unlisted?)
(:import-from :com.inuoe.jzon :parse))
(in-package :murja.models.post)
;; fuck it we're moving from hashmaps to clos now
(defclass Post ()
;; slots are copied from the table blog.Post, accessors are what I might call these were I designing the db nowadays
((id :initarg :id :accessor post-id :col-type integer)
(title :initarg :title :accessor post-title :col-type string)
(content :initarg :content :accessor article :col-type string)
(creator :initarg :creator :initform nil :accessor creator)
(creator-id :col-type string :reader creator-id)
(tags :initarg :tags :accessor tags :col-type string)
(created-at :initarg :created-at :accessor created-at :col-type simple-date:timestamp)
(hidden :initarg :hidden? :accessor post-hidden? :col-type boolean)
(unlisted :initarg :unlisted? :accessor post-unlisted? :col-type boolean))
(:metaclass postmodern:dao-class)
(:keys id)
(:table-name "blog.Post"))
(defmethod print-object ((p Post) output)
(with-slots (creator id title content creator-id tags created-at hidden unlisted) p
(format output "#<POST: ~{~{~a: ~s~}~^,~%~t ~}>" (list
(list :id id)
(list :title title)
(list :content
(if (> (length content) 50)
(format nil "~a..."
(str:substring 0 50 content))
content))
(list :creator-id creator-id)
(list :creator creator)
(list :tags tags)
(list :created-at created-at)
(list :hidden hidden)
(list :unlisted unlisted)))))
;; (postmodern:query "SELECT * FROM blog.Post limit 1" (:dao post :single))
;; (postmodern:get-dao 'Post 349)
;; #<POST: ID: 349, TITLE: "Lisp webapps ", CONTENT: "<p>So, after <a href=\"https://feuerx.net/blog/post...", CREATOR-ID: 1, TAGS: "[\"postgresql\", \"hunchentoot\", \"lisp\", \"programming\"]", CREATED-AT: #<SIMPLE-DATE:TIMESTAMP 22-02-2025T09:31:40,016>, HIDDEN: NIL, UNLISTED: NIL>
(defun fix-post (p)
(setf (tags p) (parse (tags p)))
(setf (creator p) (postmodern:get-dao 'murja.models.user:user (creator-id p)))
p)
(defun get-post (id)
(let ((p (postmodern:get-dao 'Post id)))
(fix-post p)
p))
(defun get-page (page page-size &key allow-hidden? modified-since)
(let* ((page (if (< page 1)
1
page)))
(map 'list
#'fix-post
(postmodern:query
"SELECT p.*
FROM blog.Post p
WHERE ((NOT p.unlisted) OR $3)
AND ((NOT p.hidden) OR $3)
AND (($4::timestamp IS NULL) OR p.created_at > $4::timestamp)
ORDER BY p.created_at DESC
LIMIT $2
OFFSET $1"
(* (1- page) page-size)
page-size
allow-hidden?
(if modified-since
modified-since
:null)
(:dao Post)))))