From 0745298257c781e2f4202e6ddec8078bb8e06096 Mon Sep 17 00:00:00 2001
From: jasinco
Date: Fri, 25 Apr 2025 11:45:55 +0800
Subject: [PATCH] postgres_cursor add
---
bun.lockb | Bin 38103 -> 38474 bytes
justfile | 4 ++
package.json | 1 +
src/app/page.tsx | 3 +-
src/app/post.tsx | 60 ++++++++++++-------------
src/db.ts | 112 ++++++++++++++++++++++++++--------------------
tools/gen_fake.ts | 15 +++++++
tools/post_db.ts | 13 ++++++
tsconfig.json | 5 ++-
9 files changed, 131 insertions(+), 82 deletions(-)
mode change 100644 => 100755 bun.lockb
create mode 100644 justfile
create mode 100644 tools/gen_fake.ts
create mode 100644 tools/post_db.ts
diff --git a/bun.lockb b/bun.lockb
old mode 100644
new mode 100755
index fababebaf53c4a54ea9c358c85098a8b994543fd..dc222f17e3f920d34404b82647568c307130e19e
GIT binary patch
delta 5424
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
delta 5129
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
G@P7hRe&iYe
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()
- })
- }
- })
- return ()
-}
\ 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()
+ })
+ }
+ })
+ return ()
+}
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"]