Fix SQLite date formatting
* Add missing mappings, * add validation for supported substitutions.
This commit is contained in:
parent
0534096ad2
commit
c64a98e36c
@ -2,6 +2,7 @@ package sqlite3
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/cortezaproject/corteza-server/pkg/ql"
|
||||
@ -103,6 +104,19 @@ var (
|
||||
return
|
||||
},
|
||||
}
|
||||
|
||||
supportedSubstitutions = map[string]bool{
|
||||
"d": true,
|
||||
"H": true,
|
||||
"j": true,
|
||||
"m": true,
|
||||
"M": true,
|
||||
"S": true,
|
||||
"w": true,
|
||||
"W": true,
|
||||
"Y": true,
|
||||
"%": true,
|
||||
}
|
||||
)
|
||||
|
||||
func sqlASTFormatter(n *qlng.ASTNode) rdbms.HandlerSig {
|
||||
@ -123,7 +137,15 @@ func sqlFunctionHandler(f ql.Function) (ql.ASTNode, error) {
|
||||
if len(f.Arguments) != 2 {
|
||||
return nil, fmt.Errorf("expecting exactly two arguments for DATE_FORMAT function")
|
||||
}
|
||||
return ql.MakeFormattedNode("STRFTIME('%s', %s)", f.Arguments[0], f.Arguments[1]), nil
|
||||
format := f.Arguments[1]
|
||||
col := f.Arguments[0]
|
||||
|
||||
err := supportedDateFormatParams(format)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ql.MakeReplacedFormattedNode("STRFTIME(%s, %s)", translateDateFormatParams, format, col), nil
|
||||
case "DATE":
|
||||
// need to convert back to datetime so it can be converted to time.Time
|
||||
return ql.MakeFormattedNode("STRFTIME('%%Y-%%m-%%dT00:00:00Z', %s)", f.Arguments...), nil
|
||||
@ -133,3 +155,28 @@ func sqlFunctionHandler(f ql.Function) (ql.ASTNode, error) {
|
||||
|
||||
return f, nil
|
||||
}
|
||||
|
||||
func supportedDateFormatParams(fmtNode ql.ASTNode) error {
|
||||
format := translateDateFormatParams(fmtNode.String())
|
||||
|
||||
r := regexp.MustCompile(`%(?P<sub>.)`)
|
||||
|
||||
for _, m := range r.FindAllStringSubmatch(format, -1) {
|
||||
if len(m) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if _, ok := supportedSubstitutions[m[1]]; !ok {
|
||||
return fmt.Errorf("format substitution not supported: %%%s", m[1])
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func translateDateFormatParams(format string) string {
|
||||
return strings.NewReplacer(
|
||||
`%i`, `%M`,
|
||||
`%U`, `%W`,
|
||||
).Replace(format)
|
||||
}
|
||||
|
||||
@ -1606,7 +1606,7 @@ func testComposeRecords(t *testing.T, s store.ComposeRecords) {
|
||||
req.NoError(err)
|
||||
req.Len(report, 3)
|
||||
|
||||
report, err = s.ComposeRecordReport(ctx, mod, "MAX(num1)", "DATE_FORMAT(dt1, '%y; %j @ %H %i %p')", "")
|
||||
report, err = s.ComposeRecordReport(ctx, mod, "MAX(num1)", "DATE_FORMAT(dt1, '%Y; %j @ %H %i')", "")
|
||||
req.NoError(err)
|
||||
req.Len(report, 3)
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user