Files
db/exp/ident.go
T
2025-03-22 23:02:05 +08:00

217 lines
8.1 KiB
Go

package exp
import (
"strings"
)
type (
identifier struct {
schema string
table string
col interface{}
}
)
var (
tableAndColumnParts = 2
schemaTableAndColumnIdentifierParts = 3
)
func ParseIdentifier(ident string) IdentifierExpression {
parts := strings.Split(ident, ".")
switch len(parts) {
case tableAndColumnParts:
return NewIdentifierExpression("", parts[0], parts[1])
case schemaTableAndColumnIdentifierParts:
return NewIdentifierExpression(parts[0], parts[1], parts[2])
}
return NewIdentifierExpression("", "", ident)
}
func NewIdentifierExpression(schema, table string, col interface{}) IdentifierExpression {
return identifier{}.Schema(schema).Table(table).Col(col)
}
func (i identifier) clone() identifier {
return identifier{schema: i.schema, table: i.table, col: i.col}
}
func (i identifier) Clone() Expression {
return i.clone()
}
func (i identifier) IsQualified() bool {
schema, table, col := i.schema, i.table, i.col
switch c := col.(type) {
case string:
if c != "" {
return len(table) > 0 || len(schema) > 0
}
default:
if c != nil {
return len(table) > 0 || len(schema) > 0
}
}
if len(table) > 0 {
return len(schema) > 0
}
return false
}
// Sets the table on the current identifier
//
// I("col").Table("table") -> "table"."col" //postgres
// I("col").Table("table") -> `table`.`col` //mysql
// I("col").Table("table") -> `table`.`col` //sqlite3
func (i identifier) Table(table string) IdentifierExpression {
i.table = table
return i
}
func (i identifier) GetTable() string {
return i.table
}
// Sets the table on the current identifier
//
// I("table").Schema("schema") -> "schema"."table" //postgres
// I("col").Schema("table") -> `schema`.`table` //mysql
// I("col").Schema("table") -> `schema`.`table` //sqlite3
func (i identifier) Schema(schema string) IdentifierExpression {
i.schema = schema
return i
}
func (i identifier) GetSchema() string {
return i.schema
}
// Sets the table on the current identifier
//
// I("table").Col("col") -> "table"."col" //postgres
// I("table").Schema("col") -> `table`.`col` //mysql
// I("table").Schema("col") -> `table`.`col` //sqlite3
func (i identifier) Col(col interface{}) IdentifierExpression {
if col == "*" {
i.col = Star()
} else {
i.col = col
}
return i
}
func (i identifier) Expression() Expression { return i }
// Qualifies the epression with a * literal (e.g. "table".*)
func (i identifier) All() IdentifierExpression { return i.Col("*") }
func (i identifier) IsEmpty() bool {
isEmpty := i.schema == "" && i.table == ""
if isEmpty {
switch t := i.col.(type) {
case nil:
return true
case string:
return t == ""
default:
return false
}
}
return isEmpty
}
// Gets the column identifier
func (i identifier) GetCol() interface{} { return i.col }
// Used within updates to set a column value
func (i identifier) Set(val interface{}) UpdateExpression { return set(i, val) }
// Alias an identifier (e.g "my_col" AS "other_col")
func (i identifier) As(val interface{}) AliasedExpression {
if v, ok := val.(string); ok {
ident := ParseIdentifier(v)
if i.col != nil && i.col != "" {
return NewAliasExpression(i, ident)
}
aliasCol := ident.GetCol()
if i.table != "" {
return NewAliasExpression(i, NewIdentifierExpression("", aliasCol.(string), nil))
} else if i.schema != "" {
return NewAliasExpression(i, NewIdentifierExpression(aliasCol.(string), "", nil))
}
}
return NewAliasExpression(i, val)
}
// Returns a BooleanExpression for equality (e.g "my_col" = 1)
func (i identifier) Eq(val interface{}) BooleanExpression { return eq(i, val) }
// Returns a BooleanExpression for in equality (e.g "my_col" != 1)
func (i identifier) Neq(val interface{}) BooleanExpression { return neq(i, val) }
// Returns a BooleanExpression for checking that a identifier is greater than another value (e.g "my_col" > 1)
func (i identifier) Gt(val interface{}) BooleanExpression { return gt(i, val) }
// Returns a BooleanExpression for checking that a identifier is greater than or equal to another value
// (e.g "my_col" >= 1)
func (i identifier) Gte(val interface{}) BooleanExpression { return gte(i, val) }
// Returns a BooleanExpression for checking that a identifier is less than another value (e.g "my_col" < 1)
func (i identifier) Lt(val interface{}) BooleanExpression { return lt(i, val) }
// Returns a BooleanExpression for checking that a identifier is less than or equal to another value
// (e.g "my_col" <= 1)
func (i identifier) Lte(val interface{}) BooleanExpression { return lte(i, val) }
// Returns a BooleanExpression for bit inversion (e.g ~ "my_col")
func (i identifier) BitwiseInversion() BitwiseExpression { return bitwiseInversion(i) }
// Returns a BooleanExpression for bit OR (e.g "my_col" | 1)
func (i identifier) BitwiseOr(val interface{}) BitwiseExpression { return bitwiseOr(i, val) }
// Returns a BooleanExpression for bit AND (e.g "my_col" & 1)
func (i identifier) BitwiseAnd(val interface{}) BitwiseExpression { return bitwiseAnd(i, val) }
// Returns a BooleanExpression for bit XOR (e.g "my_col" ^ 1)
func (i identifier) BitwiseXor(val interface{}) BitwiseExpression { return bitwiseXor(i, val) }
// Returns a BooleanExpression for bit LEFT shift (e.g "my_col" << 1)
func (i identifier) BitwiseLeftShift(val interface{}) BitwiseExpression {
return bitwiseLeftShift(i, val)
}
// Returns a BooleanExpression for bit RIGHT shift (e.g "my_col" >> 1)
func (i identifier) BitwiseRightShift(val interface{}) BitwiseExpression {
return bitwiseRightShift(i, val)
}
// Returns a BooleanExpression for checking that a identifier is in a list of values or (e.g "my_col" > 1)
func (i identifier) In(vals ...interface{}) BooleanExpression { return in(i, vals...) }
func (i identifier) NotIn(vals ...interface{}) BooleanExpression { return notIn(i, vals...) }
func (i identifier) Like(val interface{}) BooleanExpression { return like(i, val) }
func (i identifier) NotLike(val interface{}) BooleanExpression { return notLike(i, val) }
func (i identifier) ILike(val interface{}) BooleanExpression { return iLike(i, val) }
func (i identifier) NotILike(val interface{}) BooleanExpression { return notILike(i, val) }
func (i identifier) RegexpLike(val interface{}) BooleanExpression { return regexpLike(i, val) }
func (i identifier) RegexpNotLike(val interface{}) BooleanExpression { return regexpNotLike(i, val) }
func (i identifier) RegexpILike(val interface{}) BooleanExpression { return regexpILike(i, val) }
func (i identifier) RegexpNotILike(val interface{}) BooleanExpression { return regexpNotILike(i, val) }
func (i identifier) Is(val interface{}) BooleanExpression { return is(i, val) }
func (i identifier) IsNot(val interface{}) BooleanExpression { return isNot(i, val) }
func (i identifier) IsNull() BooleanExpression { return is(i, nil) }
func (i identifier) IsNotNull() BooleanExpression { return isNot(i, nil) }
func (i identifier) IsTrue() BooleanExpression { return is(i, true) }
func (i identifier) IsNotTrue() BooleanExpression { return isNot(i, true) }
func (i identifier) IsFalse() BooleanExpression { return is(i, false) }
func (i identifier) IsNotFalse() BooleanExpression { return isNot(i, false) }
func (i identifier) Asc() OrderedExpression { return asc(i) }
func (i identifier) Desc() OrderedExpression { return desc(i) }
func (i identifier) Distinct() SQLFunctionExpression { return NewSQLFunctionExpression("DISTINCT", i) }
func (i identifier) Cast(t string) CastExpression { return NewCastExpression(i, t) }
// Returns a RangeExpression for checking that a identifier is between two values (e.g "my_col" BETWEEN 1 AND 10)
func (i identifier) Between(val RangeVal) RangeExpression { return between(i, val) }
// Returns a RangeExpression for checking that a identifier is between two values (e.g "my_col" BETWEEN 1 AND 10)
func (i identifier) NotBetween(val RangeVal) RangeExpression { return notBetween(i, val) }