This commit is contained in:
2026-04-17 16:33:13 +02:00
parent 61e3e255ea
commit 3c51066fad
17 changed files with 3490 additions and 0 deletions

139
scrbl/keystore.scrbl~ Normal file
View File

@@ -0,0 +1,139 @@
#lang scribble/manual
@title{Keystore}
@defmodule[keystore]
A small persistent keyvalue store backed by SQLite. Keys and values
may be arbitrary Racket values and are stored using transparent
serialization.
@section{Overview}
The keystore provides persistent storage with automatic
serialization and deserialization. Keys are additionally stored in a
stringified lowercase form, which allows glob-style queries.
@section{Structure}
@defstruct*[keystore
([file any/c]
[path path?]
[dbh any/c])]{
Represents an open keystore. The @racket[file] field contains the
original argument, @racket[path] is the resolved database path, and
@racket[dbh] is the SQLite connection.
}
@section{Opening}
@defproc[(ks-open [file (or/c path? string? symbol?)]) keystore?]{
Opens or creates a keystore. When @racket[file] is a symbol, a cache
location is used; otherwise it is interpreted as a filesystem path.
The database schema is created automatically if it does not yet exist.
}
@section{Basic Operations}
@defproc[(ks-set! [ks keystore?] [key any/c] [value any/c]) boolean?]{
Stores @racket[value] under @racket[key], replacing any existing value.
The function always returns @racket[#t].
}
@defproc[(ks-get [ks keystore?] [key any/c] [default any/c] ...) any/c]{
Retrieves the value associated with @racket[key]. If the key is not
present, the provided default value is returned when given; otherwise
the symbol @racket['ks-nil] is returned.
}
@defproc[(ks-exists? [ks keystore?] [key any/c]) boolean?]{
Returns @racket[#t] if the key exists, and @racket[#f] otherwise.
}
@defproc[(ks-drop! [ks keystore?] [key any/c]) boolean?]{
Removes the key from the store. The function always returns @racket[#t].
}
@section{Enumeration}
@defproc[(ks-keys [ks keystore?]) (listof any/c)]{
Returns all keys in the store.
}
@defproc[(ks-key-values [ks keystore?]) (listof (cons/c any/c any/c))]{
Returns all keyvalue pairs as cons cells.
}
@section{Glob Queries}
Glob queries operate on a lowercase string representation of keys.
@defproc[(ks-keys-glob [ks keystore?] [pattern string?]) (listof any/c)]{
Returns all keys whose string form matches @racket[pattern].
}
@defproc[(ks-key-values-glob [ks keystore?] [pattern string?])
(listof (cons/c any/c any/c))]{
Returns keyvalue pairs whose keys match @racket[pattern].
}
@section{Raw Access}
@defproc[(ks-keys-raw [ks keystore?]) list?]{
Returns raw key rows in the form:
@racketblock[
(list key-string str-key)
]
}
@defproc[(ks-key-values-raw [ks keystore?]) list?]{
Returns raw keyvalue rows in the form:
@racketblock[
(list key-string str-key value-string)
]
}
@section{Examples}
@subsection{Basic Usage}
@racketblock[
(define ks (ks-open 'demo))
(ks-set! ks 'a 42)
(ks-set! ks "b" '(1 2 3))
(ks-get ks 'a) ; => 42
(ks-get ks 'missing) ; => 'ks-nil
(ks-get ks 'missing 0) ; => 0
]
@subsection{Enumeration}
@racketblock[
(ks-keys ks)
;; => '(a "b")
(ks-key-values ks)
;; => '((a . 42) ("b" . (1 2 3)))
]
@subsection{Glob Queries}
@racketblock[
(ks-keys-glob ks "*b*")
]