-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
expose field object publicly #52
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -17,6 +17,7 @@ import ( | |||||||||||||||||||||||||||||
//go:generate easyjson -omit_empty -disallow_unknown_fields -snake_case rql.go | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Query is the decoded result of the user input. | ||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||
//easyjson:json | ||||||||||||||||||||||||||||||
type Query struct { | ||||||||||||||||||||||||||||||
// Limit must be > 0 and <= to `LimitMaxValue`. | ||||||||||||||||||||||||||||||
|
@@ -73,7 +74,6 @@ type Query struct { | |||||||||||||||||||||||||||||
// return nil, err | ||||||||||||||||||||||||||||||
// } | ||||||||||||||||||||||||||||||
// return users, nil | ||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||
type Params struct { | ||||||||||||||||||||||||||||||
// Limit represents the number of rows returned by the SELECT statement. | ||||||||||||||||||||||||||||||
Limit int | ||||||||||||||||||||||||||||||
|
@@ -105,7 +105,7 @@ func (p ParseError) Error() string { | |||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// field is a configuration of a struct field. | ||||||||||||||||||||||||||||||
type field struct { | ||||||||||||||||||||||||||||||
type FieldMeta struct { | ||||||||||||||||||||||||||||||
// Name of the column. | ||||||||||||||||||||||||||||||
Name string | ||||||||||||||||||||||||||||||
// Has a "sort" option in the tag. | ||||||||||||||||||||||||||||||
|
@@ -114,6 +114,9 @@ type field struct { | |||||||||||||||||||||||||||||
Filterable bool | ||||||||||||||||||||||||||||||
// All supported operators for this field. | ||||||||||||||||||||||||||||||
FilterOps map[string]bool | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
type Field struct { | ||||||||||||||||||||||||||||||
*FieldMeta | ||||||||||||||||||||||||||||||
// Validation for the type. for example, unit8 greater than or equal to 0. | ||||||||||||||||||||||||||||||
ValidateFn func(interface{}) error | ||||||||||||||||||||||||||||||
// ConvertFn converts the given value to the type value. | ||||||||||||||||||||||||||||||
|
@@ -124,7 +127,7 @@ type field struct { | |||||||||||||||||||||||||||||
// It is safe for concurrent use by multiple goroutines except for configuration changes. | ||||||||||||||||||||||||||||||
type Parser struct { | ||||||||||||||||||||||||||||||
Config | ||||||||||||||||||||||||||||||
fields map[string]*field | ||||||||||||||||||||||||||||||
fields map[string]*Field | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// NewParser creates a new Parser. it fails if the configuration is invalid. | ||||||||||||||||||||||||||||||
|
@@ -134,14 +137,31 @@ func NewParser(c Config) (*Parser, error) { | |||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
p := &Parser{ | ||||||||||||||||||||||||||||||
Config: c, | ||||||||||||||||||||||||||||||
fields: make(map[string]*field), | ||||||||||||||||||||||||||||||
fields: make(map[string]*Field), | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
if err := p.init(); err != nil { | ||||||||||||||||||||||||||||||
return nil, err | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
return p, nil | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Does not use config.Model, gets config from Fields) | ||||||||||||||||||||||||||||||
func NewParserF(c Config, fields []*Field) (*Parser, error) { | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename to: NewFieldsParser or add a new option as Also, an error should return if |
||||||||||||||||||||||||||||||
if err := c.defaults(); err != nil { | ||||||||||||||||||||||||||||||
return nil, err | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
m := make(map[string]*Field, len(fields)) | ||||||||||||||||||||||||||||||
for _, v := range fields { | ||||||||||||||||||||||||||||||
m[v.Name] = v | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
p := &Parser{ | ||||||||||||||||||||||||||||||
Config: c, | ||||||||||||||||||||||||||||||
fields: m, | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
return p, nil | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// MustNewParser is like NewParser but panics if the configuration is invalid. | ||||||||||||||||||||||||||||||
// It simplifies safe initialization of global variables holding a resource parser. | ||||||||||||||||||||||||||||||
func MustNewParser(c Config) *Parser { | ||||||||||||||||||||||||||||||
|
@@ -197,13 +217,20 @@ func (p *Parser) ParseQuery(q *Query) (pr *Params, err error) { | |||||||||||||||||||||||||||||
return | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
func (p *Parser) GetFields() []*Field { | ||||||||||||||||||||||||||||||
fields := make([]*Field, 0, len(p.fields)) | ||||||||||||||||||||||||||||||
for _, v := range p.fields { | ||||||||||||||||||||||||||||||
fields = append(fields, v) | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
return fields | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
Comment on lines
+220
to
+226
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Why this method is needed? If it's for testing, let's use the existing public API instead. |
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
// Column is the default function that converts field name into a database column. | ||||||||||||||||||||||||||||||
// It used to convert the struct fields into their database names. For example: | ||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||
// Username => username | ||||||||||||||||||||||||||||||
// FullName => full_name | ||||||||||||||||||||||||||||||
// HTTPCode => http_code | ||||||||||||||||||||||||||||||
// | ||||||||||||||||||||||||||||||
func Column(s string) string { | ||||||||||||||||||||||||||||||
var b strings.Builder | ||||||||||||||||||||||||||||||
for i := 0; i < len(s); i++ { | ||||||||||||||||||||||||||||||
|
@@ -257,10 +284,12 @@ func (p *Parser) init() error { | |||||||||||||||||||||||||||||
// parseField parses the given struct field tag, and add a rule | ||||||||||||||||||||||||||||||
// in the parser according to its type and the options that were set on the tag. | ||||||||||||||||||||||||||||||
func (p *Parser) parseField(sf reflect.StructField) error { | ||||||||||||||||||||||||||||||
f := &field{ | ||||||||||||||||||||||||||||||
Name: p.ColumnFn(sf.Name), | ||||||||||||||||||||||||||||||
CovertFn: valueFn, | ||||||||||||||||||||||||||||||
FilterOps: make(map[string]bool), | ||||||||||||||||||||||||||||||
f := &Field{ | ||||||||||||||||||||||||||||||
FieldMeta: &FieldMeta{ | ||||||||||||||||||||||||||||||
Name: p.ColumnFn(sf.Name), | ||||||||||||||||||||||||||||||
FilterOps: make(map[string]bool), | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
CovertFn: valueFn, | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
layout := time.RFC3339 | ||||||||||||||||||||||||||||||
opts := strings.Split(sf.Tag.Get(p.TagName), ",") | ||||||||||||||||||||||||||||||
|
@@ -438,7 +467,7 @@ func (p *parseState) relOp(op Op, terms []interface{}) { | |||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
func (p *parseState) field(f *field, v interface{}) { | ||||||||||||||||||||||||||||||
func (p *parseState) field(f *Field, v interface{}) { | ||||||||||||||||||||||||||||||
terms, ok := v.(map[string]interface{}) | ||||||||||||||||||||||||||||||
// default equality check. | ||||||||||||||||||||||||||||||
if !ok { | ||||||||||||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not inline its fields inside the
Field
type?