src/models/post.lisp

DOWNLOAD
(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)))))