package gormlite

import (
	

	
	
	
	
	
	

	
)

type _Dialector struct {
	DSN  string
	Conn gorm.ConnPool
}

// Open opens a GORM dialector from a data source name.
func ( string) gorm.Dialector {
	return &_Dialector{DSN: }
}

// Open opens a GORM dialector from a database handle.
func ( gorm.ConnPool) gorm.Dialector {
	return &_Dialector{Conn: }
}

func ( _Dialector) () string {
	return "sqlite"
}

func ( _Dialector) ( *gorm.DB) ( error) {
	if .Conn != nil {
		.ConnPool = .Conn
	} else {
		,  := driver.Open(.DSN)
		if  != nil {
			return 
		}
		.ConnPool = 
	}

	callbacks.RegisterDefaultCallbacks(, &callbacks.Config{
		CreateClauses:        []string{"INSERT", "VALUES", "ON CONFLICT", "RETURNING"},
		UpdateClauses:        []string{"UPDATE", "SET", "FROM", "WHERE", "RETURNING"},
		DeleteClauses:        []string{"DELETE", "FROM", "WHERE", "RETURNING"},
		LastInsertIDReversed: true,
	})

	for ,  := range .ClauseBuilders() {
		if ,  := .ClauseBuilders[]; ! {
			.ClauseBuilders[] = 
		}
	}
	return
}

func ( _Dialector) () map[string]clause.ClauseBuilder {
	return map[string]clause.ClauseBuilder{
		"INSERT": func( clause.Clause,  clause.Builder) {
			if ,  := .Expression.(clause.Insert);  {
				if ,  := .(*gorm.Statement);  {
					.WriteString("INSERT ")
					if .Modifier != "" {
						.WriteString(.Modifier)
						.WriteByte(' ')
					}

					.WriteString("INTO ")
					if .Table.Name == "" {
						.WriteQuoted(.Table)
					} else {
						.WriteQuoted(.Table)
					}
					return
				}
			}

			.Build()
		},
		"LIMIT": func( clause.Clause,  clause.Builder) {
			if ,  := .Expression.(clause.Limit);  {
				var  = -1
				if .Limit != nil && *.Limit >= 0 {
					 = *.Limit
				}
				if  >= 0 || .Offset > 0 {
					.WriteString("LIMIT ")
					.WriteString(strconv.Itoa())
				}
				if .Offset > 0 {
					.WriteString(" OFFSET ")
					.WriteString(strconv.Itoa(.Offset))
				}
			}
		},
		"FOR": func( clause.Clause,  clause.Builder) {
			if ,  := .Expression.(clause.Locking);  {
				// SQLite3 does not support row-level locking.
				return
			}
			.Build()
		},
	}
}

func ( _Dialector) ( *schema.Field) clause.Expression {
	if .AutoIncrement {
		return clause.Expr{SQL: "NULL"}
	}

	// doesn't work, will raise error
	return clause.Expr{SQL: "DEFAULT"}
}

func ( _Dialector) ( *gorm.DB) gorm.Migrator {
	return _Migrator{migrator.Migrator{Config: migrator.Config{
		DB:                          ,
		Dialector:                   ,
		CreateIndexAfterCreateTable: true,
	}}}
}

func ( _Dialector) ( clause.Writer,  *gorm.Statement,  interface{}) {
	.WriteByte('?')
}

func ( _Dialector) ( clause.Writer,  string) {
	var (
		,  bool
		      int8
		          int8
	)

	for ,  := range []byte() {
		switch  {
		case '`':
			++
			if  == 2 {
				.WriteString("``")
				 = 0
			}
		case '.':
			if  > 0 || ! {
				 = 0
				 = false
				 = 0
				.WriteString("`")
			}
			.WriteByte()
			continue
		default:
			if - <= 0 && ! {
				.WriteString("`")
				 = true
				if  =  > 0;  {
					 -= 1
				}
			}

			for ;  > 0;  -= 1 {
				.WriteString("``")
			}

			.WriteByte()
		}
		++
	}

	if  > 0 && ! {
		.WriteString("``")
	}
	.WriteString("`")
}

func ( _Dialector) ( string,  ...interface{}) string {
	return logger.ExplainSQL(, nil, `"`, ...)
}

func ( _Dialector) ( *schema.Field) string {
	switch .DataType {
	case schema.Bool:
		return "numeric"
	case schema.Int, schema.Uint:
		if .AutoIncrement {
			// doesn't check `PrimaryKey`, to keep backward compatibility
			// https://sqlite.org/autoinc.html
			return "integer PRIMARY KEY AUTOINCREMENT"
		} else {
			return "integer"
		}
	case schema.Float:
		return "real"
	case schema.String:
		return "text"
	case schema.Time:
		// Distinguish between schema.Time and tag time
		if ,  := .TagSettings["TYPE"];  {
			return 
		} else {
			return "datetime"
		}
	case schema.Bytes:
		return "blob"
	}

	return string(.DataType)
}

func ( _Dialector) ( *gorm.DB,  string) error {
	.Exec("SAVEPOINT " + )
	return nil
}

func ( _Dialector) ( *gorm.DB,  string) error {
	.Exec("ROLLBACK TO SAVEPOINT " + )
	return nil
}