diff --git a/migrations/0001_add_posts_and_tags_tables.sql b/migrations/0001_add_posts_and_tags_tables.sql index fcc8b33..b82dbc1 100644 --- a/migrations/0001_add_posts_and_tags_tables.sql +++ b/migrations/0001_add_posts_and_tags_tables.sql @@ -1,7 +1,7 @@ CREATE TABLE `posts` ( - `content` text, + `content` text NOT NULL, `description` text, - `published` text NOT NULL, + `published` text, `slug` text PRIMARY KEY NOT NULL, `title` text NOT NULL, `type` text NOT NULL, diff --git a/migrations/meta/0001_snapshot.json b/migrations/meta/0001_snapshot.json index 5dacc11..2eb08bd 100644 --- a/migrations/meta/0001_snapshot.json +++ b/migrations/meta/0001_snapshot.json @@ -1,7 +1,7 @@ { "version": "6", "dialect": "sqlite", - "id": "33e6eabe-c792-4d57-bd4d-906a2df54df2", + "id": "95b0d99d-96d7-4a70-8e3d-63de6dc09478", "prevId": "d0532e55-b97a-4c4f-b350-50a3301e31bb", "tables": { "components": { @@ -164,7 +164,7 @@ "name": "content", "type": "text", "primaryKey": false, - "notNull": false, + "notNull": true, "autoincrement": false }, "description": { @@ -178,7 +178,7 @@ "name": "published", "type": "text", "primaryKey": false, - "notNull": true, + "notNull": false, "autoincrement": false }, "slug": { diff --git a/migrations/meta/_journal.json b/migrations/meta/_journal.json index 9c7bfa1..d0eb4b4 100644 --- a/migrations/meta/_journal.json +++ b/migrations/meta/_journal.json @@ -12,7 +12,7 @@ { "idx": 1, "version": "6", - "when": 1723171014511, + "when": 1730863213827, "tag": "0001_add_posts_and_tags_tables", "breakpoints": true } diff --git a/src/schemas/Post.ts b/src/schemas/Post.ts index 6dba6e3..ad6d287 100644 --- a/src/schemas/Post.ts +++ b/src/schemas/Post.ts @@ -4,7 +4,7 @@ import { z } from "zod" export const PostSchema = z.object({ content: z.string(), description: z.string().optional(), - published: z.date(), + published: z.date().nullable().optional(), slug: z.string(), title: z.string(), tags: z.array(z.string()), @@ -15,7 +15,7 @@ export type Post = z.infer export const PostsTable = sqliteTable("posts", { content: text("content").notNull(), description: text("description"), - published: text("published").notNull(), + published: text("published"), slug: text("slug").primaryKey(), title: text("title").notNull(), type: text("type", { enum: ["post", "photo"] }).notNull(), diff --git a/src/services/PostService.ts b/src/services/PostService.ts index 3d93e65..f95a948 100644 --- a/src/services/PostService.ts +++ b/src/services/PostService.ts @@ -1,7 +1,7 @@ import type { D1Database } from "@cloudflare/workers-types" import { type Post, PostsTable, schema, TagsTable } from "@schemas" import { conflictUpdateAllExcept } from "@utils" -import { asc, count, desc, eq, inArray, type InferSelectModel } from "drizzle-orm" +import { asc, count, desc, eq, inArray, type InferSelectModel, and, isNotNull } from "drizzle-orm" import { drizzle } from "drizzle-orm/d1" type PostService = { @@ -16,12 +16,13 @@ type PostService = { type PostRecord = InferSelectModel & { tags: InferSelectModel[] } const tags = { orderBy: TagsTable.name } const orderBy = [desc(PostsTable.published)] +const where = isNotNull(PostsTable.published) function transformPost(post?: PostRecord): Post | undefined { if (!post) return undefined return Object.entries({ ...post, description: post.description ? post.description : undefined, - published: new Date(post.published), + published: post.published ? new Date(post.published) : undefined, tags: post.tags.map(function(tag) { return tag.name }), updated: post.updated ? new Date(post.updated) : undefined, }).reduce(function(prev, [key, value]) { @@ -40,20 +41,20 @@ export function PostService(d1: D1Database): PostService { const db = drizzle(d1, { schema }) return { async getBySlug(slug) { - return db.query.PostsTable.findFirst({ with: { tags }, where: eq(PostsTable.slug, slug) }).then(transformPost) + return db.query.PostsTable.findFirst({ with: { tags }, where: and(where, eq(PostsTable.slug, slug)) }).then(transformPost) }, async getEarliest() { - return db.query.PostsTable.findFirst({ with: { tags }, orderBy: [asc(PostsTable.published)] }).then(transformPost) + return db.query.PostsTable.findFirst({ with: { tags }, orderBy: [asc(PostsTable.published)], where }).then(transformPost) }, async getLatest() { - return db.query.PostsTable.findFirst({ with: { tags }, orderBy }).then(transformPost) + return db.query.PostsTable.findFirst({ with: { tags }, orderBy, where }).then(transformPost) }, async list() { - return db.query.PostsTable.findMany({ with: { tags }, orderBy }).then(transformPosts) + return db.query.PostsTable.findMany({ with: { tags }, orderBy, where }).then(transformPosts) }, async listByTag(tag) { const query = db.select({ slug: TagsTable.post_slug }).from(TagsTable).where(eq(TagsTable.name, tag)) - return db.query.PostsTable.findMany({ with: { tags }, orderBy, where: inArray(PostsTable.slug, query) }).then(transformPosts) + return db.query.PostsTable.findMany({ with: { tags }, orderBy, where: and(where, inArray(PostsTable.slug, query)) }).then(transformPosts) }, async listTags() { return db.select({ name: TagsTable.name, count: count(TagsTable.name)}).from(TagsTable).groupBy(TagsTable.name).orderBy(desc(count(TagsTable.name)), TagsTable.name) @@ -61,7 +62,7 @@ export function PostService(d1: D1Database): PostService { async upsert(value) { const record = { ...value, - published: value.published.toISOString(), + published: value.published?.toISOString(), updated: value.updated?.toISOString(), } let [post] = await db.insert(PostsTable).values(record) diff --git a/test/services/PostService.test.ts b/test/services/PostService.test.ts index ab9ad15..630eacf 100644 --- a/test/services/PostService.test.ts +++ b/test/services/PostService.test.ts @@ -28,6 +28,12 @@ beforeEach(async function () { title: "Post3", type: "post", }, + { + content: "Post4 content", + slug: "post-four", + title: "Post4", + type: "post", + }, ]) await db.insert(TagsTable).values([ { diff --git a/wrangler.toml b/wrangler.toml index 47042a6..daeb812 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -15,4 +15,4 @@ bucket_name = "strava" [[d1_databases]] binding = "DB" database_name = "blog" -database_id = "eb7f2bb4-2a43-4c8b-8f47-33e4a0205d12" \ No newline at end of file +database_id = "690af449-57fa-41ac-9adf-e4e7ababf788" \ No newline at end of file