models_test.go 11 KB

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