7 Cache
(require "cache.rkt") |
In this project there are several places – the blog, the footer on each page, the RSS feed, series pages — where data from an amorphous group of Pollen documents is needed. This is what the cache is for.
This module defines and provides the schema and database connection to the SQLite cache, and some functions for retrieving records from the cache. Use these when you need quick access to pre-cooked HTML.
7.1 Cache database
parameter
(cache-conn conn) → void? conn : connection?
procedure
(init-cache-db!) → void?
7.2 Retrieving cached data
Some of this looks a little wacky, but it’s a case of putting a little extra complextity into the back end to make things simple on the front end. These functions are most commonly used inside the body of a Pollen document (i.e., series pages).
"series/my-series.poly.pm"
#lang pollen ◊title{My New Series} ...some other content ◊fenced-listing[(articles+notes 'excerpt #:order 'asc)]
procedure
(fenced-listing query) → txexpr?
query : query?
The reason for enclosing the results in a 'style txexpr is to prevent the HTML from being escaped by ->html in the template. This tag was picked for the job because there will generally never be a need to include any actual CSS information inside a <style> tag in any page, so it can be safely filtered out later. To remove the enclosing <style> tag, see unfence.
procedure
(listing-htmls listing-query) → (listof string?)
listing-query : query?
procedure
(articles type [ #:series series #:limit limit order]) → query? type : (or/c 'full 'excerpt 'short 'content) series : (or/c string? (listof string?) boolean?) = #t limit : integer? = -1 order : stringish? = 'desc
procedure
(articles+notes type [ #:series series #:limit limit order]) → query? type : (or/c 'full 'excerpt 'short 'content) series : (or/c string? (listof string?) boolean?) = #t limit : integer? = -1 order : stringish? = 'desc
The type parameter specifies what version of the articles’ and notes’ HTML markup you want. For HTML suitable for listing several articles and/or notes together on the same page, use 'full (the full content but not including notes), 'excerpt (like full but abbreviated to only the excerpt if one was specified) or 'short (date and title only). Use 'content to get the entire HTML content, including any notes but not including any header or footer. (This is the option used in the RSS feed.)
If series expression evaluates to #f, articles will not be filtered by series. If it evaluates to #t (the default), articles will be filtered by those that specify the current output of here-output-path in their series_pagenode column in the SQLite cache. If a string or a symbol is supplied, articles will be filtered by those containing the result of (format "series/~a.html" series) in their series_pagenode column in the SQLite cache. If a list of strings or symbols is provided, this format operation will be applied to each of its members and articles whose series_pagenode column matches any of the resulting values will be included.
The order expression must evaluate to either "ASC" or "DESC" (or equivalent symbols) and the limit expressions must evaluate to a value suitable for use in the LIMIT clause of a SQLite SELECT statement. An expression that evaluates to a negative integer (the default) is the same as having no limit.
Typically you will pass these functions by name to listing functions like fenced-listing rather than calling them directly.
> (articles 'full)
(query
"SELECT a.page AS path, a.title_plain AS title, a.author, a.published, a.updated, a.listing_full_html AS html FROM articles AS a WHERE (a.series_page LIKE $1) AND (NOT (a.conceal LIKE '%all%')) ORDER BY a.published DESC LIMIT $2"
"%."
-1)
Use this in templates with strings returned from ->html when called on docs that use the fenced-listing tag function.
7.3 Modifying the cache
procedure
(save-cache-things! things) → void?
things : (listof (or/c cache:article? cache:note? cache:index-entry?))
procedure
(delete-article! page) → void?
page : stringish?
procedure
(delete-notes! page) → void?
page : stringish?
7.4 Schema
The cache database has four tables: articles, notes, index_entries and series. Each of these has a corresponding schema, shown below. In addition, there is a “virtual” schema, listing, for use with queries which may or may not combine articles and notes intermingled.
The work of picking apart an article’s exported doc and metas into rows in these tables is done by parse-and-cache-article!.
The below are shown as struct forms but are actually defined with deta’s define-schema. Each schema has an associated struct with the same name and a smart constructor called make-id. The struct’s “dumb” constructor is hidden so that invalid entities cannot be created. For every defined field there is an associated functional setter and updater named set-id-field and update-id-field, respectively.
struct
(struct cache:article ( id page title-plain title-html-flow title-specified published updated author conceal series-page noun-singular note-count content-html disposition disp-html-anchor listing-full-html listing-excerpt-html listing-short-html) #:constructor-name make-cache:article) id : id/f page : symbol/f title-plain : string/f title-html-flow : string/f title-specified : boolean/f published : string/f updated : string/f author : string/f conceal : string/f series-page : string/f noun-singular : string/f note-count : integer/f content-html : string/f disposition : string/f disp-html-anchor : string/f listing-full-html : string/f listing-excerpt-html : string/f listing-short-html : string/f
When creating a cache:article (should you ever need to do so directly, which is unlikely), the only required fields are page, title, and conceal.
struct
(struct cache:note ( id page html-anchor title-html-flow title-plain author author-url published disposition content-html series-page conceal listing-full-html listing-excerpt-html listing-short-html) #:constructor-name make-cache:note) id : id/f page : symbol/f html-anchor : string/f title-html-flow : string/f title-plain : string/f author : string/f author-url : string/f published : string/f disposition : string/f content-html : string/f series-page : symbol/f conceal : string/f listing-full-html : string/f listing-excerpt-html : string/f listing-short-html : string/f
struct
(struct cache:index-entry (id entry subentry page html-anchor) #:constructor-name make-cache:index-entry) id : id/f entry : string/f subentry : string/f page : symbol/f html-anchor : string/f
struct
(struct listing (path title author published updated html) #:constructor-name make-listing) path : string/f title : string/f author : string/f published : string/f updated : string/f html : string/f