diff --git a/bun.lockb b/bun.lockb old mode 100644 new mode 100755 index fababeb..dc222f1 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/justfile b/justfile new file mode 100644 index 0000000..693ee5b --- /dev/null +++ b/justfile @@ -0,0 +1,4 @@ +fake: + POSTGRES_URL="postgres://test:test@192.168.50.14:5432/posts" bun run ./tools/gen_fake.ts +fetch_post: + POSTGRES_URL="postgres://test:test@192.168.50.14:5432/posts" bun run ./tools/post_db.ts diff --git a/package.json b/package.json index 3b19ef7..39569f4 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "lint": "next lint" }, "dependencies": { + "@faker-js/faker": "^9.7.0", "bun-types": "^1.2.9", "next": "15.3.0", "react": "^19.0.0", diff --git a/src/app/page.tsx b/src/app/page.tsx index 25af71e..6cb854d 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,4 +1,3 @@ -import { retrieve_post } from "@/db"; export default function Home() { @@ -8,7 +7,7 @@ export default function Home() {

匿名中工

- +
); diff --git a/src/app/post.tsx b/src/app/post.tsx index 4f0ea0f..3b43cfd 100644 --- a/src/app/post.tsx +++ b/src/app/post.tsx @@ -1,35 +1,35 @@ import { Suspense } from "react"; import Image from "next/image"; -import { Attachment } from "@/db"; +import { Attachment, MultiMediaType } from "@/db"; export default function Post(post_content: string, attachments: Attachment[]) { - let images = []; - let videos = []; - attachments.forEach(attachment => { - if (attachment.type.type == "video") { - attachment.urls.forEach(url => { - videos.push( - 加載中

}> - -
- ) - }) - }else if (attachment.type.type="image"){ - attachment.urls.forEach(url => { - images.push(Uploaded) - }) - } - }) - return (
-
- {post_content} -
-
-
-
-
) -} \ No newline at end of file + let images = []; + let videos = []; + attachments.forEach(attachment => { + if (attachment.type == MultiMediaType.video) { + attachment.urls.forEach(url => { + videos.push( + 加載中

}> + +
+ ) + }) + } else if (attachment.type == MultiMediaType.image) { + attachment.urls.forEach(url => { + images.push(Uploaded) + }) + } + }) + return (
+
+ {post_content} +
+
+
+
+
) +} diff --git a/src/db.ts b/src/db.ts index a31fb47..af1b730 100644 --- a/src/db.ts +++ b/src/db.ts @@ -1,57 +1,73 @@ -import { main } from "bun"; -import { sql } from "bun"; -import { MIMEType } from "util" +import { env, ReservedSQL, sql } from 'bun' +import { MIMEType } from 'util'; + +export enum MultiMediaType { + video, image +} export interface Attachment { - type: MIMEType; - urls: string[]; -} + urls: string[], + type: MultiMediaType +}; + export interface Post { - content: string, + post: string, + post_time: string, hash: string, + attachments: Attachment[], +} +interface SQLPostCast { + hash: string, post: string, post_time: string, images: number[] +}; +const SQLPostCast2Post = (obj: SQLPostCast) => { + let x: Post = + { + post: obj.post, + hash: obj.hash, + post_time: obj.post_time, + attachments: [] + }; + if (obj.images && obj.images.length > 0) { + x.attachments.push( + { + type: MultiMediaType.image, urls: obj.images.map(img => { + return `/img/${obj.hash}_${img}` + }) + } + ) + } + return x } -export async function setup_func() { - const rows = await sql` - CREATE OR REPLACE FUNCTION fetch_post( - OUT p_text VARCHAR(1000), - OUT p_hash CHAR(32), - OUT p_date TIMESTAMP, - OUT p_pics INT[] - ) - RETURNS SETOF RECORD AS - $$ - DECLARE - post_cursor CURSOR FOR - SELECT content, hash, date - FROM posts; - post_record RECORD; - BEGIN - -- Open cursor - OPEN post_cursor; - - -- Fetch rows and return - LOOP - FETCH NEXT FROM post_cursor INTO post_record; - EXIT WHEN NOT FOUND; - - p_text = post_record.content; - p_date = post_record.date; - p_hash = post_record.hash; - RETURN NEXT; - END LOOP; - - -- Close cursor - CLOSE post_cursor; - END; - $$ - LANGUAGE PLPGSQL;`; +export interface Cursor { + hash: string, + post_time: string, } -/* retrieve the latest post with posts table */ -export async function retrieve_post(offset: Number) { - const res = await sql`SELECT * FROM fetch_post();` - console.log(res) + +export class PostFetcher { + conn: Promise; + constructor() { + this.conn = sql.reserve(); + } + async init() { + await this.conn.then(async e => { + await e`DECLARE post_ptr CURSOR WITH HOLD FOR SELECT niming.posts.*, niming.images.file_sequence + AS images FROM niming.posts + LEFT JOIN niming.images ON niming.images.hash=niming.posts.hash ORDER BY niming.posts.post_time DESC, niming.posts.hash ASC` + }).catch(err => { + console.log(err); + }) + } + + async postgres_fetch() { + let x: SQLPostCast[] = [] + if (this.conn) { + x = await (await this.conn)`FETCH 10 IN post_ptr`; + } + return x.map(e => { + return SQLPostCast2Post(e) + }) + } } -setup_func() -retrieve_post(0) \ No newline at end of file + diff --git a/tools/gen_fake.ts b/tools/gen_fake.ts new file mode 100644 index 0000000..61af1d6 --- /dev/null +++ b/tools/gen_fake.ts @@ -0,0 +1,15 @@ +import { CryptoHasher, sql } from "bun"; +import { retrieve_post, setup_func } from "@/db"; +import { faker } from '@faker-js/faker'; + +for (let i = 0; i < 100; i++) { + + let text = faker.string.alpha(20); + let hash = new CryptoHasher("sha256") + hash.update(text) + hash.update(Date.now().toString()) + let dg = hash.digest("hex") + console.log(dg) + const _ = await sql`INSERT INTO niming.posts (hash, post,post_time) VALUES (${dg},${text}, now())` +} + diff --git a/tools/post_db.ts b/tools/post_db.ts new file mode 100644 index 0000000..d33303a --- /dev/null +++ b/tools/post_db.ts @@ -0,0 +1,13 @@ +import { PostFetcher, Post } from "@/db" +import { sql } from "bun"; + +let x: Post[] = []; +const fetcher = new PostFetcher(); +await fetcher.init() + +for (let i = 0; i < 10; i++) { + x = await fetcher.postgres_fetch() + + console.log(x) + +} diff --git a/tsconfig.json b/tsconfig.json index c133409..3f26a4b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -8,7 +8,7 @@ "noEmit": true, "esModuleInterop": true, "module": "esnext", - "moduleResolution": "bundler", + "moduleResolution": "Bundler", "resolveJsonModule": true, "isolatedModules": true, "jsx": "preserve", @@ -20,7 +20,8 @@ ], "paths": { "@/*": ["./src/*"] - } + }, + "types":["bun-types"] }, "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"]