github.com/aacfactory/fns-contrib/databases/sql@v1.2.84/dac/specifications/dialect.go (about) 1 package specifications 2 3 import ( 4 "fmt" 5 "github.com/aacfactory/errors" 6 "github.com/aacfactory/fns-contrib/databases/sql" 7 "github.com/aacfactory/fns/context" 8 "io" 9 ) 10 11 var ( 12 SELECT = []byte("SELECT") 13 FROM = []byte("FROM") 14 WHERE = []byte("WHERE") 15 INSERT = []byte("INSERT") 16 UPDATE = []byte("UPDATE") 17 DELETE = []byte("DELETE") 18 SPACE = []byte(" ") 19 INTO = []byte("INTO") 20 AND = []byte("AND") 21 SET = []byte("SET") 22 EQ = []byte("=") 23 PLUS = []byte("+") 24 AT = []byte("@") 25 LB = []byte("(") 26 RB = []byte(")") 27 COMMA = []byte(", ") 28 DOT = []byte(".") 29 STAR = []byte("*") 30 AS = []byte("AS") 31 VALUES = []byte("VALUES") 32 EXISTS = []byte("EXISTS") 33 COUNT = []byte("COUNT") 34 NOT = []byte("NOT") 35 CONFLICT = []byte("CONFLICT") 36 ON = []byte("ON") 37 RETURNING = []byte("RETURNING") 38 DO = []byte("DO") 39 NOTHING = []byte("NOTHING") 40 ORDER = []byte("ORDER") 41 BY = []byte("BY") 42 DESC = []byte("DESC") 43 GROUP = []byte("GROUP") 44 HAVING = []byte("HAVING") 45 OFFSET = []byte("OFFSET") 46 LIMIT = []byte("LIMIT") 47 ) 48 49 const ( 50 QueryMethod Method = iota + 1 51 ExecuteMethod 52 ) 53 54 type Method int 55 56 type QueryPlaceholder interface { 57 Next() (v string) 58 SkipCursor(n int) 59 Current() (v string) 60 } 61 62 type Render interface { 63 Render(ctx Context, w io.Writer) (argument []any, err error) 64 } 65 66 type Dialect interface { 67 Name() string 68 FormatIdent(ident string) string 69 QueryPlaceholder() QueryPlaceholder 70 Insert(ctx Context, spec *Specification, values int) (method Method, query []byte, fields []string, returning []string, err error) 71 InsertOrUpdate(ctx Context, spec *Specification) (method Method, query []byte, fields []string, returning []string, err error) 72 InsertWhenExist(ctx Context, spec *Specification, src QueryExpr) (method Method, query []byte, fields []string, arguments []any, returning []string, err error) 73 InsertWhenNotExist(ctx Context, spec *Specification, src QueryExpr) (method Method, query []byte, fields []string, arguments []any, returning []string, err error) 74 Update(ctx Context, spec *Specification) (method Method, query []byte, fields []string, err error) 75 UpdateFields(ctx Context, spec *Specification, fields []FieldValue, cond Condition) (method Method, query []byte, arguments []any, err error) 76 Delete(ctx Context, spec *Specification) (method Method, query []byte, fields []string, err error) 77 DeleteByConditions(ctx Context, spec *Specification, cond Condition) (method Method, query []byte, audits []string, arguments []any, err error) 78 Exist(ctx Context, spec *Specification, cond Condition) (method Method, query []byte, arguments []any, err error) 79 Count(ctx Context, spec *Specification, cond Condition) (method Method, query []byte, arguments []any, err error) 80 Query(ctx Context, spec *Specification, cond Condition, orders Orders, offset int, length int) (method Method, query []byte, arguments []any, fields []string, err error) 81 View(ctx Context, spec *Specification, cond Condition, orders Orders, groupBy GroupBy, offset int, length int) (method Method, query []byte, arguments []any, fields []string, err error) 82 } 83 84 var ( 85 dialects = make([]Dialect, 0, 1) 86 ) 87 88 func RegisterDialect(dialect Dialect) { 89 if dialect == nil { 90 return 91 } 92 name := dialect.Name() 93 if _, has := getDialect(name); has { 94 panic(fmt.Errorf("%+v", errors.Warning(fmt.Sprintf("sql: %s dialect has registered", name)))) 95 return 96 } 97 dialects = append(dialects, dialect) 98 } 99 100 func getDialect(name string) (dialect Dialect, has bool) { 101 for _, d := range dialects { 102 if d.Name() == name { 103 dialect = d 104 has = true 105 return 106 } 107 } 108 return 109 } 110 111 func LoadDialect(ctx context.Context) (dialect Dialect, err error) { 112 name, nameErr := sql.Dialect(ctx) 113 if nameErr != nil { 114 err = errors.Warning("sql: load dialect failed").WithCause(nameErr) 115 return 116 } 117 has := name != "" 118 if has { 119 dialect, has = getDialect(name) 120 if !has { 121 err = errors.Warning("sql: load dialect failed").WithCause(fmt.Errorf("%s was not found", name)) 122 return 123 } 124 return 125 } 126 dialect, has = defaultDialect() 127 if !has { 128 err = errors.Warning("sql: load dialect failed").WithCause(fmt.Errorf("no dialect was registerd")) 129 return 130 } 131 return 132 } 133 134 func defaultDialect() (dialect Dialect, has bool) { 135 if len(dialects) == 0 { 136 return 137 } 138 dialect = dialects[0] 139 has = true 140 return 141 }