@@ -119,6 +119,8 @@ type Field struct {
119119type FieldMeta struct {
120120 // Name of the column.
121121 Name string
122+ // name of the column.
123+ Column string
122124 // Has a "sort" option in the tag.
123125 Sortable bool
124126 // Has a "filter" option in the tag.
@@ -215,6 +217,7 @@ func (p *Parser) ParseQuery(q *Query) (pr *Params, err error) {
215217// FullName => full_name
216218// HTTPCode => http_code
217219func Column (s string ) string {
220+ s = strings .Replace (s , "." , "_" , - 1 )
218221 var b strings.Builder
219222 for i := 0 ; i < len (s ); i ++ {
220223 r := rune (s [i ])
@@ -339,6 +342,29 @@ func GetValidateFn(f *FieldMeta) Validator {
339342 }
340343}
341344
345+ func NameFn (str string , sep string ) string {
346+ var buf bytes.Buffer
347+
348+ for i , r := range str {
349+ if r == '.' {
350+ buf .WriteRune (r )
351+ continue
352+ }
353+
354+ if unicode .IsUpper (r ) {
355+ if i > 0 && str [i - 1 ] != '_' && str [i - 1 ] != '.' && ! unicode .IsUpper (rune (str [i - 1 ])) {
356+ buf .WriteRune ('_' )
357+ } else if i > 0 && unicode .IsUpper (rune (str [i - 1 ])) && i + 1 < len (str ) && unicode .IsUpper (r ) && unicode .IsLower (rune (str [i + 1 ])) {
358+ buf .WriteRune ('_' )
359+ }
360+ }
361+
362+ buf .WriteRune (unicode .ToLower (r ))
363+ }
364+
365+ return buf .String ()
366+ }
367+
342368// init initializes the parser parsing state. it scans the fields
343369// in a breath-first-search order and for each one of the field calls parseField.
344370func (p * Parser ) init () error {
@@ -378,7 +404,8 @@ func (p *Parser) init() error {
378404func (p * Parser ) parseField (sf reflect.StructField ) error {
379405 f := & Field {
380406 FieldMeta : & FieldMeta {
381- Name : p .ColumnFn (sf .Name ),
407+ Name : p .NameFn (sf .Name , p .FieldSep ),
408+ Column : p .ColumnFn (sf .Name ),
382409 FilterOps : make (map [string ]bool ),
383410 },
384411 CovertFn : valueFn ,
@@ -392,7 +419,9 @@ func (p *Parser) parseField(sf reflect.StructField) error {
392419 case s == "filter" :
393420 f .Filterable = true
394421 case strings .HasPrefix (opt , "column" ):
395- f .Name = strings .TrimPrefix (opt , "column=" )
422+ f .Column = strings .TrimPrefix (opt , "column=" )
423+ case strings .HasPrefix (opt , "name" ):
424+ f .Name = strings .TrimPrefix (opt , "name=" )
396425 case strings .HasPrefix (opt , "layout" ):
397426 layout = strings .TrimPrefix (opt , "layout=" )
398427 // if it's one of the standard layouts, like: RFC822 or Kitchen.
@@ -415,7 +444,6 @@ func (p *Parser) parseField(sf reflect.StructField) error {
415444 f .Type = indirect (sf .Type )
416445 filterOps := p .Config .GetSupportedOps (f .FieldMeta )
417446 if len (filterOps ) == 0 {
418- return fmt .Errorf ("rql: field type for %q is not supported" , sf .Name )
419447 }
420448 f .CovertFn = p .Config .GetConverter (f .FieldMeta )
421449 f .ValidateFn = p .Config .GetValidator (f .FieldMeta )
@@ -465,9 +493,10 @@ func (p *Parser) sort(fields []string) string {
465493 field = field [1 :]
466494 }
467495
468- expect (p .fields [field ] != nil , "unrecognized key %q for sorting" , field )
469- expect (p .fields [field ].Sortable , "field %q is not sortable" , field )
470- colName := p .colName (field )
496+ f := p .fields [field ]
497+ expect (f != nil , "unrecognized key %q for sorting" , field )
498+ expect (f .Sortable , "field %q is not sortable" , field )
499+ colName := f .Column
471500 if orderBy != "" {
472501 colName += " " + orderBy
473502 }
@@ -548,6 +577,7 @@ func (p *parseState) field(f *Field, v interface{}) {
548577 p .WriteString (p .fmtOp (f , op ))
549578 arg := f .CovertFn (op , * f .FieldMeta , opVal )
550579 p .values = append (p .values , arg )
580+
551581 i ++
552582 }
553583 if len (terms ) > 1 {
0 commit comments