add queries
This commit is contained in:
parent
61da2a2e84
commit
e715b918d5
3 changed files with 114 additions and 50 deletions
|
@ -1,14 +1,14 @@
|
|||
CREATE TYPE IF NOT EXISTS drive_file (
|
||||
id ascii,
|
||||
type ascii,
|
||||
created_at timestamp,
|
||||
createdAt timestamp,
|
||||
name text,
|
||||
comment text,
|
||||
blurhash text,
|
||||
url text,
|
||||
thumbnail_url text,
|
||||
is_sensitive boolean,
|
||||
is_link boolean,
|
||||
thumbnailUrl text,
|
||||
isSensitive boolean,
|
||||
isLink boolean,
|
||||
md5 ascii,
|
||||
size int,
|
||||
width int,
|
||||
|
@ -19,7 +19,7 @@ CREATE TYPE IF NOT EXISTS note_edit_history (
|
|||
content text,
|
||||
cw text,
|
||||
files set<frozen<drive_file>>,
|
||||
updated_at timestamp,
|
||||
updatedAt timestamp,
|
||||
);
|
||||
|
||||
CREATE TYPE IF NOT EXISTS emoji (
|
||||
|
@ -30,36 +30,36 @@ CREATE TYPE IF NOT EXISTS emoji (
|
|||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS note ( -- Models timeline
|
||||
created_at_date date, -- For partitioning
|
||||
created_at timestamp,
|
||||
createdAtDate date, -- For partitioning
|
||||
createdAt timestamp,
|
||||
id ascii, -- Post
|
||||
visibility ascii,
|
||||
content text,
|
||||
name text,
|
||||
cw text,
|
||||
local_only boolean,
|
||||
renote_count int,
|
||||
replies_count int,
|
||||
localOnly boolean,
|
||||
renoteCount int,
|
||||
repliesCount int,
|
||||
uri text,
|
||||
url text,
|
||||
score int,
|
||||
files set<frozen<drive_file>>,
|
||||
visible_users set<ascii>,
|
||||
visibleUsersId set<ascii>,
|
||||
mentions set<ascii>,
|
||||
emojis set<frozen<emoji>>,
|
||||
tags set<text>,
|
||||
has_poll boolean,
|
||||
thread_id ascii,
|
||||
channel_id ascii, -- Channel
|
||||
channel_name text,
|
||||
user_id ascii, -- User
|
||||
reply_id ascii, -- Reply
|
||||
renote_id ascii, -- Boost
|
||||
note_edit set<frozen<note_edit_history>>, -- Edit History
|
||||
updated_at timestamp,
|
||||
hasPoll boolean,
|
||||
threadId ascii,
|
||||
channelId ascii, -- Channel
|
||||
channelName text,
|
||||
userId ascii, -- User
|
||||
replyId ascii, -- Reply
|
||||
renoteId ascii, -- Boost
|
||||
reactions map<text, int>,
|
||||
reaction_emojis map<text, frozen<emoji>>,
|
||||
PRIMARY KEY (created_at_date, created_at)
|
||||
reactionEmojis map<text, frozen<emoji>>,
|
||||
noteEdit set<frozen<note_edit_history>>, -- Edit History
|
||||
updatedAt timestamp,
|
||||
PRIMARY KEY (createdAtDate, createdAt)
|
||||
) WITH CLUSTERING ORDER BY (created_at DESC);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS note_by_id ON note (id);
|
||||
|
@ -68,16 +68,16 @@ CREATE INDEX IF NOT EXISTS note_by_url ON note (url);
|
|||
|
||||
CREATE MATERIALIZED VIEW IF NOT EXISTS note_by_user_id AS
|
||||
SELECT * FROM note
|
||||
WHERE user_id IS NOT NULL
|
||||
AND created_at IS NOT NULL
|
||||
AND created_at_date IS NOT NULL
|
||||
PRIMARY KEY (user_id, created_at, created_at_date)
|
||||
WITH CLUSTERING ORDER BY (created_at DESC);
|
||||
WHERE userId IS NOT NULL
|
||||
AND createdAt IS NOT NULL
|
||||
AND createdAtDate IS NOT NULL
|
||||
PRIMARY KEY (userId, createdAt, createdAtDate)
|
||||
WITH CLUSTERING ORDER BY (createdAt DESC);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS reaction (
|
||||
note_id ascii,
|
||||
created_at timestamp,
|
||||
user_id ascii,
|
||||
noteId ascii,
|
||||
createdAt timestamp,
|
||||
userId ascii,
|
||||
reaction frozen<emoji>,
|
||||
PRIMARY KEY (note_id, created_at, user_id)
|
||||
PRIMARY KEY (noteId, createdAt, userId)
|
||||
);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import config from "@/config/index.js";
|
||||
import { DriveFile } from "@/models/entities/drive-file.js";
|
||||
import { Client } from "cassandra-driver";
|
||||
|
||||
function newClient(): Client | null {
|
||||
|
@ -17,46 +18,63 @@ export const scyllaClient = newClient();
|
|||
export const prepared = {
|
||||
timeline: {
|
||||
insert: `INSERT INTO note (
|
||||
created_at_date,
|
||||
created_at,
|
||||
createdAtDate,
|
||||
createdAt,
|
||||
id,
|
||||
visibility,
|
||||
content,
|
||||
name,
|
||||
cw,
|
||||
local_only,
|
||||
renote_count,
|
||||
replies_count,
|
||||
localOnly,
|
||||
renoteCount,
|
||||
repliesCount,
|
||||
uri,
|
||||
url,
|
||||
score,
|
||||
files,
|
||||
visible_users,
|
||||
visibleUsersId,
|
||||
mentions,
|
||||
emojis,
|
||||
tags,
|
||||
has_poll,
|
||||
thread_id,
|
||||
channel_id,
|
||||
channel_name,
|
||||
user_id,
|
||||
user_id,
|
||||
reply_id,
|
||||
renote_id,
|
||||
note_edit,
|
||||
updated_at,
|
||||
hasPoll,
|
||||
threadId,
|
||||
channelId,
|
||||
channelName,
|
||||
userId,
|
||||
userId,
|
||||
replyId,
|
||||
renoteId,
|
||||
reactions,
|
||||
reaction_emojis
|
||||
reactionEmojis
|
||||
noteEdit,
|
||||
updatedAt,
|
||||
)
|
||||
VALUES
|
||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
select: {
|
||||
byDate: "SELECT * FROM note WHERE created_at_date = ? AND created_at < ?",
|
||||
byDate: "SELECT * FROM note WHERE createdAtDate = ? AND createdAt < ?",
|
||||
byId: "SELECT * FROM note WHERE id IN ?",
|
||||
byUri: "SELECT * FROM note WHERE uri = ?",
|
||||
byUrl: "SELECT * FROM note WHERE url = ?",
|
||||
byUserId: "SELECT * FROM note WHERE user_id = ? AND created_at < ?",
|
||||
byUserId: "SELECT * FROM note WHERE userId = ? AND createdAt < ?",
|
||||
},
|
||||
delete: "DELETE FROM note WHERE id IN ?",
|
||||
},
|
||||
}
|
||||
|
||||
export interface ScyllaDriveFile {
|
||||
id: string;
|
||||
type: string;
|
||||
createdAt: Date;
|
||||
name: string;
|
||||
comment: string | null;
|
||||
blurhash: string | null;
|
||||
url: string;
|
||||
thumbnailUrl: string;
|
||||
isSensitive: boolean;
|
||||
isLink: boolean;
|
||||
md5: string;
|
||||
size: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,9 @@ import { shouldSilenceInstance } from "@/misc/should-block-instance.js";
|
|||
import meilisearch from "../../db/meilisearch.js";
|
||||
import { redisClient } from "@/db/redis.js";
|
||||
import { Mutex } from "redis-semaphore";
|
||||
import { prepared, scyllaClient, ScyllaDriveFile } from "@/db/scylla.js";
|
||||
import { populateEmojis } from "@/misc/populate-emojis.js";
|
||||
import { decodeReaction } from "@/misc/reaction-lib.js";
|
||||
|
||||
const mutedWordsCache = new Cache<
|
||||
{ userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[]
|
||||
|
@ -758,6 +761,49 @@ async function insertNote(
|
|||
|
||||
// 投稿を作成
|
||||
try {
|
||||
if (scyllaClient) {
|
||||
const reactionEmojiNames = Object.keys(insert.reactions)
|
||||
.filter((x) => x?.startsWith(":"))
|
||||
.map((x) => decodeReaction(x).reaction)
|
||||
.map((x) => x.replace(/:/g, ""));
|
||||
const noteEmojis = await populateEmojis(
|
||||
insert.emojis.concat(reactionEmojiNames),
|
||||
user.host,
|
||||
);
|
||||
await scyllaClient.execute(
|
||||
prepared.timeline.insert,
|
||||
[
|
||||
insert.createdAt,
|
||||
insert.createdAt,
|
||||
insert.id,
|
||||
insert.visibility,
|
||||
insert.text,
|
||||
insert.name,
|
||||
insert.cw,
|
||||
insert.localOnly,
|
||||
insert.renoteCount,
|
||||
insert.repliesCount,
|
||||
insert.uri,
|
||||
insert.url,
|
||||
insert.score,
|
||||
data.files,
|
||||
insert.visibleUserIds,
|
||||
insert.mentions,
|
||||
noteEmojis,
|
||||
insert.tags,
|
||||
insert.hasPoll,
|
||||
insert.threadId,
|
||||
data.channel?.id,
|
||||
data.channel?.name,
|
||||
user.id,
|
||||
insert.replyId,
|
||||
insert.renoteId,
|
||||
null,
|
||||
null,
|
||||
],
|
||||
{ prepare: true },
|
||||
);
|
||||
}
|
||||
if (insert.hasPoll) {
|
||||
// Start transaction
|
||||
await db.transaction(async (transactionalEntityManager) => {
|
||||
|
|
Loading…
Reference in a new issue