2020-07-17 10:03:38 +02:00
|
|
|
import { PrismaClient } from '@prisma/client';
|
2020-07-29 04:04:45 +02:00
|
|
|
import chalk from 'chalk';
|
2020-07-17 10:03:38 +02:00
|
|
|
|
2020-07-28 10:17:45 +02:00
|
|
|
const options = {
|
2020-07-25 02:00:56 +02:00
|
|
|
log: [
|
|
|
|
{
|
|
|
|
emit: 'event',
|
|
|
|
level: 'query',
|
|
|
|
},
|
|
|
|
],
|
2020-07-28 10:17:45 +02:00
|
|
|
};
|
|
|
|
|
2020-07-29 04:04:45 +02:00
|
|
|
function logQuery(e) {
|
|
|
|
if (process.env.LOG_QUERY) {
|
|
|
|
console.log(chalk.yellow(e.params), '->', e.query, chalk.greenBright(`${e.duration}ms`));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-28 10:17:45 +02:00
|
|
|
let prisma;
|
|
|
|
|
|
|
|
if (process.env.NODE_ENV === 'production') {
|
|
|
|
prisma = new PrismaClient(options);
|
2020-07-29 04:04:45 +02:00
|
|
|
prisma.on('query', logQuery);
|
2020-07-28 10:17:45 +02:00
|
|
|
} else {
|
|
|
|
if (!global.prisma) {
|
|
|
|
global.prisma = new PrismaClient(options);
|
2020-07-29 04:04:45 +02:00
|
|
|
global.prisma.on('query', logQuery);
|
2020-07-28 10:17:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
prisma = global.prisma;
|
|
|
|
}
|
|
|
|
|
|
|
|
export default prisma;
|
2020-07-25 02:00:56 +02:00
|
|
|
|
2020-07-17 10:03:38 +02:00
|
|
|
export async function runQuery(query) {
|
2020-07-24 19:56:45 +02:00
|
|
|
return query.catch(e => {
|
|
|
|
console.error(e);
|
|
|
|
throw e;
|
|
|
|
});
|
2020-07-17 10:03:38 +02:00
|
|
|
}
|
|
|
|
|
2020-08-04 03:12:28 +02:00
|
|
|
export async function getWebsite({ website_id, website_uuid }) {
|
2020-07-17 10:03:38 +02:00
|
|
|
return runQuery(
|
|
|
|
prisma.website.findOne({
|
|
|
|
where: {
|
2020-08-04 03:12:28 +02:00
|
|
|
...(website_id && { website_id }),
|
|
|
|
...(website_uuid && { website_uuid }),
|
2020-07-17 10:03:38 +02:00
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-07-28 08:52:14 +02:00
|
|
|
export async function getWebsites(user_id) {
|
|
|
|
return runQuery(
|
|
|
|
prisma.website.findMany({
|
|
|
|
where: {
|
|
|
|
user_id,
|
|
|
|
},
|
2020-08-07 11:27:12 +02:00
|
|
|
orderBy: {
|
|
|
|
name: 'asc',
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-08 02:19:42 +02:00
|
|
|
export async function createWebsite(user_id, data) {
|
|
|
|
return runQuery(
|
|
|
|
prisma.website.create({
|
|
|
|
data: {
|
|
|
|
account: {
|
|
|
|
connect: {
|
|
|
|
user_id,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
...data,
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-07 11:27:12 +02:00
|
|
|
export async function updateWebsite(website_id, data) {
|
|
|
|
return runQuery(
|
|
|
|
prisma.website.update({
|
|
|
|
where: {
|
|
|
|
website_id,
|
|
|
|
},
|
|
|
|
data,
|
2020-07-28 08:52:14 +02:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-08 02:19:42 +02:00
|
|
|
export async function deleteWebsite(website_id) {
|
|
|
|
return runQuery(
|
|
|
|
/* Prisma bug, does not cascade on non-nullable foreign keys
|
|
|
|
prisma.website.delete({
|
|
|
|
where: {
|
|
|
|
website_id,
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
*/
|
|
|
|
prisma.queryRaw(`delete from website where website_id=$1`, website_id),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-07-20 10:54:21 +02:00
|
|
|
export async function createSession(website_id, data) {
|
|
|
|
return runQuery(
|
2020-07-17 10:03:38 +02:00
|
|
|
prisma.session.create({
|
|
|
|
data: {
|
|
|
|
website: {
|
|
|
|
connect: {
|
2020-07-20 10:54:21 +02:00
|
|
|
website_id,
|
2020-07-17 10:03:38 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
...data,
|
|
|
|
},
|
2020-07-20 10:54:21 +02:00
|
|
|
select: {
|
|
|
|
session_id: true,
|
|
|
|
},
|
2020-07-17 10:03:38 +02:00
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-08-04 03:12:28 +02:00
|
|
|
export async function getSession({ session_id, session_uuid }) {
|
2020-07-17 10:03:38 +02:00
|
|
|
return runQuery(
|
|
|
|
prisma.session.findOne({
|
|
|
|
where: {
|
2020-08-04 03:12:28 +02:00
|
|
|
...(session_id && { session_id }),
|
|
|
|
...(session_uuid && { session_uuid }),
|
2020-07-17 10:03:38 +02:00
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-07-19 08:54:25 +02:00
|
|
|
export async function savePageView(website_id, session_id, url, referrer) {
|
2020-07-17 10:03:38 +02:00
|
|
|
return runQuery(
|
|
|
|
prisma.pageview.create({
|
|
|
|
data: {
|
2020-07-19 08:54:25 +02:00
|
|
|
website: {
|
|
|
|
connect: {
|
2020-07-20 10:54:21 +02:00
|
|
|
website_id,
|
2020-07-19 08:54:25 +02:00
|
|
|
},
|
|
|
|
},
|
2020-07-17 10:03:38 +02:00
|
|
|
session: {
|
|
|
|
connect: {
|
2020-07-20 10:54:21 +02:00
|
|
|
session_id,
|
2020-07-17 10:03:38 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
url,
|
|
|
|
referrer,
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
2020-07-19 10:57:01 +02:00
|
|
|
|
2020-07-19 11:23:15 +02:00
|
|
|
export async function saveEvent(website_id, session_id, url, event_type, event_value) {
|
2020-07-19 10:57:01 +02:00
|
|
|
return runQuery(
|
2020-07-19 11:23:15 +02:00
|
|
|
prisma.event.create({
|
2020-07-19 10:57:01 +02:00
|
|
|
data: {
|
|
|
|
website: {
|
|
|
|
connect: {
|
2020-07-20 10:54:21 +02:00
|
|
|
website_id,
|
2020-07-19 10:57:01 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
session: {
|
|
|
|
connect: {
|
2020-07-20 10:54:21 +02:00
|
|
|
session_id,
|
2020-07-19 10:57:01 +02:00
|
|
|
},
|
|
|
|
},
|
|
|
|
url,
|
2020-07-19 11:23:15 +02:00
|
|
|
event_type,
|
|
|
|
event_value,
|
2020-07-19 10:57:01 +02:00
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
2020-07-23 05:45:09 +02:00
|
|
|
|
|
|
|
export async function getAccount(username = '') {
|
|
|
|
return runQuery(
|
|
|
|
prisma.account.findOne({
|
|
|
|
where: {
|
|
|
|
username,
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
2020-07-26 01:31:07 +02:00
|
|
|
|
2020-07-26 09:12:42 +02:00
|
|
|
export async function getPageviews(website_id, start_at, end_at) {
|
2020-07-26 01:31:07 +02:00
|
|
|
return runQuery(
|
|
|
|
prisma.pageview.findMany({
|
|
|
|
where: {
|
|
|
|
website_id,
|
2020-07-26 09:12:42 +02:00
|
|
|
created_at: {
|
|
|
|
gte: start_at,
|
|
|
|
lte: end_at,
|
|
|
|
},
|
2020-07-26 01:31:07 +02:00
|
|
|
},
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
}
|
2020-07-28 08:52:14 +02:00
|
|
|
|
2020-08-01 04:05:14 +02:00
|
|
|
export async function getRankings(website_id, start_at, end_at, type, table) {
|
|
|
|
return runQuery(
|
|
|
|
prisma.queryRaw(
|
|
|
|
`
|
|
|
|
select distinct "${type}" x, count(*) y
|
|
|
|
from "${table}"
|
|
|
|
where website_id=$1
|
|
|
|
and created_at between $2 and $3
|
|
|
|
group by 1
|
|
|
|
order by 2 desc
|
|
|
|
`,
|
|
|
|
website_id,
|
|
|
|
start_at,
|
|
|
|
end_at,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2020-07-28 08:52:14 +02:00
|
|
|
export async function getPageviewData(
|
|
|
|
website_id,
|
|
|
|
start_at,
|
|
|
|
end_at,
|
|
|
|
timezone = 'utc',
|
|
|
|
unit = 'day',
|
|
|
|
count = '*',
|
|
|
|
) {
|
|
|
|
return runQuery(
|
|
|
|
prisma.queryRaw(
|
|
|
|
`
|
2020-07-31 07:40:16 +02:00
|
|
|
select date_trunc('${unit}', created_at at time zone '${timezone}') at time zone '${timezone}' t,
|
2020-07-28 08:52:14 +02:00
|
|
|
count(${count}) y
|
|
|
|
from pageview
|
|
|
|
where website_id=$1
|
|
|
|
and created_at between $2 and $3
|
|
|
|
group by 1
|
|
|
|
order by 1
|
|
|
|
`,
|
|
|
|
website_id,
|
|
|
|
start_at,
|
|
|
|
end_at,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
2020-07-29 09:16:02 +02:00
|
|
|
|
2020-07-31 05:11:43 +02:00
|
|
|
export async function getMetrics(website_id, start_at, end_at) {
|
2020-07-29 09:16:02 +02:00
|
|
|
return runQuery(
|
|
|
|
prisma.queryRaw(
|
|
|
|
`
|
2020-07-30 06:40:26 +02:00
|
|
|
select sum(t.c) as "pageviews",
|
|
|
|
count(distinct t.session_id) as "uniques",
|
|
|
|
sum(case when t.c = 1 then t.c else 0 end) as "bounces",
|
|
|
|
sum(t.time) as "totaltime"
|
|
|
|
from (
|
|
|
|
select session_id,
|
|
|
|
date_trunc('hour', created_at),
|
|
|
|
count(*) c,
|
|
|
|
floor(extract(epoch from max(created_at) - min(created_at))) as "time"
|
|
|
|
from pageview
|
|
|
|
where website_id=${website_id}
|
|
|
|
and created_at between '${start_at}' and '${end_at}'
|
|
|
|
group by 1, 2
|
|
|
|
) t;
|
|
|
|
`,
|
2020-07-29 09:16:02 +02:00
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|