#lang pollen/mode racket/base
;; Copyright (c) 2018 Joel Dueck.
;;
;; Licensed under the Apache License, Version 2.0 (the "License");
;; you may not use this file except in compliance with the License.
;; A copy of the License is included with this source code, in the
;; file "LICENSE.txt".
;; You may also obtain a copy of the License at
;;
;; http://www.apache.org/licenses/LICENSE-2.0
;;
;; Unless required by applicable law or agreed to in writing, software
;; distributed under the License is distributed on an "AS IS" BASIS,
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
;; See the License for the specific language governing permissions and
;; limitations under the License.
;;
;; Author contact information:
;; joel@jdueck.net
;; https://joeldueck.com
;; -------------------------------------------------------------------------
;; Provides functions for fast preserving and fetching of article/series data.
;; → Docs and metas go in (saved to SQLite database)
;; HTML comes out →
;; Calling sites have no notion of the database or schema.
;; The functions provided by sqlite-tools.rkt are not safe for user-provided
;; data; a maliciously crafted input could bomb the database. This is acceptable
;; since the database is merely a disposable cache, and since all the input
;; will be coming from me.
(require pollen/setup
pollen/core
pollen/template
pollen/pagetree
racket/string
"sqlite-tools.rkt"
"template-html.rkt"
"dates.rkt")
;; ~~~ Provides ~~~
(provide spell-of-summoning!
crystalize-article!)
;; ~~~ Private use ~~~
(define DBFILE (build-path (current-project-root) "vitreous.sqlite"))
(define table_articles-fields
'(pagenode
title
published
updated
doc_html
author
conceal
series_pagenode
noun_singular
note_count))
(define table_notes-fields
'(pagenode
note-id
heading
author
date
note_html))
(define table_series-fields
'(pagenode
title
published
noun_plural
noun_singular))
(define table_articles (make-table-schema "articles" table_articles-fields))
(define table_notes (make-table-schema "notes" table_notes-fields #:primary-key-cols '(pagenode note-id)))
(define table_series (make-table-schema "series" table_series-fields))
(define (optional-meta m)
(or (select-from-metas m (current-metas)) ""))
(define (series-noun)
(define series-pagenode (->pagenode (or (select-from-metas 'series (current-metas)) "")))
(case series-pagenode
['|| ""] ; no series specified
[else (or (select-from-metas 'noun-singular series-pagenode) "")]))
;; ~~~ Provided functions: Initializing; Saving posts and notes
;; Initialize the database connection, creating the database if it doesn’t
;; exist, and executing the table schema queries
;;
(define (spell-of-summoning!)
(init-db! DBFILE table_articles table_notes table_series))
;; Save an article (using current-doc and current-metas) and its notes (if any)
;; to the database, and return the rendered HTML.
;;
(define (crystalize-article! pagenode doc)
(define header (html-article-header))
(define footer (html-article-footer))
(define body (->html (cdr doc)))
;; TK: store notes separately
(define saving-query (make-insert/replace-query 'articles table_articles-fields))
(query! saving-query
(symbol->string pagenode)
(optional-meta 'title)
(select-from-metas 'published (current-metas))
(optional-meta 'updated)
(string-append header body footer)
(optional-meta 'author)
(optional-meta 'conceal)
(optional-meta 'series)
(series-noun)
0) ; note_count
`(@ ,header ,body ,footer))