dialect.go (2048B)
1 package sqlitedialect 2 3 import ( 4 "database/sql" 5 "encoding/hex" 6 "fmt" 7 8 "github.com/uptrace/bun" 9 "github.com/uptrace/bun/dialect" 10 "github.com/uptrace/bun/dialect/feature" 11 "github.com/uptrace/bun/dialect/sqltype" 12 "github.com/uptrace/bun/schema" 13 ) 14 15 func init() { 16 if Version() != bun.Version() { 17 panic(fmt.Errorf("sqlitedialect and Bun must have the same version: v%s != v%s", 18 Version(), bun.Version())) 19 } 20 } 21 22 type Dialect struct { 23 schema.BaseDialect 24 25 tables *schema.Tables 26 features feature.Feature 27 } 28 29 func New() *Dialect { 30 d := new(Dialect) 31 d.tables = schema.NewTables(d) 32 d.features = feature.CTE | 33 feature.WithValues | 34 feature.Returning | 35 feature.InsertReturning | 36 feature.InsertTableAlias | 37 feature.UpdateTableAlias | 38 feature.DeleteTableAlias | 39 feature.InsertOnConflict | 40 feature.TableNotExists | 41 feature.SelectExists | 42 feature.CompositeIn 43 return d 44 } 45 46 func (d *Dialect) Init(*sql.DB) {} 47 48 func (d *Dialect) Name() dialect.Name { 49 return dialect.SQLite 50 } 51 52 func (d *Dialect) Features() feature.Feature { 53 return d.features 54 } 55 56 func (d *Dialect) Tables() *schema.Tables { 57 return d.tables 58 } 59 60 func (d *Dialect) OnTable(table *schema.Table) { 61 for _, field := range table.FieldMap { 62 d.onField(field) 63 } 64 } 65 66 func (d *Dialect) onField(field *schema.Field) { 67 field.DiscoveredSQLType = fieldSQLType(field) 68 } 69 70 func (d *Dialect) IdentQuote() byte { 71 return '"' 72 } 73 74 func (d *Dialect) AppendBytes(b []byte, bs []byte) []byte { 75 if bs == nil { 76 return dialect.AppendNull(b) 77 } 78 79 b = append(b, `X'`...) 80 81 s := len(b) 82 b = append(b, make([]byte, hex.EncodedLen(len(bs)))...) 83 hex.Encode(b[s:], bs) 84 85 b = append(b, '\'') 86 87 return b 88 } 89 90 func (d *Dialect) DefaultVarcharLen() int { 91 return 0 92 } 93 94 func fieldSQLType(field *schema.Field) string { 95 switch field.DiscoveredSQLType { 96 case sqltype.SmallInt, sqltype.BigInt: 97 // INTEGER PRIMARY KEY is an alias for the ROWID. 98 // It is safe to convert all ints to INTEGER, because SQLite types don't have size. 99 return sqltype.Integer 100 default: 101 return field.DiscoveredSQLType 102 } 103 }