github.com/astaxie/beego@v1.12.3/orm/models_test.go (about)

     1  // Copyright 2014 beego Author. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package orm
    16  
    17  import (
    18  	"database/sql"
    19  	"encoding/json"
    20  	"fmt"
    21  	"os"
    22  	"strings"
    23  	"time"
    24  
    25  	_ "github.com/go-sql-driver/mysql"
    26  	_ "github.com/lib/pq"
    27  	_ "github.com/mattn/go-sqlite3"
    28  	// As tidb can't use go get, so disable the tidb testing now
    29  	// _ "github.com/pingcap/tidb"
    30  )
    31  
    32  // A slice string field.
    33  type SliceStringField []string
    34  
    35  func (e SliceStringField) Value() []string {
    36  	return []string(e)
    37  }
    38  
    39  func (e *SliceStringField) Set(d []string) {
    40  	*e = SliceStringField(d)
    41  }
    42  
    43  func (e *SliceStringField) Add(v string) {
    44  	*e = append(*e, v)
    45  }
    46  
    47  func (e *SliceStringField) String() string {
    48  	return strings.Join(e.Value(), ",")
    49  }
    50  
    51  func (e *SliceStringField) FieldType() int {
    52  	return TypeVarCharField
    53  }
    54  
    55  func (e *SliceStringField) SetRaw(value interface{}) error {
    56  	f := func(str string) {
    57  		if len(str) > 0 {
    58  			parts := strings.Split(str, ",")
    59  			v := make([]string, 0, len(parts))
    60  			for _, p := range parts {
    61  				v = append(v, strings.TrimSpace(p))
    62  			}
    63  			e.Set(v)
    64  		}
    65  	}
    66  
    67  	switch d := value.(type) {
    68  	case []string:
    69  		e.Set(d)
    70  	case string:
    71  		f(d)
    72  	case []byte:
    73  		f(string(d))
    74  	default:
    75  		return fmt.Errorf("<SliceStringField.SetRaw> unknown value `%v`", value)
    76  	}
    77  	return nil
    78  }
    79  
    80  func (e *SliceStringField) RawValue() interface{} {
    81  	return e.String()
    82  }
    83  
    84  var _ Fielder = new(SliceStringField)
    85  
    86  // A json field.
    87  type JSONFieldTest struct {
    88  	Name string
    89  	Data string
    90  }
    91  
    92  func (e *JSONFieldTest) String() string {
    93  	data, _ := json.Marshal(e)
    94  	return string(data)
    95  }
    96  
    97  func (e *JSONFieldTest) FieldType() int {
    98  	return TypeTextField
    99  }
   100  
   101  func (e *JSONFieldTest) SetRaw(value interface{}) error {
   102  	switch d := value.(type) {
   103  	case string:
   104  		return json.Unmarshal([]byte(d), e)
   105  	case []byte:
   106  		return json.Unmarshal(d, e)
   107  	default:
   108  		return fmt.Errorf("<JSONField.SetRaw> unknown value `%v`", value)
   109  	}
   110  }
   111  
   112  func (e *JSONFieldTest) RawValue() interface{} {
   113  	return e.String()
   114  }
   115  
   116  var _ Fielder = new(JSONFieldTest)
   117  
   118  type Data struct {
   119  	ID       int `orm:"column(id)"`
   120  	Boolean  bool
   121  	Char     string    `orm:"size(50)"`
   122  	Text     string    `orm:"type(text)"`
   123  	JSON     string    `orm:"type(json);default({\"name\":\"json\"})"`
   124  	Jsonb    string    `orm:"type(jsonb)"`
   125  	Time     time.Time `orm:"type(time)"`
   126  	Date     time.Time `orm:"type(date)"`
   127  	DateTime time.Time `orm:"column(datetime)"`
   128  	Byte     byte
   129  	Rune     rune
   130  	Int      int
   131  	Int8     int8
   132  	Int16    int16
   133  	Int32    int32
   134  	Int64    int64
   135  	Uint     uint
   136  	Uint8    uint8
   137  	Uint16   uint16
   138  	Uint32   uint32
   139  	Uint64   uint64
   140  	Float32  float32
   141  	Float64  float64
   142  	Decimal  float64 `orm:"digits(8);decimals(4)"`
   143  }
   144  
   145  type DataNull struct {
   146  	ID          int             `orm:"column(id)"`
   147  	Boolean     bool            `orm:"null"`
   148  	Char        string          `orm:"null;size(50)"`
   149  	Text        string          `orm:"null;type(text)"`
   150  	JSON        string          `orm:"type(json);null"`
   151  	Jsonb       string          `orm:"type(jsonb);null"`
   152  	Time        time.Time       `orm:"null;type(time)"`
   153  	Date        time.Time       `orm:"null;type(date)"`
   154  	DateTime    time.Time       `orm:"null;column(datetime)"`
   155  	Byte        byte            `orm:"null"`
   156  	Rune        rune            `orm:"null"`
   157  	Int         int             `orm:"null"`
   158  	Int8        int8            `orm:"null"`
   159  	Int16       int16           `orm:"null"`
   160  	Int32       int32           `orm:"null"`
   161  	Int64       int64           `orm:"null"`
   162  	Uint        uint            `orm:"null"`
   163  	Uint8       uint8           `orm:"null"`
   164  	Uint16      uint16          `orm:"null"`
   165  	Uint32      uint32          `orm:"null"`
   166  	Uint64      uint64          `orm:"null"`
   167  	Float32     float32         `orm:"null"`
   168  	Float64     float64         `orm:"null"`
   169  	Decimal     float64         `orm:"digits(8);decimals(4);null"`
   170  	NullString  sql.NullString  `orm:"null"`
   171  	NullBool    sql.NullBool    `orm:"null"`
   172  	NullFloat64 sql.NullFloat64 `orm:"null"`
   173  	NullInt64   sql.NullInt64   `orm:"null"`
   174  	BooleanPtr  *bool           `orm:"null"`
   175  	CharPtr     *string         `orm:"null;size(50)"`
   176  	TextPtr     *string         `orm:"null;type(text)"`
   177  	BytePtr     *byte           `orm:"null"`
   178  	RunePtr     *rune           `orm:"null"`
   179  	IntPtr      *int            `orm:"null"`
   180  	Int8Ptr     *int8           `orm:"null"`
   181  	Int16Ptr    *int16          `orm:"null"`
   182  	Int32Ptr    *int32          `orm:"null"`
   183  	Int64Ptr    *int64          `orm:"null"`
   184  	UintPtr     *uint           `orm:"null"`
   185  	Uint8Ptr    *uint8          `orm:"null"`
   186  	Uint16Ptr   *uint16         `orm:"null"`
   187  	Uint32Ptr   *uint32         `orm:"null"`
   188  	Uint64Ptr   *uint64         `orm:"null"`
   189  	Float32Ptr  *float32        `orm:"null"`
   190  	Float64Ptr  *float64        `orm:"null"`
   191  	DecimalPtr  *float64        `orm:"digits(8);decimals(4);null"`
   192  	TimePtr     *time.Time      `orm:"null;type(time)"`
   193  	DatePtr     *time.Time      `orm:"null;type(date)"`
   194  	DateTimePtr *time.Time      `orm:"null"`
   195  }
   196  
   197  type String string
   198  type Boolean bool
   199  type Byte byte
   200  type Rune rune
   201  type Int int
   202  type Int8 int8
   203  type Int16 int16
   204  type Int32 int32
   205  type Int64 int64
   206  type Uint uint
   207  type Uint8 uint8
   208  type Uint16 uint16
   209  type Uint32 uint32
   210  type Uint64 uint64
   211  type Float32 float64
   212  type Float64 float64
   213  
   214  type DataCustom struct {
   215  	ID      int `orm:"column(id)"`
   216  	Boolean Boolean
   217  	Char    string `orm:"size(50)"`
   218  	Text    string `orm:"type(text)"`
   219  	Byte    Byte
   220  	Rune    Rune
   221  	Int     Int
   222  	Int8    Int8
   223  	Int16   Int16
   224  	Int32   Int32
   225  	Int64   Int64
   226  	Uint    Uint
   227  	Uint8   Uint8
   228  	Uint16  Uint16
   229  	Uint32  Uint32
   230  	Uint64  Uint64
   231  	Float32 Float32
   232  	Float64 Float64
   233  	Decimal Float64 `orm:"digits(8);decimals(4)"`
   234  }
   235  
   236  // only for mysql
   237  type UserBig struct {
   238  	ID   uint64 `orm:"column(id)"`
   239  	Name string
   240  }
   241  
   242  type User struct {
   243  	ID           int    `orm:"column(id)"`
   244  	UserName     string `orm:"size(30);unique"`
   245  	Email        string `orm:"size(100)"`
   246  	Password     string `orm:"size(100)"`
   247  	Status       int16  `orm:"column(Status)"`
   248  	IsStaff      bool
   249  	IsActive     bool      `orm:"default(true)"`
   250  	Created      time.Time `orm:"auto_now_add;type(date)"`
   251  	Updated      time.Time `orm:"auto_now"`
   252  	Profile      *Profile  `orm:"null;rel(one);on_delete(set_null)"`
   253  	Posts        []*Post   `orm:"reverse(many)" json:"-"`
   254  	ShouldSkip   string    `orm:"-"`
   255  	Nums         int
   256  	Langs        SliceStringField `orm:"size(100)"`
   257  	Extra        JSONFieldTest    `orm:"type(text)"`
   258  	unexport     bool             `orm:"-"`
   259  	unexportBool bool
   260  }
   261  
   262  func (u *User) TableIndex() [][]string {
   263  	return [][]string{
   264  		{"Id", "UserName"},
   265  		{"Id", "Created"},
   266  	}
   267  }
   268  
   269  func (u *User) TableUnique() [][]string {
   270  	return [][]string{
   271  		{"UserName", "Email"},
   272  	}
   273  }
   274  
   275  func NewUser() *User {
   276  	obj := new(User)
   277  	return obj
   278  }
   279  
   280  type Profile struct {
   281  	ID       int `orm:"column(id)"`
   282  	Age      int16
   283  	Money    float64
   284  	User     *User `orm:"reverse(one)" json:"-"`
   285  	BestPost *Post `orm:"rel(one);null"`
   286  }
   287  
   288  func (u *Profile) TableName() string {
   289  	return "user_profile"
   290  }
   291  
   292  func NewProfile() *Profile {
   293  	obj := new(Profile)
   294  	return obj
   295  }
   296  
   297  type Post struct {
   298  	ID      int       `orm:"column(id)"`
   299  	User    *User     `orm:"rel(fk)"`
   300  	Title   string    `orm:"size(60)"`
   301  	Content string    `orm:"type(text)"`
   302  	Created time.Time `orm:"auto_now_add"`
   303  	Updated time.Time `orm:"auto_now"`
   304  	Tags    []*Tag    `orm:"rel(m2m);rel_through(github.com/astaxie/beego/orm.PostTags)"`
   305  }
   306  
   307  func (u *Post) TableIndex() [][]string {
   308  	return [][]string{
   309  		{"Id", "Created"},
   310  	}
   311  }
   312  
   313  func NewPost() *Post {
   314  	obj := new(Post)
   315  	return obj
   316  }
   317  
   318  type Tag struct {
   319  	ID       int     `orm:"column(id)"`
   320  	Name     string  `orm:"size(30)"`
   321  	BestPost *Post   `orm:"rel(one);null"`
   322  	Posts    []*Post `orm:"reverse(many)" json:"-"`
   323  }
   324  
   325  func NewTag() *Tag {
   326  	obj := new(Tag)
   327  	return obj
   328  }
   329  
   330  type PostTags struct {
   331  	ID   int   `orm:"column(id)"`
   332  	Post *Post `orm:"rel(fk)"`
   333  	Tag  *Tag  `orm:"rel(fk)"`
   334  }
   335  
   336  func (m *PostTags) TableName() string {
   337  	return "prefix_post_tags"
   338  }
   339  
   340  type Comment struct {
   341  	ID      int       `orm:"column(id)"`
   342  	Post    *Post     `orm:"rel(fk);column(post)"`
   343  	Content string    `orm:"type(text)"`
   344  	Parent  *Comment  `orm:"null;rel(fk)"`
   345  	Created time.Time `orm:"auto_now_add"`
   346  }
   347  
   348  func NewComment() *Comment {
   349  	obj := new(Comment)
   350  	return obj
   351  }
   352  
   353  type Group struct {
   354  	ID          int `orm:"column(gid);size(32)"`
   355  	Name        string
   356  	Permissions []*Permission `orm:"reverse(many)" json:"-"`
   357  }
   358  
   359  type Permission struct {
   360  	ID     int `orm:"column(id)"`
   361  	Name   string
   362  	Groups []*Group `orm:"rel(m2m);rel_through(github.com/astaxie/beego/orm.GroupPermissions)"`
   363  }
   364  
   365  type GroupPermissions struct {
   366  	ID         int         `orm:"column(id)"`
   367  	Group      *Group      `orm:"rel(fk)"`
   368  	Permission *Permission `orm:"rel(fk)"`
   369  }
   370  
   371  type ModelID struct {
   372  	ID int64
   373  }
   374  
   375  type ModelBase struct {
   376  	ModelID
   377  
   378  	Created time.Time `orm:"auto_now_add;type(datetime)"`
   379  	Updated time.Time `orm:"auto_now;type(datetime)"`
   380  }
   381  
   382  type InLine struct {
   383  	// Common Fields
   384  	ModelBase
   385  
   386  	// Other Fields
   387  	Name  string `orm:"unique"`
   388  	Email string
   389  }
   390  
   391  func NewInLine() *InLine {
   392  	return new(InLine)
   393  }
   394  
   395  type InLineOneToOne struct {
   396  	// Common Fields
   397  	ModelBase
   398  
   399  	Note   string
   400  	InLine *InLine `orm:"rel(fk);column(inline)"`
   401  }
   402  
   403  func NewInLineOneToOne() *InLineOneToOne {
   404  	return new(InLineOneToOne)
   405  }
   406  
   407  type IntegerPk struct {
   408  	ID    int64 `orm:"pk"`
   409  	Value string
   410  }
   411  
   412  type UintPk struct {
   413  	ID   uint32 `orm:"pk"`
   414  	Name string
   415  }
   416  
   417  type PtrPk struct {
   418  	ID       *IntegerPk `orm:"pk;rel(one)"`
   419  	Positive bool
   420  }
   421  
   422  var DBARGS = struct {
   423  	Driver string
   424  	Source string
   425  	Debug  string
   426  }{
   427  	os.Getenv("ORM_DRIVER"),
   428  	os.Getenv("ORM_SOURCE"),
   429  	os.Getenv("ORM_DEBUG"),
   430  }
   431  
   432  var (
   433  	IsMysql    = DBARGS.Driver == "mysql"
   434  	IsSqlite   = DBARGS.Driver == "sqlite3"
   435  	IsPostgres = DBARGS.Driver == "postgres"
   436  	IsTidb     = DBARGS.Driver == "tidb"
   437  )
   438  
   439  var (
   440  	dORM     Ormer
   441  	dDbBaser dbBaser
   442  )
   443  
   444  var (
   445  	helpinfo = `need driver and source!
   446  
   447  	Default DB Drivers.
   448  	
   449  	  driver: url
   450  	   mysql: https://github.com/go-sql-driver/mysql
   451  	 sqlite3: https://github.com/mattn/go-sqlite3
   452  	postgres: https://github.com/lib/pq
   453  	tidb: https://github.com/pingcap/tidb
   454  	
   455  	usage:
   456  	
   457  	go get -u github.com/astaxie/beego/orm
   458  	go get -u github.com/go-sql-driver/mysql
   459  	go get -u github.com/mattn/go-sqlite3
   460  	go get -u github.com/lib/pq
   461  	go get -u github.com/pingcap/tidb
   462  	
   463  	#### MySQL
   464  	mysql -u root -e 'create database orm_test;'
   465  	export ORM_DRIVER=mysql
   466  	export ORM_SOURCE="root:@/orm_test?charset=utf8"
   467  	go test -v github.com/astaxie/beego/orm
   468  	
   469  	
   470  	#### Sqlite3
   471  	export ORM_DRIVER=sqlite3
   472  	export ORM_SOURCE='file:memory_test?mode=memory'
   473  	go test -v github.com/astaxie/beego/orm
   474  	
   475  	
   476  	#### PostgreSQL
   477  	psql -c 'create database orm_test;' -U postgres
   478  	export ORM_DRIVER=postgres
   479  	export ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable"
   480  	go test -v github.com/astaxie/beego/orm
   481  	
   482  	#### TiDB
   483  	export ORM_DRIVER=tidb
   484  	export ORM_SOURCE='memory://test/test'
   485  	go test -v github.com/astaxie/beego/orm
   486  	
   487  	`
   488  )
   489  
   490  func init() {
   491  	Debug, _ = StrTo(DBARGS.Debug).Bool()
   492  
   493  	if DBARGS.Driver == "" || DBARGS.Source == "" {
   494  		fmt.Println(helpinfo)
   495  		os.Exit(2)
   496  	}
   497  
   498  	RegisterDataBase("default", DBARGS.Driver, DBARGS.Source, 20)
   499  
   500  	alias := getDbAlias("default")
   501  	if alias.Driver == DRMySQL {
   502  		alias.Engine = "INNODB"
   503  	}
   504  
   505  }