Daniel J. Summers
c29bbc04ac
- Add data types and fields - Implement in both RethinkDB and SQLite - Add uploads to backup/restore - Add empty upload folder to project - Add indexes to SQLite tables (#15)
384 lines
18 KiB
Forth
384 lines
18 KiB
Forth
namespace MyWebLog.Data
|
|
|
|
open Microsoft.Data.Sqlite
|
|
open Microsoft.Extensions.Logging
|
|
open MyWebLog.Data.SQLite
|
|
|
|
/// SQLite myWebLog data implementation
|
|
type SQLiteData (conn : SqliteConnection, log : ILogger<SQLiteData>) =
|
|
|
|
/// Determine if the given table exists
|
|
let tableExists (table : string) = backgroundTask {
|
|
use cmd = conn.CreateCommand ()
|
|
cmd.CommandText <- "SELECT COUNT(*) FROM sqlite_master WHERE type = 'table' AND name = @table"
|
|
cmd.Parameters.AddWithValue ("@table", table) |> ignore
|
|
let! count = count cmd
|
|
return count = 1
|
|
}
|
|
|
|
/// The connection for this instance
|
|
member _.Conn = conn
|
|
|
|
/// Make a SQLite connection ready to execute commends
|
|
static member setUpConnection (conn : SqliteConnection) = backgroundTask {
|
|
do! conn.OpenAsync ()
|
|
use cmd = conn.CreateCommand ()
|
|
cmd.CommandText <- "PRAGMA foreign_keys = TRUE"
|
|
let! _ = cmd.ExecuteNonQueryAsync ()
|
|
()
|
|
}
|
|
|
|
interface IData with
|
|
|
|
member _.Category = SQLiteCategoryData conn
|
|
member _.Page = SQLitePageData conn
|
|
member _.Post = SQLitePostData conn
|
|
member _.TagMap = SQLiteTagMapData conn
|
|
member _.Theme = SQLiteThemeData conn
|
|
member _.ThemeAsset = SQLiteThemeAssetData conn
|
|
member _.Upload = SQLiteUploadData conn
|
|
member _.WebLog = SQLiteWebLogData conn
|
|
member _.WebLogUser = SQLiteWebLogUserData conn
|
|
|
|
member _.startUp () = backgroundTask {
|
|
|
|
use cmd = conn.CreateCommand ()
|
|
|
|
// Theme tables
|
|
match! tableExists "theme" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating theme table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE theme (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
version TEXT NOT NULL)"""
|
|
do! write cmd
|
|
match! tableExists "theme_template" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating theme_template table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE theme_template (
|
|
theme_id TEXT NOT NULL REFERENCES theme (id),
|
|
name TEXT NOT NULL,
|
|
template TEXT NOT NULL,
|
|
PRIMARY KEY (theme_id, name))"""
|
|
do! write cmd
|
|
match! tableExists "theme_asset" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating theme_asset table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE theme_asset (
|
|
theme_id TEXT NOT NULL REFERENCES theme (id),
|
|
path TEXT NOT NULL,
|
|
updated_on TEXT NOT NULL,
|
|
data BLOB NOT NULL,
|
|
PRIMARY KEY (theme_id, path))"""
|
|
do! write cmd
|
|
|
|
// Web log tables
|
|
match! tableExists "web_log" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating web_log table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE web_log (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
subtitle TEXT,
|
|
default_page TEXT NOT NULL,
|
|
posts_per_page INTEGER NOT NULL,
|
|
theme_id TEXT NOT NULL REFERENCES theme (id),
|
|
url_base TEXT NOT NULL,
|
|
time_zone TEXT NOT NULL,
|
|
auto_htmx INTEGER NOT NULL DEFAULT 0,
|
|
uploads TEXT NOT NULL,
|
|
feed_enabled INTEGER NOT NULL DEFAULT 0,
|
|
feed_name TEXT NOT NULL,
|
|
items_in_feed INTEGER,
|
|
category_enabled INTEGER NOT NULL DEFAULT 0,
|
|
tag_enabled INTEGER NOT NULL DEFAULT 0,
|
|
copyright TEXT);
|
|
CREATE INDEX web_log_theme_idx ON web_log (theme_id)"""
|
|
do! write cmd
|
|
match! tableExists "web_log_feed" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating web_log_feed table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE web_log_feed (
|
|
id TEXT PRIMARY KEY,
|
|
web_log_id TEXT NOT NULL REFERENCES web_log (id),
|
|
source TEXT NOT NULL,
|
|
path TEXT NOT NULL);
|
|
CREATE INDEX web_log_feed_web_log_idx ON web_log_feed (web_log_id)"""
|
|
do! write cmd
|
|
match! tableExists "web_log_feed_podcast" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating web_log_feed_podcast table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE web_log_feed_podcast (
|
|
feed_id TEXT PRIMARY KEY REFERENCES web_log_feed (id),
|
|
title TEXT NOT NULL,
|
|
subtitle TEXT,
|
|
items_in_feed INTEGER NOT NULL,
|
|
summary TEXT NOT NULL,
|
|
displayed_author TEXT NOT NULL,
|
|
email TEXT NOT NULL,
|
|
image_url TEXT NOT NULL,
|
|
itunes_category TEXT NOT NULL,
|
|
itunes_subcategory TEXT,
|
|
explicit TEXT NOT NULL,
|
|
default_media_type TEXT,
|
|
media_base_url TEXT,
|
|
guid TEXT,
|
|
funding_url TEXT,
|
|
funding_text TEXT,
|
|
medium TEXT)"""
|
|
do! write cmd
|
|
|
|
// Category table
|
|
match! tableExists "category" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating category table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE category (
|
|
id TEXT PRIMARY KEY,
|
|
web_log_id TEXT NOT NULL REFERENCES web_log (id),
|
|
name TEXT NOT NULL,
|
|
slug TEXT NOT NULL,
|
|
description TEXT,
|
|
parent_id TEXT);
|
|
CREATE INDEX category_web_log_idx ON category (web_log_id)"""
|
|
do! write cmd
|
|
|
|
// Web log user table
|
|
match! tableExists "web_log_user" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating web_log_user table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE web_log_user (
|
|
id TEXT PRIMARY KEY,
|
|
web_log_id TEXT NOT NULL REFERENCES web_log (id),
|
|
user_name TEXT NOT NULL,
|
|
first_name TEXT NOT NULL,
|
|
last_name TEXT NOT NULL,
|
|
preferred_name TEXT NOT NULL,
|
|
password_hash TEXT NOT NULL,
|
|
salt TEXT NOT NULL,
|
|
url TEXT,
|
|
authorization_level TEXT NOT NULL);
|
|
CREATE INDEX web_log_user_web_log_idx ON web_log_user (web_log_id);
|
|
CREATE INDEX web_log_user_user_name_idx ON web_log_user (web_log_id, user_name)"""
|
|
do! write cmd
|
|
|
|
// Page tables
|
|
match! tableExists "page" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating page table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE page (
|
|
id TEXT PRIMARY KEY,
|
|
web_log_id TEXT NOT NULL REFERENCES web_log (id),
|
|
author_id TEXT NOT NULL REFERENCES web_log_user (id),
|
|
title TEXT NOT NULL,
|
|
permalink TEXT NOT NULL,
|
|
published_on TEXT NOT NULL,
|
|
updated_on TEXT NOT NULL,
|
|
show_in_page_list INTEGER NOT NULL DEFAULT 0,
|
|
template TEXT,
|
|
page_text TEXT NOT NULL);
|
|
CREATE INDEX page_web_log_idx ON page (web_log_id);
|
|
CREATE INDEX page_author_idx ON page (author_id);
|
|
CREATE INDEX page_permalink_idx ON page (web_log_id, permalink)"""
|
|
do! write cmd
|
|
match! tableExists "page_meta" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating page_meta table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE page_meta (
|
|
page_id TEXT NOT NULL REFERENCES page (id),
|
|
name TEXT NOT NULL,
|
|
value TEXT NOT NULL,
|
|
PRIMARY KEY (page_id, name, value))"""
|
|
do! write cmd
|
|
match! tableExists "page_permalink" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating page_permalink table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE page_permalink (
|
|
page_id TEXT NOT NULL REFERENCES page (id),
|
|
permalink TEXT NOT NULL,
|
|
PRIMARY KEY (page_id, permalink))"""
|
|
do! write cmd
|
|
match! tableExists "page_revision" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating page_revision table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE page_revision (
|
|
page_id TEXT NOT NULL REFERENCES page (id),
|
|
as_of TEXT NOT NULL,
|
|
revision_text TEXT NOT NULL,
|
|
PRIMARY KEY (page_id, as_of))"""
|
|
do! write cmd
|
|
|
|
// Post tables
|
|
match! tableExists "post" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post (
|
|
id TEXT PRIMARY KEY,
|
|
web_log_id TEXT NOT NULL REFERENCES web_log (id),
|
|
author_id TEXT NOT NULL REFERENCES web_log_user (id),
|
|
status TEXT NOT NULL,
|
|
title TEXT NOT NULL,
|
|
permalink TEXT NOT NULL,
|
|
published_on TEXT,
|
|
updated_on TEXT NOT NULL,
|
|
template TEXT,
|
|
post_text TEXT NOT NULL);
|
|
CREATE INDEX post_web_log_idx ON post (web_log_id);
|
|
CREATE INDEX post_author_idx ON post (author_id);
|
|
CREATE INDEX post_status_idx ON post (web_log_id, status, updated_on);
|
|
CREATE INDEX post_permalink_idx ON post (web_log_id, permalink)"""
|
|
do! write cmd
|
|
match! tableExists "post_category" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post_category table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post_category (
|
|
post_id TEXT NOT NULL REFERENCES post (id),
|
|
category_id TEXT NOT NULL REFERENCES category (id),
|
|
PRIMARY KEY (post_id, category_id));
|
|
CREATE INDEX post_category_category_idx ON post_category (category_id)"""
|
|
do! write cmd
|
|
match! tableExists "post_episode" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post_episode table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post_episode (
|
|
post_id TEXT PRIMARY KEY REFERENCES post(id),
|
|
media TEXT NOT NULL,
|
|
length INTEGER NOT NULL,
|
|
duration TEXT,
|
|
media_type TEXT,
|
|
image_url TEXT,
|
|
subtitle TEXT,
|
|
explicit TEXT,
|
|
chapter_file TEXT,
|
|
chapter_type TEXT,
|
|
transcript_url TEXT,
|
|
transcript_type TEXT,
|
|
transcript_lang TEXT,
|
|
transcript_captions INTEGER,
|
|
season_number INTEGER,
|
|
season_description TEXT,
|
|
episode_number TEXT,
|
|
episode_description TEXT)"""
|
|
do! write cmd
|
|
match! tableExists "post_tag" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post_tag table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post_tag (
|
|
post_id TEXT NOT NULL REFERENCES post (id),
|
|
tag TEXT NOT NULL,
|
|
PRIMARY KEY (post_id, tag))"""
|
|
do! write cmd
|
|
match! tableExists "post_meta" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post_meta table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post_meta (
|
|
post_id TEXT NOT NULL REFERENCES post (id),
|
|
name TEXT NOT NULL,
|
|
value TEXT NOT NULL,
|
|
PRIMARY KEY (post_id, name, value))"""
|
|
do! write cmd
|
|
match! tableExists "post_permalink" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post_permalink table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post_permalink (
|
|
post_id TEXT NOT NULL REFERENCES post (id),
|
|
permalink TEXT NOT NULL,
|
|
PRIMARY KEY (post_id, permalink))"""
|
|
do! write cmd
|
|
match! tableExists "post_revision" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post_revision table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post_revision (
|
|
post_id TEXT NOT NULL REFERENCES post (id),
|
|
as_of TEXT NOT NULL,
|
|
revision_text TEXT NOT NULL,
|
|
PRIMARY KEY (post_id, as_of))"""
|
|
do! write cmd
|
|
match! tableExists "post_comment" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating post_comment table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE post_comment (
|
|
id TEXT PRIMARY KEY,
|
|
post_id TEXT NOT NULL REFERENCES post(id),
|
|
in_reply_to_id TEXT,
|
|
name TEXT NOT NULL,
|
|
email TEXT NOT NULL,
|
|
url TEXT,
|
|
status TEXT NOT NULL,
|
|
posted_on TEXT NOT NULL,
|
|
comment_text TEXT NOT NULL);
|
|
CREATE INDEX post_comment_post_idx ON post_comment (post_id)"""
|
|
do! write cmd
|
|
|
|
// Tag map table
|
|
match! tableExists "tag_map" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating tag_map table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE tag_map (
|
|
id TEXT PRIMARY KEY,
|
|
web_log_id TEXT NOT NULL REFERENCES web_log (id),
|
|
tag TEXT NOT NULL,
|
|
url_value TEXT NOT NULL);
|
|
CREATE INDEX tag_map_web_log_idx ON tag_map (web_log_id)"""
|
|
do! write cmd
|
|
|
|
// Uploaded file table
|
|
match! tableExists "upload" with
|
|
| true -> ()
|
|
| false ->
|
|
log.LogInformation "Creating upload table..."
|
|
cmd.CommandText <- """
|
|
CREATE TABLE upload (
|
|
id TEXT PRIMARY KEY,
|
|
web_log_id TEXT NOT NULL REFERENCES web_log (id),
|
|
path TEXT NOT NULL,
|
|
updated_on TEXT NOT NULL,
|
|
data BLOB NOT NULL);
|
|
CREATE INDEX upload_web_log_idx ON upload (web_log_id);
|
|
CREATE INDEX upload_path_idx ON upload (web_log_id, path)"""
|
|
do! write cmd
|
|
}
|