Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
N
nexpie-grafana-theme
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Registry
Registry
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kornkitt Poolsup
nexpie-grafana-theme
Commits
f63877f2
Unverified
Commit
f63877f2
authored
Mar 26, 2020
by
Agnès Toulet
Committed by
GitHub
Mar 26, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Core: Add go-datemath library (#22978)
parent
85dc4e56
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
1160 additions
and
0 deletions
+1160
-0
go.mod
+1
-0
go.sum
+2
-0
pkg/extensions/main.go
+1
-0
vendor/github.com/timberio/go-datemath/.gitignore
+1
-0
vendor/github.com/timberio/go-datemath/CONTRIBUTING.md
+16
-0
vendor/github.com/timberio/go-datemath/LICENSE
+13
-0
vendor/github.com/timberio/go-datemath/README.md
+29
-0
vendor/github.com/timberio/go-datemath/datemath.go
+352
-0
vendor/github.com/timberio/go-datemath/datemath.l
+144
-0
vendor/github.com/timberio/go-datemath/datemath.l.go
+296
-0
vendor/github.com/timberio/go-datemath/datemath.y
+300
-0
vendor/github.com/timberio/go-datemath/datemath.y.go
+0
-0
vendor/github.com/timberio/go-datemath/go.mod
+3
-0
vendor/github.com/timberio/go-datemath/go.sum
+0
-0
vendor/modules.txt
+2
-0
No files found.
go.mod
View file @
f63877f2
...
...
@@ -60,6 +60,7 @@ require (
github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337
github.com/stretchr/testify v1.4.0
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf
github.com/timberio/go-datemath v0.1.1-0.20200323150745-74ddef604fff
github.com/ua-parser/uap-go v0.0.0-20190826212731-daf92ba38329
github.com/uber/jaeger-client-go v2.20.1+incompatible
github.com/uber/jaeger-lib v2.2.0+incompatible // indirect
...
...
go.sum
View file @
f63877f2
...
...
@@ -286,6 +286,8 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf h1:Z2X3Os7oRzpdJ75iPqWZc0HeJWFYNCvKsfpQwFpRNTA=
github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf/go.mod h1:M8agBzgqHIhgj7wEn9/0hJUZcrvt9VY+Ln+S1I5Mha0=
github.com/timberio/go-datemath v0.1.1-0.20200323150745-74ddef604fff h1:QCdUBuN+iKWAB9HqPTkBwyKPPUHDobJ2AuELSNZwd4o=
github.com/timberio/go-datemath v0.1.1-0.20200323150745-74ddef604fff/go.mod h1:m7kjsbCuO4QKP3KLfnxiUZWiOiFXmxj30HeexjL3lc0=
github.com/ua-parser/uap-go v0.0.0-20190826212731-daf92ba38329 h1:VBsKFh4W1JEMz3eLCmM9zOJKZdDkP5W4b3Y4hc7SbZc=
github.com/ua-parser/uap-go v0.0.0-20190826212731-daf92ba38329/go.mod h1:OBcG9bn7sHtXgarhUEb3OfCnNsgtGnkVf41ilSZ3K3E=
github.com/uber/jaeger-client-go v2.20.1+incompatible h1:HgqpYBng0n7tLJIlyT4kPCIv5XgCsF+kai1NnnrJzEU=
...
...
pkg/extensions/main.go
View file @
f63877f2
...
...
@@ -14,6 +14,7 @@ import (
_
"github.com/robfig/cron"
_
"github.com/robfig/cron/v3"
_
"github.com/stretchr/testify/require"
_
"github.com/timberio/go-datemath"
_
"gopkg.in/square/go-jose.v2"
)
...
...
vendor/github.com/timberio/go-datemath/.gitignore
0 → 100644
View file @
f63877f2
y.output
vendor/github.com/timberio/go-datemath/CONTRIBUTING.md
0 → 100644
View file @
f63877f2
# Contributing
Bug fixes and other contributions via pull request greatly welcomed!
This library relies on
[
goyacc
](
https://godoc.org/golang.org/x/tools/cmd/goyacc
)
and
[
golex
](
https://godoc.org/modernc.org/golex
)
for parsing and evaluating datemath grammar.
To install, run:
*
`go get golang.org/x/tools/cmd/goyacc modernc.org/golex`
After modifying either the
`datemath.l`
or
`datemath.y`
you can rerun
`go generate`
.
When in doubt on semantics of the library,
[
Elasticsearch's
implementation](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#date-math) should be
considered the canonical specification.
vendor/github.com/timberio/go-datemath/LICENSE
0 → 100644
View file @
f63877f2
Copyright (c) 2019, Timber Technologies, Inc.
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.
vendor/github.com/timberio/go-datemath/README.md
0 → 100644
View file @
f63877f2
# go-datemath
[
![GoDoc
](
https://godoc.org/github.com/timberio/go-datemath?status.svg
)
](http://godoc.org/github.com/timberio/go-datemath)
[
![Circle CI
](
https://circleci.com/gh/timberio/go-datemath.svg?style=svg
)
](https://circleci.com/gh/timberio/go-datemath)
[
![Go Report Card
](
https://goreportcard.com/badge/github.com/timberio/go-datemath
)
](https://goreportcard.com/report/github.com/timberio/go-datemath)
[
![coverage
](
https://gocover.io/_badge/github.com/timberio/go-datemath?0
"coverage"
)
](http://gocover.io/github.com/timberio/go-datemath)
This library provides support for parsing datemath expressions compatibly with
[
Elasticsearch datemath
expressions](https://www.elastic.co/guide/en/elasticsearch/reference/7.3/common-options.html#date-math). These are
useful for allowing users to specify, and for encoding, relative dates. Examples:
*
`now+15m`
: 15 minutes from now
*
`now-1w+1d`
: one day after on week ago
*
`2015-05-05T00:00:00||+1M`
: one month after 2019-05-05
These expressions will seem familiar if you have used Grafana or Kibana.
Example usage:
```
go
expr
,
_
:=
datemath
.
Parse
(
"now-15m"
)
fmt
.
Println
(
t
.
Time
(
datemath
.
WithNow
(
now
)))
```
See
[
package documentation
](
http://godoc.org/github.com/timberio/go-datemath
)
for usage and more examples.
## Development / Contributing
See
[
CONTRIBUTING.md
](
CONTRIBUTING.md
)
.
vendor/github.com/timberio/go-datemath/datemath.go
0 → 100644
View file @
f63877f2
// Requires golang.org/x/tools/cmd/goyacc and modernc.org/golex
//
//go:generate goyacc -o datemath.y.go datemath.y
//go:generate golex -o datemath.l.go datemath.l
/*
Package datemath provides an expression language for relative dates based on Elasticsearch's date math.
This package is useful for letting end-users describe dates in a simple format similar to Grafana and Kibana and for
persisting them as relative dates.
The expression starts with an anchor date, which can either be "now", or an ISO8601 date string ending with ||. This
anchor date can optionally be followed by one or more date math expressions, for example:
now+1h Add one hour
now-1d Subtract one day
now/d Round down to the nearest day
The supported time units are:
y Years
M Months
w Weeks
d Days
b Business Days (excludes Saturday and Sunday by default, use WithBusinessDayFunc to override)
h Hours
H Hours
m Minutes
s Seconds
Compatibility with Elasticsearch datemath
This package aims to be a superset of Elasticsearch's expressions. That is, any datemath expression that is valid for
Elasticsearch should evaluate in the same way here.
Currently the package does not support expressions outside of those also considered valid by Elasticsearch, but this may
change in the future to include additional functionality.
*/
package
datemath
import
(
"fmt"
"strconv"
"strings"
"time"
)
func
init
()
{
// have goyacc parser return more verbose syntax error messages
yyErrorVerbose
=
true
}
var
missingTimeZone
=
time
.
FixedZone
(
"MISSING"
,
0
)
type
timeUnit
rune
const
(
timeUnitYear
=
timeUnit
(
'y'
)
timeUnitMonth
=
timeUnit
(
'M'
)
timeUnitWeek
=
timeUnit
(
'w'
)
timeUnitDay
=
timeUnit
(
'd'
)
timeUnitBusinessDay
=
timeUnit
(
'b'
)
timeUnitHour
=
timeUnit
(
'h'
)
timeUnitMinute
=
timeUnit
(
'm'
)
timeUnitSecond
=
timeUnit
(
's'
)
)
func
(
u
timeUnit
)
String
()
string
{
return
string
(
u
)
}
// Expression represents a parsed datemath expression
type
Expression
struct
{
input
string
mathExpression
}
type
mathExpression
struct
{
anchorDateExpression
anchorDateExpression
adjustments
[]
timeAdjuster
}
func
newMathExpression
(
anchorDateExpression
anchorDateExpression
,
adjustments
[]
timeAdjuster
)
mathExpression
{
return
mathExpression
{
anchorDateExpression
:
anchorDateExpression
,
adjustments
:
adjustments
,
}
}
// MarshalJSON implements the json.Marshaler interface
//
// It serializes as the string expression the Expression was created with
func
(
e
Expression
)
MarshalJSON
()
([]
byte
,
error
)
{
return
[]
byte
(
strconv
.
Quote
(
e
.
String
())),
nil
}
// UnmarshalJSON implements the json.Unmarshaler interface
//
// Parses the datemath expression from a JSON string
func
(
e
*
Expression
)
UnmarshalJSON
(
data
[]
byte
)
error
{
s
,
err
:=
strconv
.
Unquote
(
string
(
data
))
if
err
!=
nil
{
return
err
}
expression
,
err
:=
Parse
(
s
)
if
err
!=
nil
{
return
nil
}
*
e
=
expression
return
nil
}
// String returns a the string used to create the expression
func
(
e
Expression
)
String
()
string
{
return
e
.
input
}
// Options represesent configurable behavior for interpreting the datemath expression
type
Options
struct
{
// Use this this time as "now"
// Default is `time.Now()`
Now
time
.
Time
// Use this location if there is no timezone in the expression
// Defaults to time.UTC
Location
*
time
.
Location
// Use this weekday as the start of the week
// Defaults to time.Monday
StartOfWeek
time
.
Weekday
// Rounding to period should be done to the end of the period
// Defaults to false
RoundUp
bool
BusinessDayFunc
func
(
time
.
Time
)
bool
}
// WithNow use the given time as "now"
func
WithNow
(
now
time
.
Time
)
func
(
*
Options
)
{
return
func
(
o
*
Options
)
{
o
.
Now
=
now
}
}
// WithStartOfWeek uses the given weekday as the start of the week
func
WithStartOfWeek
(
day
time
.
Weekday
)
func
(
*
Options
)
{
return
func
(
o
*
Options
)
{
o
.
StartOfWeek
=
day
}
}
// WithLocation uses the given location as the timezone of the date if unspecified
func
WithLocation
(
l
*
time
.
Location
)
func
(
*
Options
)
{
return
func
(
o
*
Options
)
{
o
.
Location
=
l
}
}
// WithRoundUp sets the rounding of time to the end of the period instead of the beginning
func
WithRoundUp
(
b
bool
)
func
(
*
Options
)
{
return
func
(
o
*
Options
)
{
o
.
RoundUp
=
b
}
}
// WithBusinessDayFunc use the given fn to check if a day is a business day
func
WithBusinessDayFunc
(
fn
func
(
time
.
Time
)
bool
)
func
(
*
Options
)
{
return
func
(
o
*
Options
)
{
o
.
BusinessDayFunc
=
fn
}
}
func
isNotWeekend
(
t
time
.
Time
)
bool
{
return
t
.
Weekday
()
!=
time
.
Saturday
&&
t
.
Weekday
()
!=
time
.
Sunday
}
// Time evaluate the expression with the given options to get the time it represents
func
(
e
Expression
)
Time
(
opts
...
func
(
*
Options
))
time
.
Time
{
options
:=
Options
{
Now
:
time
.
Now
(),
Location
:
time
.
UTC
,
StartOfWeek
:
time
.
Monday
,
}
for
_
,
opt
:=
range
opts
{
opt
(
&
options
)
}
t
:=
e
.
anchorDateExpression
(
options
)
for
_
,
adjustment
:=
range
e
.
adjustments
{
t
=
adjustment
(
t
,
options
)
}
return
t
}
// Parse parses the datemath expression which can later be evaluated
func
Parse
(
s
string
)
(
Expression
,
error
)
{
lex
:=
newLexer
([]
byte
(
s
))
lexWrapper
:=
newLexerWrapper
(
lex
)
yyParse
(
lexWrapper
)
if
len
(
lex
.
errors
)
>
0
{
return
Expression
{},
fmt
.
Errorf
(
strings
.
Join
(
lex
.
errors
,
"
\n
"
))
}
return
Expression
{
input
:
s
,
mathExpression
:
lexWrapper
.
expression
},
nil
}
// MustParse is the same as Parse() but panic's on error
func
MustParse
(
s
string
)
Expression
{
e
,
err
:=
Parse
(
s
)
if
err
!=
nil
{
panic
(
err
)
}
return
e
}
// ParseAndEvaluate is a convience wrapper to parse and return the time that the expression represents
func
ParseAndEvaluate
(
s
string
,
opts
...
func
(
*
Options
))
(
time
.
Time
,
error
)
{
expression
,
err
:=
Parse
(
s
)
if
err
!=
nil
{
return
time
.
Time
{},
err
}
return
expression
.
Time
(
opts
...
),
nil
}
type
anchorDateExpression
func
(
opts
Options
)
time
.
Time
func
anchorDateNow
(
opts
Options
)
time
.
Time
{
return
opts
.
Now
.
In
(
opts
.
Location
)
}
func
anchorDate
(
t
time
.
Time
)
func
(
opts
Options
)
time
.
Time
{
return
func
(
opts
Options
)
time
.
Time
{
location
:=
t
.
Location
()
if
location
==
missingTimeZone
{
location
=
opts
.
Location
}
return
time
.
Date
(
t
.
Year
(),
t
.
Month
(),
t
.
Day
(),
t
.
Hour
(),
t
.
Minute
(),
t
.
Second
(),
t
.
Nanosecond
(),
location
)
}
}
type
timeAdjuster
func
(
time
.
Time
,
Options
)
time
.
Time
func
addUnits
(
factor
int
,
u
timeUnit
)
func
(
time
.
Time
,
Options
)
time
.
Time
{
return
func
(
t
time
.
Time
,
options
Options
)
time
.
Time
{
switch
u
{
case
timeUnitYear
:
return
t
.
AddDate
(
factor
,
0
,
0
)
case
timeUnitMonth
:
return
t
.
AddDate
(
0
,
factor
,
0
)
case
timeUnitWeek
:
return
t
.
AddDate
(
0
,
0
,
7
*
factor
)
case
timeUnitDay
:
return
t
.
AddDate
(
0
,
0
,
factor
)
case
timeUnitBusinessDay
:
fn
:=
options
.
BusinessDayFunc
if
fn
==
nil
{
fn
=
isNotWeekend
}
increment
:=
1
if
factor
<
0
{
increment
=
-
1
}
for
i
:=
factor
;
i
!=
0
;
i
-=
increment
{
t
=
t
.
AddDate
(
0
,
0
,
increment
)
for
!
fn
(
t
)
{
t
=
t
.
AddDate
(
0
,
0
,
increment
)
}
}
return
t
case
timeUnitHour
:
return
t
.
Add
(
time
.
Duration
(
factor
)
*
time
.
Hour
)
case
timeUnitMinute
:
return
t
.
Add
(
time
.
Duration
(
factor
)
*
time
.
Minute
)
case
timeUnitSecond
:
return
t
.
Add
(
time
.
Duration
(
factor
)
*
time
.
Second
)
default
:
panic
(
fmt
.
Sprintf
(
"unknown time unit: %s"
,
u
))
}
}
}
func
truncateUnits
(
u
timeUnit
)
func
(
time
.
Time
,
Options
)
time
.
Time
{
var
roundDown
=
func
(
t
time
.
Time
,
options
Options
)
time
.
Time
{
switch
u
{
case
timeUnitYear
:
return
time
.
Date
(
t
.
Year
(),
1
,
1
,
0
,
0
,
0
,
0
,
t
.
Location
())
case
timeUnitMonth
:
return
time
.
Date
(
t
.
Year
(),
t
.
Month
(),
1
,
0
,
0
,
0
,
0
,
t
.
Location
())
case
timeUnitWeek
:
diff
:=
int
(
t
.
Weekday
()
-
options
.
StartOfWeek
)
if
diff
<
0
{
return
time
.
Date
(
t
.
Year
(),
t
.
Month
(),
t
.
Day
()
+
diff
-
1
,
0
,
0
,
0
,
0
,
t
.
Location
())
}
return
time
.
Date
(
t
.
Year
(),
t
.
Month
(),
t
.
Day
()
-
diff
,
0
,
0
,
0
,
0
,
t
.
Location
())
case
timeUnitDay
:
return
time
.
Date
(
t
.
Year
(),
t
.
Month
(),
t
.
Day
(),
0
,
0
,
0
,
0
,
t
.
Location
())
case
timeUnitHour
:
return
t
.
Truncate
(
time
.
Hour
)
case
timeUnitMinute
:
return
t
.
Truncate
(
time
.
Minute
)
case
timeUnitSecond
:
return
t
.
Truncate
(
time
.
Second
)
default
:
panic
(
fmt
.
Sprintf
(
"unknown time unit: %s"
,
u
))
}
}
return
func
(
t
time
.
Time
,
options
Options
)
time
.
Time
{
if
options
.
RoundUp
{
return
addUnits
(
1
,
u
)(
roundDown
(
t
,
options
),
options
)
.
Add
(
-
time
.
Millisecond
)
}
return
roundDown
(
t
,
options
)
}
}
func
daysIn
(
m
time
.
Month
,
year
int
)
int
{
return
time
.
Date
(
year
,
m
+
1
,
0
,
0
,
0
,
0
,
0
,
time
.
UTC
)
.
Day
()
}
// lexerWrapper wraps the golex generated wrapper to store the parsed expression for later and provide needed data to
// the parser
type
lexerWrapper
struct
{
lex
yyLexer
expression
mathExpression
}
func
newLexerWrapper
(
lex
yyLexer
)
*
lexerWrapper
{
return
&
lexerWrapper
{
lex
:
lex
,
}
}
func
(
l
*
lexerWrapper
)
Lex
(
lval
*
yySymType
)
int
{
return
l
.
lex
.
Lex
(
lval
)
}
func
(
l
*
lexerWrapper
)
Error
(
s
string
)
{
l
.
lex
.
Error
(
s
)
}
vendor/github.com/timberio/go-datemath/datemath.l
0 → 100644
View file @
f63877f2
/*
This
file
is
used
with
golex
to
generate
a
lexer
that
has
a
signature
compatible
with
goyacc
.
Many
constants
referred
to
below
are
defined
by
goyacc
when
creating
template
.
y
.
go
See
https
://
godoc
.
org
/
modernc
.
org
/
golex
for
more
about
golex
*/
%{
package
datemath
import
(
"bytes"
"fmt"
"strconv"
)
const
(
//
0
is
expected
by
the
goyacc
generated
parser
to
indicate
EOF
eofCode
=
0
)
//
lexer
holds
the
state
of
the
lexer
type
lexer
struct
{
src
*
bytes
.
Reader
buf
[]
byte
current
byte
pos
int
errors
[]
string
}
func
newLexer
(
b
[]
byte
)
*
lexer
{
l
:=
&
lexer
{
src
:
bytes
.
NewReader
(
b
),
}
//
queue
up
a
byte
l
.
next
()
return
l
}
func
(
l
*
lexer
)
Error
(
s
string
)
{
l
.
errors
=
append
(
l
.
errors
,
fmt
.
Sprintf
(
"%s at character %d starting with %q"
,
s
,
l
.
pos
,
string
(
l
.
buf
)))
}
func
(
l
*
lexer
)
next
()
{
if
l
.
current
!= 0 {
l
.
buf
=
append
(
l
.
buf
,
l
.
current
)
}
l
.
current
=
0
if
b
,
err
:=
l
.
src
.
ReadByte
();
err
==
nil
{
l
.
current
=
b
}
l
.
pos
++
}
func
(
l
*
lexer
)
Lex
(
lval
*
yySymType
)
int
{
%}
/*
give
some
regular
expressions
more
semantic
names
for
use
below
*/
eof
\
0
/*
tell
golex
how
to
determine
the
current
start
condition
*/
%
yyt
l
.
startCondition
/*
tell
golex
how
to
determine
the
current
byte
*/
%
yyc
l
.
current
/*
tell
golex
how
to
advance
to
the
next
byte
*/
%
yyn
l
.
next
()
%%
//
runs
before
each
token
is
parsed
l
.
buf
=
l
.
buf
[:
0
]
[
0
-
9
]
i
,
err
:=
strconv
.
ParseInt
(
string
(
l
.
buf
),
10
,
0
)
if
err
!= nil {
panic
(
fmt
.
Sprintf
(
"could not parse digit as number: %s"
,
err
))
}
lval
.
i
=
int
(
i
)
return
tDIGIT
"now"
return
tNOW
"+"
return
tPLUS
"-"
return
tMINUS
":"
return
tCOLON
"||"
return
tPIPES
"/"
return
tBACKSLASH
[
yMwdbhHms
]
switch
l
.
buf
[
0
]
{
case
'y'
:
lval
.
unit
=
timeUnitYear
case
'M'
:
lval
.
unit
=
timeUnitMonth
case
'w'
:
lval
.
unit
=
timeUnitWeek
case
'b'
:
lval
.
unit
=
timeUnitBusinessDay
case
'd'
:
lval
.
unit
=
timeUnitDay
case
'h'
,
'H'
:
lval
.
unit
=
timeUnitHour
case
'm'
:
lval
.
unit
=
timeUnitMinute
case
's'
:
lval
.
unit
=
timeUnitSecond
default
:
panic
(
fmt
.
Sprintf
(
"unknown time unit: %q"
,
l
.
buf
[
0
]))
}
return
tUNIT
\.
return
tDOT
"T"
return
tTIME_DELIMITER
"Z"
return
tUTC
{
eof
}
return
eofCode
.
return
tINVALID_TOKEN
%%
//
should
never
get
here
panic
(
"scanner internal error"
)
}
vendor/github.com/timberio/go-datemath/datemath.l.go
0 → 100644
View file @
f63877f2
// Code generated by golex. DO NOT EDIT.
/*
This file is used with golex to generate a lexer that has a signature compatible with goyacc.
Many constants referred to below are defined by goyacc when creating template.y.go
See https://godoc.org/modernc.org/golex for more about golex
*/
package
datemath
import
(
"bytes"
"fmt"
"strconv"
)
const
(
// 0 is expected by the goyacc generated parser to indicate EOF
eofCode
=
0
)
// lexer holds the state of the lexer
type
lexer
struct
{
src
*
bytes
.
Reader
buf
[]
byte
current
byte
pos
int
errors
[]
string
}
func
newLexer
(
b
[]
byte
)
*
lexer
{
l
:=
&
lexer
{
src
:
bytes
.
NewReader
(
b
),
}
// queue up a byte
l
.
next
()
return
l
}
func
(
l
*
lexer
)
Error
(
s
string
)
{
l
.
errors
=
append
(
l
.
errors
,
fmt
.
Sprintf
(
"%s at character %d starting with %q"
,
s
,
l
.
pos
,
string
(
l
.
buf
)))
}
func
(
l
*
lexer
)
next
()
{
if
l
.
current
!=
0
{
l
.
buf
=
append
(
l
.
buf
,
l
.
current
)
}
l
.
current
=
0
if
b
,
err
:=
l
.
src
.
ReadByte
();
err
==
nil
{
l
.
current
=
b
}
l
.
pos
++
}
func
(
l
*
lexer
)
Lex
(
lval
*
yySymType
)
int
{
/* give some regular expressions more semantic names for use below */
/* tell golex how to determine the current start condition */
/* tell golex how to determine the current byte */
/* tell golex how to advance to the next byte */
yystate0
:
// runs before each token is parsed
l
.
buf
=
l
.
buf
[
:
0
]
goto
yystart1
yystate1
:
l
.
next
()
yystart1
:
switch
{
default
:
goto
yyabort
case
l
.
current
==
'+'
:
goto
yystate4
case
l
.
current
==
'-'
:
goto
yystate5
case
l
.
current
==
'.'
:
goto
yystate6
case
l
.
current
==
'/'
:
goto
yystate7
case
l
.
current
==
':'
:
goto
yystate9
case
l
.
current
==
'H'
||
l
.
current
==
'M'
||
l
.
current
==
'b'
||
l
.
current
==
'd'
||
l
.
current
==
'h'
||
l
.
current
==
'm'
||
l
.
current
==
's'
||
l
.
current
==
'w'
||
l
.
current
==
'y'
:
goto
yystate10
case
l
.
current
==
'T'
:
goto
yystate11
case
l
.
current
==
'Z'
:
goto
yystate12
case
l
.
current
==
'\x00'
:
goto
yystate2
case
l
.
current
==
'n'
:
goto
yystate13
case
l
.
current
==
'|'
:
goto
yystate16
case
l
.
current
>=
'0'
&&
l
.
current
<=
'9'
:
goto
yystate8
case
l
.
current
>=
'\x01'
&&
l
.
current
<=
'\t'
||
l
.
current
>=
'\v'
&&
l
.
current
<=
'*'
||
l
.
current
==
','
||
l
.
current
>=
';'
&&
l
.
current
<=
'G'
||
l
.
current
>=
'I'
&&
l
.
current
<=
'L'
||
l
.
current
>=
'N'
&&
l
.
current
<=
'S'
||
l
.
current
>=
'U'
&&
l
.
current
<=
'Y'
||
l
.
current
>=
'['
&&
l
.
current
<=
'a'
||
l
.
current
==
'c'
||
l
.
current
>=
'e'
&&
l
.
current
<=
'g'
||
l
.
current
>=
'i'
&&
l
.
current
<=
'l'
||
l
.
current
>=
'o'
&&
l
.
current
<=
'r'
||
l
.
current
>=
't'
&&
l
.
current
<=
'v'
||
l
.
current
==
'x'
||
l
.
current
==
'z'
||
l
.
current
==
'{'
||
l
.
current
>=
'}'
&&
l
.
current
<=
'ÿ'
:
goto
yystate3
}
yystate2
:
l
.
next
()
goto
yyrule12
yystate3
:
l
.
next
()
goto
yyrule13
yystate4
:
l
.
next
()
goto
yyrule3
yystate5
:
l
.
next
()
goto
yyrule4
yystate6
:
l
.
next
()
goto
yyrule9
yystate7
:
l
.
next
()
goto
yyrule7
yystate8
:
l
.
next
()
goto
yyrule1
yystate9
:
l
.
next
()
goto
yyrule5
yystate10
:
l
.
next
()
goto
yyrule8
yystate11
:
l
.
next
()
goto
yyrule10
yystate12
:
l
.
next
()
goto
yyrule11
yystate13
:
l
.
next
()
switch
{
default
:
goto
yyrule13
case
l
.
current
==
'o'
:
goto
yystate14
}
yystate14
:
l
.
next
()
switch
{
default
:
goto
yyabort
case
l
.
current
==
'w'
:
goto
yystate15
}
yystate15
:
l
.
next
()
goto
yyrule2
yystate16
:
l
.
next
()
switch
{
default
:
goto
yyrule13
case
l
.
current
==
'|'
:
goto
yystate17
}
yystate17
:
l
.
next
()
goto
yyrule6
yyrule1
:
// [0-9]
{
i
,
err
:=
strconv
.
ParseInt
(
string
(
l
.
buf
),
10
,
0
)
if
err
!=
nil
{
panic
(
fmt
.
Sprintf
(
"could not parse digit as number: %s"
,
err
))
}
lval
.
i
=
int
(
i
)
return
tDIGIT
}
yyrule2
:
// "now"
{
return
tNOW
}
yyrule3
:
// "+"
{
return
tPLUS
}
yyrule4
:
// "-"
{
return
tMINUS
}
yyrule5
:
// ":"
{
return
tCOLON
}
yyrule6
:
// "||"
{
return
tPIPES
}
yyrule7
:
// "/"
{
return
tBACKSLASH
}
yyrule8
:
// [yMwdbhHms]
{
switch
l
.
buf
[
0
]
{
case
'y'
:
lval
.
unit
=
timeUnitYear
case
'M'
:
lval
.
unit
=
timeUnitMonth
case
'w'
:
lval
.
unit
=
timeUnitWeek
case
'b'
:
lval
.
unit
=
timeUnitBusinessDay
case
'd'
:
lval
.
unit
=
timeUnitDay
case
'h'
,
'H'
:
lval
.
unit
=
timeUnitHour
case
'm'
:
lval
.
unit
=
timeUnitMinute
case
's'
:
lval
.
unit
=
timeUnitSecond
default
:
panic
(
fmt
.
Sprintf
(
"unknown time unit: %q"
,
l
.
buf
[
0
]))
}
return
tUNIT
}
yyrule9
:
// \.
{
return
tDOT
}
yyrule10
:
// "T"
{
return
tTIME_DELIMITER
}
yyrule11
:
// "Z"
{
return
tUTC
}
yyrule12
:
// {eof}
{
return
eofCode
}
yyrule13
:
// .
if
true
{
// avoid go vet determining the below panic will not be reached
return
tINVALID_TOKEN
}
panic
(
"unreachable"
)
yyabort
:
// no lexem recognized
//
// silence unused label errors for build and satisfy go vet reachability analysis
//
{
if
false
{
goto
yyabort
}
if
false
{
goto
yystate0
}
if
false
{
goto
yystate1
}
}
// should never get here
panic
(
"scanner internal error"
)
}
vendor/github.com/timberio/go-datemath/datemath.y
0 → 100644
View file @
f63877f2
/*
This
file
is
used
with
goyacc
to
generate
a
parser
.
See
https
://
godoc
.
org
/
golang
.
org
/
x
/
tools
/
cmd
/
goyacc
for
more
about
goyacc
.
*/
%{
package
datemath
import
(
"fmt"
"math"
"time"
)
var
epoch
=
time
.
Unix
(
0
,
0
).
In
(
time
.
UTC
)
//
convert
a
list
of
significant
digits
to
an
integer
//
assumes
most
to
least
significant
//
e
.
g
.
5
,
2
,
3
->
523
func
digitsToInt
(
digits
...
int
)
int
{
n
:=
0
for
i
:=
range
digits
{
n
+=
digits
[
i
]
*
int
(
math
.
Pow10
(
len
(
digits
)-
i
-
1
))
}
return
n
}
%}
/*
set
of
valid
tokens
;
generated
constants
used
by
lexer
*/
%
token
tNOW
tPLUS
tMINUS
tPIPES
tBACKSLASH
tTIME_DELIMITER
tCOLON
tDOT
tUNIT
tUTC
tDIGIT
tINVALID_TOKEN
/*
Go
variables
to
hold
the
corresponding
token
values
*/
%
union
{
i64
int64
i
int
unit
timeUnit
month
time
.
Month
expression
mathExpression
anchorDateExpression
anchorDateExpression
timeAdjuster
timeAdjuster
timeAdjusters
[]
timeAdjuster
location
*
time
.
Location
time
time
.
Time
}
/*
associate
tokens
with
Go
types
*/
%
type
<
unit
>
tUNIT
%
type
<
i
>
sign
factor
number
year
day
hour
minute
second
nanoseconds
tDIGIT
%
type
<
month
>
month
%
type
<
expression
>
expression
%
type
<
time
>
date
time
absolute_date_expression
%
type
<
i64
>
millitimestamp
%
type
<
timeAdjusters
>
date_math_expressions
%
type
<
timeAdjuster
>
date_math_expression
%
type
<
location
>
timezone
%
error
start
tINVALID_TOKEN
:
"invalid token"
%%
start
:
expression
{
//
last
rule
;
assign
the
evaluated
time
so
we
can
use
use
it
later
yylex
.(*
lexerWrapper
).
expression
=
$
1
}
/*
*
an
expression
can
be
either
a
:
*
*
A
ISO8601
timestamp
(
can
be
truncated
)
*
*
the
string
"now"
*
*
followed
by
list
of
date
math
expressions
*/
expression
:
absolute_date_expression
{
$$
=
newMathExpression
(
anchorDate
($
1
),
nil
)
}
|
absolute_date_expression
tPIPES
{
$$
=
newMathExpression
(
anchorDate
($
1
),
nil
)
}
|
absolute_date_expression
tPIPES
date_math_expressions
{
$$
=
newMathExpression
(
anchorDate
($
1
),
$
3
)
}
|
tNOW
{
$$
=
newMathExpression
(
anchorDateNow
,
nil
)
}
|
tNOW
date_math_expressions
{
$$
=
newMathExpression
(
anchorDateNow
,
$
2
)
}
;
/*
*
An
absolute
date
expression
can
be
:
*
*
a
unix
timestamp
in
milliseconds
*
*
a
date
*
*
a
time
*
*
a
datetime
*
Dates
and
times
can
be
truncated
by
leaving
off
smaller
units
.
For
example
,
2006
would
map
to
2006
-
01
-
01
T00
:
00
:
00
*/
absolute_date_expression
:
date
{
$$
=
$
1
}
|
time
{
$$
=
$
1
}
|
date
tTIME_DELIMITER
time
timezone
{
$$
=
time
.
Date
($
1.
Year
(),
$
1.
Month
(),
$
1.
Day
(),
$
3.
Hour
(),
$
3.
Minute
(),
$
3.
Second
(),
$
3.
Nanosecond
(),
$
4
)
}
|
millitimestamp
{
$$
=
time
.
Unix
($
1
/
1000
,
$
1
%
1000
*
1000000
)
}
;
timezone
:
/*
empty
*/
{
$$
=
missingTimeZone
}
|
sign
tDIGIT
tDIGIT
tCOLON
tDIGIT
tDIGIT
{
/*
support
+/-
09
:
00
style
timezone
specifiers
*/
$$
=
time
.
FixedZone
(
"$1$2$3:$5$6"
,
$
1
*
((($
2
*
10
+
$
3
)
*
60
*
60
)
+
(($
5
*
10
+
$
6
)
*
60
)))
}
|
tUTC
{
/*
Z
*/
$$
=
time
.
UTC
}
;
date
:
year
{
$$
=
time
.
Date
($
1
,
1
,
1
,
0
,
0
,
0
,
0
,
missingTimeZone
)
}
|
year
tMINUS
month
{
$$
=
time
.
Date
($
1
,
$
3
,
1
,
0
,
0
,
0
,
0
,
missingTimeZone
)
}
|
year
tMINUS
month
tMINUS
day
{
if
$
5
>
daysIn
($
3
,
$
1
)
{
yylex
.
Error
(
fmt
.
Sprintf
(
"day %d out of bounds for month %d"
,
$
5
,
$
3
))
}
$$
=
time
.
Date
($
1
,
$
3
,
$
5
,
0
,
0
,
0
,
0
,
missingTimeZone
)
}
;
/*
store
in
a
time
.
Time
struct
using
the
epoch
for
the
year
/
month
/
day
*/
time
:
hour
{
$$
=
time
.
Date
(
epoch
.
Year
(),
epoch
.
Month
(),
epoch
.
Day
(),
$
1
,
0
,
0
,
0
,
missingTimeZone
)
}
|
hour
tCOLON
minute
{
$$
=
time
.
Date
(
epoch
.
Year
(),
epoch
.
Month
(),
epoch
.
Day
(),
$
1
,
$
3
,
0
,
0
,
missingTimeZone
)
}
|
hour
tCOLON
minute
tCOLON
second
{
$$
=
time
.
Date
(
epoch
.
Year
(),
epoch
.
Month
(),
epoch
.
Day
(),
$
1
,
$
3
,
$
5
,
0
,
missingTimeZone
)
}
|
hour
tCOLON
minute
tCOLON
second
tDOT
nanoseconds
{
$$
=
time
.
Date
(
epoch
.
Year
(),
epoch
.
Month
(),
epoch
.
Day
(),
$
1
,
$
3
,
$
5
,
$
7
,
missingTimeZone
)
}
;
year
:
tDIGIT
tDIGIT
tDIGIT
tDIGIT
{
$$
=
digitsToInt
($
1
,
$
2
,
$
3
,
$
4
)
}
;
month
:
tDIGIT
tDIGIT
{
$$
=
time
.
Month
(
digitsToInt
($
1
,
$
2
))
if
$$
>
12
{
yylex
.
Error
(
fmt
.
Sprintf
(
"month out of bounds %d"
,
$$))
}
}
;
day
:
tDIGIT
tDIGIT
{
//
range
validated
in
`
date
`
$$
=
digitsToInt
($
1
,
$
2
)
}
;
hour
:
tDIGIT
tDIGIT
{
$$
=
digitsToInt
($
1
,
$
2
)
if
$$
>
23
{
yylex
.
Error
(
fmt
.
Sprintf
(
"hours out of bounds %d"
,
$$))
}
}
;
minute
:
tDIGIT
tDIGIT
{
$$
=
digitsToInt
($
1
,
$
2
)
if
$$
>
59
{
yylex
.
Error
(
fmt
.
Sprintf
(
"minutes out of bounds %d"
,
$$))
}
}
;
second
:
tDIGIT
tDIGIT
{
$$
=
digitsToInt
($
1
,
$
2
)
if
$$
>
59
{
yylex
.
Error
(
fmt
.
Sprintf
(
"seconds out of bounds %d"
,
$$))
}
}
;
/*
only
supports
3
digits
for
fractional
seconds
for
now
*/
nanoseconds
:
tDIGIT
{
$$
=
$
1
*
100000000
}
|
tDIGIT
tDIGIT
{
$$
=
digitsToInt
($
1
,
$
2
)
*
10000000
}
|
tDIGIT
tDIGIT
tDIGIT
{
$$
=
digitsToInt
($
1
,
$
2
,
$
3
)
*
1000000
}
;
/*
allow
for
list
of
time
adjustments
;
evaluated
from
left
to
right
*/
date_math_expressions
:
date_math_expression
date_math_expressions
{
$$
=
append
([]
timeAdjuster
{$
1
},
$
2.
..)
/*
f
,
g
:=
$
1
,
$
2
//
bind
to
local
scope
*/
/*$$
=
func
(
t
time
.
Time
)
time
.
Time
{*/
/*
return
g
(
f
(
t
))*/
/*}*/
}
|
date_math_expression
{
$$
=
[]
timeAdjuster
{$
1
}
}
;
date_math_expression
:
sign
factor
tUNIT
{
/*
add
units
;
e
.
g
.
+
15
m
*/
$$
=
addUnits
($
1
*
$
2
,
$
3
)
}
|
tBACKSLASH
tUNIT
{
/*
truncate
to
specified
unit
:
e
.
g
.
/
d
*/
$$
=
truncateUnits
($
2
)
}
;
sign
:
tMINUS
{
$$
=
-
1
}
|
tPLUS
{
$$
=
1
}
;
factor
:
/*
empty
*/
{
/*
default
to
1
if
no
integer
specified
*/
$$
=
1
}
|
number
{
$$
=
$
1
}
;
number
:
tDIGIT
{
$$
=
$
1
}
|
number
tDIGIT
{
$$
=
$
1
*
10
+
$
2
}
;
/*
5
digits
or
longer
is
considered
a
timestamp
*/
millitimestamp
:
tDIGIT
tDIGIT
tDIGIT
tDIGIT
tDIGIT
{
$$
=
int64
(
digitsToInt
($
1
,
$
2
,
$
3
,
$
4
,
$
5
))
}
|
millitimestamp
tDIGIT
{
$$
=
$
1
*
10
+
int64
($
2
)
}
;
%%
vendor/github.com/timberio/go-datemath/datemath.y.go
0 → 100644
View file @
f63877f2
This diff is collapsed.
Click to expand it.
vendor/github.com/timberio/go-datemath/go.mod
0 → 100644
View file @
f63877f2
module github.com/timberio/go-datemath
go 1.13
vendor/github.com/timberio/go-datemath/go.sum
0 → 100644
View file @
f63877f2
vendor/modules.txt
View file @
f63877f2
...
...
@@ -262,6 +262,8 @@ github.com/stretchr/testify/assert
github.com/stretchr/testify/require
# github.com/teris-io/shortid v0.0.0-20171029131806-771a37caa5cf
github.com/teris-io/shortid
# github.com/timberio/go-datemath v0.1.1-0.20200323150745-74ddef604fff
github.com/timberio/go-datemath
# github.com/ua-parser/uap-go v0.0.0-20190826212731-daf92ba38329
github.com/ua-parser/uap-go/uaparser
# github.com/uber/jaeger-client-go v2.20.1+incompatible
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment