add psql.

This commit is contained in:
Brian Cao 2024-05-20 23:58:40 -07:00
parent 79a93ed9fc
commit 5c9abe966b

View file

@ -29,89 +29,176 @@ async function relationalQuery(
const { startDate, endDate, goals } = criteria; const { startDate, endDate, goals } = criteria;
const { rawQuery } = prisma; const { rawQuery } = prisma;
const hasUrl = goals.some(a => a.type === 'url'); const urls = goals.filter(a => a.type === 'url');
const hasEvent = goals.some(a => a.type === 'event'); const events = goals.filter(a => a.type === 'event');
const eventData = goals.filter(a => a.type === 'event-data');
function getParameters(goals: { type: string; value: string; goal: number }[]) { const hasUrl = urls.length > 0;
const urls = goals const hasEvent = events.length > 0;
.filter(a => a.type === 'url') const hasEventData = eventData.length > 0;
.reduce((acc, cv, i) => {
acc[`${cv.type}${i}`] = cv.value;
return acc;
}, {});
const events = goals function getParameters(
.filter(a => a.type === 'event') urls: { type: string; value: string; goal: number }[],
.reduce((acc, cv, i) => { events: { type: string; value: string; goal: number }[],
acc[`${cv.type}${i}`] = cv.value; eventData: {
return acc; type: string;
}, {}); value: string;
goal: number;
operator?: string;
property?: string;
}[],
) {
const urlParam = urls.reduce((acc, cv, i) => {
acc[`${cv.type}${i}`] = cv.value;
return acc;
}, {});
const eventParam = events.reduce((acc, cv, i) => {
acc[`${cv.type}${i}`] = cv.value;
return acc;
}, {});
const eventDataParam = eventData.reduce((acc, cv, i) => {
acc[`eventData${i}`] = cv.value;
acc[`property${i}`] = cv.property;
acc[`eventData${i + 999}`] = cv.value;
acc[`property${i + 999}`] = cv.property;
return acc;
}, {});
return { return {
urls: { ...urls, startDate, endDate, websiteId }, urls: { ...urlParam, startDate, endDate, websiteId },
events: { ...events, startDate, endDate, websiteId }, events: { ...eventParam, startDate, endDate, websiteId },
eventData: { ...eventDataParam, startDate, endDate, websiteId },
}; };
} }
function getColumns(goals: { type: string; value: string; goal: number }[]) { function getColumns(
const urls = goals urls: { type: string; value: string; goal: number }[],
.filter(a => a.type === 'url') events: { type: string; value: string; goal: number }[],
.map((a, i) => `COUNT(CASE WHEN url_path = {{url${i}}} THEN 1 END) AS URL${i}`) eventData: {
.join('\n'); type: string;
const events = goals value: string;
.filter(a => a.type === 'event') goal: number;
.map((a, i) => `COUNT(CASE WHEN url_path = {{event${i}}} THEN 1 END) AS EVENT${i}`) operator?: string;
.join('\n'); property?: string;
}[],
) {
const urlColumns = urls
.map((a, i) => `COUNT(CASE WHEN url_path = {{url${i}}} THEN 1 END) AS URL${i},`)
.join('\n')
.slice(0, -1);
const eventColumns = events
.map((a, i) => `COUNT(CASE WHEN url_path = {{event${i}}} THEN 1 END) AS EVENT${i},`)
.join('\n')
.slice(0, -1);
const eventDataColumns = eventData
.map(
(a, i) =>
`${
a.operator === 'average' ? 'avg' : a.operator
}(CASE WHEN event_name = {{eventData${i}}} AND data_key = {{property${i}}} THEN ${
a.operator === 'count' ? '1' : 'number_value'
} END) AS EVENT_DATA${i},`,
)
.join('\n')
.slice(0, -1);
return { urls, events }; return { urls: urlColumns, events: eventColumns, eventData: eventDataColumns };
} }
function getWhere(goals: { type: string; value: string; goal: number }[]) { function getWhere(
const urls = goals urls: { type: string; value: string; goal: number }[],
.filter(a => a.type === 'url') events: { type: string; value: string; goal: number }[],
.map((a, i) => `{{url${i}}}`) eventData: {
.join(','); type: string;
const events = goals value: string;
.filter(a => a.type === 'event') goal: number;
.map((a, i) => `{{event${i}}}`) operator?: string;
.join(','); property?: string;
}[],
) {
const urlWhere = urls.map((a, i) => `{{url${i}}}`).join(',');
const eventWhere = events.map((a, i) => `{{event${i}}}`).join(',');
const eventDataNameWhere = eventData.map((a, i) => `{{eventData${i + 999}}}`).join(',');
const eventDataKeyWhere = eventData.map((a, i) => `{{property${i + 999}}}`).join(',');
return { urls: `and url_path in (${urls})`, events: `and event_name in (${events})` }; return {
urls: `and url_path in (${urlWhere})`,
events: `and event_name in (${eventWhere})`,
eventData: `and event_name in (${eventDataNameWhere}) and data_key in (${eventDataKeyWhere})`,
};
} }
const parameters = getParameters(goals); const parameters = getParameters(urls, events, eventData);
const columns = getColumns(goals); const columns = getColumns(urls, events, eventData);
const where = getWhere(goals); const where = getWhere(urls, events, eventData);
const urls = hasUrl const urlResults = hasUrl
? await rawQuery( ? await rawQuery(
` `
select select
${columns.urls} ${columns.urls}
from website_event from website_event
where websiteId = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
${where.urls} ${where.urls}
and created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}
`, `,
parameters.urls, parameters.urls,
) ).then(a => {
const results = a[0];
return Object.keys(results).map((key, i) => ({
...urls[i],
goal: Number(urls[i].goal),
result: Number(results[key]),
}));
})
: []; : [];
const events = hasEvent const eventResults = hasEvent
? await rawQuery( ? await rawQuery(
` `
select select
${columns.events} ${columns.events}
from website_event from website_event
where websiteId = {{websiteId::uuid}} where website_id = {{websiteId::uuid}}
${where.events} ${where.events}
and created_at between {{startDate}} and {{endDate}} and created_at between {{startDate}} and {{endDate}}
`, `,
parameters.events, parameters.events,
) ).then(a => {
const results = a[0];
return Object.keys(results).map((key, i) => {
return { ...events[i], goal: Number(events[i].goal), result: Number(results[key]) };
});
})
: []; : [];
return [...urls, ...events]; const eventDataResults = hasEventData
? await rawQuery(
`
select
${columns.eventData}
from website_event w
join event_data d
on d.website_event_id = w.event_id
where w.website_id = {{websiteId::uuid}}
${where.eventData}
and w.created_at between {{startDate}} and {{endDate}}
`,
parameters.eventData,
).then(a => {
const results = a[0];
return Object.keys(results).map((key, i) => {
return { ...eventData[i], goal: Number(eventData[i].goal), result: Number(results[key]) };
});
})
: [];
return [...urlResults, ...eventResults, ...eventDataResults];
} }
async function clickhouseQuery( async function clickhouseQuery(