mirror of
https://github.com/PostHog/posthog.git
synced 2024-11-30 19:41:46 +01:00
92e8bbd283
* convert sessions table logic to TS * convert rest of sessions to TS * sessions table logic refactor, store date in the url * add back/forward buttons * load sessions based on the URL, not after mount --> avoids duplicate query if opening an url with a filter * prevent multiple queries * throw error if failed instead of returning an empty list * date from filters * rename offset to nextOffset * initial limit/offset block * indent sql * support limit + offset * load LIMIT+1 sessions in postgres, pop last and show load more sign. (was: show sign if exactly LIMIT fetched) * based offset is always 0 * default limit to 50 * events in clickhouse sessions * add elements to query results * add person properties to sessions query response * show seconds with two digits * fix pagination, timestamp calculation and ordering on pages 2 and beyond * mypy * fix test * add default time to fix test, fix some any(*) filter issues * remove reverse * WIP event list * Events progress * Finish off event listing, skip live actions for now * Fix mypy * Fix mypy again * Try fixing mypy * Fix assertnumqueries * Fix tests * Fix tests * fix test * Fix tests * Fix tests * Fix tests again Co-authored-by: Marius Andra <marius.andra@gmail.com> Co-authored-by: Eric <eeoneric@gmail.com>
81 lines
2.8 KiB
Python
81 lines
2.8 KiB
Python
from typing import Dict, List, Optional, Tuple
|
|
|
|
from ee.clickhouse.client import sync_execute
|
|
from ee.clickhouse.models.cohort import format_cohort_table_name
|
|
from ee.clickhouse.sql.cohort import COHORT_DISTINCT_ID_FILTER_SQL
|
|
from ee.clickhouse.sql.events import EVENT_PROP_CLAUSE, SELECT_PROP_VALUES_SQL, SELECT_PROP_VALUES_SQL_WITH_FILTER
|
|
from posthog.models.cohort import Cohort
|
|
from posthog.models.property import Property
|
|
from posthog.models.team import Team
|
|
|
|
|
|
def parse_filter(filters: List[Property]) -> Tuple[str, Dict]:
|
|
result = ""
|
|
params = {}
|
|
for idx, prop in enumerate(filters):
|
|
result += "{cond}(ep.key = %(k{idx})s) AND (trim(BOTH '\"' FROM ep.value) = %(v{idx})s)".format(
|
|
idx=idx, cond=" AND " if idx > 0 else ""
|
|
)
|
|
params.update({"k{}".format(idx): prop.key, "v{}".format(idx): prop.value})
|
|
return result, params
|
|
|
|
|
|
def parse_prop_clauses(key: str, filters: List[Property], team: Team, prepend: str = "") -> Tuple[str, Dict]:
|
|
final = ""
|
|
params = {}
|
|
for idx, prop in enumerate(filters):
|
|
|
|
if prop.type == "cohort":
|
|
cohort = Cohort.objects.get(pk=prop.value)
|
|
clause = COHORT_DISTINCT_ID_FILTER_SQL.format(table_name=format_cohort_table_name(cohort))
|
|
final += "{cond} ({clause}) ".format(cond="AND distinct_id IN", clause=clause)
|
|
|
|
else:
|
|
filter = "(ep.key = %(k{prepend}_{idx})s) AND (ep.value {operator} %(v{prepend}_{idx})s)".format(
|
|
idx=idx, operator=get_operator(prop.operator), prepend=prepend
|
|
)
|
|
clause = EVENT_PROP_CLAUSE.format(team_id=team.pk, filters=filter)
|
|
final += "{cond} ({clause}) ".format(cond="AND {key} IN".format(key=key), clause=clause)
|
|
params.update(
|
|
{"k{}_{}".format(prepend, idx): prop.key, "v{}_{}".format(prepend, idx): _pad_value(prop.value)}
|
|
)
|
|
return final, params
|
|
|
|
|
|
def _pad_value(val: str):
|
|
if not val.startswith('"'):
|
|
val = '"' + val
|
|
|
|
if not val.endswith('"'):
|
|
val = val + '"'
|
|
|
|
return val
|
|
|
|
|
|
# TODO: handle all operators
|
|
def get_operator(operator: Optional[str]):
|
|
if operator == "is_not":
|
|
return "!="
|
|
elif operator == "icontains":
|
|
return "LIKE"
|
|
elif operator == "not_icontains":
|
|
return "NOT LIKE"
|
|
elif operator == "regex":
|
|
return "="
|
|
elif operator == "not_regex":
|
|
return "="
|
|
elif operator == "gt":
|
|
return ">"
|
|
elif operator == "lt":
|
|
return "<"
|
|
else:
|
|
return "="
|
|
|
|
|
|
def get_property_values_for_key(key: str, team: Team, value: Optional[str] = None):
|
|
if value:
|
|
return sync_execute(
|
|
SELECT_PROP_VALUES_SQL_WITH_FILTER, {"team_id": team.pk, "key": key, "value": "%{}%".format(value)}
|
|
)
|
|
return sync_execute(SELECT_PROP_VALUES_SQL, {"team_id": team.pk, "key": key})
|