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 (
|
CREATE TYPE IF NOT EXISTS drive_file (
|
||||||
id ascii,
|
id ascii,
|
||||||
type ascii,
|
type ascii,
|
||||||
created_at timestamp,
|
createdAt timestamp,
|
||||||
name text,
|
name text,
|
||||||
comment text,
|
comment text,
|
||||||
blurhash text,
|
blurhash text,
|
||||||
url text,
|
url text,
|
||||||
thumbnail_url text,
|
thumbnailUrl text,
|
||||||
is_sensitive boolean,
|
isSensitive boolean,
|
||||||
is_link boolean,
|
isLink boolean,
|
||||||
md5 ascii,
|
md5 ascii,
|
||||||
size int,
|
size int,
|
||||||
width int,
|
width int,
|
||||||
|
@ -19,7 +19,7 @@ CREATE TYPE IF NOT EXISTS note_edit_history (
|
||||||
content text,
|
content text,
|
||||||
cw text,
|
cw text,
|
||||||
files set<frozen<drive_file>>,
|
files set<frozen<drive_file>>,
|
||||||
updated_at timestamp,
|
updatedAt timestamp,
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TYPE IF NOT EXISTS emoji (
|
CREATE TYPE IF NOT EXISTS emoji (
|
||||||
|
@ -30,36 +30,36 @@ CREATE TYPE IF NOT EXISTS emoji (
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS note ( -- Models timeline
|
CREATE TABLE IF NOT EXISTS note ( -- Models timeline
|
||||||
created_at_date date, -- For partitioning
|
createdAtDate date, -- For partitioning
|
||||||
created_at timestamp,
|
createdAt timestamp,
|
||||||
id ascii, -- Post
|
id ascii, -- Post
|
||||||
visibility ascii,
|
visibility ascii,
|
||||||
content text,
|
content text,
|
||||||
name text,
|
name text,
|
||||||
cw text,
|
cw text,
|
||||||
local_only boolean,
|
localOnly boolean,
|
||||||
renote_count int,
|
renoteCount int,
|
||||||
replies_count int,
|
repliesCount int,
|
||||||
uri text,
|
uri text,
|
||||||
url text,
|
url text,
|
||||||
score int,
|
score int,
|
||||||
files set<frozen<drive_file>>,
|
files set<frozen<drive_file>>,
|
||||||
visible_users set<ascii>,
|
visibleUsersId set<ascii>,
|
||||||
mentions set<ascii>,
|
mentions set<ascii>,
|
||||||
emojis set<frozen<emoji>>,
|
emojis set<frozen<emoji>>,
|
||||||
tags set<text>,
|
tags set<text>,
|
||||||
has_poll boolean,
|
hasPoll boolean,
|
||||||
thread_id ascii,
|
threadId ascii,
|
||||||
channel_id ascii, -- Channel
|
channelId ascii, -- Channel
|
||||||
channel_name text,
|
channelName text,
|
||||||
user_id ascii, -- User
|
userId ascii, -- User
|
||||||
reply_id ascii, -- Reply
|
replyId ascii, -- Reply
|
||||||
renote_id ascii, -- Boost
|
renoteId ascii, -- Boost
|
||||||
note_edit set<frozen<note_edit_history>>, -- Edit History
|
|
||||||
updated_at timestamp,
|
|
||||||
reactions map<text, int>,
|
reactions map<text, int>,
|
||||||
reaction_emojis map<text, frozen<emoji>>,
|
reactionEmojis map<text, frozen<emoji>>,
|
||||||
PRIMARY KEY (created_at_date, created_at)
|
noteEdit set<frozen<note_edit_history>>, -- Edit History
|
||||||
|
updatedAt timestamp,
|
||||||
|
PRIMARY KEY (createdAtDate, createdAt)
|
||||||
) WITH CLUSTERING ORDER BY (created_at DESC);
|
) WITH CLUSTERING ORDER BY (created_at DESC);
|
||||||
|
|
||||||
CREATE INDEX IF NOT EXISTS note_by_id ON note (id);
|
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
|
CREATE MATERIALIZED VIEW IF NOT EXISTS note_by_user_id AS
|
||||||
SELECT * FROM note
|
SELECT * FROM note
|
||||||
WHERE user_id IS NOT NULL
|
WHERE userId IS NOT NULL
|
||||||
AND created_at IS NOT NULL
|
AND createdAt IS NOT NULL
|
||||||
AND created_at_date IS NOT NULL
|
AND createdAtDate IS NOT NULL
|
||||||
PRIMARY KEY (user_id, created_at, created_at_date)
|
PRIMARY KEY (userId, createdAt, createdAtDate)
|
||||||
WITH CLUSTERING ORDER BY (created_at DESC);
|
WITH CLUSTERING ORDER BY (createdAt DESC);
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS reaction (
|
CREATE TABLE IF NOT EXISTS reaction (
|
||||||
note_id ascii,
|
noteId ascii,
|
||||||
created_at timestamp,
|
createdAt timestamp,
|
||||||
user_id ascii,
|
userId ascii,
|
||||||
reaction frozen<emoji>,
|
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 config from "@/config/index.js";
|
||||||
|
import { DriveFile } from "@/models/entities/drive-file.js";
|
||||||
import { Client } from "cassandra-driver";
|
import { Client } from "cassandra-driver";
|
||||||
|
|
||||||
function newClient(): Client | null {
|
function newClient(): Client | null {
|
||||||
|
@ -17,46 +18,63 @@ export const scyllaClient = newClient();
|
||||||
export const prepared = {
|
export const prepared = {
|
||||||
timeline: {
|
timeline: {
|
||||||
insert: `INSERT INTO note (
|
insert: `INSERT INTO note (
|
||||||
created_at_date,
|
createdAtDate,
|
||||||
created_at,
|
createdAt,
|
||||||
id,
|
id,
|
||||||
visibility,
|
visibility,
|
||||||
content,
|
content,
|
||||||
name,
|
name,
|
||||||
cw,
|
cw,
|
||||||
local_only,
|
localOnly,
|
||||||
renote_count,
|
renoteCount,
|
||||||
replies_count,
|
repliesCount,
|
||||||
uri,
|
uri,
|
||||||
url,
|
url,
|
||||||
score,
|
score,
|
||||||
files,
|
files,
|
||||||
visible_users,
|
visibleUsersId,
|
||||||
mentions,
|
mentions,
|
||||||
emojis,
|
emojis,
|
||||||
tags,
|
tags,
|
||||||
has_poll,
|
hasPoll,
|
||||||
thread_id,
|
threadId,
|
||||||
channel_id,
|
channelId,
|
||||||
channel_name,
|
channelName,
|
||||||
user_id,
|
userId,
|
||||||
user_id,
|
userId,
|
||||||
reply_id,
|
replyId,
|
||||||
renote_id,
|
renoteId,
|
||||||
note_edit,
|
|
||||||
updated_at,
|
|
||||||
reactions,
|
reactions,
|
||||||
reaction_emojis
|
reactionEmojis
|
||||||
|
noteEdit,
|
||||||
|
updatedAt,
|
||||||
)
|
)
|
||||||
VALUES
|
VALUES
|
||||||
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
select: {
|
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 ?",
|
byId: "SELECT * FROM note WHERE id IN ?",
|
||||||
byUri: "SELECT * FROM note WHERE uri = ?",
|
byUri: "SELECT * FROM note WHERE uri = ?",
|
||||||
byUrl: "SELECT * FROM note WHERE url = ?",
|
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 ?",
|
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 meilisearch from "../../db/meilisearch.js";
|
||||||
import { redisClient } from "@/db/redis.js";
|
import { redisClient } from "@/db/redis.js";
|
||||||
import { Mutex } from "redis-semaphore";
|
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<
|
const mutedWordsCache = new Cache<
|
||||||
{ userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[]
|
{ userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[]
|
||||||
|
@ -758,6 +761,49 @@ async function insertNote(
|
||||||
|
|
||||||
// 投稿を作成
|
// 投稿を作成
|
||||||
try {
|
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) {
|
if (insert.hasPoll) {
|
||||||
// Start transaction
|
// Start transaction
|
||||||
await db.transaction(async (transactionalEntityManager) => {
|
await db.transaction(async (transactionalEntityManager) => {
|
||||||
|
|
Loading…
Reference in a new issue