init the database and move posts into the sqlite database.
This commit is contained in:
parent
27e7c8f17b
commit
908141aeff
BIN
db/blog.sqlite
Normal file
BIN
db/blog.sqlite
Normal file
Binary file not shown.
@ -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"
|
||||
},
|
||||
|
@ -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';
|
||||
|
@ -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;
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { PostMeta } from '@blog/models/PostMeta';
|
||||
import { PostMeta } from '@blog/model/PostMeta';
|
||||
|
||||
export type Post = {
|
||||
meta: PostMeta,
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -1,4 +0,0 @@
|
||||
|
||||
export class PostRepository {
|
||||
|
||||
}
|
19
src/services/repository/post-repository.ts
Normal file
19
src/services/repository/post-repository.ts
Normal 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 {
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user