Add GLOB match type to replace PREFIX for tracker patterns
Introduces a wildcard-based match type that supports prefix, suffix, and sandwich patterns (e.g. ph_phc_*_posthog). The SQL matching uses starts_with/ends_with on the parts split at '*', avoiding LIKE and its underscore escaping issues. Existing PREFIX rows are migrated to GLOB with a trailing '*'. Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
15
pkg/coredata/migrations/20260506T193600Z.sql
Normal file
15
pkg/coredata/migrations/20260506T193600Z.sql
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
-- Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
-- purpose with or without fee is hereby granted, provided that the above
|
||||||
|
-- copyright notice and this permission notice appear in all copies.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
-- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
-- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
-- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
-- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
-- PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
ALTER TYPE cookie_pattern_match_type ADD VALUE IF NOT EXISTS 'GLOB';
|
||||||
18
pkg/coredata/migrations/20260506T193601Z.sql
Normal file
18
pkg/coredata/migrations/20260506T193601Z.sql
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
-- Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||||
|
--
|
||||||
|
-- Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
-- purpose with or without fee is hereby granted, provided that the above
|
||||||
|
-- copyright notice and this permission notice appear in all copies.
|
||||||
|
--
|
||||||
|
-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
-- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
-- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
-- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
-- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
-- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
-- PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
UPDATE tracker_patterns
|
||||||
|
SET pattern = pattern || '*',
|
||||||
|
match_type = 'GLOB'
|
||||||
|
WHERE match_type = 'PREFIX';
|
||||||
@@ -239,15 +239,17 @@ WHERE
|
|||||||
AND cookie_banner_id = @cookie_banner_id
|
AND cookie_banner_id = @cookie_banner_id
|
||||||
AND tracker_type = @tracker_type
|
AND tracker_type = @tracker_type
|
||||||
AND (
|
AND (
|
||||||
(match_type = @match_type_prefix AND starts_with(@identifier, pattern))
|
(match_type = @match_type_glob
|
||||||
|
AND starts_with(@identifier, split_part(pattern, '*', 1))
|
||||||
|
AND ends_with(@identifier, split_part(pattern, '*', 2))
|
||||||
|
AND length(@identifier) >= length(pattern) - 1)
|
||||||
OR (match_type = @match_type_exact AND pattern = @identifier)
|
OR (match_type = @match_type_exact AND pattern = @identifier)
|
||||||
)
|
)
|
||||||
ORDER BY
|
ORDER BY
|
||||||
CASE WHEN match_type = @match_type_exact AND pattern = @identifier THEN 0
|
CASE WHEN match_type = @match_type_exact AND pattern = @identifier THEN 0
|
||||||
WHEN match_type = @match_type_prefix THEN 1
|
ELSE 1
|
||||||
ELSE 2
|
|
||||||
END,
|
END,
|
||||||
LENGTH(pattern) DESC
|
length(pattern) - 1 DESC
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
`
|
`
|
||||||
|
|
||||||
@@ -257,7 +259,7 @@ LIMIT 1;
|
|||||||
"cookie_banner_id": cookieBannerID,
|
"cookie_banner_id": cookieBannerID,
|
||||||
"tracker_type": trackerType,
|
"tracker_type": trackerType,
|
||||||
"identifier": identifier,
|
"identifier": identifier,
|
||||||
"match_type_prefix": TrackerPatternMatchTypePrefix,
|
"match_type_glob": TrackerPatternMatchTypeGlob,
|
||||||
"match_type_exact": TrackerPatternMatchTypeExact,
|
"match_type_exact": TrackerPatternMatchTypeExact,
|
||||||
}
|
}
|
||||||
maps.Copy(args, scope.SQLArguments())
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|||||||
@@ -24,12 +24,13 @@ type TrackerPatternMatchType string
|
|||||||
const (
|
const (
|
||||||
TrackerPatternMatchTypeExact TrackerPatternMatchType = "EXACT"
|
TrackerPatternMatchTypeExact TrackerPatternMatchType = "EXACT"
|
||||||
TrackerPatternMatchTypePrefix TrackerPatternMatchType = "PREFIX"
|
TrackerPatternMatchTypePrefix TrackerPatternMatchType = "PREFIX"
|
||||||
|
TrackerPatternMatchTypeGlob TrackerPatternMatchType = "GLOB"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TrackerPatternMatchTypes() []TrackerPatternMatchType {
|
func TrackerPatternMatchTypes() []TrackerPatternMatchType {
|
||||||
return []TrackerPatternMatchType{
|
return []TrackerPatternMatchType{
|
||||||
TrackerPatternMatchTypeExact,
|
TrackerPatternMatchTypeExact,
|
||||||
TrackerPatternMatchTypePrefix,
|
TrackerPatternMatchTypeGlob,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +54,8 @@ func (m *TrackerPatternMatchType) Scan(value any) error {
|
|||||||
*m = TrackerPatternMatchTypeExact
|
*m = TrackerPatternMatchTypeExact
|
||||||
case TrackerPatternMatchTypePrefix:
|
case TrackerPatternMatchTypePrefix:
|
||||||
*m = TrackerPatternMatchTypePrefix
|
*m = TrackerPatternMatchTypePrefix
|
||||||
|
case TrackerPatternMatchTypeGlob:
|
||||||
|
*m = TrackerPatternMatchTypeGlob
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("invalid TrackerPatternMatchType value: %q", v)
|
return fmt.Errorf("invalid TrackerPatternMatchType value: %q", v)
|
||||||
}
|
}
|
||||||
@@ -62,7 +65,8 @@ func (m *TrackerPatternMatchType) Scan(value any) error {
|
|||||||
func (m TrackerPatternMatchType) Value() (driver.Value, error) {
|
func (m TrackerPatternMatchType) Value() (driver.Value, error) {
|
||||||
switch m {
|
switch m {
|
||||||
case TrackerPatternMatchTypeExact,
|
case TrackerPatternMatchTypeExact,
|
||||||
TrackerPatternMatchTypePrefix:
|
TrackerPatternMatchTypePrefix,
|
||||||
|
TrackerPatternMatchTypeGlob:
|
||||||
return string(m), nil
|
return string(m), nil
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("invalid TrackerPatternMatchType: %s", m)
|
return nil, fmt.Errorf("invalid TrackerPatternMatchType: %s", m)
|
||||||
|
|||||||
Reference in New Issue
Block a user