init the database and move posts into the sqlite database.

This commit is contained in:
Dave Smith-Hayes 2024-07-11 21:37:12 -04:00
parent 27e7c8f17b
commit 908141aeff
11 changed files with 70 additions and 100 deletions

BIN
bun.lockb

Binary file not shown.

BIN
db/blog.sqlite Normal file

Binary file not shown.

View File

@ -5,8 +5,8 @@
},
"dependencies": {
"@types/yaml-front-matter": "^4.1.3",
"hono": "^4.4.10",
"marked": "^13.0.1",
"hono": "^4.4.13",
"marked": "^13.0.2",
"remark": "^15.0.1",
"yaml-front-matter": "^4.1.1"
},

View File

@ -1,3 +1,4 @@
export const POST_PATH: string = __dirname + '/../posts';
export const STATIC_PATH: string = __dirname + '/../static';
export const POST_ROUTE_PREFIX: string = '/posts'
export const SQLITE_DATABASE_FILE: string = __dirname + '/../db/blog.sqlite';

View File

@ -1,13 +1,11 @@
import { readdir } from 'node:fs/promises';
import { openPostMarkdownFile, parsePostMetadata } from '@blog/post/post-reader';
import { PostMeta } from '@blog/model/PostMeta';
import db from '@blog/db/memory';
import { PostFileService } from '@blog/services/post-file';
import { db } from '@blog/services/database';
const createPostSql: string = `
CREATE TABLE posts (
CREATE TABLE IF NOT EXISTS posts (
id INTEGER PRIMARY KEY,
title TEXT NOT NULL,
slug TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
is_draft INTEGER DEFAULT 0,
description TEXT,
published_date DATE,
@ -16,7 +14,7 @@ CREATE TABLE posts (
`;
const createAuthorSql: string = `
CREATE TABLE authors (
CREATE TABLE IF NOT EXISTS authors (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT
@ -24,14 +22,14 @@ CREATE TABLE authors (
`;
const createTagsSql: string = `
CREATE TABLE tags (
CREATE TABLE IF NOT EXISTS tags (
id INTEGER PRIMARY KEY,
tag TEXT UNIQUE
)
`;
const createPostsTagsSql: string = `
CREATE TABLE posts_tags (
CREATE TABLE IF NOT EXISTS posts_tags (
tag_id TEXT,
post_id INTEGER,
@ -41,7 +39,7 @@ CREATE TABLE posts_tags (
`;
const createPostHtmlCache = `
CREATE TABLE post_html_cache (
CREATE TABLE IF NOT EXISTS post_html_cache (
id INTEGER PRIMARY KEY,
post_id INTEGER,
content TEXT,
@ -69,27 +67,44 @@ export async function setupDb(): Promise<void> {
}
export async function readPostsToDatabase(postPath: string): Promise<void> {
const posts = new Array();
export async function readPostsToDatabase(): Promise<void> {
const postService = await PostFileService.create();
const createPostSql: string = `
INSERT INTO posts (title, slug, description, is_draft, published_date, raw_content)
VALUES ($title, $slug, $description, $is_draft, $published_date, $raw_content);
`;
INSERT INTO posts (title, slug, description, is_draft,
published_date, raw_content)
VALUES ($title, $slug, $description, $is_draft,
$published_date, $raw_content);`;
const fileList = await readdir(postPath);
for (const file of fileList) {
const contents: string = await openPostMarkdownFile(postPath + "/" + file);
const post = parsePostMetadata(contents);
const createPostHtmlCacheSql: string = `
INSERT INTO post_html_cache (post_id, content)
VALUES ($posId, $content);`;
for (const [ slug, post ] of postService.getPosts().entries()) {
const postQuery = db.prepare(createPostSql);
postQuery.run({
const { lastInsertRowId } = postQuery.run({
$title: post.meta.title,
$slug: file,
$slug: slug,
$description: post.meta.description,
$is_draft: post.meta.draft ?? false,
$published_date: post.meta.date.toString(),
$raw_content: post.content
});
const htmlCacheQuery = db.prepare(createPostHtmlCacheSql);
htmlCacheQuery.run({ $postId: lastInsertRowId, $content: post.html })
console.log({ message: "Added " + post.meta.title + " to the database." });
}
}
async function main() {
await setupDb();
await readPostsToDatabase();
}
main()
.then(() => process.exit(0))
.catch(e => {
console.log(e);
throw e;
});

View File

@ -1,4 +1,4 @@
import { PostMeta } from '@blog/models/PostMeta';
import { PostMeta } from '@blog/model/PostMeta';
export type Post = {
meta: PostMeta,

View File

@ -1,62 +0,0 @@
import { marked } from 'marked';
import type { Post } from '@blog/models/Post';
import type { PostMeta } from '@blog/models/PostMeta';
import * as yamlFront from 'yaml-front-matter';
import { readdir } from 'node:fs/promises';
export async function openPostMarkdownFile(filename: string): Promise<string> {
const file = Bun.file(filename);
return file.text();
}
type PostMetaWithRawContent = {
meta: PostMeta,
content: string
};
export function parsePostMetadata(post: string): PostMetaWithRawContent {
const parsedData = yamlFront.loadFront(post);
return {
meta: {
title: parsedData.title,
description: parsedData.description,
date: new Date(parsedData.date),
draft: parsedData?.draft || false,
tags: parsedData.tags,
},
content: parsedData.__content
};
}
export async function getPostList(path: string): Promise<PostMeta[]> {
const postList: PostMeta[] = new Array<PostMeta>();
const dir = await readdir(path);
if (!dir.length) {
return postList;
}
for (const file of dir) {
const fileContent = await openPostMarkdownFile(path + '/' + file);
const postMeta = parsePostMetadata(fileContent);
postMeta.meta.slug = "/posts/" + file.slice(0, -3);
postList.push(postMeta.meta);
}
return postList;
}
export async function readPostMarkdown(filename: string): Promise<Post> {
const contents = await openPostMarkdownFile(filename);
const post = parsePostMetadata(contents);
post.meta.slug = "/posts/" + filename.slice(0, -3);
const parsedPost = await marked.parse(post.content);
return {
meta: post.meta,
content: post.content,
html: parsedPost
};
}

View File

@ -1,7 +1,4 @@
export type ConnectionConfig = {
host: string,
username: string,
password: string,
database: string,
port: number
};
import { Database } from "bun:sqlite";
import { SQLITE_DATABASE_FILE } from "@blog/config";
export const db = new Database(SQLITE_DATABASE_FILE);

View File

@ -41,8 +41,8 @@ export class PostFileService {
const posts = new Map<string, Post>();
const postFiles: string[] = await readdir(POST_PATH);
for (const postFile in postFiles) {
const post = await readPostFile(postFile);
for (const postFile of postFiles) {
const post = await readPostFile(POST_PATH + "/" + postFile);
const key = post.meta?.slug || postFile.slice(0, -3);
posts.set(key, post);
}
@ -50,6 +50,10 @@ export class PostFileService {
return new PostFileService(posts);
}
public getPosts(): Map<string, Post> {
return this.posts;
}
public getPost(slug: string): Post {
const post = this.posts.get(slug);

View File

@ -1,4 +0,0 @@
export class PostRepository {
}

View File

@ -0,0 +1,19 @@
import { Post } from '@blog/models/Post';
import { db } from '@blog/services/database';
export class PostRepository {
public async getPost(id: number): Promise<Post> {
const queryString = `
SELECT title, slug, is_draft, description, published_date, raw_content
FROM posts
WHERE id = $id
`;
const query = db.query(queryString);
const post = query.get({ $id: id }).as(Post);
return post;
}
public async getPostBySlug(slug: string): Post {
}
}