diff --git a/lib/prisma.js b/lib/prisma.js index d9eb10fb..b6cb7d5b 100644 --- a/lib/prisma.js +++ b/lib/prisma.js @@ -97,11 +97,13 @@ function getTimestampInterval(field) { } } -function getJsonField(column, property, isNumber) { +function getJsonField(column, property, isNumber, params) { const db = getDatabaseType(process.env.DATABASE_URL); if (db === POSTGRESQL) { - let accessor = `${column} ->> '${property}'`; + params.push(property); + + let accessor = `${column} ->> $${params.length}`; if (isNumber) { accessor = `CAST(${accessor} AS DECIMAL)`; @@ -111,21 +113,31 @@ function getJsonField(column, property, isNumber) { } if (db === MYSQL) { - return `${column} ->> "$.${property}"`; + params.push(`$.?${params.length}`); + + return `${column} ->> ${params.length}`; } } -function getEventDataColumnsQuery(column, columns) { - const query = Object.keys(columns).reduce((arr, key) => { +function getEventDataColumnsQuery(column, columns, params) { + const query = Object.keys(columns).reduce((arr, key, i) => { const filter = columns[key]; if (filter === undefined) { return arr; } - const isNumber = ['sum', 'avg', 'min', 'max'].some(a => a === filter); - - arr.push(`${filter}(${getJsonField(column, key, isNumber)}) as "${filter}(${key})"`); + switch (filter) { + case 'sum': + case 'svg': + case 'min': + case 'max': + arr.push(`${filter}(${getJsonField(column, key, true, params)}) as "${i}"`); + break; + case 'count': + arr.push(`${filter}(${getJsonField(column, key, false, params)}) as "${i}"`); + break; + } return arr; }, []); @@ -133,7 +145,7 @@ function getEventDataColumnsQuery(column, columns) { return query.join(',\n'); } -function getEventDataFilterQuery(column, filters) { +function getEventDataFilterQuery(column, filters, params) { const query = Object.keys(filters).reduce((arr, key) => { const filter = filters[key]; @@ -143,11 +155,9 @@ function getEventDataFilterQuery(column, filters) { const isNumber = filter && typeof filter === 'number'; - arr.push( - `${getJsonField(column, key, isNumber)} = ${ - typeof filter === 'string' ? `'${filter}'` : filter - }`, - ); + arr.push(`${getJsonField(column, key, isNumber, params)} = $${params.length + 1}`); + + params.push(filter); return arr; }, []); diff --git a/queries/analytics/event/getEventData.js b/queries/analytics/event/getEventData.js index cef3b4c2..281c9f22 100644 --- a/queries/analytics/event/getEventData.js +++ b/queries/analytics/event/getEventData.js @@ -13,9 +13,20 @@ async function relationalQuery(websiteId, { startDate, endDate, event_name, colu const { rawQuery, getEventDataColumnsQuery, getEventDataFilterQuery, toUuid } = prisma; const params = [websiteId, startDate, endDate]; + if (event_name) { + params.push(event_name); + } + + const columnQuery = getEventDataColumnsQuery('event_data.event_data', columns, params); + + const filterQuery = + Object.keys(filters).length > 0 + ? `and ${getEventDataFilterQuery('event_data.event_data', filters, params)}` + : ''; + return rawQuery( `select - ${getEventDataColumnsQuery('event_data.event_data', columns)} + ${columnQuery} from event join website on event.website_id = website.website_id @@ -23,16 +34,14 @@ async function relationalQuery(websiteId, { startDate, endDate, event_name, colu on event.event_id = event_data.event_id where website_uuid = $1${toUuid()} and event.created_at between $2 and $3 - ${event_name ? `and event_name = ${event_name}` : ''} - ${ - Object.keys(filters).length > 0 - ? `and ${getEventDataFilterQuery('event_data.event_data', filters)}` - : '' - }`, + ${event_name ? `and event_name = $4` : ''} + ${filterQuery}`, params, ).then(results => { - return Object.keys(results[0]).map(a => { - return { x: a, y: results[0][`${a}`] }; + const fields = Object.keys(columns); + + return Object.keys(results[0]).map((a, i) => { + return { x: `${columns[fields[i]]}(${fields[i]})`, y: results[0][i] }; }); }); }