mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 16:12:24 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			135 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			135 lines
		
	
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package sqlitedialect
 | |
| 
 | |
| import (
 | |
| 	"database/sql"
 | |
| 	"encoding/hex"
 | |
| 	"fmt"
 | |
| 
 | |
| 	"github.com/uptrace/bun"
 | |
| 	"github.com/uptrace/bun/dialect"
 | |
| 	"github.com/uptrace/bun/dialect/feature"
 | |
| 	"github.com/uptrace/bun/dialect/sqltype"
 | |
| 	"github.com/uptrace/bun/schema"
 | |
| )
 | |
| 
 | |
| func init() {
 | |
| 	if Version() != bun.Version() {
 | |
| 		panic(fmt.Errorf("sqlitedialect and Bun must have the same version: v%s != v%s",
 | |
| 			Version(), bun.Version()))
 | |
| 	}
 | |
| }
 | |
| 
 | |
| type Dialect struct {
 | |
| 	schema.BaseDialect
 | |
| 
 | |
| 	tables   *schema.Tables
 | |
| 	features feature.Feature
 | |
| }
 | |
| 
 | |
| func New() *Dialect {
 | |
| 	d := new(Dialect)
 | |
| 	d.tables = schema.NewTables(d)
 | |
| 	d.features = feature.CTE |
 | |
| 		feature.WithValues |
 | |
| 		feature.Returning |
 | |
| 		feature.InsertReturning |
 | |
| 		feature.InsertTableAlias |
 | |
| 		feature.UpdateTableAlias |
 | |
| 		feature.DeleteTableAlias |
 | |
| 		feature.InsertOnConflict |
 | |
| 		feature.TableNotExists |
 | |
| 		feature.SelectExists |
 | |
| 		feature.AutoIncrement |
 | |
| 		feature.CompositeIn |
 | |
| 		feature.DeleteReturning
 | |
| 	return d
 | |
| }
 | |
| 
 | |
| func (d *Dialect) Init(*sql.DB) {}
 | |
| 
 | |
| func (d *Dialect) Name() dialect.Name {
 | |
| 	return dialect.SQLite
 | |
| }
 | |
| 
 | |
| func (d *Dialect) Features() feature.Feature {
 | |
| 	return d.features
 | |
| }
 | |
| 
 | |
| func (d *Dialect) Tables() *schema.Tables {
 | |
| 	return d.tables
 | |
| }
 | |
| 
 | |
| func (d *Dialect) OnTable(table *schema.Table) {
 | |
| 	for _, field := range table.FieldMap {
 | |
| 		d.onField(field)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func (d *Dialect) onField(field *schema.Field) {
 | |
| 	field.DiscoveredSQLType = fieldSQLType(field)
 | |
| }
 | |
| 
 | |
| func (d *Dialect) IdentQuote() byte {
 | |
| 	return '"'
 | |
| }
 | |
| 
 | |
| func (d *Dialect) AppendBytes(b []byte, bs []byte) []byte {
 | |
| 	if bs == nil {
 | |
| 		return dialect.AppendNull(b)
 | |
| 	}
 | |
| 
 | |
| 	b = append(b, `X'`...)
 | |
| 
 | |
| 	s := len(b)
 | |
| 	b = append(b, make([]byte, hex.EncodedLen(len(bs)))...)
 | |
| 	hex.Encode(b[s:], bs)
 | |
| 
 | |
| 	b = append(b, '\'')
 | |
| 
 | |
| 	return b
 | |
| }
 | |
| 
 | |
| func (d *Dialect) DefaultVarcharLen() int {
 | |
| 	return 0
 | |
| }
 | |
| 
 | |
| // AppendSequence adds AUTOINCREMENT keyword to the column definition. As per [documentation],
 | |
| // AUTOINCREMENT is only valid for INTEGER PRIMARY KEY, and this method will be a noop for other columns.
 | |
| //
 | |
| // Because this is a valid construct:
 | |
| //
 | |
| //	CREATE TABLE ("id" INTEGER PRIMARY KEY AUTOINCREMENT);
 | |
| //
 | |
| // and this is not:
 | |
| //
 | |
| //	CREATE TABLE ("id" INTEGER AUTOINCREMENT, PRIMARY KEY ("id"));
 | |
| //
 | |
| // AppendSequence adds a primary key constraint as a *side-effect*. Callers should expect it to avoid building invalid SQL.
 | |
| // SQLite also [does not support] AUTOINCREMENT column in composite primary keys.
 | |
| //
 | |
| // [documentation]: https://www.sqlite.org/autoinc.html
 | |
| // [does not support]: https://stackoverflow.com/a/6793274/14726116
 | |
| func (d *Dialect) AppendSequence(b []byte, table *schema.Table, field *schema.Field) []byte {
 | |
| 	if field.IsPK && len(table.PKs) == 1 && field.CreateTableSQLType == sqltype.Integer {
 | |
| 		b = append(b, " PRIMARY KEY AUTOINCREMENT"...)
 | |
| 	}
 | |
| 	return b
 | |
| }
 | |
| 
 | |
| // DefaultSchemaName is the "schema-name" of the main database.
 | |
| // The details might differ from other dialects, but for all means and purposes
 | |
| // "main" is the default schema in an SQLite database.
 | |
| func (d *Dialect) DefaultSchema() string {
 | |
| 	return "main"
 | |
| }
 | |
| 
 | |
| func fieldSQLType(field *schema.Field) string {
 | |
| 	switch field.DiscoveredSQLType {
 | |
| 	case sqltype.SmallInt, sqltype.BigInt:
 | |
| 		// INTEGER PRIMARY KEY is an alias for the ROWID.
 | |
| 		// It is safe to convert all ints to INTEGER, because SQLite types don't have size.
 | |
| 		return sqltype.Integer
 | |
| 	default:
 | |
| 		return field.DiscoveredSQLType
 | |
| 	}
 | |
| }
 |