Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

merge #231

Merged
merged 8 commits into from
Jul 30, 2024
Merged

merge #231

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ jobs:
RSS_DESCRIPTION: ${{ vars.RSS_DESCRIPTION }}
run: |
cd Rin/
bun install
bun install --frozen-lockfile
bun scripts/migrator.ts
2 changes: 1 addition & 1 deletion .github/workflows/seo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ jobs:
S3_FORCE_PATH_STYLE: ${{ vars.S3_FORCE_PATH_STYLE }}
run: |
cd Rin/
bun i
bun install --frozen-lockfile
bun scripts/render.ts
Binary file modified bun.lockb
Binary file not shown.
10 changes: 9 additions & 1 deletion client/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ ul {
.octicon {
@apply mr-1 w-3;
}

.katex {
overflow-x: auto;
overflow-y: hidden;
}

/* animation */

@keyframes anvil {
Expand Down Expand Up @@ -127,6 +133,8 @@ ul {

.table {
@apply w-full border-collapse my-4;
overflow-x: auto;
display: block !important;
}

.table th,
Expand Down Expand Up @@ -197,4 +205,4 @@ a.toc-link {

.is-active-link::before {
@apply bg-theme;
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"dev:client": "bun --filter './client' dev",
"dev:server": "bun wrangler dev --port 11498",
"check": "turbo check",
"cf-deploy": "bun server/migrator.ts",
"cf-deploy": "bun scripts/migrator.ts",
"b": "turbo build",
"t": "turbo t",
"g": "turbo run g",
Expand All @@ -25,7 +25,7 @@
"autoprefixer": "^10.4.19",
"i18next-parser": "^9.0.0",
"postcss": "^8.4.38",
"puppeteer": "^22.10.0",
"puppeteer": "^22.13.0",
"tailwindcss": "^3.4.3",
"turbo": "^1.13.3",
"vitest": "1.3.0"
Expand Down
29 changes: 25 additions & 4 deletions scripts/dev-migrator.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,53 @@
import * as fs from 'fs';
import * as path from 'path';
import {execSync} from 'child_process';
import { execSync } from 'child_process';
import { fixTopField, getMigrationVersion, isInfoExist, updateMigrationVersion } from './fix-top-field';

const DB_NAME = "rin";
const SQL_DIR = path.join(__dirname, '..', 'server', 'sql');

// Change to the server/sql directory
process.chdir(SQL_DIR);

const typ = 'local';
const migrationVersion = await getMigrationVersion(typ, DB_NAME);
const isInfoExistResult = await isInfoExist(typ, DB_NAME);
// List all SQL files and sort them
const sqlFiles = fs
.readdirSync(SQL_DIR, {withFileTypes: true})
.readdirSync(SQL_DIR, { withFileTypes: true })
.filter(dirent => dirent.isFile() && dirent.name.endsWith('.sql'))
.map(dirent => dirent.name)
.filter(file => {
const version = parseInt(file.split('-')[0]);
return version > migrationVersion;
})
.sort();

console.log("migration_version:", migrationVersion, "Migration SQL List: ", sqlFiles)

// For each file in the sorted list
for (const file of sqlFiles) {
const filePath = path.join(SQL_DIR, file);
// Run the migration
try {
execSync(`bunx wrangler d1 execute ${DB_NAME} --local --file "${filePath}"`, {stdio: 'inherit'});
execSync(`bunx wrangler d1 execute ${DB_NAME} --local --file "${filePath}"`, { stdio: 'inherit' });
console.log(`Executed ${file}`);
} catch (error) {
console.error(`Failed to execute ${file}: ${error}`);
process.exit(1);
}
}

if (sqlFiles.length === 0) {
console.log("No migration needed.")
} else {
const lastVersion = parseInt(sqlFiles[sqlFiles.length - 1].split('-')[0]);
if (lastVersion > migrationVersion) {
// Update the migration version
await updateMigrationVersion(typ, DB_NAME, lastVersion);
}
}

await fixTopField(typ, DB_NAME, isInfoExistResult);

// Back to the root directory (optional, as the script ends)
process.chdir(__dirname);
53 changes: 53 additions & 0 deletions scripts/fix-top-field.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { $ } from "bun"

export async function fixTopField(typ: 'local' | 'remote', db: string, isInfoExistResult: boolean) {
if (!isInfoExistResult) {
console.log("Legacy database, check top field")
const result = await $`bunx wrangler d1 execute ${db} --${typ} --json --command "SELECT name FROM pragma_table_info('feeds') WHERE name='top'"`.quiet().json()
if (result[0].results.length === 0) {
console.log("Adding top field to feeds table")
await $`bunx wrangler d1 execute ${db} --${typ} --json --command "ALTER TABLE feeds ADD COLUMN top INTEGER DEFAULT 0"`.quiet()
} else {
console.log("Top field already exists in feeds table")
}
} else {
console.log("New database, skip top field check")
}
}

export async function isInfoExist(typ: 'local' | 'remote', db: string) {
const result = await $`bunx wrangler d1 execute ${db} --${typ} --json --command "SELECT name FROM sqlite_master WHERE type='table' AND name='info'"`.quiet().json()
if (result[0].results.length === 0) {
console.log("info table not exists")
return false
} else {
console.log("info table already exists")
return true
}
}

export async function getMigrationVersion(typ: 'local' | 'remote', db: string) {
const isInfoExistResult = await isInfoExist(typ, db)
if (!isInfoExistResult) {
console.log("Legacy database, migration_version not exists")
return -1
}
const result = await $`bunx wrangler d1 execute ${db} --${typ} --json --command "SELECT value FROM info WHERE key='migration_version'"`.quiet().json()
if (result[0].results.length === 0) {
console.log("migration_version not exists")
return -1
} else {
console.log("migration_version:", result[0].results[0].value)
return parseInt(result[0].results[0].value)
}
}

export async function updateMigrationVersion(typ: 'local' | 'remote', db: string, version: number) {
const exists = await isInfoExist(typ, db)
if (!exists) {
console.log("info table not exists, skip update migration_version")
throw new Error("info table not exists")
}
await $`bunx wrangler d1 execute ${db} --${typ} --json --command "UPDATE info SET value='${version}' WHERE key='migration_version'"`.quiet()
console.log("Updated migration_version to", version)
}
34 changes: 30 additions & 4 deletions scripts/migrator.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { $ } from "bun"
import { readdir } from "node:fs/promises"
import stripIndent from 'strip-indent'
import { fixTopField, getMigrationVersion, isInfoExist, updateMigrationVersion } from "./fix-top-field"

function env(name: string, defaultValue?: string, required = false) {
const env = process.env
Expand All @@ -12,7 +13,7 @@ function env(name: string, defaultValue?: string, required = false) {
}

// must be defined
const renv = (name: string, defaultValue?: string) => env(name, defaultValue, true)
const renv = (name: string, defaultValue?: string) => env(name, defaultValue, true)!

const DB_NAME = renv("DB_NAME", 'rin')
const WORKER_NAME = renv("WORKER_NAME", 'rin-server')
Expand Down Expand Up @@ -102,21 +103,46 @@ if (existing) {
}

console.log(`----------------------------`)

console.log(`Migrating D1 "${DB_NAME}"`)
const typ = 'remote';
const migrationVersion = await getMigrationVersion(typ, DB_NAME);
const isInfoExistResult = await isInfoExist(typ, DB_NAME);

try {
const files = await readdir("./server/sql", { recursive: false })
for (const file of files) {
const sqlFiles = files
.filter(name => name.endsWith('.sql'))
.filter(name => {
const version = parseInt(name.split('-')[0]);
return version > migrationVersion;
})
.sort();
console.log("migration_version:", migrationVersion, "Migration SQL List: ", sqlFiles)
for (const file of sqlFiles) {
await $`bunx wrangler d1 execute ${DB_NAME} --remote --file ./server/sql/${file} -y`
console.log(`Migrated ${file}`)
}
if (sqlFiles.length === 0) {
console.log("No migration needed.")
} else {
const lastVersion = parseInt(sqlFiles[sqlFiles.length - 1].split('-')[0]);
if (lastVersion > migrationVersion) {
// Update the migration version
await updateMigrationVersion(typ, DB_NAME, lastVersion);
}
}
} catch (e: any) {
console.error(e.stderr.toString())
console.error(e.stdio?.toString())
console.error(e.stdout?.toString())
console.error(e.stderr?.toString())
process.exit(1)
}

console.log(`Migrated D1 "${DB_NAME}"`)
console.log(`----------------------------`)
console.log(`Patch D1`)
await fixTopField(typ, DB_NAME, isInfoExistResult);
console.log(`----------------------------`)
console.log(`Put secrets`)

async function putSecret(name: string, value?: string) {
Expand Down
2 changes: 1 addition & 1 deletion scripts/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ async function fetchPage(url: string) {
const anchors = Array.from(document.querySelectorAll('a'));
return anchors.map(anchor => anchor.href);
});
for (const link of links.filter(link => (link.startsWith(baseUrl) || (containsKey !== '' && link.includes(containsKey))))) {
for (const link of links.filter(link => (link.startsWith(baseUrl) || (containsKey != '' && link.includes(containsKey))))) {
const linkWithoutHash = link.split('#')[0];
if (fetchedLinks.has(linkWithoutHash)) {
continue;
Expand Down
28 changes: 5 additions & 23 deletions server/sql/0002.sql
Original file line number Diff line number Diff line change
@@ -1,26 +1,8 @@
PRAGMA foreign_keys=off;
--> statement-breakpoint
CREATE TABLE IF NOT EXISTS `feeds_new` (
`id` integer PRIMARY KEY NOT NULL,
`alias` text,
`title` text,
`content` text NOT NULL,
`summary` text DEFAULT '' NOT NULL,
`listed` integer DEFAULT 1 NOT NULL,
`draft` integer DEFAULT 1 NOT NULL,
`uid` integer NOT NULL,
`top` integer DEFAULT 0 NOT NULL,
`created_at` integer DEFAULT (unixepoch()) NOT NULL,
`updated_at` integer DEFAULT (unixepoch()) NOT NULL,
FOREIGN KEY (`uid`) REFERENCES `users`(`id`) ON UPDATE no action ON DELETE no action
CREATE TABLE IF NOT EXISTS `info` (
`key` text NOT NULL,
`value` text NOT NULL
);
--> statement-breakpoint
INSERT INTO `feeds_new` (`id`, `alias`, `title`, `content`, `summary`, `listed`, `draft`, `uid`, `created_at`, `updated_at`)
SELECT `id`, `alias`, `title`, `content`, `summary`, `listed`, `draft`, `uid`, `created_at`, `updated_at`
FROM `feeds`;
--> statement-breakpoint
DROP TABLE `feeds`;
--> statement-breakpoint
ALTER TABLE `feeds_new` RENAME TO `feeds`;
CREATE UNIQUE INDEX `info_key_unique` ON `info` (`key`);
--> statement-breakpoint
PRAGMA foreign_keys=on;
INSERT INTO `info` (`key`, `value`) VALUES ('migration_version', '2');
5 changes: 5 additions & 0 deletions server/src/db/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ export const visits = sqliteTable("visits", {
createdAt: created_at,
});

export const info = sqliteTable("info", {
key: text("key").notNull().unique(),
value: text("value").notNull(),
});

export const friends = sqliteTable("friends", {
id: integer("id").primaryKey(),
name: text("name").notNull(),
Expand Down
5 changes: 3 additions & 2 deletions server/src/services/rss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export function RSSService() {
const folder = env.S3_CACHE_FOLDER || 'cache/';
return new Elysia({ aot: false })
.get('/sub/:name', async ({ set, params: { name } }) => {
if (!accessHost) {
const host = `${(accessHost.startsWith("http://") || accessHost.startsWith("https://") ? '' :'https://')}${accessHost}`;
if (!host) {
set.status = 500;
return 'S3_ACCESS_HOST is not defined'
}
Expand All @@ -33,7 +34,7 @@ export function RSSService() {
if (['rss.xml', 'atom.xml', 'rss.json'].includes(name)) {
const key = path.join(folder, name);
try {
const url = `${accessHost}/${key}`;
const url = `${host}/${key}`;
console.log(`Fetching ${url}`);
const response = await fetch(new Request(url))
const contentType = name === 'rss.xml' ? 'application/rss+xml; charset=UTF-8' : name === 'atom.xml' ? 'application/atom+xml; charset=UTF-8' : 'application/feed+json; charset=UTF-8';
Expand Down
Loading