On this page:
7.1 Cache database
cache-conn
init-cache-db!
7.2 Retrieving cached data
fenced-listing
listing-htmls
articles
articles+  notes
unfence
7.3 Modifying the cache
save-cache-things!
delete-article!
delete-notes!
7.4 Schema
cache:  article
cache:  note
cache:  index-entry
listing
7.7

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)  connection?

(cache-conn conn)  void?
  conn : connection?
The database connection.

procedure

(init-cache-db!)  void?

Creates and initializes the SQLite database cache file (named "vitreous.sqlite" and located in the project root folder) by running queries to create tables in the database if they do not exist.

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?
Fetches a the HTML strings from the SQLite cache and returns a 'style tagged X-expression with these strings as its elements. The query will usually be the result of a call to articles or articles+notes, but can be any custom query that projects onto the listing schema (see project-onto).

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?
Returns the HTML bodies for the articles and/or notes returned by listing-query as a list of strings. The query will usually be the result of a call to articles or articles+notes, but can be any custom query that projects onto the listing schema (see project-onto).

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
Create a query that fetches either articles only, or articles and notes intermingled, respectively. The results will be sorted by publish date according to order and optionally limited to a particular series. Use the resulting query with the listing-htmls or fenced-listing functions provided by this module, or with deta’s in-entities if you want to work with the listing schema structs.

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.

Example:
> (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)

procedure

(unfence html)  string?

  html : string?
Returns html with all occurrences of "<style>" and "</style>" removed. The contents of the style tags are left intact.

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?))
Saves all the things to the cache database.

procedure

(delete-article! page)  void?

  page : stringish?

procedure

(delete-notes! page)  void?

  page : stringish?
Delete a particular article, or all notes for a particular article, respectively.

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
Table holding cached article information.

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
Table holding cached information on notes.

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
Table holding cached information about index entries found in articles.

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
This is a “virtual” schema targeted by articles and articles+notes using deta’s project-onto. It supplies the minimum set of fields needed to build the RSS feed, and which are common to both articles and notes; most times (e.g., on series pages) only the html field is used, via fenced-listing or listing-htmls.