mirror of
https://github.com/umami-software/umami.git
synced 2026-02-13 17:15:37 +01:00
add psql.
This commit is contained in:
parent
79a93ed9fc
commit
5c9abe966b
1 changed files with 134 additions and 47 deletions
|
|
@ -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(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue