1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
// Copyright 2016 Qiang Xue. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package dbx
import (
"errors"
"fmt"
"strings"
)
var _ QueryBuilder = &SqliteQueryBuilder{}
// SqliteQueryBuilder is the query builder for SQLite databases.
type SqliteQueryBuilder struct {
*BaseQueryBuilder
}
// BuildUnion generates a UNION clause from the given union information.
//
// This is similar to BaseQueryBuilder.BuildUnion but without the parenthesis wrapping.
func (b *SqliteQueryBuilder) BuildUnion(unions []UnionInfo, params Params) string {
if len(unions) == 0 {
return ""
}
sql := ""
for i, union := range unions {
if i > 0 {
sql += " "
}
for k, v := range union.Query.params {
params[k] = v
}
u := "UNION"
if union.All {
u = "UNION ALL"
}
sql += fmt.Sprintf("%v %v", u, union.Query.sql)
}
return sql
}
// CombineUnion combines the nonempty unionClause with the provided sql string.
//
// This is similar to BaseQueryBuilder.CombineUnion but without the parenthesis wrapping.
func (q *SqliteQueryBuilder) CombineUnion(sql string, unionClause string) string {
if unionClause == "" {
return sql
}
return fmt.Sprintf("%v %v", sql, unionClause)
}
// -------------------------------------------------------------------
// SqliteBuilder is the builder for SQLite databases.
type SqliteBuilder struct {
*BaseBuilder
qb *SqliteQueryBuilder
}
var _ Builder = &SqliteBuilder{}
// NewSqliteBuilder creates a new SqliteBuilder instance.
func NewSqliteBuilder(db *DB, executor Executor) Builder {
return &SqliteBuilder{
NewBaseBuilder(db, executor),
&SqliteQueryBuilder{NewBaseQueryBuilder(db)},
}
}
// QueryBuilder returns the query builder supporting the current DB.
func (b *SqliteBuilder) QueryBuilder() QueryBuilder {
return b.qb
}
// Select returns a new SelectQuery object that can be used to build a SELECT statement.
// The parameters to this method should be the list column names to be selected.
// A column name may have an optional alias name. For example, Select("id", "my_name AS name").
func (b *SqliteBuilder) Select(cols ...string) *SelectQuery {
return NewSelectQuery(b, b.db).Select(cols...)
}
// Model returns a new ModelQuery object that can be used to perform model-based DB operations.
// The model passed to this method should be a pointer to a model struct.
func (b *SqliteBuilder) Model(model interface{}) *ModelQuery {
return NewModelQuery(model, b.db.FieldMapper, b.db, b)
}
// QuoteSimpleTableName quotes a simple table name.
// A simple table name does not contain any schema prefix.
func (b *SqliteBuilder) QuoteSimpleTableName(s string) string {
if strings.ContainsAny(s, "`") {
return s
}
return "`" + s + "`"
}
// QuoteSimpleColumnName quotes a simple column name.
// A simple column name does not contain any table prefix.
func (b *SqliteBuilder) QuoteSimpleColumnName(s string) string {
if strings.Contains(s, "`") || s == "*" {
return s
}
return "`" + s + "`"
}
// DropIndex creates a Query that can be used to remove the named index from a table.
func (b *SqliteBuilder) DropIndex(table, name string) *Query {
sql := fmt.Sprintf("DROP INDEX %v", b.db.QuoteColumnName(name))
return b.NewQuery(sql)
}
// TruncateTable creates a Query that can be used to truncate a table.
func (b *SqliteBuilder) TruncateTable(table string) *Query {
sql := "DELETE FROM " + b.db.QuoteTableName(table)
return b.NewQuery(sql)
}
// RenameTable creates a Query that can be used to rename a table.
func (b *SqliteBuilder) RenameTable(oldName, newName string) *Query {
sql := fmt.Sprintf("ALTER TABLE %v RENAME TO %v", b.db.QuoteTableName(oldName), b.db.QuoteTableName(newName))
return b.NewQuery(sql)
}
// AlterColumn creates a Query that can be used to change the definition of a table column.
func (b *SqliteBuilder) AlterColumn(table, col, typ string) *Query {
q := b.NewQuery("")
q.LastError = errors.New("SQLite does not support altering column")
return q
}
// AddPrimaryKey creates a Query that can be used to specify primary key(s) for a table.
// The "name" parameter specifies the name of the primary key constraint.
func (b *SqliteBuilder) AddPrimaryKey(table, name string, cols ...string) *Query {
q := b.NewQuery("")
q.LastError = errors.New("SQLite does not support adding primary key")
return q
}
// DropPrimaryKey creates a Query that can be used to remove the named primary key constraint from a table.
func (b *SqliteBuilder) DropPrimaryKey(table, name string) *Query {
q := b.NewQuery("")
q.LastError = errors.New("SQLite does not support dropping primary key")
return q
}
// AddForeignKey creates a Query that can be used to add a foreign key constraint to a table.
// The length of cols and refCols must be the same as they refer to the primary and referential columns.
// The optional "options" parameters will be appended to the SQL statement. They can be used to
// specify options such as "ON DELETE CASCADE".
func (b *SqliteBuilder) AddForeignKey(table, name string, cols, refCols []string, refTable string, options ...string) *Query {
q := b.NewQuery("")
q.LastError = errors.New("SQLite does not support adding foreign keys")
return q
}
// DropForeignKey creates a Query that can be used to remove the named foreign key constraint from a table.
func (b *SqliteBuilder) DropForeignKey(table, name string) *Query {
q := b.NewQuery("")
q.LastError = errors.New("SQLite does not support dropping foreign keys")
return q
}
|