github.com/aacfactory/fns-contrib/databases/sql@v1.2.84/dac/specifications/context.go (about)

     1  package specifications
     2  
     3  import (
     4  	"context"
     5  )
     6  
     7  type Context interface {
     8  	context.Context
     9  	FormatIdent(ident string) string
    10  	NextQueryPlaceholder() (v string)
    11  	SkipNextQueryPlaceholderCursor(n int)
    12  	// Localization
    13  	// key can be struct field, struct value and [struct value, struct value]
    14  	// when field then return column name
    15  	// when value then return table name
    16  	// when [struct value, struct value] then return column name of table name
    17  	Localization(key any) (content []string, has bool)
    18  }
    19  
    20  func Todo(ctx context.Context, key any, dialect Dialect) Context {
    21  	return &renderCtx{
    22  		Context: ctx,
    23  		dialect: dialect,
    24  		ph:      dialect.QueryPlaceholder(),
    25  		key:     key,
    26  	}
    27  }
    28  
    29  func Fork(ctx Context) Context {
    30  	rc := ctx.(*renderCtx)
    31  	return &renderCtx{
    32  		Context: ctx,
    33  		ph:      rc.getDialect().QueryPlaceholder(),
    34  		key:     rc.key,
    35  	}
    36  }
    37  
    38  func SwitchKey(ctx Context, key any) Context {
    39  	return &renderCtx{
    40  		Context: ctx,
    41  		key:     key,
    42  	}
    43  }
    44  
    45  type renderCtx struct {
    46  	context.Context
    47  	dialect Dialect
    48  	ph      QueryPlaceholder
    49  	key     any
    50  }
    51  
    52  func (ctx *renderCtx) getDialect() Dialect {
    53  	if ctx.dialect != nil {
    54  		return ctx.dialect
    55  	}
    56  	parent, ok := ctx.Context.(*renderCtx)
    57  	if ok {
    58  		return parent.getDialect()
    59  	}
    60  	return nil
    61  }
    62  
    63  func (ctx *renderCtx) FormatIdent(ident string) string {
    64  	return ctx.getDialect().FormatIdent(ident)
    65  }
    66  
    67  func (ctx *renderCtx) NextQueryPlaceholder() (v string) {
    68  	if ctx.ph == nil {
    69  		parent, ok := ctx.Context.(Context)
    70  		if ok {
    71  			v = parent.NextQueryPlaceholder()
    72  		}
    73  		return
    74  	}
    75  	v = ctx.ph.Next()
    76  	return
    77  }
    78  
    79  func (ctx *renderCtx) SkipNextQueryPlaceholderCursor(n int) {
    80  	if ctx.ph == nil {
    81  		parent, ok := ctx.Context.(Context)
    82  		if ok {
    83  			parent.SkipNextQueryPlaceholderCursor(n)
    84  		}
    85  		return
    86  	}
    87  	ctx.ph.SkipCursor(n)
    88  	return
    89  }
    90  
    91  func (ctx *renderCtx) Localization(key any) (content []string, has bool) {
    92  	sk, ok := key.(string)
    93  	if ok {
    94  		content, has = dict.Get(ctx.key, sk)
    95  	} else {
    96  		content, has = dict.Get(key)
    97  	}
    98  	if has {
    99  		for i, c := range content {
   100  			content[i] = ctx.getDialect().FormatIdent(c)
   101  		}
   102  	}
   103  	return
   104  }