add queries

This commit is contained in:
Namekuji 2023-07-23 22:29:38 -04:00
parent 61da2a2e84
commit e715b918d5
No known key found for this signature in database
GPG key ID: 1D62332C07FBA532
3 changed files with 114 additions and 50 deletions

View file

@ -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)
);

View file

@ -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;
}

View file

@ -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) => {