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 }