fix forgot removed records when deleting user (#5429)
* fix forgot removed records when deleting user * fix migration * fix rewritekey lock on sqlite * remove unused codestokarchuk/v1.17
parent
e726e4b828
commit
fe55ab2a68
@ -0,0 +1,33 @@ |
|||||||
|
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package migrations |
||||||
|
|
||||||
|
import ( |
||||||
|
"github.com/go-xorm/builder" |
||||||
|
"github.com/go-xorm/xorm" |
||||||
|
) |
||||||
|
|
||||||
|
func clearNonusedData(x *xorm.Engine) error { |
||||||
|
condDelete := func(colName string) builder.Cond { |
||||||
|
return builder.NotIn(colName, builder.Select("id").From("user")) |
||||||
|
} |
||||||
|
|
||||||
|
if _, err := x.Exec(builder.Delete(condDelete("uid")).From("team_user")); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
if _, err := x.Exec(builder.Delete(condDelete("user_id")).From("collaboration")); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
if _, err := x.Exec(builder.Delete(condDelete("user_id")).From("stop_watch")); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
if _, err := x.Exec(builder.Delete(condDelete("owner_id")).From("gpg_key")); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package builder |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
func (b *Builder) limitWriteTo(w Writer) error { |
||||||
|
if strings.TrimSpace(b.dialect) == "" { |
||||||
|
return ErrDialectNotSetUp |
||||||
|
} |
||||||
|
|
||||||
|
if b.limitation != nil { |
||||||
|
limit := b.limitation |
||||||
|
if limit.offset < 0 || limit.limitN <= 0 { |
||||||
|
return ErrInvalidLimitation |
||||||
|
} |
||||||
|
// erase limit condition
|
||||||
|
b.limitation = nil |
||||||
|
ow := w.(*BytesWriter) |
||||||
|
|
||||||
|
switch strings.ToLower(strings.TrimSpace(b.dialect)) { |
||||||
|
case ORACLE: |
||||||
|
if len(b.selects) == 0 { |
||||||
|
b.selects = append(b.selects, "*") |
||||||
|
} |
||||||
|
|
||||||
|
var final *Builder |
||||||
|
selects := b.selects |
||||||
|
b.selects = append(selects, "ROWNUM RN") |
||||||
|
|
||||||
|
var wb *Builder |
||||||
|
if b.optype == unionType { |
||||||
|
wb = Dialect(b.dialect).Select("at.*", "ROWNUM RN"). |
||||||
|
From(b, "at") |
||||||
|
} else { |
||||||
|
wb = b |
||||||
|
} |
||||||
|
|
||||||
|
if limit.offset == 0 { |
||||||
|
final = Dialect(b.dialect).Select(selects...).From(wb, "at"). |
||||||
|
Where(Lte{"at.RN": limit.limitN}) |
||||||
|
} else { |
||||||
|
sub := Dialect(b.dialect).Select("*"). |
||||||
|
From(b, "at").Where(Lte{"at.RN": limit.offset + limit.limitN}) |
||||||
|
|
||||||
|
final = Dialect(b.dialect).Select(selects...).From(sub, "att"). |
||||||
|
Where(Gt{"att.RN": limit.offset}) |
||||||
|
} |
||||||
|
|
||||||
|
return final.WriteTo(ow) |
||||||
|
case SQLITE, MYSQL, POSTGRES: |
||||||
|
// if type UNION, we need to write previous content back to current writer
|
||||||
|
if b.optype == unionType { |
||||||
|
if err := b.WriteTo(ow); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if limit.offset == 0 { |
||||||
|
fmt.Fprint(ow, " LIMIT ", limit.limitN) |
||||||
|
} else { |
||||||
|
fmt.Fprintf(ow, " LIMIT %v OFFSET %v", limit.limitN, limit.offset) |
||||||
|
} |
||||||
|
case MSSQL: |
||||||
|
if len(b.selects) == 0 { |
||||||
|
b.selects = append(b.selects, "*") |
||||||
|
} |
||||||
|
|
||||||
|
var final *Builder |
||||||
|
selects := b.selects |
||||||
|
b.selects = append(append([]string{fmt.Sprintf("TOP %d %v", limit.limitN+limit.offset, b.selects[0])}, |
||||||
|
b.selects[1:]...), "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN") |
||||||
|
|
||||||
|
var wb *Builder |
||||||
|
if b.optype == unionType { |
||||||
|
wb = Dialect(b.dialect).Select("*", "ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RN"). |
||||||
|
From(b, "at") |
||||||
|
} else { |
||||||
|
wb = b |
||||||
|
} |
||||||
|
|
||||||
|
if limit.offset == 0 { |
||||||
|
final = Dialect(b.dialect).Select(selects...).From(wb, "at") |
||||||
|
} else { |
||||||
|
final = Dialect(b.dialect).Select(selects...).From(wb, "at").Where(Gt{"at.RN": limit.offset}) |
||||||
|
} |
||||||
|
|
||||||
|
return final.WriteTo(ow) |
||||||
|
default: |
||||||
|
return ErrNotSupportType |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,47 @@ |
|||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package builder |
||||||
|
|
||||||
|
import ( |
||||||
|
"fmt" |
||||||
|
"strings" |
||||||
|
) |
||||||
|
|
||||||
|
func (b *Builder) unionWriteTo(w Writer) error { |
||||||
|
if b.limitation != nil || b.cond.IsValid() || |
||||||
|
b.orderBy != "" || b.having != "" || b.groupBy != "" { |
||||||
|
return ErrNotUnexpectedUnionConditions |
||||||
|
} |
||||||
|
|
||||||
|
for idx, u := range b.unions { |
||||||
|
current := u.builder |
||||||
|
if current.optype != selectType { |
||||||
|
return ErrUnsupportedUnionMembers |
||||||
|
} |
||||||
|
|
||||||
|
if len(b.unions) == 1 { |
||||||
|
if err := current.selectWriteTo(w); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
} else { |
||||||
|
if b.dialect != "" && b.dialect != current.dialect { |
||||||
|
return ErrInconsistentDialect |
||||||
|
} |
||||||
|
|
||||||
|
if idx != 0 { |
||||||
|
fmt.Fprint(w, fmt.Sprintf(" UNION %v ", strings.ToUpper(u.unionType))) |
||||||
|
} |
||||||
|
fmt.Fprint(w, "(") |
||||||
|
|
||||||
|
if err := current.selectWriteTo(w); err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
fmt.Fprint(w, ")") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
@ -0,0 +1,156 @@ |
|||||||
|
// Copyright 2018 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package builder |
||||||
|
|
||||||
|
import ( |
||||||
|
sql2 "database/sql" |
||||||
|
"fmt" |
||||||
|
"reflect" |
||||||
|
"time" |
||||||
|
) |
||||||
|
|
||||||
|
func condToSQL(cond Cond) (string, []interface{}, error) { |
||||||
|
if cond == nil || !cond.IsValid() { |
||||||
|
return "", nil, nil |
||||||
|
} |
||||||
|
|
||||||
|
w := NewWriter() |
||||||
|
if err := cond.WriteTo(w); err != nil { |
||||||
|
return "", nil, err |
||||||
|
} |
||||||
|
return w.writer.String(), w.args, nil |
||||||
|
} |
||||||
|
|
||||||
|
func condToBoundSQL(cond Cond) (string, error) { |
||||||
|
if cond == nil || !cond.IsValid() { |
||||||
|
return "", nil |
||||||
|
} |
||||||
|
|
||||||
|
w := NewWriter() |
||||||
|
if err := cond.WriteTo(w); err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
return ConvertToBoundSQL(w.writer.String(), w.args) |
||||||
|
} |
||||||
|
|
||||||
|
// ToSQL convert a builder or conditions to SQL and args
|
||||||
|
func ToSQL(cond interface{}) (string, []interface{}, error) { |
||||||
|
switch cond.(type) { |
||||||
|
case Cond: |
||||||
|
return condToSQL(cond.(Cond)) |
||||||
|
case *Builder: |
||||||
|
return cond.(*Builder).ToSQL() |
||||||
|
} |
||||||
|
return "", nil, ErrNotSupportType |
||||||
|
} |
||||||
|
|
||||||
|
// ToBoundSQL convert a builder or conditions to parameters bound SQL
|
||||||
|
func ToBoundSQL(cond interface{}) (string, error) { |
||||||
|
switch cond.(type) { |
||||||
|
case Cond: |
||||||
|
return condToBoundSQL(cond.(Cond)) |
||||||
|
case *Builder: |
||||||
|
return cond.(*Builder).ToBoundSQL() |
||||||
|
} |
||||||
|
return "", ErrNotSupportType |
||||||
|
} |
||||||
|
|
||||||
|
func noSQLQuoteNeeded(a interface{}) bool { |
||||||
|
switch a.(type) { |
||||||
|
case int, int8, int16, int32, int64: |
||||||
|
return true |
||||||
|
case uint, uint8, uint16, uint32, uint64: |
||||||
|
return true |
||||||
|
case float32, float64: |
||||||
|
return true |
||||||
|
case bool: |
||||||
|
return true |
||||||
|
case string: |
||||||
|
return false |
||||||
|
case time.Time, *time.Time: |
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
t := reflect.TypeOf(a) |
||||||
|
switch t.Kind() { |
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: |
||||||
|
return true |
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: |
||||||
|
return true |
||||||
|
case reflect.Float32, reflect.Float64: |
||||||
|
return true |
||||||
|
case reflect.Bool: |
||||||
|
return true |
||||||
|
case reflect.String: |
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
return false |
||||||
|
} |
||||||
|
|
||||||
|
// ConvertToBoundSQL will convert SQL and args to a bound SQL
|
||||||
|
func ConvertToBoundSQL(sql string, args []interface{}) (string, error) { |
||||||
|
buf := StringBuilder{} |
||||||
|
var i, j, start int |
||||||
|
for ; i < len(sql); i++ { |
||||||
|
if sql[i] == '?' { |
||||||
|
_, err := buf.WriteString(sql[start:i]) |
||||||
|
if err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
start = i + 1 |
||||||
|
|
||||||
|
if len(args) == j { |
||||||
|
return "", ErrNeedMoreArguments |
||||||
|
} |
||||||
|
|
||||||
|
arg := args[j] |
||||||
|
if namedArg, ok := arg.(sql2.NamedArg); ok { |
||||||
|
arg = namedArg.Value |
||||||
|
} |
||||||
|
|
||||||
|
if noSQLQuoteNeeded(arg) { |
||||||
|
_, err = fmt.Fprint(&buf, arg) |
||||||
|
} else { |
||||||
|
_, err = fmt.Fprintf(&buf, "'%v'", arg) |
||||||
|
} |
||||||
|
if err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
j = j + 1 |
||||||
|
} |
||||||
|
} |
||||||
|
_, err := buf.WriteString(sql[start:]) |
||||||
|
if err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
return buf.String(), nil |
||||||
|
} |
||||||
|
|
||||||
|
// ConvertPlaceholder replaces ? to $1, $2 ... or :1, :2 ... according prefix
|
||||||
|
func ConvertPlaceholder(sql, prefix string) (string, error) { |
||||||
|
buf := StringBuilder{} |
||||||
|
var i, j, start int |
||||||
|
for ; i < len(sql); i++ { |
||||||
|
if sql[i] == '?' { |
||||||
|
if _, err := buf.WriteString(sql[start:i]); err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
|
||||||
|
start = i + 1 |
||||||
|
j = j + 1 |
||||||
|
|
||||||
|
if _, err := buf.WriteString(fmt.Sprintf("%v%d", prefix, j)); err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if _, err := buf.WriteString(sql[start:]); err != nil { |
||||||
|
return "", err |
||||||
|
} |
||||||
|
|
||||||
|
return buf.String(), nil |
||||||
|
} |
Loading…
Reference in new issue