migration to postgresql

This commit is contained in:
Flummi
2022-01-02 06:52:47 +01:00
parent e1bc2c269a
commit e8ff4396aa
11 changed files with 571 additions and 280 deletions

View File

@ -80,7 +80,7 @@ export default new class {
return {
tagged,
untagged,
total: tagged + untagged,
total: +tagged + +untagged,
sfw,
nsfw
};

View File

@ -29,7 +29,7 @@ export default (router, tpl) => {
return res.reply({ body: "user doesn't exist or wrong password" });
if(!(await lib.verify(req.post.password, user[0].password)))
return res.reply({ body: "user doesn't exist or wrong password" });
const stamp = Date.now() / 1e3;
const stamp = ~~(Date.now() / 1e3);
const session = lib.md5(lib.createID());
await sql("user_sessions").insert({

View File

@ -107,9 +107,10 @@ export default (router, tpl) => {
let tagid;
const tag_exists = await sql("tags").select("id", "tag").where("tag", tag);
if(tag_exists.length === 0) { // create new tag
tagid = (await sql("tags").insert({
await sql("tags").insert({
tag: tag
}))[0];
});
tagid = (await sql("tags").select("id").where("tag", tag))[0].id;
}
else {
tagid = tag_exists[0].id;
@ -207,7 +208,11 @@ export default (router, tpl) => {
});
}
favs = await sql('favorites').select('user_id').where('item_id', itemid);
favs = await sql('favorites')
.select('user.user', 'user_options.avatar')
.leftJoin('user', 'user.id', 'favorites.user_id')
.leftJoin('user_options', 'user_options.user_id', 'favorites.user_id')
.where('favorites.item_id', itemid);
res.reply({ body: JSON.stringify({
success: true,

View File

@ -3,9 +3,10 @@ import lib from "../../lib.mjs";
import cfg from "../../config.mjs";
import fs from "fs";
import url from "url";
import { ifError } from "assert";
export default {
getf0cks: async (o = { user, tag, mime, page, mode }) => {
getf0cks: async (o = { user, tag, mime, page, mode, fav }) => {
const user = o.user ? decodeURI(o.user) : null;
const tag = lib.parseTag(o.tag ?? null);
const mime = (o.mime ?? "");
@ -33,23 +34,40 @@ export default {
.select("tags_assign.item_id", "tags.tag")
.leftJoin("tags_assign", "tags_assign.tag_id", "tags.id")
.where("tags.tag", "like", "%"+tag+"%")
.groupBy("tags_assign.item_id")
.groupBy("tags_assign.item_id", "tags.tag")
.as("st"),
"st.item_id", "items.id"
)
.whereRaw(modequery)
.groupBy('items.id', 'st.tag', 'st.item_id')
.count("* as total")
)[0]?.total;
}
else {
total = (await sql("items")
.whereRaw(modequery)
.andWhere("items.mime", "like", smime)
.andWhere("items.username", "like", user ? user : "%")
.count("* as total")
)[0]?.total;
if(!o.fav) {
total = (await sql("items")
.whereRaw(modequery)
.andWhere("items.mime", "ilike", smime)
.andWhere("items.username", "ilike", user ? user : "%")
.count("* as total")
)[0]?.total;
}
else {
total = (await sql("favorites")
.select('items.id', 'items.mime')
.leftJoin('user', 'user.id', 'favorites.user_id')
.leftJoin('tags_assign', 'tags_assign.item_id', 'favorites.item_id')
.leftJoin('tags', 'tags.id', 'tags_assign.tag_id')
.leftJoin('items', 'items.id', 'favorites.item_id')
.whereRaw(modequery)
.andWhere('items.mime', 'ilike', smime)
.andWhere('user.user', 'ilike', user)
.groupBy('items.id')
.count('* as total')
)[0]?.total;
}
}
if(!total || total.length === 0)
return {
success: false,
@ -59,27 +77,47 @@ export default {
const pages = +Math.ceil(total / cfg.websrv.eps);
const act_page = Math.min(pages, page || 1);
const offset = Math.max(0, (act_page - 1) * cfg.websrv.eps);
let rows;
let rows = sql("items")
.select("items.id", "items.mime", "tags_assign.tag_id")
.joinRaw("left join tags_assign on tags_assign.item_id = items.id and (tags_assign.tag_id = 1 or tags_assign.tag_id = 2)")
.whereRaw(modequery)
.andWhere("items.mime", "like", smime)
.andWhere("items.username", "like", user ? user : "%")
.orderBy("items.id", "desc")
.offset(offset)
.limit(cfg.websrv.eps);
if(!o.fav) {
rows = sql("items")
.select("items.id", "items.mime", "tags_assign.tag_id")
.joinRaw("left join tags_assign on tags_assign.item_id = items.id and (tags_assign.tag_id = 1 or tags_assign.tag_id = 2)")
.whereRaw(modequery)
.andWhere("items.mime", "ilike", smime)
.andWhere("items.username", "ilike", user ? user : "%")
.orderBy("items.id", "desc")
.offset(offset)
.limit(cfg.websrv.eps);
}
else {
rows = sql("favorites")
.select('items.id', 'items.mime')
.leftJoin('user', 'user.id', 'favorites.user_id')
.leftJoin('tags_assign', 'tags_assign.item_id', 'favorites.item_id')
.leftJoin('tags', 'tags.id', 'tags_assign.tag_id')
.leftJoin('items', 'items.id', 'favorites.item_id')
.whereRaw(modequery)
.andWhere('items.mime', 'ilike', smime)
.andWhere('user.user', 'ilike', user)
.orderBy('items.id', 'desc')
.groupBy('items.id')
.offset(offset)
.limit(cfg.websrv.eps);
}
if(tag) rows = rows
.innerJoin(
sql("tags")
.select("tags_assign.item_id", "tags.tag")
.leftJoin("tags_assign", "tags_assign.tag_id", "tags.id")
.where("tags.tag", "like", "%"+tag+"%")
.groupBy("tags_assign.item_id")
.where("tags.tag", "ilike", "%"+tag+"%")
.groupBy("tags_assign.item_id", "tags.tag")
.as("st"),
"st.item_id", "items.id"
);
)
.groupBy('st.item_id');
rows = await rows;
@ -99,7 +137,7 @@ export default {
for(let i = Math.max(1, act_page - 3); i <= Math.min(act_page + 3, pages); i++)
cheat.push(i);
const link = lib.genLink({ user, tag, mime, act_page });
const link = lib.genLink({ user, tag, mime, type: o.fav ? 'favs' : 'f0cks' });
data = {
success: true,
@ -136,26 +174,42 @@ export default {
};
}
let items = sql("items")
.select("*")
.orderBy("items.id", "desc")
.whereRaw(modequery);
let items;
if(o.fav) {
items = sql('favorites')
.select('items.*')
.leftJoin('items', 'items.id', 'favorites.item_id')
.leftJoin('user', 'user.id', 'favorites.user_id')
.whereRaw(modequery)
.andWhere('user.user', 'ilike', user)
.groupBy('items.id');
}
else {
items = sql("items")
.select("*")
.orderBy("items.id", "desc")
.whereRaw(modequery);
}
if(tag) {
items = items.innerJoin(
sql("tags")
.select("tags_assign.item_id", "tags.tag")
.leftJoin("tags_assign", "tags_assign.tag_id", "tags.id")
.where("tags.tag", "like", "%"+tag+"%")
.groupBy("tags_assign.item_id")
.where("tags.tag", "ilike", "%"+tag+"%")
.groupBy("tags_assign.item_id", "tags.tag")
.as("st"),
"st.item_id", "items.id"
);
)
.groupBy('items.id', 'st.item_id', 'st.tag');
}
if(user)
items = items.andWhere("username", "like", "%" + user + "%");
else
items = items.groupBy('items.id');
if(user && !o.fav)
items = items.andWhere("items.username", "ilike", "%" + user + "%");
if(mime)
items = items.andWhere("mime", "like", mime + "/%");
items = items.andWhere("items.mime", "ilike", mime + "/%");
items = await items;
@ -171,7 +225,7 @@ export default {
const tags = await lib.getTags(itemid);
const cheat = items.slice(Math.max(0, item - 3), item + 4).map(i => i.id);
const link = lib.genLink({ user, tag, mime, act_page: itemid });
const link = lib.genLink({ user, tag, mime, type: o.fav ? 'favs' : 'f0cks' });
const favorites = await sql('favorites')
.select('user.user', 'user_options.avatar')
.leftJoin('user', 'user.id', 'favorites.user_id')
@ -228,23 +282,24 @@ export default {
const modequery = mime == "audio" ? lib.getMode(0) : lib.getMode(o.mode ?? 0);
let item = sql("items").select("*").orderByRaw("rand()").whereRaw(modequery);
let item = sql("items").select("*").orderByRaw("random()").whereRaw(modequery);
if(tag) {
item = item.innerJoin(
sql("tags")
.select("tags_assign.item_id", "tags.tag")
.leftJoin("tags_assign", "tags_assign.tag_id", "tags.id")
.where("tags.tag", "like", "%"+tag+"%")
.where("tags.tag", "ilike", "%"+tag+"%")
.groupBy("tags_assign.item_id")
.as("st"),
"st.item_id", "items.id"
);
)
.groupBy('st.item_id');
}
if(user)
item = item.andWhere("username", "like", "%" + user + "%");
item = item.andWhere("username", "ilike", "%" + user + "%");
if(mime)
item = item.andWhere("mime", "like", mime + "/%");
item = item.andWhere("mime", "ilike", mime + "/%");
item = await item;

View File

@ -10,7 +10,7 @@ const auth = async (req, res, next) => {
};
export default (router, tpl) => {
router.get(/^\/?(?:\/tag\/(?<tag>.+?))?(?:\/user\/(?<user>.+?)\/(?:f0cks|favs))?(?:\/(?<mime>image|audio|video))?(?:\/p\/(?<page>\d+))?(?:\/(?<itemid>\d+))?$/, async (req, res) => {
router.get(/^\/?(?:\/tag\/(?<tag>.+?))?(?:\/user\/(?<user>.+?)\/(?<mode>f0cks|favs))?(?:\/(?<mime>image|audio|video))?(?:\/p\/(?<page>\d+))?(?:\/(?<itemid>\d+))?$/, async (req, res) => {
const mode = req.params.itemid ? 'item' : 'index';
const data = await (req.params.itemid ? f0cklib.getf0ck : f0cklib.getf0cks)({
user: req.params.user,
@ -18,6 +18,7 @@ export default (router, tpl) => {
mime: req.params.mime,
page: req.params.page,
itemid: req.params.itemid,
fav: req.params.mode == 'favs',
mode: req.session.mode
});
if(!data.success) {
@ -44,7 +45,7 @@ export default (router, tpl) => {
let referertmp = req.headers.referer;
let referer = "";
if(referertmp.match(/f0ck\.me/))
if(referertmp?.match(/f0ck\.me/))
referer = referertmp.split("/").slice(3).join("/");
if(cfg.allowedModes[mode]) {
@ -63,10 +64,11 @@ export default (router, tpl) => {
router.get(/^\/ranking$/, async (req, res) => {
try {
const list = await sql('tags_assign')
.select('user.user', sql.raw('count(distinct tag_id, item_id) count'))
.select('user.user')
.leftJoin('user', 'user.id', 'tags_assign.user_id')
.groupBy('user.user')
.orderBy('count', 'desc');
.orderBy('count', 'desc')
.countDistinct('tag_id', 'item_id', { as: 'count' });
const stats = await lib.countf0cks();

View File

@ -2,12 +2,12 @@ import f0cklib from "./inc/f0cklib.mjs";
export default (router, tpl) => {
router.get(/^\/random$/, async (req, res) => {
let referer = req.headers.referer;
let referer = req.headers.referer ?? '';
let opts = {};
if(referer.match(/f0ck\.me/)) { // parse referer
referer = referer.split("f0ck.me")[1];
const tmp = referer.match(/^\/?(?:\/tag\/(?<tag>.+?))?(?:\/user\/(?<user>.+?)\/(?:f0cks|favs))?(?:\/(?<mime>image|audio|video))?(?:\/p\/(?<page>\d+))?(?:\/(?<itemid>\d+))?$/);
const tmp = referer.match(/^\/?(?:\/tag\/(?<tag>.+?))?(?:\/user\/(?<user>.+?)\/(?<mode>f0cks|favs))?(?:\/(?<mime>image|audio|video))?(?:\/p\/(?<page>\d+))?(?:\/(?<itemid>\d+))?$/);
if(tmp)
opts = tmp.groups;
}
@ -17,6 +17,7 @@ export default (router, tpl) => {
tag: opts.tag,
mime: opts.mime,
page: opts.page,
fav: opts.mode == 'favs',
mode: req.session.mode
});

View File

@ -1,19 +1,7 @@
import knex from "knex";
import callback from "mariadb/callback.js";
import Client_MySQL from "knex/lib/dialects/mysql/index.js";
import cfg from "./config.mjs";
class Client_MariaDB extends Client_MySQL {
driverName = "mariadb";
_driver() {
return callback;
}
validateConnection(conn) {
return conn.isValid();
}
};
export default knex({
client: Client_MariaDB,
client: 'pgnative',
connection: cfg.sql
});

View File

@ -50,7 +50,7 @@ export default async bot => {
return e.reply(`repost motherf0cker (link): ${cfg.main.url}/${q_repost[0].id}`);
// generate uuid
const uuid = (await sql.select(sql.raw("left(uuid(), 8) as uuid")))[0].uuid;
const uuid = (await sql.select(sql.raw("gen_random_uuid() as uuid")))[0].uuid.substring(0, 8);
const maxfilesize = (getLevel(e.user).level > 50 ? cfg.main.maxfilesize * 2.5 : cfg.main.maxfilesize) / 1024;
@ -115,7 +115,7 @@ export default async bot => {
await fs.promises.copyFile(`./tmp/${filename}`, `./public/b/${filename}`);
await fs.promises.unlink(`./tmp/${filename}`).catch(_=>{});
const insertq = (await sql("items").insert({
await sql("items").insert({
src: e.photo ? "" : link,
dest: filename,
mime: mime,
@ -126,7 +126,8 @@ export default async bot => {
usernetwork: e.network,
stamp: ~~(new Date() / 1000),
active: 1
}))[0];
});
const insertq = (await sql('items').where('dest', filename).limit(1))[0].id;
// generate thumbnail
try {

View File

@ -81,7 +81,7 @@ import flummpress from "flummpress";
req.session = user[0];
await sql("user_sessions") // log last action
.update("last_used", (Date.now() / 1e3))
.update("last_used", ~~(Date.now() / 1e3))
.update("last_action", req.url.pathname)
.update("browser", req.headers["user-agent"])
.where("id", user[0].sess_id);