@@ -119,6 +119,8 @@ type Field struct {
119
119
type FieldMeta struct {
120
120
// Name of the column.
121
121
Name string
122
+ // name of the column.
123
+ Column string
122
124
// Has a "sort" option in the tag.
123
125
Sortable bool
124
126
// Has a "filter" option in the tag.
@@ -215,6 +217,7 @@ func (p *Parser) ParseQuery(q *Query) (pr *Params, err error) {
215
217
// FullName => full_name
216
218
// HTTPCode => http_code
217
219
func Column (s string ) string {
220
+ s = strings .Replace (s , "." , "_" , - 1 )
218
221
var b strings.Builder
219
222
for i := 0 ; i < len (s ); i ++ {
220
223
r := rune (s [i ])
@@ -339,6 +342,29 @@ func GetValidateFn(f *FieldMeta) Validator {
339
342
}
340
343
}
341
344
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
+
342
368
// init initializes the parser parsing state. it scans the fields
343
369
// in a breath-first-search order and for each one of the field calls parseField.
344
370
func (p * Parser ) init () error {
@@ -378,7 +404,8 @@ func (p *Parser) init() error {
378
404
func (p * Parser ) parseField (sf reflect.StructField ) error {
379
405
f := & Field {
380
406
FieldMeta : & FieldMeta {
381
- Name : p .ColumnFn (sf .Name ),
407
+ Name : p .NameFn (sf .Name , p .FieldSep ),
408
+ Column : p .ColumnFn (sf .Name ),
382
409
FilterOps : make (map [string ]bool ),
383
410
},
384
411
CovertFn : valueFn ,
@@ -392,7 +419,9 @@ func (p *Parser) parseField(sf reflect.StructField) error {
392
419
case s == "filter" :
393
420
f .Filterable = true
394
421
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=" )
396
425
case strings .HasPrefix (opt , "layout" ):
397
426
layout = strings .TrimPrefix (opt , "layout=" )
398
427
// if it's one of the standard layouts, like: RFC822 or Kitchen.
@@ -415,7 +444,6 @@ func (p *Parser) parseField(sf reflect.StructField) error {
415
444
f .Type = indirect (sf .Type )
416
445
filterOps := p .Config .GetSupportedOps (f .FieldMeta )
417
446
if len (filterOps ) == 0 {
418
- return fmt .Errorf ("rql: field type for %q is not supported" , sf .Name )
419
447
}
420
448
f .CovertFn = p .Config .GetConverter (f .FieldMeta )
421
449
f .ValidateFn = p .Config .GetValidator (f .FieldMeta )
@@ -465,9 +493,10 @@ func (p *Parser) sort(fields []string) string {
465
493
field = field [1 :]
466
494
}
467
495
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
471
500
if orderBy != "" {
472
501
colName += " " + orderBy
473
502
}
@@ -548,6 +577,7 @@ func (p *parseState) field(f *Field, v interface{}) {
548
577
p .WriteString (p .fmtOp (f , op ))
549
578
arg := f .CovertFn (op , * f .FieldMeta , opVal )
550
579
p .values = append (p .values , arg )
580
+
551
581
i ++
552
582
}
553
583
if len (terms ) > 1 {
0 commit comments