added strftime filter function

This commit is contained in:
Gani Georgiev
2026-01-15 14:27:53 +02:00
parent 8bbd0c2d77
commit 6bf5eccfa7
10 changed files with 726 additions and 159 deletions

View File

@@ -49,13 +49,13 @@ type runner struct {
// shared processing state
// ---------------------------------------------------------------
activeProps []string // holds the active props that remains to be processed
activeCollectionName string // the last used collection name
activeTableAlias string // the last used table alias
nullifyMisingField bool // indicating whether to return null on missing field or return an error
withMultiMatch bool // indicates whether to attach a multiMatchSubquery condition to the ResolverResult
multiMatchActiveTableAlias string // the last used multi-match table alias
multiMatch *multiMatchSubquery // the multi-match subquery expression generated from the fieldName
activeProps []string // holds the active props that remains to be processed
activeCollectionName string // the last used collection name
activeTableAlias string // the last used table alias
nullifyMisingField bool // indicating whether to return null on missing field or return an error
withMultiMatch bool // indicates whether to attach a MultiMatchSubquery condition to the ResolverResult
multiMatchActiveTableAlias string // the last used multi-match table alias
multiMatch *search.MultiMatchSubquery // the multi-match subquery expression generated from the fieldName
}
func (r *runner) run() (*search.ResolverResult, error) {
@@ -144,13 +144,13 @@ func (r *runner) prepare() {
r.nullifyMisingField = r.activeProps[0] == "@request"
// prepare a multi-match subquery
r.multiMatch = &multiMatchSubquery{
baseTableAlias: r.activeTableAlias,
params: dbx.Params{},
r.multiMatch = &search.MultiMatchSubquery{
TargetTableAlias: r.activeTableAlias,
Params: dbx.Params{},
}
r.multiMatch.fromTableName = inflector.Columnify(r.activeCollectionName)
r.multiMatch.fromTableAlias = "__mm_" + r.activeTableAlias
r.multiMatchActiveTableAlias = r.multiMatch.fromTableAlias
r.multiMatch.FromTableName = inflector.Columnify(r.activeCollectionName)
r.multiMatch.FromTableAlias = "__mm_" + r.activeTableAlias
r.multiMatchActiveTableAlias = r.multiMatch.FromTableAlias
r.withMultiMatch = false
}
@@ -185,9 +185,9 @@ func (r *runner) processCollectionField() (*search.ResolverResult, error) {
// join the collection to the multi-match subquery
r.multiMatchActiveTableAlias = "__mm_" + r.activeTableAlias
r.multiMatch.joins = append(r.multiMatch.joins, &join{
tableName: inflector.Columnify(collection.Name),
tableAlias: r.multiMatchActiveTableAlias,
r.multiMatch.Joins = append(r.multiMatch.Joins, &search.Join{
TableName: inflector.Columnify(collection.Name),
TableAlias: r.multiMatchActiveTableAlias,
})
// leave only the collection fields
@@ -230,12 +230,12 @@ func (r *runner) processRequestAuthField() (*search.ResolverResult, error) {
// join the auth collection to the multi-match subquery
r.multiMatchActiveTableAlias = "__mm_" + r.activeTableAlias
r.multiMatch.joins = append(
r.multiMatch.joins,
&join{
tableName: inflector.Columnify(r.activeCollectionName),
tableAlias: r.multiMatchActiveTableAlias,
on: dbx.HashExp{
r.multiMatch.Joins = append(
r.multiMatch.Joins,
&search.Join{
TableName: inflector.Columnify(r.activeCollectionName),
TableAlias: r.multiMatchActiveTableAlias,
On: dbx.HashExp{
(r.multiMatchActiveTableAlias + ".id"): r.resolver.requestInfo.Auth.Id,
},
},
@@ -282,7 +282,7 @@ func (r *runner) processRequestBodyChangedModifier(bodyField Field) (*search.Res
return nil, err
}
placeholder := "@changed@" + name + security.PseudorandomString(6)
placeholder := "@changed@" + name + security.PseudorandomString(8)
result := &search.ResolverResult{
Identifier: placeholder,
@@ -302,7 +302,7 @@ func (r *runner) processRequestBodyChangedModifier(bodyField Field) (*search.Res
func (r *runner) processRequestBodyLowerModifier(bodyField Field) (*search.ResolverResult, error) {
rawValue := cast.ToString(r.resolver.requestInfo.Body[bodyField.GetName()])
placeholder := "infoLower" + bodyField.GetName() + security.PseudorandomString(6)
placeholder := "infoLower" + bodyField.GetName() + security.PseudorandomString(8)
result := &search.ResolverResult{
Identifier: "LOWER({:" + placeholder + "})",
@@ -338,7 +338,7 @@ func (r *runner) processRequestBodyEachModifier(bodyField Field) (*search.Resolv
return nil, fmt.Errorf("cannot serialize the data for field %q", r.activeProps[2])
}
placeholder := "dataEach" + security.PseudorandomString(6)
placeholder := "dataEach" + security.PseudorandomString(8)
cleanFieldName := inflector.Columnify(bodyField.GetName())
jeTable := fmt.Sprintf("json_each({:%s})", placeholder)
jeAlias := "__dataEach_je_" + cleanFieldName + r.resolver.joinAliasSuffix
@@ -362,12 +362,12 @@ func (r *runner) processRequestBodyEachModifier(bodyField Field) (*search.Resolv
jeTable2 := fmt.Sprintf("json_each({:%s})", placeholder2)
jeAlias2 := "__mm_" + jeAlias
r.multiMatch.joins = append(r.multiMatch.joins, &join{
tableName: jeTable2,
tableAlias: jeAlias2,
r.multiMatch.Joins = append(r.multiMatch.Joins, &search.Join{
TableName: jeTable2,
TableAlias: jeAlias2,
})
r.multiMatch.params[placeholder2] = bodyItemsRaw
r.multiMatch.valueIdentifier = fmt.Sprintf("[[%s.value]]", jeAlias2)
r.multiMatch.Params[placeholder2] = bodyItemsRaw
r.multiMatch.ValueIdentifier = fmt.Sprintf("[[%s.value]]", jeAlias2)
result.MultiMatchSubQuery = r.multiMatch
}
@@ -416,12 +416,12 @@ func (r *runner) processRequestBodyRelationField(bodyField Field) (*search.Resol
// join the data rel collection to the multi-match subquery
r.multiMatchActiveTableAlias = "__mm_" + r.activeTableAlias
r.multiMatch.joins = append(
r.multiMatch.joins,
&join{
tableName: r.activeCollectionName,
tableAlias: r.multiMatchActiveTableAlias,
on: dbx.In(
r.multiMatch.Joins = append(
r.multiMatch.Joins,
&search.Join{
TableName: r.activeCollectionName,
TableAlias: r.multiMatchActiveTableAlias,
On: dbx.In(
fmt.Sprintf("[[%s.id]]", r.multiMatchActiveTableAlias),
list.ToInterfaceSlice(dataRelIds)...,
),
@@ -482,7 +482,7 @@ func (r *runner) processActiveProps() (*search.ResolverResult, error) {
}
if r.withMultiMatch {
r.multiMatch.valueIdentifier = dbutils.JSONExtract(r.multiMatchActiveTableAlias+"."+inflector.Columnify(prop), jsonPathStr)
r.multiMatch.ValueIdentifier = dbutils.JSONExtract(r.multiMatchActiveTableAlias+"."+inflector.Columnify(prop), jsonPathStr)
result.MultiMatchSubQuery = r.multiMatch
}
@@ -598,22 +598,22 @@ func (r *runner) processActiveProps() (*search.ResolverResult, error) {
newTableAlias2 := r.multiMatchActiveTableAlias + "_" + cleanProp + r.resolver.joinAliasSuffix
if !isBackRelMultiple {
r.multiMatch.joins = append(
r.multiMatch.joins,
&join{
tableName: newCollectionName,
tableAlias: newTableAlias2,
on: dbx.NewExp(fmt.Sprintf("[[%s.%s]] = [[%s.id]]", newTableAlias2, cleanBackFieldName, r.multiMatchActiveTableAlias)),
r.multiMatch.Joins = append(
r.multiMatch.Joins,
&search.Join{
TableName: newCollectionName,
TableAlias: newTableAlias2,
On: dbx.NewExp(fmt.Sprintf("[[%s.%s]] = [[%s.id]]", newTableAlias2, cleanBackFieldName, r.multiMatchActiveTableAlias)),
},
)
} else {
jeAlias2 := "__je_" + newTableAlias2
r.multiMatch.joins = append(
r.multiMatch.joins,
&join{
tableName: newCollectionName,
tableAlias: newTableAlias2,
on: dbx.NewExp(fmt.Sprintf(
r.multiMatch.Joins = append(
r.multiMatch.Joins,
&search.Join{
TableName: newCollectionName,
TableAlias: newTableAlias2,
On: dbx.NewExp(fmt.Sprintf(
"[[%s.id]] IN (SELECT [[%s.value]] FROM %s {{%s}})",
r.multiMatchActiveTableAlias,
jeAlias2,
@@ -702,26 +702,26 @@ func (r *runner) processActiveProps() (*search.ResolverResult, error) {
prefixedFieldName2 := r.multiMatchActiveTableAlias + "." + cleanFieldName
if !relField.IsMultiple() {
r.multiMatch.joins = append(
r.multiMatch.joins,
&join{
tableName: inflector.Columnify(newCollectionName),
tableAlias: newTableAlias2,
on: dbx.NewExp(fmt.Sprintf("[[%s.id]] = [[%s]]", newTableAlias2, prefixedFieldName2)),
r.multiMatch.Joins = append(
r.multiMatch.Joins,
&search.Join{
TableName: inflector.Columnify(newCollectionName),
TableAlias: newTableAlias2,
On: dbx.NewExp(fmt.Sprintf("[[%s.id]] = [[%s]]", newTableAlias2, prefixedFieldName2)),
},
)
} else {
jeAlias2 := r.multiMatchActiveTableAlias + "_" + cleanFieldName + "_je"
r.multiMatch.joins = append(
r.multiMatch.joins,
&join{
tableName: dbutils.JSONEach(prefixedFieldName2),
tableAlias: jeAlias2,
r.multiMatch.Joins = append(
r.multiMatch.Joins,
&search.Join{
TableName: dbutils.JSONEach(prefixedFieldName2),
TableAlias: jeAlias2,
},
&join{
tableName: inflector.Columnify(newCollectionName),
tableAlias: newTableAlias2,
on: dbx.NewExp(fmt.Sprintf("[[%s.id]] = [[%s.value]]", newTableAlias2, jeAlias2)),
&search.Join{
TableName: inflector.Columnify(newCollectionName),
TableAlias: newTableAlias2,
On: dbx.NewExp(fmt.Sprintf("[[%s.id]] = [[%s.value]]", newTableAlias2, jeAlias2)),
},
)
}
@@ -766,7 +766,7 @@ func (r *runner) finalizeActivePropsProcessing(collection *Collection, prop stri
if r.withMultiMatch {
jePair2 := r.multiMatchActiveTableAlias + "." + cleanFieldName
r.multiMatch.valueIdentifier = dbutils.JSONArrayLength(jePair2)
r.multiMatch.ValueIdentifier = dbutils.JSONArrayLength(jePair2)
result.MultiMatchSubQuery = r.multiMatch
}
@@ -796,11 +796,11 @@ func (r *runner) finalizeActivePropsProcessing(collection *Collection, prop stri
jePair2 := r.multiMatchActiveTableAlias + "." + cleanFieldName
jeAlias2 := "__je_" + r.multiMatchActiveTableAlias + "_" + cleanFieldName + r.resolver.joinAliasSuffix
r.multiMatch.joins = append(r.multiMatch.joins, &join{
tableName: dbutils.JSONEach(jePair2),
tableAlias: jeAlias2,
r.multiMatch.Joins = append(r.multiMatch.Joins, &search.Join{
TableName: dbutils.JSONEach(jePair2),
TableAlias: jeAlias2,
})
r.multiMatch.valueIdentifier = fmt.Sprintf("[[%s.value]]", jeAlias2)
r.multiMatch.ValueIdentifier = fmt.Sprintf("[[%s.value]]", jeAlias2)
result.MultiMatchSubQuery = r.multiMatch
}
@@ -815,7 +815,7 @@ func (r *runner) finalizeActivePropsProcessing(collection *Collection, prop stri
}
if r.withMultiMatch {
r.multiMatch.valueIdentifier = "[[" + r.multiMatchActiveTableAlias + "." + cleanFieldName + "]]"
r.multiMatch.ValueIdentifier = "[[" + r.multiMatchActiveTableAlias + "." + cleanFieldName + "]]"
result.MultiMatchSubQuery = r.multiMatch
}
@@ -837,7 +837,7 @@ func (r *runner) finalizeActivePropsProcessing(collection *Collection, prop stri
result.NoCoalesce = true
result.Identifier = dbutils.JSONExtract(r.activeTableAlias+"."+cleanFieldName, "")
if r.withMultiMatch {
r.multiMatch.valueIdentifier = dbutils.JSONExtract(r.multiMatchActiveTableAlias+"."+cleanFieldName, "")
r.multiMatch.ValueIdentifier = dbutils.JSONExtract(r.multiMatchActiveTableAlias+"."+cleanFieldName, "")
}
}
@@ -845,7 +845,7 @@ func (r *runner) finalizeActivePropsProcessing(collection *Collection, prop stri
if modifier == lowerModifier {
result.Identifier = "LOWER(" + result.Identifier + ")"
if r.withMultiMatch {
r.multiMatch.valueIdentifier = "LOWER(" + r.multiMatch.valueIdentifier + ")"
r.multiMatch.ValueIdentifier = "LOWER(" + r.multiMatch.ValueIdentifier + ")"
}
}