Adapter: orm

This commit is contained in:
Ming Deng 2020-09-06 13:33:43 +08:00
parent f4a43814be
commit 5b3dd7e50f
19 changed files with 2227 additions and 30 deletions

28
pkg/adapter/orm/cmd.go Normal file
View File

@ -0,0 +1,28 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// RunCommand listen for orm command and then run it if command arguments passed.
func RunCommand() {
orm.RunCommand()
}
func RunSyncdb(name string, force bool, verbose bool) error {
return orm.RunSyncdb(name, force, verbose)
}

24
pkg/adapter/orm/db.go Normal file
View File

@ -0,0 +1,24 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
var (
// ErrMissPK missing pk error
ErrMissPK = orm.ErrMissPK
)

124
pkg/adapter/orm/db_alias.go Normal file
View File

@ -0,0 +1,124 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"context"
"database/sql"
"time"
"github.com/astaxie/beego/pkg/client/orm"
"github.com/astaxie/beego/pkg/client/orm/hints"
"github.com/astaxie/beego/pkg/infrastructure/utils"
)
// DriverType database driver constant int.
type DriverType orm.DriverType
// Enum the Database driver
const (
_ DriverType = iota // int enum type
DRMySQL = orm.DRMySQL
DRSqlite = orm.DRSqlite // sqlite
DROracle = orm.DROracle // oracle
DRPostgres = orm.DRPostgres // pgsql
DRTiDB = orm.DRTiDB // TiDB
)
type DB orm.DB
func (d *DB) Begin() (*sql.Tx, error) {
return (*orm.DB)(d).Begin()
}
func (d *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) {
return (*orm.DB)(d).BeginTx(ctx, opts)
}
func (d *DB) Prepare(query string) (*sql.Stmt, error) {
return (*orm.DB)(d).Prepare(query)
}
func (d *DB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {
return (*orm.DB)(d).PrepareContext(ctx, query)
}
func (d *DB) Exec(query string, args ...interface{}) (sql.Result, error) {
return (*orm.DB)(d).Exec(query, args...)
}
func (d *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {
return (*orm.DB)(d).ExecContext(ctx, query, args...)
}
func (d *DB) Query(query string, args ...interface{}) (*sql.Rows, error) {
return (*orm.DB)(d).Query(query, args...)
}
func (d *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {
return (*orm.DB)(d).QueryContext(ctx, query, args...)
}
func (d *DB) QueryRow(query string, args ...interface{}) *sql.Row {
return (*orm.DB)(d).QueryRow(query, args)
}
func (d *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row {
return (*orm.DB)(d).QueryRowContext(ctx, query, args...)
}
// AddAliasWthDB add a aliasName for the drivename
func AddAliasWthDB(aliasName, driverName string, db *sql.DB) error {
return orm.AddAliasWthDB(aliasName, driverName, db)
}
// RegisterDataBase Setting the database connect params. Use the database driver self dataSource args.
func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) error {
opts := make([]utils.KV, 0, 2)
if len(params) > 0 {
opts = append(opts, hints.MaxIdleConnections(params[0]))
}
if len(params) > 1 {
opts = append(opts, hints.MaxOpenConnections(params[1]))
}
return orm.RegisterDataBase(aliasName, driverName, dataSource, opts...)
}
// RegisterDriver Register a database driver use specify driver name, this can be definition the driver is which database type.
func RegisterDriver(driverName string, typ DriverType) error {
return orm.RegisterDriver(driverName, orm.DriverType(typ))
}
// SetDataBaseTZ Change the database default used timezone
func SetDataBaseTZ(aliasName string, tz *time.Location) error {
return orm.SetDataBaseTZ(aliasName, tz)
}
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
func SetMaxIdleConns(aliasName string, maxIdleConns int) {
orm.SetMaxIdleConns(aliasName, maxIdleConns)
}
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
func SetMaxOpenConns(aliasName string, maxOpenConns int) {
orm.SetMaxOpenConns(aliasName, maxOpenConns)
}
// GetDB Get *sql.DB from registered database by db alias name.
// Use "default" as alias name if you not set.
func GetDB(aliasNames ...string) (*sql.DB, error) {
return orm.GetDB(aliasNames...)
}

25
pkg/adapter/orm/models.go Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// ResetModelCache Clean model cache. Then you can re-RegisterModel.
// Common use this api for test case.
func ResetModelCache() {
orm.ResetModelCache()
}

View File

@ -0,0 +1,40 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// RegisterModel register models
func RegisterModel(models ...interface{}) {
orm.RegisterModel(models...)
}
// RegisterModelWithPrefix register models with a prefix
func RegisterModelWithPrefix(prefix string, models ...interface{}) {
orm.RegisterModelWithPrefix(prefix, models)
}
// RegisterModelWithSuffix register models with a suffix
func RegisterModelWithSuffix(suffix string, models ...interface{}) {
orm.RegisterModelWithSuffix(suffix, models...)
}
// BootStrap bootstrap models.
// make all model parsed and can not add more models
func BootStrap() {
orm.BootStrap()
}

View File

@ -0,0 +1,625 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"time"
"github.com/astaxie/beego/pkg/client/orm"
)
// Define the Type enum
const (
TypeBooleanField = orm.TypeBooleanField
TypeVarCharField = orm.TypeVarCharField
TypeCharField = orm.TypeCharField
TypeTextField = orm.TypeTextField
TypeTimeField = orm.TypeTimeField
TypeDateField = orm.TypeDateField
TypeDateTimeField = orm.TypeDateTimeField
TypeBitField = orm.TypeBitField
TypeSmallIntegerField = orm.TypeSmallIntegerField
TypeIntegerField = orm.TypeIntegerField
TypeBigIntegerField = orm.TypeBigIntegerField
TypePositiveBitField = orm.TypePositiveBitField
TypePositiveSmallIntegerField = orm.TypePositiveSmallIntegerField
TypePositiveIntegerField = orm.TypePositiveIntegerField
TypePositiveBigIntegerField = orm.TypePositiveBigIntegerField
TypeFloatField = orm.TypeFloatField
TypeDecimalField = orm.TypeDecimalField
TypeJSONField = orm.TypeJSONField
TypeJsonbField = orm.TypeJsonbField
RelForeignKey = orm.RelForeignKey
RelOneToOne = orm.RelOneToOne
RelManyToMany = orm.RelManyToMany
RelReverseOne = orm.RelReverseOne
RelReverseMany = orm.RelReverseMany
)
// Define some logic enum
const (
IsIntegerField = orm.IsIntegerField
IsPositiveIntegerField = orm.IsPositiveIntegerField
IsRelField = orm.IsRelField
IsFieldType = orm.IsFieldType
)
// BooleanField A true/false field.
type BooleanField orm.BooleanField
// Value return the BooleanField
func (e BooleanField) Value() bool {
return orm.BooleanField(e).Value()
}
// Set will set the BooleanField
func (e *BooleanField) Set(d bool) {
(*orm.BooleanField)(e).Set(d)
}
// String format the Bool to string
func (e *BooleanField) String() string {
return (*orm.BooleanField)(e).String()
}
// FieldType return BooleanField the type
func (e *BooleanField) FieldType() int {
return (*orm.BooleanField)(e).FieldType()
}
// SetRaw set the interface to bool
func (e *BooleanField) SetRaw(value interface{}) error {
return (*orm.BooleanField)(e).SetRaw(value)
}
// RawValue return the current value
func (e *BooleanField) RawValue() interface{} {
return (*orm.BooleanField)(e).RawValue()
}
// verify the BooleanField implement the Fielder interface
var _ Fielder = new(BooleanField)
// CharField A string field
// required values tag: size
// The size is enforced at the database level and in modelss validation.
// eg: `orm:"size(120)"`
type CharField orm.CharField
// Value return the CharField's Value
func (e CharField) Value() string {
return orm.CharField(e).Value()
}
// Set CharField value
func (e *CharField) Set(d string) {
(*orm.CharField)(e).Set(d)
}
// String return the CharField
func (e *CharField) String() string {
return (*orm.CharField)(e).String()
}
// FieldType return the enum type
func (e *CharField) FieldType() int {
return (*orm.CharField)(e).FieldType()
}
// SetRaw set the interface to string
func (e *CharField) SetRaw(value interface{}) error {
return (*orm.CharField)(e).SetRaw(value)
}
// RawValue return the CharField value
func (e *CharField) RawValue() interface{} {
return (*orm.CharField)(e).RawValue()
}
// verify CharField implement Fielder
var _ Fielder = new(CharField)
// TimeField A time, represented in go by a time.Time instance.
// only time values like 10:00:00
// Has a few extra, optional attr tag:
//
// auto_now:
// Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// auto_now_add:
// Automatically set the field to now when the object is first created. Useful for creation of timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
type TimeField orm.TimeField
// Value return the time.Time
func (e TimeField) Value() time.Time {
return orm.TimeField(e).Value()
}
// Set set the TimeField's value
func (e *TimeField) Set(d time.Time) {
(*orm.TimeField)(e).Set(d)
}
// String convert time to string
func (e *TimeField) String() string {
return (*orm.TimeField)(e).String()
}
// FieldType return enum type Date
func (e *TimeField) FieldType() int {
return (*orm.TimeField)(e).FieldType()
}
// SetRaw convert the interface to time.Time. Allow string and time.Time
func (e *TimeField) SetRaw(value interface{}) error {
return (*orm.TimeField)(e).SetRaw(value)
}
// RawValue return time value
func (e *TimeField) RawValue() interface{} {
return (*orm.TimeField)(e).RawValue()
}
var _ Fielder = new(TimeField)
// DateField A date, represented in go by a time.Time instance.
// only date values like 2006-01-02
// Has a few extra, optional attr tag:
//
// auto_now:
// Automatically set the field to now every time the object is saved. Useful for “last-modified” timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// auto_now_add:
// Automatically set the field to now when the object is first created. Useful for creation of timestamps.
// Note that the current date is always used; its not just a default value that you can override.
//
// eg: `orm:"auto_now"` or `orm:"auto_now_add"`
type DateField orm.DateField
// Value return the time.Time
func (e DateField) Value() time.Time {
return orm.DateField(e).Value()
}
// Set set the DateField's value
func (e *DateField) Set(d time.Time) {
(*orm.DateField)(e).Set(d)
}
// String convert datetime to string
func (e *DateField) String() string {
return (*orm.DateField)(e).String()
}
// FieldType return enum type Date
func (e *DateField) FieldType() int {
return (*orm.DateField)(e).FieldType()
}
// SetRaw convert the interface to time.Time. Allow string and time.Time
func (e *DateField) SetRaw(value interface{}) error {
return (*orm.DateField)(e).SetRaw(value)
}
// RawValue return Date value
func (e *DateField) RawValue() interface{} {
return (*orm.DateField)(e).RawValue()
}
// verify DateField implement fielder interface
var _ Fielder = new(DateField)
// DateTimeField A date, represented in go by a time.Time instance.
// datetime values like 2006-01-02 15:04:05
// Takes the same extra arguments as DateField.
type DateTimeField orm.DateTimeField
// Value return the datetime value
func (e DateTimeField) Value() time.Time {
return orm.DateTimeField(e).Value()
}
// Set set the time.Time to datetime
func (e *DateTimeField) Set(d time.Time) {
(*orm.DateTimeField)(e).Set(d)
}
// String return the time's String
func (e *DateTimeField) String() string {
return (*orm.DateTimeField)(e).String()
}
// FieldType return the enum TypeDateTimeField
func (e *DateTimeField) FieldType() int {
return (*orm.DateTimeField)(e).FieldType()
}
// SetRaw convert the string or time.Time to DateTimeField
func (e *DateTimeField) SetRaw(value interface{}) error {
return (*orm.DateTimeField)(e).SetRaw(value)
}
// RawValue return the datetime value
func (e *DateTimeField) RawValue() interface{} {
return (*orm.DateTimeField)(e).RawValue()
}
// verify datetime implement fielder
var _ Fielder = new(DateTimeField)
// FloatField A floating-point number represented in go by a float32 value.
type FloatField orm.FloatField
// Value return the FloatField value
func (e FloatField) Value() float64 {
return orm.FloatField(e).Value()
}
// Set the Float64
func (e *FloatField) Set(d float64) {
(*orm.FloatField)(e).Set(d)
}
// String return the string
func (e *FloatField) String() string {
return (*orm.FloatField)(e).String()
}
// FieldType return the enum type
func (e *FloatField) FieldType() int {
return (*orm.FloatField)(e).FieldType()
}
// SetRaw converter interface Float64 float32 or string to FloatField
func (e *FloatField) SetRaw(value interface{}) error {
return (*orm.FloatField)(e).SetRaw(value)
}
// RawValue return the FloatField value
func (e *FloatField) RawValue() interface{} {
return (*orm.FloatField)(e).RawValue()
}
// verify FloatField implement Fielder
var _ Fielder = new(FloatField)
// SmallIntegerField -32768 to 32767
type SmallIntegerField orm.SmallIntegerField
// Value return int16 value
func (e SmallIntegerField) Value() int16 {
return orm.SmallIntegerField(e).Value()
}
// Set the SmallIntegerField value
func (e *SmallIntegerField) Set(d int16) {
(*orm.SmallIntegerField)(e).Set(d)
}
// String convert smallint to string
func (e *SmallIntegerField) String() string {
return (*orm.SmallIntegerField)(e).String()
}
// FieldType return enum type SmallIntegerField
func (e *SmallIntegerField) FieldType() int {
return (*orm.SmallIntegerField)(e).FieldType()
}
// SetRaw convert interface int16/string to int16
func (e *SmallIntegerField) SetRaw(value interface{}) error {
return (*orm.SmallIntegerField)(e).SetRaw(value)
}
// RawValue return smallint value
func (e *SmallIntegerField) RawValue() interface{} {
return (*orm.SmallIntegerField)(e).RawValue()
}
// verify SmallIntegerField implement Fielder
var _ Fielder = new(SmallIntegerField)
// IntegerField -2147483648 to 2147483647
type IntegerField orm.IntegerField
// Value return the int32
func (e IntegerField) Value() int32 {
return orm.IntegerField(e).Value()
}
// Set IntegerField value
func (e *IntegerField) Set(d int32) {
(*orm.IntegerField)(e).Set(d)
}
// String convert Int32 to string
func (e *IntegerField) String() string {
return (*orm.IntegerField)(e).String()
}
// FieldType return the enum type
func (e *IntegerField) FieldType() int {
return (*orm.IntegerField)(e).FieldType()
}
// SetRaw convert interface int32/string to int32
func (e *IntegerField) SetRaw(value interface{}) error {
return (*orm.IntegerField)(e).SetRaw(value)
}
// RawValue return IntegerField value
func (e *IntegerField) RawValue() interface{} {
return (*orm.IntegerField)(e).RawValue()
}
// verify IntegerField implement Fielder
var _ Fielder = new(IntegerField)
// BigIntegerField -9223372036854775808 to 9223372036854775807.
type BigIntegerField orm.BigIntegerField
// Value return int64
func (e BigIntegerField) Value() int64 {
return orm.BigIntegerField(e).Value()
}
// Set the BigIntegerField value
func (e *BigIntegerField) Set(d int64) {
(*orm.BigIntegerField)(e).Set(d)
}
// String convert BigIntegerField to string
func (e *BigIntegerField) String() string {
return (*orm.BigIntegerField)(e).String()
}
// FieldType return enum type
func (e *BigIntegerField) FieldType() int {
return (*orm.BigIntegerField)(e).FieldType()
}
// SetRaw convert interface int64/string to int64
func (e *BigIntegerField) SetRaw(value interface{}) error {
return (*orm.BigIntegerField)(e).SetRaw(value)
}
// RawValue return BigIntegerField value
func (e *BigIntegerField) RawValue() interface{} {
return (*orm.BigIntegerField)(e).RawValue()
}
// verify BigIntegerField implement Fielder
var _ Fielder = new(BigIntegerField)
// PositiveSmallIntegerField 0 to 65535
type PositiveSmallIntegerField orm.PositiveSmallIntegerField
// Value return uint16
func (e PositiveSmallIntegerField) Value() uint16 {
return orm.PositiveSmallIntegerField(e).Value()
}
// Set PositiveSmallIntegerField value
func (e *PositiveSmallIntegerField) Set(d uint16) {
(*orm.PositiveSmallIntegerField)(e).Set(d)
}
// String convert uint16 to string
func (e *PositiveSmallIntegerField) String() string {
return (*orm.PositiveSmallIntegerField)(e).String()
}
// FieldType return enum type
func (e *PositiveSmallIntegerField) FieldType() int {
return (*orm.PositiveSmallIntegerField)(e).FieldType()
}
// SetRaw convert Interface uint16/string to uint16
func (e *PositiveSmallIntegerField) SetRaw(value interface{}) error {
return (*orm.PositiveSmallIntegerField)(e).SetRaw(value)
}
// RawValue returns PositiveSmallIntegerField value
func (e *PositiveSmallIntegerField) RawValue() interface{} {
return (*orm.PositiveSmallIntegerField)(e).RawValue()
}
// verify PositiveSmallIntegerField implement Fielder
var _ Fielder = new(PositiveSmallIntegerField)
// PositiveIntegerField 0 to 4294967295
type PositiveIntegerField orm.PositiveIntegerField
// Value return PositiveIntegerField value. Uint32
func (e PositiveIntegerField) Value() uint32 {
return orm.PositiveIntegerField(e).Value()
}
// Set the PositiveIntegerField value
func (e *PositiveIntegerField) Set(d uint32) {
(*orm.PositiveIntegerField)(e).Set(d)
}
// String convert PositiveIntegerField to string
func (e *PositiveIntegerField) String() string {
return (*orm.PositiveIntegerField)(e).String()
}
// FieldType return enum type
func (e *PositiveIntegerField) FieldType() int {
return (*orm.PositiveIntegerField)(e).FieldType()
}
// SetRaw convert interface uint32/string to Uint32
func (e *PositiveIntegerField) SetRaw(value interface{}) error {
return (*orm.PositiveIntegerField)(e).SetRaw(value)
}
// RawValue return the PositiveIntegerField Value
func (e *PositiveIntegerField) RawValue() interface{} {
return (*orm.PositiveIntegerField)(e).RawValue()
}
// verify PositiveIntegerField implement Fielder
var _ Fielder = new(PositiveIntegerField)
// PositiveBigIntegerField 0 to 18446744073709551615
type PositiveBigIntegerField orm.PositiveBigIntegerField
// Value return uint64
func (e PositiveBigIntegerField) Value() uint64 {
return orm.PositiveBigIntegerField(e).Value()
}
// Set PositiveBigIntegerField value
func (e *PositiveBigIntegerField) Set(d uint64) {
(*orm.PositiveBigIntegerField)(e).Set(d)
}
// String convert PositiveBigIntegerField to string
func (e *PositiveBigIntegerField) String() string {
return (*orm.PositiveBigIntegerField)(e).String()
}
// FieldType return enum type
func (e *PositiveBigIntegerField) FieldType() int {
return (*orm.PositiveBigIntegerField)(e).FieldType()
}
// SetRaw convert interface uint64/string to Uint64
func (e *PositiveBigIntegerField) SetRaw(value interface{}) error {
return (*orm.PositiveBigIntegerField)(e).SetRaw(value)
}
// RawValue return PositiveBigIntegerField value
func (e *PositiveBigIntegerField) RawValue() interface{} {
return (*orm.PositiveBigIntegerField)(e).RawValue()
}
// verify PositiveBigIntegerField implement Fielder
var _ Fielder = new(PositiveBigIntegerField)
// TextField A large text field.
type TextField orm.TextField
// Value return TextField value
func (e TextField) Value() string {
return orm.TextField(e).Value()
}
// Set the TextField value
func (e *TextField) Set(d string) {
(*orm.TextField)(e).Set(d)
}
// String convert TextField to string
func (e *TextField) String() string {
return (*orm.TextField)(e).String()
}
// FieldType return enum type
func (e *TextField) FieldType() int {
return (*orm.TextField)(e).FieldType()
}
// SetRaw convert interface string to string
func (e *TextField) SetRaw(value interface{}) error {
return (*orm.TextField)(e).SetRaw(value)
}
// RawValue return TextField value
func (e *TextField) RawValue() interface{} {
return (*orm.TextField)(e).RawValue()
}
// verify TextField implement Fielder
var _ Fielder = new(TextField)
// JSONField postgres json field.
type JSONField orm.JSONField
// Value return JSONField value
func (j JSONField) Value() string {
return orm.JSONField(j).Value()
}
// Set the JSONField value
func (j *JSONField) Set(d string) {
(*orm.JSONField)(j).Set(d)
}
// String convert JSONField to string
func (j *JSONField) String() string {
return (*orm.JSONField)(j).String()
}
// FieldType return enum type
func (j *JSONField) FieldType() int {
return (*orm.JSONField)(j).FieldType()
}
// SetRaw convert interface string to string
func (j *JSONField) SetRaw(value interface{}) error {
return (*orm.JSONField)(j).SetRaw(value)
}
// RawValue return JSONField value
func (j *JSONField) RawValue() interface{} {
return (*orm.JSONField)(j).RawValue()
}
// verify JSONField implement Fielder
var _ Fielder = new(JSONField)
// JsonbField postgres json field.
type JsonbField orm.JsonbField
// Value return JsonbField value
func (j JsonbField) Value() string {
return orm.JsonbField(j).Value()
}
// Set the JsonbField value
func (j *JsonbField) Set(d string) {
(*orm.JsonbField)(j).Set(d)
}
// String convert JsonbField to string
func (j *JsonbField) String() string {
return (*orm.JsonbField)(j).String()
}
// FieldType return enum type
func (j *JsonbField) FieldType() int {
return (*orm.JsonbField)(j).FieldType()
}
// SetRaw convert interface string to string
func (j *JsonbField) SetRaw(value interface{}) error {
return (*orm.JsonbField)(j).SetRaw(value)
}
// RawValue return JsonbField value
func (j *JsonbField) RawValue() interface{} {
return (*orm.JsonbField)(j).RawValue()
}
// verify JsonbField implement Fielder
var _ Fielder = new(JsonbField)

314
pkg/adapter/orm/orm.go Normal file
View File

@ -0,0 +1,314 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// +build go1.8
// Package orm provide ORM for MySQL/PostgreSQL/sqlite
// Simple Usage
//
// package main
//
// import (
// "fmt"
// "github.com/astaxie/beego/orm"
// _ "github.com/go-sql-driver/mysql" // import your used driver
// )
//
// // Model Struct
// type User struct {
// Id int `orm:"auto"`
// Name string `orm:"size(100)"`
// }
//
// func init() {
// orm.RegisterDataBase("default", "mysql", "root:root@/my_db?charset=utf8", 30)
// }
//
// func main() {
// o := orm.NewOrm()
// user := User{Name: "slene"}
// // insert
// id, err := o.Insert(&user)
// // update
// user.Name = "astaxie"
// num, err := o.Update(&user)
// // read one
// u := User{Id: user.Id}
// err = o.Read(&u)
// // delete
// num, err = o.Delete(&u)
// }
//
// more docs: http://beego.me/docs/mvc/model/overview.md
package orm
import (
"context"
"database/sql"
"errors"
"github.com/astaxie/beego/pkg/client/orm"
"github.com/astaxie/beego/pkg/client/orm/hints"
"github.com/astaxie/beego/pkg/infrastructure/utils"
)
// DebugQueries define the debug
const (
DebugQueries = iota
)
// Define common vars
var (
Debug = orm.Debug
DebugLog = orm.DebugLog
DefaultRowsLimit = orm.DefaultRowsLimit
DefaultRelsDepth = orm.DefaultRelsDepth
DefaultTimeLoc = orm.DefaultTimeLoc
ErrTxHasBegan = errors.New("<Ormer.Begin> transaction already begin")
ErrTxDone = errors.New("<Ormer.Commit/Rollback> transaction not begin")
ErrMultiRows = errors.New("<QuerySeter> return multi rows")
ErrNoRows = errors.New("<QuerySeter> no row found")
ErrStmtClosed = errors.New("<QuerySeter> stmt already closed")
ErrArgs = errors.New("<Ormer> args error may be empty")
ErrNotImplement = errors.New("have not implement")
)
type ormer struct {
delegate orm.Ormer
txDelegate orm.TxOrmer
isTx bool
}
var _ Ormer = new(ormer)
// read data to model
func (o *ormer) Read(md interface{}, cols ...string) error {
if o.isTx {
return o.txDelegate.Read(md, cols...)
}
return o.delegate.Read(md, cols...)
}
// read data to model, like Read(), but use "SELECT FOR UPDATE" form
func (o *ormer) ReadForUpdate(md interface{}, cols ...string) error {
if o.isTx {
return o.txDelegate.ReadForUpdate(md, cols...)
}
return o.delegate.ReadForUpdate(md, cols...)
}
// Try to read a row from the database, or insert one if it doesn't exist
func (o *ormer) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
if o.isTx {
return o.txDelegate.ReadOrCreate(md, col1, cols...)
}
return o.delegate.ReadOrCreate(md, col1, cols...)
}
// insert model data to database
func (o *ormer) Insert(md interface{}) (int64, error) {
if o.isTx {
return o.txDelegate.Insert(md)
}
return o.delegate.Insert(md)
}
// insert some models to database
func (o *ormer) InsertMulti(bulk int, mds interface{}) (int64, error) {
if o.isTx {
return o.txDelegate.InsertMulti(bulk, mds)
}
return o.delegate.InsertMulti(bulk, mds)
}
// InsertOrUpdate data to database
func (o *ormer) InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) {
if o.isTx {
return o.txDelegate.InsertOrUpdate(md, colConflitAndArgs...)
}
return o.delegate.InsertOrUpdate(md, colConflitAndArgs...)
}
// update model to database.
// cols set the columns those want to update.
func (o *ormer) Update(md interface{}, cols ...string) (int64, error) {
if o.isTx {
return o.txDelegate.Update(md, cols...)
}
return o.delegate.Update(md, cols...)
}
// delete model in database
// cols shows the delete conditions values read from. default is pk
func (o *ormer) Delete(md interface{}, cols ...string) (int64, error) {
if o.isTx {
return o.txDelegate.Delete(md, cols...)
}
return o.delegate.Delete(md, cols...)
}
// create a models to models queryer
func (o *ormer) QueryM2M(md interface{}, name string) QueryM2Mer {
if o.isTx {
return o.txDelegate.QueryM2M(md, name)
}
return o.delegate.QueryM2M(md, name)
}
// load related models to md model.
// args are limit, offset int and order string.
//
// example:
// orm.LoadRelated(post,"Tags")
// for _,tag := range post.Tags{...}
//
// make sure the relation is defined in model struct tags.
func (o *ormer) LoadRelated(md interface{}, name string, args ...interface{}) (int64, error) {
kvs := make([]utils.KV, 0, 4)
for i, arg := range args {
switch i {
case 0:
if v, ok := arg.(bool); ok {
if v {
kvs = append(kvs, hints.DefaultRelDepth())
}
} else if v, ok := arg.(int); ok {
kvs = append(kvs, hints.RelDepth(v))
}
case 1:
kvs = append(kvs, hints.Limit(orm.ToInt64(arg)))
case 2:
kvs = append(kvs, hints.Offset(orm.ToInt64(arg)))
case 3:
kvs = append(kvs, hints.Offset(orm.ToInt64(arg)))
}
}
if o.isTx {
return o.txDelegate.LoadRelated(md, name, kvs...)
}
return o.delegate.LoadRelated(md, name, kvs...)
}
// return a QuerySeter for table operations.
// table name can be string or struct.
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
func (o *ormer) QueryTable(ptrStructOrTableName interface{}) (qs QuerySeter) {
if o.isTx {
return o.txDelegate.QueryTable(ptrStructOrTableName)
}
return o.delegate.QueryTable(ptrStructOrTableName)
}
// switch to another registered database driver by given name.
func (o *ormer) Using(name string) error {
if o.isTx {
return ErrTxHasBegan
}
o.delegate = orm.NewOrmUsingDB(name)
return nil
}
// begin transaction
func (o *ormer) Begin() error {
if o.isTx {
return ErrTxHasBegan
}
return o.BeginTx(context.Background(), nil)
}
func (o *ormer) BeginTx(ctx context.Context, opts *sql.TxOptions) error {
if o.isTx {
return ErrTxHasBegan
}
txOrmer, err := o.delegate.BeginWithCtxAndOpts(ctx, opts)
if err != nil {
return err
}
o.txDelegate = txOrmer
o.isTx = true
return nil
}
// commit transaction
func (o *ormer) Commit() error {
if !o.isTx {
return ErrTxDone
}
err := o.txDelegate.Commit()
if err == nil {
o.isTx = false
o.txDelegate = nil
} else if err == sql.ErrTxDone {
return ErrTxDone
}
return err
}
// rollback transaction
func (o *ormer) Rollback() error {
if !o.isTx {
return ErrTxDone
}
err := o.txDelegate.Rollback()
if err == nil {
o.isTx = false
o.txDelegate = nil
} else if err == sql.ErrTxDone {
return ErrTxDone
}
return err
}
// return a raw query seter for raw sql string.
func (o *ormer) Raw(query string, args ...interface{}) RawSeter {
if o.isTx {
return o.txDelegate.Raw(query, args...)
}
return o.delegate.Raw(query, args...)
}
// return current using database Driver
func (o *ormer) Driver() Driver {
if o.isTx {
return o.txDelegate.Driver()
}
return o.delegate.Driver()
}
// return sql.DBStats for current database
func (o *ormer) DBStats() *sql.DBStats {
if o.isTx {
return o.txDelegate.DBStats()
}
return o.delegate.DBStats()
}
// NewOrm create new orm
func NewOrm() Ormer {
o := orm.NewOrm()
return &ormer{
delegate: o,
}
}
// NewOrmWithDB create a new ormer object with specify *sql.DB for query
func NewOrmWithDB(driverName, aliasName string, db *sql.DB) (Ormer, error) {
o, err := orm.NewOrmWithDB(driverName, aliasName, db)
if err != nil {
return nil, err
}
return &ormer{
delegate: o,
}, nil
}

View File

@ -0,0 +1,83 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// ExprSep define the expression separation
const (
ExprSep = "__"
)
// Condition struct.
// work for WHERE conditions.
type Condition orm.Condition
// NewCondition return new condition struct
func NewCondition() *Condition {
return (*Condition)(orm.NewCondition())
}
// Raw add raw sql to condition
func (c Condition) Raw(expr string, sql string) *Condition {
return (*Condition)((orm.Condition)(c).Raw(expr, sql))
}
// And add expression to condition
func (c Condition) And(expr string, args ...interface{}) *Condition {
return (*Condition)((orm.Condition)(c).And(expr, args...))
}
// AndNot add NOT expression to condition
func (c Condition) AndNot(expr string, args ...interface{}) *Condition {
return (*Condition)((orm.Condition)(c).AndNot(expr, args...))
}
// AndCond combine a condition to current condition
func (c *Condition) AndCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).AndCond((*orm.Condition)(cond)))
}
// AndNotCond combine a AND NOT condition to current condition
func (c *Condition) AndNotCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).AndNotCond((*orm.Condition)(cond)))
}
// Or add OR expression to condition
func (c Condition) Or(expr string, args ...interface{}) *Condition {
return (*Condition)((orm.Condition)(c).Or(expr, args...))
}
// OrNot add OR NOT expression to condition
func (c Condition) OrNot(expr string, args ...interface{}) *Condition {
return (*Condition)((orm.Condition)(c).OrNot(expr, args...))
}
// OrCond combine a OR condition to current condition
func (c *Condition) OrCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).OrCond((*orm.Condition)(cond)))
}
// OrNotCond combine a OR NOT condition to current condition
func (c *Condition) OrNotCond(cond *Condition) *Condition {
return (*Condition)((*orm.Condition)(c).OrNotCond((*orm.Condition)(cond)))
}
// IsEmpty check the condition arguments are empty or not.
func (c *Condition) IsEmpty() bool {
return (*orm.Condition)(c).IsEmpty()
}

View File

@ -0,0 +1,32 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"io"
"github.com/astaxie/beego/pkg/client/orm"
)
// Log implement the log.Logger
type Log orm.Log
// costomer log func
var LogFunc = orm.LogFunc
// NewLog set io.Writer to create a Logger.
func NewLog(out io.Writer) *Log {
return (*Log)(orm.NewLog(out))
}

View File

@ -0,0 +1,32 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// define Col operations
const (
ColAdd = orm.ColAdd
ColMinus = orm.ColMinus
ColMultiply = orm.ColMultiply
ColExcept = orm.ColExcept
ColBitAnd = orm.ColBitAnd
ColBitRShift = orm.ColBitRShift
ColBitLShift = orm.ColBitLShift
ColBitXOR = orm.ColBitXOR
ColBitOr = orm.ColBitOr
)

27
pkg/adapter/orm/qb.go Normal file
View File

@ -0,0 +1,27 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// QueryBuilder is the Query builder interface
type QueryBuilder orm.QueryBuilder
// NewQueryBuilder return the QueryBuilder
func NewQueryBuilder(driver string) (qb QueryBuilder, err error) {
return orm.NewQueryBuilder(driver)
}

150
pkg/adapter/orm/qb_mysql.go Normal file
View File

@ -0,0 +1,150 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// CommaSpace is the separation
const CommaSpace = orm.CommaSpace
// MySQLQueryBuilder is the SQL build
type MySQLQueryBuilder orm.MySQLQueryBuilder
// Select will join the fields
func (qb *MySQLQueryBuilder) Select(fields ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Select(fields...)
}
// ForUpdate add the FOR UPDATE clause
func (qb *MySQLQueryBuilder) ForUpdate() QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).ForUpdate()
}
// From join the tables
func (qb *MySQLQueryBuilder) From(tables ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).From(tables...)
}
// InnerJoin INNER JOIN the table
func (qb *MySQLQueryBuilder) InnerJoin(table string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).InnerJoin(table)
}
// LeftJoin LEFT JOIN the table
func (qb *MySQLQueryBuilder) LeftJoin(table string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).LeftJoin(table)
}
// RightJoin RIGHT JOIN the table
func (qb *MySQLQueryBuilder) RightJoin(table string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).RightJoin(table)
}
// On join with on cond
func (qb *MySQLQueryBuilder) On(cond string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).On(cond)
}
// Where join the Where cond
func (qb *MySQLQueryBuilder) Where(cond string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Where(cond)
}
// And join the and cond
func (qb *MySQLQueryBuilder) And(cond string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).And(cond)
}
// Or join the or cond
func (qb *MySQLQueryBuilder) Or(cond string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Or(cond)
}
// In join the IN (vals)
func (qb *MySQLQueryBuilder) In(vals ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).In(vals...)
}
// OrderBy join the Order by fields
func (qb *MySQLQueryBuilder) OrderBy(fields ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).OrderBy(fields...)
}
// Asc join the asc
func (qb *MySQLQueryBuilder) Asc() QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Asc()
}
// Desc join the desc
func (qb *MySQLQueryBuilder) Desc() QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Desc()
}
// Limit join the limit num
func (qb *MySQLQueryBuilder) Limit(limit int) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Limit(limit)
}
// Offset join the offset num
func (qb *MySQLQueryBuilder) Offset(offset int) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Offset(offset)
}
// GroupBy join the Group by fields
func (qb *MySQLQueryBuilder) GroupBy(fields ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).GroupBy(fields...)
}
// Having join the Having cond
func (qb *MySQLQueryBuilder) Having(cond string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Having(cond)
}
// Update join the update table
func (qb *MySQLQueryBuilder) Update(tables ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Update(tables...)
}
// Set join the set kv
func (qb *MySQLQueryBuilder) Set(kv ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Set(kv...)
}
// Delete join the Delete tables
func (qb *MySQLQueryBuilder) Delete(tables ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Delete(tables...)
}
// InsertInto join the insert SQL
func (qb *MySQLQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).InsertInto(table, fields...)
}
// Values join the Values(vals)
func (qb *MySQLQueryBuilder) Values(vals ...string) QueryBuilder {
return (*orm.MySQLQueryBuilder)(qb).Values(vals...)
}
// Subquery join the sub as alias
func (qb *MySQLQueryBuilder) Subquery(sub string, alias string) string {
return (*orm.MySQLQueryBuilder)(qb).Subquery(sub, alias)
}
// String join all Tokens
func (qb *MySQLQueryBuilder) String() string {
return (*orm.MySQLQueryBuilder)(qb).String()
}

147
pkg/adapter/orm/qb_tidb.go Normal file
View File

@ -0,0 +1,147 @@
// Copyright 2015 TiDB Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
// TiDBQueryBuilder is the SQL build
type TiDBQueryBuilder orm.TiDBQueryBuilder
// Select will join the fields
func (qb *TiDBQueryBuilder) Select(fields ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Select(fields...)
}
// ForUpdate add the FOR UPDATE clause
func (qb *TiDBQueryBuilder) ForUpdate() QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).ForUpdate()
}
// From join the tables
func (qb *TiDBQueryBuilder) From(tables ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).From(tables...)
}
// InnerJoin INNER JOIN the table
func (qb *TiDBQueryBuilder) InnerJoin(table string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).InnerJoin(table)
}
// LeftJoin LEFT JOIN the table
func (qb *TiDBQueryBuilder) LeftJoin(table string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).LeftJoin(table)
}
// RightJoin RIGHT JOIN the table
func (qb *TiDBQueryBuilder) RightJoin(table string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).RightJoin(table)
}
// On join with on cond
func (qb *TiDBQueryBuilder) On(cond string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).On(cond)
}
// Where join the Where cond
func (qb *TiDBQueryBuilder) Where(cond string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Where(cond)
}
// And join the and cond
func (qb *TiDBQueryBuilder) And(cond string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).And(cond)
}
// Or join the or cond
func (qb *TiDBQueryBuilder) Or(cond string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Or(cond)
}
// In join the IN (vals)
func (qb *TiDBQueryBuilder) In(vals ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).In(vals...)
}
// OrderBy join the Order by fields
func (qb *TiDBQueryBuilder) OrderBy(fields ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).OrderBy(fields...)
}
// Asc join the asc
func (qb *TiDBQueryBuilder) Asc() QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Asc()
}
// Desc join the desc
func (qb *TiDBQueryBuilder) Desc() QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Desc()
}
// Limit join the limit num
func (qb *TiDBQueryBuilder) Limit(limit int) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Limit(limit)
}
// Offset join the offset num
func (qb *TiDBQueryBuilder) Offset(offset int) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Offset(offset)
}
// GroupBy join the Group by fields
func (qb *TiDBQueryBuilder) GroupBy(fields ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).GroupBy(fields...)
}
// Having join the Having cond
func (qb *TiDBQueryBuilder) Having(cond string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Having(cond)
}
// Update join the update table
func (qb *TiDBQueryBuilder) Update(tables ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Update(tables...)
}
// Set join the set kv
func (qb *TiDBQueryBuilder) Set(kv ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Set(kv...)
}
// Delete join the Delete tables
func (qb *TiDBQueryBuilder) Delete(tables ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Delete(tables...)
}
// InsertInto join the insert SQL
func (qb *TiDBQueryBuilder) InsertInto(table string, fields ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).InsertInto(table, fields...)
}
// Values join the Values(vals)
func (qb *TiDBQueryBuilder) Values(vals ...string) QueryBuilder {
return (*orm.TiDBQueryBuilder)(qb).Values(vals...)
}
// Subquery join the sub as alias
func (qb *TiDBQueryBuilder) Subquery(sub string, alias string) string {
return (*orm.TiDBQueryBuilder)(qb).Subquery(sub, alias)
}
// String join all Tokens
func (qb *TiDBQueryBuilder) String() string {
return (*orm.TiDBQueryBuilder)(qb).String()
}

View File

@ -0,0 +1,34 @@
// Copyright 2020
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"github.com/astaxie/beego/pkg/client/orm"
)
type baseQuerySetter struct {
}
func (b *baseQuerySetter) ForceIndex(indexes ...string) orm.QuerySeter {
panic("you should not invoke this method.")
}
func (b *baseQuerySetter) UseIndex(indexes ...string) orm.QuerySeter {
panic("you should not invoke this method.")
}
func (b *baseQuerySetter) IgnoreIndex(indexes ...string) orm.QuerySeter {
panic("you should not invoke this method.")
}

150
pkg/adapter/orm/types.go Normal file
View File

@ -0,0 +1,150 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"context"
"database/sql"
"github.com/astaxie/beego/pkg/client/orm"
)
// Params stores the Params
type Params orm.Params
// ParamsList stores paramslist
type ParamsList orm.ParamsList
// Driver define database driver
type Driver orm.Driver
// Fielder define field info
type Fielder orm.Fielder
// Ormer define the orm interface
type Ormer interface {
// read data to model
// for example:
// this will find User by Id field
// u = &User{Id: user.Id}
// err = Ormer.Read(u)
// this will find User by UserName field
// u = &User{UserName: "astaxie", Password: "pass"}
// err = Ormer.Read(u, "UserName")
Read(md interface{}, cols ...string) error
// Like Read(), but with "FOR UPDATE" clause, useful in transaction.
// Some databases are not support this feature.
ReadForUpdate(md interface{}, cols ...string) error
// Try to read a row from the database, or insert one if it doesn't exist
ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error)
// insert model data to database
// for example:
// user := new(User)
// id, err = Ormer.Insert(user)
// user must be a pointer and Insert will set user's pk field
Insert(interface{}) (int64, error)
// mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value")
// if colu type is integer : can use(+-*/), string : convert(colu,"value")
// postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value")
// if colu type is integer : can use(+-*/), string : colu || "value"
InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error)
// insert some models to database
InsertMulti(bulk int, mds interface{}) (int64, error)
// update model to database.
// cols set the columns those want to update.
// find model by Id(pk) field and update columns specified by fields, if cols is null then update all columns
// for example:
// user := User{Id: 2}
// user.Langs = append(user.Langs, "zh-CN", "en-US")
// user.Extra.Name = "beego"
// user.Extra.Data = "orm"
// num, err = Ormer.Update(&user, "Langs", "Extra")
Update(md interface{}, cols ...string) (int64, error)
// delete model in database
Delete(md interface{}, cols ...string) (int64, error)
// load related models to md model.
// args are limit, offset int and order string.
//
// example:
// Ormer.LoadRelated(post,"Tags")
// for _,tag := range post.Tags{...}
// args[0] bool true useDefaultRelsDepth ; false depth 0
// args[0] int loadRelationDepth
// args[1] int limit default limit 1000
// args[2] int offset default offset 0
// args[3] string order for example : "-Id"
// make sure the relation is defined in model struct tags.
LoadRelated(md interface{}, name string, args ...interface{}) (int64, error)
// create a models to models queryer
// for example:
// post := Post{Id: 4}
// m2m := Ormer.QueryM2M(&post, "Tags")
QueryM2M(md interface{}, name string) QueryM2Mer
// return a QuerySeter for table operations.
// table name can be string or struct.
// e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)),
QueryTable(ptrStructOrTableName interface{}) QuerySeter
// switch to another registered database driver by given name.
Using(name string) error
// begin transaction
// for example:
// o := NewOrm()
// err := o.Begin()
// ...
// err = o.Rollback()
Begin() error
// begin transaction with provided context and option
// the provided context is used until the transaction is committed or rolled back.
// if the context is canceled, the transaction will be rolled back.
// the provided TxOptions is optional and may be nil if defaults should be used.
// if a non-default isolation level is used that the driver doesn't support, an error will be returned.
// for example:
// o := NewOrm()
// err := o.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
// ...
// err = o.Rollback()
BeginTx(ctx context.Context, opts *sql.TxOptions) error
// commit transaction
Commit() error
// rollback transaction
Rollback() error
// return a raw query seter for raw sql string.
// for example:
// ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec()
// // update user testing's name to slene
Raw(query string, args ...interface{}) RawSeter
Driver() Driver
DBStats() *sql.DBStats
}
// Inserter insert prepared statement
type Inserter orm.Inserter
// QuerySeter query seter
type QuerySeter orm.QuerySeter
// QueryM2Mer model to model query struct
// all operations are on the m2m table only, will not affect the origin model table
type QueryM2Mer orm.QueryM2Mer
// RawPreparer raw query statement
type RawPreparer orm.RawPreparer
// RawSeter raw query seter
// create From Ormer.Raw
// for example:
// sql := fmt.Sprintf("SELECT %sid%s,%sname%s FROM %suser%s WHERE id = ?",Q,Q,Q,Q,Q,Q)
// rs := Ormer.Raw(sql, 1)
type RawSeter orm.RawSeter

286
pkg/adapter/orm/utils.go Normal file
View File

@ -0,0 +1,286 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"fmt"
"reflect"
"strconv"
"strings"
"time"
"github.com/astaxie/beego/pkg/client/orm"
)
type fn func(string) string
var (
nameStrategyMap = map[string]fn{
defaultNameStrategy: snakeString,
SnakeAcronymNameStrategy: snakeStringWithAcronym,
}
defaultNameStrategy = "snakeString"
SnakeAcronymNameStrategy = "snakeStringWithAcronym"
nameStrategy = defaultNameStrategy
)
// StrTo is the target string
type StrTo orm.StrTo
// Set string
func (f *StrTo) Set(v string) {
(*orm.StrTo)(f).Set(v)
}
// Clear string
func (f *StrTo) Clear() {
(*orm.StrTo)(f).Clear()
}
// Exist check string exist
func (f StrTo) Exist() bool {
return orm.StrTo(f).Exist()
}
// Bool string to bool
func (f StrTo) Bool() (bool, error) {
return orm.StrTo(f).Bool()
}
// Float32 string to float32
func (f StrTo) Float32() (float32, error) {
return orm.StrTo(f).Float32()
}
// Float64 string to float64
func (f StrTo) Float64() (float64, error) {
return orm.StrTo(f).Float64()
}
// Int string to int
func (f StrTo) Int() (int, error) {
return orm.StrTo(f).Int()
}
// Int8 string to int8
func (f StrTo) Int8() (int8, error) {
return orm.StrTo(f).Int8()
}
// Int16 string to int16
func (f StrTo) Int16() (int16, error) {
return orm.StrTo(f).Int16()
}
// Int32 string to int32
func (f StrTo) Int32() (int32, error) {
return orm.StrTo(f).Int32()
}
// Int64 string to int64
func (f StrTo) Int64() (int64, error) {
return orm.StrTo(f).Int64()
}
// Uint string to uint
func (f StrTo) Uint() (uint, error) {
return orm.StrTo(f).Uint()
}
// Uint8 string to uint8
func (f StrTo) Uint8() (uint8, error) {
return orm.StrTo(f).Uint8()
}
// Uint16 string to uint16
func (f StrTo) Uint16() (uint16, error) {
return orm.StrTo(f).Uint16()
}
// Uint32 string to uint32
func (f StrTo) Uint32() (uint32, error) {
return orm.StrTo(f).Uint32()
}
// Uint64 string to uint64
func (f StrTo) Uint64() (uint64, error) {
return orm.StrTo(f).Uint64()
}
// String string to string
func (f StrTo) String() string {
return orm.StrTo(f).String()
}
// ToStr interface to string
func ToStr(value interface{}, args ...int) (s string) {
switch v := value.(type) {
case bool:
s = strconv.FormatBool(v)
case float32:
s = strconv.FormatFloat(float64(v), 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 32))
case float64:
s = strconv.FormatFloat(v, 'f', argInt(args).Get(0, -1), argInt(args).Get(1, 64))
case int:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int8:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int16:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int32:
s = strconv.FormatInt(int64(v), argInt(args).Get(0, 10))
case int64:
s = strconv.FormatInt(v, argInt(args).Get(0, 10))
case uint:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint8:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint16:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint32:
s = strconv.FormatUint(uint64(v), argInt(args).Get(0, 10))
case uint64:
s = strconv.FormatUint(v, argInt(args).Get(0, 10))
case string:
s = v
case []byte:
s = string(v)
default:
s = fmt.Sprintf("%v", v)
}
return s
}
// ToInt64 interface to int64
func ToInt64(value interface{}) (d int64) {
val := reflect.ValueOf(value)
switch value.(type) {
case int, int8, int16, int32, int64:
d = val.Int()
case uint, uint8, uint16, uint32, uint64:
d = int64(val.Uint())
default:
panic(fmt.Errorf("ToInt64 need numeric not `%T`", value))
}
return
}
func snakeStringWithAcronym(s string) string {
data := make([]byte, 0, len(s)*2)
num := len(s)
for i := 0; i < num; i++ {
d := s[i]
before := false
after := false
if i > 0 {
before = s[i-1] >= 'a' && s[i-1] <= 'z'
}
if i+1 < num {
after = s[i+1] >= 'a' && s[i+1] <= 'z'
}
if i > 0 && d >= 'A' && d <= 'Z' && (before || after) {
data = append(data, '_')
}
data = append(data, d)
}
return strings.ToLower(string(data[:]))
}
// snake string, XxYy to xx_yy , XxYY to xx_y_y
func snakeString(s string) string {
data := make([]byte, 0, len(s)*2)
j := false
num := len(s)
for i := 0; i < num; i++ {
d := s[i]
if i > 0 && d >= 'A' && d <= 'Z' && j {
data = append(data, '_')
}
if d != '_' {
j = true
}
data = append(data, d)
}
return strings.ToLower(string(data[:]))
}
// SetNameStrategy set different name strategy
func SetNameStrategy(s string) {
if SnakeAcronymNameStrategy != s {
nameStrategy = defaultNameStrategy
}
nameStrategy = s
}
// camel string, xx_yy to XxYy
func camelString(s string) string {
data := make([]byte, 0, len(s))
flag, num := true, len(s)-1
for i := 0; i <= num; i++ {
d := s[i]
if d == '_' {
flag = true
continue
} else if flag {
if d >= 'a' && d <= 'z' {
d = d - 32
}
flag = false
}
data = append(data, d)
}
return string(data[:])
}
type argString []string
// get string by index from string slice
func (a argString) Get(i int, args ...string) (r string) {
if i >= 0 && i < len(a) {
r = a[i]
} else if len(args) > 0 {
r = args[0]
}
return
}
type argInt []int
// get int by index from int slice
func (a argInt) Get(i int, args ...int) (r int) {
if i >= 0 && i < len(a) {
r = a[i]
}
if len(args) > 0 {
r = args[0]
}
return
}
// parse time to string with location
func timeParse(dateString, format string) (time.Time, error) {
tp, err := time.ParseInLocation(format, dateString, DefaultTimeLoc)
return tp, err
}
// get pointer indirect type
func indirectType(v reflect.Type) reflect.Type {
switch v.Kind() {
case reflect.Ptr:
return indirectType(v.Elem())
default:
return v
}
}

View File

@ -0,0 +1,70 @@
// Copyright 2014 beego Author. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package orm
import (
"testing"
)
func TestCamelString(t *testing.T) {
snake := []string{"pic_url", "hello_world_", "hello__World", "_HelLO_Word", "pic_url_1", "pic_url__1"}
camel := []string{"PicUrl", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "PicUrl1"}
answer := make(map[string]string)
for i, v := range snake {
answer[v] = camel[i]
}
for _, v := range snake {
res := camelString(v)
if res != answer[v] {
t.Error("Unit Test Fail:", v, res, answer[v])
}
}
}
func TestSnakeString(t *testing.T) {
camel := []string{"PicUrl", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "XyXX"}
snake := []string{"pic_url", "hello_world", "hello_world", "hel_l_o_word", "pic_url1", "xy_x_x"}
answer := make(map[string]string)
for i, v := range camel {
answer[v] = snake[i]
}
for _, v := range camel {
res := snakeString(v)
if res != answer[v] {
t.Error("Unit Test Fail:", v, res, answer[v])
}
}
}
func TestSnakeStringWithAcronym(t *testing.T) {
camel := []string{"ID", "PicURL", "HelloWorld", "HelloWorld", "HelLOWord", "PicUrl1", "XyXX"}
snake := []string{"id", "pic_url", "hello_world", "hello_world", "hel_lo_word", "pic_url1", "xy_xx"}
answer := make(map[string]string)
for i, v := range camel {
answer[v] = snake[i]
}
for _, v := range camel {
res := snakeStringWithAcronym(v)
if res != answer[v] {
t.Error("Unit Test Fail:", v, res, answer[v])
}
}
}

View File

@ -400,22 +400,47 @@ func newAliasWithDb(aliasName, driverName string, db *sql.DB, params ...utils.KV
detectTZ(al)
kvs.IfContains(hints.KeyMaxIdleConnections, func(value interface{}) {
if m, ok := value.(int); ok {
SetMaxIdleConns(al, m)
}
al.SetMaxIdleConns(value.(int))
}).IfContains(hints.KeyMaxOpenConnections, func(value interface{}) {
if m, ok := value.(int); ok {
SetMaxOpenConns(al, m)
}
al.SetMaxOpenConns(value.(int))
}).IfContains(hints.KeyConnMaxLifetime, func(value interface{}) {
if m, ok := value.(time.Duration); ok {
SetConnMaxLifetime(al, m)
}
al.SetConnMaxLifetime(value.(time.Duration))
})
return al, nil
}
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
// Deprecated you should not use this, we will remove it in the future
func SetMaxIdleConns(aliasName string, maxIdleConns int) {
al := getDbAlias(aliasName)
al.SetMaxIdleConns(maxIdleConns)
}
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
// Deprecated you should not use this, we will remove it in the future
func SetMaxOpenConns(aliasName string, maxOpenConns int) {
al := getDbAlias(aliasName)
al.SetMaxIdleConns(maxOpenConns)
}
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
func (al *alias) SetMaxIdleConns(maxIdleConns int) {
al.MaxIdleConns = maxIdleConns
al.DB.DB.SetMaxIdleConns(maxIdleConns)
}
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
func (al *alias) SetMaxOpenConns(maxOpenConns int) {
al.MaxOpenConns = maxOpenConns
al.DB.DB.SetMaxOpenConns(maxOpenConns)
}
func (al *alias) SetConnMaxLifetime(lifeTime time.Duration) {
al.ConnMaxLifetime = lifeTime
al.DB.DB.SetConnMaxLifetime(lifeTime)
}
// AddAliasWthDB add a aliasName for the drivename
func AddAliasWthDB(aliasName, driverName string, db *sql.DB, params ...utils.KV) error {
_, err := addAliasWthDB(aliasName, driverName, db, params...)
@ -476,23 +501,6 @@ func SetDataBaseTZ(aliasName string, tz *time.Location) error {
return nil
}
// SetMaxIdleConns Change the max idle conns for *sql.DB, use specify database alias name
func SetMaxIdleConns(al *alias, maxIdleConns int) {
al.MaxIdleConns = maxIdleConns
al.DB.DB.SetMaxIdleConns(maxIdleConns)
}
// SetMaxOpenConns Change the max open conns for *sql.DB, use specify database alias name
func SetMaxOpenConns(al *alias, maxOpenConns int) {
al.MaxOpenConns = maxOpenConns
al.DB.DB.SetMaxOpenConns(maxOpenConns)
}
func SetConnMaxLifetime(al *alias, lifeTime time.Duration) {
al.ConnMaxLifetime = lifeTime
al.DB.DB.SetConnMaxLifetime(lifeTime)
}
// GetDB Get *sql.DB from registered database by db alias name.
// Use "default" as alias name if you not set.
func GetDB(aliasNames ...string) (*sql.DB, error) {

View File

@ -311,9 +311,7 @@ func (o *ormBase) LoadRelated(md interface{}, name string, args ...utils.KV) (in
return o.LoadRelatedWithCtx(context.Background(), md, name, args...)
}
func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) {
_, fi, ind, qseter := o.queryRelated(md, name)
qs := qseter.(*querySet)
_, fi, ind, qs := o.queryRelated(md, name)
var relDepth int
var limit, offset int64
@ -377,7 +375,7 @@ func (o *ormBase) LoadRelatedWithCtx(ctx context.Context, md interface{}, name s
}
// get QuerySeter for related models to md model
func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, QuerySeter) {
func (o *ormBase) queryRelated(md interface{}, name string) (*modelInfo, *fieldInfo, reflect.Value, *querySet) {
mi, ind := o.getMiInd(md, true)
fi := o.getFieldInfo(mi, name)