refactor: openpitrix module

Signed-off-by: hongming <talonwan@yunify.com>
This commit is contained in:
hongming
2019-09-25 14:07:15 +08:00
parent d0dc66cf28
commit 1b5681c12b
314 changed files with 72092 additions and 25762 deletions

12
vendor/openpitrix.io/openpitrix/pkg/db/Dockerfile generated vendored Normal file
View File

@@ -0,0 +1,12 @@
# Copyright 2017 The OpenPitrix Authors. All rights reserved.
# Use of this source code is governed by a Apache license
# that can be found in the LICENSE file.
FROM dhoer/flyway:5.1.4-mysql-8.0.11-alpine
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN apk add --no-cache mysql-client
COPY ./schema /flyway/sql
COPY ./ddl /flyway/sql/ddl
COPY ./scripts /flyway/sql/ddl

107
vendor/openpitrix.io/openpitrix/pkg/db/condition.go generated vendored Normal file
View File

@@ -0,0 +1,107 @@
// Copyright 2017 The OpenPitrix Authors. All rights reserved.
// Use of this source code is governed by a Apache license
// that can be found in the LICENSE file.
package db
import (
"strings"
"github.com/gocraft/dbr"
)
const (
placeholder = "?"
)
type EqCondition struct {
dbr.Builder
Column string
Value interface{}
}
// Copy From vendor/github.com/gocraft/dbr/condition.go:36
func buildCmp(d dbr.Dialect, buf dbr.Buffer, pred string, column string, value interface{}) error {
buf.WriteString(d.QuoteIdent(column))
buf.WriteString(" ")
buf.WriteString(pred)
buf.WriteString(" ")
buf.WriteString(placeholder)
buf.WriteValue(value)
return nil
}
// And creates AND from a list of conditions
func And(cond ...dbr.Builder) dbr.Builder {
return dbr.And(cond...)
}
// Or creates OR from a list of conditions
func Or(cond ...dbr.Builder) dbr.Builder {
return dbr.Or(cond...)
}
func escape(str string) string {
return strings.Map(func(r rune) rune {
switch r {
case '%', '\'', '^', '[', ']', '!', '_':
return ' '
}
return r
}, str)
}
func Like(column string, value string) dbr.Builder {
value = "%" + strings.TrimSpace(escape(value)) + "%"
return dbr.BuildFunc(func(d dbr.Dialect, buf dbr.Buffer) error {
return buildCmp(d, buf, "LIKE", column, value)
})
}
func Prefix(column string, value string) dbr.Builder {
value = strings.TrimSpace(escape(value)) + "%"
return dbr.BuildFunc(func(d dbr.Dialect, buf dbr.Buffer) error {
return buildCmp(d, buf, "LIKE", column, value)
})
}
// Eq is `=`.
// When value is nil, it will be translated to `IS NULL`.
// When value is a slice, it will be translated to `IN`.
// Otherwise it will be translated to `=`.
func Eq(column string, value interface{}) dbr.Builder {
return &EqCondition{
Builder: dbr.Eq(column, value),
Column: column,
Value: value,
}
}
// Neq is `!=`.
// When value is nil, it will be translated to `IS NOT NULL`.
// When value is a slice, it will be translated to `NOT IN`.
// Otherwise it will be translated to `!=`.
func Neq(column string, value interface{}) dbr.Builder {
return dbr.Neq(column, value)
}
// Gt is `>`.
func Gt(column string, value interface{}) dbr.Builder {
return dbr.Gt(column, value)
}
// Gte is '>='.
func Gte(column string, value interface{}) dbr.Builder {
return dbr.Gte(column, value)
}
// Lt is '<'.
func Lt(column string, value interface{}) dbr.Builder {
return dbr.Lt(column, value)
}
// Lte is `<=`.
func Lte(column string, value interface{}) dbr.Builder {
return dbr.Lte(column, value)
}

72
vendor/openpitrix.io/openpitrix/pkg/db/connection.go generated vendored Normal file
View File

@@ -0,0 +1,72 @@
// Copyright 2017 The OpenPitrix Authors. All rights reserved.
// Use of this source code is governed by a Apache license
// that can be found in the LICENSE file.
package db
import (
"context"
"sync"
"time"
"github.com/gocraft/dbr"
"openpitrix.io/openpitrix/pkg/config"
"openpitrix.io/openpitrix/pkg/logger"
)
type key int
var dbMap = sync.Map{}
var dbKey key
type Database struct {
Conn *dbr.Connection
}
func OpenDatabase(cfg config.MysqlConfig) (*Database, error) {
// https://github.com/go-sql-driver/mysql/issues/9
conn, err := dbr.Open("mysql", cfg.GetUrl()+"?parseTime=1&multiStatements=1&charset=utf8mb4&collation=utf8mb4_unicode_ci", nil)
if err != nil {
return nil, err
}
conn.SetMaxIdleConns(100)
conn.SetMaxOpenConns(100)
conn.SetConnMaxLifetime(10 * time.Second)
db := &Database{
Conn: conn,
}
dbMap.Store(cfg, db)
return db, nil
}
func NewContext(ctx context.Context, cfg config.MysqlConfig) context.Context {
return context.WithValue(ctx, dbKey, cfg)
}
func FromContext(ctx context.Context) (*Database, bool) {
cfg := ctx.Value(dbKey).(config.MysqlConfig)
var err error
db, ok := dbMap.Load(cfg)
if !ok {
db, err = OpenDatabase(cfg)
if err != nil {
logger.Critical(ctx, "Failed to open database: %+v", err)
return nil, false
}
}
return db.(*Database), true
}
func (db *Database) New(ctx context.Context) *Conn {
actualDb, ok := FromContext(ctx)
conn := db.Conn
if ok {
conn = actualDb.Conn
}
return &Conn{
Session: conn.NewSession(&EventReceiver{ctx}),
ctx: ctx,
}
}

272
vendor/openpitrix.io/openpitrix/pkg/db/db.go generated vendored Normal file
View File

@@ -0,0 +1,272 @@
package db
import (
"context"
"database/sql"
"fmt"
"strings"
_ "github.com/go-sql-driver/mysql"
"github.com/gocraft/dbr"
)
const (
DefaultSelectLimit = 200
)
func GetLimit(n uint64) uint64 {
if n < 0 {
n = 0
}
if n > DefaultSelectLimit {
n = DefaultSelectLimit
}
return n
}
func GetOffset(n uint64) uint64 {
if n < 0 {
n = 0
}
return n
}
type InsertHook func(query *InsertQuery)
type UpdateHook func(query *UpdateQuery)
type DeleteHook func(query *DeleteQuery)
type SelectQuery struct {
*dbr.SelectBuilder
ctx context.Context
JoinCount int // for join filter
}
type InsertQuery struct {
*dbr.InsertBuilder
ctx context.Context
Hook InsertHook
}
type DeleteQuery struct {
*dbr.DeleteBuilder
ctx context.Context
Hook DeleteHook
}
type UpdateQuery struct {
*dbr.UpdateBuilder
ctx context.Context
Hook UpdateHook
}
type Conn struct {
*dbr.Session
ctx context.Context
InsertHook InsertHook
UpdateHook UpdateHook
DeleteHook DeleteHook
}
// SelectQuery
// Example: Select().From().Where().Limit().Offset().OrderDir().Load()
// Select().From().Where().Limit().Offset().OrderDir().LoadOne()
// Select().From().Where().Count()
// SelectAll().From().Where().Limit().Offset().OrderDir().Load()
// SelectAll().From().Where().Limit().Offset().OrderDir().LoadOne()
// SelectAll().From().Where().Count()
func (conn *Conn) Select(columns ...string) *SelectQuery {
return &SelectQuery{conn.Session.Select(columns...), conn.ctx, 0}
}
func (conn *Conn) SelectBySql(query string, value ...interface{}) *SelectQuery {
return &SelectQuery{conn.Session.SelectBySql(query, value...), conn.ctx, 0}
}
func (conn *Conn) SelectAll(columns ...string) *SelectQuery {
return &SelectQuery{conn.Session.Select("*"), conn.ctx, 0}
}
func (b *SelectQuery) Join(table, on interface{}) *SelectQuery {
b.SelectBuilder.Join(table, on)
return b
}
func (b *SelectQuery) JoinAs(table string, alias string, on interface{}) *SelectQuery {
b.SelectBuilder.Join(dbr.I(table).As(alias), on)
return b
}
func (b *SelectQuery) From(table string) *SelectQuery {
b.SelectBuilder.From(table)
return b
}
func (b *SelectQuery) Where(query interface{}, value ...interface{}) *SelectQuery {
b.SelectBuilder.Where(query, value...)
return b
}
func (b *SelectQuery) GroupBy(col ...string) *SelectQuery {
b.SelectBuilder.GroupBy(col...)
return b
}
func (b *SelectQuery) Distinct() *SelectQuery {
b.SelectBuilder.Distinct()
return b
}
func (b *SelectQuery) Limit(n uint64) *SelectQuery {
n = GetLimit(n)
b.SelectBuilder.Limit(n)
return b
}
func (b *SelectQuery) Offset(n uint64) *SelectQuery {
n = GetOffset(n)
b.SelectBuilder.Offset(n)
return b
}
func (b *SelectQuery) OrderDir(col string, isAsc bool) *SelectQuery {
b.SelectBuilder.OrderDir(col, isAsc)
return b
}
func (b *SelectQuery) Load(value interface{}) (int, error) {
return b.SelectBuilder.LoadContext(b.ctx, value)
}
func (b *SelectQuery) LoadOne(value interface{}) error {
return b.SelectBuilder.LoadOneContext(b.ctx, value)
}
func getColumns(dbrColumns []interface{}) string {
var columns []string
for _, column := range dbrColumns {
if c, ok := column.(string); ok {
columns = append(columns, c)
}
}
return strings.Join(columns, ", ")
}
func (b *SelectQuery) Count() (count uint32, err error) {
// cache SelectStmt
selectStmt := b.SelectBuilder
limit := selectStmt.LimitCount
offset := selectStmt.OffsetCount
column := selectStmt.Column
isDistinct := selectStmt.IsDistinct
order := selectStmt.Order
b.LimitCount = -1
b.OffsetCount = -1
b.Column = []interface{}{"COUNT(*)"}
b.Order = []dbr.Builder{}
if isDistinct {
b.Column = []interface{}{fmt.Sprintf("COUNT(DISTINCT %s)", getColumns(column))}
b.IsDistinct = false
}
err = b.LoadOne(&count)
// fallback SelectStmt
selectStmt.LimitCount = limit
selectStmt.OffsetCount = offset
selectStmt.Column = column
selectStmt.IsDistinct = isDistinct
selectStmt.Order = order
b.SelectBuilder = selectStmt
return
}
// InsertQuery
// Example: InsertInto().Columns().Record().Exec()
func (conn *Conn) InsertInto(table string) *InsertQuery {
return &InsertQuery{conn.Session.InsertInto(table), conn.ctx, conn.InsertHook}
}
func (b *InsertQuery) Exec() (sql.Result, error) {
result, err := b.InsertBuilder.ExecContext(b.ctx)
if b.Hook != nil && err == nil {
defer b.Hook(b)
}
return result, err
}
func (b *InsertQuery) Columns(columns ...string) *InsertQuery {
b.InsertBuilder.Columns(columns...)
return b
}
func (b *InsertQuery) Record(structValue interface{}) *InsertQuery {
if len(b.Column) == 0 {
b.Columns(GetColumnsFromStruct(structValue)...)
}
b.InsertBuilder.Record(structValue)
return b
}
// DeleteQuery
// Example: DeleteFrom().Where().Limit().Exec()
func (conn *Conn) DeleteFrom(table string) *DeleteQuery {
return &DeleteQuery{conn.Session.DeleteFrom(table), conn.ctx, conn.DeleteHook}
}
func (b *DeleteQuery) Where(query interface{}, value ...interface{}) *DeleteQuery {
b.DeleteBuilder.Where(query, value...)
return b
}
func (b *DeleteQuery) Limit(n uint64) *DeleteQuery {
b.DeleteBuilder.Limit(n)
return b
}
func (b *DeleteQuery) Exec() (sql.Result, error) {
result, err := b.DeleteBuilder.ExecContext(b.ctx)
if b.Hook != nil && err == nil {
defer b.Hook(b)
}
return result, err
}
// UpdateQuery
// Example: Update().Set().Where().Exec()
func (conn *Conn) Update(table string) *UpdateQuery {
return &UpdateQuery{conn.Session.Update(table), conn.ctx, conn.UpdateHook}
}
func (b *UpdateQuery) Exec() (sql.Result, error) {
result, err := b.UpdateBuilder.ExecContext(b.ctx)
if b.Hook != nil && err == nil {
defer b.Hook(b)
}
return result, err
}
func (b *UpdateQuery) Set(column string, value interface{}) *UpdateQuery {
b.UpdateBuilder.Set(column, value)
return b
}
func (b *UpdateQuery) SetMap(m map[string]interface{}) *UpdateQuery {
b.UpdateBuilder.SetMap(m)
return b
}
func (b *UpdateQuery) Where(query interface{}, value ...interface{}) *UpdateQuery {
b.UpdateBuilder.Where(query, value...)
return b
}
func (b *UpdateQuery) Limit(n uint64) *UpdateQuery {
b.UpdateBuilder.Limit(n)
return b
}

22
vendor/openpitrix.io/openpitrix/pkg/db/errors.go generated vendored Normal file
View File

@@ -0,0 +1,22 @@
// Copyright 2018 The OpenPitrix Authors. All rights reserved.
// Use of this source code is governed by a Apache license
// that can be found in the LICENSE file.
package db
import (
"github.com/gocraft/dbr"
)
// package errors
var (
ErrNotFound = dbr.ErrNotFound
ErrNotSupported = dbr.ErrNotSupported
ErrTableNotSpecified = dbr.ErrTableNotSpecified
ErrColumnNotSpecified = dbr.ErrColumnNotSpecified
ErrInvalidPointer = dbr.ErrInvalidPointer
ErrPlaceholderCount = dbr.ErrPlaceholderCount
ErrInvalidSliceLength = dbr.ErrInvalidSliceLength
ErrCantConvertToTime = dbr.ErrCantConvertToTime
ErrInvalidTimestring = dbr.ErrInvalidTimestring
)

49
vendor/openpitrix.io/openpitrix/pkg/db/event.go generated vendored Normal file
View File

@@ -0,0 +1,49 @@
// Copyright 2017 The OpenPitrix Authors. All rights reserved.
// Use of this source code is governed by a Apache license
// that can be found in the LICENSE file.
package db
import (
"context"
"openpitrix.io/openpitrix/pkg/logger"
)
// EventReceiver is a sentinel EventReceiver; use it if the caller doesn't supply one
type EventReceiver struct {
ctx context.Context
}
// Event receives a simple notification when various events occur
func (n *EventReceiver) Event(eventName string) {
}
// EventKv receives a notification when various events occur along with
// optional key/value data
func (n *EventReceiver) EventKv(eventName string, kvs map[string]string) {
}
// EventErr receives a notification of an error if one occurs
func (n *EventReceiver) EventErr(eventName string, err error) error {
return err
}
// EventErrKv receives a notification of an error if one occurs along with
// optional key/value data
func (n *EventReceiver) EventErrKv(eventName string, err error, kvs map[string]string) error {
logger.Error(n.ctx, "%+v", err)
logger.Error(n.ctx, "%s: %+v", eventName, kvs)
return err
}
// Timing receives the time an event took to happen
func (n *EventReceiver) Timing(eventName string, nanoseconds int64) {
}
// TimingKv receives the time an event took to happen along with optional key/value data
func (n *EventReceiver) TimingKv(eventName string, nanoseconds int64, kvs map[string]string) {
logger.Debug(n.ctx, "%s spend %.2fms: %+v", eventName, float32(nanoseconds)/1000000, kvs)
}

31
vendor/openpitrix.io/openpitrix/pkg/db/util.go generated vendored Normal file
View File

@@ -0,0 +1,31 @@
// Copyright 2018 The OpenPitrix Authors. All rights reserved.
// Use of this source code is governed by a Apache license
// that can be found in the LICENSE file.
package db
import (
"github.com/fatih/structs"
"openpitrix.io/openpitrix/pkg/util/stringutil"
)
func GetColumnsFromStruct(s interface{}) []string {
names := structs.Names(s)
for i, name := range names {
names[i] = stringutil.CamelCaseToUnderscore(name)
}
return names
}
func GetColumnsFromStructWithPrefix(prefix string, s interface{}) []string {
names := structs.Names(s)
for i, name := range names {
names[i] = WithPrefix(prefix, stringutil.CamelCaseToUnderscore(name))
}
return names
}
func WithPrefix(prefix, str string) string {
return prefix + "." + str
}