Updated prisma and redis clients.

This commit is contained in:
Mike Cao 2022-12-26 21:51:16 -08:00
parent c05d116875
commit dff105c747
9 changed files with 40 additions and 125 deletions

View File

@ -1,10 +1,16 @@
import { User, Website } from '@prisma/client';
import redis from 'lib/redis';
import redis from '@umami/redis-client';
import { getSession, getUser, getWebsite } from '../queries';
const DELETED = 'DELETED';
async function fetchObject(key, query) {
const obj = await redis.get(key);
if (obj === DELETED) {
return null;
}
if (!obj) {
return query().then(async data => {
if (data) {
@ -22,8 +28,8 @@ async function storeObject(key, data) {
return redis.set(key, data);
}
async function deleteObject(key) {
return redis.set(key, redis.DELETED);
async function deleteObject(key, soft = false) {
return soft ? redis.set(key, DELETED) : redis.del(key);
}
async function fetchWebsite(id): Promise<Website> {
@ -42,7 +48,7 @@ async function deleteWebsite(id) {
}
async function fetchUser(id): Promise<User> {
return fetchObject(`user:${id}`, () => getUser({ id }, true));
return fetchObject(`user:${id}`, () => getUser({ id }, { includePassword: true }));
}
async function storeUser(data) {

View File

@ -4,7 +4,6 @@ export const MYSQL = 'mysql';
export const CLICKHOUSE = 'clickhouse';
export const KAFKA = 'kafka';
export const KAFKA_PRODUCER = 'kafka-producer';
export const REDIS = 'redis';
// Fixes issue with converting bigint values
BigInt.prototype.toJSON = function () {

View File

@ -2,10 +2,10 @@ import { createMiddleware, unauthorized, badRequest, parseSecureToken } from 'ne
import debug from 'debug';
import cors from 'cors';
import { validate } from 'uuid';
import redis from '@umami/redis-client';
import { findSession } from 'lib/session';
import { getAuthToken, parseShareToken } from 'lib/auth';
import { secret } from 'lib/crypto';
import redis from 'lib/redis';
import { ROLES } from 'lib/constants';
import { getUser } from '../queries';
@ -17,7 +17,7 @@ export const useSession = createMiddleware(async (req, res, next) => {
const session = await findSession(req);
if (!session) {
log('useSession:session-not-found');
log('useSession: Session not found');
return badRequest(res);
}
@ -42,7 +42,7 @@ export const useAuth = createMiddleware(async (req, res, next) => {
log({ token, payload, user, shareToken });
if (!user && !shareToken) {
log('useAuth:user-not-authorized');
log('useAuth: User not authorized');
return unauthorized(res);
}

View File

@ -1,10 +1,7 @@
import { PrismaClient } from '@prisma/client';
import chalk from 'chalk';
import prisma from '@umami/prisma-client';
import moment from 'moment-timezone';
import debug from 'debug';
import { PRISMA, MYSQL, POSTGRESQL, getDatabaseType } from 'lib/db';
import { MYSQL, POSTGRESQL, getDatabaseType } from 'lib/db';
import { FILTER_IGNORED } from 'lib/constants';
import { PrismaClientOptions } from '@prisma/client/runtime';
const MYSQL_DATE_FORMATS = {
minute: '%Y-%m-%d %H:%i:00',
@ -22,39 +19,7 @@ const POSTGRESQL_DATE_FORMATS = {
year: 'YYYY-01-01',
};
const log = debug('umami:prisma');
const PRISMA_OPTIONS = {
log: [
{
emit: 'event',
level: 'query',
},
],
};
function logQuery(e) {
log(chalk.yellow(e.params), '->', e.query, chalk.greenBright(`${e.duration}ms`));
}
function getClient(options) {
const prisma: PrismaClient<PrismaClientOptions, 'query' | 'error' | 'info' | 'warn'> =
new PrismaClient(options);
if (process.env.LOG_QUERY) {
prisma.$on('query', logQuery);
}
if (process.env.NODE_ENV !== 'production') {
global[PRISMA] = prisma;
}
log('Prisma initialized');
return prisma;
}
function getDateQuery(field, unit, timezone?): string {
function getDateQuery(field: string, unit: string, timezone?: string): string {
const db = getDatabaseType(process.env.DATABASE_URL);
if (db === POSTGRESQL) {
@ -75,7 +40,7 @@ function getDateQuery(field, unit, timezone?): string {
}
}
function getTimestampInterval(field): string {
function getTimestampInterval(field: string): string {
const db = getDatabaseType(process.env.DATABASE_URL);
if (db === POSTGRESQL) {
@ -207,7 +172,7 @@ function parseFilters(
};
}
async function rawQuery(query, params = []): Promise<any> {
async function rawQuery(query: string, params: never[] = []): Promise<any> {
const db = getDatabaseType(process.env.DATABASE_URL);
if (db !== POSTGRESQL && db !== MYSQL) {
@ -216,20 +181,11 @@ async function rawQuery(query, params = []): Promise<any> {
const sql = db === MYSQL ? query.replace(/\$[0-9]+/g, '?') : query;
return prisma.$queryRawUnsafe.apply(prisma, [sql, ...params]);
return prisma.rawQuery(sql, params);
}
async function transaction(queries): Promise<any> {
return prisma.$transaction(queries);
}
// Initialization
const prisma: PrismaClient<PrismaClientOptions, 'query' | 'error' | 'info' | 'warn'> =
global[PRISMA] || getClient(PRISMA_OPTIONS);
export default {
client: prisma,
log,
...prisma,
getDateQuery,
getTimestampInterval,
getFilterQuery,
@ -237,5 +193,4 @@ export default {
getEventDataFilterQuery,
parseFilters,
rawQuery,
transaction,
};

View File

@ -1,62 +0,0 @@
import { createClient } from 'redis';
import debug from 'debug';
const log = debug('umami:redis');
const REDIS = Symbol();
const DELETED = 'DELETED';
let redis;
const url = process.env.REDIS_URL;
const enabled = Boolean(url);
async function getClient() {
if (!enabled) {
return null;
}
const client = createClient({ url });
client.on('error', err => log(err));
await client.connect();
if (process.env.NODE_ENV !== 'production') {
global[REDIS] = client;
}
log('Redis initialized');
return client;
}
async function get(key) {
await connect();
const data = await redis.get(key);
try {
return JSON.parse(data);
} catch {
return null;
}
}
async function set(key, value) {
await connect();
return redis.set(key, JSON.stringify(value));
}
async function del(key) {
await connect();
return redis.del(key);
}
async function connect() {
if (!redis && enabled) {
redis = global[REDIS] || (await getClient());
}
return redis;
}
export default { enabled, client: redis, log, connect, get, set, del, DELETED };

View File

@ -61,6 +61,8 @@
"@fontsource/inter": "4.5.7",
"@prisma/client": "4.8.0",
"@tanstack/react-query": "^4.16.1",
"@umami/prisma-client": "^0.1.0",
"@umami/redis-client": "^0.1.0",
"chalk": "^4.1.1",
"chart.js": "^2.9.4",
"classnames": "^2.3.1",

View File

@ -7,9 +7,9 @@ import {
methodNotAllowed,
getRandomChars,
} from 'next-basics';
import redis from '@umami/redis-client';
import { getUser, User } from 'queries';
import { secret } from 'lib/crypto';
import redis from 'lib/redis';
import { NextApiRequestQueryBody } from 'lib/types';
import { NextApiResponse } from 'next';

View File

@ -1,6 +1,6 @@
import { methodNotAllowed, ok } from 'next-basics';
import redis from '@umami/redis-client';
import { useAuth } from 'lib/middleware';
import redis from 'lib/redis';
import { getAuthToken } from 'lib/auth';
import { NextApiRequest, NextApiResponse } from 'next';

View File

@ -2290,6 +2290,21 @@
"@typescript-eslint/types" "5.45.0"
eslint-visitor-keys "^3.3.0"
"@umami/prisma-client@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@umami/prisma-client/-/prisma-client-0.1.0.tgz#4ecc17b1998cb738b8f2027b80b003864beef6a4"
integrity sha512-2qTXN0dtMUT+HVhz37eVC02lDSwz9TGUGHRRO0LPRHdfJPfSkUF0D8pgksX7ETy3IZoIQP1h45tiXsM0pKBMZA==
dependencies:
debug "^4.3.4"
"@umami/redis-client@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@umami/redis-client/-/redis-client-0.1.0.tgz#69599b1243406a3aef83927bb8655a3ef4c0c031"
integrity sha512-XCqCdc3xA5KDOorIUvOVlz+/F/SEyL9cKWfCCGYYZix1b9yFo+5BzM0C0q7Yu/qV+1jYd+viNsBQQSM6a8sfjg==
dependencies:
debug "^4.3.4"
redis "^4.5.1"
"@vercel/node-bridge@^2.1.0":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@vercel/node-bridge/-/node-bridge-2.2.2.tgz#f63466ab6a2588afdc6262c2d060289bfe8baa6b"
@ -6632,7 +6647,7 @@ redis-parser@^3.0.0:
dependencies:
redis-errors "^1.0.0"
redis@^4.5.0:
redis@^4.5.0, redis@^4.5.1:
version "4.5.1"
resolved "https://registry.yarnpkg.com/redis/-/redis-4.5.1.tgz#f5a818970bb2dc5d60540bab41308640604c7d33"
integrity sha512-oxXSoIqMJCQVBTfxP6BNTCtDMyh9G6Vi5wjdPdV/sRKkufyZslDqCScSGcOr6XGR/reAWZefz7E4leM31RgdBA==